@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.
@@ -58197,6 +58197,18 @@ class AppDatabase {
58197
58197
  await this.saveCredentials(password, credentials);
58198
58198
  }
58199
58199
  }
58200
+ async getAccountWithActivePositions() {
58201
+ const positions = await this.pb.collection("positions").getFullList({
58202
+ filter: `quantity > 0`,
58203
+ fields: `account`
58204
+ });
58205
+ const accounts = Array.from(new Set(positions.map((p) => p.account)));
58206
+ const filter = accounts.map((a) => `id = "${a}"`).join(" || ");
58207
+ const account_instances = await this.pb.collection("exchange_accounts").getFullList({
58208
+ filter
58209
+ });
58210
+ return account_instances;
58211
+ }
58200
58212
  async getAllSymbolsFromPositions(options) {
58201
58213
  const { no_position = false, kind = "long", custom_filter } = options || {};
58202
58214
  let filter = custom_filter || (no_position ? `quantity = 0` : undefined);
@@ -59783,7 +59795,7 @@ class Signal {
59783
59795
  new_stop
59784
59796
  };
59785
59797
  });
59786
- if (greater_than_min_size.length !== less_than_min_size.length) {
59798
+ if (greater_than_min_size.length !== total_orders.length) {
59787
59799
  payload = greater_than_min_size.concat(less_than_min_size);
59788
59800
  }
59789
59801
  return payload;
@@ -59943,9 +59955,7 @@ function buildConfig(app_config, {
59943
59955
  }
59944
59956
  const condition = (kind === "long" ? entry > app_config.support : entry >= app_config.support) && stop >= app_config.support * 0.999;
59945
59957
  if (kind === "short") {
59946
- console.log("condition", condition, entry === stop);
59947
59958
  }
59948
- console.log({ entry, support: app_config.support, stop });
59949
59959
  const result = entry === stop ? [] : condition ? instance.build_entry({
59950
59960
  current_price: entry,
59951
59961
  stop_loss: stop,
@@ -60261,7 +60271,6 @@ function generateOptimumAppConfig(config2, payload, position2) {
60261
60271
  const tolerance = 0.1;
60262
60272
  const max_iterations = 150;
60263
60273
  let iterations = 0;
60264
- console.log(`Starting risk search for ${position2.kind} position. Target Entry: ${position2.entry}, Initial Risk Range: [${low_risk}, ${high_risk}]`);
60265
60274
  while (high_risk - low_risk > tolerance && iterations < max_iterations) {
60266
60275
  iterations++;
60267
60276
  const mid_risk = (low_risk + high_risk) / 2;
@@ -60307,9 +60316,7 @@ function generateOptimumAppConfig(config2, payload, position2) {
60307
60316
  price_places: current_app_config.price_places,
60308
60317
  decimal_places: current_app_config.decimal_places
60309
60318
  });
60310
- console.log(`Iteration ${iterations}: Risk=${mid_risk.toFixed(2)}, Low=${low_risk.toFixed(2)}, High=${high_risk.toFixed(2)}`);
60311
60319
  if (full_trades.length === 0) {
60312
- console.log(` -> No trades generated by sortedBuildConfig at Risk=${mid_risk.toFixed(2)}. Adjusting high_risk down.`);
60313
60320
  high_risk = mid_risk;
60314
60321
  continue;
60315
60322
  }
@@ -60322,29 +60329,23 @@ function generateOptimumAppConfig(config2, payload, position2) {
60322
60329
  existingOrders: []
60323
60330
  });
60324
60331
  if (trades.length === 0) {
60325
- console.log(` -> No trades met quantity requirement after filtering at Risk=${mid_risk.toFixed(2)}. Adjusting low_risk up.`);
60326
60332
  low_risk = mid_risk;
60327
60333
  continue;
60328
60334
  }
60329
60335
  const last_trade = trades[trades.length - 1];
60330
60336
  const last_entry = last_trade.entry;
60331
- console.log(` -> Last Trade Entry (Filtered): ${last_entry.toFixed(4)}`);
60332
60337
  if (position2.kind === "long") {
60333
60338
  if (last_entry > position2.entry) {
60334
- console.log(` -> Constraint VIOLATED (Long): last_entry (${last_entry.toFixed(4)}) > position.entry (${position2.entry.toFixed(4)}). Reducing high_risk.`);
60335
60339
  high_risk = mid_risk;
60336
60340
  } else {
60337
- console.log(` -> Constraint MET (Long): last_entry (${last_entry.toFixed(4)}) <= position.entry (${position2.entry.toFixed(4)}). Storing as best, increasing low_risk.`);
60338
60341
  best_risk = mid_risk;
60339
60342
  best_app_config = current_app_config;
60340
60343
  low_risk = mid_risk;
60341
60344
  }
60342
60345
  } else {
60343
60346
  if (last_entry < position2.entry) {
60344
- console.log(` -> Constraint VIOLATED (Short): last_entry (${last_entry.toFixed(4)}) < position.entry (${position2.entry.toFixed(4)}). Reducing high_risk.`);
60345
60347
  high_risk = mid_risk;
60346
60348
  } else {
60347
- console.log(` -> Constraint MET (Short): last_entry (${last_entry.toFixed(4)}) >= position.entry (${position2.entry.toFixed(4)}). Storing as best, increasing low_risk.`);
60348
60349
  best_risk = mid_risk;
60349
60350
  best_app_config = current_app_config;
60350
60351
  low_risk = mid_risk;
@@ -60582,7 +60583,6 @@ class Strategy {
60582
60583
  quantity,
60583
60584
  kind
60584
60585
  };
60585
- console.log({ second_payload, third_payload });
60586
60586
  const app_config = generateOptimumAppConfig(this.config.global_config, second_payload, third_payload);
60587
60587
  let entries = [];
60588
60588
  let risk_per_trade = this.config.budget;
@@ -60595,6 +60595,7 @@ class Strategy {
60595
60595
  if (ignore_entries) {
60596
60596
  entries = [];
60597
60597
  }
60598
+ console.log({ app_config });
60598
60599
  }
60599
60600
  const risk = this.to_f(risk_per_trade);
60600
60601
  let below_reverse_entries = kind === "long" ? entries.filter((u) => {
@@ -65328,6 +65329,7 @@ class ExchangeAccount {
65328
65329
  kind,
65329
65330
  place,
65330
65331
  tp,
65332
+ limit = true,
65331
65333
  raw: _raw,
65332
65334
  cancel,
65333
65335
  stop,
@@ -65340,13 +65342,14 @@ class ExchangeAccount {
65340
65342
  kind
65341
65343
  });
65342
65344
  }
65343
- if (place) {
65345
+ if (limit) {
65344
65346
  return await this.triggerTradeFromConfig({
65345
65347
  symbol,
65346
65348
  kind,
65347
65349
  raw: payload.raw,
65348
65350
  stop,
65349
- ignore_config
65351
+ ignore_config,
65352
+ place
65350
65353
  });
65351
65354
  }
65352
65355
  await this.syncAccount({
@@ -65435,7 +65438,6 @@ async function getExchangeAccount(payload) {
65435
65438
  app_db
65436
65439
  });
65437
65440
  }
65438
-
65439
65441
  // src/app.ts
65440
65442
  class App {
65441
65443
  app_db;
@@ -65494,37 +65496,6 @@ class App {
65494
65496
  stop: payload.stop
65495
65497
  });
65496
65498
  }
65497
- async updateReduceRatio(payload) {
65498
- const { symbol } = payload;
65499
- const exchange_account = await this.getExchangeAccount(payload.account);
65500
- const positions = await exchange_account.syncAccount({
65501
- as_view: true,
65502
- symbol
65503
- });
65504
- const active_account = await exchange_account.getActiveAccount({
65505
- symbol
65506
- });
65507
- const long_position = active_account.position.long;
65508
- const short_position = active_account.position.short;
65509
- const long_db_position = positions.find((p) => p.kind === "long");
65510
- const short_db_position = positions.find((p) => p.kind === "short");
65511
- const balance = active_account.usd_balance || 0;
65512
- 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;
65513
- 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;
65514
- long_position.avg_liquidation = to_f2(long_liquidation, "%.3f");
65515
- short_position.avg_liquidation = to_f2(short_liquidation, "%.3f");
65516
- const long_ratio = Math.max(long_position.avg_liquidation, long_position.avg_entry) / Math.min(long_position.avg_liquidation, long_position.avg_entry) - 1;
65517
- const short_ratio = Math.max(short_position.avg_liquidation, short_position.avg_entry) / Math.min(short_position.avg_liquidation, short_position.avg_entry) - 1;
65518
- long_position.liquidation_ratio = to_f2(long_ratio, "%.3f") * 100;
65519
- short_position.liquidation_ratio = to_f2(short_ratio, "%.3f") * 100;
65520
- return {
65521
- long_position,
65522
- short_position,
65523
- long_db_position,
65524
- short_db_position,
65525
- balance: active_account.usd_balance
65526
- };
65527
- }
65528
65499
  async getWindingDownMarkets() {
65529
65500
  return await this.app_db.getWindingDownMarkets();
65530
65501
  }
@@ -65673,7 +65644,7 @@ class App {
65673
65644
  return await this.app_db.getMoverExchangeInstances();
65674
65645
  }
65675
65646
  async updateTpOnAllMarkets() {
65676
- const move_instances = await this.getMoverExchangeInstances();
65647
+ const move_instances = await this.app_db.getAccountWithActivePositions();
65677
65648
  for (const instance of move_instances) {
65678
65649
  const params = {
65679
65650
  account: {
@@ -65734,6 +65705,171 @@ class App {
65734
65705
  });
65735
65706
  return result;
65736
65707
  }
65708
+ async profitWithinGapStrategy(payload) {
65709
+ const {
65710
+ account,
65711
+ symbol,
65712
+ kind,
65713
+ risk,
65714
+ resistance,
65715
+ support,
65716
+ reward_factor = 1
65717
+ } = payload;
65718
+ const exchange_account = await this.getExchangeAccount(account);
65719
+ console.log("Getting entry and stop for ", symbol, kind);
65720
+ const entry = kind === "long" ? resistance : support;
65721
+ const stop = kind === "long" ? support : resistance;
65722
+ console.log("Building app config for ", symbol, kind);
65723
+ const initial_app_config = await exchange_account.buildAppConfig({
65724
+ entry,
65725
+ stop,
65726
+ risk_reward: 199,
65727
+ risk,
65728
+ symbol
65729
+ });
65730
+ console.log("Computing risk reward for ", symbol, kind);
65731
+ const risk_reward = computeRiskReward({
65732
+ app_config: initial_app_config,
65733
+ entry: initial_app_config.entry,
65734
+ stop: initial_app_config.stop,
65735
+ risk_per_trade: initial_app_config.risk_per_trade
65736
+ });
65737
+ console.log("Re-computing app config for ", symbol, kind);
65738
+ const { entries, last_value, ...app_config } = await exchange_account.buildAppConfig({
65739
+ entry: initial_app_config.entry,
65740
+ stop: initial_app_config.stop,
65741
+ risk_reward,
65742
+ risk,
65743
+ symbol
65744
+ });
65745
+ console.log("Computing profit percent for ", symbol, kind);
65746
+ const pnl = reward_factor * risk;
65747
+ const profit_percent = to_f2(pnl * 100 / (last_value.avg_entry * last_value.avg_size), "%.4f");
65748
+ let config2 = {
65749
+ entry,
65750
+ stop,
65751
+ risk,
65752
+ risk_reward,
65753
+ profit_percent
65754
+ };
65755
+ console.log("Saving new config for ", symbol, kind);
65756
+ const data = await exchange_account.getPositionConfig({
65757
+ symbol,
65758
+ kind,
65759
+ params: config2
65760
+ });
65761
+ console.log("Checking orders to place for ", symbol, kind);
65762
+ const orders_to_place = await exchange_account.placeTrade({
65763
+ symbol,
65764
+ raw: true,
65765
+ kind,
65766
+ place: false
65767
+ });
65768
+ config2 = {
65769
+ ...config2,
65770
+ ...data
65771
+ };
65772
+ console.log("Fetching positions for ", symbol);
65773
+ const positions = await exchange_account.syncAccount({
65774
+ symbol,
65775
+ as_view: true
65776
+ });
65777
+ console.log("Getting long and short positions for ", symbol);
65778
+ const long_position = positions.find((k) => k.kind === "long");
65779
+ const short_position = positions.find((k) => k.kind === "short");
65780
+ console.log("Getting focus position for ", symbol, kind);
65781
+ const focus_position = kind === "long" ? long_position : short_position;
65782
+ const reverse_position = kind === "long" ? short_position : long_position;
65783
+ let reverse_action = null;
65784
+ let reverse_orders_to_buy = [];
65785
+ let reverse_config = null;
65786
+ console.log("Checking if focus position has quantity for ", symbol, kind);
65787
+ if (focus_position.quantity > 0) {
65788
+ console.log("Getting details for ", reverse_position.kind);
65789
+ reverse_action = await exchange_account.buildOppositeTrades({
65790
+ symbol,
65791
+ kind
65792
+ });
65793
+ console.log("Updating config for ", symbol, reverse_action.kind);
65794
+ await exchange_account.getPositionConfig({
65795
+ symbol,
65796
+ kind: reverse_action.kind,
65797
+ params: {
65798
+ entry: reverse_action.entry,
65799
+ stop: reverse_action.stop,
65800
+ risk: reverse_action.risk_per_trade,
65801
+ profit_percent: reverse_action.profit_percent,
65802
+ risk_reward: reverse_action.risk_reward
65803
+ }
65804
+ });
65805
+ console.log("Checking reverse orders to buy for ", symbol, reverse_action.kind);
65806
+ reverse_orders_to_buy = await exchange_account.placeTrade({
65807
+ symbol,
65808
+ raw: true,
65809
+ kind: reverse_action.kind,
65810
+ place: false
65811
+ });
65812
+ let _reverse_config = {
65813
+ avg: reverse_action.avg,
65814
+ entry: reverse_action.entry,
65815
+ stop: reverse_action.stop,
65816
+ risk_per_trade: reverse_action.risk_per_trade,
65817
+ profit_percent: reverse_action.profit_percent,
65818
+ risk_reward: reverse_action.risk_reward
65819
+ };
65820
+ if (reverse_orders_to_buy.length > 0) {
65821
+ console.log("Placing opposite trade action for ", symbol, reverse_action.kind);
65822
+ let existing = await exchange_account.placeOppositeTradeAction({
65823
+ symbol,
65824
+ kind: reverse_action.kind,
65825
+ data: _reverse_config
65826
+ });
65827
+ _reverse_config = {
65828
+ ...existing,
65829
+ ..._reverse_config
65830
+ };
65831
+ }
65832
+ reverse_config = _reverse_config;
65833
+ if (!reverse_config?.id) {
65834
+ console.log("fetching reverse config for ", symbol, reverse_action.kind);
65835
+ reverse_config = await exchange_account.getPositionConfig({
65836
+ symbol,
65837
+ kind: reverse_action.kind
65838
+ });
65839
+ }
65840
+ if (reverse_position.quantity > 0 && reverse_config?.id) {
65841
+ console.log("Checking if reverse position has quantity for ", symbol, reverse_action.kind);
65842
+ const max_size = app_config.max_size * 0.98;
65843
+ if (reverse_config.threshold_qty !== max_size) {
65844
+ await this.app_db.updateScheduledTrade(reverse_config.id, {
65845
+ follow: true,
65846
+ threshold_qty: max_size
65847
+ });
65848
+ }
65849
+ console.log("Updating follow and threshold for ", symbol, reverse_action.kind);
65850
+ } else {
65851
+ await this.app_db.updateScheduledTrade(reverse_config.id, {
65852
+ follow: false
65853
+ });
65854
+ }
65855
+ }
65856
+ return {
65857
+ reverse_config,
65858
+ reverse_action,
65859
+ reverse_orders_to_buy,
65860
+ positions: {
65861
+ long: long_position,
65862
+ short: short_position
65863
+ },
65864
+ orders_to_place,
65865
+ config_details: {
65866
+ app_config,
65867
+ last_value,
65868
+ config: config2,
65869
+ pnl
65870
+ }
65871
+ };
65872
+ }
65737
65873
  }
65738
65874
  async function initApp(payload) {
65739
65875
  const pb = await initPocketBaseClient(payload.db);
@@ -65868,13 +66004,13 @@ async function getPositions(payload) {
65868
66004
  const symbol_config = await exchange_account.recomputeSymbolConfig({
65869
66005
  symbol: payload.symbol
65870
66006
  });
65871
- const strategy = await exchange_account.getPositionStrategy();
66007
+ const strategy2 = await exchange_account.getPositionStrategy();
65872
66008
  const strategy_config = {
65873
- tp_percent: strategy?.tp_percent,
65874
- short_tp_factor: strategy?.short_tp_factor,
65875
- fee_percent: strategy?.fee_percent,
65876
- budget: strategy?.budget,
65877
- risk_reward: strategy?.risk_reward,
66009
+ tp_percent: strategy2?.tp_percent,
66010
+ short_tp_factor: strategy2?.short_tp_factor,
66011
+ fee_percent: strategy2?.fee_percent,
66012
+ budget: strategy2?.budget,
66013
+ risk_reward: strategy2?.risk_reward,
65878
66014
  global_config: symbol_config
65879
66015
  };
65880
66016
  const positions = await exchange_account.syncAccount({
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@gbozee/ultimate",
3
3
  "type": "module",
4
- "version": "0.0.2-78",
4
+ "version": "0.0.2-82",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",