@gbozee/ultimate 0.0.2-176 → 0.0.2-178
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 +106 -4
- package/dist/frontend-index.js +211 -25
- package/dist/index.cjs +272 -58
- package/dist/index.d.ts +137 -9
- package/dist/index.js +272 -58
- package/dist/mcp-server.cjs +272 -58
- package/dist/mcp-server.js +272 -58
- package/package.json +1 -1
package/dist/mcp-server.js
CHANGED
|
@@ -61368,13 +61368,29 @@ class AppDatabase {
|
|
|
61368
61368
|
});
|
|
61369
61369
|
return result;
|
|
61370
61370
|
}
|
|
61371
|
+
get positionExpand() {
|
|
61372
|
+
return "b_config, account_strategy, p_account, proxy, compound_instance.ref,support";
|
|
61373
|
+
}
|
|
61374
|
+
async fetchCentralPositions(payload) {
|
|
61375
|
+
const { asset: assetName, symbol } = payload;
|
|
61376
|
+
const pb = this.pb;
|
|
61377
|
+
let symbolFilter = assetName ? `symbol ~ "${assetName}"` : `symbol = "${symbol}"`;
|
|
61378
|
+
if (this.email) {
|
|
61379
|
+
symbolFilter = `${symbolFilter} && p_account.user.email="${this.email}"`;
|
|
61380
|
+
}
|
|
61381
|
+
let positionsWithAssetName = await pb.collection("positions_view").getFullList({
|
|
61382
|
+
filter: symbolFilter,
|
|
61383
|
+
expand: this.positionExpand
|
|
61384
|
+
});
|
|
61385
|
+
return positionsWithAssetName;
|
|
61386
|
+
}
|
|
61371
61387
|
async getPositions(options) {
|
|
61372
61388
|
const { symbol, as_view = false, account, custom_filter } = options;
|
|
61373
61389
|
let default_params = as_view ? {
|
|
61374
61390
|
table: "positions_view",
|
|
61375
61391
|
params: {
|
|
61376
61392
|
filter: `symbol:lower="${symbol.toLowerCase()}" && p_account.owner:lower="${account.owner.toLowerCase()}" && p_account.exchange:lower="${account.exchange.toLowerCase()}"`,
|
|
61377
|
-
expand:
|
|
61393
|
+
expand: this.positionExpand
|
|
61378
61394
|
}
|
|
61379
61395
|
} : {
|
|
61380
61396
|
table: "positions",
|
|
@@ -62216,6 +62232,137 @@ class AppDatabase {
|
|
|
62216
62232
|
// src/exchanges/binance/index.ts
|
|
62217
62233
|
var import_binance = __toESM(require_lib2(), 1);
|
|
62218
62234
|
|
|
62235
|
+
// src/helpers/distributions.ts
|
|
62236
|
+
function generateArithmetic(payload) {
|
|
62237
|
+
const { margin_range, risk_reward, kind, price_places = "%.1f" } = payload;
|
|
62238
|
+
const difference = Math.abs(margin_range[1] - margin_range[0]);
|
|
62239
|
+
const spread = difference / risk_reward;
|
|
62240
|
+
return Array.from({ length: risk_reward + 1 }, (_, i2) => {
|
|
62241
|
+
const price = kind === "long" ? margin_range[1] - spread * i2 : margin_range[0] + spread * i2;
|
|
62242
|
+
return to_f(price, price_places);
|
|
62243
|
+
});
|
|
62244
|
+
}
|
|
62245
|
+
function generateGeometric(payload) {
|
|
62246
|
+
const { margin_range, risk_reward, kind, price_places = "%.1f", percent_change } = payload;
|
|
62247
|
+
const effectivePercentChange = percent_change ?? Math.abs(margin_range[1] / margin_range[0] - 1) / risk_reward;
|
|
62248
|
+
return Array.from({ length: risk_reward + 1 }, (_, i2) => {
|
|
62249
|
+
const price = kind === "long" ? margin_range[1] * Math.pow(1 - effectivePercentChange, i2) : margin_range[0] * Math.pow(1 + effectivePercentChange, i2);
|
|
62250
|
+
return to_f(price, price_places);
|
|
62251
|
+
});
|
|
62252
|
+
}
|
|
62253
|
+
function approximateInverseNormal(p) {
|
|
62254
|
+
p = Math.max(0.0001, Math.min(0.9999, p));
|
|
62255
|
+
if (p < 0.5) {
|
|
62256
|
+
const t2 = Math.sqrt(-2 * Math.log(p));
|
|
62257
|
+
const c0 = 2.515517, c1 = 0.802853, c2 = 0.010328;
|
|
62258
|
+
const d1 = 1.432788, d2 = 0.189269, d3 = 0.001308;
|
|
62259
|
+
return -(t2 - (c0 + c1 * t2 + c2 * t2 * t2) / (1 + d1 * t2 + d2 * t2 * t2 + d3 * t2 * t2 * t2));
|
|
62260
|
+
} else {
|
|
62261
|
+
const t2 = Math.sqrt(-2 * Math.log(1 - p));
|
|
62262
|
+
const c0 = 2.515517, c1 = 0.802853, c2 = 0.010328;
|
|
62263
|
+
const d1 = 1.432788, d2 = 0.189269, d3 = 0.001308;
|
|
62264
|
+
return t2 - (c0 + c1 * t2 + c2 * t2 * t2) / (1 + d1 * t2 + d2 * t2 * t2 + d3 * t2 * t2 * t2);
|
|
62265
|
+
}
|
|
62266
|
+
}
|
|
62267
|
+
function generateNormal(payload) {
|
|
62268
|
+
const { margin_range, risk_reward, kind, price_places = "%.1f", stdDevFactor = 6 } = payload;
|
|
62269
|
+
const mean = (margin_range[0] + margin_range[1]) / 2;
|
|
62270
|
+
const stdDev = Math.abs(margin_range[1] - margin_range[0]) / stdDevFactor;
|
|
62271
|
+
const skew = kind === "long" ? -0.2 : 0.2;
|
|
62272
|
+
const adjustedMean = mean + stdDev * skew;
|
|
62273
|
+
const entries = Array.from({ length: risk_reward + 1 }, (_, i2) => {
|
|
62274
|
+
const p = (i2 + 0.5) / (risk_reward + 1);
|
|
62275
|
+
const z3 = approximateInverseNormal(p);
|
|
62276
|
+
let price = adjustedMean + stdDev * z3;
|
|
62277
|
+
price = Math.max(margin_range[0], Math.min(margin_range[1], price));
|
|
62278
|
+
return to_f(price, price_places);
|
|
62279
|
+
});
|
|
62280
|
+
return entries.sort((a, b) => a - b);
|
|
62281
|
+
}
|
|
62282
|
+
function generateExponential(payload) {
|
|
62283
|
+
const { margin_range, risk_reward, kind, price_places = "%.1f", lambda } = payload;
|
|
62284
|
+
const range = Math.abs(margin_range[1] - margin_range[0]);
|
|
62285
|
+
const effectiveLambda = lambda || 2.5;
|
|
62286
|
+
return Array.from({ length: risk_reward + 1 }, (_, i2) => {
|
|
62287
|
+
const t2 = i2 / risk_reward;
|
|
62288
|
+
const exponentialProgress = 1 - Math.exp(-effectiveLambda * t2);
|
|
62289
|
+
const price = kind === "long" ? margin_range[1] - range * exponentialProgress : margin_range[0] + range * exponentialProgress;
|
|
62290
|
+
return to_f(price, price_places);
|
|
62291
|
+
});
|
|
62292
|
+
}
|
|
62293
|
+
function generateInverseExponential(payload) {
|
|
62294
|
+
const { margin_range, risk_reward, kind, price_places = "%.1f", curveFactor = 2 } = payload;
|
|
62295
|
+
const range = Math.abs(margin_range[1] - margin_range[0]);
|
|
62296
|
+
return Array.from({ length: risk_reward + 1 }, (_, i2) => {
|
|
62297
|
+
const t2 = i2 / risk_reward;
|
|
62298
|
+
const progress = (Math.exp(curveFactor * t2) - 1) / (Math.exp(curveFactor) - 1);
|
|
62299
|
+
const price = kind === "long" ? margin_range[1] - range * progress : margin_range[0] + range * progress;
|
|
62300
|
+
return to_f(price, price_places);
|
|
62301
|
+
});
|
|
62302
|
+
}
|
|
62303
|
+
function getEntries(params) {
|
|
62304
|
+
const {
|
|
62305
|
+
kind,
|
|
62306
|
+
distribution,
|
|
62307
|
+
margin_range,
|
|
62308
|
+
risk_reward,
|
|
62309
|
+
price_places = "%.1f",
|
|
62310
|
+
distribution_params = {}
|
|
62311
|
+
} = params;
|
|
62312
|
+
let entries = [];
|
|
62313
|
+
switch (distribution) {
|
|
62314
|
+
case "arithmetic":
|
|
62315
|
+
entries = generateArithmetic({
|
|
62316
|
+
margin_range,
|
|
62317
|
+
risk_reward,
|
|
62318
|
+
kind,
|
|
62319
|
+
price_places,
|
|
62320
|
+
percent_change: distribution_params.curveFactor
|
|
62321
|
+
});
|
|
62322
|
+
break;
|
|
62323
|
+
case "geometric":
|
|
62324
|
+
entries = generateGeometric({
|
|
62325
|
+
margin_range,
|
|
62326
|
+
risk_reward,
|
|
62327
|
+
kind,
|
|
62328
|
+
price_places,
|
|
62329
|
+
percent_change: distribution_params.curveFactor
|
|
62330
|
+
});
|
|
62331
|
+
break;
|
|
62332
|
+
case "normal":
|
|
62333
|
+
entries = generateNormal({
|
|
62334
|
+
margin_range,
|
|
62335
|
+
risk_reward,
|
|
62336
|
+
kind,
|
|
62337
|
+
price_places,
|
|
62338
|
+
stdDevFactor: distribution_params.stdDevFactor
|
|
62339
|
+
});
|
|
62340
|
+
break;
|
|
62341
|
+
case "exponential":
|
|
62342
|
+
entries = generateExponential({
|
|
62343
|
+
margin_range,
|
|
62344
|
+
risk_reward,
|
|
62345
|
+
kind,
|
|
62346
|
+
price_places,
|
|
62347
|
+
lambda: distribution_params.lambda
|
|
62348
|
+
});
|
|
62349
|
+
break;
|
|
62350
|
+
case "inverse-exponential":
|
|
62351
|
+
entries = generateInverseExponential({
|
|
62352
|
+
margin_range,
|
|
62353
|
+
risk_reward,
|
|
62354
|
+
kind,
|
|
62355
|
+
price_places,
|
|
62356
|
+
curveFactor: distribution_params.curveFactor
|
|
62357
|
+
});
|
|
62358
|
+
break;
|
|
62359
|
+
default:
|
|
62360
|
+
throw new Error(`Unknown distribution type: ${distribution}`);
|
|
62361
|
+
}
|
|
62362
|
+
return entries.sort((a, b) => a - b);
|
|
62363
|
+
}
|
|
62364
|
+
var distributions_default = getEntries;
|
|
62365
|
+
|
|
62219
62366
|
// src/helpers/optimizations.ts
|
|
62220
62367
|
function calculateTheoreticalKelly({
|
|
62221
62368
|
current_entry,
|
|
@@ -62485,6 +62632,10 @@ class Signal {
|
|
|
62485
62632
|
kelly_minimum_risk = 0.2;
|
|
62486
62633
|
kelly_func = "theoretical";
|
|
62487
62634
|
symbol;
|
|
62635
|
+
distribution = {
|
|
62636
|
+
long: "arithmetic",
|
|
62637
|
+
short: "geometric"
|
|
62638
|
+
};
|
|
62488
62639
|
constructor({
|
|
62489
62640
|
focus,
|
|
62490
62641
|
symbol,
|
|
@@ -62511,8 +62662,12 @@ class Signal {
|
|
|
62511
62662
|
kelly_prediction_model = "exponential",
|
|
62512
62663
|
kelly_confidence_factor = 0.6,
|
|
62513
62664
|
kelly_minimum_risk = 0.2,
|
|
62514
|
-
kelly_func = "theoretical"
|
|
62665
|
+
kelly_func = "theoretical",
|
|
62666
|
+
full_distribution
|
|
62515
62667
|
}) {
|
|
62668
|
+
if (full_distribution) {
|
|
62669
|
+
this.distribution = full_distribution;
|
|
62670
|
+
}
|
|
62516
62671
|
this.symbol = symbol;
|
|
62517
62672
|
this.minimum_size = minimum_size;
|
|
62518
62673
|
this.first_order_size = first_order_size;
|
|
@@ -62548,7 +62703,8 @@ class Signal {
|
|
|
62548
62703
|
kind = "long",
|
|
62549
62704
|
risk,
|
|
62550
62705
|
no_of_trades = 1,
|
|
62551
|
-
take_profit
|
|
62706
|
+
take_profit,
|
|
62707
|
+
distribution
|
|
62552
62708
|
}) {
|
|
62553
62709
|
let _stop_loss = stop_loss;
|
|
62554
62710
|
if (!_stop_loss && stop_percent) {
|
|
@@ -62557,16 +62713,22 @@ class Signal {
|
|
|
62557
62713
|
const percent_change = _stop_loss ? Math.max(current_price, _stop_loss) / Math.min(current_price, _stop_loss) - 1 : this.percent_change;
|
|
62558
62714
|
const _no_of_trades = no_of_trades || this.risk_reward;
|
|
62559
62715
|
let _resistance = current_price * Math.pow(1 + percent_change, 1);
|
|
62716
|
+
const simple_support = Math.min(current_price, stop_loss);
|
|
62717
|
+
const simple_resistance = Math.max(current_price, stop_loss);
|
|
62560
62718
|
const derivedConfig = {
|
|
62561
62719
|
...this,
|
|
62562
62720
|
percent_change,
|
|
62563
62721
|
focus: current_price,
|
|
62564
|
-
resistance: _resistance,
|
|
62722
|
+
resistance: distribution ? simple_resistance : _resistance,
|
|
62565
62723
|
risk_per_trade: risk / this.risk_reward,
|
|
62566
62724
|
minimum_pnl: pnl,
|
|
62567
62725
|
risk_reward: _no_of_trades,
|
|
62568
62726
|
take_profit: take_profit || this.take_profit,
|
|
62569
|
-
support: kind === "long" ? _stop_loss : this.support
|
|
62727
|
+
support: distribution ? simple_support : kind === "long" ? _stop_loss : this.support,
|
|
62728
|
+
full_distribution: distribution ? {
|
|
62729
|
+
...this.distribution,
|
|
62730
|
+
[kind]: distribution
|
|
62731
|
+
} : undefined
|
|
62570
62732
|
};
|
|
62571
62733
|
const instance = new Signal(derivedConfig);
|
|
62572
62734
|
if (kind === "short") {}
|
|
@@ -62782,12 +62944,31 @@ class Signal {
|
|
|
62782
62944
|
}
|
|
62783
62945
|
this.zone_risk = original;
|
|
62784
62946
|
}
|
|
62947
|
+
get_future_zones_simple({
|
|
62948
|
+
current_price,
|
|
62949
|
+
kind = "long",
|
|
62950
|
+
raw
|
|
62951
|
+
}) {
|
|
62952
|
+
const margin_zones = [this.support, this.resistance];
|
|
62953
|
+
const distribution = this.distribution ? this.distribution[kind] : "geometric";
|
|
62954
|
+
console.log("margin_zones", { margin_zones, distribution });
|
|
62955
|
+
let _kind = distribution === "inverse-exponential" ? kind === "long" ? "short" : "long" : kind;
|
|
62956
|
+
const entries = distributions_default({
|
|
62957
|
+
margin_range: margin_zones,
|
|
62958
|
+
kind: _kind,
|
|
62959
|
+
distribution,
|
|
62960
|
+
risk_reward: this.risk_reward,
|
|
62961
|
+
price_places: this.price_places
|
|
62962
|
+
});
|
|
62963
|
+
return entries.sort((a, b) => a - b);
|
|
62964
|
+
}
|
|
62785
62965
|
get_future_zones({
|
|
62786
62966
|
current_price,
|
|
62787
62967
|
kind = "long",
|
|
62788
62968
|
raw
|
|
62789
62969
|
}) {
|
|
62790
62970
|
if (raw) {}
|
|
62971
|
+
return this.get_future_zones_simple({ current_price, raw, kind });
|
|
62791
62972
|
const margin_range = this.get_margin_range(current_price, kind);
|
|
62792
62973
|
let margin_zones = this.get_margin_zones({ current_price });
|
|
62793
62974
|
let remaining_zones = margin_zones.filter((x) => JSON.stringify(x) != JSON.stringify(margin_range));
|
|
@@ -63446,7 +63627,9 @@ function buildConfig(app_config, {
|
|
|
63446
63627
|
kelly_confidence_factor = 0.95,
|
|
63447
63628
|
kelly_minimum_risk = 0.2,
|
|
63448
63629
|
kelly_prediction_model = "exponential",
|
|
63449
|
-
kelly_func = "theoretical"
|
|
63630
|
+
kelly_func = "theoretical",
|
|
63631
|
+
min_avg_size = 0,
|
|
63632
|
+
distribution
|
|
63450
63633
|
}) {
|
|
63451
63634
|
let fee = app_config.fee / 100;
|
|
63452
63635
|
let working_risk = risk || app_config.risk_per_trade;
|
|
@@ -63493,9 +63676,12 @@ function buildConfig(app_config, {
|
|
|
63493
63676
|
stop_loss: stop,
|
|
63494
63677
|
risk: working_risk,
|
|
63495
63678
|
kind: kind || app_config.kind,
|
|
63496
|
-
no_of_trades: trade_no
|
|
63679
|
+
no_of_trades: trade_no,
|
|
63680
|
+
distribution
|
|
63497
63681
|
}) || [] : [];
|
|
63498
|
-
|
|
63682
|
+
const new_trades = computeTotalAverageForEachTrade(result, config2);
|
|
63683
|
+
let filtered = new_trades.filter((o) => o.avg_size > min_avg_size);
|
|
63684
|
+
return computeTotalAverageForEachTrade(filtered, config2);
|
|
63499
63685
|
}
|
|
63500
63686
|
function sortedBuildConfig(app_config, options) {
|
|
63501
63687
|
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 +63733,8 @@ function get_app_config_and_max_size(config2, payload) {
|
|
|
63547
63733
|
kelly_confidence_factor: payload.kelly_confidence_factor,
|
|
63548
63734
|
kelly_minimum_risk: payload.kelly_minimum_risk,
|
|
63549
63735
|
kelly_prediction_model: payload.kelly_prediction_model,
|
|
63550
|
-
kelly_func: payload.kelly_func
|
|
63736
|
+
kelly_func: payload.kelly_func,
|
|
63737
|
+
distribution: payload.distribution
|
|
63551
63738
|
});
|
|
63552
63739
|
const max_size = initialResult[0]?.avg_size;
|
|
63553
63740
|
const last_value = initialResult[0];
|
|
@@ -63585,7 +63772,8 @@ function buildAppConfig(config2, payload) {
|
|
|
63585
63772
|
kelly_confidence_factor: payload.kelly_confidence_factor,
|
|
63586
63773
|
kelly_minimum_risk: payload.kelly_minimum_risk,
|
|
63587
63774
|
kelly_prediction_model: payload.kelly_prediction_model,
|
|
63588
|
-
kelly_func: payload.kelly_func
|
|
63775
|
+
kelly_func: payload.kelly_func,
|
|
63776
|
+
distribution: payload.distribution
|
|
63589
63777
|
});
|
|
63590
63778
|
app_config.max_size = max_size;
|
|
63591
63779
|
app_config.entry = payload.entry || app_config.entry;
|
|
@@ -63602,7 +63790,7 @@ function buildAppConfig(config2, payload) {
|
|
|
63602
63790
|
return app_config;
|
|
63603
63791
|
}
|
|
63604
63792
|
function getOptimumStopAndRisk(app_config, params) {
|
|
63605
|
-
const { max_size, target_stop } = params;
|
|
63793
|
+
const { max_size, target_stop, distribution } = params;
|
|
63606
63794
|
const isLong = app_config.kind === "long";
|
|
63607
63795
|
const stopRange = Math.abs(app_config.entry - target_stop) * 0.5;
|
|
63608
63796
|
let low_stop = isLong ? target_stop - stopRange : Math.max(target_stop - stopRange, app_config.entry);
|
|
@@ -63625,7 +63813,8 @@ function getOptimumStopAndRisk(app_config, params) {
|
|
|
63625
63813
|
increase: true,
|
|
63626
63814
|
gap: app_config.gap,
|
|
63627
63815
|
price_places: app_config.price_places,
|
|
63628
|
-
decimal_places: app_config.decimal_places
|
|
63816
|
+
decimal_places: app_config.decimal_places,
|
|
63817
|
+
distribution
|
|
63629
63818
|
});
|
|
63630
63819
|
if (result.length === 0) {
|
|
63631
63820
|
if (isLong) {
|
|
@@ -63679,7 +63868,8 @@ function getOptimumStopAndRisk(app_config, params) {
|
|
|
63679
63868
|
increase: true,
|
|
63680
63869
|
gap: app_config.gap,
|
|
63681
63870
|
price_places: app_config.price_places,
|
|
63682
|
-
decimal_places: app_config.decimal_places
|
|
63871
|
+
decimal_places: app_config.decimal_places,
|
|
63872
|
+
distribution
|
|
63683
63873
|
});
|
|
63684
63874
|
if (result.length === 0) {
|
|
63685
63875
|
high_risk = mid_risk;
|
|
@@ -63724,7 +63914,8 @@ function getOptimumStopAndRisk(app_config, params) {
|
|
|
63724
63914
|
increase: true,
|
|
63725
63915
|
gap: app_config.gap,
|
|
63726
63916
|
price_places: app_config.price_places,
|
|
63727
|
-
decimal_places: app_config.decimal_places
|
|
63917
|
+
decimal_places: app_config.decimal_places,
|
|
63918
|
+
distribution
|
|
63728
63919
|
});
|
|
63729
63920
|
if (result.length === 0)
|
|
63730
63921
|
continue;
|
|
@@ -63847,7 +64038,8 @@ function generateOptimumAppConfig(config2, payload, position2) {
|
|
|
63847
64038
|
}, {
|
|
63848
64039
|
entry: payload.entry,
|
|
63849
64040
|
stop: payload.stop,
|
|
63850
|
-
kind: position2.kind
|
|
64041
|
+
kind: position2.kind,
|
|
64042
|
+
distribution: payload.distribution
|
|
63851
64043
|
});
|
|
63852
64044
|
current_app_config.max_size = max_size;
|
|
63853
64045
|
current_app_config.last_value = last_value;
|
|
@@ -63862,7 +64054,8 @@ function generateOptimumAppConfig(config2, payload, position2) {
|
|
|
63862
64054
|
increase: true,
|
|
63863
64055
|
gap: current_app_config.gap,
|
|
63864
64056
|
price_places: current_app_config.price_places,
|
|
63865
|
-
decimal_places: current_app_config.decimal_places
|
|
64057
|
+
decimal_places: current_app_config.decimal_places,
|
|
64058
|
+
distribution: payload.distribution
|
|
63866
64059
|
});
|
|
63867
64060
|
if (full_trades.length === 0) {
|
|
63868
64061
|
high_risk = mid_risk;
|
|
@@ -63926,7 +64119,8 @@ function determineOptimumReward(payload) {
|
|
|
63926
64119
|
increase = true,
|
|
63927
64120
|
low_range = 1,
|
|
63928
64121
|
high_range = 199,
|
|
63929
|
-
target_loss
|
|
64122
|
+
target_loss,
|
|
64123
|
+
distribution
|
|
63930
64124
|
} = payload;
|
|
63931
64125
|
const criterion = app_config.strategy || "quantity";
|
|
63932
64126
|
const risk_rewards = createArray(low_range, high_range, 1);
|
|
@@ -63940,7 +64134,8 @@ function determineOptimumReward(payload) {
|
|
|
63940
64134
|
increase,
|
|
63941
64135
|
kind: app_config.kind,
|
|
63942
64136
|
gap: app_config.gap,
|
|
63943
|
-
decimal_places: app_config.decimal_places
|
|
64137
|
+
decimal_places: app_config.decimal_places,
|
|
64138
|
+
distribution
|
|
63944
64139
|
});
|
|
63945
64140
|
let total = 0;
|
|
63946
64141
|
let max = -Infinity;
|
|
@@ -64105,14 +64300,17 @@ function determineOptimumRisk(config2, payload, params) {
|
|
|
64105
64300
|
};
|
|
64106
64301
|
}
|
|
64107
64302
|
function computeRiskReward(payload) {
|
|
64108
|
-
const { app_config, entry, stop, risk_per_trade, target_loss } = payload;
|
|
64303
|
+
const { app_config, entry, stop, risk_per_trade, target_loss, distribution } = payload;
|
|
64109
64304
|
const kind = entry > stop ? "long" : "short";
|
|
64110
64305
|
app_config.kind = kind;
|
|
64111
64306
|
app_config.entry = entry;
|
|
64112
64307
|
app_config.stop = stop;
|
|
64113
64308
|
app_config.risk_per_trade = risk_per_trade;
|
|
64114
|
-
const result = determineOptimumReward({
|
|
64115
|
-
|
|
64309
|
+
const result = determineOptimumReward({
|
|
64310
|
+
app_config,
|
|
64311
|
+
target_loss,
|
|
64312
|
+
distribution
|
|
64313
|
+
});
|
|
64116
64314
|
return result;
|
|
64117
64315
|
}
|
|
64118
64316
|
function getRiskReward(payload) {
|
|
@@ -64122,21 +64320,24 @@ function getRiskReward(payload) {
|
|
|
64122
64320
|
risk,
|
|
64123
64321
|
global_config,
|
|
64124
64322
|
force_exact_risk = false,
|
|
64125
|
-
target_loss
|
|
64323
|
+
target_loss,
|
|
64324
|
+
distribution
|
|
64126
64325
|
} = payload;
|
|
64127
64326
|
const { entries, last_value, ...app_config } = buildAppConfig(global_config, {
|
|
64128
64327
|
entry,
|
|
64129
64328
|
stop,
|
|
64130
64329
|
risk_reward: 30,
|
|
64131
64330
|
risk,
|
|
64132
|
-
symbol: global_config.symbol
|
|
64331
|
+
symbol: global_config.symbol,
|
|
64332
|
+
distribution
|
|
64133
64333
|
});
|
|
64134
64334
|
const risk_reward = computeRiskReward({
|
|
64135
64335
|
app_config,
|
|
64136
64336
|
entry,
|
|
64137
64337
|
stop,
|
|
64138
64338
|
risk_per_trade: risk,
|
|
64139
|
-
target_loss
|
|
64339
|
+
target_loss,
|
|
64340
|
+
distribution
|
|
64140
64341
|
});
|
|
64141
64342
|
if (force_exact_risk) {
|
|
64142
64343
|
const new_risk_per_trade = determineOptimumRisk(global_config, {
|
|
@@ -64144,7 +64345,8 @@ function getRiskReward(payload) {
|
|
|
64144
64345
|
stop,
|
|
64145
64346
|
risk_reward,
|
|
64146
64347
|
risk,
|
|
64147
|
-
symbol: global_config.symbol
|
|
64348
|
+
symbol: global_config.symbol,
|
|
64349
|
+
distribution
|
|
64148
64350
|
}, {
|
|
64149
64351
|
highest_risk: risk
|
|
64150
64352
|
}).optimal_risk;
|
|
@@ -64501,7 +64703,7 @@ function constructAppConfig(payload) {
|
|
|
64501
64703
|
kelly_minimum_risk: kelly_config?.kelly_minimum_risk ?? kelly?.kelly_minimum_risk,
|
|
64502
64704
|
kelly_prediction_model: kelly_config?.kelly_prediction_model ?? kelly?.kelly_prediction_model
|
|
64503
64705
|
};
|
|
64504
|
-
const appConfig = buildAppConfig(global_config, options);
|
|
64706
|
+
const { entries: _entries, ...appConfig } = buildAppConfig(global_config, options);
|
|
64505
64707
|
return appConfig;
|
|
64506
64708
|
}
|
|
64507
64709
|
function generateDangerousConfig(payload) {
|
|
@@ -67499,6 +67701,19 @@ class ExchangePosition {
|
|
|
67499
67701
|
const { p_account } = this.instance.expand;
|
|
67500
67702
|
return p_account;
|
|
67501
67703
|
}
|
|
67704
|
+
get compound() {
|
|
67705
|
+
const { compound_instance } = this.instance.expand;
|
|
67706
|
+
if (compound_instance) {
|
|
67707
|
+
const { ref } = compound_instance.expand;
|
|
67708
|
+
const profit_percent = ref.profit_percent / 100;
|
|
67709
|
+
return {
|
|
67710
|
+
...compound_instance,
|
|
67711
|
+
profit_percent,
|
|
67712
|
+
amount_to_risk: to_f(compound_instance.risk * profit_percent, "%.2f")
|
|
67713
|
+
};
|
|
67714
|
+
}
|
|
67715
|
+
return compound_instance;
|
|
67716
|
+
}
|
|
67502
67717
|
async getProxyForAccount() {
|
|
67503
67718
|
if (this.instance.expand.proxy) {
|
|
67504
67719
|
const result = this.instance.expand.proxy;
|
|
@@ -67624,7 +67839,8 @@ class ExchangePosition {
|
|
|
67624
67839
|
place,
|
|
67625
67840
|
raw: payload.raw,
|
|
67626
67841
|
use_current,
|
|
67627
|
-
stop_percent: config2.stop_percent || 100
|
|
67842
|
+
stop_percent: config2.stop_percent || 100,
|
|
67843
|
+
distribution: config2.distribution
|
|
67628
67844
|
});
|
|
67629
67845
|
}
|
|
67630
67846
|
}
|
|
@@ -67658,7 +67874,8 @@ class ExchangePosition {
|
|
|
67658
67874
|
kelly_confidence_factor: config2.kelly?.kelly_confidence_factor,
|
|
67659
67875
|
kelly_minimum_risk: config2.kelly?.kelly_minimum_risk,
|
|
67660
67876
|
kelly_prediction_model: config2.kelly?.kelly_prediction_model,
|
|
67661
|
-
kelly_func: config2.kelly?.kelly_func
|
|
67877
|
+
kelly_func: config2.kelly?.kelly_func,
|
|
67878
|
+
distribution: config2.distribution
|
|
67662
67879
|
}, false);
|
|
67663
67880
|
if (payload.raw) {
|
|
67664
67881
|
let actual_orders_to_buy = await this.determineAmountToBuy({
|
|
@@ -67781,7 +67998,8 @@ class ExchangePosition {
|
|
|
67781
67998
|
kelly_confidence_factor: solution.kelly_confidence_factor,
|
|
67782
67999
|
kelly_minimum_risk: solution.kelly_minimum_risk,
|
|
67783
68000
|
kelly_prediction_model: solution.kelly_prediction_model,
|
|
67784
|
-
kelly_func: solution.kelly_func
|
|
68001
|
+
kelly_func: solution.kelly_func,
|
|
68002
|
+
distribution: solution.distribution
|
|
67785
68003
|
};
|
|
67786
68004
|
const trades = sortedBuildConfig(app_config, options);
|
|
67787
68005
|
const entry_orders = {
|
|
@@ -68173,6 +68391,7 @@ class ExchangePosition {
|
|
|
68173
68391
|
});
|
|
68174
68392
|
}
|
|
68175
68393
|
async generate_config_params(payload) {
|
|
68394
|
+
const db_config = await this.getConfig();
|
|
68176
68395
|
const { entry, stop, risk_reward, risk, with_trades = false } = payload;
|
|
68177
68396
|
const symbol = this.symbol;
|
|
68178
68397
|
const app_config = await this.buildAppConfig({
|
|
@@ -68205,7 +68424,8 @@ class ExchangePosition {
|
|
|
68205
68424
|
avg_size: 0,
|
|
68206
68425
|
neg_pnl: 0,
|
|
68207
68426
|
min_size: app_config2.min_size,
|
|
68208
|
-
symbol
|
|
68427
|
+
symbol,
|
|
68428
|
+
distribution: db_config.distribution
|
|
68209
68429
|
}, false);
|
|
68210
68430
|
config2.trades = trades;
|
|
68211
68431
|
}
|
|
@@ -68306,7 +68526,8 @@ class ExchangePosition {
|
|
|
68306
68526
|
kelly_confidence_factor: config2.kelly?.kelly_confidence_factor,
|
|
68307
68527
|
kelly_minimum_risk: config2.kelly?.kelly_minimum_risk,
|
|
68308
68528
|
kelly_prediction_model: config2.kelly?.kelly_prediction_model,
|
|
68309
|
-
kelly_func: config2.kelly?.kelly_func
|
|
68529
|
+
kelly_func: config2.kelly?.kelly_func,
|
|
68530
|
+
distribution: config2.distribution
|
|
68310
68531
|
});
|
|
68311
68532
|
const position2 = this.instance;
|
|
68312
68533
|
const orders_to_place = await this.determineAmountToBuy({
|
|
@@ -68504,50 +68725,43 @@ class ExchangePosition {
|
|
|
68504
68725
|
increase: false
|
|
68505
68726
|
});
|
|
68506
68727
|
}
|
|
68507
|
-
|
|
68508
|
-
|
|
68509
|
-
|
|
68510
|
-
|
|
68511
|
-
|
|
68512
|
-
|
|
68728
|
+
get support() {
|
|
68729
|
+
return this.instance.expand?.support;
|
|
68730
|
+
}
|
|
68731
|
+
get linkedConfig() {
|
|
68732
|
+
return this.instance.expand?.b_config;
|
|
68733
|
+
}
|
|
68734
|
+
get isActiveTrade() {
|
|
68735
|
+
const config2 = this.linkedConfig;
|
|
68513
68736
|
return {
|
|
68514
68737
|
config: config2,
|
|
68515
|
-
condition:
|
|
68516
|
-
supportTable
|
|
68738
|
+
condition: this.compound && this.support?.price === config2.stop
|
|
68517
68739
|
};
|
|
68518
68740
|
}
|
|
68519
68741
|
async updateCompound(payload) {
|
|
68520
68742
|
const pb = this.app_db.pb;
|
|
68521
|
-
const item =
|
|
68522
|
-
|
|
68523
|
-
}
|
|
68524
|
-
const {
|
|
68525
|
-
expand: { ref }
|
|
68526
|
-
} = item;
|
|
68527
|
-
const risk = item.risk;
|
|
68528
|
-
const percent = ref.profit_percent / 100;
|
|
68529
|
-
const new_risk = risk * (1 + percent);
|
|
68530
|
-
const { condition, supportTable, config: config2 } = await this.isActiveTrade();
|
|
68743
|
+
const item = this.compound;
|
|
68744
|
+
const new_risk = item.risk + item.amount_to_risk;
|
|
68745
|
+
const { condition, config: config2 } = this.isActiveTrade;
|
|
68531
68746
|
if (payload?.place && condition) {
|
|
68532
68747
|
await pb.collection("compound_instances").update(item.id, {
|
|
68533
68748
|
risk: new_risk
|
|
68534
68749
|
});
|
|
68535
68750
|
await pb.collection("scheduled_trades").update(config2.id, {
|
|
68536
|
-
profit: to_f(new_risk *
|
|
68751
|
+
profit: to_f(new_risk * item.profit_percent, "%.3f")
|
|
68537
68752
|
});
|
|
68538
68753
|
}
|
|
68539
68754
|
return {
|
|
68540
|
-
support:
|
|
68541
|
-
counter:
|
|
68542
|
-
new_risk
|
|
68755
|
+
support: this.support?.price,
|
|
68756
|
+
counter: this.support?.counter,
|
|
68757
|
+
new_risk,
|
|
68758
|
+
condition,
|
|
68759
|
+
stop: config2.stop
|
|
68543
68760
|
};
|
|
68544
68761
|
}
|
|
68545
68762
|
async cleanOnActiveCompoundInstance() {
|
|
68546
|
-
const
|
|
68547
|
-
|
|
68548
|
-
});
|
|
68549
|
-
const { condition } = await this.isActiveTrade();
|
|
68550
|
-
if (item && condition && this.instance.quantity === 0) {
|
|
68763
|
+
const { condition } = this.isActiveTrade;
|
|
68764
|
+
if (condition && this.instance.quantity === 0) {
|
|
68551
68765
|
await this.cancelOrders({ limit: true });
|
|
68552
68766
|
}
|
|
68553
68767
|
}
|