@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.
@@ -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: number;
546
+ reward_factor?: number;
547
547
  risk_factor?: number;
548
+ support?: number;
548
549
  }): {
549
550
  support: number;
550
551
  resistance: number;
@@ -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(payload.account, exchange);
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: payload.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 = (account, exchange) => {
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(account, exchange) {
60261
+ async function getCredentials(payload) {
60262
+ const { account, exchange, app_db } = payload;
60173
60263
  console.log(`Fetching credentials for account: ${account}, exchange: ${exchange}`);
60174
- let apiKey;
60175
- let apiSecret;
60176
- switch (account) {
60177
- case "sub_account":
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: number;
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: (account: string, exchange: string) => {
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: (account: string, exchange: string) => {
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
- }, proxyOptions?: {
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: (account: string, exchange: string) => {
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(account: string, exchange: string): {
2486
- api_key: string;
2487
- api_secret: string;
2488
- email: string;
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(payload.account, exchange);
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: payload.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 = (account, exchange) => {
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(account, exchange) {
60211
+ async function getCredentials(payload) {
60212
+ const { account, exchange, app_db } = payload;
60123
60213
  console.log(`Fetching credentials for account: ${account}, exchange: ${exchange}`);
60124
- let apiKey;
60125
- let apiSecret;
60126
- switch (account) {
60127
- case "sub_account":
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;
@@ -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(payload.account, exchange);
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: payload.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 = (account, exchange) => {
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: (account, exchange) => {
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
  });
@@ -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(payload.account, exchange);
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: payload.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 = (account, exchange) => {
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: (account, exchange) => {
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
  });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@gbozee/ultimate",
3
3
  "type": "module",
4
- "version": "0.0.2-111",
4
+ "version": "0.0.2-113",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",