@gbozee/ultimate 0.0.2-152 → 0.0.2-154

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.
@@ -278,6 +278,100 @@ export type GlobalConfig = {
278
278
  reverse_factor: number;
279
279
  leverage?: number;
280
280
  };
281
+ export interface BaseSystemFields {
282
+ id: string;
283
+ created: string;
284
+ updated: string;
285
+ }
286
+ export interface ExchangeAccount extends BaseSystemFields {
287
+ exchange: "binance" | "bybit";
288
+ owner: string;
289
+ email?: string;
290
+ user?: string;
291
+ usdt?: number;
292
+ usdc?: number;
293
+ proxy?: string;
294
+ bullish?: boolean;
295
+ bearish?: boolean;
296
+ movePercent?: number;
297
+ totalRisk?: number;
298
+ max_non_essential?: number;
299
+ profit_percent?: number;
300
+ risk_reward?: number;
301
+ exclude_coins?: {
302
+ bullish?: string[];
303
+ };
304
+ include_delisted?: boolean;
305
+ }
306
+ export interface ScheduledTrade extends BaseSystemFields {
307
+ symbol: string;
308
+ account: string;
309
+ profit?: number;
310
+ risk?: number;
311
+ entry?: number;
312
+ stop?: number;
313
+ risk_reward?: number;
314
+ profit_percent?: number;
315
+ place_tp?: boolean;
316
+ kind?: "long" | "short";
317
+ follow?: boolean | 1 | 0;
318
+ reduce_ratio?: number;
319
+ sell_ratio?: number;
320
+ threshold_qty?: number;
321
+ pause_tp?: boolean;
322
+ stop_percent?: number;
323
+ kelly?: {
324
+ use_kelly?: boolean;
325
+ kelly_confidence_factor?: number;
326
+ kelly_minimum_risk?: number;
327
+ kelly_prediction_model?: "exponential" | "normal" | "uniform";
328
+ };
329
+ }
330
+ interface Proxy$1 extends BaseSystemFields {
331
+ ip_address?: string;
332
+ type?: "http" | "socks5";
333
+ }
334
+ export interface PositionsView {
335
+ id: string;
336
+ symbol?: any;
337
+ entry?: any;
338
+ quantity?: any;
339
+ take_profit?: any;
340
+ account?: any;
341
+ kind?: any;
342
+ target_pnl?: number;
343
+ liquidation?: number;
344
+ avg_price?: number;
345
+ avg_qty?: number;
346
+ next_order?: number;
347
+ last_order?: number;
348
+ config?: any;
349
+ stop_loss?: {
350
+ price: number;
351
+ quantity: number;
352
+ };
353
+ stop_pnl?: any;
354
+ leverage?: any;
355
+ avg_liquidation?: any;
356
+ balance?: any;
357
+ reduce_ratio?: number;
358
+ sell_ratio?: number;
359
+ threshold_qty?: number;
360
+ follow?: boolean | 1 | 0;
361
+ current_price?: number;
362
+ usd_balance?: number;
363
+ tp?: {
364
+ price: number;
365
+ quantity: number;
366
+ };
367
+ next_risk?: number;
368
+ proxy?: string;
369
+ expand?: {
370
+ p_account?: ExchangeAccount;
371
+ b_config?: ScheduledTrade;
372
+ proxy?: Proxy$1;
373
+ };
374
+ }
281
375
  export type AppConfig = {
282
376
  fee: number;
283
377
  risk_per_trade: number;
@@ -440,7 +534,13 @@ export declare function generateOptimumAppConfig(config: GlobalConfig, payload:
440
534
  quantity: number;
441
535
  kind: "long" | "short";
442
536
  }): AppConfig | null;
443
- export declare function determineOptimumReward(app_config: AppConfig, increase?: boolean, low_range?: number, high_range?: number): number | {
537
+ export declare function determineOptimumReward(payload: {
538
+ app_config: AppConfig;
539
+ increase?: boolean;
540
+ low_range?: number;
541
+ high_range?: number;
542
+ target_loss?: number;
543
+ }): number | {
444
544
  result: any[];
445
545
  value: number;
446
546
  total: number;
@@ -476,6 +576,7 @@ export declare function computeRiskReward(payload: {
476
576
  entry: number;
477
577
  stop: number;
478
578
  risk_per_trade: number;
579
+ target_loss?: number;
479
580
  }): number | {
480
581
  result: any[];
481
582
  value: number;
@@ -660,6 +761,38 @@ export declare function determineCompoundLongTrade(payload: {
660
761
  result: any;
661
762
  short_max_size: any;
662
763
  };
764
+ export declare function generateOppositeTradeConfig(payload: {
765
+ kind: "long" | "short";
766
+ entry: number;
767
+ quantity: number;
768
+ target_pnl: number;
769
+ global_config: GlobalConfig;
770
+ ratio?: number;
771
+ }): {
772
+ entry: number;
773
+ stop: number;
774
+ risk: number;
775
+ risk_reward: number | {
776
+ result: any[];
777
+ value: number;
778
+ total: number;
779
+ risk_per_trade: number;
780
+ max: number;
781
+ min: number;
782
+ neg_pnl: any;
783
+ entry: any;
784
+ };
785
+ };
786
+ export declare function constructAppConfig(payload: {
787
+ account: PositionsView;
788
+ global_config: GlobalConfig;
789
+ kelly_config?: {
790
+ use_kelly: boolean;
791
+ kelly_confidence_factor: number;
792
+ kelly_minimum_risk: number;
793
+ kelly_prediction_model: string;
794
+ };
795
+ }): AppConfig;
663
796
  export type StrategyPosition = {
664
797
  entry: number;
665
798
  quantity: number;
@@ -1928,7 +1928,14 @@ function generateOptimumAppConfig(config, payload, position2) {
1928
1928
  });
1929
1929
  return best_app_config;
1930
1930
  }
1931
- function determineOptimumReward(app_config, increase = true, low_range = 30, high_range = 199) {
1931
+ function determineOptimumReward(payload) {
1932
+ const {
1933
+ app_config,
1934
+ increase = true,
1935
+ low_range = 1,
1936
+ high_range = 199,
1937
+ target_loss
1938
+ } = payload;
1932
1939
  const criterion = app_config.strategy || "quantity";
1933
1940
  const risk_rewards = createArray(low_range, high_range, 1);
1934
1941
  let func = risk_rewards.map((trade_no) => {
@@ -1968,10 +1975,33 @@ function determineOptimumReward(app_config, increase = true, low_range = 30, hig
1968
1975
  entry
1969
1976
  };
1970
1977
  });
1971
- func = func.filter((r) => Boolean(r)).filter((r) => {
1972
- let foundIndex = r?.result.findIndex((e) => e.quantity === r.max);
1973
- return criterion === "quantity" ? foundIndex === 0 : true;
1974
- });
1978
+ func = func.filter((r) => Boolean(r));
1979
+ if (target_loss === undefined) {
1980
+ func = func.filter((r) => {
1981
+ let foundIndex = r?.result.findIndex((e) => e.quantity === r.max);
1982
+ return criterion === "quantity" ? foundIndex === 0 : true;
1983
+ });
1984
+ }
1985
+ if (target_loss !== undefined) {
1986
+ const validResults = func.filter((r) => Math.abs(r.neg_pnl) <= target_loss);
1987
+ if (validResults.length > 0) {
1988
+ validResults.sort((a, b) => {
1989
+ const diffA = target_loss - Math.abs(a.neg_pnl);
1990
+ const diffB = target_loss - Math.abs(b.neg_pnl);
1991
+ return diffA - diffB;
1992
+ });
1993
+ if (app_config.raw) {
1994
+ return validResults[0];
1995
+ }
1996
+ return validResults[0]?.value;
1997
+ } else {
1998
+ func.sort((a, b) => Math.abs(a.neg_pnl) - Math.abs(b.neg_pnl));
1999
+ if (app_config.raw) {
2000
+ return func[0];
2001
+ }
2002
+ return func[0]?.value;
2003
+ }
2004
+ }
1975
2005
  const highest = criterion === "quantity" ? Math.max(...func.map((o) => o.max)) : Math.min(...func.map((o) => o.entry));
1976
2006
  const key = criterion === "quantity" ? "max" : "entry";
1977
2007
  const index = findIndexByCondition(func, app_config.kind, (x) => x[key] == highest, criterion);
@@ -2083,13 +2113,13 @@ function determineOptimumRisk(config, payload, params) {
2083
2113
  };
2084
2114
  }
2085
2115
  function computeRiskReward(payload) {
2086
- const { app_config, entry, stop, risk_per_trade } = payload;
2116
+ const { app_config, entry, stop, risk_per_trade, target_loss } = payload;
2087
2117
  const kind = entry > stop ? "long" : "short";
2088
2118
  app_config.kind = kind;
2089
2119
  app_config.entry = entry;
2090
2120
  app_config.stop = stop;
2091
2121
  app_config.risk_per_trade = risk_per_trade;
2092
- const result = determineOptimumReward(app_config);
2122
+ const result = determineOptimumReward({ app_config, target_loss });
2093
2123
  return result;
2094
2124
  }
2095
2125
  function getRiskReward(payload) {
@@ -2424,6 +2454,67 @@ function determineCompoundLongTrade(payload) {
2424
2454
  short_max_size
2425
2455
  };
2426
2456
  }
2457
+ function generateOppositeTradeConfig(payload) {
2458
+ const {
2459
+ kind,
2460
+ entry,
2461
+ quantity,
2462
+ target_pnl,
2463
+ ratio = 0.5,
2464
+ global_config
2465
+ } = payload;
2466
+ const diff = target_pnl / quantity;
2467
+ const tp = kind === "long" ? entry + diff : entry - diff;
2468
+ const stop = kind === "long" ? entry - diff : entry + diff;
2469
+ const opposite_pnl = target_pnl * ratio;
2470
+ const app_config = constructAppConfig({
2471
+ account: {
2472
+ expand: {
2473
+ b_config: {
2474
+ entry,
2475
+ stop,
2476
+ symbol: global_config.symbol,
2477
+ risk: target_pnl
2478
+ }
2479
+ }
2480
+ },
2481
+ global_config
2482
+ });
2483
+ const risk_reward = computeRiskReward({
2484
+ app_config,
2485
+ entry: stop,
2486
+ stop: tp,
2487
+ risk_per_trade: opposite_pnl,
2488
+ target_loss: opposite_pnl
2489
+ });
2490
+ return {
2491
+ entry: to_f(stop, global_config.price_places),
2492
+ stop: to_f(tp, global_config.price_places),
2493
+ risk: to_f(opposite_pnl, "%.2f"),
2494
+ risk_reward
2495
+ };
2496
+ }
2497
+ function constructAppConfig(payload) {
2498
+ const { account, global_config, kelly_config } = payload;
2499
+ const config = account.expand?.b_config;
2500
+ if (!config) {
2501
+ return null;
2502
+ }
2503
+ const kelly = config.kelly;
2504
+ const options = {
2505
+ entry: config?.entry,
2506
+ stop: config?.stop,
2507
+ risk_reward: config?.risk_reward,
2508
+ risk: config?.risk,
2509
+ symbol: account.symbol,
2510
+ use_kelly: kelly_config?.use_kelly ?? kelly?.use_kelly,
2511
+ kelly_confidence_factor: kelly_config?.kelly_confidence_factor ?? kelly?.kelly_confidence_factor,
2512
+ kelly_minimum_risk: kelly_config?.kelly_minimum_risk ?? kelly?.kelly_minimum_risk,
2513
+ kelly_prediction_model: kelly_config?.kelly_prediction_model ?? kelly?.kelly_prediction_model
2514
+ };
2515
+ const appConfig = buildAppConfig(global_config, options);
2516
+ return appConfig;
2517
+ }
2427
2518
  // src/helpers/strategy.ts
2428
2519
  class Strategy {
2429
2520
  position;
@@ -2942,6 +3033,7 @@ export {
2942
3033
  getDecimalPlaces,
2943
3034
  generate_config_params,
2944
3035
  generateOptimumAppConfig,
3036
+ generateOppositeTradeConfig,
2945
3037
  generateGapTp,
2946
3038
  formatPrice,
2947
3039
  fibonacci_analysis,
@@ -2960,6 +3052,7 @@ export {
2960
3052
  determineCompoundLongTrade,
2961
3053
  createGapPairs,
2962
3054
  createArray,
3055
+ constructAppConfig,
2963
3056
  computeTotalAverageForEachTrade,
2964
3057
  computeSellZones,
2965
3058
  computeRiskReward,
package/dist/index.cjs CHANGED
@@ -41955,6 +41955,7 @@ __export(exports_src, {
41955
41955
  getHedgeZone: () => getHedgeZone,
41956
41956
  generate_config_params: () => generate_config_params,
41957
41957
  generateOptimumAppConfig: () => generateOptimumAppConfig,
41958
+ generateOppositeTradeConfig: () => generateOppositeTradeConfig,
41958
41959
  generateGapTp: () => generateGapTp,
41959
41960
  exchange_account: () => exports_exchange_account,
41960
41961
  determine_break_even_price: () => determine_break_even_price,
@@ -41966,6 +41967,7 @@ __export(exports_src, {
41966
41967
  determineCompoundLongTrade: () => determineCompoundLongTrade,
41967
41968
  database: () => exports_database,
41968
41969
  createArray: () => createArray,
41970
+ constructAppConfig: () => constructAppConfig,
41969
41971
  computeRiskReward: () => computeRiskReward,
41970
41972
  computeProfitDetail: () => computeProfitDetail,
41971
41973
  buildConfig: () => buildConfig,
@@ -51744,7 +51746,6 @@ class AppDatabase {
51744
51746
  const result = await this.get_exchange_db_instance(account);
51745
51747
  if (result?.expand?.proxy) {
51746
51748
  const { type, ip_address } = result.expand.proxy;
51747
- console.log(type, ip_address);
51748
51749
  if (type === "http") {
51749
51750
  return new import_https_proxy_agent.HttpsProxyAgent(`http://${ip_address}`);
51750
51751
  }
@@ -51792,13 +51793,13 @@ class AppDatabase {
51792
51793
  table: "positions_view",
51793
51794
  params: {
51794
51795
  filter: `symbol:lower="${symbol.toLowerCase()}" && account:lower="${account.owner.toLowerCase()} ${account.exchange.toLowerCase()}"`,
51795
- expand: "config, account_strategy, p_account"
51796
+ expand: "config, account_strategy, p_account, proxy"
51796
51797
  }
51797
51798
  } : {
51798
51799
  table: "positions",
51799
51800
  params: {
51800
51801
  filter: `symbol:lower="${symbol.toLowerCase()}" && account.owner:lower="${account.owner.toLowerCase()}" && account.exchange:lower="${account.exchange.toLowerCase()}"`,
51801
- expand: "account,config"
51802
+ expand: "account,config, proxy"
51802
51803
  }
51803
51804
  };
51804
51805
  if (custom_filter) {
@@ -54328,7 +54329,14 @@ function generateOptimumAppConfig(config2, payload, position2) {
54328
54329
  });
54329
54330
  return best_app_config;
54330
54331
  }
54331
- function determineOptimumReward(app_config, increase = true, low_range = 30, high_range = 199) {
54332
+ function determineOptimumReward(payload) {
54333
+ const {
54334
+ app_config,
54335
+ increase = true,
54336
+ low_range = 1,
54337
+ high_range = 199,
54338
+ target_loss
54339
+ } = payload;
54332
54340
  const criterion = app_config.strategy || "quantity";
54333
54341
  const risk_rewards = createArray(low_range, high_range, 1);
54334
54342
  let func = risk_rewards.map((trade_no) => {
@@ -54368,10 +54376,33 @@ function determineOptimumReward(app_config, increase = true, low_range = 30, hig
54368
54376
  entry
54369
54377
  };
54370
54378
  });
54371
- func = func.filter((r2) => Boolean(r2)).filter((r2) => {
54372
- let foundIndex = r2?.result.findIndex((e2) => e2.quantity === r2.max);
54373
- return criterion === "quantity" ? foundIndex === 0 : true;
54374
- });
54379
+ func = func.filter((r2) => Boolean(r2));
54380
+ if (target_loss === undefined) {
54381
+ func = func.filter((r2) => {
54382
+ let foundIndex = r2?.result.findIndex((e2) => e2.quantity === r2.max);
54383
+ return criterion === "quantity" ? foundIndex === 0 : true;
54384
+ });
54385
+ }
54386
+ if (target_loss !== undefined) {
54387
+ const validResults = func.filter((r2) => Math.abs(r2.neg_pnl) <= target_loss);
54388
+ if (validResults.length > 0) {
54389
+ validResults.sort((a, b) => {
54390
+ const diffA = target_loss - Math.abs(a.neg_pnl);
54391
+ const diffB = target_loss - Math.abs(b.neg_pnl);
54392
+ return diffA - diffB;
54393
+ });
54394
+ if (app_config.raw) {
54395
+ return validResults[0];
54396
+ }
54397
+ return validResults[0]?.value;
54398
+ } else {
54399
+ func.sort((a, b) => Math.abs(a.neg_pnl) - Math.abs(b.neg_pnl));
54400
+ if (app_config.raw) {
54401
+ return func[0];
54402
+ }
54403
+ return func[0]?.value;
54404
+ }
54405
+ }
54375
54406
  const highest = criterion === "quantity" ? Math.max(...func.map((o) => o.max)) : Math.min(...func.map((o) => o.entry));
54376
54407
  const key = criterion === "quantity" ? "max" : "entry";
54377
54408
  const index = findIndexByCondition(func, app_config.kind, (x) => x[key] == highest, criterion);
@@ -54483,13 +54514,13 @@ function determineOptimumRisk(config2, payload, params) {
54483
54514
  };
54484
54515
  }
54485
54516
  function computeRiskReward(payload) {
54486
- const { app_config, entry, stop, risk_per_trade } = payload;
54517
+ const { app_config, entry, stop, risk_per_trade, target_loss } = payload;
54487
54518
  const kind = entry > stop ? "long" : "short";
54488
54519
  app_config.kind = kind;
54489
54520
  app_config.entry = entry;
54490
54521
  app_config.stop = stop;
54491
54522
  app_config.risk_per_trade = risk_per_trade;
54492
- const result = determineOptimumReward(app_config);
54523
+ const result = determineOptimumReward({ app_config, target_loss });
54493
54524
  return result;
54494
54525
  }
54495
54526
  function getRiskReward(payload) {
@@ -54824,6 +54855,67 @@ function determineCompoundLongTrade(payload) {
54824
54855
  short_max_size
54825
54856
  };
54826
54857
  }
54858
+ function generateOppositeTradeConfig(payload) {
54859
+ const {
54860
+ kind,
54861
+ entry,
54862
+ quantity,
54863
+ target_pnl,
54864
+ ratio = 0.5,
54865
+ global_config
54866
+ } = payload;
54867
+ const diff = target_pnl / quantity;
54868
+ const tp = kind === "long" ? entry + diff : entry - diff;
54869
+ const stop = kind === "long" ? entry - diff : entry + diff;
54870
+ const opposite_pnl = target_pnl * ratio;
54871
+ const app_config = constructAppConfig({
54872
+ account: {
54873
+ expand: {
54874
+ b_config: {
54875
+ entry,
54876
+ stop,
54877
+ symbol: global_config.symbol,
54878
+ risk: target_pnl
54879
+ }
54880
+ }
54881
+ },
54882
+ global_config
54883
+ });
54884
+ const risk_reward = computeRiskReward({
54885
+ app_config,
54886
+ entry: stop,
54887
+ stop: tp,
54888
+ risk_per_trade: opposite_pnl,
54889
+ target_loss: opposite_pnl
54890
+ });
54891
+ return {
54892
+ entry: to_f(stop, global_config.price_places),
54893
+ stop: to_f(tp, global_config.price_places),
54894
+ risk: to_f(opposite_pnl, "%.2f"),
54895
+ risk_reward
54896
+ };
54897
+ }
54898
+ function constructAppConfig(payload) {
54899
+ const { account, global_config, kelly_config } = payload;
54900
+ const config2 = account.expand?.b_config;
54901
+ if (!config2) {
54902
+ return null;
54903
+ }
54904
+ const kelly = config2.kelly;
54905
+ const options = {
54906
+ entry: config2?.entry,
54907
+ stop: config2?.stop,
54908
+ risk_reward: config2?.risk_reward,
54909
+ risk: config2?.risk,
54910
+ symbol: account.symbol,
54911
+ use_kelly: kelly_config?.use_kelly ?? kelly?.use_kelly,
54912
+ kelly_confidence_factor: kelly_config?.kelly_confidence_factor ?? kelly?.kelly_confidence_factor,
54913
+ kelly_minimum_risk: kelly_config?.kelly_minimum_risk ?? kelly?.kelly_minimum_risk,
54914
+ kelly_prediction_model: kelly_config?.kelly_prediction_model ?? kelly?.kelly_prediction_model
54915
+ };
54916
+ const appConfig = buildAppConfig(global_config, options);
54917
+ return appConfig;
54918
+ }
54827
54919
  // src/helpers/strategy.ts
54828
54920
  class Strategy {
54829
54921
  position;
@@ -57745,6 +57837,9 @@ async function reduceMajorPositionEntry(input, accountInfo, trigger2, exchange_i
57745
57837
  }
57746
57838
 
57747
57839
  // src/position.ts
57840
+ var import_https_proxy_agent2 = __toESM(require_dist2());
57841
+ var import_socks_proxy_agent2 = __toESM(require_dist3());
57842
+
57748
57843
  class ExchangePosition {
57749
57844
  exchange;
57750
57845
  symbol_config;
@@ -57758,6 +57853,13 @@ class ExchangePosition {
57758
57853
  this.instance = payload.instance;
57759
57854
  this.exchange_account = payload.exchange_account;
57760
57855
  }
57856
+ async initialize() {
57857
+ const proxy = await this.getProxyForAccount();
57858
+ if (proxy) {
57859
+ this.exchange.client.globalRequestOptions.httpAgent = proxy;
57860
+ this.exchange.client.globalRequestOptions.httpsAgent = proxy;
57861
+ }
57862
+ }
57761
57863
  getInstance() {
57762
57864
  return this.instance;
57763
57865
  }
@@ -57771,6 +57873,20 @@ class ExchangePosition {
57771
57873
  const { p_account } = this.instance.expand;
57772
57874
  return p_account;
57773
57875
  }
57876
+ async getProxyForAccount() {
57877
+ if (this.instance.expand.proxy) {
57878
+ const result = this.instance.expand.proxy;
57879
+ const { type, ip_address } = result;
57880
+ console.log("position", type, ip_address);
57881
+ if (type === "http") {
57882
+ return new import_https_proxy_agent2.HttpsProxyAgent(`http://${ip_address}`);
57883
+ }
57884
+ if (type === "socks5") {
57885
+ return new import_socks_proxy_agent2.SocksProxyAgent(`socks://${ip_address}`);
57886
+ }
57887
+ }
57888
+ return null;
57889
+ }
57774
57890
  async cancelOrders(payload) {
57775
57891
  const { limit, price: _price, raw } = payload;
57776
57892
  if (limit) {
@@ -58597,6 +58713,27 @@ class ExchangePosition {
58597
58713
  }
58598
58714
  return config2;
58599
58715
  }
58716
+ getOppositeConfig(payload) {
58717
+ return generateOppositeTradeConfig({
58718
+ kind: this.kind,
58719
+ entry: this.instance.entry,
58720
+ quantity: this.instance.quantity,
58721
+ target_pnl: this.instance.target_pnl,
58722
+ global_config: this.symbol_config,
58723
+ ratio: payload.ratio
58724
+ });
58725
+ }
58726
+ async getOptimumRiskReward() {
58727
+ const app_config = await this.tradeConfig({});
58728
+ const risk_reward = computeRiskReward({
58729
+ app_config,
58730
+ entry: app_config.entry,
58731
+ stop: app_config.stop,
58732
+ risk_per_trade: app_config.risk_per_trade,
58733
+ target_loss: app_config.risk_per_trade
58734
+ });
58735
+ return risk_reward;
58736
+ }
58600
58737
  }
58601
58738
 
58602
58739
  // src/exchange-account.ts
@@ -58669,6 +58806,7 @@ class ExchangeAccount {
58669
58806
  app_db: this.app_db,
58670
58807
  without_view: raw_positions.find((x) => x.kind === "long")
58671
58808
  });
58809
+ await this.long_position.initialize();
58672
58810
  this.short_position = new ExchangePosition({
58673
58811
  symbol_config,
58674
58812
  exchange: this.exchange,
@@ -58677,6 +58815,7 @@ class ExchangeAccount {
58677
58815
  app_db: this.app_db,
58678
58816
  without_view: raw_positions.find((x) => x.kind === "short")
58679
58817
  });
58818
+ await this.short_position.initialize();
58680
58819
  return payload.kind === "long" ? this.long_position : this.short_position;
58681
58820
  }
58682
58821
  async getActiveAccount(payload) {
@@ -60036,6 +60175,7 @@ class ExchangeAccount {
60036
60175
  return;
60037
60176
  }
60038
60177
  const kind = strategy2.kind;
60178
+ const reward_factor = strategy2.reward_factor;
60039
60179
  const { entries, last_value, ...app_config } = await this.tradeConfig({
60040
60180
  symbol,
60041
60181
  kind
@@ -60057,6 +60197,36 @@ class ExchangeAccount {
60057
60197
  });
60058
60198
  }
60059
60199
  console.log("Checking if focus position has quantity for ", symbol, kind);
60200
+ const focusPosition = await this.getFocusPosition({
60201
+ symbol,
60202
+ kind
60203
+ });
60204
+ const reversePosition = await this.getFocusPosition({
60205
+ symbol,
60206
+ kind: kind === "long" ? "short" : "long"
60207
+ });
60208
+ const opposite_config = focusPosition.getOppositeConfig({
60209
+ ratio: reward_factor
60210
+ });
60211
+ const reverse_config = await reversePosition.getConfig();
60212
+ if ((reverse_config.entry !== opposite_config.entry || reverse_config.stop !== opposite_config.stop || reverse_config.risk !== opposite_config.risk || reverse_config.risk_reward !== opposite_config.risk_reward) && focusPosition.getInstance().quantity > 0) {
60213
+ console.log("Updating reverse config for ", symbol, kind, "with opposite config", opposite_config);
60214
+ await reversePosition.getConfig({
60215
+ params: {
60216
+ entry: opposite_config.entry,
60217
+ stop: opposite_config.stop,
60218
+ risk: opposite_config.risk,
60219
+ risk_reward: opposite_config.risk_reward
60220
+ }
60221
+ });
60222
+ console.log("Placing trade for ", symbol, reversePosition.kind);
60223
+ await reversePosition.placeTrade({
60224
+ ignore_config: true,
60225
+ limit: true,
60226
+ place: true
60227
+ });
60228
+ }
60229
+ console.log("Opposite config for ", symbol, kind, opposite_config);
60060
60230
  return {
60061
60231
  config_details: {
60062
60232
  app_config,