@gbozee/ultimate 0.0.2-151 → 0.0.2-154
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 +134 -1
- package/dist/frontend-index.js +100 -7
- package/dist/index.cjs +202 -40
- package/dist/index.d.ts +79 -1
- package/dist/index.js +202 -40
- package/dist/mcp-server.cjs +200 -40
- package/dist/mcp-server.js +200 -40
- package/package.json +1 -1
package/dist/frontend-index.d.ts
CHANGED
|
@@ -278,6 +278,100 @@ export type GlobalConfig = {
|
|
|
278
278
|
reverse_factor: number;
|
|
279
279
|
leverage?: number;
|
|
280
280
|
};
|
|
281
|
+
export interface BaseSystemFields {
|
|
282
|
+
id: string;
|
|
283
|
+
created: string;
|
|
284
|
+
updated: string;
|
|
285
|
+
}
|
|
286
|
+
export interface ExchangeAccount extends BaseSystemFields {
|
|
287
|
+
exchange: "binance" | "bybit";
|
|
288
|
+
owner: string;
|
|
289
|
+
email?: string;
|
|
290
|
+
user?: string;
|
|
291
|
+
usdt?: number;
|
|
292
|
+
usdc?: number;
|
|
293
|
+
proxy?: string;
|
|
294
|
+
bullish?: boolean;
|
|
295
|
+
bearish?: boolean;
|
|
296
|
+
movePercent?: number;
|
|
297
|
+
totalRisk?: number;
|
|
298
|
+
max_non_essential?: number;
|
|
299
|
+
profit_percent?: number;
|
|
300
|
+
risk_reward?: number;
|
|
301
|
+
exclude_coins?: {
|
|
302
|
+
bullish?: string[];
|
|
303
|
+
};
|
|
304
|
+
include_delisted?: boolean;
|
|
305
|
+
}
|
|
306
|
+
export interface ScheduledTrade extends BaseSystemFields {
|
|
307
|
+
symbol: string;
|
|
308
|
+
account: string;
|
|
309
|
+
profit?: number;
|
|
310
|
+
risk?: number;
|
|
311
|
+
entry?: number;
|
|
312
|
+
stop?: number;
|
|
313
|
+
risk_reward?: number;
|
|
314
|
+
profit_percent?: number;
|
|
315
|
+
place_tp?: boolean;
|
|
316
|
+
kind?: "long" | "short";
|
|
317
|
+
follow?: boolean | 1 | 0;
|
|
318
|
+
reduce_ratio?: number;
|
|
319
|
+
sell_ratio?: number;
|
|
320
|
+
threshold_qty?: number;
|
|
321
|
+
pause_tp?: boolean;
|
|
322
|
+
stop_percent?: number;
|
|
323
|
+
kelly?: {
|
|
324
|
+
use_kelly?: boolean;
|
|
325
|
+
kelly_confidence_factor?: number;
|
|
326
|
+
kelly_minimum_risk?: number;
|
|
327
|
+
kelly_prediction_model?: "exponential" | "normal" | "uniform";
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
interface Proxy$1 extends BaseSystemFields {
|
|
331
|
+
ip_address?: string;
|
|
332
|
+
type?: "http" | "socks5";
|
|
333
|
+
}
|
|
334
|
+
export interface PositionsView {
|
|
335
|
+
id: string;
|
|
336
|
+
symbol?: any;
|
|
337
|
+
entry?: any;
|
|
338
|
+
quantity?: any;
|
|
339
|
+
take_profit?: any;
|
|
340
|
+
account?: any;
|
|
341
|
+
kind?: any;
|
|
342
|
+
target_pnl?: number;
|
|
343
|
+
liquidation?: number;
|
|
344
|
+
avg_price?: number;
|
|
345
|
+
avg_qty?: number;
|
|
346
|
+
next_order?: number;
|
|
347
|
+
last_order?: number;
|
|
348
|
+
config?: any;
|
|
349
|
+
stop_loss?: {
|
|
350
|
+
price: number;
|
|
351
|
+
quantity: number;
|
|
352
|
+
};
|
|
353
|
+
stop_pnl?: any;
|
|
354
|
+
leverage?: any;
|
|
355
|
+
avg_liquidation?: any;
|
|
356
|
+
balance?: any;
|
|
357
|
+
reduce_ratio?: number;
|
|
358
|
+
sell_ratio?: number;
|
|
359
|
+
threshold_qty?: number;
|
|
360
|
+
follow?: boolean | 1 | 0;
|
|
361
|
+
current_price?: number;
|
|
362
|
+
usd_balance?: number;
|
|
363
|
+
tp?: {
|
|
364
|
+
price: number;
|
|
365
|
+
quantity: number;
|
|
366
|
+
};
|
|
367
|
+
next_risk?: number;
|
|
368
|
+
proxy?: string;
|
|
369
|
+
expand?: {
|
|
370
|
+
p_account?: ExchangeAccount;
|
|
371
|
+
b_config?: ScheduledTrade;
|
|
372
|
+
proxy?: Proxy$1;
|
|
373
|
+
};
|
|
374
|
+
}
|
|
281
375
|
export type AppConfig = {
|
|
282
376
|
fee: number;
|
|
283
377
|
risk_per_trade: number;
|
|
@@ -440,7 +534,13 @@ export declare function generateOptimumAppConfig(config: GlobalConfig, payload:
|
|
|
440
534
|
quantity: number;
|
|
441
535
|
kind: "long" | "short";
|
|
442
536
|
}): AppConfig | null;
|
|
443
|
-
export declare function determineOptimumReward(
|
|
537
|
+
export declare function determineOptimumReward(payload: {
|
|
538
|
+
app_config: AppConfig;
|
|
539
|
+
increase?: boolean;
|
|
540
|
+
low_range?: number;
|
|
541
|
+
high_range?: number;
|
|
542
|
+
target_loss?: number;
|
|
543
|
+
}): number | {
|
|
444
544
|
result: any[];
|
|
445
545
|
value: number;
|
|
446
546
|
total: number;
|
|
@@ -476,6 +576,7 @@ export declare function computeRiskReward(payload: {
|
|
|
476
576
|
entry: number;
|
|
477
577
|
stop: number;
|
|
478
578
|
risk_per_trade: number;
|
|
579
|
+
target_loss?: number;
|
|
479
580
|
}): number | {
|
|
480
581
|
result: any[];
|
|
481
582
|
value: number;
|
|
@@ -660,6 +761,38 @@ export declare function determineCompoundLongTrade(payload: {
|
|
|
660
761
|
result: any;
|
|
661
762
|
short_max_size: any;
|
|
662
763
|
};
|
|
764
|
+
export declare function generateOppositeTradeConfig(payload: {
|
|
765
|
+
kind: "long" | "short";
|
|
766
|
+
entry: number;
|
|
767
|
+
quantity: number;
|
|
768
|
+
target_pnl: number;
|
|
769
|
+
global_config: GlobalConfig;
|
|
770
|
+
ratio?: number;
|
|
771
|
+
}): {
|
|
772
|
+
entry: number;
|
|
773
|
+
stop: number;
|
|
774
|
+
risk: number;
|
|
775
|
+
risk_reward: number | {
|
|
776
|
+
result: any[];
|
|
777
|
+
value: number;
|
|
778
|
+
total: number;
|
|
779
|
+
risk_per_trade: number;
|
|
780
|
+
max: number;
|
|
781
|
+
min: number;
|
|
782
|
+
neg_pnl: any;
|
|
783
|
+
entry: any;
|
|
784
|
+
};
|
|
785
|
+
};
|
|
786
|
+
export declare function constructAppConfig(payload: {
|
|
787
|
+
account: PositionsView;
|
|
788
|
+
global_config: GlobalConfig;
|
|
789
|
+
kelly_config?: {
|
|
790
|
+
use_kelly: boolean;
|
|
791
|
+
kelly_confidence_factor: number;
|
|
792
|
+
kelly_minimum_risk: number;
|
|
793
|
+
kelly_prediction_model: string;
|
|
794
|
+
};
|
|
795
|
+
}): AppConfig;
|
|
663
796
|
export type StrategyPosition = {
|
|
664
797
|
entry: number;
|
|
665
798
|
quantity: number;
|
package/dist/frontend-index.js
CHANGED
|
@@ -1928,7 +1928,14 @@ function generateOptimumAppConfig(config, payload, position2) {
|
|
|
1928
1928
|
});
|
|
1929
1929
|
return best_app_config;
|
|
1930
1930
|
}
|
|
1931
|
-
function determineOptimumReward(
|
|
1931
|
+
function determineOptimumReward(payload) {
|
|
1932
|
+
const {
|
|
1933
|
+
app_config,
|
|
1934
|
+
increase = true,
|
|
1935
|
+
low_range = 1,
|
|
1936
|
+
high_range = 199,
|
|
1937
|
+
target_loss
|
|
1938
|
+
} = payload;
|
|
1932
1939
|
const criterion = app_config.strategy || "quantity";
|
|
1933
1940
|
const risk_rewards = createArray(low_range, high_range, 1);
|
|
1934
1941
|
let func = risk_rewards.map((trade_no) => {
|
|
@@ -1968,10 +1975,33 @@ function determineOptimumReward(app_config, increase = true, low_range = 30, hig
|
|
|
1968
1975
|
entry
|
|
1969
1976
|
};
|
|
1970
1977
|
});
|
|
1971
|
-
func = func.filter((r) => Boolean(r))
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1978
|
+
func = func.filter((r) => Boolean(r));
|
|
1979
|
+
if (target_loss === undefined) {
|
|
1980
|
+
func = func.filter((r) => {
|
|
1981
|
+
let foundIndex = r?.result.findIndex((e) => e.quantity === r.max);
|
|
1982
|
+
return criterion === "quantity" ? foundIndex === 0 : true;
|
|
1983
|
+
});
|
|
1984
|
+
}
|
|
1985
|
+
if (target_loss !== undefined) {
|
|
1986
|
+
const validResults = func.filter((r) => Math.abs(r.neg_pnl) <= target_loss);
|
|
1987
|
+
if (validResults.length > 0) {
|
|
1988
|
+
validResults.sort((a, b) => {
|
|
1989
|
+
const diffA = target_loss - Math.abs(a.neg_pnl);
|
|
1990
|
+
const diffB = target_loss - Math.abs(b.neg_pnl);
|
|
1991
|
+
return diffA - diffB;
|
|
1992
|
+
});
|
|
1993
|
+
if (app_config.raw) {
|
|
1994
|
+
return validResults[0];
|
|
1995
|
+
}
|
|
1996
|
+
return validResults[0]?.value;
|
|
1997
|
+
} else {
|
|
1998
|
+
func.sort((a, b) => Math.abs(a.neg_pnl) - Math.abs(b.neg_pnl));
|
|
1999
|
+
if (app_config.raw) {
|
|
2000
|
+
return func[0];
|
|
2001
|
+
}
|
|
2002
|
+
return func[0]?.value;
|
|
2003
|
+
}
|
|
2004
|
+
}
|
|
1975
2005
|
const highest = criterion === "quantity" ? Math.max(...func.map((o) => o.max)) : Math.min(...func.map((o) => o.entry));
|
|
1976
2006
|
const key = criterion === "quantity" ? "max" : "entry";
|
|
1977
2007
|
const index = findIndexByCondition(func, app_config.kind, (x) => x[key] == highest, criterion);
|
|
@@ -2083,13 +2113,13 @@ function determineOptimumRisk(config, payload, params) {
|
|
|
2083
2113
|
};
|
|
2084
2114
|
}
|
|
2085
2115
|
function computeRiskReward(payload) {
|
|
2086
|
-
const { app_config, entry, stop, risk_per_trade } = payload;
|
|
2116
|
+
const { app_config, entry, stop, risk_per_trade, target_loss } = payload;
|
|
2087
2117
|
const kind = entry > stop ? "long" : "short";
|
|
2088
2118
|
app_config.kind = kind;
|
|
2089
2119
|
app_config.entry = entry;
|
|
2090
2120
|
app_config.stop = stop;
|
|
2091
2121
|
app_config.risk_per_trade = risk_per_trade;
|
|
2092
|
-
const result = determineOptimumReward(app_config);
|
|
2122
|
+
const result = determineOptimumReward({ app_config, target_loss });
|
|
2093
2123
|
return result;
|
|
2094
2124
|
}
|
|
2095
2125
|
function getRiskReward(payload) {
|
|
@@ -2424,6 +2454,67 @@ function determineCompoundLongTrade(payload) {
|
|
|
2424
2454
|
short_max_size
|
|
2425
2455
|
};
|
|
2426
2456
|
}
|
|
2457
|
+
function generateOppositeTradeConfig(payload) {
|
|
2458
|
+
const {
|
|
2459
|
+
kind,
|
|
2460
|
+
entry,
|
|
2461
|
+
quantity,
|
|
2462
|
+
target_pnl,
|
|
2463
|
+
ratio = 0.5,
|
|
2464
|
+
global_config
|
|
2465
|
+
} = payload;
|
|
2466
|
+
const diff = target_pnl / quantity;
|
|
2467
|
+
const tp = kind === "long" ? entry + diff : entry - diff;
|
|
2468
|
+
const stop = kind === "long" ? entry - diff : entry + diff;
|
|
2469
|
+
const opposite_pnl = target_pnl * ratio;
|
|
2470
|
+
const app_config = constructAppConfig({
|
|
2471
|
+
account: {
|
|
2472
|
+
expand: {
|
|
2473
|
+
b_config: {
|
|
2474
|
+
entry,
|
|
2475
|
+
stop,
|
|
2476
|
+
symbol: global_config.symbol,
|
|
2477
|
+
risk: target_pnl
|
|
2478
|
+
}
|
|
2479
|
+
}
|
|
2480
|
+
},
|
|
2481
|
+
global_config
|
|
2482
|
+
});
|
|
2483
|
+
const risk_reward = computeRiskReward({
|
|
2484
|
+
app_config,
|
|
2485
|
+
entry: stop,
|
|
2486
|
+
stop: tp,
|
|
2487
|
+
risk_per_trade: opposite_pnl,
|
|
2488
|
+
target_loss: opposite_pnl
|
|
2489
|
+
});
|
|
2490
|
+
return {
|
|
2491
|
+
entry: to_f(stop, global_config.price_places),
|
|
2492
|
+
stop: to_f(tp, global_config.price_places),
|
|
2493
|
+
risk: to_f(opposite_pnl, "%.2f"),
|
|
2494
|
+
risk_reward
|
|
2495
|
+
};
|
|
2496
|
+
}
|
|
2497
|
+
function constructAppConfig(payload) {
|
|
2498
|
+
const { account, global_config, kelly_config } = payload;
|
|
2499
|
+
const config = account.expand?.b_config;
|
|
2500
|
+
if (!config) {
|
|
2501
|
+
return null;
|
|
2502
|
+
}
|
|
2503
|
+
const kelly = config.kelly;
|
|
2504
|
+
const options = {
|
|
2505
|
+
entry: config?.entry,
|
|
2506
|
+
stop: config?.stop,
|
|
2507
|
+
risk_reward: config?.risk_reward,
|
|
2508
|
+
risk: config?.risk,
|
|
2509
|
+
symbol: account.symbol,
|
|
2510
|
+
use_kelly: kelly_config?.use_kelly ?? kelly?.use_kelly,
|
|
2511
|
+
kelly_confidence_factor: kelly_config?.kelly_confidence_factor ?? kelly?.kelly_confidence_factor,
|
|
2512
|
+
kelly_minimum_risk: kelly_config?.kelly_minimum_risk ?? kelly?.kelly_minimum_risk,
|
|
2513
|
+
kelly_prediction_model: kelly_config?.kelly_prediction_model ?? kelly?.kelly_prediction_model
|
|
2514
|
+
};
|
|
2515
|
+
const appConfig = buildAppConfig(global_config, options);
|
|
2516
|
+
return appConfig;
|
|
2517
|
+
}
|
|
2427
2518
|
// src/helpers/strategy.ts
|
|
2428
2519
|
class Strategy {
|
|
2429
2520
|
position;
|
|
@@ -2942,6 +3033,7 @@ export {
|
|
|
2942
3033
|
getDecimalPlaces,
|
|
2943
3034
|
generate_config_params,
|
|
2944
3035
|
generateOptimumAppConfig,
|
|
3036
|
+
generateOppositeTradeConfig,
|
|
2945
3037
|
generateGapTp,
|
|
2946
3038
|
formatPrice,
|
|
2947
3039
|
fibonacci_analysis,
|
|
@@ -2960,6 +3052,7 @@ export {
|
|
|
2960
3052
|
determineCompoundLongTrade,
|
|
2961
3053
|
createGapPairs,
|
|
2962
3054
|
createArray,
|
|
3055
|
+
constructAppConfig,
|
|
2963
3056
|
computeTotalAverageForEachTrade,
|
|
2964
3057
|
computeSellZones,
|
|
2965
3058
|
computeRiskReward,
|
package/dist/index.cjs
CHANGED
|
@@ -41955,6 +41955,7 @@ __export(exports_src, {
|
|
|
41955
41955
|
getHedgeZone: () => getHedgeZone,
|
|
41956
41956
|
generate_config_params: () => generate_config_params,
|
|
41957
41957
|
generateOptimumAppConfig: () => generateOptimumAppConfig,
|
|
41958
|
+
generateOppositeTradeConfig: () => generateOppositeTradeConfig,
|
|
41958
41959
|
generateGapTp: () => generateGapTp,
|
|
41959
41960
|
exchange_account: () => exports_exchange_account,
|
|
41960
41961
|
determine_break_even_price: () => determine_break_even_price,
|
|
@@ -41966,6 +41967,7 @@ __export(exports_src, {
|
|
|
41966
41967
|
determineCompoundLongTrade: () => determineCompoundLongTrade,
|
|
41967
41968
|
database: () => exports_database,
|
|
41968
41969
|
createArray: () => createArray,
|
|
41970
|
+
constructAppConfig: () => constructAppConfig,
|
|
41969
41971
|
computeRiskReward: () => computeRiskReward,
|
|
41970
41972
|
computeProfitDetail: () => computeProfitDetail,
|
|
41971
41973
|
buildConfig: () => buildConfig,
|
|
@@ -51744,7 +51746,6 @@ class AppDatabase {
|
|
|
51744
51746
|
const result = await this.get_exchange_db_instance(account);
|
|
51745
51747
|
if (result?.expand?.proxy) {
|
|
51746
51748
|
const { type, ip_address } = result.expand.proxy;
|
|
51747
|
-
console.log(type, ip_address);
|
|
51748
51749
|
if (type === "http") {
|
|
51749
51750
|
return new import_https_proxy_agent.HttpsProxyAgent(`http://${ip_address}`);
|
|
51750
51751
|
}
|
|
@@ -51792,13 +51793,13 @@ class AppDatabase {
|
|
|
51792
51793
|
table: "positions_view",
|
|
51793
51794
|
params: {
|
|
51794
51795
|
filter: `symbol:lower="${symbol.toLowerCase()}" && account:lower="${account.owner.toLowerCase()} ${account.exchange.toLowerCase()}"`,
|
|
51795
|
-
expand: "config, account_strategy, p_account"
|
|
51796
|
+
expand: "config, account_strategy, p_account, proxy"
|
|
51796
51797
|
}
|
|
51797
51798
|
} : {
|
|
51798
51799
|
table: "positions",
|
|
51799
51800
|
params: {
|
|
51800
51801
|
filter: `symbol:lower="${symbol.toLowerCase()}" && account.owner:lower="${account.owner.toLowerCase()}" && account.exchange:lower="${account.exchange.toLowerCase()}"`,
|
|
51801
|
-
expand: "account,config"
|
|
51802
|
+
expand: "account,config, proxy"
|
|
51802
51803
|
}
|
|
51803
51804
|
};
|
|
51804
51805
|
if (custom_filter) {
|
|
@@ -54328,7 +54329,14 @@ function generateOptimumAppConfig(config2, payload, position2) {
|
|
|
54328
54329
|
});
|
|
54329
54330
|
return best_app_config;
|
|
54330
54331
|
}
|
|
54331
|
-
function determineOptimumReward(
|
|
54332
|
+
function determineOptimumReward(payload) {
|
|
54333
|
+
const {
|
|
54334
|
+
app_config,
|
|
54335
|
+
increase = true,
|
|
54336
|
+
low_range = 1,
|
|
54337
|
+
high_range = 199,
|
|
54338
|
+
target_loss
|
|
54339
|
+
} = payload;
|
|
54332
54340
|
const criterion = app_config.strategy || "quantity";
|
|
54333
54341
|
const risk_rewards = createArray(low_range, high_range, 1);
|
|
54334
54342
|
let func = risk_rewards.map((trade_no) => {
|
|
@@ -54368,10 +54376,33 @@ function determineOptimumReward(app_config, increase = true, low_range = 30, hig
|
|
|
54368
54376
|
entry
|
|
54369
54377
|
};
|
|
54370
54378
|
});
|
|
54371
|
-
func = func.filter((r2) => Boolean(r2))
|
|
54372
|
-
|
|
54373
|
-
|
|
54374
|
-
|
|
54379
|
+
func = func.filter((r2) => Boolean(r2));
|
|
54380
|
+
if (target_loss === undefined) {
|
|
54381
|
+
func = func.filter((r2) => {
|
|
54382
|
+
let foundIndex = r2?.result.findIndex((e2) => e2.quantity === r2.max);
|
|
54383
|
+
return criterion === "quantity" ? foundIndex === 0 : true;
|
|
54384
|
+
});
|
|
54385
|
+
}
|
|
54386
|
+
if (target_loss !== undefined) {
|
|
54387
|
+
const validResults = func.filter((r2) => Math.abs(r2.neg_pnl) <= target_loss);
|
|
54388
|
+
if (validResults.length > 0) {
|
|
54389
|
+
validResults.sort((a, b) => {
|
|
54390
|
+
const diffA = target_loss - Math.abs(a.neg_pnl);
|
|
54391
|
+
const diffB = target_loss - Math.abs(b.neg_pnl);
|
|
54392
|
+
return diffA - diffB;
|
|
54393
|
+
});
|
|
54394
|
+
if (app_config.raw) {
|
|
54395
|
+
return validResults[0];
|
|
54396
|
+
}
|
|
54397
|
+
return validResults[0]?.value;
|
|
54398
|
+
} else {
|
|
54399
|
+
func.sort((a, b) => Math.abs(a.neg_pnl) - Math.abs(b.neg_pnl));
|
|
54400
|
+
if (app_config.raw) {
|
|
54401
|
+
return func[0];
|
|
54402
|
+
}
|
|
54403
|
+
return func[0]?.value;
|
|
54404
|
+
}
|
|
54405
|
+
}
|
|
54375
54406
|
const highest = criterion === "quantity" ? Math.max(...func.map((o) => o.max)) : Math.min(...func.map((o) => o.entry));
|
|
54376
54407
|
const key = criterion === "quantity" ? "max" : "entry";
|
|
54377
54408
|
const index = findIndexByCondition(func, app_config.kind, (x) => x[key] == highest, criterion);
|
|
@@ -54483,13 +54514,13 @@ function determineOptimumRisk(config2, payload, params) {
|
|
|
54483
54514
|
};
|
|
54484
54515
|
}
|
|
54485
54516
|
function computeRiskReward(payload) {
|
|
54486
|
-
const { app_config, entry, stop, risk_per_trade } = payload;
|
|
54517
|
+
const { app_config, entry, stop, risk_per_trade, target_loss } = payload;
|
|
54487
54518
|
const kind = entry > stop ? "long" : "short";
|
|
54488
54519
|
app_config.kind = kind;
|
|
54489
54520
|
app_config.entry = entry;
|
|
54490
54521
|
app_config.stop = stop;
|
|
54491
54522
|
app_config.risk_per_trade = risk_per_trade;
|
|
54492
|
-
const result = determineOptimumReward(app_config);
|
|
54523
|
+
const result = determineOptimumReward({ app_config, target_loss });
|
|
54493
54524
|
return result;
|
|
54494
54525
|
}
|
|
54495
54526
|
function getRiskReward(payload) {
|
|
@@ -54824,6 +54855,67 @@ function determineCompoundLongTrade(payload) {
|
|
|
54824
54855
|
short_max_size
|
|
54825
54856
|
};
|
|
54826
54857
|
}
|
|
54858
|
+
function generateOppositeTradeConfig(payload) {
|
|
54859
|
+
const {
|
|
54860
|
+
kind,
|
|
54861
|
+
entry,
|
|
54862
|
+
quantity,
|
|
54863
|
+
target_pnl,
|
|
54864
|
+
ratio = 0.5,
|
|
54865
|
+
global_config
|
|
54866
|
+
} = payload;
|
|
54867
|
+
const diff = target_pnl / quantity;
|
|
54868
|
+
const tp = kind === "long" ? entry + diff : entry - diff;
|
|
54869
|
+
const stop = kind === "long" ? entry - diff : entry + diff;
|
|
54870
|
+
const opposite_pnl = target_pnl * ratio;
|
|
54871
|
+
const app_config = constructAppConfig({
|
|
54872
|
+
account: {
|
|
54873
|
+
expand: {
|
|
54874
|
+
b_config: {
|
|
54875
|
+
entry,
|
|
54876
|
+
stop,
|
|
54877
|
+
symbol: global_config.symbol,
|
|
54878
|
+
risk: target_pnl
|
|
54879
|
+
}
|
|
54880
|
+
}
|
|
54881
|
+
},
|
|
54882
|
+
global_config
|
|
54883
|
+
});
|
|
54884
|
+
const risk_reward = computeRiskReward({
|
|
54885
|
+
app_config,
|
|
54886
|
+
entry: stop,
|
|
54887
|
+
stop: tp,
|
|
54888
|
+
risk_per_trade: opposite_pnl,
|
|
54889
|
+
target_loss: opposite_pnl
|
|
54890
|
+
});
|
|
54891
|
+
return {
|
|
54892
|
+
entry: to_f(stop, global_config.price_places),
|
|
54893
|
+
stop: to_f(tp, global_config.price_places),
|
|
54894
|
+
risk: to_f(opposite_pnl, "%.2f"),
|
|
54895
|
+
risk_reward
|
|
54896
|
+
};
|
|
54897
|
+
}
|
|
54898
|
+
function constructAppConfig(payload) {
|
|
54899
|
+
const { account, global_config, kelly_config } = payload;
|
|
54900
|
+
const config2 = account.expand?.b_config;
|
|
54901
|
+
if (!config2) {
|
|
54902
|
+
return null;
|
|
54903
|
+
}
|
|
54904
|
+
const kelly = config2.kelly;
|
|
54905
|
+
const options = {
|
|
54906
|
+
entry: config2?.entry,
|
|
54907
|
+
stop: config2?.stop,
|
|
54908
|
+
risk_reward: config2?.risk_reward,
|
|
54909
|
+
risk: config2?.risk,
|
|
54910
|
+
symbol: account.symbol,
|
|
54911
|
+
use_kelly: kelly_config?.use_kelly ?? kelly?.use_kelly,
|
|
54912
|
+
kelly_confidence_factor: kelly_config?.kelly_confidence_factor ?? kelly?.kelly_confidence_factor,
|
|
54913
|
+
kelly_minimum_risk: kelly_config?.kelly_minimum_risk ?? kelly?.kelly_minimum_risk,
|
|
54914
|
+
kelly_prediction_model: kelly_config?.kelly_prediction_model ?? kelly?.kelly_prediction_model
|
|
54915
|
+
};
|
|
54916
|
+
const appConfig = buildAppConfig(global_config, options);
|
|
54917
|
+
return appConfig;
|
|
54918
|
+
}
|
|
54827
54919
|
// src/helpers/strategy.ts
|
|
54828
54920
|
class Strategy {
|
|
54829
54921
|
position;
|
|
@@ -57745,6 +57837,9 @@ async function reduceMajorPositionEntry(input, accountInfo, trigger2, exchange_i
|
|
|
57745
57837
|
}
|
|
57746
57838
|
|
|
57747
57839
|
// src/position.ts
|
|
57840
|
+
var import_https_proxy_agent2 = __toESM(require_dist2());
|
|
57841
|
+
var import_socks_proxy_agent2 = __toESM(require_dist3());
|
|
57842
|
+
|
|
57748
57843
|
class ExchangePosition {
|
|
57749
57844
|
exchange;
|
|
57750
57845
|
symbol_config;
|
|
@@ -57758,6 +57853,13 @@ class ExchangePosition {
|
|
|
57758
57853
|
this.instance = payload.instance;
|
|
57759
57854
|
this.exchange_account = payload.exchange_account;
|
|
57760
57855
|
}
|
|
57856
|
+
async initialize() {
|
|
57857
|
+
const proxy = await this.getProxyForAccount();
|
|
57858
|
+
if (proxy) {
|
|
57859
|
+
this.exchange.client.globalRequestOptions.httpAgent = proxy;
|
|
57860
|
+
this.exchange.client.globalRequestOptions.httpsAgent = proxy;
|
|
57861
|
+
}
|
|
57862
|
+
}
|
|
57761
57863
|
getInstance() {
|
|
57762
57864
|
return this.instance;
|
|
57763
57865
|
}
|
|
@@ -57771,6 +57873,20 @@ class ExchangePosition {
|
|
|
57771
57873
|
const { p_account } = this.instance.expand;
|
|
57772
57874
|
return p_account;
|
|
57773
57875
|
}
|
|
57876
|
+
async getProxyForAccount() {
|
|
57877
|
+
if (this.instance.expand.proxy) {
|
|
57878
|
+
const result = this.instance.expand.proxy;
|
|
57879
|
+
const { type, ip_address } = result;
|
|
57880
|
+
console.log("position", type, ip_address);
|
|
57881
|
+
if (type === "http") {
|
|
57882
|
+
return new import_https_proxy_agent2.HttpsProxyAgent(`http://${ip_address}`);
|
|
57883
|
+
}
|
|
57884
|
+
if (type === "socks5") {
|
|
57885
|
+
return new import_socks_proxy_agent2.SocksProxyAgent(`socks://${ip_address}`);
|
|
57886
|
+
}
|
|
57887
|
+
}
|
|
57888
|
+
return null;
|
|
57889
|
+
}
|
|
57774
57890
|
async cancelOrders(payload) {
|
|
57775
57891
|
const { limit, price: _price, raw } = payload;
|
|
57776
57892
|
if (limit) {
|
|
@@ -58578,6 +58694,46 @@ class ExchangePosition {
|
|
|
58578
58694
|
});
|
|
58579
58695
|
return app_config;
|
|
58580
58696
|
}
|
|
58697
|
+
async getOrCreatePositionConfig(payload) {
|
|
58698
|
+
const { risk = 50, risk_reward = 199 } = payload;
|
|
58699
|
+
const config2 = await this.getConfig();
|
|
58700
|
+
if (!config2) {
|
|
58701
|
+
const long_c = await this.buildConfigForSymbol({
|
|
58702
|
+
risk,
|
|
58703
|
+
risk_reward
|
|
58704
|
+
});
|
|
58705
|
+
return this.getConfig({
|
|
58706
|
+
params: {
|
|
58707
|
+
entry: config2.entry,
|
|
58708
|
+
stop: config2.stop,
|
|
58709
|
+
risk_reward: long_c.risk_reward,
|
|
58710
|
+
risk: long_c.risk
|
|
58711
|
+
}
|
|
58712
|
+
});
|
|
58713
|
+
}
|
|
58714
|
+
return config2;
|
|
58715
|
+
}
|
|
58716
|
+
getOppositeConfig(payload) {
|
|
58717
|
+
return generateOppositeTradeConfig({
|
|
58718
|
+
kind: this.kind,
|
|
58719
|
+
entry: this.instance.entry,
|
|
58720
|
+
quantity: this.instance.quantity,
|
|
58721
|
+
target_pnl: this.instance.target_pnl,
|
|
58722
|
+
global_config: this.symbol_config,
|
|
58723
|
+
ratio: payload.ratio
|
|
58724
|
+
});
|
|
58725
|
+
}
|
|
58726
|
+
async getOptimumRiskReward() {
|
|
58727
|
+
const app_config = await this.tradeConfig({});
|
|
58728
|
+
const risk_reward = computeRiskReward({
|
|
58729
|
+
app_config,
|
|
58730
|
+
entry: app_config.entry,
|
|
58731
|
+
stop: app_config.stop,
|
|
58732
|
+
risk_per_trade: app_config.risk_per_trade,
|
|
58733
|
+
target_loss: app_config.risk_per_trade
|
|
58734
|
+
});
|
|
58735
|
+
return risk_reward;
|
|
58736
|
+
}
|
|
58581
58737
|
}
|
|
58582
58738
|
|
|
58583
58739
|
// src/exchange-account.ts
|
|
@@ -58650,6 +58806,7 @@ class ExchangeAccount {
|
|
|
58650
58806
|
app_db: this.app_db,
|
|
58651
58807
|
without_view: raw_positions.find((x) => x.kind === "long")
|
|
58652
58808
|
});
|
|
58809
|
+
await this.long_position.initialize();
|
|
58653
58810
|
this.short_position = new ExchangePosition({
|
|
58654
58811
|
symbol_config,
|
|
58655
58812
|
exchange: this.exchange,
|
|
@@ -58658,6 +58815,7 @@ class ExchangeAccount {
|
|
|
58658
58815
|
app_db: this.app_db,
|
|
58659
58816
|
without_view: raw_positions.find((x) => x.kind === "short")
|
|
58660
58817
|
});
|
|
58818
|
+
await this.short_position.initialize();
|
|
58661
58819
|
return payload.kind === "long" ? this.long_position : this.short_position;
|
|
58662
58820
|
}
|
|
58663
58821
|
async getActiveAccount(payload) {
|
|
@@ -58897,29 +59055,8 @@ class ExchangeAccount {
|
|
|
58897
59055
|
return result;
|
|
58898
59056
|
}
|
|
58899
59057
|
async getOrCreatePositionConfig(payload) {
|
|
58900
|
-
const
|
|
58901
|
-
|
|
58902
|
-
symbol: payload.symbol,
|
|
58903
|
-
kind: payload.kind
|
|
58904
|
-
});
|
|
58905
|
-
if (!config2) {
|
|
58906
|
-
const long_c = await this.buildConfigForSymbol({
|
|
58907
|
-
symbol,
|
|
58908
|
-
risk,
|
|
58909
|
-
risk_reward
|
|
58910
|
-
});
|
|
58911
|
-
return this.getPositionConfig({
|
|
58912
|
-
symbol,
|
|
58913
|
-
kind,
|
|
58914
|
-
params: {
|
|
58915
|
-
entry: kind === "long" ? long_c.entry : long_c.stop,
|
|
58916
|
-
stop: kind === "long" ? long_c.stop : long_c.entry,
|
|
58917
|
-
risk_reward: long_c.risk_reward,
|
|
58918
|
-
risk: long_c.risk
|
|
58919
|
-
}
|
|
58920
|
-
});
|
|
58921
|
-
}
|
|
58922
|
-
return config2;
|
|
59058
|
+
const focus_position = await this.getFocusPosition(payload);
|
|
59059
|
+
return await focus_position.getOrCreatePositionConfig(payload);
|
|
58923
59060
|
}
|
|
58924
59061
|
async getPositionConfig(payload) {
|
|
58925
59062
|
const focus_position = await this.getFocusPosition(payload);
|
|
@@ -59653,15 +59790,9 @@ class ExchangeAccount {
|
|
|
59653
59790
|
const all_open_symbols = await this.exchange.getOpenPositions();
|
|
59654
59791
|
await new Promise((resolve) => setTimeout(resolve, interval * 1000));
|
|
59655
59792
|
for (const symbol of Array.from(new Set(symbols.concat(all_open_symbols)))) {
|
|
59656
|
-
await this.
|
|
59793
|
+
await this.initializePositions({ symbol, kind: "long", update: true });
|
|
59657
59794
|
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
59658
59795
|
}
|
|
59659
|
-
for (const symbol of all_open_symbols) {
|
|
59660
|
-
await this.syncAccount({
|
|
59661
|
-
symbol,
|
|
59662
|
-
update: true
|
|
59663
|
-
});
|
|
59664
|
-
}
|
|
59665
59796
|
}
|
|
59666
59797
|
async updateAllPositionsWithNoConfig(payload) {
|
|
59667
59798
|
const { kind } = payload;
|
|
@@ -60044,6 +60175,7 @@ class ExchangeAccount {
|
|
|
60044
60175
|
return;
|
|
60045
60176
|
}
|
|
60046
60177
|
const kind = strategy2.kind;
|
|
60178
|
+
const reward_factor = strategy2.reward_factor;
|
|
60047
60179
|
const { entries, last_value, ...app_config } = await this.tradeConfig({
|
|
60048
60180
|
symbol,
|
|
60049
60181
|
kind
|
|
@@ -60065,6 +60197,36 @@ class ExchangeAccount {
|
|
|
60065
60197
|
});
|
|
60066
60198
|
}
|
|
60067
60199
|
console.log("Checking if focus position has quantity for ", symbol, kind);
|
|
60200
|
+
const focusPosition = await this.getFocusPosition({
|
|
60201
|
+
symbol,
|
|
60202
|
+
kind
|
|
60203
|
+
});
|
|
60204
|
+
const reversePosition = await this.getFocusPosition({
|
|
60205
|
+
symbol,
|
|
60206
|
+
kind: kind === "long" ? "short" : "long"
|
|
60207
|
+
});
|
|
60208
|
+
const opposite_config = focusPosition.getOppositeConfig({
|
|
60209
|
+
ratio: reward_factor
|
|
60210
|
+
});
|
|
60211
|
+
const reverse_config = await reversePosition.getConfig();
|
|
60212
|
+
if ((reverse_config.entry !== opposite_config.entry || reverse_config.stop !== opposite_config.stop || reverse_config.risk !== opposite_config.risk || reverse_config.risk_reward !== opposite_config.risk_reward) && focusPosition.getInstance().quantity > 0) {
|
|
60213
|
+
console.log("Updating reverse config for ", symbol, kind, "with opposite config", opposite_config);
|
|
60214
|
+
await reversePosition.getConfig({
|
|
60215
|
+
params: {
|
|
60216
|
+
entry: opposite_config.entry,
|
|
60217
|
+
stop: opposite_config.stop,
|
|
60218
|
+
risk: opposite_config.risk,
|
|
60219
|
+
risk_reward: opposite_config.risk_reward
|
|
60220
|
+
}
|
|
60221
|
+
});
|
|
60222
|
+
console.log("Placing trade for ", symbol, reversePosition.kind);
|
|
60223
|
+
await reversePosition.placeTrade({
|
|
60224
|
+
ignore_config: true,
|
|
60225
|
+
limit: true,
|
|
60226
|
+
place: true
|
|
60227
|
+
});
|
|
60228
|
+
}
|
|
60229
|
+
console.log("Opposite config for ", symbol, kind, opposite_config);
|
|
60068
60230
|
return {
|
|
60069
60231
|
config_details: {
|
|
60070
60232
|
app_config,
|