@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.cjs
CHANGED
|
@@ -58220,6 +58220,18 @@ class AppDatabase {
|
|
|
58220
58220
|
await this.saveCredentials(password, credentials);
|
|
58221
58221
|
}
|
|
58222
58222
|
}
|
|
58223
|
+
async getAccountWithActivePositions() {
|
|
58224
|
+
const positions = await this.pb.collection("positions").getFullList({
|
|
58225
|
+
filter: `quantity > 0`,
|
|
58226
|
+
fields: `account`
|
|
58227
|
+
});
|
|
58228
|
+
const accounts = Array.from(new Set(positions.map((p) => p.account)));
|
|
58229
|
+
const filter = accounts.map((a) => `id = "${a}"`).join(" || ");
|
|
58230
|
+
const account_instances = await this.pb.collection("exchange_accounts").getFullList({
|
|
58231
|
+
filter
|
|
58232
|
+
});
|
|
58233
|
+
return account_instances;
|
|
58234
|
+
}
|
|
58223
58235
|
async getAllSymbolsFromPositions(options) {
|
|
58224
58236
|
const { no_position = false, kind = "long", custom_filter } = options || {};
|
|
58225
58237
|
let filter = custom_filter || (no_position ? `quantity = 0` : undefined);
|
|
@@ -59806,7 +59818,7 @@ class Signal {
|
|
|
59806
59818
|
new_stop
|
|
59807
59819
|
};
|
|
59808
59820
|
});
|
|
59809
|
-
if (greater_than_min_size.length !==
|
|
59821
|
+
if (greater_than_min_size.length !== total_orders.length) {
|
|
59810
59822
|
payload = greater_than_min_size.concat(less_than_min_size);
|
|
59811
59823
|
}
|
|
59812
59824
|
return payload;
|
|
@@ -59966,9 +59978,7 @@ function buildConfig(app_config, {
|
|
|
59966
59978
|
}
|
|
59967
59979
|
const condition = (kind === "long" ? entry > app_config.support : entry >= app_config.support) && stop >= app_config.support * 0.999;
|
|
59968
59980
|
if (kind === "short") {
|
|
59969
|
-
console.log("condition", condition, entry === stop);
|
|
59970
59981
|
}
|
|
59971
|
-
console.log({ entry, support: app_config.support, stop });
|
|
59972
59982
|
const result = entry === stop ? [] : condition ? instance.build_entry({
|
|
59973
59983
|
current_price: entry,
|
|
59974
59984
|
stop_loss: stop,
|
|
@@ -60284,7 +60294,6 @@ function generateOptimumAppConfig(config2, payload, position2) {
|
|
|
60284
60294
|
const tolerance = 0.1;
|
|
60285
60295
|
const max_iterations = 150;
|
|
60286
60296
|
let iterations = 0;
|
|
60287
|
-
console.log(`Starting risk search for ${position2.kind} position. Target Entry: ${position2.entry}, Initial Risk Range: [${low_risk}, ${high_risk}]`);
|
|
60288
60297
|
while (high_risk - low_risk > tolerance && iterations < max_iterations) {
|
|
60289
60298
|
iterations++;
|
|
60290
60299
|
const mid_risk = (low_risk + high_risk) / 2;
|
|
@@ -60330,9 +60339,7 @@ function generateOptimumAppConfig(config2, payload, position2) {
|
|
|
60330
60339
|
price_places: current_app_config.price_places,
|
|
60331
60340
|
decimal_places: current_app_config.decimal_places
|
|
60332
60341
|
});
|
|
60333
|
-
console.log(`Iteration ${iterations}: Risk=${mid_risk.toFixed(2)}, Low=${low_risk.toFixed(2)}, High=${high_risk.toFixed(2)}`);
|
|
60334
60342
|
if (full_trades.length === 0) {
|
|
60335
|
-
console.log(` -> No trades generated by sortedBuildConfig at Risk=${mid_risk.toFixed(2)}. Adjusting high_risk down.`);
|
|
60336
60343
|
high_risk = mid_risk;
|
|
60337
60344
|
continue;
|
|
60338
60345
|
}
|
|
@@ -60345,29 +60352,23 @@ function generateOptimumAppConfig(config2, payload, position2) {
|
|
|
60345
60352
|
existingOrders: []
|
|
60346
60353
|
});
|
|
60347
60354
|
if (trades.length === 0) {
|
|
60348
|
-
console.log(` -> No trades met quantity requirement after filtering at Risk=${mid_risk.toFixed(2)}. Adjusting low_risk up.`);
|
|
60349
60355
|
low_risk = mid_risk;
|
|
60350
60356
|
continue;
|
|
60351
60357
|
}
|
|
60352
60358
|
const last_trade = trades[trades.length - 1];
|
|
60353
60359
|
const last_entry = last_trade.entry;
|
|
60354
|
-
console.log(` -> Last Trade Entry (Filtered): ${last_entry.toFixed(4)}`);
|
|
60355
60360
|
if (position2.kind === "long") {
|
|
60356
60361
|
if (last_entry > position2.entry) {
|
|
60357
|
-
console.log(` -> Constraint VIOLATED (Long): last_entry (${last_entry.toFixed(4)}) > position.entry (${position2.entry.toFixed(4)}). Reducing high_risk.`);
|
|
60358
60362
|
high_risk = mid_risk;
|
|
60359
60363
|
} else {
|
|
60360
|
-
console.log(` -> Constraint MET (Long): last_entry (${last_entry.toFixed(4)}) <= position.entry (${position2.entry.toFixed(4)}). Storing as best, increasing low_risk.`);
|
|
60361
60364
|
best_risk = mid_risk;
|
|
60362
60365
|
best_app_config = current_app_config;
|
|
60363
60366
|
low_risk = mid_risk;
|
|
60364
60367
|
}
|
|
60365
60368
|
} else {
|
|
60366
60369
|
if (last_entry < position2.entry) {
|
|
60367
|
-
console.log(` -> Constraint VIOLATED (Short): last_entry (${last_entry.toFixed(4)}) < position.entry (${position2.entry.toFixed(4)}). Reducing high_risk.`);
|
|
60368
60370
|
high_risk = mid_risk;
|
|
60369
60371
|
} else {
|
|
60370
|
-
console.log(` -> Constraint MET (Short): last_entry (${last_entry.toFixed(4)}) >= position.entry (${position2.entry.toFixed(4)}). Storing as best, increasing low_risk.`);
|
|
60371
60372
|
best_risk = mid_risk;
|
|
60372
60373
|
best_app_config = current_app_config;
|
|
60373
60374
|
low_risk = mid_risk;
|
|
@@ -60605,7 +60606,6 @@ class Strategy {
|
|
|
60605
60606
|
quantity,
|
|
60606
60607
|
kind
|
|
60607
60608
|
};
|
|
60608
|
-
console.log({ second_payload, third_payload });
|
|
60609
60609
|
const app_config = generateOptimumAppConfig(this.config.global_config, second_payload, third_payload);
|
|
60610
60610
|
let entries = [];
|
|
60611
60611
|
let risk_per_trade = this.config.budget;
|
|
@@ -60618,6 +60618,7 @@ class Strategy {
|
|
|
60618
60618
|
if (ignore_entries) {
|
|
60619
60619
|
entries = [];
|
|
60620
60620
|
}
|
|
60621
|
+
console.log({ app_config });
|
|
60621
60622
|
}
|
|
60622
60623
|
const risk = this.to_f(risk_per_trade);
|
|
60623
60624
|
let below_reverse_entries = kind === "long" ? entries.filter((u) => {
|
|
@@ -65351,6 +65352,7 @@ class ExchangeAccount {
|
|
|
65351
65352
|
kind,
|
|
65352
65353
|
place,
|
|
65353
65354
|
tp,
|
|
65355
|
+
limit = true,
|
|
65354
65356
|
raw: _raw,
|
|
65355
65357
|
cancel,
|
|
65356
65358
|
stop,
|
|
@@ -65363,13 +65365,14 @@ class ExchangeAccount {
|
|
|
65363
65365
|
kind
|
|
65364
65366
|
});
|
|
65365
65367
|
}
|
|
65366
|
-
if (
|
|
65368
|
+
if (limit) {
|
|
65367
65369
|
return await this.triggerTradeFromConfig({
|
|
65368
65370
|
symbol,
|
|
65369
65371
|
kind,
|
|
65370
65372
|
raw: payload.raw,
|
|
65371
65373
|
stop,
|
|
65372
|
-
ignore_config
|
|
65374
|
+
ignore_config,
|
|
65375
|
+
place
|
|
65373
65376
|
});
|
|
65374
65377
|
}
|
|
65375
65378
|
await this.syncAccount({
|
|
@@ -65458,7 +65461,6 @@ async function getExchangeAccount(payload) {
|
|
|
65458
65461
|
app_db
|
|
65459
65462
|
});
|
|
65460
65463
|
}
|
|
65461
|
-
|
|
65462
65464
|
// src/app.ts
|
|
65463
65465
|
class App {
|
|
65464
65466
|
app_db;
|
|
@@ -65517,37 +65519,6 @@ class App {
|
|
|
65517
65519
|
stop: payload.stop
|
|
65518
65520
|
});
|
|
65519
65521
|
}
|
|
65520
|
-
async updateReduceRatio(payload) {
|
|
65521
|
-
const { symbol } = payload;
|
|
65522
|
-
const exchange_account = await this.getExchangeAccount(payload.account);
|
|
65523
|
-
const positions = await exchange_account.syncAccount({
|
|
65524
|
-
as_view: true,
|
|
65525
|
-
symbol
|
|
65526
|
-
});
|
|
65527
|
-
const active_account = await exchange_account.getActiveAccount({
|
|
65528
|
-
symbol
|
|
65529
|
-
});
|
|
65530
|
-
const long_position = active_account.position.long;
|
|
65531
|
-
const short_position = active_account.position.short;
|
|
65532
|
-
const long_db_position = positions.find((p) => p.kind === "long");
|
|
65533
|
-
const short_db_position = positions.find((p) => p.kind === "short");
|
|
65534
|
-
const balance = active_account.usd_balance || 0;
|
|
65535
|
-
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;
|
|
65536
|
-
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;
|
|
65537
|
-
long_position.avg_liquidation = to_f2(long_liquidation, "%.3f");
|
|
65538
|
-
short_position.avg_liquidation = to_f2(short_liquidation, "%.3f");
|
|
65539
|
-
const long_ratio = Math.max(long_position.avg_liquidation, long_position.avg_entry) / Math.min(long_position.avg_liquidation, long_position.avg_entry) - 1;
|
|
65540
|
-
const short_ratio = Math.max(short_position.avg_liquidation, short_position.avg_entry) / Math.min(short_position.avg_liquidation, short_position.avg_entry) - 1;
|
|
65541
|
-
long_position.liquidation_ratio = to_f2(long_ratio, "%.3f") * 100;
|
|
65542
|
-
short_position.liquidation_ratio = to_f2(short_ratio, "%.3f") * 100;
|
|
65543
|
-
return {
|
|
65544
|
-
long_position,
|
|
65545
|
-
short_position,
|
|
65546
|
-
long_db_position,
|
|
65547
|
-
short_db_position,
|
|
65548
|
-
balance: active_account.usd_balance
|
|
65549
|
-
};
|
|
65550
|
-
}
|
|
65551
65522
|
async getWindingDownMarkets() {
|
|
65552
65523
|
return await this.app_db.getWindingDownMarkets();
|
|
65553
65524
|
}
|
|
@@ -65696,7 +65667,7 @@ class App {
|
|
|
65696
65667
|
return await this.app_db.getMoverExchangeInstances();
|
|
65697
65668
|
}
|
|
65698
65669
|
async updateTpOnAllMarkets() {
|
|
65699
|
-
const move_instances = await this.
|
|
65670
|
+
const move_instances = await this.app_db.getAccountWithActivePositions();
|
|
65700
65671
|
for (const instance of move_instances) {
|
|
65701
65672
|
const params = {
|
|
65702
65673
|
account: {
|
|
@@ -65757,6 +65728,171 @@ class App {
|
|
|
65757
65728
|
});
|
|
65758
65729
|
return result;
|
|
65759
65730
|
}
|
|
65731
|
+
async profitWithinGapStrategy(payload) {
|
|
65732
|
+
const {
|
|
65733
|
+
account,
|
|
65734
|
+
symbol,
|
|
65735
|
+
kind,
|
|
65736
|
+
risk,
|
|
65737
|
+
resistance,
|
|
65738
|
+
support,
|
|
65739
|
+
reward_factor = 1
|
|
65740
|
+
} = payload;
|
|
65741
|
+
const exchange_account = await this.getExchangeAccount(account);
|
|
65742
|
+
console.log("Getting entry and stop for ", symbol, kind);
|
|
65743
|
+
const entry = kind === "long" ? resistance : support;
|
|
65744
|
+
const stop = kind === "long" ? support : resistance;
|
|
65745
|
+
console.log("Building app config for ", symbol, kind);
|
|
65746
|
+
const initial_app_config = await exchange_account.buildAppConfig({
|
|
65747
|
+
entry,
|
|
65748
|
+
stop,
|
|
65749
|
+
risk_reward: 199,
|
|
65750
|
+
risk,
|
|
65751
|
+
symbol
|
|
65752
|
+
});
|
|
65753
|
+
console.log("Computing risk reward for ", symbol, kind);
|
|
65754
|
+
const risk_reward = computeRiskReward({
|
|
65755
|
+
app_config: initial_app_config,
|
|
65756
|
+
entry: initial_app_config.entry,
|
|
65757
|
+
stop: initial_app_config.stop,
|
|
65758
|
+
risk_per_trade: initial_app_config.risk_per_trade
|
|
65759
|
+
});
|
|
65760
|
+
console.log("Re-computing app config for ", symbol, kind);
|
|
65761
|
+
const { entries, last_value, ...app_config } = await exchange_account.buildAppConfig({
|
|
65762
|
+
entry: initial_app_config.entry,
|
|
65763
|
+
stop: initial_app_config.stop,
|
|
65764
|
+
risk_reward,
|
|
65765
|
+
risk,
|
|
65766
|
+
symbol
|
|
65767
|
+
});
|
|
65768
|
+
console.log("Computing profit percent for ", symbol, kind);
|
|
65769
|
+
const pnl = reward_factor * risk;
|
|
65770
|
+
const profit_percent = to_f2(pnl * 100 / (last_value.avg_entry * last_value.avg_size), "%.4f");
|
|
65771
|
+
let config2 = {
|
|
65772
|
+
entry,
|
|
65773
|
+
stop,
|
|
65774
|
+
risk,
|
|
65775
|
+
risk_reward,
|
|
65776
|
+
profit_percent
|
|
65777
|
+
};
|
|
65778
|
+
console.log("Saving new config for ", symbol, kind);
|
|
65779
|
+
const data = await exchange_account.getPositionConfig({
|
|
65780
|
+
symbol,
|
|
65781
|
+
kind,
|
|
65782
|
+
params: config2
|
|
65783
|
+
});
|
|
65784
|
+
console.log("Checking orders to place for ", symbol, kind);
|
|
65785
|
+
const orders_to_place = await exchange_account.placeTrade({
|
|
65786
|
+
symbol,
|
|
65787
|
+
raw: true,
|
|
65788
|
+
kind,
|
|
65789
|
+
place: false
|
|
65790
|
+
});
|
|
65791
|
+
config2 = {
|
|
65792
|
+
...config2,
|
|
65793
|
+
...data
|
|
65794
|
+
};
|
|
65795
|
+
console.log("Fetching positions for ", symbol);
|
|
65796
|
+
const positions = await exchange_account.syncAccount({
|
|
65797
|
+
symbol,
|
|
65798
|
+
as_view: true
|
|
65799
|
+
});
|
|
65800
|
+
console.log("Getting long and short positions for ", symbol);
|
|
65801
|
+
const long_position = positions.find((k) => k.kind === "long");
|
|
65802
|
+
const short_position = positions.find((k) => k.kind === "short");
|
|
65803
|
+
console.log("Getting focus position for ", symbol, kind);
|
|
65804
|
+
const focus_position = kind === "long" ? long_position : short_position;
|
|
65805
|
+
const reverse_position = kind === "long" ? short_position : long_position;
|
|
65806
|
+
let reverse_action = null;
|
|
65807
|
+
let reverse_orders_to_buy = [];
|
|
65808
|
+
let reverse_config = null;
|
|
65809
|
+
console.log("Checking if focus position has quantity for ", symbol, kind);
|
|
65810
|
+
if (focus_position.quantity > 0) {
|
|
65811
|
+
console.log("Getting details for ", reverse_position.kind);
|
|
65812
|
+
reverse_action = await exchange_account.buildOppositeTrades({
|
|
65813
|
+
symbol,
|
|
65814
|
+
kind
|
|
65815
|
+
});
|
|
65816
|
+
console.log("Updating config for ", symbol, reverse_action.kind);
|
|
65817
|
+
await exchange_account.getPositionConfig({
|
|
65818
|
+
symbol,
|
|
65819
|
+
kind: reverse_action.kind,
|
|
65820
|
+
params: {
|
|
65821
|
+
entry: reverse_action.entry,
|
|
65822
|
+
stop: reverse_action.stop,
|
|
65823
|
+
risk: reverse_action.risk_per_trade,
|
|
65824
|
+
profit_percent: reverse_action.profit_percent,
|
|
65825
|
+
risk_reward: reverse_action.risk_reward
|
|
65826
|
+
}
|
|
65827
|
+
});
|
|
65828
|
+
console.log("Checking reverse orders to buy for ", symbol, reverse_action.kind);
|
|
65829
|
+
reverse_orders_to_buy = await exchange_account.placeTrade({
|
|
65830
|
+
symbol,
|
|
65831
|
+
raw: true,
|
|
65832
|
+
kind: reverse_action.kind,
|
|
65833
|
+
place: false
|
|
65834
|
+
});
|
|
65835
|
+
let _reverse_config = {
|
|
65836
|
+
avg: reverse_action.avg,
|
|
65837
|
+
entry: reverse_action.entry,
|
|
65838
|
+
stop: reverse_action.stop,
|
|
65839
|
+
risk_per_trade: reverse_action.risk_per_trade,
|
|
65840
|
+
profit_percent: reverse_action.profit_percent,
|
|
65841
|
+
risk_reward: reverse_action.risk_reward
|
|
65842
|
+
};
|
|
65843
|
+
if (reverse_orders_to_buy.length > 0) {
|
|
65844
|
+
console.log("Placing opposite trade action for ", symbol, reverse_action.kind);
|
|
65845
|
+
let existing = await exchange_account.placeOppositeTradeAction({
|
|
65846
|
+
symbol,
|
|
65847
|
+
kind: reverse_action.kind,
|
|
65848
|
+
data: _reverse_config
|
|
65849
|
+
});
|
|
65850
|
+
_reverse_config = {
|
|
65851
|
+
...existing,
|
|
65852
|
+
..._reverse_config
|
|
65853
|
+
};
|
|
65854
|
+
}
|
|
65855
|
+
reverse_config = _reverse_config;
|
|
65856
|
+
if (!reverse_config?.id) {
|
|
65857
|
+
console.log("fetching reverse config for ", symbol, reverse_action.kind);
|
|
65858
|
+
reverse_config = await exchange_account.getPositionConfig({
|
|
65859
|
+
symbol,
|
|
65860
|
+
kind: reverse_action.kind
|
|
65861
|
+
});
|
|
65862
|
+
}
|
|
65863
|
+
if (reverse_position.quantity > 0 && reverse_config?.id) {
|
|
65864
|
+
console.log("Checking if reverse position has quantity for ", symbol, reverse_action.kind);
|
|
65865
|
+
const max_size = app_config.max_size * 0.98;
|
|
65866
|
+
if (reverse_config.threshold_qty !== max_size) {
|
|
65867
|
+
await this.app_db.updateScheduledTrade(reverse_config.id, {
|
|
65868
|
+
follow: true,
|
|
65869
|
+
threshold_qty: max_size
|
|
65870
|
+
});
|
|
65871
|
+
}
|
|
65872
|
+
console.log("Updating follow and threshold for ", symbol, reverse_action.kind);
|
|
65873
|
+
} else {
|
|
65874
|
+
await this.app_db.updateScheduledTrade(reverse_config.id, {
|
|
65875
|
+
follow: false
|
|
65876
|
+
});
|
|
65877
|
+
}
|
|
65878
|
+
}
|
|
65879
|
+
return {
|
|
65880
|
+
reverse_config,
|
|
65881
|
+
reverse_action,
|
|
65882
|
+
reverse_orders_to_buy,
|
|
65883
|
+
positions: {
|
|
65884
|
+
long: long_position,
|
|
65885
|
+
short: short_position
|
|
65886
|
+
},
|
|
65887
|
+
orders_to_place,
|
|
65888
|
+
config_details: {
|
|
65889
|
+
app_config,
|
|
65890
|
+
last_value,
|
|
65891
|
+
config: config2,
|
|
65892
|
+
pnl
|
|
65893
|
+
}
|
|
65894
|
+
};
|
|
65895
|
+
}
|
|
65760
65896
|
}
|
|
65761
65897
|
async function initApp(payload) {
|
|
65762
65898
|
const pb = await initPocketBaseClient(payload.db);
|
|
@@ -65891,13 +66027,13 @@ async function getPositions(payload) {
|
|
|
65891
66027
|
const symbol_config = await exchange_account.recomputeSymbolConfig({
|
|
65892
66028
|
symbol: payload.symbol
|
|
65893
66029
|
});
|
|
65894
|
-
const
|
|
66030
|
+
const strategy2 = await exchange_account.getPositionStrategy();
|
|
65895
66031
|
const strategy_config = {
|
|
65896
|
-
tp_percent:
|
|
65897
|
-
short_tp_factor:
|
|
65898
|
-
fee_percent:
|
|
65899
|
-
budget:
|
|
65900
|
-
risk_reward:
|
|
66032
|
+
tp_percent: strategy2?.tp_percent,
|
|
66033
|
+
short_tp_factor: strategy2?.short_tp_factor,
|
|
66034
|
+
fee_percent: strategy2?.fee_percent,
|
|
66035
|
+
budget: strategy2?.budget,
|
|
66036
|
+
risk_reward: strategy2?.risk_reward,
|
|
65901
66037
|
global_config: symbol_config
|
|
65902
66038
|
};
|
|
65903
66039
|
const positions = await exchange_account.syncAccount({
|