@gbozee/ultimate 0.0.2-78 → 0.0.2-82

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.
@@ -58220,6 +58220,18 @@ class AppDatabase {
58220
58220
  await this.saveCredentials(password, credentials);
58221
58221
  }
58222
58222
  }
58223
+ async getAccountWithActivePositions() {
58224
+ const positions = await this.pb.collection("positions").getFullList({
58225
+ filter: `quantity > 0`,
58226
+ fields: `account`
58227
+ });
58228
+ const accounts = Array.from(new Set(positions.map((p) => p.account)));
58229
+ const filter = accounts.map((a) => `id = "${a}"`).join(" || ");
58230
+ const account_instances = await this.pb.collection("exchange_accounts").getFullList({
58231
+ filter
58232
+ });
58233
+ return account_instances;
58234
+ }
58223
58235
  async getAllSymbolsFromPositions(options) {
58224
58236
  const { no_position = false, kind = "long", custom_filter } = options || {};
58225
58237
  let filter = custom_filter || (no_position ? `quantity = 0` : undefined);
@@ -59806,7 +59818,7 @@ class Signal {
59806
59818
  new_stop
59807
59819
  };
59808
59820
  });
59809
- if (greater_than_min_size.length !== less_than_min_size.length) {
59821
+ if (greater_than_min_size.length !== total_orders.length) {
59810
59822
  payload = greater_than_min_size.concat(less_than_min_size);
59811
59823
  }
59812
59824
  return payload;
@@ -59966,9 +59978,7 @@ function buildConfig(app_config, {
59966
59978
  }
59967
59979
  const condition = (kind === "long" ? entry > app_config.support : entry >= app_config.support) && stop >= app_config.support * 0.999;
59968
59980
  if (kind === "short") {
59969
- console.log("condition", condition, entry === stop);
59970
59981
  }
59971
- console.log({ entry, support: app_config.support, stop });
59972
59982
  const result = entry === stop ? [] : condition ? instance.build_entry({
59973
59983
  current_price: entry,
59974
59984
  stop_loss: stop,
@@ -60284,7 +60294,6 @@ function generateOptimumAppConfig(config2, payload, position2) {
60284
60294
  const tolerance = 0.1;
60285
60295
  const max_iterations = 150;
60286
60296
  let iterations = 0;
60287
- console.log(`Starting risk search for ${position2.kind} position. Target Entry: ${position2.entry}, Initial Risk Range: [${low_risk}, ${high_risk}]`);
60288
60297
  while (high_risk - low_risk > tolerance && iterations < max_iterations) {
60289
60298
  iterations++;
60290
60299
  const mid_risk = (low_risk + high_risk) / 2;
@@ -60330,9 +60339,7 @@ function generateOptimumAppConfig(config2, payload, position2) {
60330
60339
  price_places: current_app_config.price_places,
60331
60340
  decimal_places: current_app_config.decimal_places
60332
60341
  });
60333
- console.log(`Iteration ${iterations}: Risk=${mid_risk.toFixed(2)}, Low=${low_risk.toFixed(2)}, High=${high_risk.toFixed(2)}`);
60334
60342
  if (full_trades.length === 0) {
60335
- console.log(` -> No trades generated by sortedBuildConfig at Risk=${mid_risk.toFixed(2)}. Adjusting high_risk down.`);
60336
60343
  high_risk = mid_risk;
60337
60344
  continue;
60338
60345
  }
@@ -60345,29 +60352,23 @@ function generateOptimumAppConfig(config2, payload, position2) {
60345
60352
  existingOrders: []
60346
60353
  });
60347
60354
  if (trades.length === 0) {
60348
- console.log(` -> No trades met quantity requirement after filtering at Risk=${mid_risk.toFixed(2)}. Adjusting low_risk up.`);
60349
60355
  low_risk = mid_risk;
60350
60356
  continue;
60351
60357
  }
60352
60358
  const last_trade = trades[trades.length - 1];
60353
60359
  const last_entry = last_trade.entry;
60354
- console.log(` -> Last Trade Entry (Filtered): ${last_entry.toFixed(4)}`);
60355
60360
  if (position2.kind === "long") {
60356
60361
  if (last_entry > position2.entry) {
60357
- console.log(` -> Constraint VIOLATED (Long): last_entry (${last_entry.toFixed(4)}) > position.entry (${position2.entry.toFixed(4)}). Reducing high_risk.`);
60358
60362
  high_risk = mid_risk;
60359
60363
  } else {
60360
- console.log(` -> Constraint MET (Long): last_entry (${last_entry.toFixed(4)}) <= position.entry (${position2.entry.toFixed(4)}). Storing as best, increasing low_risk.`);
60361
60364
  best_risk = mid_risk;
60362
60365
  best_app_config = current_app_config;
60363
60366
  low_risk = mid_risk;
60364
60367
  }
60365
60368
  } else {
60366
60369
  if (last_entry < position2.entry) {
60367
- console.log(` -> Constraint VIOLATED (Short): last_entry (${last_entry.toFixed(4)}) < position.entry (${position2.entry.toFixed(4)}). Reducing high_risk.`);
60368
60370
  high_risk = mid_risk;
60369
60371
  } else {
60370
- console.log(` -> Constraint MET (Short): last_entry (${last_entry.toFixed(4)}) >= position.entry (${position2.entry.toFixed(4)}). Storing as best, increasing low_risk.`);
60371
60372
  best_risk = mid_risk;
60372
60373
  best_app_config = current_app_config;
60373
60374
  low_risk = mid_risk;
@@ -60605,7 +60606,6 @@ class Strategy {
60605
60606
  quantity,
60606
60607
  kind
60607
60608
  };
60608
- console.log({ second_payload, third_payload });
60609
60609
  const app_config = generateOptimumAppConfig(this.config.global_config, second_payload, third_payload);
60610
60610
  let entries = [];
60611
60611
  let risk_per_trade = this.config.budget;
@@ -60618,6 +60618,7 @@ class Strategy {
60618
60618
  if (ignore_entries) {
60619
60619
  entries = [];
60620
60620
  }
60621
+ console.log({ app_config });
60621
60622
  }
60622
60623
  const risk = this.to_f(risk_per_trade);
60623
60624
  let below_reverse_entries = kind === "long" ? entries.filter((u) => {
@@ -65351,6 +65352,7 @@ class ExchangeAccount {
65351
65352
  kind,
65352
65353
  place,
65353
65354
  tp,
65355
+ limit = true,
65354
65356
  raw: _raw,
65355
65357
  cancel,
65356
65358
  stop,
@@ -65363,13 +65365,14 @@ class ExchangeAccount {
65363
65365
  kind
65364
65366
  });
65365
65367
  }
65366
- if (place) {
65368
+ if (limit) {
65367
65369
  return await this.triggerTradeFromConfig({
65368
65370
  symbol,
65369
65371
  kind,
65370
65372
  raw: payload.raw,
65371
65373
  stop,
65372
- ignore_config
65374
+ ignore_config,
65375
+ place
65373
65376
  });
65374
65377
  }
65375
65378
  await this.syncAccount({
@@ -65458,7 +65461,6 @@ async function getExchangeAccount(payload) {
65458
65461
  app_db
65459
65462
  });
65460
65463
  }
65461
-
65462
65464
  // src/app.ts
65463
65465
  class App {
65464
65466
  app_db;
@@ -65517,37 +65519,6 @@ class App {
65517
65519
  stop: payload.stop
65518
65520
  });
65519
65521
  }
65520
- async updateReduceRatio(payload) {
65521
- const { symbol } = payload;
65522
- const exchange_account = await this.getExchangeAccount(payload.account);
65523
- const positions = await exchange_account.syncAccount({
65524
- as_view: true,
65525
- symbol
65526
- });
65527
- const active_account = await exchange_account.getActiveAccount({
65528
- symbol
65529
- });
65530
- const long_position = active_account.position.long;
65531
- const short_position = active_account.position.short;
65532
- const long_db_position = positions.find((p) => p.kind === "long");
65533
- const short_db_position = positions.find((p) => p.kind === "short");
65534
- const balance = active_account.usd_balance || 0;
65535
- const long_liquidation = long_db_position.avg_price * long_db_position.avg_qty / long_db_position.leverage - balance / long_db_position.avg_qty + long_db_position.avg_price;
65536
- const short_liquidation = -(short_db_position.avg_price * short_db_position.avg_qty / short_db_position.leverage) + balance / short_db_position.avg_qty + short_db_position.avg_price;
65537
- long_position.avg_liquidation = to_f2(long_liquidation, "%.3f");
65538
- short_position.avg_liquidation = to_f2(short_liquidation, "%.3f");
65539
- const long_ratio = Math.max(long_position.avg_liquidation, long_position.avg_entry) / Math.min(long_position.avg_liquidation, long_position.avg_entry) - 1;
65540
- const short_ratio = Math.max(short_position.avg_liquidation, short_position.avg_entry) / Math.min(short_position.avg_liquidation, short_position.avg_entry) - 1;
65541
- long_position.liquidation_ratio = to_f2(long_ratio, "%.3f") * 100;
65542
- short_position.liquidation_ratio = to_f2(short_ratio, "%.3f") * 100;
65543
- return {
65544
- long_position,
65545
- short_position,
65546
- long_db_position,
65547
- short_db_position,
65548
- balance: active_account.usd_balance
65549
- };
65550
- }
65551
65522
  async getWindingDownMarkets() {
65552
65523
  return await this.app_db.getWindingDownMarkets();
65553
65524
  }
@@ -65696,7 +65667,7 @@ class App {
65696
65667
  return await this.app_db.getMoverExchangeInstances();
65697
65668
  }
65698
65669
  async updateTpOnAllMarkets() {
65699
- const move_instances = await this.getMoverExchangeInstances();
65670
+ const move_instances = await this.app_db.getAccountWithActivePositions();
65700
65671
  for (const instance of move_instances) {
65701
65672
  const params = {
65702
65673
  account: {
@@ -65757,6 +65728,171 @@ class App {
65757
65728
  });
65758
65729
  return result;
65759
65730
  }
65731
+ async profitWithinGapStrategy(payload) {
65732
+ const {
65733
+ account,
65734
+ symbol,
65735
+ kind,
65736
+ risk,
65737
+ resistance,
65738
+ support,
65739
+ reward_factor = 1
65740
+ } = payload;
65741
+ const exchange_account = await this.getExchangeAccount(account);
65742
+ console.log("Getting entry and stop for ", symbol, kind);
65743
+ const entry = kind === "long" ? resistance : support;
65744
+ const stop = kind === "long" ? support : resistance;
65745
+ console.log("Building app config for ", symbol, kind);
65746
+ const initial_app_config = await exchange_account.buildAppConfig({
65747
+ entry,
65748
+ stop,
65749
+ risk_reward: 199,
65750
+ risk,
65751
+ symbol
65752
+ });
65753
+ console.log("Computing risk reward for ", symbol, kind);
65754
+ const risk_reward = computeRiskReward({
65755
+ app_config: initial_app_config,
65756
+ entry: initial_app_config.entry,
65757
+ stop: initial_app_config.stop,
65758
+ risk_per_trade: initial_app_config.risk_per_trade
65759
+ });
65760
+ console.log("Re-computing app config for ", symbol, kind);
65761
+ const { entries, last_value, ...app_config } = await exchange_account.buildAppConfig({
65762
+ entry: initial_app_config.entry,
65763
+ stop: initial_app_config.stop,
65764
+ risk_reward,
65765
+ risk,
65766
+ symbol
65767
+ });
65768
+ console.log("Computing profit percent for ", symbol, kind);
65769
+ const pnl = reward_factor * risk;
65770
+ const profit_percent = to_f2(pnl * 100 / (last_value.avg_entry * last_value.avg_size), "%.4f");
65771
+ let config2 = {
65772
+ entry,
65773
+ stop,
65774
+ risk,
65775
+ risk_reward,
65776
+ profit_percent
65777
+ };
65778
+ console.log("Saving new config for ", symbol, kind);
65779
+ const data = await exchange_account.getPositionConfig({
65780
+ symbol,
65781
+ kind,
65782
+ params: config2
65783
+ });
65784
+ console.log("Checking orders to place for ", symbol, kind);
65785
+ const orders_to_place = await exchange_account.placeTrade({
65786
+ symbol,
65787
+ raw: true,
65788
+ kind,
65789
+ place: false
65790
+ });
65791
+ config2 = {
65792
+ ...config2,
65793
+ ...data
65794
+ };
65795
+ console.log("Fetching positions for ", symbol);
65796
+ const positions = await exchange_account.syncAccount({
65797
+ symbol,
65798
+ as_view: true
65799
+ });
65800
+ console.log("Getting long and short positions for ", symbol);
65801
+ const long_position = positions.find((k) => k.kind === "long");
65802
+ const short_position = positions.find((k) => k.kind === "short");
65803
+ console.log("Getting focus position for ", symbol, kind);
65804
+ const focus_position = kind === "long" ? long_position : short_position;
65805
+ const reverse_position = kind === "long" ? short_position : long_position;
65806
+ let reverse_action = null;
65807
+ let reverse_orders_to_buy = [];
65808
+ let reverse_config = null;
65809
+ console.log("Checking if focus position has quantity for ", symbol, kind);
65810
+ if (focus_position.quantity > 0) {
65811
+ console.log("Getting details for ", reverse_position.kind);
65812
+ reverse_action = await exchange_account.buildOppositeTrades({
65813
+ symbol,
65814
+ kind
65815
+ });
65816
+ console.log("Updating config for ", symbol, reverse_action.kind);
65817
+ await exchange_account.getPositionConfig({
65818
+ symbol,
65819
+ kind: reverse_action.kind,
65820
+ params: {
65821
+ entry: reverse_action.entry,
65822
+ stop: reverse_action.stop,
65823
+ risk: reverse_action.risk_per_trade,
65824
+ profit_percent: reverse_action.profit_percent,
65825
+ risk_reward: reverse_action.risk_reward
65826
+ }
65827
+ });
65828
+ console.log("Checking reverse orders to buy for ", symbol, reverse_action.kind);
65829
+ reverse_orders_to_buy = await exchange_account.placeTrade({
65830
+ symbol,
65831
+ raw: true,
65832
+ kind: reverse_action.kind,
65833
+ place: false
65834
+ });
65835
+ let _reverse_config = {
65836
+ avg: reverse_action.avg,
65837
+ entry: reverse_action.entry,
65838
+ stop: reverse_action.stop,
65839
+ risk_per_trade: reverse_action.risk_per_trade,
65840
+ profit_percent: reverse_action.profit_percent,
65841
+ risk_reward: reverse_action.risk_reward
65842
+ };
65843
+ if (reverse_orders_to_buy.length > 0) {
65844
+ console.log("Placing opposite trade action for ", symbol, reverse_action.kind);
65845
+ let existing = await exchange_account.placeOppositeTradeAction({
65846
+ symbol,
65847
+ kind: reverse_action.kind,
65848
+ data: _reverse_config
65849
+ });
65850
+ _reverse_config = {
65851
+ ...existing,
65852
+ ..._reverse_config
65853
+ };
65854
+ }
65855
+ reverse_config = _reverse_config;
65856
+ if (!reverse_config?.id) {
65857
+ console.log("fetching reverse config for ", symbol, reverse_action.kind);
65858
+ reverse_config = await exchange_account.getPositionConfig({
65859
+ symbol,
65860
+ kind: reverse_action.kind
65861
+ });
65862
+ }
65863
+ if (reverse_position.quantity > 0 && reverse_config?.id) {
65864
+ console.log("Checking if reverse position has quantity for ", symbol, reverse_action.kind);
65865
+ const max_size = app_config.max_size * 0.98;
65866
+ if (reverse_config.threshold_qty !== max_size) {
65867
+ await this.app_db.updateScheduledTrade(reverse_config.id, {
65868
+ follow: true,
65869
+ threshold_qty: max_size
65870
+ });
65871
+ }
65872
+ console.log("Updating follow and threshold for ", symbol, reverse_action.kind);
65873
+ } else {
65874
+ await this.app_db.updateScheduledTrade(reverse_config.id, {
65875
+ follow: false
65876
+ });
65877
+ }
65878
+ }
65879
+ return {
65880
+ reverse_config,
65881
+ reverse_action,
65882
+ reverse_orders_to_buy,
65883
+ positions: {
65884
+ long: long_position,
65885
+ short: short_position
65886
+ },
65887
+ orders_to_place,
65888
+ config_details: {
65889
+ app_config,
65890
+ last_value,
65891
+ config: config2,
65892
+ pnl
65893
+ }
65894
+ };
65895
+ }
65760
65896
  }
65761
65897
  async function initApp(payload) {
65762
65898
  const pb = await initPocketBaseClient(payload.db);
@@ -65891,13 +66027,13 @@ async function getPositions(payload) {
65891
66027
  const symbol_config = await exchange_account.recomputeSymbolConfig({
65892
66028
  symbol: payload.symbol
65893
66029
  });
65894
- const strategy = await exchange_account.getPositionStrategy();
66030
+ const strategy2 = await exchange_account.getPositionStrategy();
65895
66031
  const strategy_config = {
65896
- tp_percent: strategy?.tp_percent,
65897
- short_tp_factor: strategy?.short_tp_factor,
65898
- fee_percent: strategy?.fee_percent,
65899
- budget: strategy?.budget,
65900
- risk_reward: strategy?.risk_reward,
66032
+ tp_percent: strategy2?.tp_percent,
66033
+ short_tp_factor: strategy2?.short_tp_factor,
66034
+ fee_percent: strategy2?.fee_percent,
66035
+ budget: strategy2?.budget,
66036
+ risk_reward: strategy2?.risk_reward,
65901
66037
  global_config: symbol_config
65902
66038
  };
65903
66039
  const positions = await exchange_account.syncAccount({