@gbozee/ultimate 0.0.2-78 → 0.0.2-82
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 -13
- package/dist/index.cjs +184 -48
- package/dist/index.d.ts +98 -10
- package/dist/index.js +184 -48
- package/dist/mcp-server.cjs +190 -54
- package/dist/mcp-server.js +190 -54
- package/package.json +1 -1
package/dist/mcp-server.js
CHANGED
|
@@ -58197,6 +58197,18 @@ class AppDatabase {
|
|
|
58197
58197
|
await this.saveCredentials(password, credentials);
|
|
58198
58198
|
}
|
|
58199
58199
|
}
|
|
58200
|
+
async getAccountWithActivePositions() {
|
|
58201
|
+
const positions = await this.pb.collection("positions").getFullList({
|
|
58202
|
+
filter: `quantity > 0`,
|
|
58203
|
+
fields: `account`
|
|
58204
|
+
});
|
|
58205
|
+
const accounts = Array.from(new Set(positions.map((p) => p.account)));
|
|
58206
|
+
const filter = accounts.map((a) => `id = "${a}"`).join(" || ");
|
|
58207
|
+
const account_instances = await this.pb.collection("exchange_accounts").getFullList({
|
|
58208
|
+
filter
|
|
58209
|
+
});
|
|
58210
|
+
return account_instances;
|
|
58211
|
+
}
|
|
58200
58212
|
async getAllSymbolsFromPositions(options) {
|
|
58201
58213
|
const { no_position = false, kind = "long", custom_filter } = options || {};
|
|
58202
58214
|
let filter = custom_filter || (no_position ? `quantity = 0` : undefined);
|
|
@@ -59783,7 +59795,7 @@ class Signal {
|
|
|
59783
59795
|
new_stop
|
|
59784
59796
|
};
|
|
59785
59797
|
});
|
|
59786
|
-
if (greater_than_min_size.length !==
|
|
59798
|
+
if (greater_than_min_size.length !== total_orders.length) {
|
|
59787
59799
|
payload = greater_than_min_size.concat(less_than_min_size);
|
|
59788
59800
|
}
|
|
59789
59801
|
return payload;
|
|
@@ -59943,9 +59955,7 @@ function buildConfig(app_config, {
|
|
|
59943
59955
|
}
|
|
59944
59956
|
const condition = (kind === "long" ? entry > app_config.support : entry >= app_config.support) && stop >= app_config.support * 0.999;
|
|
59945
59957
|
if (kind === "short") {
|
|
59946
|
-
console.log("condition", condition, entry === stop);
|
|
59947
59958
|
}
|
|
59948
|
-
console.log({ entry, support: app_config.support, stop });
|
|
59949
59959
|
const result = entry === stop ? [] : condition ? instance.build_entry({
|
|
59950
59960
|
current_price: entry,
|
|
59951
59961
|
stop_loss: stop,
|
|
@@ -60261,7 +60271,6 @@ function generateOptimumAppConfig(config2, payload, position2) {
|
|
|
60261
60271
|
const tolerance = 0.1;
|
|
60262
60272
|
const max_iterations = 150;
|
|
60263
60273
|
let iterations = 0;
|
|
60264
|
-
console.log(`Starting risk search for ${position2.kind} position. Target Entry: ${position2.entry}, Initial Risk Range: [${low_risk}, ${high_risk}]`);
|
|
60265
60274
|
while (high_risk - low_risk > tolerance && iterations < max_iterations) {
|
|
60266
60275
|
iterations++;
|
|
60267
60276
|
const mid_risk = (low_risk + high_risk) / 2;
|
|
@@ -60307,9 +60316,7 @@ function generateOptimumAppConfig(config2, payload, position2) {
|
|
|
60307
60316
|
price_places: current_app_config.price_places,
|
|
60308
60317
|
decimal_places: current_app_config.decimal_places
|
|
60309
60318
|
});
|
|
60310
|
-
console.log(`Iteration ${iterations}: Risk=${mid_risk.toFixed(2)}, Low=${low_risk.toFixed(2)}, High=${high_risk.toFixed(2)}`);
|
|
60311
60319
|
if (full_trades.length === 0) {
|
|
60312
|
-
console.log(` -> No trades generated by sortedBuildConfig at Risk=${mid_risk.toFixed(2)}. Adjusting high_risk down.`);
|
|
60313
60320
|
high_risk = mid_risk;
|
|
60314
60321
|
continue;
|
|
60315
60322
|
}
|
|
@@ -60322,29 +60329,23 @@ function generateOptimumAppConfig(config2, payload, position2) {
|
|
|
60322
60329
|
existingOrders: []
|
|
60323
60330
|
});
|
|
60324
60331
|
if (trades.length === 0) {
|
|
60325
|
-
console.log(` -> No trades met quantity requirement after filtering at Risk=${mid_risk.toFixed(2)}. Adjusting low_risk up.`);
|
|
60326
60332
|
low_risk = mid_risk;
|
|
60327
60333
|
continue;
|
|
60328
60334
|
}
|
|
60329
60335
|
const last_trade = trades[trades.length - 1];
|
|
60330
60336
|
const last_entry = last_trade.entry;
|
|
60331
|
-
console.log(` -> Last Trade Entry (Filtered): ${last_entry.toFixed(4)}`);
|
|
60332
60337
|
if (position2.kind === "long") {
|
|
60333
60338
|
if (last_entry > position2.entry) {
|
|
60334
|
-
console.log(` -> Constraint VIOLATED (Long): last_entry (${last_entry.toFixed(4)}) > position.entry (${position2.entry.toFixed(4)}). Reducing high_risk.`);
|
|
60335
60339
|
high_risk = mid_risk;
|
|
60336
60340
|
} else {
|
|
60337
|
-
console.log(` -> Constraint MET (Long): last_entry (${last_entry.toFixed(4)}) <= position.entry (${position2.entry.toFixed(4)}). Storing as best, increasing low_risk.`);
|
|
60338
60341
|
best_risk = mid_risk;
|
|
60339
60342
|
best_app_config = current_app_config;
|
|
60340
60343
|
low_risk = mid_risk;
|
|
60341
60344
|
}
|
|
60342
60345
|
} else {
|
|
60343
60346
|
if (last_entry < position2.entry) {
|
|
60344
|
-
console.log(` -> Constraint VIOLATED (Short): last_entry (${last_entry.toFixed(4)}) < position.entry (${position2.entry.toFixed(4)}). Reducing high_risk.`);
|
|
60345
60347
|
high_risk = mid_risk;
|
|
60346
60348
|
} else {
|
|
60347
|
-
console.log(` -> Constraint MET (Short): last_entry (${last_entry.toFixed(4)}) >= position.entry (${position2.entry.toFixed(4)}). Storing as best, increasing low_risk.`);
|
|
60348
60349
|
best_risk = mid_risk;
|
|
60349
60350
|
best_app_config = current_app_config;
|
|
60350
60351
|
low_risk = mid_risk;
|
|
@@ -60582,7 +60583,6 @@ class Strategy {
|
|
|
60582
60583
|
quantity,
|
|
60583
60584
|
kind
|
|
60584
60585
|
};
|
|
60585
|
-
console.log({ second_payload, third_payload });
|
|
60586
60586
|
const app_config = generateOptimumAppConfig(this.config.global_config, second_payload, third_payload);
|
|
60587
60587
|
let entries = [];
|
|
60588
60588
|
let risk_per_trade = this.config.budget;
|
|
@@ -60595,6 +60595,7 @@ class Strategy {
|
|
|
60595
60595
|
if (ignore_entries) {
|
|
60596
60596
|
entries = [];
|
|
60597
60597
|
}
|
|
60598
|
+
console.log({ app_config });
|
|
60598
60599
|
}
|
|
60599
60600
|
const risk = this.to_f(risk_per_trade);
|
|
60600
60601
|
let below_reverse_entries = kind === "long" ? entries.filter((u) => {
|
|
@@ -65328,6 +65329,7 @@ class ExchangeAccount {
|
|
|
65328
65329
|
kind,
|
|
65329
65330
|
place,
|
|
65330
65331
|
tp,
|
|
65332
|
+
limit = true,
|
|
65331
65333
|
raw: _raw,
|
|
65332
65334
|
cancel,
|
|
65333
65335
|
stop,
|
|
@@ -65340,13 +65342,14 @@ class ExchangeAccount {
|
|
|
65340
65342
|
kind
|
|
65341
65343
|
});
|
|
65342
65344
|
}
|
|
65343
|
-
if (
|
|
65345
|
+
if (limit) {
|
|
65344
65346
|
return await this.triggerTradeFromConfig({
|
|
65345
65347
|
symbol,
|
|
65346
65348
|
kind,
|
|
65347
65349
|
raw: payload.raw,
|
|
65348
65350
|
stop,
|
|
65349
|
-
ignore_config
|
|
65351
|
+
ignore_config,
|
|
65352
|
+
place
|
|
65350
65353
|
});
|
|
65351
65354
|
}
|
|
65352
65355
|
await this.syncAccount({
|
|
@@ -65435,7 +65438,6 @@ async function getExchangeAccount(payload) {
|
|
|
65435
65438
|
app_db
|
|
65436
65439
|
});
|
|
65437
65440
|
}
|
|
65438
|
-
|
|
65439
65441
|
// src/app.ts
|
|
65440
65442
|
class App {
|
|
65441
65443
|
app_db;
|
|
@@ -65494,37 +65496,6 @@ class App {
|
|
|
65494
65496
|
stop: payload.stop
|
|
65495
65497
|
});
|
|
65496
65498
|
}
|
|
65497
|
-
async updateReduceRatio(payload) {
|
|
65498
|
-
const { symbol } = payload;
|
|
65499
|
-
const exchange_account = await this.getExchangeAccount(payload.account);
|
|
65500
|
-
const positions = await exchange_account.syncAccount({
|
|
65501
|
-
as_view: true,
|
|
65502
|
-
symbol
|
|
65503
|
-
});
|
|
65504
|
-
const active_account = await exchange_account.getActiveAccount({
|
|
65505
|
-
symbol
|
|
65506
|
-
});
|
|
65507
|
-
const long_position = active_account.position.long;
|
|
65508
|
-
const short_position = active_account.position.short;
|
|
65509
|
-
const long_db_position = positions.find((p) => p.kind === "long");
|
|
65510
|
-
const short_db_position = positions.find((p) => p.kind === "short");
|
|
65511
|
-
const balance = active_account.usd_balance || 0;
|
|
65512
|
-
const long_liquidation = long_db_position.avg_price * long_db_position.avg_qty / long_db_position.leverage - balance / long_db_position.avg_qty + long_db_position.avg_price;
|
|
65513
|
-
const short_liquidation = -(short_db_position.avg_price * short_db_position.avg_qty / short_db_position.leverage) + balance / short_db_position.avg_qty + short_db_position.avg_price;
|
|
65514
|
-
long_position.avg_liquidation = to_f2(long_liquidation, "%.3f");
|
|
65515
|
-
short_position.avg_liquidation = to_f2(short_liquidation, "%.3f");
|
|
65516
|
-
const long_ratio = Math.max(long_position.avg_liquidation, long_position.avg_entry) / Math.min(long_position.avg_liquidation, long_position.avg_entry) - 1;
|
|
65517
|
-
const short_ratio = Math.max(short_position.avg_liquidation, short_position.avg_entry) / Math.min(short_position.avg_liquidation, short_position.avg_entry) - 1;
|
|
65518
|
-
long_position.liquidation_ratio = to_f2(long_ratio, "%.3f") * 100;
|
|
65519
|
-
short_position.liquidation_ratio = to_f2(short_ratio, "%.3f") * 100;
|
|
65520
|
-
return {
|
|
65521
|
-
long_position,
|
|
65522
|
-
short_position,
|
|
65523
|
-
long_db_position,
|
|
65524
|
-
short_db_position,
|
|
65525
|
-
balance: active_account.usd_balance
|
|
65526
|
-
};
|
|
65527
|
-
}
|
|
65528
65499
|
async getWindingDownMarkets() {
|
|
65529
65500
|
return await this.app_db.getWindingDownMarkets();
|
|
65530
65501
|
}
|
|
@@ -65673,7 +65644,7 @@ class App {
|
|
|
65673
65644
|
return await this.app_db.getMoverExchangeInstances();
|
|
65674
65645
|
}
|
|
65675
65646
|
async updateTpOnAllMarkets() {
|
|
65676
|
-
const move_instances = await this.
|
|
65647
|
+
const move_instances = await this.app_db.getAccountWithActivePositions();
|
|
65677
65648
|
for (const instance of move_instances) {
|
|
65678
65649
|
const params = {
|
|
65679
65650
|
account: {
|
|
@@ -65734,6 +65705,171 @@ class App {
|
|
|
65734
65705
|
});
|
|
65735
65706
|
return result;
|
|
65736
65707
|
}
|
|
65708
|
+
async profitWithinGapStrategy(payload) {
|
|
65709
|
+
const {
|
|
65710
|
+
account,
|
|
65711
|
+
symbol,
|
|
65712
|
+
kind,
|
|
65713
|
+
risk,
|
|
65714
|
+
resistance,
|
|
65715
|
+
support,
|
|
65716
|
+
reward_factor = 1
|
|
65717
|
+
} = payload;
|
|
65718
|
+
const exchange_account = await this.getExchangeAccount(account);
|
|
65719
|
+
console.log("Getting entry and stop for ", symbol, kind);
|
|
65720
|
+
const entry = kind === "long" ? resistance : support;
|
|
65721
|
+
const stop = kind === "long" ? support : resistance;
|
|
65722
|
+
console.log("Building app config for ", symbol, kind);
|
|
65723
|
+
const initial_app_config = await exchange_account.buildAppConfig({
|
|
65724
|
+
entry,
|
|
65725
|
+
stop,
|
|
65726
|
+
risk_reward: 199,
|
|
65727
|
+
risk,
|
|
65728
|
+
symbol
|
|
65729
|
+
});
|
|
65730
|
+
console.log("Computing risk reward for ", symbol, kind);
|
|
65731
|
+
const risk_reward = computeRiskReward({
|
|
65732
|
+
app_config: initial_app_config,
|
|
65733
|
+
entry: initial_app_config.entry,
|
|
65734
|
+
stop: initial_app_config.stop,
|
|
65735
|
+
risk_per_trade: initial_app_config.risk_per_trade
|
|
65736
|
+
});
|
|
65737
|
+
console.log("Re-computing app config for ", symbol, kind);
|
|
65738
|
+
const { entries, last_value, ...app_config } = await exchange_account.buildAppConfig({
|
|
65739
|
+
entry: initial_app_config.entry,
|
|
65740
|
+
stop: initial_app_config.stop,
|
|
65741
|
+
risk_reward,
|
|
65742
|
+
risk,
|
|
65743
|
+
symbol
|
|
65744
|
+
});
|
|
65745
|
+
console.log("Computing profit percent for ", symbol, kind);
|
|
65746
|
+
const pnl = reward_factor * risk;
|
|
65747
|
+
const profit_percent = to_f2(pnl * 100 / (last_value.avg_entry * last_value.avg_size), "%.4f");
|
|
65748
|
+
let config2 = {
|
|
65749
|
+
entry,
|
|
65750
|
+
stop,
|
|
65751
|
+
risk,
|
|
65752
|
+
risk_reward,
|
|
65753
|
+
profit_percent
|
|
65754
|
+
};
|
|
65755
|
+
console.log("Saving new config for ", symbol, kind);
|
|
65756
|
+
const data = await exchange_account.getPositionConfig({
|
|
65757
|
+
symbol,
|
|
65758
|
+
kind,
|
|
65759
|
+
params: config2
|
|
65760
|
+
});
|
|
65761
|
+
console.log("Checking orders to place for ", symbol, kind);
|
|
65762
|
+
const orders_to_place = await exchange_account.placeTrade({
|
|
65763
|
+
symbol,
|
|
65764
|
+
raw: true,
|
|
65765
|
+
kind,
|
|
65766
|
+
place: false
|
|
65767
|
+
});
|
|
65768
|
+
config2 = {
|
|
65769
|
+
...config2,
|
|
65770
|
+
...data
|
|
65771
|
+
};
|
|
65772
|
+
console.log("Fetching positions for ", symbol);
|
|
65773
|
+
const positions = await exchange_account.syncAccount({
|
|
65774
|
+
symbol,
|
|
65775
|
+
as_view: true
|
|
65776
|
+
});
|
|
65777
|
+
console.log("Getting long and short positions for ", symbol);
|
|
65778
|
+
const long_position = positions.find((k) => k.kind === "long");
|
|
65779
|
+
const short_position = positions.find((k) => k.kind === "short");
|
|
65780
|
+
console.log("Getting focus position for ", symbol, kind);
|
|
65781
|
+
const focus_position = kind === "long" ? long_position : short_position;
|
|
65782
|
+
const reverse_position = kind === "long" ? short_position : long_position;
|
|
65783
|
+
let reverse_action = null;
|
|
65784
|
+
let reverse_orders_to_buy = [];
|
|
65785
|
+
let reverse_config = null;
|
|
65786
|
+
console.log("Checking if focus position has quantity for ", symbol, kind);
|
|
65787
|
+
if (focus_position.quantity > 0) {
|
|
65788
|
+
console.log("Getting details for ", reverse_position.kind);
|
|
65789
|
+
reverse_action = await exchange_account.buildOppositeTrades({
|
|
65790
|
+
symbol,
|
|
65791
|
+
kind
|
|
65792
|
+
});
|
|
65793
|
+
console.log("Updating config for ", symbol, reverse_action.kind);
|
|
65794
|
+
await exchange_account.getPositionConfig({
|
|
65795
|
+
symbol,
|
|
65796
|
+
kind: reverse_action.kind,
|
|
65797
|
+
params: {
|
|
65798
|
+
entry: reverse_action.entry,
|
|
65799
|
+
stop: reverse_action.stop,
|
|
65800
|
+
risk: reverse_action.risk_per_trade,
|
|
65801
|
+
profit_percent: reverse_action.profit_percent,
|
|
65802
|
+
risk_reward: reverse_action.risk_reward
|
|
65803
|
+
}
|
|
65804
|
+
});
|
|
65805
|
+
console.log("Checking reverse orders to buy for ", symbol, reverse_action.kind);
|
|
65806
|
+
reverse_orders_to_buy = await exchange_account.placeTrade({
|
|
65807
|
+
symbol,
|
|
65808
|
+
raw: true,
|
|
65809
|
+
kind: reverse_action.kind,
|
|
65810
|
+
place: false
|
|
65811
|
+
});
|
|
65812
|
+
let _reverse_config = {
|
|
65813
|
+
avg: reverse_action.avg,
|
|
65814
|
+
entry: reverse_action.entry,
|
|
65815
|
+
stop: reverse_action.stop,
|
|
65816
|
+
risk_per_trade: reverse_action.risk_per_trade,
|
|
65817
|
+
profit_percent: reverse_action.profit_percent,
|
|
65818
|
+
risk_reward: reverse_action.risk_reward
|
|
65819
|
+
};
|
|
65820
|
+
if (reverse_orders_to_buy.length > 0) {
|
|
65821
|
+
console.log("Placing opposite trade action for ", symbol, reverse_action.kind);
|
|
65822
|
+
let existing = await exchange_account.placeOppositeTradeAction({
|
|
65823
|
+
symbol,
|
|
65824
|
+
kind: reverse_action.kind,
|
|
65825
|
+
data: _reverse_config
|
|
65826
|
+
});
|
|
65827
|
+
_reverse_config = {
|
|
65828
|
+
...existing,
|
|
65829
|
+
..._reverse_config
|
|
65830
|
+
};
|
|
65831
|
+
}
|
|
65832
|
+
reverse_config = _reverse_config;
|
|
65833
|
+
if (!reverse_config?.id) {
|
|
65834
|
+
console.log("fetching reverse config for ", symbol, reverse_action.kind);
|
|
65835
|
+
reverse_config = await exchange_account.getPositionConfig({
|
|
65836
|
+
symbol,
|
|
65837
|
+
kind: reverse_action.kind
|
|
65838
|
+
});
|
|
65839
|
+
}
|
|
65840
|
+
if (reverse_position.quantity > 0 && reverse_config?.id) {
|
|
65841
|
+
console.log("Checking if reverse position has quantity for ", symbol, reverse_action.kind);
|
|
65842
|
+
const max_size = app_config.max_size * 0.98;
|
|
65843
|
+
if (reverse_config.threshold_qty !== max_size) {
|
|
65844
|
+
await this.app_db.updateScheduledTrade(reverse_config.id, {
|
|
65845
|
+
follow: true,
|
|
65846
|
+
threshold_qty: max_size
|
|
65847
|
+
});
|
|
65848
|
+
}
|
|
65849
|
+
console.log("Updating follow and threshold for ", symbol, reverse_action.kind);
|
|
65850
|
+
} else {
|
|
65851
|
+
await this.app_db.updateScheduledTrade(reverse_config.id, {
|
|
65852
|
+
follow: false
|
|
65853
|
+
});
|
|
65854
|
+
}
|
|
65855
|
+
}
|
|
65856
|
+
return {
|
|
65857
|
+
reverse_config,
|
|
65858
|
+
reverse_action,
|
|
65859
|
+
reverse_orders_to_buy,
|
|
65860
|
+
positions: {
|
|
65861
|
+
long: long_position,
|
|
65862
|
+
short: short_position
|
|
65863
|
+
},
|
|
65864
|
+
orders_to_place,
|
|
65865
|
+
config_details: {
|
|
65866
|
+
app_config,
|
|
65867
|
+
last_value,
|
|
65868
|
+
config: config2,
|
|
65869
|
+
pnl
|
|
65870
|
+
}
|
|
65871
|
+
};
|
|
65872
|
+
}
|
|
65737
65873
|
}
|
|
65738
65874
|
async function initApp(payload) {
|
|
65739
65875
|
const pb = await initPocketBaseClient(payload.db);
|
|
@@ -65868,13 +66004,13 @@ async function getPositions(payload) {
|
|
|
65868
66004
|
const symbol_config = await exchange_account.recomputeSymbolConfig({
|
|
65869
66005
|
symbol: payload.symbol
|
|
65870
66006
|
});
|
|
65871
|
-
const
|
|
66007
|
+
const strategy2 = await exchange_account.getPositionStrategy();
|
|
65872
66008
|
const strategy_config = {
|
|
65873
|
-
tp_percent:
|
|
65874
|
-
short_tp_factor:
|
|
65875
|
-
fee_percent:
|
|
65876
|
-
budget:
|
|
65877
|
-
risk_reward:
|
|
66009
|
+
tp_percent: strategy2?.tp_percent,
|
|
66010
|
+
short_tp_factor: strategy2?.short_tp_factor,
|
|
66011
|
+
fee_percent: strategy2?.fee_percent,
|
|
66012
|
+
budget: strategy2?.budget,
|
|
66013
|
+
risk_reward: strategy2?.risk_reward,
|
|
65878
66014
|
global_config: symbol_config
|
|
65879
66015
|
};
|
|
65880
66016
|
const positions = await exchange_account.syncAccount({
|