@gbozee/ultimate 0.0.2-91 → 0.0.2-94
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 +64 -41
- package/dist/index.d.ts +35 -17
- package/dist/index.js +64 -41
- package/dist/mcp-server.cjs +64 -41
- package/dist/mcp-server.js +64 -41
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -51603,7 +51603,7 @@ class AppDatabase {
|
|
|
51603
51603
|
table: "positions_view",
|
|
51604
51604
|
params: {
|
|
51605
51605
|
filter: `symbol:lower="${symbol.toLowerCase()}" && account:lower="${account.owner.toLowerCase()} ${account.exchange.toLowerCase()}"`,
|
|
51606
|
-
expand: "config"
|
|
51606
|
+
expand: "config, account_strategy, p_account"
|
|
51607
51607
|
}
|
|
51608
51608
|
} : {
|
|
51609
51609
|
table: "positions",
|
|
@@ -58740,15 +58740,67 @@ 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
|
+
console.log("Fetching positions for ", symbol);
|
|
58775
|
+
const positions = await this.syncAccount({
|
|
58745
58776
|
symbol,
|
|
58746
|
-
|
|
58747
|
-
|
|
58748
|
-
|
|
58749
|
-
|
|
58750
|
-
|
|
58751
|
-
}
|
|
58777
|
+
as_view: true
|
|
58778
|
+
});
|
|
58779
|
+
const focus_position = positions.find((k) => k.expand?.account_strategy);
|
|
58780
|
+
if (!focus_position) {
|
|
58781
|
+
return;
|
|
58782
|
+
}
|
|
58783
|
+
const strategy = focus_position?.expand?.account_strategy;
|
|
58784
|
+
if (!strategy) {
|
|
58785
|
+
return;
|
|
58786
|
+
}
|
|
58787
|
+
const risk = strategy.risk;
|
|
58788
|
+
const kind = strategy.kind;
|
|
58789
|
+
const support = strategy.support;
|
|
58790
|
+
const resistance = strategy.resistance;
|
|
58791
|
+
console.log("Getting long and short positions for ", symbol);
|
|
58792
|
+
const long_position = positions.find((k) => k.kind === "long");
|
|
58793
|
+
const short_position = positions.find((k) => k.kind === "short");
|
|
58794
|
+
console.log("Getting focus position for ", symbol, kind);
|
|
58795
|
+
const reverse_position = kind === "long" ? short_position : long_position;
|
|
58796
|
+
if (strategy.max_reward_factor === 0) {
|
|
58797
|
+
reward_factor = strategy.reward_factor;
|
|
58798
|
+
}
|
|
58799
|
+
if (focus_position.avg_qty >= focus_position.quantity && strategy.max_reward_factor) {
|
|
58800
|
+
reward_factor = to_f2(focus_position.quantity * strategy.max_reward_factor / focus_position.avg_qty, "%.2f");
|
|
58801
|
+
} else {
|
|
58802
|
+
reward_factor = strategy.reward_factor;
|
|
58803
|
+
}
|
|
58752
58804
|
console.log("Getting entry and stop for ", symbol, kind);
|
|
58753
58805
|
const entry = kind === "long" ? resistance : support;
|
|
58754
58806
|
const stop = kind === "long" ? support : resistance;
|
|
@@ -58810,17 +58862,6 @@ class ExchangeAccount {
|
|
|
58810
58862
|
...config2,
|
|
58811
58863
|
...data
|
|
58812
58864
|
};
|
|
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
58865
|
let reverse_action = null;
|
|
58825
58866
|
let reverse_orders_to_buy = [];
|
|
58826
58867
|
let reverse_config = null;
|
|
@@ -58902,7 +58943,7 @@ class ExchangeAccount {
|
|
|
58902
58943
|
const max_size = app_config.max_size * 0.98;
|
|
58903
58944
|
if (reverse_config.threshold_qty !== max_size) {
|
|
58904
58945
|
await this.app_db.updateScheduledTrade(reverse_config.id, {
|
|
58905
|
-
follow:
|
|
58946
|
+
follow: strategy.follow,
|
|
58906
58947
|
threshold_qty: max_size
|
|
58907
58948
|
});
|
|
58908
58949
|
}
|
|
@@ -59250,33 +59291,15 @@ class App {
|
|
|
59250
59291
|
console.log("Running strategy for ", strategy.symbol, "for account", strategy.expand.account.owner, strategy.expand.account.exchange);
|
|
59251
59292
|
await callback({
|
|
59252
59293
|
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
|
|
59294
|
+
account: strategy.expand.account
|
|
59259
59295
|
});
|
|
59260
59296
|
}
|
|
59261
59297
|
}
|
|
59262
59298
|
async profitWithinGapStrategy(payload) {
|
|
59263
|
-
const {
|
|
59264
|
-
account,
|
|
59265
|
-
symbol,
|
|
59266
|
-
kind,
|
|
59267
|
-
risk,
|
|
59268
|
-
resistance,
|
|
59269
|
-
support,
|
|
59270
|
-
reward_factor = 1
|
|
59271
|
-
} = payload;
|
|
59299
|
+
const { account, symbol } = payload;
|
|
59272
59300
|
const exchange_account = await this.getExchangeAccount(account);
|
|
59273
59301
|
const result = await exchange_account.profitWithinGapStrategy({
|
|
59274
|
-
symbol
|
|
59275
|
-
kind,
|
|
59276
|
-
risk,
|
|
59277
|
-
resistance,
|
|
59278
|
-
support,
|
|
59279
|
-
reward_factor
|
|
59302
|
+
symbol
|
|
59280
59303
|
});
|
|
59281
59304
|
return result;
|
|
59282
59305
|
}
|
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: {
|
|
@@ -1718,8 +1728,16 @@ declare class ExchangeAccount$1 {
|
|
|
1718
1728
|
};
|
|
1719
1729
|
reverse_orders_to_buy: any;
|
|
1720
1730
|
positions: {
|
|
1721
|
-
long: PositionsView
|
|
1722
|
-
|
|
1731
|
+
long: PositionsView & {
|
|
1732
|
+
expand?: {
|
|
1733
|
+
account_strategy?: AccountStrategy;
|
|
1734
|
+
};
|
|
1735
|
+
};
|
|
1736
|
+
short: PositionsView & {
|
|
1737
|
+
expand?: {
|
|
1738
|
+
account_strategy?: AccountStrategy;
|
|
1739
|
+
};
|
|
1740
|
+
};
|
|
1723
1741
|
};
|
|
1724
1742
|
orders_to_place: any;
|
|
1725
1743
|
config_details: {
|
|
@@ -1891,18 +1909,10 @@ declare class App {
|
|
|
1891
1909
|
runDbStrategyAccounts(callback: (params: {
|
|
1892
1910
|
symbol: string;
|
|
1893
1911
|
account: ExchangeType;
|
|
1894
|
-
risk: number;
|
|
1895
|
-
resistance: number;
|
|
1896
|
-
support: number;
|
|
1897
1912
|
}) => Promise<any>): Promise<void>;
|
|
1898
1913
|
profitWithinGapStrategy(payload: {
|
|
1899
1914
|
account: ExchangeType;
|
|
1900
1915
|
symbol: string;
|
|
1901
|
-
kind: "long" | "short";
|
|
1902
|
-
risk: number;
|
|
1903
|
-
resistance: number;
|
|
1904
|
-
support: number;
|
|
1905
|
-
reward_factor?: number;
|
|
1906
1916
|
}): Promise<{
|
|
1907
1917
|
reverse_config: any;
|
|
1908
1918
|
reverse_action: {
|
|
@@ -1940,8 +1950,16 @@ declare class App {
|
|
|
1940
1950
|
};
|
|
1941
1951
|
reverse_orders_to_buy: any;
|
|
1942
1952
|
positions: {
|
|
1943
|
-
long: PositionsView
|
|
1944
|
-
|
|
1953
|
+
long: PositionsView & {
|
|
1954
|
+
expand?: {
|
|
1955
|
+
account_strategy?: AccountStrategy;
|
|
1956
|
+
};
|
|
1957
|
+
};
|
|
1958
|
+
short: PositionsView & {
|
|
1959
|
+
expand?: {
|
|
1960
|
+
account_strategy?: AccountStrategy;
|
|
1961
|
+
};
|
|
1962
|
+
};
|
|
1945
1963
|
};
|
|
1946
1964
|
orders_to_place: any;
|
|
1947
1965
|
config_details: {
|
package/dist/index.js
CHANGED
|
@@ -51558,7 +51558,7 @@ class AppDatabase {
|
|
|
51558
51558
|
table: "positions_view",
|
|
51559
51559
|
params: {
|
|
51560
51560
|
filter: `symbol:lower="${symbol.toLowerCase()}" && account:lower="${account.owner.toLowerCase()} ${account.exchange.toLowerCase()}"`,
|
|
51561
|
-
expand: "config"
|
|
51561
|
+
expand: "config, account_strategy, p_account"
|
|
51562
51562
|
}
|
|
51563
51563
|
} : {
|
|
51564
51564
|
table: "positions",
|
|
@@ -58695,15 +58695,67 @@ 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
|
+
console.log("Fetching positions for ", symbol);
|
|
58730
|
+
const positions = await this.syncAccount({
|
|
58700
58731
|
symbol,
|
|
58701
|
-
|
|
58702
|
-
|
|
58703
|
-
|
|
58704
|
-
|
|
58705
|
-
|
|
58706
|
-
}
|
|
58732
|
+
as_view: true
|
|
58733
|
+
});
|
|
58734
|
+
const focus_position = positions.find((k) => k.expand?.account_strategy);
|
|
58735
|
+
if (!focus_position) {
|
|
58736
|
+
return;
|
|
58737
|
+
}
|
|
58738
|
+
const strategy = focus_position?.expand?.account_strategy;
|
|
58739
|
+
if (!strategy) {
|
|
58740
|
+
return;
|
|
58741
|
+
}
|
|
58742
|
+
const risk = strategy.risk;
|
|
58743
|
+
const kind = strategy.kind;
|
|
58744
|
+
const support = strategy.support;
|
|
58745
|
+
const resistance = strategy.resistance;
|
|
58746
|
+
console.log("Getting long and short positions for ", symbol);
|
|
58747
|
+
const long_position = positions.find((k) => k.kind === "long");
|
|
58748
|
+
const short_position = positions.find((k) => k.kind === "short");
|
|
58749
|
+
console.log("Getting focus position for ", symbol, kind);
|
|
58750
|
+
const reverse_position = kind === "long" ? short_position : long_position;
|
|
58751
|
+
if (strategy.max_reward_factor === 0) {
|
|
58752
|
+
reward_factor = strategy.reward_factor;
|
|
58753
|
+
}
|
|
58754
|
+
if (focus_position.avg_qty >= focus_position.quantity && strategy.max_reward_factor) {
|
|
58755
|
+
reward_factor = to_f2(focus_position.quantity * strategy.max_reward_factor / focus_position.avg_qty, "%.2f");
|
|
58756
|
+
} else {
|
|
58757
|
+
reward_factor = strategy.reward_factor;
|
|
58758
|
+
}
|
|
58707
58759
|
console.log("Getting entry and stop for ", symbol, kind);
|
|
58708
58760
|
const entry = kind === "long" ? resistance : support;
|
|
58709
58761
|
const stop = kind === "long" ? support : resistance;
|
|
@@ -58765,17 +58817,6 @@ class ExchangeAccount {
|
|
|
58765
58817
|
...config2,
|
|
58766
58818
|
...data
|
|
58767
58819
|
};
|
|
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
58820
|
let reverse_action = null;
|
|
58780
58821
|
let reverse_orders_to_buy = [];
|
|
58781
58822
|
let reverse_config = null;
|
|
@@ -58857,7 +58898,7 @@ class ExchangeAccount {
|
|
|
58857
58898
|
const max_size = app_config.max_size * 0.98;
|
|
58858
58899
|
if (reverse_config.threshold_qty !== max_size) {
|
|
58859
58900
|
await this.app_db.updateScheduledTrade(reverse_config.id, {
|
|
58860
|
-
follow:
|
|
58901
|
+
follow: strategy.follow,
|
|
58861
58902
|
threshold_qty: max_size
|
|
58862
58903
|
});
|
|
58863
58904
|
}
|
|
@@ -59205,33 +59246,15 @@ class App {
|
|
|
59205
59246
|
console.log("Running strategy for ", strategy.symbol, "for account", strategy.expand.account.owner, strategy.expand.account.exchange);
|
|
59206
59247
|
await callback({
|
|
59207
59248
|
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
|
|
59249
|
+
account: strategy.expand.account
|
|
59214
59250
|
});
|
|
59215
59251
|
}
|
|
59216
59252
|
}
|
|
59217
59253
|
async profitWithinGapStrategy(payload) {
|
|
59218
|
-
const {
|
|
59219
|
-
account,
|
|
59220
|
-
symbol,
|
|
59221
|
-
kind,
|
|
59222
|
-
risk,
|
|
59223
|
-
resistance,
|
|
59224
|
-
support,
|
|
59225
|
-
reward_factor = 1
|
|
59226
|
-
} = payload;
|
|
59254
|
+
const { account, symbol } = payload;
|
|
59227
59255
|
const exchange_account = await this.getExchangeAccount(account);
|
|
59228
59256
|
const result = await exchange_account.profitWithinGapStrategy({
|
|
59229
|
-
symbol
|
|
59230
|
-
kind,
|
|
59231
|
-
risk,
|
|
59232
|
-
resistance,
|
|
59233
|
-
support,
|
|
59234
|
-
reward_factor
|
|
59257
|
+
symbol
|
|
59235
59258
|
});
|
|
59236
59259
|
return result;
|
|
59237
59260
|
}
|
package/dist/mcp-server.cjs
CHANGED
|
@@ -58314,7 +58314,7 @@ class AppDatabase {
|
|
|
58314
58314
|
table: "positions_view",
|
|
58315
58315
|
params: {
|
|
58316
58316
|
filter: `symbol:lower="${symbol.toLowerCase()}" && account:lower="${account.owner.toLowerCase()} ${account.exchange.toLowerCase()}"`,
|
|
58317
|
-
expand: "config"
|
|
58317
|
+
expand: "config, account_strategy, p_account"
|
|
58318
58318
|
}
|
|
58319
58319
|
} : {
|
|
58320
58320
|
table: "positions",
|
|
@@ -65431,15 +65431,67 @@ 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
|
+
console.log("Fetching positions for ", symbol);
|
|
65466
|
+
const positions = await this.syncAccount({
|
|
65436
65467
|
symbol,
|
|
65437
|
-
|
|
65438
|
-
|
|
65439
|
-
|
|
65440
|
-
|
|
65441
|
-
|
|
65442
|
-
}
|
|
65468
|
+
as_view: true
|
|
65469
|
+
});
|
|
65470
|
+
const focus_position = positions.find((k) => k.expand?.account_strategy);
|
|
65471
|
+
if (!focus_position) {
|
|
65472
|
+
return;
|
|
65473
|
+
}
|
|
65474
|
+
const strategy = focus_position?.expand?.account_strategy;
|
|
65475
|
+
if (!strategy) {
|
|
65476
|
+
return;
|
|
65477
|
+
}
|
|
65478
|
+
const risk = strategy.risk;
|
|
65479
|
+
const kind = strategy.kind;
|
|
65480
|
+
const support = strategy.support;
|
|
65481
|
+
const resistance = strategy.resistance;
|
|
65482
|
+
console.log("Getting long and short positions for ", symbol);
|
|
65483
|
+
const long_position = positions.find((k) => k.kind === "long");
|
|
65484
|
+
const short_position = positions.find((k) => k.kind === "short");
|
|
65485
|
+
console.log("Getting focus position for ", symbol, kind);
|
|
65486
|
+
const reverse_position = kind === "long" ? short_position : long_position;
|
|
65487
|
+
if (strategy.max_reward_factor === 0) {
|
|
65488
|
+
reward_factor = strategy.reward_factor;
|
|
65489
|
+
}
|
|
65490
|
+
if (focus_position.avg_qty >= focus_position.quantity && strategy.max_reward_factor) {
|
|
65491
|
+
reward_factor = to_f2(focus_position.quantity * strategy.max_reward_factor / focus_position.avg_qty, "%.2f");
|
|
65492
|
+
} else {
|
|
65493
|
+
reward_factor = strategy.reward_factor;
|
|
65494
|
+
}
|
|
65443
65495
|
console.log("Getting entry and stop for ", symbol, kind);
|
|
65444
65496
|
const entry = kind === "long" ? resistance : support;
|
|
65445
65497
|
const stop = kind === "long" ? support : resistance;
|
|
@@ -65501,17 +65553,6 @@ class ExchangeAccount {
|
|
|
65501
65553
|
...config2,
|
|
65502
65554
|
...data
|
|
65503
65555
|
};
|
|
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
65556
|
let reverse_action = null;
|
|
65516
65557
|
let reverse_orders_to_buy = [];
|
|
65517
65558
|
let reverse_config = null;
|
|
@@ -65593,7 +65634,7 @@ class ExchangeAccount {
|
|
|
65593
65634
|
const max_size = app_config.max_size * 0.98;
|
|
65594
65635
|
if (reverse_config.threshold_qty !== max_size) {
|
|
65595
65636
|
await this.app_db.updateScheduledTrade(reverse_config.id, {
|
|
65596
|
-
follow:
|
|
65637
|
+
follow: strategy.follow,
|
|
65597
65638
|
threshold_qty: max_size
|
|
65598
65639
|
});
|
|
65599
65640
|
}
|
|
@@ -65941,33 +65982,15 @@ class App {
|
|
|
65941
65982
|
console.log("Running strategy for ", strategy.symbol, "for account", strategy.expand.account.owner, strategy.expand.account.exchange);
|
|
65942
65983
|
await callback({
|
|
65943
65984
|
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
|
|
65985
|
+
account: strategy.expand.account
|
|
65950
65986
|
});
|
|
65951
65987
|
}
|
|
65952
65988
|
}
|
|
65953
65989
|
async profitWithinGapStrategy(payload) {
|
|
65954
|
-
const {
|
|
65955
|
-
account,
|
|
65956
|
-
symbol,
|
|
65957
|
-
kind,
|
|
65958
|
-
risk,
|
|
65959
|
-
resistance,
|
|
65960
|
-
support,
|
|
65961
|
-
reward_factor = 1
|
|
65962
|
-
} = payload;
|
|
65990
|
+
const { account, symbol } = payload;
|
|
65963
65991
|
const exchange_account = await this.getExchangeAccount(account);
|
|
65964
65992
|
const result = await exchange_account.profitWithinGapStrategy({
|
|
65965
|
-
symbol
|
|
65966
|
-
kind,
|
|
65967
|
-
risk,
|
|
65968
|
-
resistance,
|
|
65969
|
-
support,
|
|
65970
|
-
reward_factor
|
|
65993
|
+
symbol
|
|
65971
65994
|
});
|
|
65972
65995
|
return result;
|
|
65973
65996
|
}
|
package/dist/mcp-server.js
CHANGED
|
@@ -58291,7 +58291,7 @@ class AppDatabase {
|
|
|
58291
58291
|
table: "positions_view",
|
|
58292
58292
|
params: {
|
|
58293
58293
|
filter: `symbol:lower="${symbol.toLowerCase()}" && account:lower="${account.owner.toLowerCase()} ${account.exchange.toLowerCase()}"`,
|
|
58294
|
-
expand: "config"
|
|
58294
|
+
expand: "config, account_strategy, p_account"
|
|
58295
58295
|
}
|
|
58296
58296
|
} : {
|
|
58297
58297
|
table: "positions",
|
|
@@ -65408,15 +65408,67 @@ 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
|
+
console.log("Fetching positions for ", symbol);
|
|
65443
|
+
const positions = await this.syncAccount({
|
|
65413
65444
|
symbol,
|
|
65414
|
-
|
|
65415
|
-
|
|
65416
|
-
|
|
65417
|
-
|
|
65418
|
-
|
|
65419
|
-
}
|
|
65445
|
+
as_view: true
|
|
65446
|
+
});
|
|
65447
|
+
const focus_position = positions.find((k) => k.expand?.account_strategy);
|
|
65448
|
+
if (!focus_position) {
|
|
65449
|
+
return;
|
|
65450
|
+
}
|
|
65451
|
+
const strategy = focus_position?.expand?.account_strategy;
|
|
65452
|
+
if (!strategy) {
|
|
65453
|
+
return;
|
|
65454
|
+
}
|
|
65455
|
+
const risk = strategy.risk;
|
|
65456
|
+
const kind = strategy.kind;
|
|
65457
|
+
const support = strategy.support;
|
|
65458
|
+
const resistance = strategy.resistance;
|
|
65459
|
+
console.log("Getting long and short positions for ", symbol);
|
|
65460
|
+
const long_position = positions.find((k) => k.kind === "long");
|
|
65461
|
+
const short_position = positions.find((k) => k.kind === "short");
|
|
65462
|
+
console.log("Getting focus position for ", symbol, kind);
|
|
65463
|
+
const reverse_position = kind === "long" ? short_position : long_position;
|
|
65464
|
+
if (strategy.max_reward_factor === 0) {
|
|
65465
|
+
reward_factor = strategy.reward_factor;
|
|
65466
|
+
}
|
|
65467
|
+
if (focus_position.avg_qty >= focus_position.quantity && strategy.max_reward_factor) {
|
|
65468
|
+
reward_factor = to_f2(focus_position.quantity * strategy.max_reward_factor / focus_position.avg_qty, "%.2f");
|
|
65469
|
+
} else {
|
|
65470
|
+
reward_factor = strategy.reward_factor;
|
|
65471
|
+
}
|
|
65420
65472
|
console.log("Getting entry and stop for ", symbol, kind);
|
|
65421
65473
|
const entry = kind === "long" ? resistance : support;
|
|
65422
65474
|
const stop = kind === "long" ? support : resistance;
|
|
@@ -65478,17 +65530,6 @@ class ExchangeAccount {
|
|
|
65478
65530
|
...config2,
|
|
65479
65531
|
...data
|
|
65480
65532
|
};
|
|
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
65533
|
let reverse_action = null;
|
|
65493
65534
|
let reverse_orders_to_buy = [];
|
|
65494
65535
|
let reverse_config = null;
|
|
@@ -65570,7 +65611,7 @@ class ExchangeAccount {
|
|
|
65570
65611
|
const max_size = app_config.max_size * 0.98;
|
|
65571
65612
|
if (reverse_config.threshold_qty !== max_size) {
|
|
65572
65613
|
await this.app_db.updateScheduledTrade(reverse_config.id, {
|
|
65573
|
-
follow:
|
|
65614
|
+
follow: strategy.follow,
|
|
65574
65615
|
threshold_qty: max_size
|
|
65575
65616
|
});
|
|
65576
65617
|
}
|
|
@@ -65918,33 +65959,15 @@ class App {
|
|
|
65918
65959
|
console.log("Running strategy for ", strategy.symbol, "for account", strategy.expand.account.owner, strategy.expand.account.exchange);
|
|
65919
65960
|
await callback({
|
|
65920
65961
|
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
|
|
65962
|
+
account: strategy.expand.account
|
|
65927
65963
|
});
|
|
65928
65964
|
}
|
|
65929
65965
|
}
|
|
65930
65966
|
async profitWithinGapStrategy(payload) {
|
|
65931
|
-
const {
|
|
65932
|
-
account,
|
|
65933
|
-
symbol,
|
|
65934
|
-
kind,
|
|
65935
|
-
risk,
|
|
65936
|
-
resistance,
|
|
65937
|
-
support,
|
|
65938
|
-
reward_factor = 1
|
|
65939
|
-
} = payload;
|
|
65967
|
+
const { account, symbol } = payload;
|
|
65940
65968
|
const exchange_account = await this.getExchangeAccount(account);
|
|
65941
65969
|
const result = await exchange_account.profitWithinGapStrategy({
|
|
65942
|
-
symbol
|
|
65943
|
-
kind,
|
|
65944
|
-
risk,
|
|
65945
|
-
resistance,
|
|
65946
|
-
support,
|
|
65947
|
-
reward_factor
|
|
65970
|
+
symbol
|
|
65948
65971
|
});
|
|
65949
65972
|
return result;
|
|
65950
65973
|
}
|