@gbozee/ultimate 0.0.2-91 → 0.0.2-93
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +60 -40
- package/dist/index.d.ts +15 -13
- package/dist/index.js +60 -40
- package/dist/mcp-server.cjs +60 -40
- package/dist/mcp-server.js +60 -40
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -58740,15 +58740,64 @@ class ExchangeAccount {
|
|
|
58740
58740
|
});
|
|
58741
58741
|
}
|
|
58742
58742
|
}
|
|
58743
|
+
async determineReduceTp(payload) {
|
|
58744
|
+
const { symbol, factor } = payload;
|
|
58745
|
+
const positions = await this.syncAccount({
|
|
58746
|
+
symbol,
|
|
58747
|
+
as_view: true
|
|
58748
|
+
});
|
|
58749
|
+
const symbol_config = await this.recomputeSymbolConfig({ symbol });
|
|
58750
|
+
const long_position = positions.find((k) => k.kind === "long");
|
|
58751
|
+
const short_position = positions.find((k) => k.kind === "short");
|
|
58752
|
+
const gap = Math.abs(long_position.entry - short_position.entry);
|
|
58753
|
+
const gap_cost = gap * long_position.quantity * factor;
|
|
58754
|
+
const long_diff = gap_cost / (short_position.entry * short_position.quantity);
|
|
58755
|
+
const short_diff = gap_cost / (long_position.entry * long_position.quantity);
|
|
58756
|
+
const long_tp = to_f2((long_diff + 1) * short_position.entry, symbol_config.price_places);
|
|
58757
|
+
const short_tp = to_f2((short_diff + 1) ** -1 * long_position.entry, symbol_config.price_places);
|
|
58758
|
+
const long_percent = to_f2(Math.abs(long_tp - long_position.entry) * 100 / long_position.entry, "%.4f");
|
|
58759
|
+
const short_percent = to_f2(Math.abs(short_tp - short_position.entry) * 100 / short_position.entry, "%.4f");
|
|
58760
|
+
return {
|
|
58761
|
+
long_diff,
|
|
58762
|
+
short_diff,
|
|
58763
|
+
gap,
|
|
58764
|
+
gap_cost,
|
|
58765
|
+
long_tp,
|
|
58766
|
+
short_tp,
|
|
58767
|
+
long_percent,
|
|
58768
|
+
short_percent
|
|
58769
|
+
};
|
|
58770
|
+
}
|
|
58743
58771
|
async profitWithinGapStrategy(payload) {
|
|
58744
|
-
const {
|
|
58772
|
+
const { symbol } = payload;
|
|
58773
|
+
let reward_factor = 1;
|
|
58774
|
+
const strategy = await this.getAccountStrategy({ symbol });
|
|
58775
|
+
if (!strategy) {
|
|
58776
|
+
return;
|
|
58777
|
+
}
|
|
58778
|
+
console.log("Fetching positions for ", symbol);
|
|
58779
|
+
const positions = await this.syncAccount({
|
|
58745
58780
|
symbol,
|
|
58746
|
-
|
|
58747
|
-
|
|
58748
|
-
|
|
58749
|
-
|
|
58750
|
-
|
|
58751
|
-
|
|
58781
|
+
as_view: true
|
|
58782
|
+
});
|
|
58783
|
+
const risk = strategy.risk;
|
|
58784
|
+
const kind = strategy.kind;
|
|
58785
|
+
const support = strategy.support;
|
|
58786
|
+
const resistance = strategy.resistance;
|
|
58787
|
+
console.log("Getting long and short positions for ", symbol);
|
|
58788
|
+
const long_position = positions.find((k) => k.kind === "long");
|
|
58789
|
+
const short_position = positions.find((k) => k.kind === "short");
|
|
58790
|
+
console.log("Getting focus position for ", symbol, kind);
|
|
58791
|
+
const focus_position = kind === "long" ? long_position : short_position;
|
|
58792
|
+
const reverse_position = kind === "long" ? short_position : long_position;
|
|
58793
|
+
if (strategy.max_reward_factor === 0) {
|
|
58794
|
+
reward_factor = strategy.reward_factor;
|
|
58795
|
+
}
|
|
58796
|
+
if (focus_position.avg_qty >= focus_position.quantity && strategy.max_reward_factor) {
|
|
58797
|
+
reward_factor = to_f2(focus_position.quantity * strategy.max_reward_factor / focus_position.avg_qty, "%.2f");
|
|
58798
|
+
} else {
|
|
58799
|
+
reward_factor = strategy.reward_factor;
|
|
58800
|
+
}
|
|
58752
58801
|
console.log("Getting entry and stop for ", symbol, kind);
|
|
58753
58802
|
const entry = kind === "long" ? resistance : support;
|
|
58754
58803
|
const stop = kind === "long" ? support : resistance;
|
|
@@ -58810,17 +58859,6 @@ class ExchangeAccount {
|
|
|
58810
58859
|
...config2,
|
|
58811
58860
|
...data
|
|
58812
58861
|
};
|
|
58813
|
-
console.log("Fetching positions for ", symbol);
|
|
58814
|
-
const positions = await this.syncAccount({
|
|
58815
|
-
symbol,
|
|
58816
|
-
as_view: true
|
|
58817
|
-
});
|
|
58818
|
-
console.log("Getting long and short positions for ", symbol);
|
|
58819
|
-
const long_position = positions.find((k) => k.kind === "long");
|
|
58820
|
-
const short_position = positions.find((k) => k.kind === "short");
|
|
58821
|
-
console.log("Getting focus position for ", symbol, kind);
|
|
58822
|
-
const focus_position = kind === "long" ? long_position : short_position;
|
|
58823
|
-
const reverse_position = kind === "long" ? short_position : long_position;
|
|
58824
58862
|
let reverse_action = null;
|
|
58825
58863
|
let reverse_orders_to_buy = [];
|
|
58826
58864
|
let reverse_config = null;
|
|
@@ -58902,7 +58940,7 @@ class ExchangeAccount {
|
|
|
58902
58940
|
const max_size = app_config.max_size * 0.98;
|
|
58903
58941
|
if (reverse_config.threshold_qty !== max_size) {
|
|
58904
58942
|
await this.app_db.updateScheduledTrade(reverse_config.id, {
|
|
58905
|
-
follow:
|
|
58943
|
+
follow: strategy.follow,
|
|
58906
58944
|
threshold_qty: max_size
|
|
58907
58945
|
});
|
|
58908
58946
|
}
|
|
@@ -59250,33 +59288,15 @@ class App {
|
|
|
59250
59288
|
console.log("Running strategy for ", strategy.symbol, "for account", strategy.expand.account.owner, strategy.expand.account.exchange);
|
|
59251
59289
|
await callback({
|
|
59252
59290
|
symbol: strategy.symbol,
|
|
59253
|
-
|
|
59254
|
-
risk: strategy.risk,
|
|
59255
|
-
resistance: strategy.resistance,
|
|
59256
|
-
support: strategy.support,
|
|
59257
|
-
account: strategy.expand.account,
|
|
59258
|
-
reward_factor: strategy.reward_factor
|
|
59291
|
+
account: strategy.expand.account
|
|
59259
59292
|
});
|
|
59260
59293
|
}
|
|
59261
59294
|
}
|
|
59262
59295
|
async profitWithinGapStrategy(payload) {
|
|
59263
|
-
const {
|
|
59264
|
-
account,
|
|
59265
|
-
symbol,
|
|
59266
|
-
kind,
|
|
59267
|
-
risk,
|
|
59268
|
-
resistance,
|
|
59269
|
-
support,
|
|
59270
|
-
reward_factor = 1
|
|
59271
|
-
} = payload;
|
|
59296
|
+
const { account, symbol } = payload;
|
|
59272
59297
|
const exchange_account = await this.getExchangeAccount(account);
|
|
59273
59298
|
const result = await exchange_account.profitWithinGapStrategy({
|
|
59274
|
-
symbol
|
|
59275
|
-
kind,
|
|
59276
|
-
risk,
|
|
59277
|
-
resistance,
|
|
59278
|
-
support,
|
|
59279
|
-
reward_factor
|
|
59299
|
+
symbol
|
|
59280
59300
|
});
|
|
59281
59301
|
return result;
|
|
59282
59302
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -81,6 +81,8 @@ export interface AccountStrategy extends BaseSystemFields {
|
|
|
81
81
|
support?: number;
|
|
82
82
|
resistance?: number;
|
|
83
83
|
running?: boolean;
|
|
84
|
+
max_reward_factor?: number;
|
|
85
|
+
follow?: boolean;
|
|
84
86
|
}
|
|
85
87
|
interface Proxy$1 extends BaseSystemFields {
|
|
86
88
|
ip_address?: string;
|
|
@@ -1674,13 +1676,21 @@ declare class ExchangeAccount$1 {
|
|
|
1674
1676
|
symbol: string;
|
|
1675
1677
|
kind: "long" | "short";
|
|
1676
1678
|
}): Promise<void>;
|
|
1679
|
+
determineReduceTp(payload: {
|
|
1680
|
+
symbol: string;
|
|
1681
|
+
factor: number;
|
|
1682
|
+
}): Promise<{
|
|
1683
|
+
long_diff: number;
|
|
1684
|
+
short_diff: number;
|
|
1685
|
+
gap: number;
|
|
1686
|
+
gap_cost: number;
|
|
1687
|
+
long_tp: number;
|
|
1688
|
+
short_tp: number;
|
|
1689
|
+
long_percent: number;
|
|
1690
|
+
short_percent: number;
|
|
1691
|
+
}>;
|
|
1677
1692
|
profitWithinGapStrategy(payload: {
|
|
1678
1693
|
symbol: string;
|
|
1679
|
-
kind: "long" | "short";
|
|
1680
|
-
risk: number;
|
|
1681
|
-
resistance: number;
|
|
1682
|
-
support: number;
|
|
1683
|
-
reward_factor?: number;
|
|
1684
1694
|
}): Promise<{
|
|
1685
1695
|
reverse_config: any;
|
|
1686
1696
|
reverse_action: {
|
|
@@ -1891,18 +1901,10 @@ declare class App {
|
|
|
1891
1901
|
runDbStrategyAccounts(callback: (params: {
|
|
1892
1902
|
symbol: string;
|
|
1893
1903
|
account: ExchangeType;
|
|
1894
|
-
risk: number;
|
|
1895
|
-
resistance: number;
|
|
1896
|
-
support: number;
|
|
1897
1904
|
}) => Promise<any>): Promise<void>;
|
|
1898
1905
|
profitWithinGapStrategy(payload: {
|
|
1899
1906
|
account: ExchangeType;
|
|
1900
1907
|
symbol: string;
|
|
1901
|
-
kind: "long" | "short";
|
|
1902
|
-
risk: number;
|
|
1903
|
-
resistance: number;
|
|
1904
|
-
support: number;
|
|
1905
|
-
reward_factor?: number;
|
|
1906
1908
|
}): Promise<{
|
|
1907
1909
|
reverse_config: any;
|
|
1908
1910
|
reverse_action: {
|
package/dist/index.js
CHANGED
|
@@ -58695,15 +58695,64 @@ class ExchangeAccount {
|
|
|
58695
58695
|
});
|
|
58696
58696
|
}
|
|
58697
58697
|
}
|
|
58698
|
+
async determineReduceTp(payload) {
|
|
58699
|
+
const { symbol, factor } = payload;
|
|
58700
|
+
const positions = await this.syncAccount({
|
|
58701
|
+
symbol,
|
|
58702
|
+
as_view: true
|
|
58703
|
+
});
|
|
58704
|
+
const symbol_config = await this.recomputeSymbolConfig({ symbol });
|
|
58705
|
+
const long_position = positions.find((k) => k.kind === "long");
|
|
58706
|
+
const short_position = positions.find((k) => k.kind === "short");
|
|
58707
|
+
const gap = Math.abs(long_position.entry - short_position.entry);
|
|
58708
|
+
const gap_cost = gap * long_position.quantity * factor;
|
|
58709
|
+
const long_diff = gap_cost / (short_position.entry * short_position.quantity);
|
|
58710
|
+
const short_diff = gap_cost / (long_position.entry * long_position.quantity);
|
|
58711
|
+
const long_tp = to_f2((long_diff + 1) * short_position.entry, symbol_config.price_places);
|
|
58712
|
+
const short_tp = to_f2((short_diff + 1) ** -1 * long_position.entry, symbol_config.price_places);
|
|
58713
|
+
const long_percent = to_f2(Math.abs(long_tp - long_position.entry) * 100 / long_position.entry, "%.4f");
|
|
58714
|
+
const short_percent = to_f2(Math.abs(short_tp - short_position.entry) * 100 / short_position.entry, "%.4f");
|
|
58715
|
+
return {
|
|
58716
|
+
long_diff,
|
|
58717
|
+
short_diff,
|
|
58718
|
+
gap,
|
|
58719
|
+
gap_cost,
|
|
58720
|
+
long_tp,
|
|
58721
|
+
short_tp,
|
|
58722
|
+
long_percent,
|
|
58723
|
+
short_percent
|
|
58724
|
+
};
|
|
58725
|
+
}
|
|
58698
58726
|
async profitWithinGapStrategy(payload) {
|
|
58699
|
-
const {
|
|
58727
|
+
const { symbol } = payload;
|
|
58728
|
+
let reward_factor = 1;
|
|
58729
|
+
const strategy = await this.getAccountStrategy({ symbol });
|
|
58730
|
+
if (!strategy) {
|
|
58731
|
+
return;
|
|
58732
|
+
}
|
|
58733
|
+
console.log("Fetching positions for ", symbol);
|
|
58734
|
+
const positions = await this.syncAccount({
|
|
58700
58735
|
symbol,
|
|
58701
|
-
|
|
58702
|
-
|
|
58703
|
-
|
|
58704
|
-
|
|
58705
|
-
|
|
58706
|
-
|
|
58736
|
+
as_view: true
|
|
58737
|
+
});
|
|
58738
|
+
const risk = strategy.risk;
|
|
58739
|
+
const kind = strategy.kind;
|
|
58740
|
+
const support = strategy.support;
|
|
58741
|
+
const resistance = strategy.resistance;
|
|
58742
|
+
console.log("Getting long and short positions for ", symbol);
|
|
58743
|
+
const long_position = positions.find((k) => k.kind === "long");
|
|
58744
|
+
const short_position = positions.find((k) => k.kind === "short");
|
|
58745
|
+
console.log("Getting focus position for ", symbol, kind);
|
|
58746
|
+
const focus_position = kind === "long" ? long_position : short_position;
|
|
58747
|
+
const reverse_position = kind === "long" ? short_position : long_position;
|
|
58748
|
+
if (strategy.max_reward_factor === 0) {
|
|
58749
|
+
reward_factor = strategy.reward_factor;
|
|
58750
|
+
}
|
|
58751
|
+
if (focus_position.avg_qty >= focus_position.quantity && strategy.max_reward_factor) {
|
|
58752
|
+
reward_factor = to_f2(focus_position.quantity * strategy.max_reward_factor / focus_position.avg_qty, "%.2f");
|
|
58753
|
+
} else {
|
|
58754
|
+
reward_factor = strategy.reward_factor;
|
|
58755
|
+
}
|
|
58707
58756
|
console.log("Getting entry and stop for ", symbol, kind);
|
|
58708
58757
|
const entry = kind === "long" ? resistance : support;
|
|
58709
58758
|
const stop = kind === "long" ? support : resistance;
|
|
@@ -58765,17 +58814,6 @@ class ExchangeAccount {
|
|
|
58765
58814
|
...config2,
|
|
58766
58815
|
...data
|
|
58767
58816
|
};
|
|
58768
|
-
console.log("Fetching positions for ", symbol);
|
|
58769
|
-
const positions = await this.syncAccount({
|
|
58770
|
-
symbol,
|
|
58771
|
-
as_view: true
|
|
58772
|
-
});
|
|
58773
|
-
console.log("Getting long and short positions for ", symbol);
|
|
58774
|
-
const long_position = positions.find((k) => k.kind === "long");
|
|
58775
|
-
const short_position = positions.find((k) => k.kind === "short");
|
|
58776
|
-
console.log("Getting focus position for ", symbol, kind);
|
|
58777
|
-
const focus_position = kind === "long" ? long_position : short_position;
|
|
58778
|
-
const reverse_position = kind === "long" ? short_position : long_position;
|
|
58779
58817
|
let reverse_action = null;
|
|
58780
58818
|
let reverse_orders_to_buy = [];
|
|
58781
58819
|
let reverse_config = null;
|
|
@@ -58857,7 +58895,7 @@ class ExchangeAccount {
|
|
|
58857
58895
|
const max_size = app_config.max_size * 0.98;
|
|
58858
58896
|
if (reverse_config.threshold_qty !== max_size) {
|
|
58859
58897
|
await this.app_db.updateScheduledTrade(reverse_config.id, {
|
|
58860
|
-
follow:
|
|
58898
|
+
follow: strategy.follow,
|
|
58861
58899
|
threshold_qty: max_size
|
|
58862
58900
|
});
|
|
58863
58901
|
}
|
|
@@ -59205,33 +59243,15 @@ class App {
|
|
|
59205
59243
|
console.log("Running strategy for ", strategy.symbol, "for account", strategy.expand.account.owner, strategy.expand.account.exchange);
|
|
59206
59244
|
await callback({
|
|
59207
59245
|
symbol: strategy.symbol,
|
|
59208
|
-
|
|
59209
|
-
risk: strategy.risk,
|
|
59210
|
-
resistance: strategy.resistance,
|
|
59211
|
-
support: strategy.support,
|
|
59212
|
-
account: strategy.expand.account,
|
|
59213
|
-
reward_factor: strategy.reward_factor
|
|
59246
|
+
account: strategy.expand.account
|
|
59214
59247
|
});
|
|
59215
59248
|
}
|
|
59216
59249
|
}
|
|
59217
59250
|
async profitWithinGapStrategy(payload) {
|
|
59218
|
-
const {
|
|
59219
|
-
account,
|
|
59220
|
-
symbol,
|
|
59221
|
-
kind,
|
|
59222
|
-
risk,
|
|
59223
|
-
resistance,
|
|
59224
|
-
support,
|
|
59225
|
-
reward_factor = 1
|
|
59226
|
-
} = payload;
|
|
59251
|
+
const { account, symbol } = payload;
|
|
59227
59252
|
const exchange_account = await this.getExchangeAccount(account);
|
|
59228
59253
|
const result = await exchange_account.profitWithinGapStrategy({
|
|
59229
|
-
symbol
|
|
59230
|
-
kind,
|
|
59231
|
-
risk,
|
|
59232
|
-
resistance,
|
|
59233
|
-
support,
|
|
59234
|
-
reward_factor
|
|
59254
|
+
symbol
|
|
59235
59255
|
});
|
|
59236
59256
|
return result;
|
|
59237
59257
|
}
|
package/dist/mcp-server.cjs
CHANGED
|
@@ -65431,15 +65431,64 @@ class ExchangeAccount {
|
|
|
65431
65431
|
});
|
|
65432
65432
|
}
|
|
65433
65433
|
}
|
|
65434
|
+
async determineReduceTp(payload) {
|
|
65435
|
+
const { symbol, factor } = payload;
|
|
65436
|
+
const positions = await this.syncAccount({
|
|
65437
|
+
symbol,
|
|
65438
|
+
as_view: true
|
|
65439
|
+
});
|
|
65440
|
+
const symbol_config = await this.recomputeSymbolConfig({ symbol });
|
|
65441
|
+
const long_position = positions.find((k) => k.kind === "long");
|
|
65442
|
+
const short_position = positions.find((k) => k.kind === "short");
|
|
65443
|
+
const gap = Math.abs(long_position.entry - short_position.entry);
|
|
65444
|
+
const gap_cost = gap * long_position.quantity * factor;
|
|
65445
|
+
const long_diff = gap_cost / (short_position.entry * short_position.quantity);
|
|
65446
|
+
const short_diff = gap_cost / (long_position.entry * long_position.quantity);
|
|
65447
|
+
const long_tp = to_f2((long_diff + 1) * short_position.entry, symbol_config.price_places);
|
|
65448
|
+
const short_tp = to_f2((short_diff + 1) ** -1 * long_position.entry, symbol_config.price_places);
|
|
65449
|
+
const long_percent = to_f2(Math.abs(long_tp - long_position.entry) * 100 / long_position.entry, "%.4f");
|
|
65450
|
+
const short_percent = to_f2(Math.abs(short_tp - short_position.entry) * 100 / short_position.entry, "%.4f");
|
|
65451
|
+
return {
|
|
65452
|
+
long_diff,
|
|
65453
|
+
short_diff,
|
|
65454
|
+
gap,
|
|
65455
|
+
gap_cost,
|
|
65456
|
+
long_tp,
|
|
65457
|
+
short_tp,
|
|
65458
|
+
long_percent,
|
|
65459
|
+
short_percent
|
|
65460
|
+
};
|
|
65461
|
+
}
|
|
65434
65462
|
async profitWithinGapStrategy(payload) {
|
|
65435
|
-
const {
|
|
65463
|
+
const { symbol } = payload;
|
|
65464
|
+
let reward_factor = 1;
|
|
65465
|
+
const strategy = await this.getAccountStrategy({ symbol });
|
|
65466
|
+
if (!strategy) {
|
|
65467
|
+
return;
|
|
65468
|
+
}
|
|
65469
|
+
console.log("Fetching positions for ", symbol);
|
|
65470
|
+
const positions = await this.syncAccount({
|
|
65436
65471
|
symbol,
|
|
65437
|
-
|
|
65438
|
-
|
|
65439
|
-
|
|
65440
|
-
|
|
65441
|
-
|
|
65442
|
-
|
|
65472
|
+
as_view: true
|
|
65473
|
+
});
|
|
65474
|
+
const risk = strategy.risk;
|
|
65475
|
+
const kind = strategy.kind;
|
|
65476
|
+
const support = strategy.support;
|
|
65477
|
+
const resistance = strategy.resistance;
|
|
65478
|
+
console.log("Getting long and short positions for ", symbol);
|
|
65479
|
+
const long_position = positions.find((k) => k.kind === "long");
|
|
65480
|
+
const short_position = positions.find((k) => k.kind === "short");
|
|
65481
|
+
console.log("Getting focus position for ", symbol, kind);
|
|
65482
|
+
const focus_position = kind === "long" ? long_position : short_position;
|
|
65483
|
+
const reverse_position = kind === "long" ? short_position : long_position;
|
|
65484
|
+
if (strategy.max_reward_factor === 0) {
|
|
65485
|
+
reward_factor = strategy.reward_factor;
|
|
65486
|
+
}
|
|
65487
|
+
if (focus_position.avg_qty >= focus_position.quantity && strategy.max_reward_factor) {
|
|
65488
|
+
reward_factor = to_f2(focus_position.quantity * strategy.max_reward_factor / focus_position.avg_qty, "%.2f");
|
|
65489
|
+
} else {
|
|
65490
|
+
reward_factor = strategy.reward_factor;
|
|
65491
|
+
}
|
|
65443
65492
|
console.log("Getting entry and stop for ", symbol, kind);
|
|
65444
65493
|
const entry = kind === "long" ? resistance : support;
|
|
65445
65494
|
const stop = kind === "long" ? support : resistance;
|
|
@@ -65501,17 +65550,6 @@ class ExchangeAccount {
|
|
|
65501
65550
|
...config2,
|
|
65502
65551
|
...data
|
|
65503
65552
|
};
|
|
65504
|
-
console.log("Fetching positions for ", symbol);
|
|
65505
|
-
const positions = await this.syncAccount({
|
|
65506
|
-
symbol,
|
|
65507
|
-
as_view: true
|
|
65508
|
-
});
|
|
65509
|
-
console.log("Getting long and short positions for ", symbol);
|
|
65510
|
-
const long_position = positions.find((k) => k.kind === "long");
|
|
65511
|
-
const short_position = positions.find((k) => k.kind === "short");
|
|
65512
|
-
console.log("Getting focus position for ", symbol, kind);
|
|
65513
|
-
const focus_position = kind === "long" ? long_position : short_position;
|
|
65514
|
-
const reverse_position = kind === "long" ? short_position : long_position;
|
|
65515
65553
|
let reverse_action = null;
|
|
65516
65554
|
let reverse_orders_to_buy = [];
|
|
65517
65555
|
let reverse_config = null;
|
|
@@ -65593,7 +65631,7 @@ class ExchangeAccount {
|
|
|
65593
65631
|
const max_size = app_config.max_size * 0.98;
|
|
65594
65632
|
if (reverse_config.threshold_qty !== max_size) {
|
|
65595
65633
|
await this.app_db.updateScheduledTrade(reverse_config.id, {
|
|
65596
|
-
follow:
|
|
65634
|
+
follow: strategy.follow,
|
|
65597
65635
|
threshold_qty: max_size
|
|
65598
65636
|
});
|
|
65599
65637
|
}
|
|
@@ -65941,33 +65979,15 @@ class App {
|
|
|
65941
65979
|
console.log("Running strategy for ", strategy.symbol, "for account", strategy.expand.account.owner, strategy.expand.account.exchange);
|
|
65942
65980
|
await callback({
|
|
65943
65981
|
symbol: strategy.symbol,
|
|
65944
|
-
|
|
65945
|
-
risk: strategy.risk,
|
|
65946
|
-
resistance: strategy.resistance,
|
|
65947
|
-
support: strategy.support,
|
|
65948
|
-
account: strategy.expand.account,
|
|
65949
|
-
reward_factor: strategy.reward_factor
|
|
65982
|
+
account: strategy.expand.account
|
|
65950
65983
|
});
|
|
65951
65984
|
}
|
|
65952
65985
|
}
|
|
65953
65986
|
async profitWithinGapStrategy(payload) {
|
|
65954
|
-
const {
|
|
65955
|
-
account,
|
|
65956
|
-
symbol,
|
|
65957
|
-
kind,
|
|
65958
|
-
risk,
|
|
65959
|
-
resistance,
|
|
65960
|
-
support,
|
|
65961
|
-
reward_factor = 1
|
|
65962
|
-
} = payload;
|
|
65987
|
+
const { account, symbol } = payload;
|
|
65963
65988
|
const exchange_account = await this.getExchangeAccount(account);
|
|
65964
65989
|
const result = await exchange_account.profitWithinGapStrategy({
|
|
65965
|
-
symbol
|
|
65966
|
-
kind,
|
|
65967
|
-
risk,
|
|
65968
|
-
resistance,
|
|
65969
|
-
support,
|
|
65970
|
-
reward_factor
|
|
65990
|
+
symbol
|
|
65971
65991
|
});
|
|
65972
65992
|
return result;
|
|
65973
65993
|
}
|
package/dist/mcp-server.js
CHANGED
|
@@ -65408,15 +65408,64 @@ class ExchangeAccount {
|
|
|
65408
65408
|
});
|
|
65409
65409
|
}
|
|
65410
65410
|
}
|
|
65411
|
+
async determineReduceTp(payload) {
|
|
65412
|
+
const { symbol, factor } = payload;
|
|
65413
|
+
const positions = await this.syncAccount({
|
|
65414
|
+
symbol,
|
|
65415
|
+
as_view: true
|
|
65416
|
+
});
|
|
65417
|
+
const symbol_config = await this.recomputeSymbolConfig({ symbol });
|
|
65418
|
+
const long_position = positions.find((k) => k.kind === "long");
|
|
65419
|
+
const short_position = positions.find((k) => k.kind === "short");
|
|
65420
|
+
const gap = Math.abs(long_position.entry - short_position.entry);
|
|
65421
|
+
const gap_cost = gap * long_position.quantity * factor;
|
|
65422
|
+
const long_diff = gap_cost / (short_position.entry * short_position.quantity);
|
|
65423
|
+
const short_diff = gap_cost / (long_position.entry * long_position.quantity);
|
|
65424
|
+
const long_tp = to_f2((long_diff + 1) * short_position.entry, symbol_config.price_places);
|
|
65425
|
+
const short_tp = to_f2((short_diff + 1) ** -1 * long_position.entry, symbol_config.price_places);
|
|
65426
|
+
const long_percent = to_f2(Math.abs(long_tp - long_position.entry) * 100 / long_position.entry, "%.4f");
|
|
65427
|
+
const short_percent = to_f2(Math.abs(short_tp - short_position.entry) * 100 / short_position.entry, "%.4f");
|
|
65428
|
+
return {
|
|
65429
|
+
long_diff,
|
|
65430
|
+
short_diff,
|
|
65431
|
+
gap,
|
|
65432
|
+
gap_cost,
|
|
65433
|
+
long_tp,
|
|
65434
|
+
short_tp,
|
|
65435
|
+
long_percent,
|
|
65436
|
+
short_percent
|
|
65437
|
+
};
|
|
65438
|
+
}
|
|
65411
65439
|
async profitWithinGapStrategy(payload) {
|
|
65412
|
-
const {
|
|
65440
|
+
const { symbol } = payload;
|
|
65441
|
+
let reward_factor = 1;
|
|
65442
|
+
const strategy = await this.getAccountStrategy({ symbol });
|
|
65443
|
+
if (!strategy) {
|
|
65444
|
+
return;
|
|
65445
|
+
}
|
|
65446
|
+
console.log("Fetching positions for ", symbol);
|
|
65447
|
+
const positions = await this.syncAccount({
|
|
65413
65448
|
symbol,
|
|
65414
|
-
|
|
65415
|
-
|
|
65416
|
-
|
|
65417
|
-
|
|
65418
|
-
|
|
65419
|
-
|
|
65449
|
+
as_view: true
|
|
65450
|
+
});
|
|
65451
|
+
const risk = strategy.risk;
|
|
65452
|
+
const kind = strategy.kind;
|
|
65453
|
+
const support = strategy.support;
|
|
65454
|
+
const resistance = strategy.resistance;
|
|
65455
|
+
console.log("Getting long and short positions for ", symbol);
|
|
65456
|
+
const long_position = positions.find((k) => k.kind === "long");
|
|
65457
|
+
const short_position = positions.find((k) => k.kind === "short");
|
|
65458
|
+
console.log("Getting focus position for ", symbol, kind);
|
|
65459
|
+
const focus_position = kind === "long" ? long_position : short_position;
|
|
65460
|
+
const reverse_position = kind === "long" ? short_position : long_position;
|
|
65461
|
+
if (strategy.max_reward_factor === 0) {
|
|
65462
|
+
reward_factor = strategy.reward_factor;
|
|
65463
|
+
}
|
|
65464
|
+
if (focus_position.avg_qty >= focus_position.quantity && strategy.max_reward_factor) {
|
|
65465
|
+
reward_factor = to_f2(focus_position.quantity * strategy.max_reward_factor / focus_position.avg_qty, "%.2f");
|
|
65466
|
+
} else {
|
|
65467
|
+
reward_factor = strategy.reward_factor;
|
|
65468
|
+
}
|
|
65420
65469
|
console.log("Getting entry and stop for ", symbol, kind);
|
|
65421
65470
|
const entry = kind === "long" ? resistance : support;
|
|
65422
65471
|
const stop = kind === "long" ? support : resistance;
|
|
@@ -65478,17 +65527,6 @@ class ExchangeAccount {
|
|
|
65478
65527
|
...config2,
|
|
65479
65528
|
...data
|
|
65480
65529
|
};
|
|
65481
|
-
console.log("Fetching positions for ", symbol);
|
|
65482
|
-
const positions = await this.syncAccount({
|
|
65483
|
-
symbol,
|
|
65484
|
-
as_view: true
|
|
65485
|
-
});
|
|
65486
|
-
console.log("Getting long and short positions for ", symbol);
|
|
65487
|
-
const long_position = positions.find((k) => k.kind === "long");
|
|
65488
|
-
const short_position = positions.find((k) => k.kind === "short");
|
|
65489
|
-
console.log("Getting focus position for ", symbol, kind);
|
|
65490
|
-
const focus_position = kind === "long" ? long_position : short_position;
|
|
65491
|
-
const reverse_position = kind === "long" ? short_position : long_position;
|
|
65492
65530
|
let reverse_action = null;
|
|
65493
65531
|
let reverse_orders_to_buy = [];
|
|
65494
65532
|
let reverse_config = null;
|
|
@@ -65570,7 +65608,7 @@ class ExchangeAccount {
|
|
|
65570
65608
|
const max_size = app_config.max_size * 0.98;
|
|
65571
65609
|
if (reverse_config.threshold_qty !== max_size) {
|
|
65572
65610
|
await this.app_db.updateScheduledTrade(reverse_config.id, {
|
|
65573
|
-
follow:
|
|
65611
|
+
follow: strategy.follow,
|
|
65574
65612
|
threshold_qty: max_size
|
|
65575
65613
|
});
|
|
65576
65614
|
}
|
|
@@ -65918,33 +65956,15 @@ class App {
|
|
|
65918
65956
|
console.log("Running strategy for ", strategy.symbol, "for account", strategy.expand.account.owner, strategy.expand.account.exchange);
|
|
65919
65957
|
await callback({
|
|
65920
65958
|
symbol: strategy.symbol,
|
|
65921
|
-
|
|
65922
|
-
risk: strategy.risk,
|
|
65923
|
-
resistance: strategy.resistance,
|
|
65924
|
-
support: strategy.support,
|
|
65925
|
-
account: strategy.expand.account,
|
|
65926
|
-
reward_factor: strategy.reward_factor
|
|
65959
|
+
account: strategy.expand.account
|
|
65927
65960
|
});
|
|
65928
65961
|
}
|
|
65929
65962
|
}
|
|
65930
65963
|
async profitWithinGapStrategy(payload) {
|
|
65931
|
-
const {
|
|
65932
|
-
account,
|
|
65933
|
-
symbol,
|
|
65934
|
-
kind,
|
|
65935
|
-
risk,
|
|
65936
|
-
resistance,
|
|
65937
|
-
support,
|
|
65938
|
-
reward_factor = 1
|
|
65939
|
-
} = payload;
|
|
65964
|
+
const { account, symbol } = payload;
|
|
65940
65965
|
const exchange_account = await this.getExchangeAccount(account);
|
|
65941
65966
|
const result = await exchange_account.profitWithinGapStrategy({
|
|
65942
|
-
symbol
|
|
65943
|
-
kind,
|
|
65944
|
-
risk,
|
|
65945
|
-
resistance,
|
|
65946
|
-
support,
|
|
65947
|
-
reward_factor
|
|
65967
|
+
symbol
|
|
65948
65968
|
});
|
|
65949
65969
|
return result;
|
|
65950
65970
|
}
|