@gbozee/ultimate 0.0.2-174 → 0.0.2-177
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.d.ts +134 -4
- package/dist/frontend-index.js +305 -25
- package/dist/index.cjs +397 -32
- package/dist/index.d.ts +206 -5
- package/dist/index.js +397 -32
- package/dist/mcp-server.cjs +303 -32
- package/dist/mcp-server.js +303 -32
- package/package.json +1 -1
package/dist/mcp-server.cjs
CHANGED
|
@@ -61401,7 +61401,7 @@ class AppDatabase {
|
|
|
61401
61401
|
table: "positions_view",
|
|
61402
61402
|
params: {
|
|
61403
61403
|
filter: `symbol:lower="${symbol.toLowerCase()}" && p_account.owner:lower="${account.owner.toLowerCase()}" && p_account.exchange:lower="${account.exchange.toLowerCase()}"`,
|
|
61404
|
-
expand: "b_config, account_strategy, p_account, proxy"
|
|
61404
|
+
expand: "b_config, account_strategy, p_account, proxy, compound_instance.ref,support"
|
|
61405
61405
|
}
|
|
61406
61406
|
} : {
|
|
61407
61407
|
table: "positions",
|
|
@@ -62211,11 +62211,169 @@ class AppDatabase {
|
|
|
62211
62211
|
parent: config_id
|
|
62212
62212
|
});
|
|
62213
62213
|
}
|
|
62214
|
+
async getCompoundInstance(payload) {
|
|
62215
|
+
const { position } = payload;
|
|
62216
|
+
const found = await this.pb.collection("compound_instances").getFullList({
|
|
62217
|
+
filter: `position.id = "${position.id}"`,
|
|
62218
|
+
expand: `ref`
|
|
62219
|
+
});
|
|
62220
|
+
if (found.length == 0) {
|
|
62221
|
+
return;
|
|
62222
|
+
}
|
|
62223
|
+
const item = found[0];
|
|
62224
|
+
return item;
|
|
62225
|
+
}
|
|
62226
|
+
async getSupportTable(payload) {
|
|
62227
|
+
const { symbol, kind } = payload;
|
|
62228
|
+
const found = await this.pb.collection("support_table").getFullList({
|
|
62229
|
+
filter: `symbol = "${symbol}" && kind = "${kind}"`
|
|
62230
|
+
});
|
|
62231
|
+
if (found.length === 0) {
|
|
62232
|
+
return;
|
|
62233
|
+
}
|
|
62234
|
+
const item = found[0];
|
|
62235
|
+
return item;
|
|
62236
|
+
}
|
|
62237
|
+
async updateCompoundInstance(payload) {
|
|
62238
|
+
const { id, params } = payload;
|
|
62239
|
+
return await this.pb.collection("compound_instances").update(id, params);
|
|
62240
|
+
}
|
|
62214
62241
|
}
|
|
62215
62242
|
|
|
62216
62243
|
// src/exchanges/binance/index.ts
|
|
62217
62244
|
var import_binance = __toESM(require_lib2());
|
|
62218
62245
|
|
|
62246
|
+
// src/helpers/distributions.ts
|
|
62247
|
+
function generateArithmetic(payload) {
|
|
62248
|
+
const { margin_range, risk_reward, kind, price_places = "%.1f" } = payload;
|
|
62249
|
+
const difference = Math.abs(margin_range[1] - margin_range[0]);
|
|
62250
|
+
const spread = difference / risk_reward;
|
|
62251
|
+
return Array.from({ length: risk_reward + 1 }, (_, i2) => {
|
|
62252
|
+
const price = kind === "long" ? margin_range[1] - spread * i2 : margin_range[0] + spread * i2;
|
|
62253
|
+
return to_f(price, price_places);
|
|
62254
|
+
});
|
|
62255
|
+
}
|
|
62256
|
+
function generateGeometric(payload) {
|
|
62257
|
+
const { margin_range, risk_reward, kind, price_places = "%.1f", percent_change } = payload;
|
|
62258
|
+
const effectivePercentChange = percent_change ?? Math.abs(margin_range[1] / margin_range[0] - 1) / risk_reward;
|
|
62259
|
+
return Array.from({ length: risk_reward + 1 }, (_, i2) => {
|
|
62260
|
+
const price = kind === "long" ? margin_range[1] * Math.pow(1 - effectivePercentChange, i2) : margin_range[0] * Math.pow(1 + effectivePercentChange, i2);
|
|
62261
|
+
return to_f(price, price_places);
|
|
62262
|
+
});
|
|
62263
|
+
}
|
|
62264
|
+
function approximateInverseNormal(p) {
|
|
62265
|
+
p = Math.max(0.0001, Math.min(0.9999, p));
|
|
62266
|
+
if (p < 0.5) {
|
|
62267
|
+
const t2 = Math.sqrt(-2 * Math.log(p));
|
|
62268
|
+
const c0 = 2.515517, c1 = 0.802853, c2 = 0.010328;
|
|
62269
|
+
const d1 = 1.432788, d2 = 0.189269, d3 = 0.001308;
|
|
62270
|
+
return -(t2 - (c0 + c1 * t2 + c2 * t2 * t2) / (1 + d1 * t2 + d2 * t2 * t2 + d3 * t2 * t2 * t2));
|
|
62271
|
+
} else {
|
|
62272
|
+
const t2 = Math.sqrt(-2 * Math.log(1 - p));
|
|
62273
|
+
const c0 = 2.515517, c1 = 0.802853, c2 = 0.010328;
|
|
62274
|
+
const d1 = 1.432788, d2 = 0.189269, d3 = 0.001308;
|
|
62275
|
+
return t2 - (c0 + c1 * t2 + c2 * t2 * t2) / (1 + d1 * t2 + d2 * t2 * t2 + d3 * t2 * t2 * t2);
|
|
62276
|
+
}
|
|
62277
|
+
}
|
|
62278
|
+
function generateNormal(payload) {
|
|
62279
|
+
const { margin_range, risk_reward, kind, price_places = "%.1f", stdDevFactor = 6 } = payload;
|
|
62280
|
+
const mean = (margin_range[0] + margin_range[1]) / 2;
|
|
62281
|
+
const stdDev = Math.abs(margin_range[1] - margin_range[0]) / stdDevFactor;
|
|
62282
|
+
const skew = kind === "long" ? -0.2 : 0.2;
|
|
62283
|
+
const adjustedMean = mean + stdDev * skew;
|
|
62284
|
+
const entries = Array.from({ length: risk_reward + 1 }, (_, i2) => {
|
|
62285
|
+
const p = (i2 + 0.5) / (risk_reward + 1);
|
|
62286
|
+
const z3 = approximateInverseNormal(p);
|
|
62287
|
+
let price = adjustedMean + stdDev * z3;
|
|
62288
|
+
price = Math.max(margin_range[0], Math.min(margin_range[1], price));
|
|
62289
|
+
return to_f(price, price_places);
|
|
62290
|
+
});
|
|
62291
|
+
return entries.sort((a, b) => a - b);
|
|
62292
|
+
}
|
|
62293
|
+
function generateExponential(payload) {
|
|
62294
|
+
const { margin_range, risk_reward, kind, price_places = "%.1f", lambda } = payload;
|
|
62295
|
+
const range = Math.abs(margin_range[1] - margin_range[0]);
|
|
62296
|
+
const effectiveLambda = lambda || 2.5;
|
|
62297
|
+
return Array.from({ length: risk_reward + 1 }, (_, i2) => {
|
|
62298
|
+
const t2 = i2 / risk_reward;
|
|
62299
|
+
const exponentialProgress = 1 - Math.exp(-effectiveLambda * t2);
|
|
62300
|
+
const price = kind === "long" ? margin_range[1] - range * exponentialProgress : margin_range[0] + range * exponentialProgress;
|
|
62301
|
+
return to_f(price, price_places);
|
|
62302
|
+
});
|
|
62303
|
+
}
|
|
62304
|
+
function generateInverseExponential(payload) {
|
|
62305
|
+
const { margin_range, risk_reward, kind, price_places = "%.1f", curveFactor = 2 } = payload;
|
|
62306
|
+
const range = Math.abs(margin_range[1] - margin_range[0]);
|
|
62307
|
+
return Array.from({ length: risk_reward + 1 }, (_, i2) => {
|
|
62308
|
+
const t2 = i2 / risk_reward;
|
|
62309
|
+
const progress = (Math.exp(curveFactor * t2) - 1) / (Math.exp(curveFactor) - 1);
|
|
62310
|
+
const price = kind === "long" ? margin_range[1] - range * progress : margin_range[0] + range * progress;
|
|
62311
|
+
return to_f(price, price_places);
|
|
62312
|
+
});
|
|
62313
|
+
}
|
|
62314
|
+
function getEntries(params) {
|
|
62315
|
+
const {
|
|
62316
|
+
kind,
|
|
62317
|
+
distribution,
|
|
62318
|
+
margin_range,
|
|
62319
|
+
risk_reward,
|
|
62320
|
+
price_places = "%.1f",
|
|
62321
|
+
distribution_params = {}
|
|
62322
|
+
} = params;
|
|
62323
|
+
let entries = [];
|
|
62324
|
+
switch (distribution) {
|
|
62325
|
+
case "arithmetic":
|
|
62326
|
+
entries = generateArithmetic({
|
|
62327
|
+
margin_range,
|
|
62328
|
+
risk_reward,
|
|
62329
|
+
kind,
|
|
62330
|
+
price_places,
|
|
62331
|
+
percent_change: distribution_params.curveFactor
|
|
62332
|
+
});
|
|
62333
|
+
break;
|
|
62334
|
+
case "geometric":
|
|
62335
|
+
entries = generateGeometric({
|
|
62336
|
+
margin_range,
|
|
62337
|
+
risk_reward,
|
|
62338
|
+
kind,
|
|
62339
|
+
price_places,
|
|
62340
|
+
percent_change: distribution_params.curveFactor
|
|
62341
|
+
});
|
|
62342
|
+
break;
|
|
62343
|
+
case "normal":
|
|
62344
|
+
entries = generateNormal({
|
|
62345
|
+
margin_range,
|
|
62346
|
+
risk_reward,
|
|
62347
|
+
kind,
|
|
62348
|
+
price_places,
|
|
62349
|
+
stdDevFactor: distribution_params.stdDevFactor
|
|
62350
|
+
});
|
|
62351
|
+
break;
|
|
62352
|
+
case "exponential":
|
|
62353
|
+
entries = generateExponential({
|
|
62354
|
+
margin_range,
|
|
62355
|
+
risk_reward,
|
|
62356
|
+
kind,
|
|
62357
|
+
price_places,
|
|
62358
|
+
lambda: distribution_params.lambda
|
|
62359
|
+
});
|
|
62360
|
+
break;
|
|
62361
|
+
case "inverse-exponential":
|
|
62362
|
+
entries = generateInverseExponential({
|
|
62363
|
+
margin_range,
|
|
62364
|
+
risk_reward,
|
|
62365
|
+
kind,
|
|
62366
|
+
price_places,
|
|
62367
|
+
curveFactor: distribution_params.curveFactor
|
|
62368
|
+
});
|
|
62369
|
+
break;
|
|
62370
|
+
default:
|
|
62371
|
+
throw new Error(`Unknown distribution type: ${distribution}`);
|
|
62372
|
+
}
|
|
62373
|
+
return entries.sort((a, b) => a - b);
|
|
62374
|
+
}
|
|
62375
|
+
var distributions_default = getEntries;
|
|
62376
|
+
|
|
62219
62377
|
// src/helpers/optimizations.ts
|
|
62220
62378
|
function calculateTheoreticalKelly({
|
|
62221
62379
|
current_entry,
|
|
@@ -62485,6 +62643,10 @@ class Signal {
|
|
|
62485
62643
|
kelly_minimum_risk = 0.2;
|
|
62486
62644
|
kelly_func = "theoretical";
|
|
62487
62645
|
symbol;
|
|
62646
|
+
distribution = {
|
|
62647
|
+
long: "arithmetic",
|
|
62648
|
+
short: "geometric"
|
|
62649
|
+
};
|
|
62488
62650
|
constructor({
|
|
62489
62651
|
focus,
|
|
62490
62652
|
symbol,
|
|
@@ -62511,8 +62673,12 @@ class Signal {
|
|
|
62511
62673
|
kelly_prediction_model = "exponential",
|
|
62512
62674
|
kelly_confidence_factor = 0.6,
|
|
62513
62675
|
kelly_minimum_risk = 0.2,
|
|
62514
|
-
kelly_func = "theoretical"
|
|
62676
|
+
kelly_func = "theoretical",
|
|
62677
|
+
full_distribution
|
|
62515
62678
|
}) {
|
|
62679
|
+
if (full_distribution) {
|
|
62680
|
+
this.distribution = full_distribution;
|
|
62681
|
+
}
|
|
62516
62682
|
this.symbol = symbol;
|
|
62517
62683
|
this.minimum_size = minimum_size;
|
|
62518
62684
|
this.first_order_size = first_order_size;
|
|
@@ -62548,7 +62714,8 @@ class Signal {
|
|
|
62548
62714
|
kind = "long",
|
|
62549
62715
|
risk,
|
|
62550
62716
|
no_of_trades = 1,
|
|
62551
|
-
take_profit
|
|
62717
|
+
take_profit,
|
|
62718
|
+
distribution
|
|
62552
62719
|
}) {
|
|
62553
62720
|
let _stop_loss = stop_loss;
|
|
62554
62721
|
if (!_stop_loss && stop_percent) {
|
|
@@ -62557,16 +62724,22 @@ class Signal {
|
|
|
62557
62724
|
const percent_change = _stop_loss ? Math.max(current_price, _stop_loss) / Math.min(current_price, _stop_loss) - 1 : this.percent_change;
|
|
62558
62725
|
const _no_of_trades = no_of_trades || this.risk_reward;
|
|
62559
62726
|
let _resistance = current_price * Math.pow(1 + percent_change, 1);
|
|
62727
|
+
const simple_support = Math.min(current_price, stop_loss);
|
|
62728
|
+
const simple_resistance = Math.max(current_price, stop_loss);
|
|
62560
62729
|
const derivedConfig = {
|
|
62561
62730
|
...this,
|
|
62562
62731
|
percent_change,
|
|
62563
62732
|
focus: current_price,
|
|
62564
|
-
resistance: _resistance,
|
|
62733
|
+
resistance: distribution ? simple_resistance : _resistance,
|
|
62565
62734
|
risk_per_trade: risk / this.risk_reward,
|
|
62566
62735
|
minimum_pnl: pnl,
|
|
62567
62736
|
risk_reward: _no_of_trades,
|
|
62568
62737
|
take_profit: take_profit || this.take_profit,
|
|
62569
|
-
support: kind === "long" ? _stop_loss : this.support
|
|
62738
|
+
support: distribution ? simple_support : kind === "long" ? _stop_loss : this.support,
|
|
62739
|
+
full_distribution: distribution ? {
|
|
62740
|
+
...this.distribution,
|
|
62741
|
+
[kind]: distribution
|
|
62742
|
+
} : undefined
|
|
62570
62743
|
};
|
|
62571
62744
|
const instance = new Signal(derivedConfig);
|
|
62572
62745
|
if (kind === "short") {}
|
|
@@ -62782,12 +62955,31 @@ class Signal {
|
|
|
62782
62955
|
}
|
|
62783
62956
|
this.zone_risk = original;
|
|
62784
62957
|
}
|
|
62958
|
+
get_future_zones_simple({
|
|
62959
|
+
current_price,
|
|
62960
|
+
kind = "long",
|
|
62961
|
+
raw
|
|
62962
|
+
}) {
|
|
62963
|
+
const margin_zones = [this.support, this.resistance];
|
|
62964
|
+
const distribution = this.distribution ? this.distribution[kind] : "geometric";
|
|
62965
|
+
console.log("margin_zones", { margin_zones, distribution });
|
|
62966
|
+
let _kind = distribution === "inverse-exponential" ? kind === "long" ? "short" : "long" : kind;
|
|
62967
|
+
const entries = distributions_default({
|
|
62968
|
+
margin_range: margin_zones,
|
|
62969
|
+
kind: _kind,
|
|
62970
|
+
distribution,
|
|
62971
|
+
risk_reward: this.risk_reward,
|
|
62972
|
+
price_places: this.price_places
|
|
62973
|
+
});
|
|
62974
|
+
return entries.sort((a, b) => a - b);
|
|
62975
|
+
}
|
|
62785
62976
|
get_future_zones({
|
|
62786
62977
|
current_price,
|
|
62787
62978
|
kind = "long",
|
|
62788
62979
|
raw
|
|
62789
62980
|
}) {
|
|
62790
62981
|
if (raw) {}
|
|
62982
|
+
return this.get_future_zones_simple({ current_price, raw, kind });
|
|
62791
62983
|
const margin_range = this.get_margin_range(current_price, kind);
|
|
62792
62984
|
let margin_zones = this.get_margin_zones({ current_price });
|
|
62793
62985
|
let remaining_zones = margin_zones.filter((x) => JSON.stringify(x) != JSON.stringify(margin_range));
|
|
@@ -63446,7 +63638,9 @@ function buildConfig(app_config, {
|
|
|
63446
63638
|
kelly_confidence_factor = 0.95,
|
|
63447
63639
|
kelly_minimum_risk = 0.2,
|
|
63448
63640
|
kelly_prediction_model = "exponential",
|
|
63449
|
-
kelly_func = "theoretical"
|
|
63641
|
+
kelly_func = "theoretical",
|
|
63642
|
+
min_avg_size = 0,
|
|
63643
|
+
distribution
|
|
63450
63644
|
}) {
|
|
63451
63645
|
let fee = app_config.fee / 100;
|
|
63452
63646
|
let working_risk = risk || app_config.risk_per_trade;
|
|
@@ -63493,9 +63687,12 @@ function buildConfig(app_config, {
|
|
|
63493
63687
|
stop_loss: stop,
|
|
63494
63688
|
risk: working_risk,
|
|
63495
63689
|
kind: kind || app_config.kind,
|
|
63496
|
-
no_of_trades: trade_no
|
|
63690
|
+
no_of_trades: trade_no,
|
|
63691
|
+
distribution
|
|
63497
63692
|
}) || [] : [];
|
|
63498
|
-
|
|
63693
|
+
const new_trades = computeTotalAverageForEachTrade(result, config2);
|
|
63694
|
+
let filtered = new_trades.filter((o) => o.avg_size > min_avg_size);
|
|
63695
|
+
return computeTotalAverageForEachTrade(filtered, config2);
|
|
63499
63696
|
}
|
|
63500
63697
|
function sortedBuildConfig(app_config, options) {
|
|
63501
63698
|
const sorted = buildConfig(app_config, options).sort((a, b) => app_config.kind === "long" ? a.entry - b.entry : b.entry - b.entry).filter((x) => {
|
|
@@ -63547,7 +63744,8 @@ function get_app_config_and_max_size(config2, payload) {
|
|
|
63547
63744
|
kelly_confidence_factor: payload.kelly_confidence_factor,
|
|
63548
63745
|
kelly_minimum_risk: payload.kelly_minimum_risk,
|
|
63549
63746
|
kelly_prediction_model: payload.kelly_prediction_model,
|
|
63550
|
-
kelly_func: payload.kelly_func
|
|
63747
|
+
kelly_func: payload.kelly_func,
|
|
63748
|
+
distribution: payload.distribution
|
|
63551
63749
|
});
|
|
63552
63750
|
const max_size = initialResult[0]?.avg_size;
|
|
63553
63751
|
const last_value = initialResult[0];
|
|
@@ -63585,7 +63783,8 @@ function buildAppConfig(config2, payload) {
|
|
|
63585
63783
|
kelly_confidence_factor: payload.kelly_confidence_factor,
|
|
63586
63784
|
kelly_minimum_risk: payload.kelly_minimum_risk,
|
|
63587
63785
|
kelly_prediction_model: payload.kelly_prediction_model,
|
|
63588
|
-
kelly_func: payload.kelly_func
|
|
63786
|
+
kelly_func: payload.kelly_func,
|
|
63787
|
+
distribution: payload.distribution
|
|
63589
63788
|
});
|
|
63590
63789
|
app_config.max_size = max_size;
|
|
63591
63790
|
app_config.entry = payload.entry || app_config.entry;
|
|
@@ -63602,7 +63801,7 @@ function buildAppConfig(config2, payload) {
|
|
|
63602
63801
|
return app_config;
|
|
63603
63802
|
}
|
|
63604
63803
|
function getOptimumStopAndRisk(app_config, params) {
|
|
63605
|
-
const { max_size, target_stop } = params;
|
|
63804
|
+
const { max_size, target_stop, distribution } = params;
|
|
63606
63805
|
const isLong = app_config.kind === "long";
|
|
63607
63806
|
const stopRange = Math.abs(app_config.entry - target_stop) * 0.5;
|
|
63608
63807
|
let low_stop = isLong ? target_stop - stopRange : Math.max(target_stop - stopRange, app_config.entry);
|
|
@@ -63625,7 +63824,8 @@ function getOptimumStopAndRisk(app_config, params) {
|
|
|
63625
63824
|
increase: true,
|
|
63626
63825
|
gap: app_config.gap,
|
|
63627
63826
|
price_places: app_config.price_places,
|
|
63628
|
-
decimal_places: app_config.decimal_places
|
|
63827
|
+
decimal_places: app_config.decimal_places,
|
|
63828
|
+
distribution
|
|
63629
63829
|
});
|
|
63630
63830
|
if (result.length === 0) {
|
|
63631
63831
|
if (isLong) {
|
|
@@ -63679,7 +63879,8 @@ function getOptimumStopAndRisk(app_config, params) {
|
|
|
63679
63879
|
increase: true,
|
|
63680
63880
|
gap: app_config.gap,
|
|
63681
63881
|
price_places: app_config.price_places,
|
|
63682
|
-
decimal_places: app_config.decimal_places
|
|
63882
|
+
decimal_places: app_config.decimal_places,
|
|
63883
|
+
distribution
|
|
63683
63884
|
});
|
|
63684
63885
|
if (result.length === 0) {
|
|
63685
63886
|
high_risk = mid_risk;
|
|
@@ -63724,7 +63925,8 @@ function getOptimumStopAndRisk(app_config, params) {
|
|
|
63724
63925
|
increase: true,
|
|
63725
63926
|
gap: app_config.gap,
|
|
63726
63927
|
price_places: app_config.price_places,
|
|
63727
|
-
decimal_places: app_config.decimal_places
|
|
63928
|
+
decimal_places: app_config.decimal_places,
|
|
63929
|
+
distribution
|
|
63728
63930
|
});
|
|
63729
63931
|
if (result.length === 0)
|
|
63730
63932
|
continue;
|
|
@@ -63847,7 +64049,8 @@ function generateOptimumAppConfig(config2, payload, position2) {
|
|
|
63847
64049
|
}, {
|
|
63848
64050
|
entry: payload.entry,
|
|
63849
64051
|
stop: payload.stop,
|
|
63850
|
-
kind: position2.kind
|
|
64052
|
+
kind: position2.kind,
|
|
64053
|
+
distribution: payload.distribution
|
|
63851
64054
|
});
|
|
63852
64055
|
current_app_config.max_size = max_size;
|
|
63853
64056
|
current_app_config.last_value = last_value;
|
|
@@ -63862,7 +64065,8 @@ function generateOptimumAppConfig(config2, payload, position2) {
|
|
|
63862
64065
|
increase: true,
|
|
63863
64066
|
gap: current_app_config.gap,
|
|
63864
64067
|
price_places: current_app_config.price_places,
|
|
63865
|
-
decimal_places: current_app_config.decimal_places
|
|
64068
|
+
decimal_places: current_app_config.decimal_places,
|
|
64069
|
+
distribution: payload.distribution
|
|
63866
64070
|
});
|
|
63867
64071
|
if (full_trades.length === 0) {
|
|
63868
64072
|
high_risk = mid_risk;
|
|
@@ -63926,7 +64130,8 @@ function determineOptimumReward(payload) {
|
|
|
63926
64130
|
increase = true,
|
|
63927
64131
|
low_range = 1,
|
|
63928
64132
|
high_range = 199,
|
|
63929
|
-
target_loss
|
|
64133
|
+
target_loss,
|
|
64134
|
+
distribution
|
|
63930
64135
|
} = payload;
|
|
63931
64136
|
const criterion = app_config.strategy || "quantity";
|
|
63932
64137
|
const risk_rewards = createArray(low_range, high_range, 1);
|
|
@@ -63940,7 +64145,8 @@ function determineOptimumReward(payload) {
|
|
|
63940
64145
|
increase,
|
|
63941
64146
|
kind: app_config.kind,
|
|
63942
64147
|
gap: app_config.gap,
|
|
63943
|
-
decimal_places: app_config.decimal_places
|
|
64148
|
+
decimal_places: app_config.decimal_places,
|
|
64149
|
+
distribution
|
|
63944
64150
|
});
|
|
63945
64151
|
let total = 0;
|
|
63946
64152
|
let max = -Infinity;
|
|
@@ -64105,14 +64311,17 @@ function determineOptimumRisk(config2, payload, params) {
|
|
|
64105
64311
|
};
|
|
64106
64312
|
}
|
|
64107
64313
|
function computeRiskReward(payload) {
|
|
64108
|
-
const { app_config, entry, stop, risk_per_trade, target_loss } = payload;
|
|
64314
|
+
const { app_config, entry, stop, risk_per_trade, target_loss, distribution } = payload;
|
|
64109
64315
|
const kind = entry > stop ? "long" : "short";
|
|
64110
64316
|
app_config.kind = kind;
|
|
64111
64317
|
app_config.entry = entry;
|
|
64112
64318
|
app_config.stop = stop;
|
|
64113
64319
|
app_config.risk_per_trade = risk_per_trade;
|
|
64114
|
-
const result = determineOptimumReward({
|
|
64115
|
-
|
|
64320
|
+
const result = determineOptimumReward({
|
|
64321
|
+
app_config,
|
|
64322
|
+
target_loss,
|
|
64323
|
+
distribution
|
|
64324
|
+
});
|
|
64116
64325
|
return result;
|
|
64117
64326
|
}
|
|
64118
64327
|
function getRiskReward(payload) {
|
|
@@ -64122,21 +64331,24 @@ function getRiskReward(payload) {
|
|
|
64122
64331
|
risk,
|
|
64123
64332
|
global_config,
|
|
64124
64333
|
force_exact_risk = false,
|
|
64125
|
-
target_loss
|
|
64334
|
+
target_loss,
|
|
64335
|
+
distribution
|
|
64126
64336
|
} = payload;
|
|
64127
64337
|
const { entries, last_value, ...app_config } = buildAppConfig(global_config, {
|
|
64128
64338
|
entry,
|
|
64129
64339
|
stop,
|
|
64130
64340
|
risk_reward: 30,
|
|
64131
64341
|
risk,
|
|
64132
|
-
symbol: global_config.symbol
|
|
64342
|
+
symbol: global_config.symbol,
|
|
64343
|
+
distribution
|
|
64133
64344
|
});
|
|
64134
64345
|
const risk_reward = computeRiskReward({
|
|
64135
64346
|
app_config,
|
|
64136
64347
|
entry,
|
|
64137
64348
|
stop,
|
|
64138
64349
|
risk_per_trade: risk,
|
|
64139
|
-
target_loss
|
|
64350
|
+
target_loss,
|
|
64351
|
+
distribution
|
|
64140
64352
|
});
|
|
64141
64353
|
if (force_exact_risk) {
|
|
64142
64354
|
const new_risk_per_trade = determineOptimumRisk(global_config, {
|
|
@@ -64144,7 +64356,8 @@ function getRiskReward(payload) {
|
|
|
64144
64356
|
stop,
|
|
64145
64357
|
risk_reward,
|
|
64146
64358
|
risk,
|
|
64147
|
-
symbol: global_config.symbol
|
|
64359
|
+
symbol: global_config.symbol,
|
|
64360
|
+
distribution
|
|
64148
64361
|
}, {
|
|
64149
64362
|
highest_risk: risk
|
|
64150
64363
|
}).optimal_risk;
|
|
@@ -64501,7 +64714,7 @@ function constructAppConfig(payload) {
|
|
|
64501
64714
|
kelly_minimum_risk: kelly_config?.kelly_minimum_risk ?? kelly?.kelly_minimum_risk,
|
|
64502
64715
|
kelly_prediction_model: kelly_config?.kelly_prediction_model ?? kelly?.kelly_prediction_model
|
|
64503
64716
|
};
|
|
64504
|
-
const appConfig = buildAppConfig(global_config, options);
|
|
64717
|
+
const { entries: _entries, ...appConfig } = buildAppConfig(global_config, options);
|
|
64505
64718
|
return appConfig;
|
|
64506
64719
|
}
|
|
64507
64720
|
function generateDangerousConfig(payload) {
|
|
@@ -67460,7 +67673,6 @@ async function reduceMajorPositionEntry(input, accountInfo, trigger2, exchange_i
|
|
|
67460
67673
|
// src/position.ts
|
|
67461
67674
|
var import_https_proxy_agent2 = __toESM(require_dist2());
|
|
67462
67675
|
var import_socks_proxy_agent2 = __toESM(require_dist3());
|
|
67463
|
-
|
|
67464
67676
|
class ExchangePosition {
|
|
67465
67677
|
exchange;
|
|
67466
67678
|
symbol_config;
|
|
@@ -67500,6 +67712,19 @@ class ExchangePosition {
|
|
|
67500
67712
|
const { p_account } = this.instance.expand;
|
|
67501
67713
|
return p_account;
|
|
67502
67714
|
}
|
|
67715
|
+
get compound() {
|
|
67716
|
+
const { compound_instance } = this.instance.expand;
|
|
67717
|
+
if (compound_instance) {
|
|
67718
|
+
const { ref } = compound_instance.expand;
|
|
67719
|
+
const profit_percent = ref.profit_percent / 100;
|
|
67720
|
+
return {
|
|
67721
|
+
...compound_instance,
|
|
67722
|
+
profit_percent,
|
|
67723
|
+
amount_to_risk: to_f(compound_instance.risk * profit_percent, "%.2f")
|
|
67724
|
+
};
|
|
67725
|
+
}
|
|
67726
|
+
return compound_instance;
|
|
67727
|
+
}
|
|
67503
67728
|
async getProxyForAccount() {
|
|
67504
67729
|
if (this.instance.expand.proxy) {
|
|
67505
67730
|
const result = this.instance.expand.proxy;
|
|
@@ -67625,7 +67850,8 @@ class ExchangePosition {
|
|
|
67625
67850
|
place,
|
|
67626
67851
|
raw: payload.raw,
|
|
67627
67852
|
use_current,
|
|
67628
|
-
stop_percent: config2.stop_percent || 100
|
|
67853
|
+
stop_percent: config2.stop_percent || 100,
|
|
67854
|
+
distribution: config2.distribution
|
|
67629
67855
|
});
|
|
67630
67856
|
}
|
|
67631
67857
|
}
|
|
@@ -67659,7 +67885,8 @@ class ExchangePosition {
|
|
|
67659
67885
|
kelly_confidence_factor: config2.kelly?.kelly_confidence_factor,
|
|
67660
67886
|
kelly_minimum_risk: config2.kelly?.kelly_minimum_risk,
|
|
67661
67887
|
kelly_prediction_model: config2.kelly?.kelly_prediction_model,
|
|
67662
|
-
kelly_func: config2.kelly?.kelly_func
|
|
67888
|
+
kelly_func: config2.kelly?.kelly_func,
|
|
67889
|
+
distribution: config2.distribution
|
|
67663
67890
|
}, false);
|
|
67664
67891
|
if (payload.raw) {
|
|
67665
67892
|
let actual_orders_to_buy = await this.determineAmountToBuy({
|
|
@@ -67782,7 +68009,8 @@ class ExchangePosition {
|
|
|
67782
68009
|
kelly_confidence_factor: solution.kelly_confidence_factor,
|
|
67783
68010
|
kelly_minimum_risk: solution.kelly_minimum_risk,
|
|
67784
68011
|
kelly_prediction_model: solution.kelly_prediction_model,
|
|
67785
|
-
kelly_func: solution.kelly_func
|
|
68012
|
+
kelly_func: solution.kelly_func,
|
|
68013
|
+
distribution: solution.distribution
|
|
67786
68014
|
};
|
|
67787
68015
|
const trades = sortedBuildConfig(app_config, options);
|
|
67788
68016
|
const entry_orders = {
|
|
@@ -68174,6 +68402,7 @@ class ExchangePosition {
|
|
|
68174
68402
|
});
|
|
68175
68403
|
}
|
|
68176
68404
|
async generate_config_params(payload) {
|
|
68405
|
+
const db_config = await this.getConfig();
|
|
68177
68406
|
const { entry, stop, risk_reward, risk, with_trades = false } = payload;
|
|
68178
68407
|
const symbol = this.symbol;
|
|
68179
68408
|
const app_config = await this.buildAppConfig({
|
|
@@ -68206,7 +68435,8 @@ class ExchangePosition {
|
|
|
68206
68435
|
avg_size: 0,
|
|
68207
68436
|
neg_pnl: 0,
|
|
68208
68437
|
min_size: app_config2.min_size,
|
|
68209
|
-
symbol
|
|
68438
|
+
symbol,
|
|
68439
|
+
distribution: db_config.distribution
|
|
68210
68440
|
}, false);
|
|
68211
68441
|
config2.trades = trades;
|
|
68212
68442
|
}
|
|
@@ -68307,7 +68537,8 @@ class ExchangePosition {
|
|
|
68307
68537
|
kelly_confidence_factor: config2.kelly?.kelly_confidence_factor,
|
|
68308
68538
|
kelly_minimum_risk: config2.kelly?.kelly_minimum_risk,
|
|
68309
68539
|
kelly_prediction_model: config2.kelly?.kelly_prediction_model,
|
|
68310
|
-
kelly_func: config2.kelly?.kelly_func
|
|
68540
|
+
kelly_func: config2.kelly?.kelly_func,
|
|
68541
|
+
distribution: config2.distribution
|
|
68311
68542
|
});
|
|
68312
68543
|
const position2 = this.instance;
|
|
68313
68544
|
const orders_to_place = await this.determineAmountToBuy({
|
|
@@ -68505,6 +68736,46 @@ class ExchangePosition {
|
|
|
68505
68736
|
increase: false
|
|
68506
68737
|
});
|
|
68507
68738
|
}
|
|
68739
|
+
get support() {
|
|
68740
|
+
return this.instance.expand?.support;
|
|
68741
|
+
}
|
|
68742
|
+
get linkedConfig() {
|
|
68743
|
+
return this.instance.expand?.b_config;
|
|
68744
|
+
}
|
|
68745
|
+
get isActiveTrade() {
|
|
68746
|
+
const config2 = this.linkedConfig;
|
|
68747
|
+
return {
|
|
68748
|
+
config: config2,
|
|
68749
|
+
condition: this.compound && this.support?.price === config2.stop
|
|
68750
|
+
};
|
|
68751
|
+
}
|
|
68752
|
+
async updateCompound(payload) {
|
|
68753
|
+
const pb = this.app_db.pb;
|
|
68754
|
+
const item = this.compound;
|
|
68755
|
+
const new_risk = item.risk + item.amount_to_risk;
|
|
68756
|
+
const { condition, config: config2 } = this.isActiveTrade;
|
|
68757
|
+
if (payload?.place && condition) {
|
|
68758
|
+
await pb.collection("compound_instances").update(item.id, {
|
|
68759
|
+
risk: new_risk
|
|
68760
|
+
});
|
|
68761
|
+
await pb.collection("scheduled_trades").update(config2.id, {
|
|
68762
|
+
profit: to_f(new_risk * item.profit_percent, "%.3f")
|
|
68763
|
+
});
|
|
68764
|
+
}
|
|
68765
|
+
return {
|
|
68766
|
+
support: this.support?.price,
|
|
68767
|
+
counter: this.support?.counter,
|
|
68768
|
+
new_risk,
|
|
68769
|
+
condition,
|
|
68770
|
+
stop: config2.stop
|
|
68771
|
+
};
|
|
68772
|
+
}
|
|
68773
|
+
async cleanOnActiveCompoundInstance() {
|
|
68774
|
+
const { condition } = this.isActiveTrade;
|
|
68775
|
+
if (condition && this.instance.quantity === 0) {
|
|
68776
|
+
await this.cancelOrders({ limit: true });
|
|
68777
|
+
}
|
|
68778
|
+
}
|
|
68508
68779
|
}
|
|
68509
68780
|
function convert_to_exchange_order(order) {
|
|
68510
68781
|
return {
|