@gbozee/ultimate 0.0.2-111 → 0.0.2-113
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 +2 -1
- package/dist/frontend-index.js +13 -2
- package/dist/index.cjs +102 -38
- package/dist/index.d.ts +42 -12
- package/dist/index.js +102 -38
- package/dist/mcp-server.cjs +196 -8
- package/dist/mcp-server.js +196 -8
- package/package.json +1 -1
package/dist/frontend-index.d.ts
CHANGED
|
@@ -543,8 +543,9 @@ export declare function getHedgeZone(payload: {
|
|
|
543
543
|
symbol_config: GlobalConfig;
|
|
544
544
|
risk: number;
|
|
545
545
|
position: BotPosition;
|
|
546
|
-
reward_factor
|
|
546
|
+
reward_factor?: number;
|
|
547
547
|
risk_factor?: number;
|
|
548
|
+
support?: number;
|
|
548
549
|
}): {
|
|
549
550
|
support: number;
|
|
550
551
|
resistance: number;
|
package/dist/frontend-index.js
CHANGED
|
@@ -1948,13 +1948,24 @@ function determineRewardFactor(payload) {
|
|
|
1948
1948
|
}
|
|
1949
1949
|
function getHedgeZone(payload) {
|
|
1950
1950
|
const {
|
|
1951
|
-
reward_factor,
|
|
1951
|
+
reward_factor: _reward_factor,
|
|
1952
1952
|
symbol_config,
|
|
1953
1953
|
risk,
|
|
1954
1954
|
position: position2,
|
|
1955
|
-
risk_factor = 1
|
|
1955
|
+
risk_factor = 1,
|
|
1956
|
+
support
|
|
1956
1957
|
} = payload;
|
|
1957
1958
|
const kind = position2.kind;
|
|
1959
|
+
let reward_factor = _reward_factor;
|
|
1960
|
+
if (support) {
|
|
1961
|
+
const _result = getOptimumHedgeFactor({
|
|
1962
|
+
target_support: support,
|
|
1963
|
+
symbol_config,
|
|
1964
|
+
risk,
|
|
1965
|
+
position: position2
|
|
1966
|
+
});
|
|
1967
|
+
reward_factor = Number(_result.reward_factor);
|
|
1968
|
+
}
|
|
1958
1969
|
const take_profit = position2.tp?.price;
|
|
1959
1970
|
const tp_diff = Math.abs(take_profit - position2.entry);
|
|
1960
1971
|
const quantity = position2.quantity;
|
package/dist/index.cjs
CHANGED
|
@@ -54170,13 +54170,24 @@ function determineRewardFactor(payload) {
|
|
|
54170
54170
|
}
|
|
54171
54171
|
function getHedgeZone(payload) {
|
|
54172
54172
|
const {
|
|
54173
|
-
reward_factor,
|
|
54173
|
+
reward_factor: _reward_factor,
|
|
54174
54174
|
symbol_config,
|
|
54175
54175
|
risk,
|
|
54176
54176
|
position: position2,
|
|
54177
|
-
risk_factor = 1
|
|
54177
|
+
risk_factor = 1,
|
|
54178
|
+
support
|
|
54178
54179
|
} = payload;
|
|
54179
54180
|
const kind = position2.kind;
|
|
54181
|
+
let reward_factor = _reward_factor;
|
|
54182
|
+
if (support) {
|
|
54183
|
+
const _result = getOptimumHedgeFactor({
|
|
54184
|
+
target_support: support,
|
|
54185
|
+
symbol_config,
|
|
54186
|
+
risk,
|
|
54187
|
+
position: position2
|
|
54188
|
+
});
|
|
54189
|
+
reward_factor = Number(_result.reward_factor);
|
|
54190
|
+
}
|
|
54180
54191
|
const take_profit = position2.tp?.price;
|
|
54181
54192
|
const tp_diff = Math.abs(take_profit - position2.entry);
|
|
54182
54193
|
const quantity = position2.quantity;
|
|
@@ -58681,6 +58692,78 @@ class ExchangeAccount {
|
|
|
58681
58692
|
}
|
|
58682
58693
|
return 0;
|
|
58683
58694
|
}
|
|
58695
|
+
async updateGoodHedgeConfig(payload) {
|
|
58696
|
+
const {
|
|
58697
|
+
params,
|
|
58698
|
+
place,
|
|
58699
|
+
update_tp,
|
|
58700
|
+
symbol,
|
|
58701
|
+
risk_factor = 1,
|
|
58702
|
+
update = true
|
|
58703
|
+
} = payload;
|
|
58704
|
+
let _params = params;
|
|
58705
|
+
if (!params) {
|
|
58706
|
+
const result = await this.exchange.analyzeCandlesticks({ symbol });
|
|
58707
|
+
const support_price = Math.min(...Object.keys(result.support).map(Number));
|
|
58708
|
+
const symbol_config = await this.recomputeSymbolConfig({ symbol });
|
|
58709
|
+
const config2 = await this.getPositionConfig({
|
|
58710
|
+
symbol,
|
|
58711
|
+
kind: "long"
|
|
58712
|
+
});
|
|
58713
|
+
const position2 = await this.syncAccount({
|
|
58714
|
+
symbol,
|
|
58715
|
+
kind: "long",
|
|
58716
|
+
as_view: true
|
|
58717
|
+
});
|
|
58718
|
+
const bot_position = {
|
|
58719
|
+
kind: "long",
|
|
58720
|
+
entry: position2.entry,
|
|
58721
|
+
quantity: position2.quantity,
|
|
58722
|
+
tp: {
|
|
58723
|
+
price: position2.take_profit
|
|
58724
|
+
}
|
|
58725
|
+
};
|
|
58726
|
+
_params = getHedgeZone({
|
|
58727
|
+
symbol_config,
|
|
58728
|
+
risk: config2.risk,
|
|
58729
|
+
position: bot_position,
|
|
58730
|
+
support: support_price
|
|
58731
|
+
});
|
|
58732
|
+
}
|
|
58733
|
+
if (update) {
|
|
58734
|
+
await this.getPositionConfig({
|
|
58735
|
+
symbol,
|
|
58736
|
+
kind: "short",
|
|
58737
|
+
params: {
|
|
58738
|
+
entry: _params.support,
|
|
58739
|
+
stop: _params.resistance,
|
|
58740
|
+
risk: _params.risk * risk_factor
|
|
58741
|
+
}
|
|
58742
|
+
});
|
|
58743
|
+
}
|
|
58744
|
+
if (update_tp) {
|
|
58745
|
+
await this.getPositionConfig({
|
|
58746
|
+
symbol,
|
|
58747
|
+
kind: "long",
|
|
58748
|
+
params: {
|
|
58749
|
+
profit_percent: _params.profit_percent
|
|
58750
|
+
}
|
|
58751
|
+
});
|
|
58752
|
+
await this.updateTargetPnl({
|
|
58753
|
+
symbol,
|
|
58754
|
+
kind: "long"
|
|
58755
|
+
});
|
|
58756
|
+
}
|
|
58757
|
+
if (place) {
|
|
58758
|
+
await this.placeTrade({
|
|
58759
|
+
symbol,
|
|
58760
|
+
kind: "short",
|
|
58761
|
+
limit: true,
|
|
58762
|
+
ignore_config: true
|
|
58763
|
+
});
|
|
58764
|
+
}
|
|
58765
|
+
return _params;
|
|
58766
|
+
}
|
|
58684
58767
|
async placeOppositeTradeAction(payload) {
|
|
58685
58768
|
const { symbol, kind, data } = payload;
|
|
58686
58769
|
const position2 = await this.syncAccount({
|
|
@@ -59768,7 +59851,10 @@ function getExchangeKlass(exchange) {
|
|
|
59768
59851
|
const func = exchange === "binance" ? BinanceExchange : BybitExchange;
|
|
59769
59852
|
const clientFunc = exchange === "binance" ? initClient : initClient2;
|
|
59770
59853
|
return async (payload) => {
|
|
59771
|
-
const credentials = payload.getCredentials(
|
|
59854
|
+
const credentials = await payload.getCredentials({
|
|
59855
|
+
account: payload.account,
|
|
59856
|
+
exchange
|
|
59857
|
+
});
|
|
59772
59858
|
const client = await clientFunc(credentials, {
|
|
59773
59859
|
type: "future",
|
|
59774
59860
|
proxyAgent: payload.proxyAgent
|
|
@@ -59799,7 +59885,9 @@ async function getExchangeAccount(payload) {
|
|
|
59799
59885
|
const proxyAgent = proxyOptions?.ignore_proxy ? null : proxyOptions?.proxy || _proxyAgent;
|
|
59800
59886
|
const exchange_instance = await getExchangeKlass(account.exchange)({
|
|
59801
59887
|
account: account.owner,
|
|
59802
|
-
getCredentials:
|
|
59888
|
+
getCredentials: async (_payload) => {
|
|
59889
|
+
return await payload.getCredentials({ ..._payload, app_db });
|
|
59890
|
+
},
|
|
59803
59891
|
proxyAgent,
|
|
59804
59892
|
canWithdraw
|
|
59805
59893
|
});
|
|
@@ -59823,7 +59911,7 @@ class App {
|
|
|
59823
59911
|
return await getExchangeAccount({
|
|
59824
59912
|
account,
|
|
59825
59913
|
app_db: this.app_db,
|
|
59826
|
-
getCredentials: this.getCredentials,
|
|
59914
|
+
getCredentials: (p) => this.getCredentials({ ...p, app_db: this.app_db }),
|
|
59827
59915
|
proxyOptions: this.proxyOptions,
|
|
59828
59916
|
canWithdraw: this.proxyOptions?.canWithdraw
|
|
59829
59917
|
});
|
|
@@ -60141,7 +60229,8 @@ async function initApp(payload) {
|
|
|
60141
60229
|
password: payload.password
|
|
60142
60230
|
});
|
|
60143
60231
|
if (credentials) {
|
|
60144
|
-
_getCredentials = (
|
|
60232
|
+
_getCredentials = async (payload2) => {
|
|
60233
|
+
const { account, exchange } = payload2;
|
|
60145
60234
|
const credential = credentials.find((c) => c.name === account && c.exchange === exchange);
|
|
60146
60235
|
if (!credential) {
|
|
60147
60236
|
throw new Error(`Missing API Key or Secret for account '${account}' in .env file. Please check your environment variables.`);
|
|
@@ -60169,41 +60258,16 @@ async function initApp(payload) {
|
|
|
60169
60258
|
});
|
|
60170
60259
|
return app;
|
|
60171
60260
|
}
|
|
60172
|
-
function getCredentials(
|
|
60261
|
+
async function getCredentials(payload) {
|
|
60262
|
+
const { account, exchange, app_db } = payload;
|
|
60173
60263
|
console.log(`Fetching credentials for account: ${account}, exchange: ${exchange}`);
|
|
60174
|
-
|
|
60175
|
-
|
|
60176
|
-
|
|
60177
|
-
|
|
60178
|
-
apiKey = process.env.SUB_ACCOUNT_API_KEY;
|
|
60179
|
-
apiSecret = process.env.SUB_ACCOUNT_API_SECRET;
|
|
60180
|
-
break;
|
|
60181
|
-
case "tola_sub_account":
|
|
60182
|
-
apiKey = process.env.TOLA_SUB_ACCOUNT_API_KEY;
|
|
60183
|
-
apiSecret = process.env.TOLA_SUB_ACCOUNT_API_SECRET;
|
|
60184
|
-
break;
|
|
60185
|
-
case "gbozee1_sub_account":
|
|
60186
|
-
apiKey = process.env.GBOZEE1_SUB_ACCOUNT_API_KEY;
|
|
60187
|
-
apiSecret = process.env.GBOZEE1_SUB_ACCOUNT_API_SECRET;
|
|
60188
|
-
break;
|
|
60189
|
-
case "tomi_account":
|
|
60190
|
-
apiKey = process.env.TOMI_ACCOUNT_API_KEY;
|
|
60191
|
-
apiSecret = process.env.TOMI_ACCOUNT_API_SECRET;
|
|
60192
|
-
break;
|
|
60193
|
-
case "main_account":
|
|
60194
|
-
default:
|
|
60195
|
-
apiKey = process.env.MAIN_ACCOUNT_API_KEY;
|
|
60196
|
-
apiSecret = process.env.MAIN_ACCOUNT_API_SECRET;
|
|
60197
|
-
break;
|
|
60198
|
-
}
|
|
60199
|
-
if (!apiKey || !apiSecret) {
|
|
60264
|
+
const password = process.env.POCKETBASE_PASSWORD;
|
|
60265
|
+
const credentials = await app_db.getCredentials({ password });
|
|
60266
|
+
const result = credentials.find((c) => c.name === account && c.exchange === exchange);
|
|
60267
|
+
if (!result.api_key || !result.api_secret) {
|
|
60200
60268
|
throw new Error(`Missing API Key or Secret for account '${account}' in .env file. Please check your environment variables.`);
|
|
60201
60269
|
}
|
|
60202
|
-
return
|
|
60203
|
-
api_key: apiKey,
|
|
60204
|
-
api_secret: apiSecret,
|
|
60205
|
-
email: process.env.POCKETBASE_EMAIL
|
|
60206
|
-
};
|
|
60270
|
+
return result;
|
|
60207
60271
|
}
|
|
60208
60272
|
async function initialize(payload) {
|
|
60209
60273
|
const { password, proxy, ignore_proxy, canWithdraw } = payload;
|
package/dist/index.d.ts
CHANGED
|
@@ -1381,8 +1381,9 @@ export declare function getHedgeZone(payload: {
|
|
|
1381
1381
|
symbol_config: GlobalConfig;
|
|
1382
1382
|
risk: number;
|
|
1383
1383
|
position: BotPosition;
|
|
1384
|
-
reward_factor
|
|
1384
|
+
reward_factor?: number;
|
|
1385
1385
|
risk_factor?: number;
|
|
1386
|
+
support?: number;
|
|
1386
1387
|
}): {
|
|
1387
1388
|
support: number;
|
|
1388
1389
|
resistance: number;
|
|
@@ -1891,6 +1892,24 @@ declare class ExchangeAccount$1 {
|
|
|
1891
1892
|
symbol: string;
|
|
1892
1893
|
kind: "long" | "short";
|
|
1893
1894
|
}): Promise<number>;
|
|
1895
|
+
updateGoodHedgeConfig(payload: {
|
|
1896
|
+
symbol: string;
|
|
1897
|
+
params?: {
|
|
1898
|
+
support: number;
|
|
1899
|
+
resistance: number;
|
|
1900
|
+
risk: number;
|
|
1901
|
+
profit_percent: number;
|
|
1902
|
+
};
|
|
1903
|
+
risk_factor?: number;
|
|
1904
|
+
update?: boolean;
|
|
1905
|
+
place?: boolean;
|
|
1906
|
+
update_tp?: boolean;
|
|
1907
|
+
}): Promise<{
|
|
1908
|
+
support: number;
|
|
1909
|
+
resistance: number;
|
|
1910
|
+
risk: number;
|
|
1911
|
+
profit_percent: number;
|
|
1912
|
+
}>;
|
|
1894
1913
|
/**
|
|
1895
1914
|
* This method is used to place the opposite trade action
|
|
1896
1915
|
*/
|
|
@@ -2232,11 +2251,15 @@ declare class ExchangeAccount$1 {
|
|
|
2232
2251
|
declare function getExchangeAccount(payload: {
|
|
2233
2252
|
account: ExchangeType;
|
|
2234
2253
|
app_db: AppDatabase;
|
|
2235
|
-
getCredentials: (
|
|
2254
|
+
getCredentials: (payload: {
|
|
2255
|
+
account: string;
|
|
2256
|
+
exchange: string;
|
|
2257
|
+
app_db: AppDatabase;
|
|
2258
|
+
}) => Promise<{
|
|
2236
2259
|
api_key: string;
|
|
2237
2260
|
api_secret: string;
|
|
2238
2261
|
email: string;
|
|
2239
|
-
}
|
|
2262
|
+
}>;
|
|
2240
2263
|
proxyOptions?: {
|
|
2241
2264
|
proxy?: any;
|
|
2242
2265
|
ignore_proxy?: boolean;
|
|
@@ -2251,11 +2274,14 @@ declare class App {
|
|
|
2251
2274
|
canWithdraw?: boolean;
|
|
2252
2275
|
};
|
|
2253
2276
|
private getCredentials;
|
|
2254
|
-
constructor(app_db: AppDatabase, getCredentials: (
|
|
2277
|
+
constructor(app_db: AppDatabase, getCredentials: (payload: {
|
|
2278
|
+
account: string;
|
|
2279
|
+
exchange: string;
|
|
2280
|
+
}) => Promise<{
|
|
2255
2281
|
api_key: string;
|
|
2256
2282
|
api_secret: string;
|
|
2257
2283
|
email: string;
|
|
2258
|
-
}
|
|
2284
|
+
}>, proxyOptions?: {
|
|
2259
2285
|
proxy?: any;
|
|
2260
2286
|
ignore_proxy?: boolean;
|
|
2261
2287
|
canWithdraw?: boolean;
|
|
@@ -2472,21 +2498,25 @@ export declare function initApp(payload: {
|
|
|
2472
2498
|
password?: string;
|
|
2473
2499
|
salt?: string;
|
|
2474
2500
|
email?: string;
|
|
2475
|
-
getCredentials: (
|
|
2501
|
+
getCredentials: (payload: {
|
|
2502
|
+
account: string;
|
|
2503
|
+
exchange: string;
|
|
2504
|
+
app_db: AppDatabase;
|
|
2505
|
+
}) => Promise<{
|
|
2476
2506
|
api_key: string;
|
|
2477
2507
|
api_secret: string;
|
|
2478
2508
|
email: string;
|
|
2479
|
-
}
|
|
2509
|
+
}>;
|
|
2480
2510
|
proxy?: any;
|
|
2481
2511
|
ignore_proxy?: boolean;
|
|
2482
2512
|
canWithdraw?: boolean;
|
|
2483
2513
|
triggerToken?: string;
|
|
2484
2514
|
}): Promise<App>;
|
|
2485
|
-
declare function getCredentials(
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
}
|
|
2515
|
+
declare function getCredentials(payload: {
|
|
2516
|
+
account: string;
|
|
2517
|
+
exchange: string;
|
|
2518
|
+
app_db: AppDatabase;
|
|
2519
|
+
}): Promise<any>;
|
|
2490
2520
|
export declare function initialize(payload: {
|
|
2491
2521
|
password?: string;
|
|
2492
2522
|
proxy?: any;
|
package/dist/index.js
CHANGED
|
@@ -54120,13 +54120,24 @@ function determineRewardFactor(payload) {
|
|
|
54120
54120
|
}
|
|
54121
54121
|
function getHedgeZone(payload) {
|
|
54122
54122
|
const {
|
|
54123
|
-
reward_factor,
|
|
54123
|
+
reward_factor: _reward_factor,
|
|
54124
54124
|
symbol_config,
|
|
54125
54125
|
risk,
|
|
54126
54126
|
position: position2,
|
|
54127
|
-
risk_factor = 1
|
|
54127
|
+
risk_factor = 1,
|
|
54128
|
+
support
|
|
54128
54129
|
} = payload;
|
|
54129
54130
|
const kind = position2.kind;
|
|
54131
|
+
let reward_factor = _reward_factor;
|
|
54132
|
+
if (support) {
|
|
54133
|
+
const _result = getOptimumHedgeFactor({
|
|
54134
|
+
target_support: support,
|
|
54135
|
+
symbol_config,
|
|
54136
|
+
risk,
|
|
54137
|
+
position: position2
|
|
54138
|
+
});
|
|
54139
|
+
reward_factor = Number(_result.reward_factor);
|
|
54140
|
+
}
|
|
54130
54141
|
const take_profit = position2.tp?.price;
|
|
54131
54142
|
const tp_diff = Math.abs(take_profit - position2.entry);
|
|
54132
54143
|
const quantity = position2.quantity;
|
|
@@ -58631,6 +58642,78 @@ class ExchangeAccount {
|
|
|
58631
58642
|
}
|
|
58632
58643
|
return 0;
|
|
58633
58644
|
}
|
|
58645
|
+
async updateGoodHedgeConfig(payload) {
|
|
58646
|
+
const {
|
|
58647
|
+
params,
|
|
58648
|
+
place,
|
|
58649
|
+
update_tp,
|
|
58650
|
+
symbol,
|
|
58651
|
+
risk_factor = 1,
|
|
58652
|
+
update = true
|
|
58653
|
+
} = payload;
|
|
58654
|
+
let _params = params;
|
|
58655
|
+
if (!params) {
|
|
58656
|
+
const result = await this.exchange.analyzeCandlesticks({ symbol });
|
|
58657
|
+
const support_price = Math.min(...Object.keys(result.support).map(Number));
|
|
58658
|
+
const symbol_config = await this.recomputeSymbolConfig({ symbol });
|
|
58659
|
+
const config2 = await this.getPositionConfig({
|
|
58660
|
+
symbol,
|
|
58661
|
+
kind: "long"
|
|
58662
|
+
});
|
|
58663
|
+
const position2 = await this.syncAccount({
|
|
58664
|
+
symbol,
|
|
58665
|
+
kind: "long",
|
|
58666
|
+
as_view: true
|
|
58667
|
+
});
|
|
58668
|
+
const bot_position = {
|
|
58669
|
+
kind: "long",
|
|
58670
|
+
entry: position2.entry,
|
|
58671
|
+
quantity: position2.quantity,
|
|
58672
|
+
tp: {
|
|
58673
|
+
price: position2.take_profit
|
|
58674
|
+
}
|
|
58675
|
+
};
|
|
58676
|
+
_params = getHedgeZone({
|
|
58677
|
+
symbol_config,
|
|
58678
|
+
risk: config2.risk,
|
|
58679
|
+
position: bot_position,
|
|
58680
|
+
support: support_price
|
|
58681
|
+
});
|
|
58682
|
+
}
|
|
58683
|
+
if (update) {
|
|
58684
|
+
await this.getPositionConfig({
|
|
58685
|
+
symbol,
|
|
58686
|
+
kind: "short",
|
|
58687
|
+
params: {
|
|
58688
|
+
entry: _params.support,
|
|
58689
|
+
stop: _params.resistance,
|
|
58690
|
+
risk: _params.risk * risk_factor
|
|
58691
|
+
}
|
|
58692
|
+
});
|
|
58693
|
+
}
|
|
58694
|
+
if (update_tp) {
|
|
58695
|
+
await this.getPositionConfig({
|
|
58696
|
+
symbol,
|
|
58697
|
+
kind: "long",
|
|
58698
|
+
params: {
|
|
58699
|
+
profit_percent: _params.profit_percent
|
|
58700
|
+
}
|
|
58701
|
+
});
|
|
58702
|
+
await this.updateTargetPnl({
|
|
58703
|
+
symbol,
|
|
58704
|
+
kind: "long"
|
|
58705
|
+
});
|
|
58706
|
+
}
|
|
58707
|
+
if (place) {
|
|
58708
|
+
await this.placeTrade({
|
|
58709
|
+
symbol,
|
|
58710
|
+
kind: "short",
|
|
58711
|
+
limit: true,
|
|
58712
|
+
ignore_config: true
|
|
58713
|
+
});
|
|
58714
|
+
}
|
|
58715
|
+
return _params;
|
|
58716
|
+
}
|
|
58634
58717
|
async placeOppositeTradeAction(payload) {
|
|
58635
58718
|
const { symbol, kind, data } = payload;
|
|
58636
58719
|
const position2 = await this.syncAccount({
|
|
@@ -59718,7 +59801,10 @@ function getExchangeKlass(exchange) {
|
|
|
59718
59801
|
const func = exchange === "binance" ? BinanceExchange : BybitExchange;
|
|
59719
59802
|
const clientFunc = exchange === "binance" ? initClient : initClient2;
|
|
59720
59803
|
return async (payload) => {
|
|
59721
|
-
const credentials = payload.getCredentials(
|
|
59804
|
+
const credentials = await payload.getCredentials({
|
|
59805
|
+
account: payload.account,
|
|
59806
|
+
exchange
|
|
59807
|
+
});
|
|
59722
59808
|
const client = await clientFunc(credentials, {
|
|
59723
59809
|
type: "future",
|
|
59724
59810
|
proxyAgent: payload.proxyAgent
|
|
@@ -59749,7 +59835,9 @@ async function getExchangeAccount(payload) {
|
|
|
59749
59835
|
const proxyAgent = proxyOptions?.ignore_proxy ? null : proxyOptions?.proxy || _proxyAgent;
|
|
59750
59836
|
const exchange_instance = await getExchangeKlass(account.exchange)({
|
|
59751
59837
|
account: account.owner,
|
|
59752
|
-
getCredentials:
|
|
59838
|
+
getCredentials: async (_payload) => {
|
|
59839
|
+
return await payload.getCredentials({ ..._payload, app_db });
|
|
59840
|
+
},
|
|
59753
59841
|
proxyAgent,
|
|
59754
59842
|
canWithdraw
|
|
59755
59843
|
});
|
|
@@ -59773,7 +59861,7 @@ class App {
|
|
|
59773
59861
|
return await getExchangeAccount({
|
|
59774
59862
|
account,
|
|
59775
59863
|
app_db: this.app_db,
|
|
59776
|
-
getCredentials: this.getCredentials,
|
|
59864
|
+
getCredentials: (p) => this.getCredentials({ ...p, app_db: this.app_db }),
|
|
59777
59865
|
proxyOptions: this.proxyOptions,
|
|
59778
59866
|
canWithdraw: this.proxyOptions?.canWithdraw
|
|
59779
59867
|
});
|
|
@@ -60091,7 +60179,8 @@ async function initApp(payload) {
|
|
|
60091
60179
|
password: payload.password
|
|
60092
60180
|
});
|
|
60093
60181
|
if (credentials) {
|
|
60094
|
-
_getCredentials = (
|
|
60182
|
+
_getCredentials = async (payload2) => {
|
|
60183
|
+
const { account, exchange } = payload2;
|
|
60095
60184
|
const credential = credentials.find((c) => c.name === account && c.exchange === exchange);
|
|
60096
60185
|
if (!credential) {
|
|
60097
60186
|
throw new Error(`Missing API Key or Secret for account '${account}' in .env file. Please check your environment variables.`);
|
|
@@ -60119,41 +60208,16 @@ async function initApp(payload) {
|
|
|
60119
60208
|
});
|
|
60120
60209
|
return app;
|
|
60121
60210
|
}
|
|
60122
|
-
function getCredentials(
|
|
60211
|
+
async function getCredentials(payload) {
|
|
60212
|
+
const { account, exchange, app_db } = payload;
|
|
60123
60213
|
console.log(`Fetching credentials for account: ${account}, exchange: ${exchange}`);
|
|
60124
|
-
|
|
60125
|
-
|
|
60126
|
-
|
|
60127
|
-
|
|
60128
|
-
apiKey = process.env.SUB_ACCOUNT_API_KEY;
|
|
60129
|
-
apiSecret = process.env.SUB_ACCOUNT_API_SECRET;
|
|
60130
|
-
break;
|
|
60131
|
-
case "tola_sub_account":
|
|
60132
|
-
apiKey = process.env.TOLA_SUB_ACCOUNT_API_KEY;
|
|
60133
|
-
apiSecret = process.env.TOLA_SUB_ACCOUNT_API_SECRET;
|
|
60134
|
-
break;
|
|
60135
|
-
case "gbozee1_sub_account":
|
|
60136
|
-
apiKey = process.env.GBOZEE1_SUB_ACCOUNT_API_KEY;
|
|
60137
|
-
apiSecret = process.env.GBOZEE1_SUB_ACCOUNT_API_SECRET;
|
|
60138
|
-
break;
|
|
60139
|
-
case "tomi_account":
|
|
60140
|
-
apiKey = process.env.TOMI_ACCOUNT_API_KEY;
|
|
60141
|
-
apiSecret = process.env.TOMI_ACCOUNT_API_SECRET;
|
|
60142
|
-
break;
|
|
60143
|
-
case "main_account":
|
|
60144
|
-
default:
|
|
60145
|
-
apiKey = process.env.MAIN_ACCOUNT_API_KEY;
|
|
60146
|
-
apiSecret = process.env.MAIN_ACCOUNT_API_SECRET;
|
|
60147
|
-
break;
|
|
60148
|
-
}
|
|
60149
|
-
if (!apiKey || !apiSecret) {
|
|
60214
|
+
const password = process.env.POCKETBASE_PASSWORD;
|
|
60215
|
+
const credentials = await app_db.getCredentials({ password });
|
|
60216
|
+
const result = credentials.find((c) => c.name === account && c.exchange === exchange);
|
|
60217
|
+
if (!result.api_key || !result.api_secret) {
|
|
60150
60218
|
throw new Error(`Missing API Key or Secret for account '${account}' in .env file. Please check your environment variables.`);
|
|
60151
60219
|
}
|
|
60152
|
-
return
|
|
60153
|
-
api_key: apiKey,
|
|
60154
|
-
api_secret: apiSecret,
|
|
60155
|
-
email: process.env.POCKETBASE_EMAIL
|
|
60156
|
-
};
|
|
60220
|
+
return result;
|
|
60157
60221
|
}
|
|
60158
60222
|
async function initialize(payload) {
|
|
60159
60223
|
const { password, proxy, ignore_proxy, canWithdraw } = payload;
|
package/dist/mcp-server.cjs
CHANGED
|
@@ -60848,6 +60848,108 @@ function calculate_factor(payload) {
|
|
|
60848
60848
|
calculated_factor = to_f2(calculated_factor, places);
|
|
60849
60849
|
return calculated_factor;
|
|
60850
60850
|
}
|
|
60851
|
+
function getHedgeZone(payload) {
|
|
60852
|
+
const {
|
|
60853
|
+
reward_factor: _reward_factor,
|
|
60854
|
+
symbol_config,
|
|
60855
|
+
risk,
|
|
60856
|
+
position: position2,
|
|
60857
|
+
risk_factor = 1,
|
|
60858
|
+
support
|
|
60859
|
+
} = payload;
|
|
60860
|
+
const kind = position2.kind;
|
|
60861
|
+
let reward_factor = _reward_factor;
|
|
60862
|
+
if (support) {
|
|
60863
|
+
const _result = getOptimumHedgeFactor({
|
|
60864
|
+
target_support: support,
|
|
60865
|
+
symbol_config,
|
|
60866
|
+
risk,
|
|
60867
|
+
position: position2
|
|
60868
|
+
});
|
|
60869
|
+
reward_factor = Number(_result.reward_factor);
|
|
60870
|
+
}
|
|
60871
|
+
const take_profit = position2.tp?.price;
|
|
60872
|
+
const tp_diff = Math.abs(take_profit - position2.entry);
|
|
60873
|
+
const quantity = position2.quantity;
|
|
60874
|
+
const diff = risk / quantity;
|
|
60875
|
+
let new_take_profit = kind === "long" ? to_f2(position2.entry + diff, symbol_config.price_places) : to_f2(position2.entry - diff, symbol_config.price_places);
|
|
60876
|
+
let base_factor = to_f2(Math.max(tp_diff, diff) / (Math.min(tp_diff, diff) || 1), "%.3f");
|
|
60877
|
+
let factor = reward_factor || base_factor;
|
|
60878
|
+
const new_risk = risk * factor * risk_factor;
|
|
60879
|
+
const stop_loss_diff = new_risk / quantity;
|
|
60880
|
+
new_take_profit = kind === "long" ? to_f2(position2.entry + stop_loss_diff, symbol_config.price_places) : to_f2(position2.entry - stop_loss_diff, symbol_config.price_places);
|
|
60881
|
+
const stop_loss = kind === "long" ? to_f2(position2.entry - stop_loss_diff, symbol_config.price_places) : to_f2(position2.entry + stop_loss_diff, symbol_config.price_places);
|
|
60882
|
+
const profit_percent = new_risk * 100 / (position2.entry * position2.quantity);
|
|
60883
|
+
return {
|
|
60884
|
+
support: Math.min(new_take_profit, stop_loss),
|
|
60885
|
+
resistance: Math.max(new_take_profit, stop_loss),
|
|
60886
|
+
risk: to_f2(new_risk, "%.2f"),
|
|
60887
|
+
profit_percent: to_f2(profit_percent, "%.2f")
|
|
60888
|
+
};
|
|
60889
|
+
}
|
|
60890
|
+
function getOptimumHedgeFactor(payload) {
|
|
60891
|
+
const {
|
|
60892
|
+
target_support,
|
|
60893
|
+
max_iterations = 50,
|
|
60894
|
+
min_factor = 0.1,
|
|
60895
|
+
max_factor = 20,
|
|
60896
|
+
symbol_config,
|
|
60897
|
+
risk,
|
|
60898
|
+
position: position2
|
|
60899
|
+
} = payload;
|
|
60900
|
+
const current_price = position2.entry;
|
|
60901
|
+
const tolerance = current_price > 100 ? 0.5 : current_price > 1 ? 0.01 : 0.001;
|
|
60902
|
+
let low = min_factor;
|
|
60903
|
+
let high = max_factor;
|
|
60904
|
+
let best_factor = low;
|
|
60905
|
+
let best_diff = Infinity;
|
|
60906
|
+
for (let iteration = 0;iteration < max_iterations; iteration++) {
|
|
60907
|
+
const mid_factor = (low + high) / 2;
|
|
60908
|
+
const hedge_zone = getHedgeZone({
|
|
60909
|
+
reward_factor: mid_factor,
|
|
60910
|
+
symbol_config,
|
|
60911
|
+
risk,
|
|
60912
|
+
position: position2
|
|
60913
|
+
});
|
|
60914
|
+
const current_support = hedge_zone.support;
|
|
60915
|
+
const diff = Math.abs(current_support - target_support);
|
|
60916
|
+
if (diff < best_diff) {
|
|
60917
|
+
best_diff = diff;
|
|
60918
|
+
best_factor = mid_factor;
|
|
60919
|
+
}
|
|
60920
|
+
if (diff <= tolerance) {
|
|
60921
|
+
return {
|
|
60922
|
+
reward_factor: to_f2(mid_factor, "%.4f"),
|
|
60923
|
+
achieved_support: to_f2(current_support, symbol_config.price_places),
|
|
60924
|
+
target_support: to_f2(target_support, symbol_config.price_places),
|
|
60925
|
+
difference: to_f2(diff, symbol_config.price_places),
|
|
60926
|
+
iterations: iteration + 1
|
|
60927
|
+
};
|
|
60928
|
+
}
|
|
60929
|
+
if (current_support > target_support) {
|
|
60930
|
+
low = mid_factor;
|
|
60931
|
+
} else {
|
|
60932
|
+
high = mid_factor;
|
|
60933
|
+
}
|
|
60934
|
+
if (Math.abs(high - low) < 0.0001) {
|
|
60935
|
+
break;
|
|
60936
|
+
}
|
|
60937
|
+
}
|
|
60938
|
+
const final_hedge_zone = getHedgeZone({
|
|
60939
|
+
symbol_config,
|
|
60940
|
+
risk,
|
|
60941
|
+
position: position2,
|
|
60942
|
+
reward_factor: best_factor
|
|
60943
|
+
});
|
|
60944
|
+
return {
|
|
60945
|
+
reward_factor: to_f2(best_factor, "%.4f"),
|
|
60946
|
+
achieved_support: to_f2(final_hedge_zone.support, symbol_config.price_places),
|
|
60947
|
+
target_support: to_f2(target_support, symbol_config.price_places),
|
|
60948
|
+
difference: to_f2(best_diff, symbol_config.price_places),
|
|
60949
|
+
iterations: max_iterations,
|
|
60950
|
+
converged: best_diff <= tolerance
|
|
60951
|
+
};
|
|
60952
|
+
}
|
|
60851
60953
|
|
|
60852
60954
|
// src/helpers/strategy.ts
|
|
60853
60955
|
class Strategy {
|
|
@@ -65270,6 +65372,78 @@ class ExchangeAccount {
|
|
|
65270
65372
|
}
|
|
65271
65373
|
return 0;
|
|
65272
65374
|
}
|
|
65375
|
+
async updateGoodHedgeConfig(payload) {
|
|
65376
|
+
const {
|
|
65377
|
+
params,
|
|
65378
|
+
place,
|
|
65379
|
+
update_tp,
|
|
65380
|
+
symbol,
|
|
65381
|
+
risk_factor = 1,
|
|
65382
|
+
update = true
|
|
65383
|
+
} = payload;
|
|
65384
|
+
let _params = params;
|
|
65385
|
+
if (!params) {
|
|
65386
|
+
const result = await this.exchange.analyzeCandlesticks({ symbol });
|
|
65387
|
+
const support_price = Math.min(...Object.keys(result.support).map(Number));
|
|
65388
|
+
const symbol_config = await this.recomputeSymbolConfig({ symbol });
|
|
65389
|
+
const config2 = await this.getPositionConfig({
|
|
65390
|
+
symbol,
|
|
65391
|
+
kind: "long"
|
|
65392
|
+
});
|
|
65393
|
+
const position2 = await this.syncAccount({
|
|
65394
|
+
symbol,
|
|
65395
|
+
kind: "long",
|
|
65396
|
+
as_view: true
|
|
65397
|
+
});
|
|
65398
|
+
const bot_position = {
|
|
65399
|
+
kind: "long",
|
|
65400
|
+
entry: position2.entry,
|
|
65401
|
+
quantity: position2.quantity,
|
|
65402
|
+
tp: {
|
|
65403
|
+
price: position2.take_profit
|
|
65404
|
+
}
|
|
65405
|
+
};
|
|
65406
|
+
_params = getHedgeZone({
|
|
65407
|
+
symbol_config,
|
|
65408
|
+
risk: config2.risk,
|
|
65409
|
+
position: bot_position,
|
|
65410
|
+
support: support_price
|
|
65411
|
+
});
|
|
65412
|
+
}
|
|
65413
|
+
if (update) {
|
|
65414
|
+
await this.getPositionConfig({
|
|
65415
|
+
symbol,
|
|
65416
|
+
kind: "short",
|
|
65417
|
+
params: {
|
|
65418
|
+
entry: _params.support,
|
|
65419
|
+
stop: _params.resistance,
|
|
65420
|
+
risk: _params.risk * risk_factor
|
|
65421
|
+
}
|
|
65422
|
+
});
|
|
65423
|
+
}
|
|
65424
|
+
if (update_tp) {
|
|
65425
|
+
await this.getPositionConfig({
|
|
65426
|
+
symbol,
|
|
65427
|
+
kind: "long",
|
|
65428
|
+
params: {
|
|
65429
|
+
profit_percent: _params.profit_percent
|
|
65430
|
+
}
|
|
65431
|
+
});
|
|
65432
|
+
await this.updateTargetPnl({
|
|
65433
|
+
symbol,
|
|
65434
|
+
kind: "long"
|
|
65435
|
+
});
|
|
65436
|
+
}
|
|
65437
|
+
if (place) {
|
|
65438
|
+
await this.placeTrade({
|
|
65439
|
+
symbol,
|
|
65440
|
+
kind: "short",
|
|
65441
|
+
limit: true,
|
|
65442
|
+
ignore_config: true
|
|
65443
|
+
});
|
|
65444
|
+
}
|
|
65445
|
+
return _params;
|
|
65446
|
+
}
|
|
65273
65447
|
async placeOppositeTradeAction(payload) {
|
|
65274
65448
|
const { symbol, kind, data } = payload;
|
|
65275
65449
|
const position2 = await this.syncAccount({
|
|
@@ -66357,7 +66531,10 @@ function getExchangeKlass(exchange) {
|
|
|
66357
66531
|
const func = exchange === "binance" ? BinanceExchange : BybitExchange;
|
|
66358
66532
|
const clientFunc = exchange === "binance" ? initClient : initClient2;
|
|
66359
66533
|
return async (payload) => {
|
|
66360
|
-
const credentials = payload.getCredentials(
|
|
66534
|
+
const credentials = await payload.getCredentials({
|
|
66535
|
+
account: payload.account,
|
|
66536
|
+
exchange
|
|
66537
|
+
});
|
|
66361
66538
|
const client = await clientFunc(credentials, {
|
|
66362
66539
|
type: "future",
|
|
66363
66540
|
proxyAgent: payload.proxyAgent
|
|
@@ -66388,7 +66565,9 @@ async function getExchangeAccount(payload) {
|
|
|
66388
66565
|
const proxyAgent = proxyOptions?.ignore_proxy ? null : proxyOptions?.proxy || _proxyAgent;
|
|
66389
66566
|
const exchange_instance = await getExchangeKlass(account.exchange)({
|
|
66390
66567
|
account: account.owner,
|
|
66391
|
-
getCredentials:
|
|
66568
|
+
getCredentials: async (_payload) => {
|
|
66569
|
+
return await payload.getCredentials({ ..._payload, app_db });
|
|
66570
|
+
},
|
|
66392
66571
|
proxyAgent,
|
|
66393
66572
|
canWithdraw
|
|
66394
66573
|
});
|
|
@@ -66412,7 +66591,7 @@ class App {
|
|
|
66412
66591
|
return await getExchangeAccount({
|
|
66413
66592
|
account,
|
|
66414
66593
|
app_db: this.app_db,
|
|
66415
|
-
getCredentials: this.getCredentials,
|
|
66594
|
+
getCredentials: (p) => this.getCredentials({ ...p, app_db: this.app_db }),
|
|
66416
66595
|
proxyOptions: this.proxyOptions,
|
|
66417
66596
|
canWithdraw: this.proxyOptions?.canWithdraw
|
|
66418
66597
|
});
|
|
@@ -66730,7 +66909,8 @@ async function initApp(payload) {
|
|
|
66730
66909
|
password: payload.password
|
|
66731
66910
|
});
|
|
66732
66911
|
if (credentials) {
|
|
66733
|
-
_getCredentials = (
|
|
66912
|
+
_getCredentials = async (payload2) => {
|
|
66913
|
+
const { account, exchange } = payload2;
|
|
66734
66914
|
const credential = credentials.find((c) => c.name === account && c.exchange === exchange);
|
|
66735
66915
|
if (!credential) {
|
|
66736
66916
|
throw new Error(`Missing API Key or Secret for account '${account}' in .env file. Please check your environment variables.`);
|
|
@@ -66768,11 +66948,19 @@ async function getApp() {
|
|
|
66768
66948
|
password: process.env.POCKETBASE_PASSWORD
|
|
66769
66949
|
},
|
|
66770
66950
|
password: process.env.POCKETBASE_PASSWORD,
|
|
66771
|
-
getCredentials: (
|
|
66951
|
+
getCredentials: async (payload) => {
|
|
66952
|
+
const { account, exchange, app_db } = payload;
|
|
66953
|
+
const credentials = await app_db.getCredentials({
|
|
66954
|
+
password: process.env.POCKETBASE_PASSWORD
|
|
66955
|
+
});
|
|
66956
|
+
const credential = credentials.find((c) => c.name === account && c.exchange === exchange);
|
|
66957
|
+
if (!credential) {
|
|
66958
|
+
throw new Error(`Missing API Key or Secret for account '${account}' in .env file. Please check your environment variables.`);
|
|
66959
|
+
}
|
|
66772
66960
|
return {
|
|
66773
|
-
api_key:
|
|
66774
|
-
api_secret:
|
|
66775
|
-
email:
|
|
66961
|
+
api_key: credential.api_key,
|
|
66962
|
+
api_secret: credential.api_secret,
|
|
66963
|
+
email: credential.email
|
|
66776
66964
|
};
|
|
66777
66965
|
}
|
|
66778
66966
|
});
|
package/dist/mcp-server.js
CHANGED
|
@@ -60825,6 +60825,108 @@ function calculate_factor(payload) {
|
|
|
60825
60825
|
calculated_factor = to_f2(calculated_factor, places);
|
|
60826
60826
|
return calculated_factor;
|
|
60827
60827
|
}
|
|
60828
|
+
function getHedgeZone(payload) {
|
|
60829
|
+
const {
|
|
60830
|
+
reward_factor: _reward_factor,
|
|
60831
|
+
symbol_config,
|
|
60832
|
+
risk,
|
|
60833
|
+
position: position2,
|
|
60834
|
+
risk_factor = 1,
|
|
60835
|
+
support
|
|
60836
|
+
} = payload;
|
|
60837
|
+
const kind = position2.kind;
|
|
60838
|
+
let reward_factor = _reward_factor;
|
|
60839
|
+
if (support) {
|
|
60840
|
+
const _result = getOptimumHedgeFactor({
|
|
60841
|
+
target_support: support,
|
|
60842
|
+
symbol_config,
|
|
60843
|
+
risk,
|
|
60844
|
+
position: position2
|
|
60845
|
+
});
|
|
60846
|
+
reward_factor = Number(_result.reward_factor);
|
|
60847
|
+
}
|
|
60848
|
+
const take_profit = position2.tp?.price;
|
|
60849
|
+
const tp_diff = Math.abs(take_profit - position2.entry);
|
|
60850
|
+
const quantity = position2.quantity;
|
|
60851
|
+
const diff = risk / quantity;
|
|
60852
|
+
let new_take_profit = kind === "long" ? to_f2(position2.entry + diff, symbol_config.price_places) : to_f2(position2.entry - diff, symbol_config.price_places);
|
|
60853
|
+
let base_factor = to_f2(Math.max(tp_diff, diff) / (Math.min(tp_diff, diff) || 1), "%.3f");
|
|
60854
|
+
let factor = reward_factor || base_factor;
|
|
60855
|
+
const new_risk = risk * factor * risk_factor;
|
|
60856
|
+
const stop_loss_diff = new_risk / quantity;
|
|
60857
|
+
new_take_profit = kind === "long" ? to_f2(position2.entry + stop_loss_diff, symbol_config.price_places) : to_f2(position2.entry - stop_loss_diff, symbol_config.price_places);
|
|
60858
|
+
const stop_loss = kind === "long" ? to_f2(position2.entry - stop_loss_diff, symbol_config.price_places) : to_f2(position2.entry + stop_loss_diff, symbol_config.price_places);
|
|
60859
|
+
const profit_percent = new_risk * 100 / (position2.entry * position2.quantity);
|
|
60860
|
+
return {
|
|
60861
|
+
support: Math.min(new_take_profit, stop_loss),
|
|
60862
|
+
resistance: Math.max(new_take_profit, stop_loss),
|
|
60863
|
+
risk: to_f2(new_risk, "%.2f"),
|
|
60864
|
+
profit_percent: to_f2(profit_percent, "%.2f")
|
|
60865
|
+
};
|
|
60866
|
+
}
|
|
60867
|
+
function getOptimumHedgeFactor(payload) {
|
|
60868
|
+
const {
|
|
60869
|
+
target_support,
|
|
60870
|
+
max_iterations = 50,
|
|
60871
|
+
min_factor = 0.1,
|
|
60872
|
+
max_factor = 20,
|
|
60873
|
+
symbol_config,
|
|
60874
|
+
risk,
|
|
60875
|
+
position: position2
|
|
60876
|
+
} = payload;
|
|
60877
|
+
const current_price = position2.entry;
|
|
60878
|
+
const tolerance = current_price > 100 ? 0.5 : current_price > 1 ? 0.01 : 0.001;
|
|
60879
|
+
let low = min_factor;
|
|
60880
|
+
let high = max_factor;
|
|
60881
|
+
let best_factor = low;
|
|
60882
|
+
let best_diff = Infinity;
|
|
60883
|
+
for (let iteration = 0;iteration < max_iterations; iteration++) {
|
|
60884
|
+
const mid_factor = (low + high) / 2;
|
|
60885
|
+
const hedge_zone = getHedgeZone({
|
|
60886
|
+
reward_factor: mid_factor,
|
|
60887
|
+
symbol_config,
|
|
60888
|
+
risk,
|
|
60889
|
+
position: position2
|
|
60890
|
+
});
|
|
60891
|
+
const current_support = hedge_zone.support;
|
|
60892
|
+
const diff = Math.abs(current_support - target_support);
|
|
60893
|
+
if (diff < best_diff) {
|
|
60894
|
+
best_diff = diff;
|
|
60895
|
+
best_factor = mid_factor;
|
|
60896
|
+
}
|
|
60897
|
+
if (diff <= tolerance) {
|
|
60898
|
+
return {
|
|
60899
|
+
reward_factor: to_f2(mid_factor, "%.4f"),
|
|
60900
|
+
achieved_support: to_f2(current_support, symbol_config.price_places),
|
|
60901
|
+
target_support: to_f2(target_support, symbol_config.price_places),
|
|
60902
|
+
difference: to_f2(diff, symbol_config.price_places),
|
|
60903
|
+
iterations: iteration + 1
|
|
60904
|
+
};
|
|
60905
|
+
}
|
|
60906
|
+
if (current_support > target_support) {
|
|
60907
|
+
low = mid_factor;
|
|
60908
|
+
} else {
|
|
60909
|
+
high = mid_factor;
|
|
60910
|
+
}
|
|
60911
|
+
if (Math.abs(high - low) < 0.0001) {
|
|
60912
|
+
break;
|
|
60913
|
+
}
|
|
60914
|
+
}
|
|
60915
|
+
const final_hedge_zone = getHedgeZone({
|
|
60916
|
+
symbol_config,
|
|
60917
|
+
risk,
|
|
60918
|
+
position: position2,
|
|
60919
|
+
reward_factor: best_factor
|
|
60920
|
+
});
|
|
60921
|
+
return {
|
|
60922
|
+
reward_factor: to_f2(best_factor, "%.4f"),
|
|
60923
|
+
achieved_support: to_f2(final_hedge_zone.support, symbol_config.price_places),
|
|
60924
|
+
target_support: to_f2(target_support, symbol_config.price_places),
|
|
60925
|
+
difference: to_f2(best_diff, symbol_config.price_places),
|
|
60926
|
+
iterations: max_iterations,
|
|
60927
|
+
converged: best_diff <= tolerance
|
|
60928
|
+
};
|
|
60929
|
+
}
|
|
60828
60930
|
|
|
60829
60931
|
// src/helpers/strategy.ts
|
|
60830
60932
|
class Strategy {
|
|
@@ -65247,6 +65349,78 @@ class ExchangeAccount {
|
|
|
65247
65349
|
}
|
|
65248
65350
|
return 0;
|
|
65249
65351
|
}
|
|
65352
|
+
async updateGoodHedgeConfig(payload) {
|
|
65353
|
+
const {
|
|
65354
|
+
params,
|
|
65355
|
+
place,
|
|
65356
|
+
update_tp,
|
|
65357
|
+
symbol,
|
|
65358
|
+
risk_factor = 1,
|
|
65359
|
+
update = true
|
|
65360
|
+
} = payload;
|
|
65361
|
+
let _params = params;
|
|
65362
|
+
if (!params) {
|
|
65363
|
+
const result = await this.exchange.analyzeCandlesticks({ symbol });
|
|
65364
|
+
const support_price = Math.min(...Object.keys(result.support).map(Number));
|
|
65365
|
+
const symbol_config = await this.recomputeSymbolConfig({ symbol });
|
|
65366
|
+
const config2 = await this.getPositionConfig({
|
|
65367
|
+
symbol,
|
|
65368
|
+
kind: "long"
|
|
65369
|
+
});
|
|
65370
|
+
const position2 = await this.syncAccount({
|
|
65371
|
+
symbol,
|
|
65372
|
+
kind: "long",
|
|
65373
|
+
as_view: true
|
|
65374
|
+
});
|
|
65375
|
+
const bot_position = {
|
|
65376
|
+
kind: "long",
|
|
65377
|
+
entry: position2.entry,
|
|
65378
|
+
quantity: position2.quantity,
|
|
65379
|
+
tp: {
|
|
65380
|
+
price: position2.take_profit
|
|
65381
|
+
}
|
|
65382
|
+
};
|
|
65383
|
+
_params = getHedgeZone({
|
|
65384
|
+
symbol_config,
|
|
65385
|
+
risk: config2.risk,
|
|
65386
|
+
position: bot_position,
|
|
65387
|
+
support: support_price
|
|
65388
|
+
});
|
|
65389
|
+
}
|
|
65390
|
+
if (update) {
|
|
65391
|
+
await this.getPositionConfig({
|
|
65392
|
+
symbol,
|
|
65393
|
+
kind: "short",
|
|
65394
|
+
params: {
|
|
65395
|
+
entry: _params.support,
|
|
65396
|
+
stop: _params.resistance,
|
|
65397
|
+
risk: _params.risk * risk_factor
|
|
65398
|
+
}
|
|
65399
|
+
});
|
|
65400
|
+
}
|
|
65401
|
+
if (update_tp) {
|
|
65402
|
+
await this.getPositionConfig({
|
|
65403
|
+
symbol,
|
|
65404
|
+
kind: "long",
|
|
65405
|
+
params: {
|
|
65406
|
+
profit_percent: _params.profit_percent
|
|
65407
|
+
}
|
|
65408
|
+
});
|
|
65409
|
+
await this.updateTargetPnl({
|
|
65410
|
+
symbol,
|
|
65411
|
+
kind: "long"
|
|
65412
|
+
});
|
|
65413
|
+
}
|
|
65414
|
+
if (place) {
|
|
65415
|
+
await this.placeTrade({
|
|
65416
|
+
symbol,
|
|
65417
|
+
kind: "short",
|
|
65418
|
+
limit: true,
|
|
65419
|
+
ignore_config: true
|
|
65420
|
+
});
|
|
65421
|
+
}
|
|
65422
|
+
return _params;
|
|
65423
|
+
}
|
|
65250
65424
|
async placeOppositeTradeAction(payload) {
|
|
65251
65425
|
const { symbol, kind, data } = payload;
|
|
65252
65426
|
const position2 = await this.syncAccount({
|
|
@@ -66334,7 +66508,10 @@ function getExchangeKlass(exchange) {
|
|
|
66334
66508
|
const func = exchange === "binance" ? BinanceExchange : BybitExchange;
|
|
66335
66509
|
const clientFunc = exchange === "binance" ? initClient : initClient2;
|
|
66336
66510
|
return async (payload) => {
|
|
66337
|
-
const credentials = payload.getCredentials(
|
|
66511
|
+
const credentials = await payload.getCredentials({
|
|
66512
|
+
account: payload.account,
|
|
66513
|
+
exchange
|
|
66514
|
+
});
|
|
66338
66515
|
const client = await clientFunc(credentials, {
|
|
66339
66516
|
type: "future",
|
|
66340
66517
|
proxyAgent: payload.proxyAgent
|
|
@@ -66365,7 +66542,9 @@ async function getExchangeAccount(payload) {
|
|
|
66365
66542
|
const proxyAgent = proxyOptions?.ignore_proxy ? null : proxyOptions?.proxy || _proxyAgent;
|
|
66366
66543
|
const exchange_instance = await getExchangeKlass(account.exchange)({
|
|
66367
66544
|
account: account.owner,
|
|
66368
|
-
getCredentials:
|
|
66545
|
+
getCredentials: async (_payload) => {
|
|
66546
|
+
return await payload.getCredentials({ ..._payload, app_db });
|
|
66547
|
+
},
|
|
66369
66548
|
proxyAgent,
|
|
66370
66549
|
canWithdraw
|
|
66371
66550
|
});
|
|
@@ -66389,7 +66568,7 @@ class App {
|
|
|
66389
66568
|
return await getExchangeAccount({
|
|
66390
66569
|
account,
|
|
66391
66570
|
app_db: this.app_db,
|
|
66392
|
-
getCredentials: this.getCredentials,
|
|
66571
|
+
getCredentials: (p) => this.getCredentials({ ...p, app_db: this.app_db }),
|
|
66393
66572
|
proxyOptions: this.proxyOptions,
|
|
66394
66573
|
canWithdraw: this.proxyOptions?.canWithdraw
|
|
66395
66574
|
});
|
|
@@ -66707,7 +66886,8 @@ async function initApp(payload) {
|
|
|
66707
66886
|
password: payload.password
|
|
66708
66887
|
});
|
|
66709
66888
|
if (credentials) {
|
|
66710
|
-
_getCredentials = (
|
|
66889
|
+
_getCredentials = async (payload2) => {
|
|
66890
|
+
const { account, exchange } = payload2;
|
|
66711
66891
|
const credential = credentials.find((c) => c.name === account && c.exchange === exchange);
|
|
66712
66892
|
if (!credential) {
|
|
66713
66893
|
throw new Error(`Missing API Key or Secret for account '${account}' in .env file. Please check your environment variables.`);
|
|
@@ -66745,11 +66925,19 @@ async function getApp() {
|
|
|
66745
66925
|
password: process.env.POCKETBASE_PASSWORD
|
|
66746
66926
|
},
|
|
66747
66927
|
password: process.env.POCKETBASE_PASSWORD,
|
|
66748
|
-
getCredentials: (
|
|
66928
|
+
getCredentials: async (payload) => {
|
|
66929
|
+
const { account, exchange, app_db } = payload;
|
|
66930
|
+
const credentials = await app_db.getCredentials({
|
|
66931
|
+
password: process.env.POCKETBASE_PASSWORD
|
|
66932
|
+
});
|
|
66933
|
+
const credential = credentials.find((c) => c.name === account && c.exchange === exchange);
|
|
66934
|
+
if (!credential) {
|
|
66935
|
+
throw new Error(`Missing API Key or Secret for account '${account}' in .env file. Please check your environment variables.`);
|
|
66936
|
+
}
|
|
66749
66937
|
return {
|
|
66750
|
-
api_key:
|
|
66751
|
-
api_secret:
|
|
66752
|
-
email:
|
|
66938
|
+
api_key: credential.api_key,
|
|
66939
|
+
api_secret: credential.api_secret,
|
|
66940
|
+
email: credential.email
|
|
66753
66941
|
};
|
|
66754
66942
|
}
|
|
66755
66943
|
});
|