@gbozee/ultimate 0.0.2-90 → 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/frontend-index.js +2 -1
- package/dist/index.cjs +62 -41
- package/dist/index.d.ts +15 -13
- package/dist/index.js +62 -41
- package/dist/mcp-server.cjs +62 -41
- package/dist/mcp-server.js +62 -41
- package/package.json +1 -1
package/dist/frontend-index.js
CHANGED
|
@@ -1264,7 +1264,8 @@ function get_app_config_and_max_size(config, payload) {
|
|
|
1264
1264
|
budget: 0,
|
|
1265
1265
|
price_places: config.price_places,
|
|
1266
1266
|
decimal_places: config.decimal_places,
|
|
1267
|
-
min_profit: config.profit_percent * config.profit / 100
|
|
1267
|
+
min_profit: config.profit_percent * config.profit / 100,
|
|
1268
|
+
symbol: config.symbol
|
|
1268
1269
|
};
|
|
1269
1270
|
const initialResult = sortedBuildConfig(app_config, {
|
|
1270
1271
|
entry: app_config.entry,
|
package/dist/index.cjs
CHANGED
|
@@ -53343,7 +53343,8 @@ function get_app_config_and_max_size(config2, payload) {
|
|
|
53343
53343
|
budget: 0,
|
|
53344
53344
|
price_places: config2.price_places,
|
|
53345
53345
|
decimal_places: config2.decimal_places,
|
|
53346
|
-
min_profit: config2.profit_percent * config2.profit / 100
|
|
53346
|
+
min_profit: config2.profit_percent * config2.profit / 100,
|
|
53347
|
+
symbol: config2.symbol
|
|
53347
53348
|
};
|
|
53348
53349
|
const initialResult = sortedBuildConfig(app_config, {
|
|
53349
53350
|
entry: app_config.entry,
|
|
@@ -58739,15 +58740,64 @@ class ExchangeAccount {
|
|
|
58739
58740
|
});
|
|
58740
58741
|
}
|
|
58741
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
|
+
}
|
|
58742
58771
|
async profitWithinGapStrategy(payload) {
|
|
58743
|
-
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({
|
|
58744
58780
|
symbol,
|
|
58745
|
-
|
|
58746
|
-
|
|
58747
|
-
|
|
58748
|
-
|
|
58749
|
-
|
|
58750
|
-
|
|
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
|
+
}
|
|
58751
58801
|
console.log("Getting entry and stop for ", symbol, kind);
|
|
58752
58802
|
const entry = kind === "long" ? resistance : support;
|
|
58753
58803
|
const stop = kind === "long" ? support : resistance;
|
|
@@ -58809,17 +58859,6 @@ class ExchangeAccount {
|
|
|
58809
58859
|
...config2,
|
|
58810
58860
|
...data
|
|
58811
58861
|
};
|
|
58812
|
-
console.log("Fetching positions for ", symbol);
|
|
58813
|
-
const positions = await this.syncAccount({
|
|
58814
|
-
symbol,
|
|
58815
|
-
as_view: true
|
|
58816
|
-
});
|
|
58817
|
-
console.log("Getting long and short positions for ", symbol);
|
|
58818
|
-
const long_position = positions.find((k) => k.kind === "long");
|
|
58819
|
-
const short_position = positions.find((k) => k.kind === "short");
|
|
58820
|
-
console.log("Getting focus position for ", symbol, kind);
|
|
58821
|
-
const focus_position = kind === "long" ? long_position : short_position;
|
|
58822
|
-
const reverse_position = kind === "long" ? short_position : long_position;
|
|
58823
58862
|
let reverse_action = null;
|
|
58824
58863
|
let reverse_orders_to_buy = [];
|
|
58825
58864
|
let reverse_config = null;
|
|
@@ -58901,7 +58940,7 @@ class ExchangeAccount {
|
|
|
58901
58940
|
const max_size = app_config.max_size * 0.98;
|
|
58902
58941
|
if (reverse_config.threshold_qty !== max_size) {
|
|
58903
58942
|
await this.app_db.updateScheduledTrade(reverse_config.id, {
|
|
58904
|
-
follow:
|
|
58943
|
+
follow: strategy.follow,
|
|
58905
58944
|
threshold_qty: max_size
|
|
58906
58945
|
});
|
|
58907
58946
|
}
|
|
@@ -59249,33 +59288,15 @@ class App {
|
|
|
59249
59288
|
console.log("Running strategy for ", strategy.symbol, "for account", strategy.expand.account.owner, strategy.expand.account.exchange);
|
|
59250
59289
|
await callback({
|
|
59251
59290
|
symbol: strategy.symbol,
|
|
59252
|
-
|
|
59253
|
-
risk: strategy.risk,
|
|
59254
|
-
resistance: strategy.resistance,
|
|
59255
|
-
support: strategy.support,
|
|
59256
|
-
account: strategy.expand.account,
|
|
59257
|
-
reward_factor: strategy.reward_factor
|
|
59291
|
+
account: strategy.expand.account
|
|
59258
59292
|
});
|
|
59259
59293
|
}
|
|
59260
59294
|
}
|
|
59261
59295
|
async profitWithinGapStrategy(payload) {
|
|
59262
|
-
const {
|
|
59263
|
-
account,
|
|
59264
|
-
symbol,
|
|
59265
|
-
kind,
|
|
59266
|
-
risk,
|
|
59267
|
-
resistance,
|
|
59268
|
-
support,
|
|
59269
|
-
reward_factor = 1
|
|
59270
|
-
} = payload;
|
|
59296
|
+
const { account, symbol } = payload;
|
|
59271
59297
|
const exchange_account = await this.getExchangeAccount(account);
|
|
59272
59298
|
const result = await exchange_account.profitWithinGapStrategy({
|
|
59273
|
-
symbol
|
|
59274
|
-
kind,
|
|
59275
|
-
risk,
|
|
59276
|
-
resistance,
|
|
59277
|
-
support,
|
|
59278
|
-
reward_factor
|
|
59299
|
+
symbol
|
|
59279
59300
|
});
|
|
59280
59301
|
return result;
|
|
59281
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
|
@@ -53298,7 +53298,8 @@ function get_app_config_and_max_size(config2, payload) {
|
|
|
53298
53298
|
budget: 0,
|
|
53299
53299
|
price_places: config2.price_places,
|
|
53300
53300
|
decimal_places: config2.decimal_places,
|
|
53301
|
-
min_profit: config2.profit_percent * config2.profit / 100
|
|
53301
|
+
min_profit: config2.profit_percent * config2.profit / 100,
|
|
53302
|
+
symbol: config2.symbol
|
|
53302
53303
|
};
|
|
53303
53304
|
const initialResult = sortedBuildConfig(app_config, {
|
|
53304
53305
|
entry: app_config.entry,
|
|
@@ -58694,15 +58695,64 @@ class ExchangeAccount {
|
|
|
58694
58695
|
});
|
|
58695
58696
|
}
|
|
58696
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
|
+
}
|
|
58697
58726
|
async profitWithinGapStrategy(payload) {
|
|
58698
|
-
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({
|
|
58699
58735
|
symbol,
|
|
58700
|
-
|
|
58701
|
-
|
|
58702
|
-
|
|
58703
|
-
|
|
58704
|
-
|
|
58705
|
-
|
|
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
|
+
}
|
|
58706
58756
|
console.log("Getting entry and stop for ", symbol, kind);
|
|
58707
58757
|
const entry = kind === "long" ? resistance : support;
|
|
58708
58758
|
const stop = kind === "long" ? support : resistance;
|
|
@@ -58764,17 +58814,6 @@ class ExchangeAccount {
|
|
|
58764
58814
|
...config2,
|
|
58765
58815
|
...data
|
|
58766
58816
|
};
|
|
58767
|
-
console.log("Fetching positions for ", symbol);
|
|
58768
|
-
const positions = await this.syncAccount({
|
|
58769
|
-
symbol,
|
|
58770
|
-
as_view: true
|
|
58771
|
-
});
|
|
58772
|
-
console.log("Getting long and short positions for ", symbol);
|
|
58773
|
-
const long_position = positions.find((k) => k.kind === "long");
|
|
58774
|
-
const short_position = positions.find((k) => k.kind === "short");
|
|
58775
|
-
console.log("Getting focus position for ", symbol, kind);
|
|
58776
|
-
const focus_position = kind === "long" ? long_position : short_position;
|
|
58777
|
-
const reverse_position = kind === "long" ? short_position : long_position;
|
|
58778
58817
|
let reverse_action = null;
|
|
58779
58818
|
let reverse_orders_to_buy = [];
|
|
58780
58819
|
let reverse_config = null;
|
|
@@ -58856,7 +58895,7 @@ class ExchangeAccount {
|
|
|
58856
58895
|
const max_size = app_config.max_size * 0.98;
|
|
58857
58896
|
if (reverse_config.threshold_qty !== max_size) {
|
|
58858
58897
|
await this.app_db.updateScheduledTrade(reverse_config.id, {
|
|
58859
|
-
follow:
|
|
58898
|
+
follow: strategy.follow,
|
|
58860
58899
|
threshold_qty: max_size
|
|
58861
58900
|
});
|
|
58862
58901
|
}
|
|
@@ -59204,33 +59243,15 @@ class App {
|
|
|
59204
59243
|
console.log("Running strategy for ", strategy.symbol, "for account", strategy.expand.account.owner, strategy.expand.account.exchange);
|
|
59205
59244
|
await callback({
|
|
59206
59245
|
symbol: strategy.symbol,
|
|
59207
|
-
|
|
59208
|
-
risk: strategy.risk,
|
|
59209
|
-
resistance: strategy.resistance,
|
|
59210
|
-
support: strategy.support,
|
|
59211
|
-
account: strategy.expand.account,
|
|
59212
|
-
reward_factor: strategy.reward_factor
|
|
59246
|
+
account: strategy.expand.account
|
|
59213
59247
|
});
|
|
59214
59248
|
}
|
|
59215
59249
|
}
|
|
59216
59250
|
async profitWithinGapStrategy(payload) {
|
|
59217
|
-
const {
|
|
59218
|
-
account,
|
|
59219
|
-
symbol,
|
|
59220
|
-
kind,
|
|
59221
|
-
risk,
|
|
59222
|
-
resistance,
|
|
59223
|
-
support,
|
|
59224
|
-
reward_factor = 1
|
|
59225
|
-
} = payload;
|
|
59251
|
+
const { account, symbol } = payload;
|
|
59226
59252
|
const exchange_account = await this.getExchangeAccount(account);
|
|
59227
59253
|
const result = await exchange_account.profitWithinGapStrategy({
|
|
59228
|
-
symbol
|
|
59229
|
-
kind,
|
|
59230
|
-
risk,
|
|
59231
|
-
resistance,
|
|
59232
|
-
support,
|
|
59233
|
-
reward_factor
|
|
59254
|
+
symbol
|
|
59234
59255
|
});
|
|
59235
59256
|
return result;
|
|
59236
59257
|
}
|
package/dist/mcp-server.cjs
CHANGED
|
@@ -60034,7 +60034,8 @@ function get_app_config_and_max_size(config2, payload) {
|
|
|
60034
60034
|
budget: 0,
|
|
60035
60035
|
price_places: config2.price_places,
|
|
60036
60036
|
decimal_places: config2.decimal_places,
|
|
60037
|
-
min_profit: config2.profit_percent * config2.profit / 100
|
|
60037
|
+
min_profit: config2.profit_percent * config2.profit / 100,
|
|
60038
|
+
symbol: config2.symbol
|
|
60038
60039
|
};
|
|
60039
60040
|
const initialResult = sortedBuildConfig(app_config, {
|
|
60040
60041
|
entry: app_config.entry,
|
|
@@ -65430,15 +65431,64 @@ class ExchangeAccount {
|
|
|
65430
65431
|
});
|
|
65431
65432
|
}
|
|
65432
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
|
+
}
|
|
65433
65462
|
async profitWithinGapStrategy(payload) {
|
|
65434
|
-
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({
|
|
65435
65471
|
symbol,
|
|
65436
|
-
|
|
65437
|
-
|
|
65438
|
-
|
|
65439
|
-
|
|
65440
|
-
|
|
65441
|
-
|
|
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
|
+
}
|
|
65442
65492
|
console.log("Getting entry and stop for ", symbol, kind);
|
|
65443
65493
|
const entry = kind === "long" ? resistance : support;
|
|
65444
65494
|
const stop = kind === "long" ? support : resistance;
|
|
@@ -65500,17 +65550,6 @@ class ExchangeAccount {
|
|
|
65500
65550
|
...config2,
|
|
65501
65551
|
...data
|
|
65502
65552
|
};
|
|
65503
|
-
console.log("Fetching positions for ", symbol);
|
|
65504
|
-
const positions = await this.syncAccount({
|
|
65505
|
-
symbol,
|
|
65506
|
-
as_view: true
|
|
65507
|
-
});
|
|
65508
|
-
console.log("Getting long and short positions for ", symbol);
|
|
65509
|
-
const long_position = positions.find((k) => k.kind === "long");
|
|
65510
|
-
const short_position = positions.find((k) => k.kind === "short");
|
|
65511
|
-
console.log("Getting focus position for ", symbol, kind);
|
|
65512
|
-
const focus_position = kind === "long" ? long_position : short_position;
|
|
65513
|
-
const reverse_position = kind === "long" ? short_position : long_position;
|
|
65514
65553
|
let reverse_action = null;
|
|
65515
65554
|
let reverse_orders_to_buy = [];
|
|
65516
65555
|
let reverse_config = null;
|
|
@@ -65592,7 +65631,7 @@ class ExchangeAccount {
|
|
|
65592
65631
|
const max_size = app_config.max_size * 0.98;
|
|
65593
65632
|
if (reverse_config.threshold_qty !== max_size) {
|
|
65594
65633
|
await this.app_db.updateScheduledTrade(reverse_config.id, {
|
|
65595
|
-
follow:
|
|
65634
|
+
follow: strategy.follow,
|
|
65596
65635
|
threshold_qty: max_size
|
|
65597
65636
|
});
|
|
65598
65637
|
}
|
|
@@ -65940,33 +65979,15 @@ class App {
|
|
|
65940
65979
|
console.log("Running strategy for ", strategy.symbol, "for account", strategy.expand.account.owner, strategy.expand.account.exchange);
|
|
65941
65980
|
await callback({
|
|
65942
65981
|
symbol: strategy.symbol,
|
|
65943
|
-
|
|
65944
|
-
risk: strategy.risk,
|
|
65945
|
-
resistance: strategy.resistance,
|
|
65946
|
-
support: strategy.support,
|
|
65947
|
-
account: strategy.expand.account,
|
|
65948
|
-
reward_factor: strategy.reward_factor
|
|
65982
|
+
account: strategy.expand.account
|
|
65949
65983
|
});
|
|
65950
65984
|
}
|
|
65951
65985
|
}
|
|
65952
65986
|
async profitWithinGapStrategy(payload) {
|
|
65953
|
-
const {
|
|
65954
|
-
account,
|
|
65955
|
-
symbol,
|
|
65956
|
-
kind,
|
|
65957
|
-
risk,
|
|
65958
|
-
resistance,
|
|
65959
|
-
support,
|
|
65960
|
-
reward_factor = 1
|
|
65961
|
-
} = payload;
|
|
65987
|
+
const { account, symbol } = payload;
|
|
65962
65988
|
const exchange_account = await this.getExchangeAccount(account);
|
|
65963
65989
|
const result = await exchange_account.profitWithinGapStrategy({
|
|
65964
|
-
symbol
|
|
65965
|
-
kind,
|
|
65966
|
-
risk,
|
|
65967
|
-
resistance,
|
|
65968
|
-
support,
|
|
65969
|
-
reward_factor
|
|
65990
|
+
symbol
|
|
65970
65991
|
});
|
|
65971
65992
|
return result;
|
|
65972
65993
|
}
|
package/dist/mcp-server.js
CHANGED
|
@@ -60011,7 +60011,8 @@ function get_app_config_and_max_size(config2, payload) {
|
|
|
60011
60011
|
budget: 0,
|
|
60012
60012
|
price_places: config2.price_places,
|
|
60013
60013
|
decimal_places: config2.decimal_places,
|
|
60014
|
-
min_profit: config2.profit_percent * config2.profit / 100
|
|
60014
|
+
min_profit: config2.profit_percent * config2.profit / 100,
|
|
60015
|
+
symbol: config2.symbol
|
|
60015
60016
|
};
|
|
60016
60017
|
const initialResult = sortedBuildConfig(app_config, {
|
|
60017
60018
|
entry: app_config.entry,
|
|
@@ -65407,15 +65408,64 @@ class ExchangeAccount {
|
|
|
65407
65408
|
});
|
|
65408
65409
|
}
|
|
65409
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
|
+
}
|
|
65410
65439
|
async profitWithinGapStrategy(payload) {
|
|
65411
|
-
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({
|
|
65412
65448
|
symbol,
|
|
65413
|
-
|
|
65414
|
-
|
|
65415
|
-
|
|
65416
|
-
|
|
65417
|
-
|
|
65418
|
-
|
|
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
|
+
}
|
|
65419
65469
|
console.log("Getting entry and stop for ", symbol, kind);
|
|
65420
65470
|
const entry = kind === "long" ? resistance : support;
|
|
65421
65471
|
const stop = kind === "long" ? support : resistance;
|
|
@@ -65477,17 +65527,6 @@ class ExchangeAccount {
|
|
|
65477
65527
|
...config2,
|
|
65478
65528
|
...data
|
|
65479
65529
|
};
|
|
65480
|
-
console.log("Fetching positions for ", symbol);
|
|
65481
|
-
const positions = await this.syncAccount({
|
|
65482
|
-
symbol,
|
|
65483
|
-
as_view: true
|
|
65484
|
-
});
|
|
65485
|
-
console.log("Getting long and short positions for ", symbol);
|
|
65486
|
-
const long_position = positions.find((k) => k.kind === "long");
|
|
65487
|
-
const short_position = positions.find((k) => k.kind === "short");
|
|
65488
|
-
console.log("Getting focus position for ", symbol, kind);
|
|
65489
|
-
const focus_position = kind === "long" ? long_position : short_position;
|
|
65490
|
-
const reverse_position = kind === "long" ? short_position : long_position;
|
|
65491
65530
|
let reverse_action = null;
|
|
65492
65531
|
let reverse_orders_to_buy = [];
|
|
65493
65532
|
let reverse_config = null;
|
|
@@ -65569,7 +65608,7 @@ class ExchangeAccount {
|
|
|
65569
65608
|
const max_size = app_config.max_size * 0.98;
|
|
65570
65609
|
if (reverse_config.threshold_qty !== max_size) {
|
|
65571
65610
|
await this.app_db.updateScheduledTrade(reverse_config.id, {
|
|
65572
|
-
follow:
|
|
65611
|
+
follow: strategy.follow,
|
|
65573
65612
|
threshold_qty: max_size
|
|
65574
65613
|
});
|
|
65575
65614
|
}
|
|
@@ -65917,33 +65956,15 @@ class App {
|
|
|
65917
65956
|
console.log("Running strategy for ", strategy.symbol, "for account", strategy.expand.account.owner, strategy.expand.account.exchange);
|
|
65918
65957
|
await callback({
|
|
65919
65958
|
symbol: strategy.symbol,
|
|
65920
|
-
|
|
65921
|
-
risk: strategy.risk,
|
|
65922
|
-
resistance: strategy.resistance,
|
|
65923
|
-
support: strategy.support,
|
|
65924
|
-
account: strategy.expand.account,
|
|
65925
|
-
reward_factor: strategy.reward_factor
|
|
65959
|
+
account: strategy.expand.account
|
|
65926
65960
|
});
|
|
65927
65961
|
}
|
|
65928
65962
|
}
|
|
65929
65963
|
async profitWithinGapStrategy(payload) {
|
|
65930
|
-
const {
|
|
65931
|
-
account,
|
|
65932
|
-
symbol,
|
|
65933
|
-
kind,
|
|
65934
|
-
risk,
|
|
65935
|
-
resistance,
|
|
65936
|
-
support,
|
|
65937
|
-
reward_factor = 1
|
|
65938
|
-
} = payload;
|
|
65964
|
+
const { account, symbol } = payload;
|
|
65939
65965
|
const exchange_account = await this.getExchangeAccount(account);
|
|
65940
65966
|
const result = await exchange_account.profitWithinGapStrategy({
|
|
65941
|
-
symbol
|
|
65942
|
-
kind,
|
|
65943
|
-
risk,
|
|
65944
|
-
resistance,
|
|
65945
|
-
support,
|
|
65946
|
-
reward_factor
|
|
65967
|
+
symbol
|
|
65947
65968
|
});
|
|
65948
65969
|
return result;
|
|
65949
65970
|
}
|