@steerprotocol/strategy-utils 2.2.1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/nodejs.yml +9 -9
- package/CHANGELOG.md +28 -0
- package/assembly/utils/MarketFeedAggregator.ts +140 -0
- package/assembly/utils/Ranges.ts +1 -1
- package/assembly/utils/env.ts +23 -2
- package/assembly/utils/triggers.ts +469 -0
- package/index.js +11 -11
- package/package.json +6 -3
- package/readme.md +387 -0
- package/tests/debug.wasm +0 -0
- package/tests/index.test.ts +236 -26
- package/tests/utils.ts +607 -0
- package/.vscode/settings.json +0 -8
|
@@ -25,14 +25,14 @@ jobs:
|
|
|
25
25
|
if: steps.node-cache.outputs.cache-hit != 'true'
|
|
26
26
|
run: yarn
|
|
27
27
|
|
|
28
|
-
- name: Test to see if the project compiles
|
|
29
|
-
|
|
28
|
+
# - name: Test to see if the project compiles
|
|
29
|
+
# run: yarn asbuild
|
|
30
30
|
|
|
31
31
|
- name: Perform tests
|
|
32
32
|
run: yarn test
|
|
33
33
|
|
|
34
|
-
- name: Create the docs directory locally in CI
|
|
35
|
-
|
|
34
|
+
# - name: Create the docs directory locally in CI
|
|
35
|
+
# run: yarn docs
|
|
36
36
|
|
|
37
37
|
- name: Release
|
|
38
38
|
run: npx semantic-release
|
|
@@ -40,8 +40,8 @@ jobs:
|
|
|
40
40
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
41
41
|
NPM_TOKEN: ${{ secrets.SEMANTIC_RELEASE_BOT_NPM_TOKEN }}
|
|
42
42
|
|
|
43
|
-
- name: Deploy 🚀
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
43
|
+
# - name: Deploy 🚀
|
|
44
|
+
# uses: JamesIves/github-pages-deploy-action@4.1.4
|
|
45
|
+
# with:
|
|
46
|
+
# branch: gh-pages
|
|
47
|
+
# folder: docs
|
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,31 @@
|
|
|
1
|
+
## [1.2.0-alpha.2](https://github.com/SteerProtocol/strategy-utils-assemblyscript/compare/v1.2.0-alpha.1...v1.2.0-alpha.2) (2023-08-17)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* :sparkles: Trigger Logic Utils ([dc1058c](https://github.com/SteerProtocol/strategy-utils-assemblyscript/commit/dc1058c48db7b7f1ae6ad9de321a49023859cd1e))
|
|
7
|
+
* :zap: Latest spec for bundle interfacing ([c7287a5](https://github.com/SteerProtocol/strategy-utils-assemblyscript/commit/c7287a5ef5510d67b9ec884d3529fc1bda14ac3d))
|
|
8
|
+
* :zap: Trigger logic and tests ([5105832](https://github.com/SteerProtocol/strategy-utils-assemblyscript/commit/510583295e2f9b94d0091ff9944daf6c84eb9196))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* :white_check_mark: Fix tests ([2944e90](https://github.com/SteerProtocol/strategy-utils-assemblyscript/commit/2944e90dbf4e532c934dcef325ff023e863fcef7))
|
|
14
|
+
|
|
15
|
+
## [1.2.0-alpha.1](https://github.com/SteerProtocol/strategy-utils-assemblyscript/compare/v1.1.2-alpha.1...v1.2.0-alpha.1) (2023-08-15)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Features
|
|
19
|
+
|
|
20
|
+
* :zap: f32 -> f64 conversion ([19c98cb](https://github.com/SteerProtocol/strategy-utils-assemblyscript/commit/19c98cb82dab0057cec790de29188c20bab09f76))
|
|
21
|
+
* asyncify support ([45234ab](https://github.com/SteerProtocol/strategy-utils-assemblyscript/commit/45234ab5edfc389580f09392e9b5c47ff2cbc1dc))
|
|
22
|
+
* Integrate ccxt into strategy-utils ([bbc67b5](https://github.com/SteerProtocol/strategy-utils-assemblyscript/commit/bbc67b52462163581e020b7576cc5b176102952b))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
### Bug Fixes
|
|
26
|
+
|
|
27
|
+
* array GC issues ([15a3a36](https://github.com/SteerProtocol/strategy-utils-assemblyscript/commit/15a3a36b2779ac64341867ac4d8eabe6748bd55d))
|
|
28
|
+
|
|
1
29
|
### [1.1.2-alpha.1](https://github.com/SteerProtocol/strategy-utils-assemblyscript/compare/v1.1.1...v1.1.2-alpha.1) (2022-08-15)
|
|
2
30
|
|
|
3
31
|
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
class Candle {
|
|
2
|
+
timestamp: f64;
|
|
3
|
+
open: f64;
|
|
4
|
+
high: f64;
|
|
5
|
+
close: f64;
|
|
6
|
+
low: f64;
|
|
7
|
+
volume: f64;
|
|
8
|
+
|
|
9
|
+
constructor(
|
|
10
|
+
timestamp: f64,
|
|
11
|
+
open: f64,
|
|
12
|
+
high: f64,
|
|
13
|
+
close: f64,
|
|
14
|
+
low: f64,
|
|
15
|
+
volume: f64
|
|
16
|
+
) {
|
|
17
|
+
this.timestamp = timestamp;
|
|
18
|
+
this.open = open;
|
|
19
|
+
this.high = high;
|
|
20
|
+
this.close = close;
|
|
21
|
+
this.low = low;
|
|
22
|
+
this.volume = volume;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
class MarketFeedAggregator {
|
|
27
|
+
data: Array<Candle>;
|
|
28
|
+
|
|
29
|
+
constructor(data: Array<Candle>) {
|
|
30
|
+
this.data = data;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
geometricMean(): Candle {
|
|
34
|
+
let n: f64 = f64(this.data.length);
|
|
35
|
+
let logSum = new Candle(0, 0, 0, 0, 0, 0);
|
|
36
|
+
|
|
37
|
+
for (let i = 0; i < this.data.length; i++) {
|
|
38
|
+
let candle = this.data[i];
|
|
39
|
+
logSum.timestamp += Mathf.log(candle.timestamp);
|
|
40
|
+
logSum.open += Mathf.log(candle.open);
|
|
41
|
+
logSum.high += Mathf.log(candle.high);
|
|
42
|
+
logSum.close += Mathf.log(candle.close);
|
|
43
|
+
logSum.low += Mathf.log(candle.low);
|
|
44
|
+
logSum.volume += Mathf.log(candle.volume);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return new Candle(
|
|
48
|
+
Mathf.exp(logSum.timestamp / n),
|
|
49
|
+
Mathf.exp(logSum.open / n),
|
|
50
|
+
Mathf.exp(logSum.high / n),
|
|
51
|
+
Mathf.exp(logSum.close / n),
|
|
52
|
+
Mathf.exp(logSum.low / n),
|
|
53
|
+
Mathf.exp(logSum.volume / n)
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
timeWeightedAveragePrice(): f64 {
|
|
58
|
+
let sumProduct: f64 = 0;
|
|
59
|
+
let sumTime: f64 = 0;
|
|
60
|
+
|
|
61
|
+
for (let i = 0; i < this.data.length; i++) {
|
|
62
|
+
let candle = this.data[i];
|
|
63
|
+
let midPrice: f64 = (candle.high + candle.low) / 2;
|
|
64
|
+
sumProduct += midPrice * candle.timestamp;
|
|
65
|
+
sumTime += candle.timestamp;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return sumProduct / sumTime;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
volumeWeightedAveragePrice(): f64 {
|
|
72
|
+
let sumProduct: f64 = 0;
|
|
73
|
+
let sumVolume: f64 = 0;
|
|
74
|
+
|
|
75
|
+
for (let i = 0; i < this.data.length; i++) {
|
|
76
|
+
let candle = this.data[i];
|
|
77
|
+
let midPrice: f64 = (candle.high + candle.low) / 2;
|
|
78
|
+
sumProduct += midPrice * candle.volume;
|
|
79
|
+
sumVolume += candle.volume;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return sumProduct / sumVolume;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
weightedMean(weights: Candle): Candle {
|
|
86
|
+
let sumWeights: f64 = 0;
|
|
87
|
+
let sumProduct: Candle = new Candle(0, 0, 0, 0, 0, 0);
|
|
88
|
+
|
|
89
|
+
for (let i = 0; i < this.data.length; i++) {
|
|
90
|
+
let candle = this.data[i];
|
|
91
|
+
sumProduct.timestamp += weights.timestamp * candle.timestamp;
|
|
92
|
+
sumProduct.open += weights.open * candle.open;
|
|
93
|
+
sumProduct.high += weights.high * candle.high;
|
|
94
|
+
sumProduct.close += weights.close * candle.close;
|
|
95
|
+
sumProduct.low += weights.low * candle.low;
|
|
96
|
+
sumProduct.volume += weights.volume * candle.volume;
|
|
97
|
+
|
|
98
|
+
sumWeights +=
|
|
99
|
+
weights.timestamp +
|
|
100
|
+
weights.open +
|
|
101
|
+
weights.high +
|
|
102
|
+
weights.close +
|
|
103
|
+
weights.low +
|
|
104
|
+
weights.volume;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return new Candle(
|
|
108
|
+
sumProduct.timestamp / sumWeights,
|
|
109
|
+
sumProduct.open / sumWeights,
|
|
110
|
+
sumProduct.high / sumWeights,
|
|
111
|
+
sumProduct.close / sumWeights,
|
|
112
|
+
sumProduct.low / sumWeights,
|
|
113
|
+
sumProduct.volume / sumWeights
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
arithmeticMean(): Candle {
|
|
118
|
+
let n: f64 = f64(this.data.length);
|
|
119
|
+
let sum: Candle = new Candle(0, 0, 0, 0, 0, 0);
|
|
120
|
+
|
|
121
|
+
for (let i = 0; i < this.data.length; i++) {
|
|
122
|
+
let candle = this.data[i];
|
|
123
|
+
sum.timestamp += candle.timestamp;
|
|
124
|
+
sum.open += candle.open;
|
|
125
|
+
sum.high += candle.high;
|
|
126
|
+
sum.close += candle.close;
|
|
127
|
+
sum.low += candle.low;
|
|
128
|
+
sum.volume += candle.volume;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return new Candle(
|
|
132
|
+
sum.timestamp / n,
|
|
133
|
+
sum.open / n,
|
|
134
|
+
sum.high / n,
|
|
135
|
+
sum.close / n,
|
|
136
|
+
sum.low / n,
|
|
137
|
+
sum.volume / n
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
}
|
package/assembly/utils/Ranges.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Candle } from "./types/Candle";
|
|
2
2
|
import { getMax, _mean, _getMax } from "./Math";
|
|
3
3
|
|
|
4
|
-
export function getAverageTrueRange(candles: Array<Candle
|
|
4
|
+
export function getAverageTrueRange(candles: Array<Candle>): f64 {
|
|
5
5
|
let rangeSum: f64 = 0;
|
|
6
6
|
for (let i = 1; i < candles.length; i++) {
|
|
7
7
|
const currentPrice = candles[i];
|
package/assembly/utils/env.ts
CHANGED
|
@@ -1,2 +1,23 @@
|
|
|
1
|
-
export declare function generateCandles(data: string, candleSize: string): string
|
|
2
|
-
|
|
1
|
+
export declare function generateCandles(data: string, candleSize: string): string;
|
|
2
|
+
@external("env", "ccxt_fetchOHLCV")
|
|
3
|
+
declare function _ccxt_fetchOHLCV(exchangeId: string, symbol: string, timeframe: string, limit: number, since: number): StaticArray<StaticArray<f64>>;
|
|
4
|
+
|
|
5
|
+
// Required for asyncify
|
|
6
|
+
// @ts-ignore: Global should exist here
|
|
7
|
+
@global let __ASYNCIFY_INITIALIZED = false;
|
|
8
|
+
@external("env", "_initAsyncify")
|
|
9
|
+
declare function _initAsyncify(asyncify_data_ptr: usize, stack_pointer: usize): void;
|
|
10
|
+
|
|
11
|
+
export function ccxt_fetchOHLCV(exchangeId: string, symbol: string, timeframe: string, limit: number, since: number): StaticArray<StaticArray<f64>> {
|
|
12
|
+
if (!__ASYNCIFY_INITIALIZED) {
|
|
13
|
+
// We need to initialize space for Asyncify to work.
|
|
14
|
+
// Asyncify will create a full - duplex communication channel through this bit of memory.
|
|
15
|
+
// For every asyncify-enabled function, make sure to add this
|
|
16
|
+
// memory.data() reserves a section of data that is not touched by the Garbage Collector
|
|
17
|
+
// We can only do this once or else we will cause a memory leak and eventual overflow
|
|
18
|
+
// It will not grow past the stack pointer which is where real data starts.
|
|
19
|
+
_initAsyncify(memory.data(8, 16), __stack_pointer);
|
|
20
|
+
__ASYNCIFY_INITIALIZED = true;
|
|
21
|
+
}
|
|
22
|
+
return _ccxt_fetchOHLCV(exchangeId, symbol, timeframe, limit, since);
|
|
23
|
+
}
|