@steerprotocol/strategy-utils 2.1.9 → 2.2.1

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.
@@ -0,0 +1,60 @@
1
+ import { Candle } from "./types/Candle";
2
+ import { RawTradeData } from "./types/RawTradeData";
3
+
4
+ // CandlestickConverter class provides a static method to convert raw trade data into OHLCV format
5
+ export class CandlestickConverter {
6
+ // convertToOHLCV method accepts raw trade data and a period (default is 3600 seconds or 1 hour)
7
+ // and returns the data in OHLCV format
8
+ static convertToOHLCV(rawData: RawTradeData[], period: i32 = 3600): Candle[] {
9
+ // If the raw data is empty, an error is thrown
10
+ if (rawData.length === 0) {
11
+ throw new Error("Input data is empty");
12
+ }
13
+
14
+ // Array to hold the converted data
15
+ let ohlcvData: Candle[] = [];
16
+
17
+ // Initialize variables
18
+ let i: i32 = 0;
19
+ let currentTimestamp: i32 = Math.floor(rawData[0].timestamp / period) * period;
20
+ let open: f64 = rawData[0].price;
21
+ let high: f64 = rawData[0].price;
22
+ let low: f64 = rawData[0].price;
23
+ let close: f64 = rawData[0].price;
24
+ let volume: f64 = 0.0;
25
+
26
+ // Loop through all raw data
27
+ while (i < rawData.length) {
28
+ // For each period, set the initial values of open, high, low to the closing price of the last period
29
+ // and reset the volume to 0
30
+ open = close;
31
+ high = close;
32
+ low = close;
33
+ volume = 0.0;
34
+
35
+ // Process all raw data within the current period
36
+ while (i < rawData.length && rawData[i].timestamp < currentTimestamp + period) {
37
+ // Set the open price to the price of the first trade in the period
38
+ open = i == 0 ? rawData[i].price : open;
39
+ // Update high and low prices
40
+ high = Math.max(high, rawData[i].price);
41
+ low = Math.min(low, rawData[i].price);
42
+ // Update close price to the price of the last trade in the period
43
+ close = rawData[i].price;
44
+ // Update the total volume
45
+ volume += rawData[i].volume;
46
+ i++;
47
+ }
48
+
49
+ // Create a new Candle object with the calculated OHLCV values and add it to the array
50
+ let ohlcv: Candle = new Candle(currentTimestamp, open, high, low, close, volume);
51
+ ohlcvData.push(ohlcv);
52
+
53
+ // Move to the next period
54
+ currentTimestamp += period;
55
+ }
56
+
57
+ // Return the converted data
58
+ return ohlcvData;
59
+ }
60
+ }
@@ -1,4 +1,4 @@
1
- export function _getMax(arr: Array<f32>): f32 {
1
+ export function _getMax(arr: Array<f64>): f64 {
2
2
  let max = arr[0];
3
3
  for (let i = 1; i < arr.length; i++) {
4
4
  if (arr[i] > max) {
@@ -8,36 +8,41 @@ export function _getMax(arr: Array<f32>): f32 {
8
8
  return max;
9
9
  }
10
10
 
11
- export function getMax(a: f32, b: f32): f32 {
11
+ export function getMax(a: f64, b: f64): f64 {
12
12
  if (a >= b) return a
13
13
  return b
14
14
  }
15
15
 
16
16
 
17
- export function _normalDensity(std: f32, mean: f32, x: f32): f32 {
18
- return f32(
19
- (f32(Math.E) ** (((x - mean) / std) ** 2 / -2) / std) *
20
- Math.sqrt(2 * f32(Math.PI))
17
+ export function _normalDensity(std: f64, mean: f64, x: f64): f64 {
18
+ return f64(
19
+ (f64(Math.E) ** (((x - mean) / std) ** 2 / -2) / std) *
20
+ Math.sqrt(2 * f64(Math.PI))
21
21
  );
22
22
  }
23
23
 
24
- export function _standardDeviation(list:f32[]): f32 {
24
+ export function _standardDeviation(list:f64[]): f64 {
25
25
  const mean = _mean(list)
26
- const sqrdDiff: f32[] = []
26
+ const sqrdDiff: f64[] = []
27
27
  for (let i = 0; i < list.length; i++){
28
28
  sqrdDiff.push((list[i]-mean)*(list[i]-mean))
29
29
  }
30
30
  const variance = _mean(sqrdDiff)
31
31
  const stddev = Math.sqrt(variance)
32
- return f32(stddev)
32
+ return f64(stddev)
33
33
  }
34
34
 
35
35
  // SMA simple moving average
36
- export function _mean(list: f32[]): f32 {
36
+ export function _mean(list: f64[]): f64 {
37
37
  const length = list.length;
38
- let total: f32 = 0.0;
38
+ let total: f64 = 0.0;
39
39
  for (let i = 0; i < length; i++){
40
40
  total += list[i]
41
41
  }
42
- return total / f32(length)
42
+ return total / f64(length)
43
+ }
44
+
45
+ export function closestDivisibleNumber(num: number, divisor: number, floor: boolean): number {
46
+ if (floor) return Math.floor(num / divisor) * divisor;
47
+ return Math.ceil(num / divisor) * divisor;
43
48
  }
@@ -1,18 +1,18 @@
1
1
  export class SMA {
2
- private readonly prices: f32[] = [];
2
+ private readonly prices: f64[] = [];
3
3
  private interval: i32 = 0;
4
- private result: f32;
5
- private prevEMA: f32;
4
+ private result: f64 = 0
5
+ // private prevEMA: f64;
6
6
 
7
7
  constructor(interval: i32) {
8
8
  this.interval = interval;
9
9
  }
10
10
 
11
- getResult(): f32 {
11
+ getResult(): f64 {
12
12
  return this.result;
13
13
  }
14
14
 
15
- update(price: f32): void {
15
+ update(price: f64): void {
16
16
  this.prices.push(price);
17
17
 
18
18
  if (this.prices.length > this.interval) {
@@ -20,32 +20,32 @@ export class SMA {
20
20
  }
21
21
 
22
22
  if (this.prices.length === this.interval) {
23
- let result = f32(0);
23
+ let result = f64(0);
24
24
  for (let priceIndex = 0; priceIndex < this.prices.length; priceIndex++) {
25
25
  result = result + this.prices[priceIndex];
26
26
  }
27
- this.result = result / f32(this.prices.length || 1);
27
+ this.result = result / f64(this.prices.length || 1);
28
28
  }
29
29
  }
30
30
  }
31
31
 
32
32
  export class EMA {
33
- private readonly prices: f32[] = [];
33
+ private readonly prices: f64[] = [];
34
34
  private interval: i32 = 0;
35
- private result: f32;
35
+ private result: f64 = 0
36
36
  private multiplier: i32;
37
- private prevEMA: f32;
37
+ private prevEMA: f64 = 0
38
38
 
39
39
  constructor(interval: i32, multiplier: i32) {
40
40
  this.interval = interval;
41
41
  this.multiplier = multiplier;
42
42
  }
43
43
 
44
- getResult(): f32 {
44
+ getResult(): f64 {
45
45
  return this.result;
46
46
  }
47
47
 
48
- update(price: f32): void {
48
+ update(price: f64): void {
49
49
  this.prices.push(price);
50
50
 
51
51
  if (this.prices.length > this.interval) {
@@ -56,11 +56,11 @@ export class EMA {
56
56
  this.prevEMA = price;
57
57
  }
58
58
 
59
- let p1 = price * (f32(this.multiplier) / (1 + f32(this.interval)));
59
+ let p1 = price * (f64(this.multiplier) / (1 + f64(this.interval)));
60
60
  let p2 =
61
- this.prevEMA * (1 - f32(this.multiplier) / (1 + f32(this.interval)));
61
+ this.prevEMA * (1 - f64(this.multiplier) / (1 + f64(this.interval)));
62
62
 
63
- this.result = f32(p1 + p2);
63
+ this.result = f64(p1 + p2);
64
64
  this.prevEMA = this.result;
65
65
  }
66
66
  }
@@ -1,8 +1,8 @@
1
1
  import { Candle } from "./types/Candle";
2
2
  import { getMax, _mean, _getMax } from "./Math";
3
3
 
4
- export function getAverageTrueRange(candles: Array<Candle>, interval: i32): f32 {
5
- let rangeSum: f32 = 0;
4
+ export function getAverageTrueRange(candles: Array<Candle>, interval: i32): f64 {
5
+ let rangeSum: f64 = 0;
6
6
  for (let i = 1; i < candles.length; i++) {
7
7
  const currentPrice = candles[i];
8
8
 
@@ -14,34 +14,34 @@ export function getAverageTrueRange(candles: Array<Candle>, interval: i32): f32
14
14
  const range2 = Math.abs(currentLow - previousClose);
15
15
  const range3 = Math.abs(currentHigh - currentLow);
16
16
 
17
- let max = _getMax([f32(range1), f32(range2), f32(range3)]);
17
+ let max = _getMax([f64(range1), f64(range2), f64(range3)]);
18
18
  rangeSum += max;
19
19
  }
20
20
 
21
21
 
22
- return f32(rangeSum) / f32(candles.length - 1);
22
+ return f64(rangeSum) / f64(candles.length - 1);
23
23
 
24
24
  }
25
25
 
26
26
 
27
- export function trailingStop(percent: f32, prices: Candle[]): f32 {
27
+ export function trailingStop(percent: f64, prices: Candle[]): f64 {
28
28
  // Get the current price of the asset pair
29
29
  const currentPrice = prices[prices.length - 1];
30
30
 
31
31
  // Calculate the trailing stop price
32
- const trailingStopPrice = currentPrice.close - (currentPrice.close * f32(percent / 100));
32
+ const trailingStopPrice = currentPrice.close - (currentPrice.close * f64(percent / 100));
33
33
 
34
34
  // Return the trailing stop price
35
- return f32(trailingStopPrice);
35
+ return f64(trailingStopPrice);
36
36
  }
37
37
 
38
- export function trueRange(price: Candle): f32{
39
- const trueRange = getMax(f32(price.high) - f32(price.low),getMax(f32(Math.abs(price.high-price.close)),f32(Math.abs(price.low-price.close))));
38
+ export function trueRange(price: Candle): f64{
39
+ const trueRange = getMax(f64(price.high) - f64(price.low),getMax(f64(Math.abs(price.high-price.close)),f64(Math.abs(price.low-price.close))));
40
40
  return trueRange;
41
41
  }
42
42
 
43
- export function averageTrueRange(prices: Candle[]): f32 {
44
- const trueRanges: f32[] = []
43
+ export function averageTrueRange(prices: Candle[]): f64 {
44
+ const trueRanges: f64[] = []
45
45
  for (let i = 0; i < prices.length; i++) {
46
46
  trueRanges.push(trueRange(prices[i]));
47
47
  }
@@ -1 +1,2 @@
1
- export declare function generateCandles(data: string, candleSize: string): string
1
+ export declare function generateCandles(data: string, candleSize: string): string
2
+ export declare function ccxt_fetchOHLCV(exchangeId: string, symbol: string, timeframe: string, limit: number, since: number): string
@@ -3,13 +3,13 @@ import { JSON } from 'json-as/assembly';
3
3
  @serializable
4
4
  export class Candle {
5
5
  timestamp: i64 = 0;
6
- high: number = 0.0;
7
- low: number = 0.0;
8
- open: number = 0.0;
9
- close: number = 0.0;
10
- volume: number = 0.0;
6
+ high: f64 = 0.0;
7
+ low: f64 = 0.0;
8
+ open: f64 = 0.0;
9
+ close: f64 = 0.0;
10
+ volume: f64 = 0.0;
11
11
 
12
- constructor(timestamp: i64, high: number, low: number, open: number, close: number, volume: number) {
12
+ constructor(timestamp: i64, high: f64, low: f64, open: f64, close: f64, volume: f64) {
13
13
  this.timestamp = timestamp;
14
14
  this.high = high;
15
15
  this.low = low;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@steerprotocol/strategy-utils",
3
- "version": "2.1.9",
3
+ "version": "2.2.1",
4
4
  "description": "Strategy utilities library for Steer Protocol strategies",
5
5
  "main": "assembly/index.ts",
6
6
  "types": "assembly/index.ts",