@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.
- package/dist/index.d.ts +57 -48
- package/dist/index.js +293 -101
- 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<
|
|
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<
|
|
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<
|
|
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
|
-
|
|
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
|
-
|
|
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 (
|
|
32169
|
-
await this.pb.collection("
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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);
|