@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.cjs
CHANGED
|
@@ -61395,13 +61395,29 @@ class AppDatabase {
|
|
|
61395
61395
|
});
|
|
61396
61396
|
return result;
|
|
61397
61397
|
}
|
|
61398
|
+
get positionExpand() {
|
|
61399
|
+
return "b_config, account_strategy, p_account, proxy, compound_instance.ref,support";
|
|
61400
|
+
}
|
|
61401
|
+
async fetchCentralPositions(payload) {
|
|
61402
|
+
const { asset: assetName, symbol } = payload;
|
|
61403
|
+
const pb = this.pb;
|
|
61404
|
+
let symbolFilter = assetName ? `symbol ~ "${assetName}"` : `symbol = "${symbol}"`;
|
|
61405
|
+
if (this.email) {
|
|
61406
|
+
symbolFilter = `${symbolFilter} && p_account.user.email="${this.email}"`;
|
|
61407
|
+
}
|
|
61408
|
+
let positionsWithAssetName = await pb.collection("positions_view").getFullList({
|
|
61409
|
+
filter: symbolFilter,
|
|
61410
|
+
expand: this.positionExpand
|
|
61411
|
+
});
|
|
61412
|
+
return positionsWithAssetName;
|
|
61413
|
+
}
|
|
61398
61414
|
async getPositions(options) {
|
|
61399
61415
|
const { symbol, as_view = false, account, custom_filter } = options;
|
|
61400
61416
|
let default_params = as_view ? {
|
|
61401
61417
|
table: "positions_view",
|
|
61402
61418
|
params: {
|
|
61403
61419
|
filter: `symbol:lower="${symbol.toLowerCase()}" && p_account.owner:lower="${account.owner.toLowerCase()}" && p_account.exchange:lower="${account.exchange.toLowerCase()}"`,
|
|
61404
|
-
expand:
|
|
61420
|
+
expand: this.positionExpand
|
|
61405
61421
|
}
|
|
61406
61422
|
} : {
|
|
61407
61423
|
table: "positions",
|
|
@@ -62243,6 +62259,137 @@ class AppDatabase {
|
|
|
62243
62259
|
// src/exchanges/binance/index.ts
|
|
62244
62260
|
var import_binance = __toESM(require_lib2());
|
|
62245
62261
|
|
|
62262
|
+
// src/helpers/distributions.ts
|
|
62263
|
+
function generateArithmetic(payload) {
|
|
62264
|
+
const { margin_range, risk_reward, kind, price_places = "%.1f" } = payload;
|
|
62265
|
+
const difference = Math.abs(margin_range[1] - margin_range[0]);
|
|
62266
|
+
const spread = difference / risk_reward;
|
|
62267
|
+
return Array.from({ length: risk_reward + 1 }, (_, i2) => {
|
|
62268
|
+
const price = kind === "long" ? margin_range[1] - spread * i2 : margin_range[0] + spread * i2;
|
|
62269
|
+
return to_f(price, price_places);
|
|
62270
|
+
});
|
|
62271
|
+
}
|
|
62272
|
+
function generateGeometric(payload) {
|
|
62273
|
+
const { margin_range, risk_reward, kind, price_places = "%.1f", percent_change } = payload;
|
|
62274
|
+
const effectivePercentChange = percent_change ?? Math.abs(margin_range[1] / margin_range[0] - 1) / risk_reward;
|
|
62275
|
+
return Array.from({ length: risk_reward + 1 }, (_, i2) => {
|
|
62276
|
+
const price = kind === "long" ? margin_range[1] * Math.pow(1 - effectivePercentChange, i2) : margin_range[0] * Math.pow(1 + effectivePercentChange, i2);
|
|
62277
|
+
return to_f(price, price_places);
|
|
62278
|
+
});
|
|
62279
|
+
}
|
|
62280
|
+
function approximateInverseNormal(p) {
|
|
62281
|
+
p = Math.max(0.0001, Math.min(0.9999, p));
|
|
62282
|
+
if (p < 0.5) {
|
|
62283
|
+
const t2 = Math.sqrt(-2 * Math.log(p));
|
|
62284
|
+
const c0 = 2.515517, c1 = 0.802853, c2 = 0.010328;
|
|
62285
|
+
const d1 = 1.432788, d2 = 0.189269, d3 = 0.001308;
|
|
62286
|
+
return -(t2 - (c0 + c1 * t2 + c2 * t2 * t2) / (1 + d1 * t2 + d2 * t2 * t2 + d3 * t2 * t2 * t2));
|
|
62287
|
+
} else {
|
|
62288
|
+
const t2 = Math.sqrt(-2 * Math.log(1 - p));
|
|
62289
|
+
const c0 = 2.515517, c1 = 0.802853, c2 = 0.010328;
|
|
62290
|
+
const d1 = 1.432788, d2 = 0.189269, d3 = 0.001308;
|
|
62291
|
+
return t2 - (c0 + c1 * t2 + c2 * t2 * t2) / (1 + d1 * t2 + d2 * t2 * t2 + d3 * t2 * t2 * t2);
|
|
62292
|
+
}
|
|
62293
|
+
}
|
|
62294
|
+
function generateNormal(payload) {
|
|
62295
|
+
const { margin_range, risk_reward, kind, price_places = "%.1f", stdDevFactor = 6 } = payload;
|
|
62296
|
+
const mean = (margin_range[0] + margin_range[1]) / 2;
|
|
62297
|
+
const stdDev = Math.abs(margin_range[1] - margin_range[0]) / stdDevFactor;
|
|
62298
|
+
const skew = kind === "long" ? -0.2 : 0.2;
|
|
62299
|
+
const adjustedMean = mean + stdDev * skew;
|
|
62300
|
+
const entries = Array.from({ length: risk_reward + 1 }, (_, i2) => {
|
|
62301
|
+
const p = (i2 + 0.5) / (risk_reward + 1);
|
|
62302
|
+
const z3 = approximateInverseNormal(p);
|
|
62303
|
+
let price = adjustedMean + stdDev * z3;
|
|
62304
|
+
price = Math.max(margin_range[0], Math.min(margin_range[1], price));
|
|
62305
|
+
return to_f(price, price_places);
|
|
62306
|
+
});
|
|
62307
|
+
return entries.sort((a, b) => a - b);
|
|
62308
|
+
}
|
|
62309
|
+
function generateExponential(payload) {
|
|
62310
|
+
const { margin_range, risk_reward, kind, price_places = "%.1f", lambda } = payload;
|
|
62311
|
+
const range = Math.abs(margin_range[1] - margin_range[0]);
|
|
62312
|
+
const effectiveLambda = lambda || 2.5;
|
|
62313
|
+
return Array.from({ length: risk_reward + 1 }, (_, i2) => {
|
|
62314
|
+
const t2 = i2 / risk_reward;
|
|
62315
|
+
const exponentialProgress = 1 - Math.exp(-effectiveLambda * t2);
|
|
62316
|
+
const price = kind === "long" ? margin_range[1] - range * exponentialProgress : margin_range[0] + range * exponentialProgress;
|
|
62317
|
+
return to_f(price, price_places);
|
|
62318
|
+
});
|
|
62319
|
+
}
|
|
62320
|
+
function generateInverseExponential(payload) {
|
|
62321
|
+
const { margin_range, risk_reward, kind, price_places = "%.1f", curveFactor = 2 } = payload;
|
|
62322
|
+
const range = Math.abs(margin_range[1] - margin_range[0]);
|
|
62323
|
+
return Array.from({ length: risk_reward + 1 }, (_, i2) => {
|
|
62324
|
+
const t2 = i2 / risk_reward;
|
|
62325
|
+
const progress = (Math.exp(curveFactor * t2) - 1) / (Math.exp(curveFactor) - 1);
|
|
62326
|
+
const price = kind === "long" ? margin_range[1] - range * progress : margin_range[0] + range * progress;
|
|
62327
|
+
return to_f(price, price_places);
|
|
62328
|
+
});
|
|
62329
|
+
}
|
|
62330
|
+
function getEntries(params) {
|
|
62331
|
+
const {
|
|
62332
|
+
kind,
|
|
62333
|
+
distribution,
|
|
62334
|
+
margin_range,
|
|
62335
|
+
risk_reward,
|
|
62336
|
+
price_places = "%.1f",
|
|
62337
|
+
distribution_params = {}
|
|
62338
|
+
} = params;
|
|
62339
|
+
let entries = [];
|
|
62340
|
+
switch (distribution) {
|
|
62341
|
+
case "arithmetic":
|
|
62342
|
+
entries = generateArithmetic({
|
|
62343
|
+
margin_range,
|
|
62344
|
+
risk_reward,
|
|
62345
|
+
kind,
|
|
62346
|
+
price_places,
|
|
62347
|
+
percent_change: distribution_params.curveFactor
|
|
62348
|
+
});
|
|
62349
|
+
break;
|
|
62350
|
+
case "geometric":
|
|
62351
|
+
entries = generateGeometric({
|
|
62352
|
+
margin_range,
|
|
62353
|
+
risk_reward,
|
|
62354
|
+
kind,
|
|
62355
|
+
price_places,
|
|
62356
|
+
percent_change: distribution_params.curveFactor
|
|
62357
|
+
});
|
|
62358
|
+
break;
|
|
62359
|
+
case "normal":
|
|
62360
|
+
entries = generateNormal({
|
|
62361
|
+
margin_range,
|
|
62362
|
+
risk_reward,
|
|
62363
|
+
kind,
|
|
62364
|
+
price_places,
|
|
62365
|
+
stdDevFactor: distribution_params.stdDevFactor
|
|
62366
|
+
});
|
|
62367
|
+
break;
|
|
62368
|
+
case "exponential":
|
|
62369
|
+
entries = generateExponential({
|
|
62370
|
+
margin_range,
|
|
62371
|
+
risk_reward,
|
|
62372
|
+
kind,
|
|
62373
|
+
price_places,
|
|
62374
|
+
lambda: distribution_params.lambda
|
|
62375
|
+
});
|
|
62376
|
+
break;
|
|
62377
|
+
case "inverse-exponential":
|
|
62378
|
+
entries = generateInverseExponential({
|
|
62379
|
+
margin_range,
|
|
62380
|
+
risk_reward,
|
|
62381
|
+
kind,
|
|
62382
|
+
price_places,
|
|
62383
|
+
curveFactor: distribution_params.curveFactor
|
|
62384
|
+
});
|
|
62385
|
+
break;
|
|
62386
|
+
default:
|
|
62387
|
+
throw new Error(`Unknown distribution type: ${distribution}`);
|
|
62388
|
+
}
|
|
62389
|
+
return entries.sort((a, b) => a - b);
|
|
62390
|
+
}
|
|
62391
|
+
var distributions_default = getEntries;
|
|
62392
|
+
|
|
62246
62393
|
// src/helpers/optimizations.ts
|
|
62247
62394
|
function calculateTheoreticalKelly({
|
|
62248
62395
|
current_entry,
|
|
@@ -62512,6 +62659,10 @@ class Signal {
|
|
|
62512
62659
|
kelly_minimum_risk = 0.2;
|
|
62513
62660
|
kelly_func = "theoretical";
|
|
62514
62661
|
symbol;
|
|
62662
|
+
distribution = {
|
|
62663
|
+
long: "arithmetic",
|
|
62664
|
+
short: "geometric"
|
|
62665
|
+
};
|
|
62515
62666
|
constructor({
|
|
62516
62667
|
focus,
|
|
62517
62668
|
symbol,
|
|
@@ -62538,8 +62689,12 @@ class Signal {
|
|
|
62538
62689
|
kelly_prediction_model = "exponential",
|
|
62539
62690
|
kelly_confidence_factor = 0.6,
|
|
62540
62691
|
kelly_minimum_risk = 0.2,
|
|
62541
|
-
kelly_func = "theoretical"
|
|
62692
|
+
kelly_func = "theoretical",
|
|
62693
|
+
full_distribution
|
|
62542
62694
|
}) {
|
|
62695
|
+
if (full_distribution) {
|
|
62696
|
+
this.distribution = full_distribution;
|
|
62697
|
+
}
|
|
62543
62698
|
this.symbol = symbol;
|
|
62544
62699
|
this.minimum_size = minimum_size;
|
|
62545
62700
|
this.first_order_size = first_order_size;
|
|
@@ -62575,7 +62730,8 @@ class Signal {
|
|
|
62575
62730
|
kind = "long",
|
|
62576
62731
|
risk,
|
|
62577
62732
|
no_of_trades = 1,
|
|
62578
|
-
take_profit
|
|
62733
|
+
take_profit,
|
|
62734
|
+
distribution
|
|
62579
62735
|
}) {
|
|
62580
62736
|
let _stop_loss = stop_loss;
|
|
62581
62737
|
if (!_stop_loss && stop_percent) {
|
|
@@ -62584,16 +62740,22 @@ class Signal {
|
|
|
62584
62740
|
const percent_change = _stop_loss ? Math.max(current_price, _stop_loss) / Math.min(current_price, _stop_loss) - 1 : this.percent_change;
|
|
62585
62741
|
const _no_of_trades = no_of_trades || this.risk_reward;
|
|
62586
62742
|
let _resistance = current_price * Math.pow(1 + percent_change, 1);
|
|
62743
|
+
const simple_support = Math.min(current_price, stop_loss);
|
|
62744
|
+
const simple_resistance = Math.max(current_price, stop_loss);
|
|
62587
62745
|
const derivedConfig = {
|
|
62588
62746
|
...this,
|
|
62589
62747
|
percent_change,
|
|
62590
62748
|
focus: current_price,
|
|
62591
|
-
resistance: _resistance,
|
|
62749
|
+
resistance: distribution ? simple_resistance : _resistance,
|
|
62592
62750
|
risk_per_trade: risk / this.risk_reward,
|
|
62593
62751
|
minimum_pnl: pnl,
|
|
62594
62752
|
risk_reward: _no_of_trades,
|
|
62595
62753
|
take_profit: take_profit || this.take_profit,
|
|
62596
|
-
support: kind === "long" ? _stop_loss : this.support
|
|
62754
|
+
support: distribution ? simple_support : kind === "long" ? _stop_loss : this.support,
|
|
62755
|
+
full_distribution: distribution ? {
|
|
62756
|
+
...this.distribution,
|
|
62757
|
+
[kind]: distribution
|
|
62758
|
+
} : undefined
|
|
62597
62759
|
};
|
|
62598
62760
|
const instance = new Signal(derivedConfig);
|
|
62599
62761
|
if (kind === "short") {}
|
|
@@ -62809,12 +62971,31 @@ class Signal {
|
|
|
62809
62971
|
}
|
|
62810
62972
|
this.zone_risk = original;
|
|
62811
62973
|
}
|
|
62974
|
+
get_future_zones_simple({
|
|
62975
|
+
current_price,
|
|
62976
|
+
kind = "long",
|
|
62977
|
+
raw
|
|
62978
|
+
}) {
|
|
62979
|
+
const margin_zones = [this.support, this.resistance];
|
|
62980
|
+
const distribution = this.distribution ? this.distribution[kind] : "geometric";
|
|
62981
|
+
console.log("margin_zones", { margin_zones, distribution });
|
|
62982
|
+
let _kind = distribution === "inverse-exponential" ? kind === "long" ? "short" : "long" : kind;
|
|
62983
|
+
const entries = distributions_default({
|
|
62984
|
+
margin_range: margin_zones,
|
|
62985
|
+
kind: _kind,
|
|
62986
|
+
distribution,
|
|
62987
|
+
risk_reward: this.risk_reward,
|
|
62988
|
+
price_places: this.price_places
|
|
62989
|
+
});
|
|
62990
|
+
return entries.sort((a, b) => a - b);
|
|
62991
|
+
}
|
|
62812
62992
|
get_future_zones({
|
|
62813
62993
|
current_price,
|
|
62814
62994
|
kind = "long",
|
|
62815
62995
|
raw
|
|
62816
62996
|
}) {
|
|
62817
62997
|
if (raw) {}
|
|
62998
|
+
return this.get_future_zones_simple({ current_price, raw, kind });
|
|
62818
62999
|
const margin_range = this.get_margin_range(current_price, kind);
|
|
62819
63000
|
let margin_zones = this.get_margin_zones({ current_price });
|
|
62820
63001
|
let remaining_zones = margin_zones.filter((x) => JSON.stringify(x) != JSON.stringify(margin_range));
|
|
@@ -63473,7 +63654,9 @@ function buildConfig(app_config, {
|
|
|
63473
63654
|
kelly_confidence_factor = 0.95,
|
|
63474
63655
|
kelly_minimum_risk = 0.2,
|
|
63475
63656
|
kelly_prediction_model = "exponential",
|
|
63476
|
-
kelly_func = "theoretical"
|
|
63657
|
+
kelly_func = "theoretical",
|
|
63658
|
+
min_avg_size = 0,
|
|
63659
|
+
distribution
|
|
63477
63660
|
}) {
|
|
63478
63661
|
let fee = app_config.fee / 100;
|
|
63479
63662
|
let working_risk = risk || app_config.risk_per_trade;
|
|
@@ -63520,9 +63703,12 @@ function buildConfig(app_config, {
|
|
|
63520
63703
|
stop_loss: stop,
|
|
63521
63704
|
risk: working_risk,
|
|
63522
63705
|
kind: kind || app_config.kind,
|
|
63523
|
-
no_of_trades: trade_no
|
|
63706
|
+
no_of_trades: trade_no,
|
|
63707
|
+
distribution
|
|
63524
63708
|
}) || [] : [];
|
|
63525
|
-
|
|
63709
|
+
const new_trades = computeTotalAverageForEachTrade(result, config2);
|
|
63710
|
+
let filtered = new_trades.filter((o) => o.avg_size > min_avg_size);
|
|
63711
|
+
return computeTotalAverageForEachTrade(filtered, config2);
|
|
63526
63712
|
}
|
|
63527
63713
|
function sortedBuildConfig(app_config, options) {
|
|
63528
63714
|
const sorted = buildConfig(app_config, options).sort((a, b) => app_config.kind === "long" ? a.entry - b.entry : b.entry - b.entry).filter((x) => {
|
|
@@ -63574,7 +63760,8 @@ function get_app_config_and_max_size(config2, payload) {
|
|
|
63574
63760
|
kelly_confidence_factor: payload.kelly_confidence_factor,
|
|
63575
63761
|
kelly_minimum_risk: payload.kelly_minimum_risk,
|
|
63576
63762
|
kelly_prediction_model: payload.kelly_prediction_model,
|
|
63577
|
-
kelly_func: payload.kelly_func
|
|
63763
|
+
kelly_func: payload.kelly_func,
|
|
63764
|
+
distribution: payload.distribution
|
|
63578
63765
|
});
|
|
63579
63766
|
const max_size = initialResult[0]?.avg_size;
|
|
63580
63767
|
const last_value = initialResult[0];
|
|
@@ -63612,7 +63799,8 @@ function buildAppConfig(config2, payload) {
|
|
|
63612
63799
|
kelly_confidence_factor: payload.kelly_confidence_factor,
|
|
63613
63800
|
kelly_minimum_risk: payload.kelly_minimum_risk,
|
|
63614
63801
|
kelly_prediction_model: payload.kelly_prediction_model,
|
|
63615
|
-
kelly_func: payload.kelly_func
|
|
63802
|
+
kelly_func: payload.kelly_func,
|
|
63803
|
+
distribution: payload.distribution
|
|
63616
63804
|
});
|
|
63617
63805
|
app_config.max_size = max_size;
|
|
63618
63806
|
app_config.entry = payload.entry || app_config.entry;
|
|
@@ -63629,7 +63817,7 @@ function buildAppConfig(config2, payload) {
|
|
|
63629
63817
|
return app_config;
|
|
63630
63818
|
}
|
|
63631
63819
|
function getOptimumStopAndRisk(app_config, params) {
|
|
63632
|
-
const { max_size, target_stop } = params;
|
|
63820
|
+
const { max_size, target_stop, distribution } = params;
|
|
63633
63821
|
const isLong = app_config.kind === "long";
|
|
63634
63822
|
const stopRange = Math.abs(app_config.entry - target_stop) * 0.5;
|
|
63635
63823
|
let low_stop = isLong ? target_stop - stopRange : Math.max(target_stop - stopRange, app_config.entry);
|
|
@@ -63652,7 +63840,8 @@ function getOptimumStopAndRisk(app_config, params) {
|
|
|
63652
63840
|
increase: true,
|
|
63653
63841
|
gap: app_config.gap,
|
|
63654
63842
|
price_places: app_config.price_places,
|
|
63655
|
-
decimal_places: app_config.decimal_places
|
|
63843
|
+
decimal_places: app_config.decimal_places,
|
|
63844
|
+
distribution
|
|
63656
63845
|
});
|
|
63657
63846
|
if (result.length === 0) {
|
|
63658
63847
|
if (isLong) {
|
|
@@ -63706,7 +63895,8 @@ function getOptimumStopAndRisk(app_config, params) {
|
|
|
63706
63895
|
increase: true,
|
|
63707
63896
|
gap: app_config.gap,
|
|
63708
63897
|
price_places: app_config.price_places,
|
|
63709
|
-
decimal_places: app_config.decimal_places
|
|
63898
|
+
decimal_places: app_config.decimal_places,
|
|
63899
|
+
distribution
|
|
63710
63900
|
});
|
|
63711
63901
|
if (result.length === 0) {
|
|
63712
63902
|
high_risk = mid_risk;
|
|
@@ -63751,7 +63941,8 @@ function getOptimumStopAndRisk(app_config, params) {
|
|
|
63751
63941
|
increase: true,
|
|
63752
63942
|
gap: app_config.gap,
|
|
63753
63943
|
price_places: app_config.price_places,
|
|
63754
|
-
decimal_places: app_config.decimal_places
|
|
63944
|
+
decimal_places: app_config.decimal_places,
|
|
63945
|
+
distribution
|
|
63755
63946
|
});
|
|
63756
63947
|
if (result.length === 0)
|
|
63757
63948
|
continue;
|
|
@@ -63874,7 +64065,8 @@ function generateOptimumAppConfig(config2, payload, position2) {
|
|
|
63874
64065
|
}, {
|
|
63875
64066
|
entry: payload.entry,
|
|
63876
64067
|
stop: payload.stop,
|
|
63877
|
-
kind: position2.kind
|
|
64068
|
+
kind: position2.kind,
|
|
64069
|
+
distribution: payload.distribution
|
|
63878
64070
|
});
|
|
63879
64071
|
current_app_config.max_size = max_size;
|
|
63880
64072
|
current_app_config.last_value = last_value;
|
|
@@ -63889,7 +64081,8 @@ function generateOptimumAppConfig(config2, payload, position2) {
|
|
|
63889
64081
|
increase: true,
|
|
63890
64082
|
gap: current_app_config.gap,
|
|
63891
64083
|
price_places: current_app_config.price_places,
|
|
63892
|
-
decimal_places: current_app_config.decimal_places
|
|
64084
|
+
decimal_places: current_app_config.decimal_places,
|
|
64085
|
+
distribution: payload.distribution
|
|
63893
64086
|
});
|
|
63894
64087
|
if (full_trades.length === 0) {
|
|
63895
64088
|
high_risk = mid_risk;
|
|
@@ -63953,7 +64146,8 @@ function determineOptimumReward(payload) {
|
|
|
63953
64146
|
increase = true,
|
|
63954
64147
|
low_range = 1,
|
|
63955
64148
|
high_range = 199,
|
|
63956
|
-
target_loss
|
|
64149
|
+
target_loss,
|
|
64150
|
+
distribution
|
|
63957
64151
|
} = payload;
|
|
63958
64152
|
const criterion = app_config.strategy || "quantity";
|
|
63959
64153
|
const risk_rewards = createArray(low_range, high_range, 1);
|
|
@@ -63967,7 +64161,8 @@ function determineOptimumReward(payload) {
|
|
|
63967
64161
|
increase,
|
|
63968
64162
|
kind: app_config.kind,
|
|
63969
64163
|
gap: app_config.gap,
|
|
63970
|
-
decimal_places: app_config.decimal_places
|
|
64164
|
+
decimal_places: app_config.decimal_places,
|
|
64165
|
+
distribution
|
|
63971
64166
|
});
|
|
63972
64167
|
let total = 0;
|
|
63973
64168
|
let max = -Infinity;
|
|
@@ -64132,14 +64327,17 @@ function determineOptimumRisk(config2, payload, params) {
|
|
|
64132
64327
|
};
|
|
64133
64328
|
}
|
|
64134
64329
|
function computeRiskReward(payload) {
|
|
64135
|
-
const { app_config, entry, stop, risk_per_trade, target_loss } = payload;
|
|
64330
|
+
const { app_config, entry, stop, risk_per_trade, target_loss, distribution } = payload;
|
|
64136
64331
|
const kind = entry > stop ? "long" : "short";
|
|
64137
64332
|
app_config.kind = kind;
|
|
64138
64333
|
app_config.entry = entry;
|
|
64139
64334
|
app_config.stop = stop;
|
|
64140
64335
|
app_config.risk_per_trade = risk_per_trade;
|
|
64141
|
-
const result = determineOptimumReward({
|
|
64142
|
-
|
|
64336
|
+
const result = determineOptimumReward({
|
|
64337
|
+
app_config,
|
|
64338
|
+
target_loss,
|
|
64339
|
+
distribution
|
|
64340
|
+
});
|
|
64143
64341
|
return result;
|
|
64144
64342
|
}
|
|
64145
64343
|
function getRiskReward(payload) {
|
|
@@ -64149,21 +64347,24 @@ function getRiskReward(payload) {
|
|
|
64149
64347
|
risk,
|
|
64150
64348
|
global_config,
|
|
64151
64349
|
force_exact_risk = false,
|
|
64152
|
-
target_loss
|
|
64350
|
+
target_loss,
|
|
64351
|
+
distribution
|
|
64153
64352
|
} = payload;
|
|
64154
64353
|
const { entries, last_value, ...app_config } = buildAppConfig(global_config, {
|
|
64155
64354
|
entry,
|
|
64156
64355
|
stop,
|
|
64157
64356
|
risk_reward: 30,
|
|
64158
64357
|
risk,
|
|
64159
|
-
symbol: global_config.symbol
|
|
64358
|
+
symbol: global_config.symbol,
|
|
64359
|
+
distribution
|
|
64160
64360
|
});
|
|
64161
64361
|
const risk_reward = computeRiskReward({
|
|
64162
64362
|
app_config,
|
|
64163
64363
|
entry,
|
|
64164
64364
|
stop,
|
|
64165
64365
|
risk_per_trade: risk,
|
|
64166
|
-
target_loss
|
|
64366
|
+
target_loss,
|
|
64367
|
+
distribution
|
|
64167
64368
|
});
|
|
64168
64369
|
if (force_exact_risk) {
|
|
64169
64370
|
const new_risk_per_trade = determineOptimumRisk(global_config, {
|
|
@@ -64171,7 +64372,8 @@ function getRiskReward(payload) {
|
|
|
64171
64372
|
stop,
|
|
64172
64373
|
risk_reward,
|
|
64173
64374
|
risk,
|
|
64174
|
-
symbol: global_config.symbol
|
|
64375
|
+
symbol: global_config.symbol,
|
|
64376
|
+
distribution
|
|
64175
64377
|
}, {
|
|
64176
64378
|
highest_risk: risk
|
|
64177
64379
|
}).optimal_risk;
|
|
@@ -64528,7 +64730,7 @@ function constructAppConfig(payload) {
|
|
|
64528
64730
|
kelly_minimum_risk: kelly_config?.kelly_minimum_risk ?? kelly?.kelly_minimum_risk,
|
|
64529
64731
|
kelly_prediction_model: kelly_config?.kelly_prediction_model ?? kelly?.kelly_prediction_model
|
|
64530
64732
|
};
|
|
64531
|
-
const appConfig = buildAppConfig(global_config, options);
|
|
64733
|
+
const { entries: _entries, ...appConfig } = buildAppConfig(global_config, options);
|
|
64532
64734
|
return appConfig;
|
|
64533
64735
|
}
|
|
64534
64736
|
function generateDangerousConfig(payload) {
|
|
@@ -67526,6 +67728,19 @@ class ExchangePosition {
|
|
|
67526
67728
|
const { p_account } = this.instance.expand;
|
|
67527
67729
|
return p_account;
|
|
67528
67730
|
}
|
|
67731
|
+
get compound() {
|
|
67732
|
+
const { compound_instance } = this.instance.expand;
|
|
67733
|
+
if (compound_instance) {
|
|
67734
|
+
const { ref } = compound_instance.expand;
|
|
67735
|
+
const profit_percent = ref.profit_percent / 100;
|
|
67736
|
+
return {
|
|
67737
|
+
...compound_instance,
|
|
67738
|
+
profit_percent,
|
|
67739
|
+
amount_to_risk: to_f(compound_instance.risk * profit_percent, "%.2f")
|
|
67740
|
+
};
|
|
67741
|
+
}
|
|
67742
|
+
return compound_instance;
|
|
67743
|
+
}
|
|
67529
67744
|
async getProxyForAccount() {
|
|
67530
67745
|
if (this.instance.expand.proxy) {
|
|
67531
67746
|
const result = this.instance.expand.proxy;
|
|
@@ -67651,7 +67866,8 @@ class ExchangePosition {
|
|
|
67651
67866
|
place,
|
|
67652
67867
|
raw: payload.raw,
|
|
67653
67868
|
use_current,
|
|
67654
|
-
stop_percent: config2.stop_percent || 100
|
|
67869
|
+
stop_percent: config2.stop_percent || 100,
|
|
67870
|
+
distribution: config2.distribution
|
|
67655
67871
|
});
|
|
67656
67872
|
}
|
|
67657
67873
|
}
|
|
@@ -67685,7 +67901,8 @@ class ExchangePosition {
|
|
|
67685
67901
|
kelly_confidence_factor: config2.kelly?.kelly_confidence_factor,
|
|
67686
67902
|
kelly_minimum_risk: config2.kelly?.kelly_minimum_risk,
|
|
67687
67903
|
kelly_prediction_model: config2.kelly?.kelly_prediction_model,
|
|
67688
|
-
kelly_func: config2.kelly?.kelly_func
|
|
67904
|
+
kelly_func: config2.kelly?.kelly_func,
|
|
67905
|
+
distribution: config2.distribution
|
|
67689
67906
|
}, false);
|
|
67690
67907
|
if (payload.raw) {
|
|
67691
67908
|
let actual_orders_to_buy = await this.determineAmountToBuy({
|
|
@@ -67808,7 +68025,8 @@ class ExchangePosition {
|
|
|
67808
68025
|
kelly_confidence_factor: solution.kelly_confidence_factor,
|
|
67809
68026
|
kelly_minimum_risk: solution.kelly_minimum_risk,
|
|
67810
68027
|
kelly_prediction_model: solution.kelly_prediction_model,
|
|
67811
|
-
kelly_func: solution.kelly_func
|
|
68028
|
+
kelly_func: solution.kelly_func,
|
|
68029
|
+
distribution: solution.distribution
|
|
67812
68030
|
};
|
|
67813
68031
|
const trades = sortedBuildConfig(app_config, options);
|
|
67814
68032
|
const entry_orders = {
|
|
@@ -68200,6 +68418,7 @@ class ExchangePosition {
|
|
|
68200
68418
|
});
|
|
68201
68419
|
}
|
|
68202
68420
|
async generate_config_params(payload) {
|
|
68421
|
+
const db_config = await this.getConfig();
|
|
68203
68422
|
const { entry, stop, risk_reward, risk, with_trades = false } = payload;
|
|
68204
68423
|
const symbol = this.symbol;
|
|
68205
68424
|
const app_config = await this.buildAppConfig({
|
|
@@ -68232,7 +68451,8 @@ class ExchangePosition {
|
|
|
68232
68451
|
avg_size: 0,
|
|
68233
68452
|
neg_pnl: 0,
|
|
68234
68453
|
min_size: app_config2.min_size,
|
|
68235
|
-
symbol
|
|
68454
|
+
symbol,
|
|
68455
|
+
distribution: db_config.distribution
|
|
68236
68456
|
}, false);
|
|
68237
68457
|
config2.trades = trades;
|
|
68238
68458
|
}
|
|
@@ -68333,7 +68553,8 @@ class ExchangePosition {
|
|
|
68333
68553
|
kelly_confidence_factor: config2.kelly?.kelly_confidence_factor,
|
|
68334
68554
|
kelly_minimum_risk: config2.kelly?.kelly_minimum_risk,
|
|
68335
68555
|
kelly_prediction_model: config2.kelly?.kelly_prediction_model,
|
|
68336
|
-
kelly_func: config2.kelly?.kelly_func
|
|
68556
|
+
kelly_func: config2.kelly?.kelly_func,
|
|
68557
|
+
distribution: config2.distribution
|
|
68337
68558
|
});
|
|
68338
68559
|
const position2 = this.instance;
|
|
68339
68560
|
const orders_to_place = await this.determineAmountToBuy({
|
|
@@ -68531,50 +68752,43 @@ class ExchangePosition {
|
|
|
68531
68752
|
increase: false
|
|
68532
68753
|
});
|
|
68533
68754
|
}
|
|
68534
|
-
|
|
68535
|
-
|
|
68536
|
-
|
|
68537
|
-
|
|
68538
|
-
|
|
68539
|
-
|
|
68755
|
+
get support() {
|
|
68756
|
+
return this.instance.expand?.support;
|
|
68757
|
+
}
|
|
68758
|
+
get linkedConfig() {
|
|
68759
|
+
return this.instance.expand?.b_config;
|
|
68760
|
+
}
|
|
68761
|
+
get isActiveTrade() {
|
|
68762
|
+
const config2 = this.linkedConfig;
|
|
68540
68763
|
return {
|
|
68541
68764
|
config: config2,
|
|
68542
|
-
condition:
|
|
68543
|
-
supportTable
|
|
68765
|
+
condition: this.compound && this.support?.price === config2.stop
|
|
68544
68766
|
};
|
|
68545
68767
|
}
|
|
68546
68768
|
async updateCompound(payload) {
|
|
68547
68769
|
const pb = this.app_db.pb;
|
|
68548
|
-
const item =
|
|
68549
|
-
|
|
68550
|
-
}
|
|
68551
|
-
const {
|
|
68552
|
-
expand: { ref }
|
|
68553
|
-
} = item;
|
|
68554
|
-
const risk = item.risk;
|
|
68555
|
-
const percent = ref.profit_percent / 100;
|
|
68556
|
-
const new_risk = risk * (1 + percent);
|
|
68557
|
-
const { condition, supportTable, config: config2 } = await this.isActiveTrade();
|
|
68770
|
+
const item = this.compound;
|
|
68771
|
+
const new_risk = item.risk + item.amount_to_risk;
|
|
68772
|
+
const { condition, config: config2 } = this.isActiveTrade;
|
|
68558
68773
|
if (payload?.place && condition) {
|
|
68559
68774
|
await pb.collection("compound_instances").update(item.id, {
|
|
68560
68775
|
risk: new_risk
|
|
68561
68776
|
});
|
|
68562
68777
|
await pb.collection("scheduled_trades").update(config2.id, {
|
|
68563
|
-
profit: to_f(new_risk *
|
|
68778
|
+
profit: to_f(new_risk * item.profit_percent, "%.3f")
|
|
68564
68779
|
});
|
|
68565
68780
|
}
|
|
68566
68781
|
return {
|
|
68567
|
-
support:
|
|
68568
|
-
counter:
|
|
68569
|
-
new_risk
|
|
68782
|
+
support: this.support?.price,
|
|
68783
|
+
counter: this.support?.counter,
|
|
68784
|
+
new_risk,
|
|
68785
|
+
condition,
|
|
68786
|
+
stop: config2.stop
|
|
68570
68787
|
};
|
|
68571
68788
|
}
|
|
68572
68789
|
async cleanOnActiveCompoundInstance() {
|
|
68573
|
-
const
|
|
68574
|
-
|
|
68575
|
-
});
|
|
68576
|
-
const { condition } = await this.isActiveTrade();
|
|
68577
|
-
if (item && condition && this.instance.quantity === 0) {
|
|
68790
|
+
const { condition } = this.isActiveTrade;
|
|
68791
|
+
if (condition && this.instance.quantity === 0) {
|
|
68578
68792
|
await this.cancelOrders({ limit: true });
|
|
68579
68793
|
}
|
|
68580
68794
|
}
|