@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.
package/dist/index.js CHANGED
@@ -54645,7 +54645,7 @@ class AppDatabase {
54645
54645
  table: "positions_view",
54646
54646
  params: {
54647
54647
  filter: `symbol:lower="${symbol.toLowerCase()}" && p_account.owner:lower="${account.owner.toLowerCase()}" && p_account.exchange:lower="${account.exchange.toLowerCase()}"`,
54648
- expand: "b_config, account_strategy, p_account, proxy"
54648
+ expand: "b_config, account_strategy, p_account, proxy, compound_instance.ref,support"
54649
54649
  }
54650
54650
  } : {
54651
54651
  table: "positions",
@@ -55455,6 +55455,33 @@ class AppDatabase {
55455
55455
  parent: config_id
55456
55456
  });
55457
55457
  }
55458
+ async getCompoundInstance(payload) {
55459
+ const { position } = payload;
55460
+ const found = await this.pb.collection("compound_instances").getFullList({
55461
+ filter: `position.id = "${position.id}"`,
55462
+ expand: `ref`
55463
+ });
55464
+ if (found.length == 0) {
55465
+ return;
55466
+ }
55467
+ const item = found[0];
55468
+ return item;
55469
+ }
55470
+ async getSupportTable(payload) {
55471
+ const { symbol, kind } = payload;
55472
+ const found = await this.pb.collection("support_table").getFullList({
55473
+ filter: `symbol = "${symbol}" && kind = "${kind}"`
55474
+ });
55475
+ if (found.length === 0) {
55476
+ return;
55477
+ }
55478
+ const item = found[0];
55479
+ return item;
55480
+ }
55481
+ async updateCompoundInstance(payload) {
55482
+ const { id, params } = payload;
55483
+ return await this.pb.collection("compound_instances").update(id, params);
55484
+ }
55458
55485
  }
55459
55486
 
55460
55487
  // src/exchange-account.ts
@@ -55467,6 +55494,137 @@ __export(exports_exchange_account, {
55467
55494
  // src/exchanges/binance/index.ts
55468
55495
  var import_binance = __toESM(require_lib2(), 1);
55469
55496
 
55497
+ // src/helpers/distributions.ts
55498
+ function generateArithmetic(payload) {
55499
+ const { margin_range, risk_reward, kind, price_places = "%.1f" } = payload;
55500
+ const difference = Math.abs(margin_range[1] - margin_range[0]);
55501
+ const spread = difference / risk_reward;
55502
+ return Array.from({ length: risk_reward + 1 }, (_, i2) => {
55503
+ const price = kind === "long" ? margin_range[1] - spread * i2 : margin_range[0] + spread * i2;
55504
+ return to_f(price, price_places);
55505
+ });
55506
+ }
55507
+ function generateGeometric(payload) {
55508
+ const { margin_range, risk_reward, kind, price_places = "%.1f", percent_change } = payload;
55509
+ const effectivePercentChange = percent_change ?? Math.abs(margin_range[1] / margin_range[0] - 1) / risk_reward;
55510
+ return Array.from({ length: risk_reward + 1 }, (_, i2) => {
55511
+ const price = kind === "long" ? margin_range[1] * Math.pow(1 - effectivePercentChange, i2) : margin_range[0] * Math.pow(1 + effectivePercentChange, i2);
55512
+ return to_f(price, price_places);
55513
+ });
55514
+ }
55515
+ function approximateInverseNormal(p) {
55516
+ p = Math.max(0.0001, Math.min(0.9999, p));
55517
+ if (p < 0.5) {
55518
+ const t2 = Math.sqrt(-2 * Math.log(p));
55519
+ const c0 = 2.515517, c1 = 0.802853, c2 = 0.010328;
55520
+ const d1 = 1.432788, d2 = 0.189269, d3 = 0.001308;
55521
+ return -(t2 - (c0 + c1 * t2 + c2 * t2 * t2) / (1 + d1 * t2 + d2 * t2 * t2 + d3 * t2 * t2 * t2));
55522
+ } else {
55523
+ const t2 = Math.sqrt(-2 * Math.log(1 - p));
55524
+ const c0 = 2.515517, c1 = 0.802853, c2 = 0.010328;
55525
+ const d1 = 1.432788, d2 = 0.189269, d3 = 0.001308;
55526
+ return t2 - (c0 + c1 * t2 + c2 * t2 * t2) / (1 + d1 * t2 + d2 * t2 * t2 + d3 * t2 * t2 * t2);
55527
+ }
55528
+ }
55529
+ function generateNormal(payload) {
55530
+ const { margin_range, risk_reward, kind, price_places = "%.1f", stdDevFactor = 6 } = payload;
55531
+ const mean = (margin_range[0] + margin_range[1]) / 2;
55532
+ const stdDev = Math.abs(margin_range[1] - margin_range[0]) / stdDevFactor;
55533
+ const skew = kind === "long" ? -0.2 : 0.2;
55534
+ const adjustedMean = mean + stdDev * skew;
55535
+ const entries = Array.from({ length: risk_reward + 1 }, (_, i2) => {
55536
+ const p = (i2 + 0.5) / (risk_reward + 1);
55537
+ const z2 = approximateInverseNormal(p);
55538
+ let price = adjustedMean + stdDev * z2;
55539
+ price = Math.max(margin_range[0], Math.min(margin_range[1], price));
55540
+ return to_f(price, price_places);
55541
+ });
55542
+ return entries.sort((a, b) => a - b);
55543
+ }
55544
+ function generateExponential(payload) {
55545
+ const { margin_range, risk_reward, kind, price_places = "%.1f", lambda } = payload;
55546
+ const range = Math.abs(margin_range[1] - margin_range[0]);
55547
+ const effectiveLambda = lambda || 2.5;
55548
+ return Array.from({ length: risk_reward + 1 }, (_, i2) => {
55549
+ const t2 = i2 / risk_reward;
55550
+ const exponentialProgress = 1 - Math.exp(-effectiveLambda * t2);
55551
+ const price = kind === "long" ? margin_range[1] - range * exponentialProgress : margin_range[0] + range * exponentialProgress;
55552
+ return to_f(price, price_places);
55553
+ });
55554
+ }
55555
+ function generateInverseExponential(payload) {
55556
+ const { margin_range, risk_reward, kind, price_places = "%.1f", curveFactor = 2 } = payload;
55557
+ const range = Math.abs(margin_range[1] - margin_range[0]);
55558
+ return Array.from({ length: risk_reward + 1 }, (_, i2) => {
55559
+ const t2 = i2 / risk_reward;
55560
+ const progress = (Math.exp(curveFactor * t2) - 1) / (Math.exp(curveFactor) - 1);
55561
+ const price = kind === "long" ? margin_range[1] - range * progress : margin_range[0] + range * progress;
55562
+ return to_f(price, price_places);
55563
+ });
55564
+ }
55565
+ function getEntries(params) {
55566
+ const {
55567
+ kind,
55568
+ distribution,
55569
+ margin_range,
55570
+ risk_reward,
55571
+ price_places = "%.1f",
55572
+ distribution_params = {}
55573
+ } = params;
55574
+ let entries = [];
55575
+ switch (distribution) {
55576
+ case "arithmetic":
55577
+ entries = generateArithmetic({
55578
+ margin_range,
55579
+ risk_reward,
55580
+ kind,
55581
+ price_places,
55582
+ percent_change: distribution_params.curveFactor
55583
+ });
55584
+ break;
55585
+ case "geometric":
55586
+ entries = generateGeometric({
55587
+ margin_range,
55588
+ risk_reward,
55589
+ kind,
55590
+ price_places,
55591
+ percent_change: distribution_params.curveFactor
55592
+ });
55593
+ break;
55594
+ case "normal":
55595
+ entries = generateNormal({
55596
+ margin_range,
55597
+ risk_reward,
55598
+ kind,
55599
+ price_places,
55600
+ stdDevFactor: distribution_params.stdDevFactor
55601
+ });
55602
+ break;
55603
+ case "exponential":
55604
+ entries = generateExponential({
55605
+ margin_range,
55606
+ risk_reward,
55607
+ kind,
55608
+ price_places,
55609
+ lambda: distribution_params.lambda
55610
+ });
55611
+ break;
55612
+ case "inverse-exponential":
55613
+ entries = generateInverseExponential({
55614
+ margin_range,
55615
+ risk_reward,
55616
+ kind,
55617
+ price_places,
55618
+ curveFactor: distribution_params.curveFactor
55619
+ });
55620
+ break;
55621
+ default:
55622
+ throw new Error(`Unknown distribution type: ${distribution}`);
55623
+ }
55624
+ return entries.sort((a, b) => a - b);
55625
+ }
55626
+ var distributions_default = getEntries;
55627
+
55470
55628
  // src/helpers/optimizations.ts
55471
55629
  function calculateTheoreticalKelly({
55472
55630
  current_entry,
@@ -55736,6 +55894,10 @@ class Signal {
55736
55894
  kelly_minimum_risk = 0.2;
55737
55895
  kelly_func = "theoretical";
55738
55896
  symbol;
55897
+ distribution = {
55898
+ long: "arithmetic",
55899
+ short: "geometric"
55900
+ };
55739
55901
  constructor({
55740
55902
  focus,
55741
55903
  symbol,
@@ -55762,8 +55924,12 @@ class Signal {
55762
55924
  kelly_prediction_model = "exponential",
55763
55925
  kelly_confidence_factor = 0.6,
55764
55926
  kelly_minimum_risk = 0.2,
55765
- kelly_func = "theoretical"
55927
+ kelly_func = "theoretical",
55928
+ full_distribution
55766
55929
  }) {
55930
+ if (full_distribution) {
55931
+ this.distribution = full_distribution;
55932
+ }
55767
55933
  this.symbol = symbol;
55768
55934
  this.minimum_size = minimum_size;
55769
55935
  this.first_order_size = first_order_size;
@@ -55799,7 +55965,8 @@ class Signal {
55799
55965
  kind = "long",
55800
55966
  risk,
55801
55967
  no_of_trades = 1,
55802
- take_profit
55968
+ take_profit,
55969
+ distribution
55803
55970
  }) {
55804
55971
  let _stop_loss = stop_loss;
55805
55972
  if (!_stop_loss && stop_percent) {
@@ -55808,16 +55975,22 @@ class Signal {
55808
55975
  const percent_change = _stop_loss ? Math.max(current_price, _stop_loss) / Math.min(current_price, _stop_loss) - 1 : this.percent_change;
55809
55976
  const _no_of_trades = no_of_trades || this.risk_reward;
55810
55977
  let _resistance = current_price * Math.pow(1 + percent_change, 1);
55978
+ const simple_support = Math.min(current_price, stop_loss);
55979
+ const simple_resistance = Math.max(current_price, stop_loss);
55811
55980
  const derivedConfig = {
55812
55981
  ...this,
55813
55982
  percent_change,
55814
55983
  focus: current_price,
55815
- resistance: _resistance,
55984
+ resistance: distribution ? simple_resistance : _resistance,
55816
55985
  risk_per_trade: risk / this.risk_reward,
55817
55986
  minimum_pnl: pnl,
55818
55987
  risk_reward: _no_of_trades,
55819
55988
  take_profit: take_profit || this.take_profit,
55820
- support: kind === "long" ? _stop_loss : this.support
55989
+ support: distribution ? simple_support : kind === "long" ? _stop_loss : this.support,
55990
+ full_distribution: distribution ? {
55991
+ ...this.distribution,
55992
+ [kind]: distribution
55993
+ } : undefined
55821
55994
  };
55822
55995
  const instance = new Signal(derivedConfig);
55823
55996
  if (kind === "short") {}
@@ -56033,12 +56206,31 @@ class Signal {
56033
56206
  }
56034
56207
  this.zone_risk = original;
56035
56208
  }
56209
+ get_future_zones_simple({
56210
+ current_price,
56211
+ kind = "long",
56212
+ raw
56213
+ }) {
56214
+ const margin_zones = [this.support, this.resistance];
56215
+ const distribution = this.distribution ? this.distribution[kind] : "geometric";
56216
+ console.log("margin_zones", { margin_zones, distribution });
56217
+ let _kind = distribution === "inverse-exponential" ? kind === "long" ? "short" : "long" : kind;
56218
+ const entries = distributions_default({
56219
+ margin_range: margin_zones,
56220
+ kind: _kind,
56221
+ distribution,
56222
+ risk_reward: this.risk_reward,
56223
+ price_places: this.price_places
56224
+ });
56225
+ return entries.sort((a, b) => a - b);
56226
+ }
56036
56227
  get_future_zones({
56037
56228
  current_price,
56038
56229
  kind = "long",
56039
56230
  raw
56040
56231
  }) {
56041
56232
  if (raw) {}
56233
+ return this.get_future_zones_simple({ current_price, raw, kind });
56042
56234
  const margin_range = this.get_margin_range(current_price, kind);
56043
56235
  let margin_zones = this.get_margin_zones({ current_price });
56044
56236
  let remaining_zones = margin_zones.filter((x) => JSON.stringify(x) != JSON.stringify(margin_range));
@@ -56697,7 +56889,9 @@ function buildConfig(app_config, {
56697
56889
  kelly_confidence_factor = 0.95,
56698
56890
  kelly_minimum_risk = 0.2,
56699
56891
  kelly_prediction_model = "exponential",
56700
- kelly_func = "theoretical"
56892
+ kelly_func = "theoretical",
56893
+ min_avg_size = 0,
56894
+ distribution
56701
56895
  }) {
56702
56896
  let fee = app_config.fee / 100;
56703
56897
  let working_risk = risk || app_config.risk_per_trade;
@@ -56744,9 +56938,12 @@ function buildConfig(app_config, {
56744
56938
  stop_loss: stop,
56745
56939
  risk: working_risk,
56746
56940
  kind: kind || app_config.kind,
56747
- no_of_trades: trade_no
56941
+ no_of_trades: trade_no,
56942
+ distribution
56748
56943
  }) || [] : [];
56749
- return computeTotalAverageForEachTrade(result, config2);
56944
+ const new_trades = computeTotalAverageForEachTrade(result, config2);
56945
+ let filtered = new_trades.filter((o) => o.avg_size > min_avg_size);
56946
+ return computeTotalAverageForEachTrade(filtered, config2);
56750
56947
  }
56751
56948
  function buildAvg({
56752
56949
  _trades,
@@ -56811,7 +57008,8 @@ function get_app_config_and_max_size(config2, payload) {
56811
57008
  kelly_confidence_factor: payload.kelly_confidence_factor,
56812
57009
  kelly_minimum_risk: payload.kelly_minimum_risk,
56813
57010
  kelly_prediction_model: payload.kelly_prediction_model,
56814
- kelly_func: payload.kelly_func
57011
+ kelly_func: payload.kelly_func,
57012
+ distribution: payload.distribution
56815
57013
  });
56816
57014
  const max_size = initialResult[0]?.avg_size;
56817
57015
  const last_value = initialResult[0];
@@ -56849,7 +57047,8 @@ function buildAppConfig(config2, payload) {
56849
57047
  kelly_confidence_factor: payload.kelly_confidence_factor,
56850
57048
  kelly_minimum_risk: payload.kelly_minimum_risk,
56851
57049
  kelly_prediction_model: payload.kelly_prediction_model,
56852
- kelly_func: payload.kelly_func
57050
+ kelly_func: payload.kelly_func,
57051
+ distribution: payload.distribution
56853
57052
  });
56854
57053
  app_config.max_size = max_size;
56855
57054
  app_config.entry = payload.entry || app_config.entry;
@@ -56866,7 +57065,7 @@ function buildAppConfig(config2, payload) {
56866
57065
  return app_config;
56867
57066
  }
56868
57067
  function getOptimumStopAndRisk(app_config, params) {
56869
- const { max_size, target_stop } = params;
57068
+ const { max_size, target_stop, distribution } = params;
56870
57069
  const isLong = app_config.kind === "long";
56871
57070
  const stopRange = Math.abs(app_config.entry - target_stop) * 0.5;
56872
57071
  let low_stop = isLong ? target_stop - stopRange : Math.max(target_stop - stopRange, app_config.entry);
@@ -56889,7 +57088,8 @@ function getOptimumStopAndRisk(app_config, params) {
56889
57088
  increase: true,
56890
57089
  gap: app_config.gap,
56891
57090
  price_places: app_config.price_places,
56892
- decimal_places: app_config.decimal_places
57091
+ decimal_places: app_config.decimal_places,
57092
+ distribution
56893
57093
  });
56894
57094
  if (result.length === 0) {
56895
57095
  if (isLong) {
@@ -56943,7 +57143,8 @@ function getOptimumStopAndRisk(app_config, params) {
56943
57143
  increase: true,
56944
57144
  gap: app_config.gap,
56945
57145
  price_places: app_config.price_places,
56946
- decimal_places: app_config.decimal_places
57146
+ decimal_places: app_config.decimal_places,
57147
+ distribution
56947
57148
  });
56948
57149
  if (result.length === 0) {
56949
57150
  high_risk = mid_risk;
@@ -56988,7 +57189,8 @@ function getOptimumStopAndRisk(app_config, params) {
56988
57189
  increase: true,
56989
57190
  gap: app_config.gap,
56990
57191
  price_places: app_config.price_places,
56991
- decimal_places: app_config.decimal_places
57192
+ decimal_places: app_config.decimal_places,
57193
+ distribution
56992
57194
  });
56993
57195
  if (result.length === 0)
56994
57196
  continue;
@@ -57111,7 +57313,8 @@ function generateOptimumAppConfig(config2, payload, position2) {
57111
57313
  }, {
57112
57314
  entry: payload.entry,
57113
57315
  stop: payload.stop,
57114
- kind: position2.kind
57316
+ kind: position2.kind,
57317
+ distribution: payload.distribution
57115
57318
  });
57116
57319
  current_app_config.max_size = max_size;
57117
57320
  current_app_config.last_value = last_value;
@@ -57126,7 +57329,8 @@ function generateOptimumAppConfig(config2, payload, position2) {
57126
57329
  increase: true,
57127
57330
  gap: current_app_config.gap,
57128
57331
  price_places: current_app_config.price_places,
57129
- decimal_places: current_app_config.decimal_places
57332
+ decimal_places: current_app_config.decimal_places,
57333
+ distribution: payload.distribution
57130
57334
  });
57131
57335
  if (full_trades.length === 0) {
57132
57336
  high_risk = mid_risk;
@@ -57190,7 +57394,8 @@ function determineOptimumReward(payload) {
57190
57394
  increase = true,
57191
57395
  low_range = 1,
57192
57396
  high_range = 199,
57193
- target_loss
57397
+ target_loss,
57398
+ distribution
57194
57399
  } = payload;
57195
57400
  const criterion = app_config.strategy || "quantity";
57196
57401
  const risk_rewards = createArray(low_range, high_range, 1);
@@ -57204,7 +57409,8 @@ function determineOptimumReward(payload) {
57204
57409
  increase,
57205
57410
  kind: app_config.kind,
57206
57411
  gap: app_config.gap,
57207
- decimal_places: app_config.decimal_places
57412
+ decimal_places: app_config.decimal_places,
57413
+ distribution
57208
57414
  });
57209
57415
  let total = 0;
57210
57416
  let max = -Infinity;
@@ -57369,14 +57575,17 @@ function determineOptimumRisk(config2, payload, params) {
57369
57575
  };
57370
57576
  }
57371
57577
  function computeRiskReward(payload) {
57372
- const { app_config, entry, stop, risk_per_trade, target_loss } = payload;
57578
+ const { app_config, entry, stop, risk_per_trade, target_loss, distribution } = payload;
57373
57579
  const kind = entry > stop ? "long" : "short";
57374
57580
  app_config.kind = kind;
57375
57581
  app_config.entry = entry;
57376
57582
  app_config.stop = stop;
57377
57583
  app_config.risk_per_trade = risk_per_trade;
57378
- const result = determineOptimumReward({ app_config, target_loss });
57379
- console.log("result", result, "target_loss", target_loss);
57584
+ const result = determineOptimumReward({
57585
+ app_config,
57586
+ target_loss,
57587
+ distribution
57588
+ });
57380
57589
  return result;
57381
57590
  }
57382
57591
  function getRiskReward(payload) {
@@ -57386,21 +57595,24 @@ function getRiskReward(payload) {
57386
57595
  risk,
57387
57596
  global_config,
57388
57597
  force_exact_risk = false,
57389
- target_loss
57598
+ target_loss,
57599
+ distribution
57390
57600
  } = payload;
57391
57601
  const { entries, last_value, ...app_config } = buildAppConfig(global_config, {
57392
57602
  entry,
57393
57603
  stop,
57394
57604
  risk_reward: 30,
57395
57605
  risk,
57396
- symbol: global_config.symbol
57606
+ symbol: global_config.symbol,
57607
+ distribution
57397
57608
  });
57398
57609
  const risk_reward = computeRiskReward({
57399
57610
  app_config,
57400
57611
  entry,
57401
57612
  stop,
57402
57613
  risk_per_trade: risk,
57403
- target_loss
57614
+ target_loss,
57615
+ distribution
57404
57616
  });
57405
57617
  if (force_exact_risk) {
57406
57618
  const new_risk_per_trade = determineOptimumRisk(global_config, {
@@ -57408,7 +57620,8 @@ function getRiskReward(payload) {
57408
57620
  stop,
57409
57621
  risk_reward,
57410
57622
  risk,
57411
- symbol: global_config.symbol
57623
+ symbol: global_config.symbol,
57624
+ distribution
57412
57625
  }, {
57413
57626
  highest_risk: risk
57414
57627
  }).optimal_risk;
@@ -57557,6 +57770,98 @@ function calculate_factor(payload) {
57557
57770
  calculated_factor = to_f(calculated_factor, places);
57558
57771
  return calculated_factor;
57559
57772
  }
57773
+ function calculateFactorFromTakeProfit(payload) {
57774
+ const { long, short, knownTp, tpType, price_places = "%.4f" } = payload;
57775
+ const gap = Math.abs(long.entry - short.entry);
57776
+ const max_quantity = Math.max(long.quantity, short.quantity);
57777
+ const gapLoss = gap * max_quantity;
57778
+ if (gapLoss === 0) {
57779
+ return 0;
57780
+ }
57781
+ let factor;
57782
+ if (tpType === "long") {
57783
+ const longPercent = knownTp / long.entry - 1;
57784
+ factor = longPercent * short.entry * short.quantity / gapLoss;
57785
+ } else {
57786
+ const shortPercent = short.entry / knownTp - 1;
57787
+ factor = shortPercent * long.entry * long.quantity / gapLoss;
57788
+ }
57789
+ return to_f(factor, price_places);
57790
+ }
57791
+ function calculateFactorFromSellQuantity(payload) {
57792
+ const {
57793
+ long,
57794
+ short,
57795
+ knownSellQuantity,
57796
+ sellType,
57797
+ sell_factor = 1,
57798
+ price_places = "%.4f"
57799
+ } = payload;
57800
+ if (knownSellQuantity < 0.00001) {
57801
+ return 0;
57802
+ }
57803
+ const gap = Math.abs(long.entry - short.entry);
57804
+ const max_quantity = Math.max(long.quantity, short.quantity);
57805
+ const gapLoss = gap * max_quantity;
57806
+ if (gapLoss === 0) {
57807
+ return 0;
57808
+ }
57809
+ let low_factor = 0.001;
57810
+ let high_factor = 1;
57811
+ let best_factor = 0;
57812
+ let best_diff = Infinity;
57813
+ const tolerance = 0.00001;
57814
+ const max_iterations = 150;
57815
+ let expansions = 0;
57816
+ const max_expansions = 15;
57817
+ let iterations = 0;
57818
+ while (iterations < max_iterations) {
57819
+ iterations++;
57820
+ const mid_factor = (low_factor + high_factor) / 2;
57821
+ const testResult = generateGapTp({
57822
+ long,
57823
+ short,
57824
+ factor: mid_factor,
57825
+ sell_factor,
57826
+ price_places: "%.8f",
57827
+ decimal_places: "%.8f"
57828
+ });
57829
+ const testSellQty = sellType === "long" ? testResult.sell_quantity.long : testResult.sell_quantity.short;
57830
+ const diff = Math.abs(testSellQty - knownSellQuantity);
57831
+ if (diff < best_diff) {
57832
+ best_diff = diff;
57833
+ best_factor = mid_factor;
57834
+ }
57835
+ if (diff < tolerance) {
57836
+ return to_f(mid_factor, price_places);
57837
+ }
57838
+ if (testSellQty < knownSellQuantity) {
57839
+ low_factor = mid_factor;
57840
+ if (mid_factor > high_factor * 0.9 && expansions < max_expansions) {
57841
+ const ratio = knownSellQuantity / testSellQty;
57842
+ if (ratio > 2) {
57843
+ high_factor = high_factor * Math.min(ratio, 10);
57844
+ } else {
57845
+ high_factor = high_factor * 2;
57846
+ }
57847
+ expansions++;
57848
+ continue;
57849
+ }
57850
+ } else {
57851
+ high_factor = mid_factor;
57852
+ }
57853
+ if (Math.abs(high_factor - low_factor) < 0.00001 && diff > tolerance) {
57854
+ if (testSellQty < knownSellQuantity && expansions < max_expansions) {
57855
+ high_factor = high_factor * 1.1;
57856
+ expansions++;
57857
+ continue;
57858
+ } else {
57859
+ break;
57860
+ }
57861
+ }
57862
+ }
57863
+ return to_f(best_factor, price_places);
57864
+ }
57560
57865
  function determineRewardFactor(payload) {
57561
57866
  const { quantity, avg_qty, minimum_pnl, risk } = payload;
57562
57867
  const reward_factor = minimum_pnl / risk;
@@ -57771,7 +58076,7 @@ function constructAppConfig(payload) {
57771
58076
  kelly_minimum_risk: kelly_config?.kelly_minimum_risk ?? kelly?.kelly_minimum_risk,
57772
58077
  kelly_prediction_model: kelly_config?.kelly_prediction_model ?? kelly?.kelly_prediction_model
57773
58078
  };
57774
- const appConfig = buildAppConfig(global_config, options);
58079
+ const { entries: _entries, ...appConfig } = buildAppConfig(global_config, options);
57775
58080
  return appConfig;
57776
58081
  }
57777
58082
  function generateDangerousConfig(payload) {
@@ -60730,7 +61035,6 @@ async function reduceMajorPositionEntry(input, accountInfo, trigger2, exchange_i
60730
61035
  // src/position.ts
60731
61036
  var import_https_proxy_agent2 = __toESM(require_dist2(), 1);
60732
61037
  var import_socks_proxy_agent2 = __toESM(require_dist3(), 1);
60733
-
60734
61038
  class ExchangePosition {
60735
61039
  exchange;
60736
61040
  symbol_config;
@@ -60770,6 +61074,19 @@ class ExchangePosition {
60770
61074
  const { p_account } = this.instance.expand;
60771
61075
  return p_account;
60772
61076
  }
61077
+ get compound() {
61078
+ const { compound_instance } = this.instance.expand;
61079
+ if (compound_instance) {
61080
+ const { ref } = compound_instance.expand;
61081
+ const profit_percent = ref.profit_percent / 100;
61082
+ return {
61083
+ ...compound_instance,
61084
+ profit_percent,
61085
+ amount_to_risk: to_f(compound_instance.risk * profit_percent, "%.2f")
61086
+ };
61087
+ }
61088
+ return compound_instance;
61089
+ }
60773
61090
  async getProxyForAccount() {
60774
61091
  if (this.instance.expand.proxy) {
60775
61092
  const result = this.instance.expand.proxy;
@@ -60895,7 +61212,8 @@ class ExchangePosition {
60895
61212
  place,
60896
61213
  raw: payload.raw,
60897
61214
  use_current,
60898
- stop_percent: config2.stop_percent || 100
61215
+ stop_percent: config2.stop_percent || 100,
61216
+ distribution: config2.distribution
60899
61217
  });
60900
61218
  }
60901
61219
  }
@@ -60929,7 +61247,8 @@ class ExchangePosition {
60929
61247
  kelly_confidence_factor: config2.kelly?.kelly_confidence_factor,
60930
61248
  kelly_minimum_risk: config2.kelly?.kelly_minimum_risk,
60931
61249
  kelly_prediction_model: config2.kelly?.kelly_prediction_model,
60932
- kelly_func: config2.kelly?.kelly_func
61250
+ kelly_func: config2.kelly?.kelly_func,
61251
+ distribution: config2.distribution
60933
61252
  }, false);
60934
61253
  if (payload.raw) {
60935
61254
  let actual_orders_to_buy = await this.determineAmountToBuy({
@@ -61052,7 +61371,8 @@ class ExchangePosition {
61052
61371
  kelly_confidence_factor: solution.kelly_confidence_factor,
61053
61372
  kelly_minimum_risk: solution.kelly_minimum_risk,
61054
61373
  kelly_prediction_model: solution.kelly_prediction_model,
61055
- kelly_func: solution.kelly_func
61374
+ kelly_func: solution.kelly_func,
61375
+ distribution: solution.distribution
61056
61376
  };
61057
61377
  const trades = sortedBuildConfig(app_config, options);
61058
61378
  const entry_orders = {
@@ -61444,6 +61764,7 @@ class ExchangePosition {
61444
61764
  });
61445
61765
  }
61446
61766
  async generate_config_params(payload) {
61767
+ const db_config = await this.getConfig();
61447
61768
  const { entry, stop, risk_reward, risk, with_trades = false } = payload;
61448
61769
  const symbol = this.symbol;
61449
61770
  const app_config = await this.buildAppConfig({
@@ -61476,7 +61797,8 @@ class ExchangePosition {
61476
61797
  avg_size: 0,
61477
61798
  neg_pnl: 0,
61478
61799
  min_size: app_config2.min_size,
61479
- symbol
61800
+ symbol,
61801
+ distribution: db_config.distribution
61480
61802
  }, false);
61481
61803
  config2.trades = trades;
61482
61804
  }
@@ -61577,7 +61899,8 @@ class ExchangePosition {
61577
61899
  kelly_confidence_factor: config2.kelly?.kelly_confidence_factor,
61578
61900
  kelly_minimum_risk: config2.kelly?.kelly_minimum_risk,
61579
61901
  kelly_prediction_model: config2.kelly?.kelly_prediction_model,
61580
- kelly_func: config2.kelly?.kelly_func
61902
+ kelly_func: config2.kelly?.kelly_func,
61903
+ distribution: config2.distribution
61581
61904
  });
61582
61905
  const position2 = this.instance;
61583
61906
  const orders_to_place = await this.determineAmountToBuy({
@@ -61775,6 +62098,46 @@ class ExchangePosition {
61775
62098
  increase: false
61776
62099
  });
61777
62100
  }
62101
+ get support() {
62102
+ return this.instance.expand?.support;
62103
+ }
62104
+ get linkedConfig() {
62105
+ return this.instance.expand?.b_config;
62106
+ }
62107
+ get isActiveTrade() {
62108
+ const config2 = this.linkedConfig;
62109
+ return {
62110
+ config: config2,
62111
+ condition: this.compound && this.support?.price === config2.stop
62112
+ };
62113
+ }
62114
+ async updateCompound(payload) {
62115
+ const pb = this.app_db.pb;
62116
+ const item = this.compound;
62117
+ const new_risk = item.risk + item.amount_to_risk;
62118
+ const { condition, config: config2 } = this.isActiveTrade;
62119
+ if (payload?.place && condition) {
62120
+ await pb.collection("compound_instances").update(item.id, {
62121
+ risk: new_risk
62122
+ });
62123
+ await pb.collection("scheduled_trades").update(config2.id, {
62124
+ profit: to_f(new_risk * item.profit_percent, "%.3f")
62125
+ });
62126
+ }
62127
+ return {
62128
+ support: this.support?.price,
62129
+ counter: this.support?.counter,
62130
+ new_risk,
62131
+ condition,
62132
+ stop: config2.stop
62133
+ };
62134
+ }
62135
+ async cleanOnActiveCompoundInstance() {
62136
+ const { condition } = this.isActiveTrade;
62137
+ if (condition && this.instance.quantity === 0) {
62138
+ await this.cancelOrders({ limit: true });
62139
+ }
62140
+ }
61778
62141
  }
61779
62142
  function convert_to_exchange_order(order) {
61780
62143
  return {
@@ -64060,6 +64423,8 @@ export {
64060
64423
  constructAppConfig,
64061
64424
  computeRiskReward,
64062
64425
  computeProfitDetail,
64426
+ calculateFactorFromTakeProfit,
64427
+ calculateFactorFromSellQuantity,
64063
64428
  buildConfig,
64064
64429
  buildAvg,
64065
64430
  buildAppConfig,