@gbozee/ultimate 0.0.2-33 → 0.0.2-36
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/frontend-index.d.ts +14 -0
- package/dist/frontend-index.js +13 -0
- package/dist/index.d.ts +62 -0
- package/dist/index.js +192 -10
- package/package.json +1 -1
package/dist/frontend-index.d.ts
CHANGED
|
@@ -263,5 +263,19 @@ export declare function generate_config_params(app_config: AppConfig, payload: {
|
|
|
263
263
|
neg_pnl: any;
|
|
264
264
|
risk: number;
|
|
265
265
|
};
|
|
266
|
+
export declare function determine_break_even_price(payload: {
|
|
267
|
+
long_position: {
|
|
268
|
+
entry: number;
|
|
269
|
+
quantity: number;
|
|
270
|
+
};
|
|
271
|
+
short_position: {
|
|
272
|
+
entry: number;
|
|
273
|
+
quantity: number;
|
|
274
|
+
};
|
|
275
|
+
fee_percent?: number;
|
|
276
|
+
}): {
|
|
277
|
+
price: number;
|
|
278
|
+
direction: string;
|
|
279
|
+
};
|
|
266
280
|
|
|
267
281
|
export {};
|
package/dist/frontend-index.js
CHANGED
|
@@ -1305,11 +1305,24 @@ function generate_config_params(app_config, payload) {
|
|
|
1305
1305
|
risk: payload.risk
|
|
1306
1306
|
};
|
|
1307
1307
|
}
|
|
1308
|
+
function determine_break_even_price(payload) {
|
|
1309
|
+
const { long_position, short_position, fee_percent = 0.05 / 100 } = payload;
|
|
1310
|
+
const long_notional = long_position.entry * long_position.quantity;
|
|
1311
|
+
const short_notional = short_position.entry * short_position.quantity;
|
|
1312
|
+
const net_quantity = long_position.quantity - short_position.quantity;
|
|
1313
|
+
const net_capital = Math.abs(long_notional - short_notional);
|
|
1314
|
+
const break_even_price = net_capital / (Math.abs(net_quantity) + fee_percent * Math.abs(net_quantity));
|
|
1315
|
+
return {
|
|
1316
|
+
price: break_even_price,
|
|
1317
|
+
direction: net_quantity > 0 ? "long" : "short"
|
|
1318
|
+
};
|
|
1319
|
+
}
|
|
1308
1320
|
export {
|
|
1309
1321
|
sortedBuildConfig,
|
|
1310
1322
|
get_app_config_and_max_size,
|
|
1311
1323
|
getOptimumStopAndRisk,
|
|
1312
1324
|
generate_config_params,
|
|
1325
|
+
determine_break_even_price,
|
|
1313
1326
|
determine_average_entry_and_size,
|
|
1314
1327
|
createArray,
|
|
1315
1328
|
buildConfig,
|
package/dist/index.d.ts
CHANGED
|
@@ -183,6 +183,13 @@ export interface BaseExchange {
|
|
|
183
183
|
asset: string;
|
|
184
184
|
amount: number;
|
|
185
185
|
}): Promise<any>;
|
|
186
|
+
placeMarketOrder(payload: {
|
|
187
|
+
symbol: string;
|
|
188
|
+
kind: "long" | "short";
|
|
189
|
+
quantity: number;
|
|
190
|
+
price_places?: string;
|
|
191
|
+
decimal_places?: string;
|
|
192
|
+
}): Promise<any>;
|
|
186
193
|
}
|
|
187
194
|
export interface BaseSystemFields {
|
|
188
195
|
id: string;
|
|
@@ -410,6 +417,11 @@ export declare class AppDatabase {
|
|
|
410
417
|
}>;
|
|
411
418
|
getMoverExchangeInstances(): Promise<ExchangeAccount[]>;
|
|
412
419
|
updateScheduledTrade(id: string, payload: any): Promise<import("pocketbase").RecordModel>;
|
|
420
|
+
getPositionsToAutoFollow(): Promise<(Position$1 & {
|
|
421
|
+
expand: {
|
|
422
|
+
account: ExchangeAccount;
|
|
423
|
+
};
|
|
424
|
+
})[]>;
|
|
413
425
|
createOrUpdatePositionConfig(db_position: any, payload: {
|
|
414
426
|
entry: number;
|
|
415
427
|
stop: number;
|
|
@@ -709,6 +721,20 @@ export declare function generate_config_params(app_config: AppConfig, payload: {
|
|
|
709
721
|
neg_pnl: any;
|
|
710
722
|
risk: number;
|
|
711
723
|
};
|
|
724
|
+
export declare function determine_break_even_price(payload: {
|
|
725
|
+
long_position: {
|
|
726
|
+
entry: number;
|
|
727
|
+
quantity: number;
|
|
728
|
+
};
|
|
729
|
+
short_position: {
|
|
730
|
+
entry: number;
|
|
731
|
+
quantity: number;
|
|
732
|
+
};
|
|
733
|
+
fee_percent?: number;
|
|
734
|
+
}): {
|
|
735
|
+
price: number;
|
|
736
|
+
direction: string;
|
|
737
|
+
};
|
|
712
738
|
declare class ExchangeAccount$1 {
|
|
713
739
|
private instance;
|
|
714
740
|
exchange: BaseExchange;
|
|
@@ -793,6 +819,12 @@ declare class ExchangeAccount$1 {
|
|
|
793
819
|
symbol: string;
|
|
794
820
|
orders: number[];
|
|
795
821
|
}): Promise<any>;
|
|
822
|
+
getBreakEvenPrice(payload: {
|
|
823
|
+
symbol: string;
|
|
824
|
+
}): Promise<{
|
|
825
|
+
price: number;
|
|
826
|
+
direction: string;
|
|
827
|
+
}>;
|
|
796
828
|
buildAppConfig(payload: {
|
|
797
829
|
entry: number;
|
|
798
830
|
stop: number;
|
|
@@ -803,6 +835,17 @@ declare class ExchangeAccount$1 {
|
|
|
803
835
|
update_db?: boolean;
|
|
804
836
|
profit_percent?: number;
|
|
805
837
|
}): Promise<AppConfig>;
|
|
838
|
+
buildTrades(payload: {
|
|
839
|
+
symbol: string;
|
|
840
|
+
kind: "long" | "short";
|
|
841
|
+
risk?: number;
|
|
842
|
+
}): Promise<{
|
|
843
|
+
trades: any[];
|
|
844
|
+
max_size: any;
|
|
845
|
+
last_price: any;
|
|
846
|
+
total_size: number;
|
|
847
|
+
avg_entry: number;
|
|
848
|
+
}>;
|
|
806
849
|
placeConfigOrders(app_config: AppConfig, solution: {
|
|
807
850
|
risk_reward: number;
|
|
808
851
|
entry: number;
|
|
@@ -837,9 +880,11 @@ declare class ExchangeAccount$1 {
|
|
|
837
880
|
determineAmountToBuy(payload: {
|
|
838
881
|
orders: any[];
|
|
839
882
|
kind: "long" | "short";
|
|
883
|
+
refresh?: boolean;
|
|
840
884
|
decimal_places?: string;
|
|
841
885
|
price_places?: string;
|
|
842
886
|
symbol: string;
|
|
887
|
+
cancel?: boolean;
|
|
843
888
|
place?: boolean;
|
|
844
889
|
}): Promise<any[]>;
|
|
845
890
|
placeSharedOrder(action: "place_limit_orders" | "place_stop_orders" | "place_tp_orders", payload: {
|
|
@@ -853,6 +898,12 @@ declare class ExchangeAccount$1 {
|
|
|
853
898
|
raw?: boolean;
|
|
854
899
|
use_current?: boolean;
|
|
855
900
|
}): Promise<any>;
|
|
901
|
+
getOrCreatePositionConfig(payload: {
|
|
902
|
+
symbol: string;
|
|
903
|
+
kind: "long" | "short";
|
|
904
|
+
risk?: number;
|
|
905
|
+
risk_reward?: number;
|
|
906
|
+
}): Promise<ScheduledTrade | import("pocketbase").RecordModel>;
|
|
856
907
|
getPositionConfig(payload: {
|
|
857
908
|
symbol: string;
|
|
858
909
|
kind: "long" | "short";
|
|
@@ -962,6 +1013,15 @@ declare class ExchangeAccount$1 {
|
|
|
962
1013
|
risk_reward?: number;
|
|
963
1014
|
risk?: number;
|
|
964
1015
|
}): Promise<any>;
|
|
1016
|
+
placeMarketOrder(payload: {
|
|
1017
|
+
symbol: string;
|
|
1018
|
+
kind: "long" | "short";
|
|
1019
|
+
quantity: number;
|
|
1020
|
+
}): Promise<void>;
|
|
1021
|
+
placeSingleOrder(payload: {
|
|
1022
|
+
symbol: string;
|
|
1023
|
+
kind: "long" | "short";
|
|
1024
|
+
}): Promise<string>;
|
|
965
1025
|
triggerTradeFromConfig(payload: {
|
|
966
1026
|
symbol: string;
|
|
967
1027
|
kind: "long" | "short";
|
|
@@ -969,6 +1029,7 @@ declare class ExchangeAccount$1 {
|
|
|
969
1029
|
raw?: boolean;
|
|
970
1030
|
tp?: boolean;
|
|
971
1031
|
stop?: boolean;
|
|
1032
|
+
use_current?: boolean;
|
|
972
1033
|
}): Promise<any>;
|
|
973
1034
|
verifyStopLoss(payload: {
|
|
974
1035
|
symbol: string;
|
|
@@ -1148,6 +1209,7 @@ declare class App {
|
|
|
1148
1209
|
refreshAllPositionsWithSymbol(payload: {
|
|
1149
1210
|
symbol: string;
|
|
1150
1211
|
}): Promise<void>;
|
|
1212
|
+
autoFollowPositions(): Promise<void>;
|
|
1151
1213
|
getMoverExchangeInstances(): Promise<ExchangeAccount[]>;
|
|
1152
1214
|
updateTpOnAllMarkets(): Promise<void>;
|
|
1153
1215
|
triggerMoverTask(payload: {
|
package/dist/index.js
CHANGED
|
@@ -32491,6 +32491,13 @@ class AppDatabase {
|
|
|
32491
32491
|
async updateScheduledTrade(id, payload) {
|
|
32492
32492
|
return await this.pb.collection("scheduled_trades").update(id, payload);
|
|
32493
32493
|
}
|
|
32494
|
+
async getPositionsToAutoFollow() {
|
|
32495
|
+
const result = await this.pb.collection("positions").getFullList({
|
|
32496
|
+
filter: `follow=true`,
|
|
32497
|
+
expand: "account"
|
|
32498
|
+
});
|
|
32499
|
+
return result;
|
|
32500
|
+
}
|
|
32494
32501
|
async createOrUpdatePositionConfig(db_position, payload) {
|
|
32495
32502
|
let config = null;
|
|
32496
32503
|
if (db_position.config) {
|
|
@@ -34835,6 +34842,19 @@ class BinanceExchange {
|
|
|
34835
34842
|
return result;
|
|
34836
34843
|
}
|
|
34837
34844
|
}
|
|
34845
|
+
async placeMarketOrder(payload) {
|
|
34846
|
+
const { symbol, kind, quantity, price_places, decimal_places } = payload;
|
|
34847
|
+
const currentPrice = await this.get_current_price(symbol);
|
|
34848
|
+
return createLimitPurchaseOrders(this.client, symbol, price_places, decimal_places, [
|
|
34849
|
+
{
|
|
34850
|
+
force_market: true,
|
|
34851
|
+
side: kind === "long" ? "buy" : "sell",
|
|
34852
|
+
kind,
|
|
34853
|
+
quantity,
|
|
34854
|
+
price: currentPrice
|
|
34855
|
+
}
|
|
34856
|
+
]);
|
|
34857
|
+
}
|
|
34838
34858
|
}
|
|
34839
34859
|
function getPricePlaces(target) {
|
|
34840
34860
|
const numStr = target.toString();
|
|
@@ -35507,6 +35527,8 @@ class BybitExchange {
|
|
|
35507
35527
|
}
|
|
35508
35528
|
async crossAccountTransfer(payload) {
|
|
35509
35529
|
}
|
|
35530
|
+
async placeMarketOrder(payload) {
|
|
35531
|
+
}
|
|
35510
35532
|
}
|
|
35511
35533
|
|
|
35512
35534
|
// src/helpers/accounts.ts
|
|
@@ -36190,6 +36212,18 @@ function generate_config_params(app_config, payload) {
|
|
|
36190
36212
|
risk: payload.risk
|
|
36191
36213
|
};
|
|
36192
36214
|
}
|
|
36215
|
+
function determine_break_even_price(payload) {
|
|
36216
|
+
const { long_position, short_position, fee_percent = 0.05 / 100 } = payload;
|
|
36217
|
+
const long_notional = long_position.entry * long_position.quantity;
|
|
36218
|
+
const short_notional = short_position.entry * short_position.quantity;
|
|
36219
|
+
const net_quantity = long_position.quantity - short_position.quantity;
|
|
36220
|
+
const net_capital = Math.abs(long_notional - short_notional);
|
|
36221
|
+
const break_even_price = net_capital / (Math.abs(net_quantity) + fee_percent * Math.abs(net_quantity));
|
|
36222
|
+
return {
|
|
36223
|
+
price: break_even_price,
|
|
36224
|
+
direction: net_quantity > 0 ? "long" : "short"
|
|
36225
|
+
};
|
|
36226
|
+
}
|
|
36193
36227
|
|
|
36194
36228
|
// src/exchange-account.ts
|
|
36195
36229
|
class ExchangeAccount {
|
|
@@ -36371,6 +36405,18 @@ class ExchangeAccount {
|
|
|
36371
36405
|
async cancelExchangeOrders(payload) {
|
|
36372
36406
|
return this.exchange.cancelOrders(payload);
|
|
36373
36407
|
}
|
|
36408
|
+
async getBreakEvenPrice(payload) {
|
|
36409
|
+
const positions = await this.syncAccount({
|
|
36410
|
+
symbol: payload.symbol
|
|
36411
|
+
});
|
|
36412
|
+
const long_position = positions.find((x) => x.kind === "long");
|
|
36413
|
+
const short_position = positions.find((x) => x.kind === "short");
|
|
36414
|
+
const break_even_price = determine_break_even_price({
|
|
36415
|
+
long_position,
|
|
36416
|
+
short_position
|
|
36417
|
+
});
|
|
36418
|
+
return break_even_price;
|
|
36419
|
+
}
|
|
36374
36420
|
async buildAppConfig(payload) {
|
|
36375
36421
|
let config = await this.app_db.getSymbolConfigFromDB(payload.symbol);
|
|
36376
36422
|
const app_config = buildAppConfig(config, payload);
|
|
@@ -36391,6 +36437,58 @@ class ExchangeAccount {
|
|
|
36391
36437
|
}
|
|
36392
36438
|
return app_config;
|
|
36393
36439
|
}
|
|
36440
|
+
async buildTrades(payload) {
|
|
36441
|
+
const { symbol, kind, risk } = payload;
|
|
36442
|
+
const config = await this.getPositionConfig({
|
|
36443
|
+
symbol,
|
|
36444
|
+
kind
|
|
36445
|
+
});
|
|
36446
|
+
const app_config = await this.buildAppConfig({
|
|
36447
|
+
entry: config.entry,
|
|
36448
|
+
stop: config.stop,
|
|
36449
|
+
risk_reward: config.risk_reward,
|
|
36450
|
+
risk: risk || config.risk,
|
|
36451
|
+
symbol
|
|
36452
|
+
});
|
|
36453
|
+
const { trades } = await this.placeConfigOrders(app_config, {
|
|
36454
|
+
risk_reward: config.risk_reward,
|
|
36455
|
+
entry: config.entry,
|
|
36456
|
+
stop: config.stop,
|
|
36457
|
+
risk_per_trade: risk || config.risk,
|
|
36458
|
+
avg_size: 0,
|
|
36459
|
+
neg_pnl: 0,
|
|
36460
|
+
min_size: app_config.min_size,
|
|
36461
|
+
symbol
|
|
36462
|
+
});
|
|
36463
|
+
const position2 = await this.syncAccount({
|
|
36464
|
+
symbol,
|
|
36465
|
+
kind
|
|
36466
|
+
});
|
|
36467
|
+
const orders_to_place = await this.determineAmountToBuy({
|
|
36468
|
+
orders: trades.map((x) => ({
|
|
36469
|
+
entry: x.entry,
|
|
36470
|
+
quantity: x.quantity
|
|
36471
|
+
})),
|
|
36472
|
+
kind,
|
|
36473
|
+
decimal_places: app_config.decimal_places,
|
|
36474
|
+
price_places: app_config.price_places,
|
|
36475
|
+
symbol
|
|
36476
|
+
});
|
|
36477
|
+
const avg_values = determine_average_entry_and_size(orders_to_place.map((u) => ({
|
|
36478
|
+
price: u.entry,
|
|
36479
|
+
quantity: u.quantity
|
|
36480
|
+
})).concat({
|
|
36481
|
+
price: position2.entry,
|
|
36482
|
+
quantity: position2.quantity
|
|
36483
|
+
}), app_config.decimal_places, app_config.price_places);
|
|
36484
|
+
return {
|
|
36485
|
+
trades: orders_to_place,
|
|
36486
|
+
max_size: trades[0].avg_size,
|
|
36487
|
+
last_price: trades[0].entry,
|
|
36488
|
+
total_size: avg_values.quantity,
|
|
36489
|
+
avg_entry: avg_values.price
|
|
36490
|
+
};
|
|
36491
|
+
}
|
|
36394
36492
|
async placeConfigOrders(app_config, solution, place, skip_stop) {
|
|
36395
36493
|
app_config.entry = solution.entry;
|
|
36396
36494
|
app_config.stop = solution.stop;
|
|
@@ -36466,7 +36564,14 @@ class ExchangeAccount {
|
|
|
36466
36564
|
};
|
|
36467
36565
|
}
|
|
36468
36566
|
async determineAmountToBuy(payload) {
|
|
36469
|
-
const {
|
|
36567
|
+
const {
|
|
36568
|
+
orders,
|
|
36569
|
+
kind,
|
|
36570
|
+
decimal_places = "%.3f",
|
|
36571
|
+
symbol,
|
|
36572
|
+
refresh,
|
|
36573
|
+
cancel
|
|
36574
|
+
} = payload;
|
|
36470
36575
|
const totalQuantity = orders.reduce((sum, order) => sum + (order.quantity || 0), 0);
|
|
36471
36576
|
let runningTotal = to_f(totalQuantity, decimal_places);
|
|
36472
36577
|
let sortedOrders = [...orders].sort((a, b) => (a.entry || 0) - (b.entry || 0));
|
|
@@ -36485,7 +36590,7 @@ class ExchangeAccount {
|
|
|
36485
36590
|
const position2 = await this.syncAccount({
|
|
36486
36591
|
symbol,
|
|
36487
36592
|
kind,
|
|
36488
|
-
live_refresh:
|
|
36593
|
+
live_refresh: refresh,
|
|
36489
36594
|
update: true
|
|
36490
36595
|
});
|
|
36491
36596
|
let existingOrders = await this.syncOrders({
|
|
@@ -36502,7 +36607,7 @@ class ExchangeAccount {
|
|
|
36502
36607
|
filteredOrders = filteredOrders.filter((k) => !existingOrders.map((j) => j.price).includes(k.price));
|
|
36503
36608
|
const side = kind.toLowerCase() === "long" ? "buy" : "sell";
|
|
36504
36609
|
const shouldCancel = existingOrders.filter((k) => !orders.map((j) => j.entry).includes(k.price) && k.side === side).map((u) => u.price);
|
|
36505
|
-
if (shouldCancel.length > 0) {
|
|
36610
|
+
if (shouldCancel.length > 0 && cancel) {
|
|
36506
36611
|
const pp = kind === "long" ? Math.max(...shouldCancel) : Math.min(...shouldCancel);
|
|
36507
36612
|
const cancel_orders = await this.cancelOrders({
|
|
36508
36613
|
symbol,
|
|
@@ -36599,6 +36704,31 @@ class ExchangeAccount {
|
|
|
36599
36704
|
stop_orders
|
|
36600
36705
|
};
|
|
36601
36706
|
}
|
|
36707
|
+
async getOrCreatePositionConfig(payload) {
|
|
36708
|
+
const { symbol, kind, risk = 50, risk_reward = 199 } = payload;
|
|
36709
|
+
const config = await this.getPositionConfig({
|
|
36710
|
+
symbol: payload.symbol,
|
|
36711
|
+
kind: payload.kind
|
|
36712
|
+
});
|
|
36713
|
+
if (!config) {
|
|
36714
|
+
const long_c = await this.buildConfigForSymbol({
|
|
36715
|
+
symbol,
|
|
36716
|
+
risk,
|
|
36717
|
+
risk_reward
|
|
36718
|
+
});
|
|
36719
|
+
return this.getPositionConfig({
|
|
36720
|
+
symbol,
|
|
36721
|
+
kind,
|
|
36722
|
+
params: {
|
|
36723
|
+
entry: kind === "long" ? long_c.entry : long_c.stop,
|
|
36724
|
+
stop: kind === "long" ? long_c.stop : long_c.entry,
|
|
36725
|
+
risk_reward: long_c.risk_reward,
|
|
36726
|
+
risk: long_c.risk
|
|
36727
|
+
}
|
|
36728
|
+
});
|
|
36729
|
+
}
|
|
36730
|
+
return config;
|
|
36731
|
+
}
|
|
36602
36732
|
async getPositionConfig(payload) {
|
|
36603
36733
|
if (payload.params) {
|
|
36604
36734
|
const db_position = await this.syncAccount({
|
|
@@ -36924,8 +37054,44 @@ class ExchangeAccount {
|
|
|
36924
37054
|
}
|
|
36925
37055
|
return null;
|
|
36926
37056
|
}
|
|
37057
|
+
async placeMarketOrder(payload) {
|
|
37058
|
+
const { symbol, kind, quantity } = payload;
|
|
37059
|
+
const symbol_config = await this.recomputeSymbolConfig({
|
|
37060
|
+
symbol
|
|
37061
|
+
});
|
|
37062
|
+
await this.exchange.placeMarketOrder({
|
|
37063
|
+
symbol,
|
|
37064
|
+
kind,
|
|
37065
|
+
quantity,
|
|
37066
|
+
price_places: symbol_config.price_places,
|
|
37067
|
+
decimal_places: symbol_config.decimal_places
|
|
37068
|
+
});
|
|
37069
|
+
}
|
|
37070
|
+
async placeSingleOrder(payload) {
|
|
37071
|
+
const { symbol, kind } = payload;
|
|
37072
|
+
const positions = await this.syncAccount({
|
|
37073
|
+
live_refresh: true,
|
|
37074
|
+
update: true,
|
|
37075
|
+
symbol
|
|
37076
|
+
});
|
|
37077
|
+
const long_position = positions.find((x) => x.kind === "long");
|
|
37078
|
+
const short_position = positions.find((x) => x.kind === "short");
|
|
37079
|
+
const focus_position = kind === "long" ? long_position : short_position;
|
|
37080
|
+
const track_position = kind === "long" ? short_position : long_position;
|
|
37081
|
+
if (!focus_position.follow) {
|
|
37082
|
+
return "No follow set";
|
|
37083
|
+
}
|
|
37084
|
+
if (track_position.quantity !== focus_position.quantity && focus_position.quantity < track_position.quantity) {
|
|
37085
|
+
const remaining_quantity = Math.abs(track_position.quantity - focus_position.quantity);
|
|
37086
|
+
await this.placeMarketOrder({
|
|
37087
|
+
symbol,
|
|
37088
|
+
kind,
|
|
37089
|
+
quantity: remaining_quantity
|
|
37090
|
+
});
|
|
37091
|
+
}
|
|
37092
|
+
}
|
|
36927
37093
|
async triggerTradeFromConfig(payload) {
|
|
36928
|
-
const { symbol, kind, place = true, stop } = payload;
|
|
37094
|
+
const { symbol, kind, place = true, stop, use_current } = payload;
|
|
36929
37095
|
const position2 = await this.syncAccount({
|
|
36930
37096
|
symbol,
|
|
36931
37097
|
kind
|
|
@@ -36942,7 +37108,7 @@ class ExchangeAccount {
|
|
|
36942
37108
|
risk: config.risk,
|
|
36943
37109
|
place,
|
|
36944
37110
|
raw: payload.raw,
|
|
36945
|
-
use_current
|
|
37111
|
+
use_current
|
|
36946
37112
|
});
|
|
36947
37113
|
}
|
|
36948
37114
|
}
|
|
@@ -37991,6 +38157,7 @@ class App {
|
|
|
37991
38157
|
}
|
|
37992
38158
|
const positions = await this.app_db.hasExistingPosition(symbol);
|
|
37993
38159
|
if (positions.length === 0) {
|
|
38160
|
+
console.log("Removing symbol from DB", symbol);
|
|
37994
38161
|
return this.app_db.unwindSymbolFromDB(symbol);
|
|
37995
38162
|
}
|
|
37996
38163
|
const unique_instances = new Set(positions.map((x) => `${x.symbol}-${x.expand.account.owner}-${x.expand.account.exchange}`));
|
|
@@ -38074,15 +38241,29 @@ class App {
|
|
|
38074
38241
|
owner: exchange.owner,
|
|
38075
38242
|
exchange: exchange.exchange
|
|
38076
38243
|
});
|
|
38077
|
-
await exchange_account.
|
|
38244
|
+
await exchange_account.placeProfitAndStop({
|
|
38078
38245
|
symbol,
|
|
38079
|
-
|
|
38080
|
-
|
|
38246
|
+
trigger: true,
|
|
38247
|
+
refresh: true
|
|
38081
38248
|
});
|
|
38082
|
-
await exchange_account.
|
|
38249
|
+
await exchange_account.syncAccount({
|
|
38083
38250
|
symbol,
|
|
38084
|
-
|
|
38251
|
+
update: true
|
|
38252
|
+
});
|
|
38253
|
+
}
|
|
38254
|
+
}
|
|
38255
|
+
async autoFollowPositions() {
|
|
38256
|
+
const positions = await this.app_db.getPositionsToAutoFollow();
|
|
38257
|
+
for (const position2 of positions) {
|
|
38258
|
+
const account = position2.expand.account;
|
|
38259
|
+
console.log("Getting account for ", account.owner, account.exchange);
|
|
38260
|
+
const exchange_account = await this.getExchangeAccount(account);
|
|
38261
|
+
console.log("Placing follow order for ", position2.symbol);
|
|
38262
|
+
const result = await exchange_account.placeSingleOrder({
|
|
38263
|
+
symbol: position2.symbol,
|
|
38264
|
+
kind: position2.kind
|
|
38085
38265
|
});
|
|
38266
|
+
console.log("result", result);
|
|
38086
38267
|
}
|
|
38087
38268
|
}
|
|
38088
38269
|
async getMoverExchangeInstances() {
|
|
@@ -38241,6 +38422,7 @@ export {
|
|
|
38241
38422
|
get_app_config_and_max_size,
|
|
38242
38423
|
getOptimumStopAndRisk,
|
|
38243
38424
|
generate_config_params,
|
|
38425
|
+
determine_break_even_price,
|
|
38244
38426
|
determine_average_entry_and_size,
|
|
38245
38427
|
createArray,
|
|
38246
38428
|
buildConfig,
|