@gbozee/ultimate 0.0.2-10 → 0.0.2-11

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.
Files changed (3) hide show
  1. package/dist/index.d.ts +57 -48
  2. package/dist/index.js +293 -101
  3. package/package.json +1 -1
package/dist/index.d.ts CHANGED
@@ -217,6 +217,7 @@ export interface BullishMarket extends RecordModel {
217
217
  export interface WindingDownMarket extends RecordModel {
218
218
  id: string;
219
219
  symbol: string;
220
+ risk_reward: number;
220
221
  }
221
222
  export type ExchangeType = {
222
223
  owner: string;
@@ -323,13 +324,13 @@ export declare class AppDatabase {
323
324
  symbol: string;
324
325
  kind: "long" | "short";
325
326
  account: ExchangeType;
326
- }): Promise<import("pocketbase").RecordModel>;
327
+ }): Promise<ScheduledTrade | null>;
327
328
  getPositionStrategy(account: ExchangeType): Promise<{
328
329
  strategy_instance: Strategy;
329
330
  focus_account: ExchangeAccount;
330
331
  }>;
331
332
  createOrUpdateWindingDownMarket(symbol: string): Promise<import("pocketbase").RecordModel>;
332
- getWindingDownMarkets(): Promise<WindingDownMarket[]>;
333
+ getWindingDownMarkets(symbol?: string): Promise<WindingDownMarket[]>;
333
334
  getBullishMarkets(options?: {
334
335
  new_markets: Array<{
335
336
  symbol: string;
@@ -354,7 +355,11 @@ export declare class AppDatabase {
354
355
  updated: number;
355
356
  created: number;
356
357
  } | SymbolConfig[]>;
357
- unwindSymbolFromDB(symbol: string): Promise<void>;
358
+ unwindSymbolFromDB(symbol: string): Promise<boolean>;
359
+ hasExistingPosition(symbol: string): Promise<import("pocketbase").RecordModel[]>;
360
+ removeSymbolFromUnwindingMarkets(symbol: string): Promise<boolean>;
361
+ removePosition(position: any): Promise<void>;
362
+ removePositionConfig(position: any): Promise<void>;
358
363
  }
359
364
  export interface CodeNode {
360
365
  minimum_pnl: number;
@@ -441,6 +446,11 @@ declare class ExchangeAccount$1 {
441
446
  kind: "long" | "short";
442
447
  update?: boolean;
443
448
  }): Promise<import("pocketbase").RecordModel[]>;
449
+ toggleStopBuying(payload: {
450
+ symbol: string;
451
+ kind: "long" | "short";
452
+ should_stop?: boolean;
453
+ }): Promise<import("pocketbase").RecordModel>;
444
454
  cancelOrders(payload: {
445
455
  symbol: string;
446
456
  kind: "long" | "short";
@@ -526,7 +536,7 @@ declare class ExchangeAccount$1 {
526
536
  risk: number;
527
537
  profit_percent?: number;
528
538
  };
529
- }): Promise<import("pocketbase").RecordModel>;
539
+ }): Promise<ScheduledTrade>;
530
540
  getCurrentPrice(symbol: string): Promise<any>;
531
541
  getPositionStrategy(): Promise<{
532
542
  strategy_instance: Strategy;
@@ -545,6 +555,48 @@ declare class ExchangeAccount$1 {
545
555
  short: boolean;
546
556
  };
547
557
  }): Promise<any>;
558
+ generate_config_params(payload: {
559
+ entry: number;
560
+ stop: number;
561
+ risk_reward: number;
562
+ risk: number;
563
+ symbol: string;
564
+ }): Promise<{
565
+ place_stop: boolean;
566
+ profit_percent: number;
567
+ entry: number;
568
+ stop: number;
569
+ avg_size: any;
570
+ avg_entry: any;
571
+ risk_reward: number;
572
+ neg_pnl: any;
573
+ risk: number;
574
+ }>;
575
+ extrapolateShortConfig(payload: {
576
+ kind: "long" | "short";
577
+ symbol: string;
578
+ risk_reward?: number;
579
+ }): Promise<{
580
+ place_stop: boolean;
581
+ profit_percent: number;
582
+ entry: number;
583
+ stop: number;
584
+ avg_size: any;
585
+ avg_entry: any;
586
+ risk_reward: number;
587
+ neg_pnl: any;
588
+ risk: number;
589
+ }>;
590
+ triggerTradeFromConfig(payload: {
591
+ symbol: string;
592
+ kind: "long" | "short";
593
+ }): Promise<any>;
594
+ verifyStopLoss(payload: {
595
+ symbol: string;
596
+ kind: "long" | "short";
597
+ revert?: boolean;
598
+ }): Promise<import("pocketbase").RecordModel[]>;
599
+ windDownSymbol(symbol: string, risk_reward?: number): Promise<void>;
548
600
  }
549
601
  declare class App {
550
602
  private app_db;
@@ -597,34 +649,6 @@ declare class App {
597
649
  message?: undefined;
598
650
  exchange_result?: undefined;
599
651
  }>;
600
- triggerTradeFromConfig(payload: {
601
- account: ExchangeType;
602
- symbol: string;
603
- kind: "long" | "short";
604
- }): Promise<any>;
605
- toggleStopBuying(payload: {
606
- account: ExchangeType;
607
- symbol: string;
608
- kind: "long" | "short";
609
- should_stop?: boolean;
610
- }): Promise<import("pocketbase").RecordModel>;
611
- generate_config_params(exchange_account: ExchangeAccount$1, payload: {
612
- entry: number;
613
- stop: number;
614
- risk_reward: number;
615
- risk: number;
616
- symbol: string;
617
- }): Promise<{
618
- place_stop: boolean;
619
- profit_percent: number;
620
- entry: number;
621
- stop: number;
622
- avg_size: any;
623
- avg_entry: any;
624
- risk_reward: number;
625
- neg_pnl: any;
626
- risk: number;
627
- }>;
628
652
  generateConfig(payload: {
629
653
  account: ExchangeType;
630
654
  symbol: string;
@@ -642,22 +666,6 @@ declare class App {
642
666
  short_db_position: any;
643
667
  balance: any;
644
668
  }>;
645
- extrapolateShortConfig(payload: {
646
- account: ExchangeType;
647
- kind: "long" | "short";
648
- symbol: string;
649
- risk_reward?: number;
650
- }): Promise<PositionsView | {
651
- place_stop: boolean;
652
- profit_percent: number;
653
- entry: number;
654
- stop: number;
655
- avg_size: any;
656
- avg_entry: any;
657
- risk_reward: number;
658
- neg_pnl: any;
659
- risk: number;
660
- }>;
661
669
  verifyStopLoss(payload: {
662
670
  account: ExchangeType;
663
671
  symbol: string;
@@ -690,6 +698,7 @@ declare class App {
690
698
  created: number;
691
699
  }>;
692
700
  updateAllAccountWithSymbols(with_positions?: boolean): Promise<void>;
701
+ windDownSymbol(symbol: string): Promise<boolean>;
693
702
  }
694
703
  export declare function initApp(payload: {
695
704
  db: {
package/dist/index.js CHANGED
@@ -31968,10 +31968,14 @@ class AppDatabase {
31968
31968
  if (existing_winding_down_market.length > 0) {
31969
31969
  return existing_winding_down_market[0];
31970
31970
  }
31971
- return await this.pb.collection("winding_down_markets").create({ symbol });
31971
+ return await this.pb.collection("winding_down_markets").create({ symbol, risk_reward: 199 });
31972
31972
  }
31973
- async getWindingDownMarkets() {
31974
- return await this.pb.collection("winding_down_markets").getFullList();
31973
+ async getWindingDownMarkets(symbol) {
31974
+ const result = await this.pb.collection("winding_down_markets").getFullList();
31975
+ if (symbol) {
31976
+ return result.filter((m) => m.symbol === symbol);
31977
+ }
31978
+ return result;
31975
31979
  }
31976
31980
  async getBullishMarkets(options) {
31977
31981
  if (!options) {
@@ -32162,12 +32166,30 @@ class AppDatabase {
32162
32166
  if (symbol_configs.length > 0) {
32163
32167
  await this.pb.collection("symbol_configs").delete(symbol_configs[0].id);
32164
32168
  }
32165
- const found_unwinding_market = await this.pb.collection("unwinding_markets").getFullList({
32169
+ return await this.removeSymbolFromUnwindingMarkets(symbol);
32170
+ }
32171
+ async hasExistingPosition(symbol) {
32172
+ const result = await this.pb.collection("positions").getFullList({
32173
+ filter: `symbol:lower="${symbol.toLowerCase()}"`,
32174
+ expand: "account"
32175
+ });
32176
+ return result;
32177
+ }
32178
+ async removeSymbolFromUnwindingMarkets(symbol) {
32179
+ const result = await this.pb.collection("winding_down_markets").getFullList({
32166
32180
  filter: `symbol:lower="${symbol.toLowerCase()}"`
32167
32181
  });
32168
- if (found_unwinding_market.length > 0) {
32169
- await this.pb.collection("unwinding_markets").delete(found_unwinding_market[0].id);
32182
+ if (result.length > 0) {
32183
+ await this.pb.collection("winding_down_markets").delete(result[0].id);
32184
+ return true;
32170
32185
  }
32186
+ return false;
32187
+ }
32188
+ async removePosition(position) {
32189
+ await this.pb.collection("positions").delete(position.id);
32190
+ }
32191
+ async removePositionConfig(position) {
32192
+ await this.pb.collection("scheduled_trades").delete(position.config);
32171
32193
  }
32172
32194
  }
32173
32195
 
@@ -32328,9 +32350,7 @@ class Signal {
32328
32350
  support: kind === "long" ? _stop_loss : this.support
32329
32351
  };
32330
32352
  const instance = new Signal(derivedConfig);
32331
- const ll = this.resistance?.toString().split(".")[0].length || 5;
32332
32353
  if (kind === "short") {
32333
- console.log("llll", ll);
32334
32354
  }
32335
32355
  let result = instance.get_bulk_trade_zones({ current_price, kind });
32336
32356
  return result;
@@ -32565,7 +32585,6 @@ class Signal {
32565
32585
  entries = Array.from({ length: Math.floor(this.risk_reward) + 1 }, (_, x) => to_f(margin_range[1] * Math.pow(1 + percent_change, x), this.price_places));
32566
32586
  }
32567
32587
  if (Math.min(...entries) < this.to_f(current_price) && this.to_f(current_price) < Math.max(...entries)) {
32568
- console.log("found: ", entries, "current: ", current_price);
32569
32588
  return entries.sort((a, b) => a - b);
32570
32589
  }
32571
32590
  if (remaining_zones.length > 0) {
@@ -32759,7 +32778,6 @@ class Signal {
32759
32778
  });
32760
32779
  let total_orders = limit_trades.concat(market_trades);
32761
32780
  if (kind === "short") {
32762
- console.log("raw_total", total_orders);
32763
32781
  }
32764
32782
  if (this.minimum_size && total_orders.length > 0) {
32765
32783
  let payload = total_orders;
@@ -34806,8 +34824,6 @@ function get_app_config_and_max_size(config, payload) {
34806
34824
  price_places: app_config.price_places,
34807
34825
  decimal_places: app_config.decimal_places
34808
34826
  });
34809
- console.log("app_config", app_config);
34810
- console.log("initialResult", initialResult);
34811
34827
  const max_size = initialResult[0]?.avg_size;
34812
34828
  return {
34813
34829
  app_config,
@@ -35096,15 +35112,42 @@ class ExchangeAccount {
35096
35112
  kind
35097
35113
  }, all_orders);
35098
35114
  }
35115
+ async toggleStopBuying(payload) {
35116
+ const { symbol, kind, should_stop = false } = payload;
35117
+ const position2 = await this.syncAccount({
35118
+ symbol,
35119
+ kind
35120
+ });
35121
+ if (should_stop) {
35122
+ return await this.app_db.update_db_position(position2, {
35123
+ config: null
35124
+ });
35125
+ }
35126
+ if (!position2.config) {
35127
+ const config = await this.getPositionConfig({
35128
+ symbol,
35129
+ kind
35130
+ });
35131
+ if (config) {
35132
+ return await this.app_db.update_db_position(position2, {
35133
+ config: config.id
35134
+ });
35135
+ }
35136
+ }
35137
+ }
35099
35138
  async cancelOrders(payload) {
35100
35139
  const { symbol, kind, price: _price, all, stop } = payload;
35101
35140
  let price = _price || 0;
35141
+ await this.getLiveExchangeInstance({
35142
+ symbol,
35143
+ refresh: true
35144
+ });
35145
+ await this.syncOrders({
35146
+ symbol,
35147
+ kind,
35148
+ update: true
35149
+ });
35102
35150
  if (all) {
35103
- await this.syncOrders({
35104
- symbol,
35105
- kind,
35106
- update: true
35107
- });
35108
35151
  } else {
35109
35152
  if (!price) {
35110
35153
  const position2 = await this.syncAccount({
@@ -35115,7 +35158,7 @@ class ExchangeAccount {
35115
35158
  price = position2?.take_profit || 0;
35116
35159
  }
35117
35160
  }
35118
- return this.app_db.cancelOrders({
35161
+ let result = await this.app_db.cancelOrders({
35119
35162
  cancelExchangeOrders: this.cancelExchangeOrders.bind(this),
35120
35163
  all,
35121
35164
  kind,
@@ -35124,6 +35167,7 @@ class ExchangeAccount {
35124
35167
  price,
35125
35168
  stop
35126
35169
  });
35170
+ return result;
35127
35171
  }
35128
35172
  async cancelExchangeOrders(payload) {
35129
35173
  return this.exchange.cancelOrders(payload);
@@ -35242,7 +35286,7 @@ class ExchangeAccount {
35242
35286
  symbol: payload.symbol
35243
35287
  }, false);
35244
35288
  if (action === "place_limit_orders" && payload.place) {
35245
- return await this.exchange.bulkPlaceLimitOrders({
35289
+ let result = await this.exchange.bulkPlaceLimitOrders({
35246
35290
  orders: trades.map((x) => ({
35247
35291
  entry: x.entry,
35248
35292
  quantity: x.quantity
@@ -35252,9 +35296,14 @@ class ExchangeAccount {
35252
35296
  symbol: payload.symbol,
35253
35297
  place: payload.place
35254
35298
  });
35299
+ await this.getLiveExchangeInstance({
35300
+ symbol: payload.symbol,
35301
+ refresh: true
35302
+ });
35303
+ return result;
35255
35304
  }
35256
35305
  if (action === "place_stop_orders" && payload.place) {
35257
- return await this.exchange.placeStopOrders({
35306
+ let result = await this.exchange.placeStopOrders({
35258
35307
  symbol: payload.symbol,
35259
35308
  quantity: trades[0].avg_size,
35260
35309
  kind: app_config.kind,
@@ -35263,6 +35312,11 @@ class ExchangeAccount {
35263
35312
  decimal_places: app_config.decimal_places,
35264
35313
  place: true
35265
35314
  });
35315
+ await this.getLiveExchangeInstance({
35316
+ symbol: payload.symbol,
35317
+ refresh: true
35318
+ });
35319
+ return result;
35266
35320
  }
35267
35321
  return {
35268
35322
  entry_orders,
@@ -35366,6 +35420,188 @@ class ExchangeAccount {
35366
35420
  short
35367
35421
  }, accountInfo, trigger, this.exchange);
35368
35422
  }
35423
+ async generate_config_params(payload) {
35424
+ const { entry, stop, risk_reward, risk, symbol } = payload;
35425
+ const app_config = await this.buildAppConfig({
35426
+ entry,
35427
+ stop,
35428
+ risk_reward,
35429
+ risk,
35430
+ symbol
35431
+ });
35432
+ let config = generate_config_params(app_config, {
35433
+ entry,
35434
+ stop,
35435
+ risk_reward,
35436
+ risk,
35437
+ symbol
35438
+ });
35439
+ return { ...config, place_stop: false, profit_percent: 0 };
35440
+ }
35441
+ async extrapolateShortConfig(payload) {
35442
+ const { symbol, risk_reward = 199, kind } = payload;
35443
+ let reverse_kind = kind === "long" ? "short" : "long";
35444
+ const position2 = await this.syncAccount({
35445
+ symbol,
35446
+ kind: reverse_kind,
35447
+ as_view: true
35448
+ });
35449
+ if (position2) {
35450
+ return await this.generate_config_params({
35451
+ entry: position2.next_order || position2.avg_liquidation,
35452
+ stop: position2.take_profit,
35453
+ risk_reward,
35454
+ risk: position2.target_pnl,
35455
+ symbol
35456
+ });
35457
+ }
35458
+ return null;
35459
+ }
35460
+ async triggerTradeFromConfig(payload) {
35461
+ const position2 = await this.syncAccount({
35462
+ symbol: payload.symbol,
35463
+ kind: payload.kind
35464
+ });
35465
+ if (position2?.config) {
35466
+ const config = position2.expand.config;
35467
+ return await this.placeSharedOrder("place_limit_orders", {
35468
+ symbol: payload.symbol,
35469
+ entry: config.entry,
35470
+ stop: config.stop,
35471
+ risk_reward: config.risk_reward,
35472
+ risk: config.risk,
35473
+ place: true
35474
+ });
35475
+ }
35476
+ }
35477
+ async verifyStopLoss(payload) {
35478
+ const { symbol, kind, revert } = payload;
35479
+ await this.syncOrders({
35480
+ symbol,
35481
+ kind,
35482
+ update: true
35483
+ });
35484
+ let original = null;
35485
+ if (revert) {
35486
+ original = await this.getOriginalPlannedStop({
35487
+ symbol,
35488
+ kind
35489
+ });
35490
+ }
35491
+ const position2 = await this.syncAccount({
35492
+ symbol,
35493
+ kind,
35494
+ as_view: true
35495
+ });
35496
+ if (original && position2?.stop_loss && original.quantity != position2.stop_loss.quantity) {
35497
+ const opposite_kind = kind === "long" ? "short" : "long";
35498
+ await this.cancelOrders({
35499
+ symbol,
35500
+ kind: opposite_kind,
35501
+ stop: true
35502
+ });
35503
+ return await this.syncOrders({
35504
+ symbol,
35505
+ kind,
35506
+ update: true
35507
+ });
35508
+ }
35509
+ if (true) {
35510
+ const opposite_kind = kind === "long" ? "short" : "long";
35511
+ await this.syncOrders({
35512
+ symbol,
35513
+ kind: opposite_kind,
35514
+ update: true
35515
+ });
35516
+ await this.cancelOrders({
35517
+ symbol,
35518
+ kind: opposite_kind,
35519
+ stop: true
35520
+ });
35521
+ await this.syncReduceClosePosition(symbol, {
35522
+ kind: opposite_kind
35523
+ });
35524
+ await this.syncOrders({
35525
+ symbol,
35526
+ kind,
35527
+ update: true
35528
+ });
35529
+ }
35530
+ }
35531
+ async windDownSymbol(symbol, risk_reward = 199) {
35532
+ const positions = await this.syncAccount({
35533
+ symbol,
35534
+ as_view: true
35535
+ });
35536
+ let long_position = positions.find((x) => x.kind === "long");
35537
+ let short_position = positions.find((x) => x.kind === "short");
35538
+ if (long_position && long_position.quantity > 0) {
35539
+ console.log("Start to wind down the long position");
35540
+ let config = long_position?.expand?.config;
35541
+ if (!config && long_position.config) {
35542
+ config = await this.getPositionConfig({
35543
+ symbol,
35544
+ kind: "long"
35545
+ });
35546
+ }
35547
+ if (config) {
35548
+ console.log("cancelling any existing open orders for the long position");
35549
+ await this.cancelOrders({
35550
+ symbol,
35551
+ kind: "long",
35552
+ price: long_position.entry
35553
+ });
35554
+ console.log("updating the long position target_pnl");
35555
+ console.log("toggling the stop buying for the long position");
35556
+ await this.toggleStopBuying({
35557
+ symbol,
35558
+ kind: "long",
35559
+ should_stop: true
35560
+ });
35561
+ }
35562
+ const new_config = await this.extrapolateShortConfig({
35563
+ symbol,
35564
+ kind: "short",
35565
+ risk_reward
35566
+ });
35567
+ const short_config = await this.getPositionConfig({
35568
+ symbol,
35569
+ kind: "short"
35570
+ });
35571
+ if (new_config && short_config && (short_config.entry !== new_config.entry || short_config.stop !== new_config.stop || short_config.risk !== new_config.risk)) {
35572
+ console.log("updating short position");
35573
+ short_position = await this.app_db.update_db_position(short_position, {
35574
+ reduce_ratio: 0.95
35575
+ });
35576
+ console.log("Updating the short position config");
35577
+ await this.getPositionConfig({
35578
+ symbol,
35579
+ kind: "short",
35580
+ params: {
35581
+ entry: new_config.entry,
35582
+ stop: new_config.stop,
35583
+ risk_reward,
35584
+ risk: new_config.risk,
35585
+ profit_percent: 1
35586
+ }
35587
+ });
35588
+ console.log("placing the short trade based off config values");
35589
+ await this.triggerTradeFromConfig({
35590
+ symbol,
35591
+ kind: "short"
35592
+ });
35593
+ console.log("updating the stop loss for the short position from the long");
35594
+ await this.verifyStopLoss({
35595
+ symbol,
35596
+ kind: "short"
35597
+ });
35598
+ }
35599
+ }
35600
+ if (long_position && long_position.quantity === 0 && short_position && short_position.quantity == 0) {
35601
+ this.app_db.removePosition(long_position);
35602
+ this.app_db.removePosition(short_position);
35603
+ }
35604
+ }
35369
35605
  }
35370
35606
  function getExchangeKlass(exchange) {
35371
35607
  const func = exchange === "binance" ? BinanceExchange : BybitExchange;
@@ -35458,66 +35694,6 @@ class App {
35458
35694
  stop: payload.stop
35459
35695
  });
35460
35696
  }
35461
- async triggerTradeFromConfig(payload) {
35462
- const exchange_account = await this.getExchangeAccount(payload.account);
35463
- const position2 = await exchange_account.syncAccount({
35464
- symbol: payload.symbol,
35465
- kind: payload.kind
35466
- });
35467
- if (position2?.config) {
35468
- const config = position2.expand.config;
35469
- return await exchange_account.placeSharedOrder("place_limit_orders", {
35470
- symbol: payload.symbol,
35471
- entry: config.entry,
35472
- stop: config.stop,
35473
- risk_reward: config.risk_reward,
35474
- risk: config.risk,
35475
- place: true
35476
- });
35477
- }
35478
- }
35479
- async toggleStopBuying(payload) {
35480
- const { symbol, kind, should_stop = false } = payload;
35481
- const exchange_account = await this.getExchangeAccount(payload.account);
35482
- const position2 = await exchange_account.syncAccount({
35483
- symbol,
35484
- kind
35485
- });
35486
- if (should_stop) {
35487
- return await this.app_db.update_db_position(position2, {
35488
- config: null
35489
- });
35490
- }
35491
- if (!position2.config) {
35492
- const config = await exchange_account.getPositionConfig({
35493
- symbol,
35494
- kind
35495
- });
35496
- if (config) {
35497
- return await this.app_db.update_db_position(position2, {
35498
- config: config.id
35499
- });
35500
- }
35501
- }
35502
- }
35503
- async generate_config_params(exchange_account, payload) {
35504
- const { entry, stop, risk_reward, risk, symbol } = payload;
35505
- const app_config = await exchange_account.buildAppConfig({
35506
- entry,
35507
- stop,
35508
- risk_reward,
35509
- risk,
35510
- symbol
35511
- });
35512
- let config = generate_config_params(app_config, {
35513
- entry,
35514
- stop,
35515
- risk_reward,
35516
- risk,
35517
- symbol
35518
- });
35519
- return { ...config, place_stop: false, profit_percent: 0 };
35520
- }
35521
35697
  async generateConfig(payload) {
35522
35698
  const { symbol, kind } = payload;
35523
35699
  const exchange_account = await this.getExchangeAccount(payload.account);
@@ -35559,7 +35735,7 @@ class App {
35559
35735
  if (!risk_factor) {
35560
35736
  return null;
35561
35737
  }
35562
- let config = await this.generate_config_params(exchange_account, {
35738
+ let config = await exchange_account.generate_config_params({
35563
35739
  entry,
35564
35740
  stop,
35565
35741
  risk_reward: config_instance.risk_reward,
@@ -35637,26 +35813,6 @@ class App {
35637
35813
  balance: active_account.usd_balance
35638
35814
  };
35639
35815
  }
35640
- async extrapolateShortConfig(payload) {
35641
- const { symbol, risk_reward = 199, kind } = payload;
35642
- const exchange_account = await this.getExchangeAccount(payload.account);
35643
- let reverse_kind = kind === "long" ? "short" : "long";
35644
- const position2 = await exchange_account.syncAccount({
35645
- symbol,
35646
- kind: reverse_kind,
35647
- as_view: true
35648
- });
35649
- if (position2) {
35650
- return await this.generate_config_params(exchange_account, {
35651
- entry: position2.next_order || position2.avg_liquidation,
35652
- stop: position2.take_profit,
35653
- risk_reward,
35654
- risk: position2.target_pnl,
35655
- symbol
35656
- });
35657
- }
35658
- return position2;
35659
- }
35660
35816
  async verifyStopLoss(payload) {
35661
35817
  const { account, symbol, kind, revert } = payload;
35662
35818
  const exchange_account = await this.getExchangeAccount(payload.account);
@@ -35741,6 +35897,42 @@ class App {
35741
35897
  await new Promise((resolve) => setTimeout(resolve, 5000));
35742
35898
  }
35743
35899
  }
35900
+ async windDownSymbol(symbol) {
35901
+ let winding_instance = await this.app_db.getWindingDownMarkets(symbol);
35902
+ if (winding_instance && winding_instance.length > 0) {
35903
+ winding_instance = winding_instance[0];
35904
+ }
35905
+ if (!winding_instance || winding_instance.length === 0) {
35906
+ return true;
35907
+ }
35908
+ const positions = await this.app_db.hasExistingPosition(symbol);
35909
+ if (positions.length === 0) {
35910
+ return this.app_db.unwindSymbolFromDB(symbol);
35911
+ }
35912
+ const unique_instances = new Set(positions.map((x) => `${x.symbol}-${x.expand.account.owner}-${x.expand.account.exchange}`));
35913
+ let position_pairs = [];
35914
+ for (const instance of unique_instances) {
35915
+ const pair = positions.filter((x) => `${x.symbol}-${x.expand.account.owner}-${x.expand.account.exchange}` === instance && x.quantity === 0);
35916
+ if (pair.length === 2) {
35917
+ position_pairs = position_pairs.concat(pair);
35918
+ }
35919
+ }
35920
+ const not_paired_positions = positions.filter((x) => !position_pairs.map((p) => p.id).includes(x.id) && x.kind === "long");
35921
+ console.log("not_paired_positions", not_paired_positions.map((x) => `${x.symbol} - ${x.expand.account.owner} - ${x.expand.account.exchange}`));
35922
+ if (position_pairs.length > 0) {
35923
+ console.log("removing position pairs");
35924
+ for (const pair of position_pairs) {
35925
+ await this.app_db.removePosition(pair);
35926
+ }
35927
+ }
35928
+ if (not_paired_positions.length > 0) {
35929
+ console.log("winding down not paired positions");
35930
+ for (const pair of not_paired_positions) {
35931
+ const exchange_account = await this.getExchangeAccount(pair.expand.account);
35932
+ await exchange_account.windDownSymbol(pair.symbol, winding_instance?.risk_reward || 199);
35933
+ }
35934
+ }
35935
+ }
35744
35936
  }
35745
35937
  async function initApp(payload) {
35746
35938
  const pb = await initPocketBaseClient(payload.db);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@gbozee/ultimate",
3
3
  "type": "module",
4
- "version": "0.0.2-10",
4
+ "version": "0.0.2-11",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",