@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.
package/dist/index.js CHANGED
@@ -51464,6 +51464,18 @@ class AppDatabase {
51464
51464
  await this.saveCredentials(password, credentials);
51465
51465
  }
51466
51466
  }
51467
+ async getAccountWithActivePositions() {
51468
+ const positions = await this.pb.collection("positions").getFullList({
51469
+ filter: `quantity > 0`,
51470
+ fields: `account`
51471
+ });
51472
+ const accounts = Array.from(new Set(positions.map((p) => p.account)));
51473
+ const filter = accounts.map((a) => `id = "${a}"`).join(" || ");
51474
+ const account_instances = await this.pb.collection("exchange_accounts").getFullList({
51475
+ filter
51476
+ });
51477
+ return account_instances;
51478
+ }
51467
51479
  async getAllSymbolsFromPositions(options) {
51468
51480
  const { no_position = false, kind = "long", custom_filter } = options || {};
51469
51481
  let filter = custom_filter || (no_position ? `quantity = 0` : undefined);
@@ -53057,7 +53069,7 @@ class Signal {
53057
53069
  new_stop
53058
53070
  };
53059
53071
  });
53060
- if (greater_than_min_size.length !== less_than_min_size.length) {
53072
+ if (greater_than_min_size.length !== total_orders.length) {
53061
53073
  payload = greater_than_min_size.concat(less_than_min_size);
53062
53074
  }
53063
53075
  return payload;
@@ -53217,9 +53229,7 @@ function buildConfig(app_config, {
53217
53229
  }
53218
53230
  const condition = (kind === "long" ? entry > app_config.support : entry >= app_config.support) && stop >= app_config.support * 0.999;
53219
53231
  if (kind === "short") {
53220
- console.log("condition", condition, entry === stop);
53221
53232
  }
53222
- console.log({ entry, support: app_config.support, stop });
53223
53233
  const result = entry === stop ? [] : condition ? instance.build_entry({
53224
53234
  current_price: entry,
53225
53235
  stop_loss: stop,
@@ -53548,7 +53558,6 @@ function generateOptimumAppConfig(config2, payload, position2) {
53548
53558
  const tolerance = 0.1;
53549
53559
  const max_iterations = 150;
53550
53560
  let iterations = 0;
53551
- console.log(`Starting risk search for ${position2.kind} position. Target Entry: ${position2.entry}, Initial Risk Range: [${low_risk}, ${high_risk}]`);
53552
53561
  while (high_risk - low_risk > tolerance && iterations < max_iterations) {
53553
53562
  iterations++;
53554
53563
  const mid_risk = (low_risk + high_risk) / 2;
@@ -53594,9 +53603,7 @@ function generateOptimumAppConfig(config2, payload, position2) {
53594
53603
  price_places: current_app_config.price_places,
53595
53604
  decimal_places: current_app_config.decimal_places
53596
53605
  });
53597
- console.log(`Iteration ${iterations}: Risk=${mid_risk.toFixed(2)}, Low=${low_risk.toFixed(2)}, High=${high_risk.toFixed(2)}`);
53598
53606
  if (full_trades.length === 0) {
53599
- console.log(` -> No trades generated by sortedBuildConfig at Risk=${mid_risk.toFixed(2)}. Adjusting high_risk down.`);
53600
53607
  high_risk = mid_risk;
53601
53608
  continue;
53602
53609
  }
@@ -53609,29 +53616,23 @@ function generateOptimumAppConfig(config2, payload, position2) {
53609
53616
  existingOrders: []
53610
53617
  });
53611
53618
  if (trades.length === 0) {
53612
- console.log(` -> No trades met quantity requirement after filtering at Risk=${mid_risk.toFixed(2)}. Adjusting low_risk up.`);
53613
53619
  low_risk = mid_risk;
53614
53620
  continue;
53615
53621
  }
53616
53622
  const last_trade = trades[trades.length - 1];
53617
53623
  const last_entry = last_trade.entry;
53618
- console.log(` -> Last Trade Entry (Filtered): ${last_entry.toFixed(4)}`);
53619
53624
  if (position2.kind === "long") {
53620
53625
  if (last_entry > position2.entry) {
53621
- console.log(` -> Constraint VIOLATED (Long): last_entry (${last_entry.toFixed(4)}) > position.entry (${position2.entry.toFixed(4)}). Reducing high_risk.`);
53622
53626
  high_risk = mid_risk;
53623
53627
  } else {
53624
- console.log(` -> Constraint MET (Long): last_entry (${last_entry.toFixed(4)}) <= position.entry (${position2.entry.toFixed(4)}). Storing as best, increasing low_risk.`);
53625
53628
  best_risk = mid_risk;
53626
53629
  best_app_config = current_app_config;
53627
53630
  low_risk = mid_risk;
53628
53631
  }
53629
53632
  } else {
53630
53633
  if (last_entry < position2.entry) {
53631
- console.log(` -> Constraint VIOLATED (Short): last_entry (${last_entry.toFixed(4)}) < position.entry (${position2.entry.toFixed(4)}). Reducing high_risk.`);
53632
53634
  high_risk = mid_risk;
53633
53635
  } else {
53634
- console.log(` -> Constraint MET (Short): last_entry (${last_entry.toFixed(4)}) >= position.entry (${position2.entry.toFixed(4)}). Storing as best, increasing low_risk.`);
53635
53636
  best_risk = mid_risk;
53636
53637
  best_app_config = current_app_config;
53637
53638
  low_risk = mid_risk;
@@ -53869,7 +53870,6 @@ class Strategy {
53869
53870
  quantity,
53870
53871
  kind
53871
53872
  };
53872
- console.log({ second_payload, third_payload });
53873
53873
  const app_config = generateOptimumAppConfig(this.config.global_config, second_payload, third_payload);
53874
53874
  let entries = [];
53875
53875
  let risk_per_trade = this.config.budget;
@@ -53882,6 +53882,7 @@ class Strategy {
53882
53882
  if (ignore_entries) {
53883
53883
  entries = [];
53884
53884
  }
53885
+ console.log({ app_config });
53885
53886
  }
53886
53887
  const risk = this.to_f(risk_per_trade);
53887
53888
  let below_reverse_entries = kind === "long" ? entries.filter((u) => {
@@ -58615,6 +58616,7 @@ class ExchangeAccount {
58615
58616
  kind,
58616
58617
  place,
58617
58618
  tp,
58619
+ limit = true,
58618
58620
  raw: _raw,
58619
58621
  cancel,
58620
58622
  stop,
@@ -58627,13 +58629,14 @@ class ExchangeAccount {
58627
58629
  kind
58628
58630
  });
58629
58631
  }
58630
- if (place) {
58632
+ if (limit) {
58631
58633
  return await this.triggerTradeFromConfig({
58632
58634
  symbol,
58633
58635
  kind,
58634
58636
  raw: payload.raw,
58635
58637
  stop,
58636
- ignore_config
58638
+ ignore_config,
58639
+ place
58637
58640
  });
58638
58641
  }
58639
58642
  await this.syncAccount({
@@ -58722,7 +58725,6 @@ async function getExchangeAccount(payload) {
58722
58725
  app_db
58723
58726
  });
58724
58727
  }
58725
-
58726
58728
  // src/app.ts
58727
58729
  class App {
58728
58730
  app_db;
@@ -58781,37 +58783,6 @@ class App {
58781
58783
  stop: payload.stop
58782
58784
  });
58783
58785
  }
58784
- async updateReduceRatio(payload) {
58785
- const { symbol } = payload;
58786
- const exchange_account = await this.getExchangeAccount(payload.account);
58787
- const positions = await exchange_account.syncAccount({
58788
- as_view: true,
58789
- symbol
58790
- });
58791
- const active_account = await exchange_account.getActiveAccount({
58792
- symbol
58793
- });
58794
- const long_position = active_account.position.long;
58795
- const short_position = active_account.position.short;
58796
- const long_db_position = positions.find((p) => p.kind === "long");
58797
- const short_db_position = positions.find((p) => p.kind === "short");
58798
- const balance = active_account.usd_balance || 0;
58799
- 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;
58800
- 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;
58801
- long_position.avg_liquidation = to_f2(long_liquidation, "%.3f");
58802
- short_position.avg_liquidation = to_f2(short_liquidation, "%.3f");
58803
- const long_ratio = Math.max(long_position.avg_liquidation, long_position.avg_entry) / Math.min(long_position.avg_liquidation, long_position.avg_entry) - 1;
58804
- const short_ratio = Math.max(short_position.avg_liquidation, short_position.avg_entry) / Math.min(short_position.avg_liquidation, short_position.avg_entry) - 1;
58805
- long_position.liquidation_ratio = to_f2(long_ratio, "%.3f") * 100;
58806
- short_position.liquidation_ratio = to_f2(short_ratio, "%.3f") * 100;
58807
- return {
58808
- long_position,
58809
- short_position,
58810
- long_db_position,
58811
- short_db_position,
58812
- balance: active_account.usd_balance
58813
- };
58814
- }
58815
58786
  async getWindingDownMarkets() {
58816
58787
  return await this.app_db.getWindingDownMarkets();
58817
58788
  }
@@ -58960,7 +58931,7 @@ class App {
58960
58931
  return await this.app_db.getMoverExchangeInstances();
58961
58932
  }
58962
58933
  async updateTpOnAllMarkets() {
58963
- const move_instances = await this.getMoverExchangeInstances();
58934
+ const move_instances = await this.app_db.getAccountWithActivePositions();
58964
58935
  for (const instance of move_instances) {
58965
58936
  const params = {
58966
58937
  account: {
@@ -59021,6 +58992,171 @@ class App {
59021
58992
  });
59022
58993
  return result;
59023
58994
  }
58995
+ async profitWithinGapStrategy(payload) {
58996
+ const {
58997
+ account,
58998
+ symbol,
58999
+ kind,
59000
+ risk,
59001
+ resistance,
59002
+ support,
59003
+ reward_factor = 1
59004
+ } = payload;
59005
+ const exchange_account = await this.getExchangeAccount(account);
59006
+ console.log("Getting entry and stop for ", symbol, kind);
59007
+ const entry = kind === "long" ? resistance : support;
59008
+ const stop = kind === "long" ? support : resistance;
59009
+ console.log("Building app config for ", symbol, kind);
59010
+ const initial_app_config = await exchange_account.buildAppConfig({
59011
+ entry,
59012
+ stop,
59013
+ risk_reward: 199,
59014
+ risk,
59015
+ symbol
59016
+ });
59017
+ console.log("Computing risk reward for ", symbol, kind);
59018
+ const risk_reward = computeRiskReward({
59019
+ app_config: initial_app_config,
59020
+ entry: initial_app_config.entry,
59021
+ stop: initial_app_config.stop,
59022
+ risk_per_trade: initial_app_config.risk_per_trade
59023
+ });
59024
+ console.log("Re-computing app config for ", symbol, kind);
59025
+ const { entries, last_value, ...app_config } = await exchange_account.buildAppConfig({
59026
+ entry: initial_app_config.entry,
59027
+ stop: initial_app_config.stop,
59028
+ risk_reward,
59029
+ risk,
59030
+ symbol
59031
+ });
59032
+ console.log("Computing profit percent for ", symbol, kind);
59033
+ const pnl = reward_factor * risk;
59034
+ const profit_percent = to_f2(pnl * 100 / (last_value.avg_entry * last_value.avg_size), "%.4f");
59035
+ let config2 = {
59036
+ entry,
59037
+ stop,
59038
+ risk,
59039
+ risk_reward,
59040
+ profit_percent
59041
+ };
59042
+ console.log("Saving new config for ", symbol, kind);
59043
+ const data = await exchange_account.getPositionConfig({
59044
+ symbol,
59045
+ kind,
59046
+ params: config2
59047
+ });
59048
+ console.log("Checking orders to place for ", symbol, kind);
59049
+ const orders_to_place = await exchange_account.placeTrade({
59050
+ symbol,
59051
+ raw: true,
59052
+ kind,
59053
+ place: false
59054
+ });
59055
+ config2 = {
59056
+ ...config2,
59057
+ ...data
59058
+ };
59059
+ console.log("Fetching positions for ", symbol);
59060
+ const positions = await exchange_account.syncAccount({
59061
+ symbol,
59062
+ as_view: true
59063
+ });
59064
+ console.log("Getting long and short positions for ", symbol);
59065
+ const long_position = positions.find((k) => k.kind === "long");
59066
+ const short_position = positions.find((k) => k.kind === "short");
59067
+ console.log("Getting focus position for ", symbol, kind);
59068
+ const focus_position = kind === "long" ? long_position : short_position;
59069
+ const reverse_position = kind === "long" ? short_position : long_position;
59070
+ let reverse_action = null;
59071
+ let reverse_orders_to_buy = [];
59072
+ let reverse_config = null;
59073
+ console.log("Checking if focus position has quantity for ", symbol, kind);
59074
+ if (focus_position.quantity > 0) {
59075
+ console.log("Getting details for ", reverse_position.kind);
59076
+ reverse_action = await exchange_account.buildOppositeTrades({
59077
+ symbol,
59078
+ kind
59079
+ });
59080
+ console.log("Updating config for ", symbol, reverse_action.kind);
59081
+ await exchange_account.getPositionConfig({
59082
+ symbol,
59083
+ kind: reverse_action.kind,
59084
+ params: {
59085
+ entry: reverse_action.entry,
59086
+ stop: reverse_action.stop,
59087
+ risk: reverse_action.risk_per_trade,
59088
+ profit_percent: reverse_action.profit_percent,
59089
+ risk_reward: reverse_action.risk_reward
59090
+ }
59091
+ });
59092
+ console.log("Checking reverse orders to buy for ", symbol, reverse_action.kind);
59093
+ reverse_orders_to_buy = await exchange_account.placeTrade({
59094
+ symbol,
59095
+ raw: true,
59096
+ kind: reverse_action.kind,
59097
+ place: false
59098
+ });
59099
+ let _reverse_config = {
59100
+ avg: reverse_action.avg,
59101
+ entry: reverse_action.entry,
59102
+ stop: reverse_action.stop,
59103
+ risk_per_trade: reverse_action.risk_per_trade,
59104
+ profit_percent: reverse_action.profit_percent,
59105
+ risk_reward: reverse_action.risk_reward
59106
+ };
59107
+ if (reverse_orders_to_buy.length > 0) {
59108
+ console.log("Placing opposite trade action for ", symbol, reverse_action.kind);
59109
+ let existing = await exchange_account.placeOppositeTradeAction({
59110
+ symbol,
59111
+ kind: reverse_action.kind,
59112
+ data: _reverse_config
59113
+ });
59114
+ _reverse_config = {
59115
+ ...existing,
59116
+ ..._reverse_config
59117
+ };
59118
+ }
59119
+ reverse_config = _reverse_config;
59120
+ if (!reverse_config?.id) {
59121
+ console.log("fetching reverse config for ", symbol, reverse_action.kind);
59122
+ reverse_config = await exchange_account.getPositionConfig({
59123
+ symbol,
59124
+ kind: reverse_action.kind
59125
+ });
59126
+ }
59127
+ if (reverse_position.quantity > 0 && reverse_config?.id) {
59128
+ console.log("Checking if reverse position has quantity for ", symbol, reverse_action.kind);
59129
+ const max_size = app_config.max_size * 0.98;
59130
+ if (reverse_config.threshold_qty !== max_size) {
59131
+ await this.app_db.updateScheduledTrade(reverse_config.id, {
59132
+ follow: true,
59133
+ threshold_qty: max_size
59134
+ });
59135
+ }
59136
+ console.log("Updating follow and threshold for ", symbol, reverse_action.kind);
59137
+ } else {
59138
+ await this.app_db.updateScheduledTrade(reverse_config.id, {
59139
+ follow: false
59140
+ });
59141
+ }
59142
+ }
59143
+ return {
59144
+ reverse_config,
59145
+ reverse_action,
59146
+ reverse_orders_to_buy,
59147
+ positions: {
59148
+ long: long_position,
59149
+ short: short_position
59150
+ },
59151
+ orders_to_place,
59152
+ config_details: {
59153
+ app_config,
59154
+ last_value,
59155
+ config: config2,
59156
+ pnl
59157
+ }
59158
+ };
59159
+ }
59024
59160
  }
59025
59161
  async function initApp(payload) {
59026
59162
  const pb = await initPocketBaseClient(payload.db);