@gbozee/ultimate 0.0.2-72 → 0.0.2-74

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.
@@ -438,6 +438,9 @@ export declare class Strategy {
438
438
  get short_tp(): number;
439
439
  generateGapClosingAlgorithm(payload: {
440
440
  kind: "long" | "short";
441
+ ignore_entries?: boolean;
442
+ reduce_ratio?: number;
443
+ sell_factor?: number;
441
444
  }): {
442
445
  [x: string]: any;
443
446
  risk: number;
@@ -445,11 +448,17 @@ export declare class Strategy {
445
448
  last_entry: any;
446
449
  first_entry: any;
447
450
  threshold: any;
451
+ spread: number;
452
+ gap_loss: number;
453
+ net_profit: number;
448
454
  };
449
455
  runIterations(payload: {
450
456
  kind: "long" | "short";
451
457
  iterations: number;
452
458
  risk_reward?: number;
459
+ ignore_entries?: boolean;
460
+ reduce_ratio?: number;
461
+ sell_factor?: number;
453
462
  }): {
454
463
  [x: string]: any;
455
464
  risk: number;
@@ -457,6 +466,9 @@ export declare class Strategy {
457
466
  last_entry: any;
458
467
  first_entry: any;
459
468
  threshold: any;
469
+ spread: number;
470
+ gap_loss: number;
471
+ net_profit: number;
460
472
  }[];
461
473
  getPositionAfterTp(payload: {
462
474
  kind: "long" | "short";
@@ -506,6 +518,7 @@ export declare class Strategy {
506
518
  generateOppositeTrades(payload: {
507
519
  kind: "long" | "short";
508
520
  risk_factor?: number;
521
+ avg_entry?: number;
509
522
  }): {
510
523
  avg: {
511
524
  entry: number;
@@ -1830,7 +1830,12 @@ class Strategy {
1830
1830
  return this.tp("short");
1831
1831
  }
1832
1832
  generateGapClosingAlgorithm(payload) {
1833
- const { kind } = payload;
1833
+ const {
1834
+ kind,
1835
+ ignore_entries = false,
1836
+ reduce_ratio = 1,
1837
+ sell_factor = 1
1838
+ } = payload;
1834
1839
  const { entry, quantity } = this.position[kind];
1835
1840
  const focus_position = this.position[kind];
1836
1841
  const reverse_kind = kind == "long" ? "short" : "long";
@@ -1857,7 +1862,10 @@ class Strategy {
1857
1862
  if (!app_config) {
1858
1863
  return null;
1859
1864
  }
1860
- const { entries, ...rest } = app_config;
1865
+ let { entries, ...rest } = app_config;
1866
+ if (ignore_entries) {
1867
+ entries = [];
1868
+ }
1861
1869
  const risk = this.to_f(rest.risk_per_trade);
1862
1870
  const adjusted_focus_entries = entries.map((entry2) => {
1863
1871
  let adjusted_price = entry2.price;
@@ -1879,7 +1887,7 @@ class Strategy {
1879
1887
  quantity
1880
1888
  }
1881
1889
  ]), rest.decimal_places, rest.price_places);
1882
- const focus_loss = this.to_f((avg.price - second_payload.stop) * avg.quantity);
1890
+ const focus_loss = this.to_f(Math.abs(avg.price - second_payload.stop) * avg.quantity);
1883
1891
  let below_reverse_entries = kind === "long" ? entries.filter((u) => {
1884
1892
  return u.entry < (reverse_position.entry || focus_position.entry);
1885
1893
  }) : entries.filter((u) => {
@@ -1906,18 +1914,20 @@ class Strategy {
1906
1914
  quantity: reverse_position.quantity
1907
1915
  }
1908
1916
  ]), rest.decimal_places, rest.price_places);
1909
- const reverse_pnl = this.to_f((reverse_avg.price - second_payload.stop) * reverse_avg.quantity);
1917
+ const sell_quantity = this.to_df(reverse_avg.quantity * sell_factor);
1918
+ const reverse_pnl = this.to_f(Math.abs(reverse_avg.price - second_payload.stop) * sell_quantity);
1910
1919
  const fee_to_pay = this.calculate_fee({
1911
1920
  price: avg.entry,
1912
1921
  quantity: avg.quantity
1913
1922
  }) + this.calculate_fee({
1914
1923
  price: reverse_avg.entry,
1915
- quantity: reverse_avg.quantity
1924
+ quantity: sell_quantity
1916
1925
  });
1917
1926
  const net_reverse_pnl = reverse_pnl - fee_to_pay;
1918
- const ratio = net_reverse_pnl / focus_loss;
1927
+ const ratio = net_reverse_pnl * reduce_ratio / focus_loss;
1919
1928
  const quantity_to_sell = this.to_df(ratio * avg.quantity);
1920
1929
  const remaining_quantity = this.to_df(avg.quantity - quantity_to_sell);
1930
+ const incurred_loss = this.to_f((avg.price - second_payload.stop) * quantity_to_sell);
1921
1931
  return {
1922
1932
  risk,
1923
1933
  risk_reward: this.config.risk_reward,
@@ -1929,7 +1939,8 @@ class Strategy {
1929
1939
  stop_quantity: quantity_to_sell,
1930
1940
  re_entry_quantity: remaining_quantity,
1931
1941
  initial_pnl: this.pnl(kind),
1932
- tp: second_payload.entry
1942
+ tp: second_payload.entry,
1943
+ incurred_loss
1933
1944
  },
1934
1945
  [reverse_kind]: {
1935
1946
  avg_entry: reverse_avg.entry,
@@ -1937,32 +1948,48 @@ class Strategy {
1937
1948
  pnl: reverse_pnl,
1938
1949
  tp: second_payload.stop,
1939
1950
  re_entry_quantity: remaining_quantity,
1940
- initial_pnl: this.pnl(reverse_kind)
1951
+ initial_pnl: this.pnl(reverse_kind),
1952
+ remaining_quantity: this.to_df(reverse_avg.quantity - sell_quantity)
1941
1953
  },
1942
1954
  last_entry: rest.last_value.entry,
1943
- first_entry: entries.at(-1).entry,
1944
- threshold
1955
+ first_entry: entries.at(-1)?.entry,
1956
+ threshold,
1957
+ spread: Math.abs(avg.entry - reverse_avg.entry),
1958
+ gap_loss: to_f(Math.abs(avg.entry - reverse_avg.entry) * reverse_avg.quantity, "%.2f"),
1959
+ net_profit: incurred_loss + reverse_pnl
1945
1960
  };
1946
1961
  }
1947
1962
  runIterations(payload) {
1948
- const { kind, iterations } = payload;
1963
+ const {
1964
+ kind,
1965
+ iterations,
1966
+ ignore_entries = false,
1967
+ reduce_ratio = 1,
1968
+ sell_factor = 1
1969
+ } = payload;
1949
1970
  const reverse_kind = kind == "long" ? "short" : "long";
1950
1971
  const result = [];
1951
1972
  let position2 = {
1952
1973
  long: this.position.long,
1953
1974
  short: this.position.short
1954
1975
  };
1976
+ let tp_percent_multiplier = 1;
1977
+ let short_tp_factor_multiplier = 1;
1955
1978
  for (let i = 0;i < iterations; i++) {
1956
1979
  const instance = new Strategy({
1957
1980
  long: position2.long,
1958
1981
  short: position2.short,
1959
1982
  config: {
1960
1983
  ...this.config,
1961
- tp_percent: this.config.tp_percent + i * 4
1984
+ tp_percent: this.config.tp_percent * tp_percent_multiplier,
1985
+ short_tp_factor: this.config.short_tp_factor * short_tp_factor_multiplier
1962
1986
  }
1963
1987
  });
1964
1988
  const algorithm = instance.generateGapClosingAlgorithm({
1965
- kind
1989
+ kind,
1990
+ ignore_entries,
1991
+ reduce_ratio,
1992
+ sell_factor
1966
1993
  });
1967
1994
  if (!algorithm) {
1968
1995
  console.log("No algorithm found");
@@ -1974,9 +2001,31 @@ class Strategy {
1974
2001
  entry: algorithm[kind].avg_entry,
1975
2002
  quantity: algorithm[kind].re_entry_quantity
1976
2003
  };
2004
+ let reverse_entry = algorithm[reverse_kind].tp;
2005
+ let reverse_quantity = algorithm[reverse_kind].re_entry_quantity;
2006
+ if (algorithm[reverse_kind].remaining_quantity > 0) {
2007
+ const purchase_to_occur = {
2008
+ price: reverse_entry,
2009
+ quantity: algorithm[reverse_kind].remaining_quantity
2010
+ };
2011
+ const avg = determine_average_entry_and_size([
2012
+ purchase_to_occur,
2013
+ {
2014
+ price: algorithm[reverse_kind].avg_entry,
2015
+ quantity: reverse_quantity - algorithm[reverse_kind].remaining_quantity
2016
+ }
2017
+ ], this.config.global_config.decimal_places, this.config.global_config.price_places);
2018
+ reverse_entry = avg.entry;
2019
+ reverse_quantity = avg.quantity;
2020
+ if (reverse_kind === "short") {
2021
+ short_tp_factor_multiplier = 2;
2022
+ } else {
2023
+ tp_percent_multiplier = 2;
2024
+ }
2025
+ }
1977
2026
  position2[reverse_kind] = {
1978
- entry: algorithm[reverse_kind].tp,
1979
- quantity: algorithm[reverse_kind].re_entry_quantity
2027
+ entry: reverse_entry,
2028
+ quantity: reverse_quantity
1980
2029
  };
1981
2030
  }
1982
2031
  return result;
@@ -2040,8 +2089,8 @@ class Strategy {
2040
2089
  return result;
2041
2090
  }
2042
2091
  generateOppositeTrades(payload) {
2043
- const { kind, risk_factor = 0.5 } = payload;
2044
- const entry = this.position[kind].entry;
2092
+ const { kind, risk_factor = 0.5, avg_entry } = payload;
2093
+ const entry = avg_entry || this.position[kind].entry;
2045
2094
  const stop = this.tp(kind);
2046
2095
  const risk = this.pnl(kind) * risk_factor;
2047
2096
  const risk_reward = getRiskReward({
package/dist/index.cjs CHANGED
@@ -53890,7 +53890,12 @@ class Strategy {
53890
53890
  return this.tp("short");
53891
53891
  }
53892
53892
  generateGapClosingAlgorithm(payload) {
53893
- const { kind } = payload;
53893
+ const {
53894
+ kind,
53895
+ ignore_entries = false,
53896
+ reduce_ratio = 1,
53897
+ sell_factor = 1
53898
+ } = payload;
53894
53899
  const { entry, quantity } = this.position[kind];
53895
53900
  const focus_position = this.position[kind];
53896
53901
  const reverse_kind = kind == "long" ? "short" : "long";
@@ -53917,7 +53922,10 @@ class Strategy {
53917
53922
  if (!app_config) {
53918
53923
  return null;
53919
53924
  }
53920
- const { entries, ...rest } = app_config;
53925
+ let { entries, ...rest } = app_config;
53926
+ if (ignore_entries) {
53927
+ entries = [];
53928
+ }
53921
53929
  const risk = this.to_f(rest.risk_per_trade);
53922
53930
  const adjusted_focus_entries = entries.map((entry2) => {
53923
53931
  let adjusted_price = entry2.price;
@@ -53939,7 +53947,7 @@ class Strategy {
53939
53947
  quantity
53940
53948
  }
53941
53949
  ]), rest.decimal_places, rest.price_places);
53942
- const focus_loss = this.to_f((avg.price - second_payload.stop) * avg.quantity);
53950
+ const focus_loss = this.to_f(Math.abs(avg.price - second_payload.stop) * avg.quantity);
53943
53951
  let below_reverse_entries = kind === "long" ? entries.filter((u) => {
53944
53952
  return u.entry < (reverse_position.entry || focus_position.entry);
53945
53953
  }) : entries.filter((u) => {
@@ -53966,18 +53974,20 @@ class Strategy {
53966
53974
  quantity: reverse_position.quantity
53967
53975
  }
53968
53976
  ]), rest.decimal_places, rest.price_places);
53969
- const reverse_pnl = this.to_f((reverse_avg.price - second_payload.stop) * reverse_avg.quantity);
53977
+ const sell_quantity = this.to_df(reverse_avg.quantity * sell_factor);
53978
+ const reverse_pnl = this.to_f(Math.abs(reverse_avg.price - second_payload.stop) * sell_quantity);
53970
53979
  const fee_to_pay = this.calculate_fee({
53971
53980
  price: avg.entry,
53972
53981
  quantity: avg.quantity
53973
53982
  }) + this.calculate_fee({
53974
53983
  price: reverse_avg.entry,
53975
- quantity: reverse_avg.quantity
53984
+ quantity: sell_quantity
53976
53985
  });
53977
53986
  const net_reverse_pnl = reverse_pnl - fee_to_pay;
53978
- const ratio = net_reverse_pnl / focus_loss;
53987
+ const ratio = net_reverse_pnl * reduce_ratio / focus_loss;
53979
53988
  const quantity_to_sell = this.to_df(ratio * avg.quantity);
53980
53989
  const remaining_quantity = this.to_df(avg.quantity - quantity_to_sell);
53990
+ const incurred_loss = this.to_f((avg.price - second_payload.stop) * quantity_to_sell);
53981
53991
  return {
53982
53992
  risk,
53983
53993
  risk_reward: this.config.risk_reward,
@@ -53989,7 +53999,8 @@ class Strategy {
53989
53999
  stop_quantity: quantity_to_sell,
53990
54000
  re_entry_quantity: remaining_quantity,
53991
54001
  initial_pnl: this.pnl(kind),
53992
- tp: second_payload.entry
54002
+ tp: second_payload.entry,
54003
+ incurred_loss
53993
54004
  },
53994
54005
  [reverse_kind]: {
53995
54006
  avg_entry: reverse_avg.entry,
@@ -53997,32 +54008,48 @@ class Strategy {
53997
54008
  pnl: reverse_pnl,
53998
54009
  tp: second_payload.stop,
53999
54010
  re_entry_quantity: remaining_quantity,
54000
- initial_pnl: this.pnl(reverse_kind)
54011
+ initial_pnl: this.pnl(reverse_kind),
54012
+ remaining_quantity: this.to_df(reverse_avg.quantity - sell_quantity)
54001
54013
  },
54002
54014
  last_entry: rest.last_value.entry,
54003
- first_entry: entries.at(-1).entry,
54004
- threshold
54015
+ first_entry: entries.at(-1)?.entry,
54016
+ threshold,
54017
+ spread: Math.abs(avg.entry - reverse_avg.entry),
54018
+ gap_loss: to_f2(Math.abs(avg.entry - reverse_avg.entry) * reverse_avg.quantity, "%.2f"),
54019
+ net_profit: incurred_loss + reverse_pnl
54005
54020
  };
54006
54021
  }
54007
54022
  runIterations(payload) {
54008
- const { kind, iterations } = payload;
54023
+ const {
54024
+ kind,
54025
+ iterations,
54026
+ ignore_entries = false,
54027
+ reduce_ratio = 1,
54028
+ sell_factor = 1
54029
+ } = payload;
54009
54030
  const reverse_kind = kind == "long" ? "short" : "long";
54010
54031
  const result = [];
54011
54032
  let position2 = {
54012
54033
  long: this.position.long,
54013
54034
  short: this.position.short
54014
54035
  };
54036
+ let tp_percent_multiplier = 1;
54037
+ let short_tp_factor_multiplier = 1;
54015
54038
  for (let i2 = 0;i2 < iterations; i2++) {
54016
54039
  const instance = new Strategy({
54017
54040
  long: position2.long,
54018
54041
  short: position2.short,
54019
54042
  config: {
54020
54043
  ...this.config,
54021
- tp_percent: this.config.tp_percent + i2 * 4
54044
+ tp_percent: this.config.tp_percent * tp_percent_multiplier,
54045
+ short_tp_factor: this.config.short_tp_factor * short_tp_factor_multiplier
54022
54046
  }
54023
54047
  });
54024
54048
  const algorithm = instance.generateGapClosingAlgorithm({
54025
- kind
54049
+ kind,
54050
+ ignore_entries,
54051
+ reduce_ratio,
54052
+ sell_factor
54026
54053
  });
54027
54054
  if (!algorithm) {
54028
54055
  console.log("No algorithm found");
@@ -54034,9 +54061,31 @@ class Strategy {
54034
54061
  entry: algorithm[kind].avg_entry,
54035
54062
  quantity: algorithm[kind].re_entry_quantity
54036
54063
  };
54064
+ let reverse_entry = algorithm[reverse_kind].tp;
54065
+ let reverse_quantity = algorithm[reverse_kind].re_entry_quantity;
54066
+ if (algorithm[reverse_kind].remaining_quantity > 0) {
54067
+ const purchase_to_occur = {
54068
+ price: reverse_entry,
54069
+ quantity: algorithm[reverse_kind].remaining_quantity
54070
+ };
54071
+ const avg = determine_average_entry_and_size([
54072
+ purchase_to_occur,
54073
+ {
54074
+ price: algorithm[reverse_kind].avg_entry,
54075
+ quantity: reverse_quantity - algorithm[reverse_kind].remaining_quantity
54076
+ }
54077
+ ], this.config.global_config.decimal_places, this.config.global_config.price_places);
54078
+ reverse_entry = avg.entry;
54079
+ reverse_quantity = avg.quantity;
54080
+ if (reverse_kind === "short") {
54081
+ short_tp_factor_multiplier = 2;
54082
+ } else {
54083
+ tp_percent_multiplier = 2;
54084
+ }
54085
+ }
54037
54086
  position2[reverse_kind] = {
54038
- entry: algorithm[reverse_kind].tp,
54039
- quantity: algorithm[reverse_kind].re_entry_quantity
54087
+ entry: reverse_entry,
54088
+ quantity: reverse_quantity
54040
54089
  };
54041
54090
  }
54042
54091
  return result;
@@ -54100,8 +54149,8 @@ class Strategy {
54100
54149
  return result;
54101
54150
  }
54102
54151
  generateOppositeTrades(payload) {
54103
- const { kind, risk_factor = 0.5 } = payload;
54104
- const entry = this.position[kind].entry;
54152
+ const { kind, risk_factor = 0.5, avg_entry } = payload;
54153
+ const entry = avg_entry || this.position[kind].entry;
54105
54154
  const stop = this.tp(kind);
54106
54155
  const risk = this.pnl(kind) * risk_factor;
54107
54156
  const risk_reward = getRiskReward({
@@ -57669,6 +57718,9 @@ class ExchangeAccount {
57669
57718
  if (threshold_qty > 0 && track_position.quantity >= threshold_qty) {
57670
57719
  should_place_order = true;
57671
57720
  }
57721
+ if (focus_position.quantity === 0) {
57722
+ should_place_order = true;
57723
+ }
57672
57724
  if (track_position.quantity !== focus_position.quantity && focus_position.quantity < track_position.quantity && should_place_order) {
57673
57725
  const remaining_quantity = Math.abs(track_position.quantity - focus_position.quantity);
57674
57726
  await this.placeMarketOrder({
package/dist/index.d.ts CHANGED
@@ -564,6 +564,9 @@ export declare class Strategy {
564
564
  get short_tp(): number;
565
565
  generateGapClosingAlgorithm(payload: {
566
566
  kind: "long" | "short";
567
+ ignore_entries?: boolean;
568
+ reduce_ratio?: number;
569
+ sell_factor?: number;
567
570
  }): {
568
571
  [x: string]: any;
569
572
  risk: number;
@@ -571,11 +574,17 @@ export declare class Strategy {
571
574
  last_entry: any;
572
575
  first_entry: any;
573
576
  threshold: any;
577
+ spread: number;
578
+ gap_loss: number;
579
+ net_profit: number;
574
580
  };
575
581
  runIterations(payload: {
576
582
  kind: "long" | "short";
577
583
  iterations: number;
578
584
  risk_reward?: number;
585
+ ignore_entries?: boolean;
586
+ reduce_ratio?: number;
587
+ sell_factor?: number;
579
588
  }): {
580
589
  [x: string]: any;
581
590
  risk: number;
@@ -583,6 +592,9 @@ export declare class Strategy {
583
592
  last_entry: any;
584
593
  first_entry: any;
585
594
  threshold: any;
595
+ spread: number;
596
+ gap_loss: number;
597
+ net_profit: number;
586
598
  }[];
587
599
  getPositionAfterTp(payload: {
588
600
  kind: "long" | "short";
@@ -632,6 +644,7 @@ export declare class Strategy {
632
644
  generateOppositeTrades(payload: {
633
645
  kind: "long" | "short";
634
646
  risk_factor?: number;
647
+ avg_entry?: number;
635
648
  }): {
636
649
  avg: {
637
650
  entry: number;
@@ -1462,6 +1475,9 @@ declare class ExchangeAccount$1 {
1462
1475
  last_entry: any;
1463
1476
  first_entry: any;
1464
1477
  threshold: any;
1478
+ spread: number;
1479
+ gap_loss: number;
1480
+ net_profit: number;
1465
1481
  }[]>;
1466
1482
  getCurrentRun(payload: {
1467
1483
  symbol: string;