@gbozee/ultimate 0.0.2-174 → 0.0.2-177

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.
@@ -61401,7 +61401,7 @@ class AppDatabase {
61401
61401
  table: "positions_view",
61402
61402
  params: {
61403
61403
  filter: `symbol:lower="${symbol.toLowerCase()}" && p_account.owner:lower="${account.owner.toLowerCase()}" && p_account.exchange:lower="${account.exchange.toLowerCase()}"`,
61404
- expand: "b_config, account_strategy, p_account, proxy"
61404
+ expand: "b_config, account_strategy, p_account, proxy, compound_instance.ref,support"
61405
61405
  }
61406
61406
  } : {
61407
61407
  table: "positions",
@@ -62211,11 +62211,169 @@ class AppDatabase {
62211
62211
  parent: config_id
62212
62212
  });
62213
62213
  }
62214
+ async getCompoundInstance(payload) {
62215
+ const { position } = payload;
62216
+ const found = await this.pb.collection("compound_instances").getFullList({
62217
+ filter: `position.id = "${position.id}"`,
62218
+ expand: `ref`
62219
+ });
62220
+ if (found.length == 0) {
62221
+ return;
62222
+ }
62223
+ const item = found[0];
62224
+ return item;
62225
+ }
62226
+ async getSupportTable(payload) {
62227
+ const { symbol, kind } = payload;
62228
+ const found = await this.pb.collection("support_table").getFullList({
62229
+ filter: `symbol = "${symbol}" && kind = "${kind}"`
62230
+ });
62231
+ if (found.length === 0) {
62232
+ return;
62233
+ }
62234
+ const item = found[0];
62235
+ return item;
62236
+ }
62237
+ async updateCompoundInstance(payload) {
62238
+ const { id, params } = payload;
62239
+ return await this.pb.collection("compound_instances").update(id, params);
62240
+ }
62214
62241
  }
62215
62242
 
62216
62243
  // src/exchanges/binance/index.ts
62217
62244
  var import_binance = __toESM(require_lib2());
62218
62245
 
62246
+ // src/helpers/distributions.ts
62247
+ function generateArithmetic(payload) {
62248
+ const { margin_range, risk_reward, kind, price_places = "%.1f" } = payload;
62249
+ const difference = Math.abs(margin_range[1] - margin_range[0]);
62250
+ const spread = difference / risk_reward;
62251
+ return Array.from({ length: risk_reward + 1 }, (_, i2) => {
62252
+ const price = kind === "long" ? margin_range[1] - spread * i2 : margin_range[0] + spread * i2;
62253
+ return to_f(price, price_places);
62254
+ });
62255
+ }
62256
+ function generateGeometric(payload) {
62257
+ const { margin_range, risk_reward, kind, price_places = "%.1f", percent_change } = payload;
62258
+ const effectivePercentChange = percent_change ?? Math.abs(margin_range[1] / margin_range[0] - 1) / risk_reward;
62259
+ return Array.from({ length: risk_reward + 1 }, (_, i2) => {
62260
+ const price = kind === "long" ? margin_range[1] * Math.pow(1 - effectivePercentChange, i2) : margin_range[0] * Math.pow(1 + effectivePercentChange, i2);
62261
+ return to_f(price, price_places);
62262
+ });
62263
+ }
62264
+ function approximateInverseNormal(p) {
62265
+ p = Math.max(0.0001, Math.min(0.9999, p));
62266
+ if (p < 0.5) {
62267
+ const t2 = Math.sqrt(-2 * Math.log(p));
62268
+ const c0 = 2.515517, c1 = 0.802853, c2 = 0.010328;
62269
+ const d1 = 1.432788, d2 = 0.189269, d3 = 0.001308;
62270
+ return -(t2 - (c0 + c1 * t2 + c2 * t2 * t2) / (1 + d1 * t2 + d2 * t2 * t2 + d3 * t2 * t2 * t2));
62271
+ } else {
62272
+ const t2 = Math.sqrt(-2 * Math.log(1 - p));
62273
+ const c0 = 2.515517, c1 = 0.802853, c2 = 0.010328;
62274
+ const d1 = 1.432788, d2 = 0.189269, d3 = 0.001308;
62275
+ return t2 - (c0 + c1 * t2 + c2 * t2 * t2) / (1 + d1 * t2 + d2 * t2 * t2 + d3 * t2 * t2 * t2);
62276
+ }
62277
+ }
62278
+ function generateNormal(payload) {
62279
+ const { margin_range, risk_reward, kind, price_places = "%.1f", stdDevFactor = 6 } = payload;
62280
+ const mean = (margin_range[0] + margin_range[1]) / 2;
62281
+ const stdDev = Math.abs(margin_range[1] - margin_range[0]) / stdDevFactor;
62282
+ const skew = kind === "long" ? -0.2 : 0.2;
62283
+ const adjustedMean = mean + stdDev * skew;
62284
+ const entries = Array.from({ length: risk_reward + 1 }, (_, i2) => {
62285
+ const p = (i2 + 0.5) / (risk_reward + 1);
62286
+ const z3 = approximateInverseNormal(p);
62287
+ let price = adjustedMean + stdDev * z3;
62288
+ price = Math.max(margin_range[0], Math.min(margin_range[1], price));
62289
+ return to_f(price, price_places);
62290
+ });
62291
+ return entries.sort((a, b) => a - b);
62292
+ }
62293
+ function generateExponential(payload) {
62294
+ const { margin_range, risk_reward, kind, price_places = "%.1f", lambda } = payload;
62295
+ const range = Math.abs(margin_range[1] - margin_range[0]);
62296
+ const effectiveLambda = lambda || 2.5;
62297
+ return Array.from({ length: risk_reward + 1 }, (_, i2) => {
62298
+ const t2 = i2 / risk_reward;
62299
+ const exponentialProgress = 1 - Math.exp(-effectiveLambda * t2);
62300
+ const price = kind === "long" ? margin_range[1] - range * exponentialProgress : margin_range[0] + range * exponentialProgress;
62301
+ return to_f(price, price_places);
62302
+ });
62303
+ }
62304
+ function generateInverseExponential(payload) {
62305
+ const { margin_range, risk_reward, kind, price_places = "%.1f", curveFactor = 2 } = payload;
62306
+ const range = Math.abs(margin_range[1] - margin_range[0]);
62307
+ return Array.from({ length: risk_reward + 1 }, (_, i2) => {
62308
+ const t2 = i2 / risk_reward;
62309
+ const progress = (Math.exp(curveFactor * t2) - 1) / (Math.exp(curveFactor) - 1);
62310
+ const price = kind === "long" ? margin_range[1] - range * progress : margin_range[0] + range * progress;
62311
+ return to_f(price, price_places);
62312
+ });
62313
+ }
62314
+ function getEntries(params) {
62315
+ const {
62316
+ kind,
62317
+ distribution,
62318
+ margin_range,
62319
+ risk_reward,
62320
+ price_places = "%.1f",
62321
+ distribution_params = {}
62322
+ } = params;
62323
+ let entries = [];
62324
+ switch (distribution) {
62325
+ case "arithmetic":
62326
+ entries = generateArithmetic({
62327
+ margin_range,
62328
+ risk_reward,
62329
+ kind,
62330
+ price_places,
62331
+ percent_change: distribution_params.curveFactor
62332
+ });
62333
+ break;
62334
+ case "geometric":
62335
+ entries = generateGeometric({
62336
+ margin_range,
62337
+ risk_reward,
62338
+ kind,
62339
+ price_places,
62340
+ percent_change: distribution_params.curveFactor
62341
+ });
62342
+ break;
62343
+ case "normal":
62344
+ entries = generateNormal({
62345
+ margin_range,
62346
+ risk_reward,
62347
+ kind,
62348
+ price_places,
62349
+ stdDevFactor: distribution_params.stdDevFactor
62350
+ });
62351
+ break;
62352
+ case "exponential":
62353
+ entries = generateExponential({
62354
+ margin_range,
62355
+ risk_reward,
62356
+ kind,
62357
+ price_places,
62358
+ lambda: distribution_params.lambda
62359
+ });
62360
+ break;
62361
+ case "inverse-exponential":
62362
+ entries = generateInverseExponential({
62363
+ margin_range,
62364
+ risk_reward,
62365
+ kind,
62366
+ price_places,
62367
+ curveFactor: distribution_params.curveFactor
62368
+ });
62369
+ break;
62370
+ default:
62371
+ throw new Error(`Unknown distribution type: ${distribution}`);
62372
+ }
62373
+ return entries.sort((a, b) => a - b);
62374
+ }
62375
+ var distributions_default = getEntries;
62376
+
62219
62377
  // src/helpers/optimizations.ts
62220
62378
  function calculateTheoreticalKelly({
62221
62379
  current_entry,
@@ -62485,6 +62643,10 @@ class Signal {
62485
62643
  kelly_minimum_risk = 0.2;
62486
62644
  kelly_func = "theoretical";
62487
62645
  symbol;
62646
+ distribution = {
62647
+ long: "arithmetic",
62648
+ short: "geometric"
62649
+ };
62488
62650
  constructor({
62489
62651
  focus,
62490
62652
  symbol,
@@ -62511,8 +62673,12 @@ class Signal {
62511
62673
  kelly_prediction_model = "exponential",
62512
62674
  kelly_confidence_factor = 0.6,
62513
62675
  kelly_minimum_risk = 0.2,
62514
- kelly_func = "theoretical"
62676
+ kelly_func = "theoretical",
62677
+ full_distribution
62515
62678
  }) {
62679
+ if (full_distribution) {
62680
+ this.distribution = full_distribution;
62681
+ }
62516
62682
  this.symbol = symbol;
62517
62683
  this.minimum_size = minimum_size;
62518
62684
  this.first_order_size = first_order_size;
@@ -62548,7 +62714,8 @@ class Signal {
62548
62714
  kind = "long",
62549
62715
  risk,
62550
62716
  no_of_trades = 1,
62551
- take_profit
62717
+ take_profit,
62718
+ distribution
62552
62719
  }) {
62553
62720
  let _stop_loss = stop_loss;
62554
62721
  if (!_stop_loss && stop_percent) {
@@ -62557,16 +62724,22 @@ class Signal {
62557
62724
  const percent_change = _stop_loss ? Math.max(current_price, _stop_loss) / Math.min(current_price, _stop_loss) - 1 : this.percent_change;
62558
62725
  const _no_of_trades = no_of_trades || this.risk_reward;
62559
62726
  let _resistance = current_price * Math.pow(1 + percent_change, 1);
62727
+ const simple_support = Math.min(current_price, stop_loss);
62728
+ const simple_resistance = Math.max(current_price, stop_loss);
62560
62729
  const derivedConfig = {
62561
62730
  ...this,
62562
62731
  percent_change,
62563
62732
  focus: current_price,
62564
- resistance: _resistance,
62733
+ resistance: distribution ? simple_resistance : _resistance,
62565
62734
  risk_per_trade: risk / this.risk_reward,
62566
62735
  minimum_pnl: pnl,
62567
62736
  risk_reward: _no_of_trades,
62568
62737
  take_profit: take_profit || this.take_profit,
62569
- support: kind === "long" ? _stop_loss : this.support
62738
+ support: distribution ? simple_support : kind === "long" ? _stop_loss : this.support,
62739
+ full_distribution: distribution ? {
62740
+ ...this.distribution,
62741
+ [kind]: distribution
62742
+ } : undefined
62570
62743
  };
62571
62744
  const instance = new Signal(derivedConfig);
62572
62745
  if (kind === "short") {}
@@ -62782,12 +62955,31 @@ class Signal {
62782
62955
  }
62783
62956
  this.zone_risk = original;
62784
62957
  }
62958
+ get_future_zones_simple({
62959
+ current_price,
62960
+ kind = "long",
62961
+ raw
62962
+ }) {
62963
+ const margin_zones = [this.support, this.resistance];
62964
+ const distribution = this.distribution ? this.distribution[kind] : "geometric";
62965
+ console.log("margin_zones", { margin_zones, distribution });
62966
+ let _kind = distribution === "inverse-exponential" ? kind === "long" ? "short" : "long" : kind;
62967
+ const entries = distributions_default({
62968
+ margin_range: margin_zones,
62969
+ kind: _kind,
62970
+ distribution,
62971
+ risk_reward: this.risk_reward,
62972
+ price_places: this.price_places
62973
+ });
62974
+ return entries.sort((a, b) => a - b);
62975
+ }
62785
62976
  get_future_zones({
62786
62977
  current_price,
62787
62978
  kind = "long",
62788
62979
  raw
62789
62980
  }) {
62790
62981
  if (raw) {}
62982
+ return this.get_future_zones_simple({ current_price, raw, kind });
62791
62983
  const margin_range = this.get_margin_range(current_price, kind);
62792
62984
  let margin_zones = this.get_margin_zones({ current_price });
62793
62985
  let remaining_zones = margin_zones.filter((x) => JSON.stringify(x) != JSON.stringify(margin_range));
@@ -63446,7 +63638,9 @@ function buildConfig(app_config, {
63446
63638
  kelly_confidence_factor = 0.95,
63447
63639
  kelly_minimum_risk = 0.2,
63448
63640
  kelly_prediction_model = "exponential",
63449
- kelly_func = "theoretical"
63641
+ kelly_func = "theoretical",
63642
+ min_avg_size = 0,
63643
+ distribution
63450
63644
  }) {
63451
63645
  let fee = app_config.fee / 100;
63452
63646
  let working_risk = risk || app_config.risk_per_trade;
@@ -63493,9 +63687,12 @@ function buildConfig(app_config, {
63493
63687
  stop_loss: stop,
63494
63688
  risk: working_risk,
63495
63689
  kind: kind || app_config.kind,
63496
- no_of_trades: trade_no
63690
+ no_of_trades: trade_no,
63691
+ distribution
63497
63692
  }) || [] : [];
63498
- return computeTotalAverageForEachTrade(result, config2);
63693
+ const new_trades = computeTotalAverageForEachTrade(result, config2);
63694
+ let filtered = new_trades.filter((o) => o.avg_size > min_avg_size);
63695
+ return computeTotalAverageForEachTrade(filtered, config2);
63499
63696
  }
63500
63697
  function sortedBuildConfig(app_config, options) {
63501
63698
  const sorted = buildConfig(app_config, options).sort((a, b) => app_config.kind === "long" ? a.entry - b.entry : b.entry - b.entry).filter((x) => {
@@ -63547,7 +63744,8 @@ function get_app_config_and_max_size(config2, payload) {
63547
63744
  kelly_confidence_factor: payload.kelly_confidence_factor,
63548
63745
  kelly_minimum_risk: payload.kelly_minimum_risk,
63549
63746
  kelly_prediction_model: payload.kelly_prediction_model,
63550
- kelly_func: payload.kelly_func
63747
+ kelly_func: payload.kelly_func,
63748
+ distribution: payload.distribution
63551
63749
  });
63552
63750
  const max_size = initialResult[0]?.avg_size;
63553
63751
  const last_value = initialResult[0];
@@ -63585,7 +63783,8 @@ function buildAppConfig(config2, payload) {
63585
63783
  kelly_confidence_factor: payload.kelly_confidence_factor,
63586
63784
  kelly_minimum_risk: payload.kelly_minimum_risk,
63587
63785
  kelly_prediction_model: payload.kelly_prediction_model,
63588
- kelly_func: payload.kelly_func
63786
+ kelly_func: payload.kelly_func,
63787
+ distribution: payload.distribution
63589
63788
  });
63590
63789
  app_config.max_size = max_size;
63591
63790
  app_config.entry = payload.entry || app_config.entry;
@@ -63602,7 +63801,7 @@ function buildAppConfig(config2, payload) {
63602
63801
  return app_config;
63603
63802
  }
63604
63803
  function getOptimumStopAndRisk(app_config, params) {
63605
- const { max_size, target_stop } = params;
63804
+ const { max_size, target_stop, distribution } = params;
63606
63805
  const isLong = app_config.kind === "long";
63607
63806
  const stopRange = Math.abs(app_config.entry - target_stop) * 0.5;
63608
63807
  let low_stop = isLong ? target_stop - stopRange : Math.max(target_stop - stopRange, app_config.entry);
@@ -63625,7 +63824,8 @@ function getOptimumStopAndRisk(app_config, params) {
63625
63824
  increase: true,
63626
63825
  gap: app_config.gap,
63627
63826
  price_places: app_config.price_places,
63628
- decimal_places: app_config.decimal_places
63827
+ decimal_places: app_config.decimal_places,
63828
+ distribution
63629
63829
  });
63630
63830
  if (result.length === 0) {
63631
63831
  if (isLong) {
@@ -63679,7 +63879,8 @@ function getOptimumStopAndRisk(app_config, params) {
63679
63879
  increase: true,
63680
63880
  gap: app_config.gap,
63681
63881
  price_places: app_config.price_places,
63682
- decimal_places: app_config.decimal_places
63882
+ decimal_places: app_config.decimal_places,
63883
+ distribution
63683
63884
  });
63684
63885
  if (result.length === 0) {
63685
63886
  high_risk = mid_risk;
@@ -63724,7 +63925,8 @@ function getOptimumStopAndRisk(app_config, params) {
63724
63925
  increase: true,
63725
63926
  gap: app_config.gap,
63726
63927
  price_places: app_config.price_places,
63727
- decimal_places: app_config.decimal_places
63928
+ decimal_places: app_config.decimal_places,
63929
+ distribution
63728
63930
  });
63729
63931
  if (result.length === 0)
63730
63932
  continue;
@@ -63847,7 +64049,8 @@ function generateOptimumAppConfig(config2, payload, position2) {
63847
64049
  }, {
63848
64050
  entry: payload.entry,
63849
64051
  stop: payload.stop,
63850
- kind: position2.kind
64052
+ kind: position2.kind,
64053
+ distribution: payload.distribution
63851
64054
  });
63852
64055
  current_app_config.max_size = max_size;
63853
64056
  current_app_config.last_value = last_value;
@@ -63862,7 +64065,8 @@ function generateOptimumAppConfig(config2, payload, position2) {
63862
64065
  increase: true,
63863
64066
  gap: current_app_config.gap,
63864
64067
  price_places: current_app_config.price_places,
63865
- decimal_places: current_app_config.decimal_places
64068
+ decimal_places: current_app_config.decimal_places,
64069
+ distribution: payload.distribution
63866
64070
  });
63867
64071
  if (full_trades.length === 0) {
63868
64072
  high_risk = mid_risk;
@@ -63926,7 +64130,8 @@ function determineOptimumReward(payload) {
63926
64130
  increase = true,
63927
64131
  low_range = 1,
63928
64132
  high_range = 199,
63929
- target_loss
64133
+ target_loss,
64134
+ distribution
63930
64135
  } = payload;
63931
64136
  const criterion = app_config.strategy || "quantity";
63932
64137
  const risk_rewards = createArray(low_range, high_range, 1);
@@ -63940,7 +64145,8 @@ function determineOptimumReward(payload) {
63940
64145
  increase,
63941
64146
  kind: app_config.kind,
63942
64147
  gap: app_config.gap,
63943
- decimal_places: app_config.decimal_places
64148
+ decimal_places: app_config.decimal_places,
64149
+ distribution
63944
64150
  });
63945
64151
  let total = 0;
63946
64152
  let max = -Infinity;
@@ -64105,14 +64311,17 @@ function determineOptimumRisk(config2, payload, params) {
64105
64311
  };
64106
64312
  }
64107
64313
  function computeRiskReward(payload) {
64108
- const { app_config, entry, stop, risk_per_trade, target_loss } = payload;
64314
+ const { app_config, entry, stop, risk_per_trade, target_loss, distribution } = payload;
64109
64315
  const kind = entry > stop ? "long" : "short";
64110
64316
  app_config.kind = kind;
64111
64317
  app_config.entry = entry;
64112
64318
  app_config.stop = stop;
64113
64319
  app_config.risk_per_trade = risk_per_trade;
64114
- const result = determineOptimumReward({ app_config, target_loss });
64115
- console.log("result", result, "target_loss", target_loss);
64320
+ const result = determineOptimumReward({
64321
+ app_config,
64322
+ target_loss,
64323
+ distribution
64324
+ });
64116
64325
  return result;
64117
64326
  }
64118
64327
  function getRiskReward(payload) {
@@ -64122,21 +64331,24 @@ function getRiskReward(payload) {
64122
64331
  risk,
64123
64332
  global_config,
64124
64333
  force_exact_risk = false,
64125
- target_loss
64334
+ target_loss,
64335
+ distribution
64126
64336
  } = payload;
64127
64337
  const { entries, last_value, ...app_config } = buildAppConfig(global_config, {
64128
64338
  entry,
64129
64339
  stop,
64130
64340
  risk_reward: 30,
64131
64341
  risk,
64132
- symbol: global_config.symbol
64342
+ symbol: global_config.symbol,
64343
+ distribution
64133
64344
  });
64134
64345
  const risk_reward = computeRiskReward({
64135
64346
  app_config,
64136
64347
  entry,
64137
64348
  stop,
64138
64349
  risk_per_trade: risk,
64139
- target_loss
64350
+ target_loss,
64351
+ distribution
64140
64352
  });
64141
64353
  if (force_exact_risk) {
64142
64354
  const new_risk_per_trade = determineOptimumRisk(global_config, {
@@ -64144,7 +64356,8 @@ function getRiskReward(payload) {
64144
64356
  stop,
64145
64357
  risk_reward,
64146
64358
  risk,
64147
- symbol: global_config.symbol
64359
+ symbol: global_config.symbol,
64360
+ distribution
64148
64361
  }, {
64149
64362
  highest_risk: risk
64150
64363
  }).optimal_risk;
@@ -64501,7 +64714,7 @@ function constructAppConfig(payload) {
64501
64714
  kelly_minimum_risk: kelly_config?.kelly_minimum_risk ?? kelly?.kelly_minimum_risk,
64502
64715
  kelly_prediction_model: kelly_config?.kelly_prediction_model ?? kelly?.kelly_prediction_model
64503
64716
  };
64504
- const appConfig = buildAppConfig(global_config, options);
64717
+ const { entries: _entries, ...appConfig } = buildAppConfig(global_config, options);
64505
64718
  return appConfig;
64506
64719
  }
64507
64720
  function generateDangerousConfig(payload) {
@@ -67460,7 +67673,6 @@ async function reduceMajorPositionEntry(input, accountInfo, trigger2, exchange_i
67460
67673
  // src/position.ts
67461
67674
  var import_https_proxy_agent2 = __toESM(require_dist2());
67462
67675
  var import_socks_proxy_agent2 = __toESM(require_dist3());
67463
-
67464
67676
  class ExchangePosition {
67465
67677
  exchange;
67466
67678
  symbol_config;
@@ -67500,6 +67712,19 @@ class ExchangePosition {
67500
67712
  const { p_account } = this.instance.expand;
67501
67713
  return p_account;
67502
67714
  }
67715
+ get compound() {
67716
+ const { compound_instance } = this.instance.expand;
67717
+ if (compound_instance) {
67718
+ const { ref } = compound_instance.expand;
67719
+ const profit_percent = ref.profit_percent / 100;
67720
+ return {
67721
+ ...compound_instance,
67722
+ profit_percent,
67723
+ amount_to_risk: to_f(compound_instance.risk * profit_percent, "%.2f")
67724
+ };
67725
+ }
67726
+ return compound_instance;
67727
+ }
67503
67728
  async getProxyForAccount() {
67504
67729
  if (this.instance.expand.proxy) {
67505
67730
  const result = this.instance.expand.proxy;
@@ -67625,7 +67850,8 @@ class ExchangePosition {
67625
67850
  place,
67626
67851
  raw: payload.raw,
67627
67852
  use_current,
67628
- stop_percent: config2.stop_percent || 100
67853
+ stop_percent: config2.stop_percent || 100,
67854
+ distribution: config2.distribution
67629
67855
  });
67630
67856
  }
67631
67857
  }
@@ -67659,7 +67885,8 @@ class ExchangePosition {
67659
67885
  kelly_confidence_factor: config2.kelly?.kelly_confidence_factor,
67660
67886
  kelly_minimum_risk: config2.kelly?.kelly_minimum_risk,
67661
67887
  kelly_prediction_model: config2.kelly?.kelly_prediction_model,
67662
- kelly_func: config2.kelly?.kelly_func
67888
+ kelly_func: config2.kelly?.kelly_func,
67889
+ distribution: config2.distribution
67663
67890
  }, false);
67664
67891
  if (payload.raw) {
67665
67892
  let actual_orders_to_buy = await this.determineAmountToBuy({
@@ -67782,7 +68009,8 @@ class ExchangePosition {
67782
68009
  kelly_confidence_factor: solution.kelly_confidence_factor,
67783
68010
  kelly_minimum_risk: solution.kelly_minimum_risk,
67784
68011
  kelly_prediction_model: solution.kelly_prediction_model,
67785
- kelly_func: solution.kelly_func
68012
+ kelly_func: solution.kelly_func,
68013
+ distribution: solution.distribution
67786
68014
  };
67787
68015
  const trades = sortedBuildConfig(app_config, options);
67788
68016
  const entry_orders = {
@@ -68174,6 +68402,7 @@ class ExchangePosition {
68174
68402
  });
68175
68403
  }
68176
68404
  async generate_config_params(payload) {
68405
+ const db_config = await this.getConfig();
68177
68406
  const { entry, stop, risk_reward, risk, with_trades = false } = payload;
68178
68407
  const symbol = this.symbol;
68179
68408
  const app_config = await this.buildAppConfig({
@@ -68206,7 +68435,8 @@ class ExchangePosition {
68206
68435
  avg_size: 0,
68207
68436
  neg_pnl: 0,
68208
68437
  min_size: app_config2.min_size,
68209
- symbol
68438
+ symbol,
68439
+ distribution: db_config.distribution
68210
68440
  }, false);
68211
68441
  config2.trades = trades;
68212
68442
  }
@@ -68307,7 +68537,8 @@ class ExchangePosition {
68307
68537
  kelly_confidence_factor: config2.kelly?.kelly_confidence_factor,
68308
68538
  kelly_minimum_risk: config2.kelly?.kelly_minimum_risk,
68309
68539
  kelly_prediction_model: config2.kelly?.kelly_prediction_model,
68310
- kelly_func: config2.kelly?.kelly_func
68540
+ kelly_func: config2.kelly?.kelly_func,
68541
+ distribution: config2.distribution
68311
68542
  });
68312
68543
  const position2 = this.instance;
68313
68544
  const orders_to_place = await this.determineAmountToBuy({
@@ -68505,6 +68736,46 @@ class ExchangePosition {
68505
68736
  increase: false
68506
68737
  });
68507
68738
  }
68739
+ get support() {
68740
+ return this.instance.expand?.support;
68741
+ }
68742
+ get linkedConfig() {
68743
+ return this.instance.expand?.b_config;
68744
+ }
68745
+ get isActiveTrade() {
68746
+ const config2 = this.linkedConfig;
68747
+ return {
68748
+ config: config2,
68749
+ condition: this.compound && this.support?.price === config2.stop
68750
+ };
68751
+ }
68752
+ async updateCompound(payload) {
68753
+ const pb = this.app_db.pb;
68754
+ const item = this.compound;
68755
+ const new_risk = item.risk + item.amount_to_risk;
68756
+ const { condition, config: config2 } = this.isActiveTrade;
68757
+ if (payload?.place && condition) {
68758
+ await pb.collection("compound_instances").update(item.id, {
68759
+ risk: new_risk
68760
+ });
68761
+ await pb.collection("scheduled_trades").update(config2.id, {
68762
+ profit: to_f(new_risk * item.profit_percent, "%.3f")
68763
+ });
68764
+ }
68765
+ return {
68766
+ support: this.support?.price,
68767
+ counter: this.support?.counter,
68768
+ new_risk,
68769
+ condition,
68770
+ stop: config2.stop
68771
+ };
68772
+ }
68773
+ async cleanOnActiveCompoundInstance() {
68774
+ const { condition } = this.isActiveTrade;
68775
+ if (condition && this.instance.quantity === 0) {
68776
+ await this.cancelOrders({ limit: true });
68777
+ }
68778
+ }
68508
68779
  }
68509
68780
  function convert_to_exchange_order(order) {
68510
68781
  return {