@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/index.cjs
CHANGED
|
@@ -54701,13 +54701,29 @@ class AppDatabase {
|
|
|
54701
54701
|
});
|
|
54702
54702
|
return result;
|
|
54703
54703
|
}
|
|
54704
|
+
get positionExpand() {
|
|
54705
|
+
return "b_config, account_strategy, p_account, proxy, compound_instance.ref,support";
|
|
54706
|
+
}
|
|
54707
|
+
async fetchCentralPositions(payload) {
|
|
54708
|
+
const { asset: assetName, symbol } = payload;
|
|
54709
|
+
const pb = this.pb;
|
|
54710
|
+
let symbolFilter = assetName ? `symbol ~ "${assetName}"` : `symbol = "${symbol}"`;
|
|
54711
|
+
if (this.email) {
|
|
54712
|
+
symbolFilter = `${symbolFilter} && p_account.user.email="${this.email}"`;
|
|
54713
|
+
}
|
|
54714
|
+
let positionsWithAssetName = await pb.collection("positions_view").getFullList({
|
|
54715
|
+
filter: symbolFilter,
|
|
54716
|
+
expand: this.positionExpand
|
|
54717
|
+
});
|
|
54718
|
+
return positionsWithAssetName;
|
|
54719
|
+
}
|
|
54704
54720
|
async getPositions(options) {
|
|
54705
54721
|
const { symbol, as_view = false, account, custom_filter } = options;
|
|
54706
54722
|
let default_params = as_view ? {
|
|
54707
54723
|
table: "positions_view",
|
|
54708
54724
|
params: {
|
|
54709
54725
|
filter: `symbol:lower="${symbol.toLowerCase()}" && p_account.owner:lower="${account.owner.toLowerCase()}" && p_account.exchange:lower="${account.exchange.toLowerCase()}"`,
|
|
54710
|
-
expand:
|
|
54726
|
+
expand: this.positionExpand
|
|
54711
54727
|
}
|
|
54712
54728
|
} : {
|
|
54713
54729
|
table: "positions",
|
|
@@ -55556,6 +55572,137 @@ __export(exports_exchange_account, {
|
|
|
55556
55572
|
// src/exchanges/binance/index.ts
|
|
55557
55573
|
var import_binance = __toESM(require_lib2());
|
|
55558
55574
|
|
|
55575
|
+
// src/helpers/distributions.ts
|
|
55576
|
+
function generateArithmetic(payload) {
|
|
55577
|
+
const { margin_range, risk_reward, kind, price_places = "%.1f" } = payload;
|
|
55578
|
+
const difference = Math.abs(margin_range[1] - margin_range[0]);
|
|
55579
|
+
const spread = difference / risk_reward;
|
|
55580
|
+
return Array.from({ length: risk_reward + 1 }, (_, i2) => {
|
|
55581
|
+
const price = kind === "long" ? margin_range[1] - spread * i2 : margin_range[0] + spread * i2;
|
|
55582
|
+
return to_f(price, price_places);
|
|
55583
|
+
});
|
|
55584
|
+
}
|
|
55585
|
+
function generateGeometric(payload) {
|
|
55586
|
+
const { margin_range, risk_reward, kind, price_places = "%.1f", percent_change } = payload;
|
|
55587
|
+
const effectivePercentChange = percent_change ?? Math.abs(margin_range[1] / margin_range[0] - 1) / risk_reward;
|
|
55588
|
+
return Array.from({ length: risk_reward + 1 }, (_, i2) => {
|
|
55589
|
+
const price = kind === "long" ? margin_range[1] * Math.pow(1 - effectivePercentChange, i2) : margin_range[0] * Math.pow(1 + effectivePercentChange, i2);
|
|
55590
|
+
return to_f(price, price_places);
|
|
55591
|
+
});
|
|
55592
|
+
}
|
|
55593
|
+
function approximateInverseNormal(p) {
|
|
55594
|
+
p = Math.max(0.0001, Math.min(0.9999, p));
|
|
55595
|
+
if (p < 0.5) {
|
|
55596
|
+
const t2 = Math.sqrt(-2 * Math.log(p));
|
|
55597
|
+
const c0 = 2.515517, c1 = 0.802853, c2 = 0.010328;
|
|
55598
|
+
const d1 = 1.432788, d2 = 0.189269, d3 = 0.001308;
|
|
55599
|
+
return -(t2 - (c0 + c1 * t2 + c2 * t2 * t2) / (1 + d1 * t2 + d2 * t2 * t2 + d3 * t2 * t2 * t2));
|
|
55600
|
+
} else {
|
|
55601
|
+
const t2 = Math.sqrt(-2 * Math.log(1 - p));
|
|
55602
|
+
const c0 = 2.515517, c1 = 0.802853, c2 = 0.010328;
|
|
55603
|
+
const d1 = 1.432788, d2 = 0.189269, d3 = 0.001308;
|
|
55604
|
+
return t2 - (c0 + c1 * t2 + c2 * t2 * t2) / (1 + d1 * t2 + d2 * t2 * t2 + d3 * t2 * t2 * t2);
|
|
55605
|
+
}
|
|
55606
|
+
}
|
|
55607
|
+
function generateNormal(payload) {
|
|
55608
|
+
const { margin_range, risk_reward, kind, price_places = "%.1f", stdDevFactor = 6 } = payload;
|
|
55609
|
+
const mean = (margin_range[0] + margin_range[1]) / 2;
|
|
55610
|
+
const stdDev = Math.abs(margin_range[1] - margin_range[0]) / stdDevFactor;
|
|
55611
|
+
const skew = kind === "long" ? -0.2 : 0.2;
|
|
55612
|
+
const adjustedMean = mean + stdDev * skew;
|
|
55613
|
+
const entries = Array.from({ length: risk_reward + 1 }, (_, i2) => {
|
|
55614
|
+
const p = (i2 + 0.5) / (risk_reward + 1);
|
|
55615
|
+
const z2 = approximateInverseNormal(p);
|
|
55616
|
+
let price = adjustedMean + stdDev * z2;
|
|
55617
|
+
price = Math.max(margin_range[0], Math.min(margin_range[1], price));
|
|
55618
|
+
return to_f(price, price_places);
|
|
55619
|
+
});
|
|
55620
|
+
return entries.sort((a, b) => a - b);
|
|
55621
|
+
}
|
|
55622
|
+
function generateExponential(payload) {
|
|
55623
|
+
const { margin_range, risk_reward, kind, price_places = "%.1f", lambda } = payload;
|
|
55624
|
+
const range = Math.abs(margin_range[1] - margin_range[0]);
|
|
55625
|
+
const effectiveLambda = lambda || 2.5;
|
|
55626
|
+
return Array.from({ length: risk_reward + 1 }, (_, i2) => {
|
|
55627
|
+
const t2 = i2 / risk_reward;
|
|
55628
|
+
const exponentialProgress = 1 - Math.exp(-effectiveLambda * t2);
|
|
55629
|
+
const price = kind === "long" ? margin_range[1] - range * exponentialProgress : margin_range[0] + range * exponentialProgress;
|
|
55630
|
+
return to_f(price, price_places);
|
|
55631
|
+
});
|
|
55632
|
+
}
|
|
55633
|
+
function generateInverseExponential(payload) {
|
|
55634
|
+
const { margin_range, risk_reward, kind, price_places = "%.1f", curveFactor = 2 } = payload;
|
|
55635
|
+
const range = Math.abs(margin_range[1] - margin_range[0]);
|
|
55636
|
+
return Array.from({ length: risk_reward + 1 }, (_, i2) => {
|
|
55637
|
+
const t2 = i2 / risk_reward;
|
|
55638
|
+
const progress = (Math.exp(curveFactor * t2) - 1) / (Math.exp(curveFactor) - 1);
|
|
55639
|
+
const price = kind === "long" ? margin_range[1] - range * progress : margin_range[0] + range * progress;
|
|
55640
|
+
return to_f(price, price_places);
|
|
55641
|
+
});
|
|
55642
|
+
}
|
|
55643
|
+
function getEntries(params) {
|
|
55644
|
+
const {
|
|
55645
|
+
kind,
|
|
55646
|
+
distribution,
|
|
55647
|
+
margin_range,
|
|
55648
|
+
risk_reward,
|
|
55649
|
+
price_places = "%.1f",
|
|
55650
|
+
distribution_params = {}
|
|
55651
|
+
} = params;
|
|
55652
|
+
let entries = [];
|
|
55653
|
+
switch (distribution) {
|
|
55654
|
+
case "arithmetic":
|
|
55655
|
+
entries = generateArithmetic({
|
|
55656
|
+
margin_range,
|
|
55657
|
+
risk_reward,
|
|
55658
|
+
kind,
|
|
55659
|
+
price_places,
|
|
55660
|
+
percent_change: distribution_params.curveFactor
|
|
55661
|
+
});
|
|
55662
|
+
break;
|
|
55663
|
+
case "geometric":
|
|
55664
|
+
entries = generateGeometric({
|
|
55665
|
+
margin_range,
|
|
55666
|
+
risk_reward,
|
|
55667
|
+
kind,
|
|
55668
|
+
price_places,
|
|
55669
|
+
percent_change: distribution_params.curveFactor
|
|
55670
|
+
});
|
|
55671
|
+
break;
|
|
55672
|
+
case "normal":
|
|
55673
|
+
entries = generateNormal({
|
|
55674
|
+
margin_range,
|
|
55675
|
+
risk_reward,
|
|
55676
|
+
kind,
|
|
55677
|
+
price_places,
|
|
55678
|
+
stdDevFactor: distribution_params.stdDevFactor
|
|
55679
|
+
});
|
|
55680
|
+
break;
|
|
55681
|
+
case "exponential":
|
|
55682
|
+
entries = generateExponential({
|
|
55683
|
+
margin_range,
|
|
55684
|
+
risk_reward,
|
|
55685
|
+
kind,
|
|
55686
|
+
price_places,
|
|
55687
|
+
lambda: distribution_params.lambda
|
|
55688
|
+
});
|
|
55689
|
+
break;
|
|
55690
|
+
case "inverse-exponential":
|
|
55691
|
+
entries = generateInverseExponential({
|
|
55692
|
+
margin_range,
|
|
55693
|
+
risk_reward,
|
|
55694
|
+
kind,
|
|
55695
|
+
price_places,
|
|
55696
|
+
curveFactor: distribution_params.curveFactor
|
|
55697
|
+
});
|
|
55698
|
+
break;
|
|
55699
|
+
default:
|
|
55700
|
+
throw new Error(`Unknown distribution type: ${distribution}`);
|
|
55701
|
+
}
|
|
55702
|
+
return entries.sort((a, b) => a - b);
|
|
55703
|
+
}
|
|
55704
|
+
var distributions_default = getEntries;
|
|
55705
|
+
|
|
55559
55706
|
// src/helpers/optimizations.ts
|
|
55560
55707
|
function calculateTheoreticalKelly({
|
|
55561
55708
|
current_entry,
|
|
@@ -55825,6 +55972,10 @@ class Signal {
|
|
|
55825
55972
|
kelly_minimum_risk = 0.2;
|
|
55826
55973
|
kelly_func = "theoretical";
|
|
55827
55974
|
symbol;
|
|
55975
|
+
distribution = {
|
|
55976
|
+
long: "arithmetic",
|
|
55977
|
+
short: "geometric"
|
|
55978
|
+
};
|
|
55828
55979
|
constructor({
|
|
55829
55980
|
focus,
|
|
55830
55981
|
symbol,
|
|
@@ -55851,8 +56002,12 @@ class Signal {
|
|
|
55851
56002
|
kelly_prediction_model = "exponential",
|
|
55852
56003
|
kelly_confidence_factor = 0.6,
|
|
55853
56004
|
kelly_minimum_risk = 0.2,
|
|
55854
|
-
kelly_func = "theoretical"
|
|
56005
|
+
kelly_func = "theoretical",
|
|
56006
|
+
full_distribution
|
|
55855
56007
|
}) {
|
|
56008
|
+
if (full_distribution) {
|
|
56009
|
+
this.distribution = full_distribution;
|
|
56010
|
+
}
|
|
55856
56011
|
this.symbol = symbol;
|
|
55857
56012
|
this.minimum_size = minimum_size;
|
|
55858
56013
|
this.first_order_size = first_order_size;
|
|
@@ -55888,7 +56043,8 @@ class Signal {
|
|
|
55888
56043
|
kind = "long",
|
|
55889
56044
|
risk,
|
|
55890
56045
|
no_of_trades = 1,
|
|
55891
|
-
take_profit
|
|
56046
|
+
take_profit,
|
|
56047
|
+
distribution
|
|
55892
56048
|
}) {
|
|
55893
56049
|
let _stop_loss = stop_loss;
|
|
55894
56050
|
if (!_stop_loss && stop_percent) {
|
|
@@ -55897,16 +56053,22 @@ class Signal {
|
|
|
55897
56053
|
const percent_change = _stop_loss ? Math.max(current_price, _stop_loss) / Math.min(current_price, _stop_loss) - 1 : this.percent_change;
|
|
55898
56054
|
const _no_of_trades = no_of_trades || this.risk_reward;
|
|
55899
56055
|
let _resistance = current_price * Math.pow(1 + percent_change, 1);
|
|
56056
|
+
const simple_support = Math.min(current_price, stop_loss);
|
|
56057
|
+
const simple_resistance = Math.max(current_price, stop_loss);
|
|
55900
56058
|
const derivedConfig = {
|
|
55901
56059
|
...this,
|
|
55902
56060
|
percent_change,
|
|
55903
56061
|
focus: current_price,
|
|
55904
|
-
resistance: _resistance,
|
|
56062
|
+
resistance: distribution ? simple_resistance : _resistance,
|
|
55905
56063
|
risk_per_trade: risk / this.risk_reward,
|
|
55906
56064
|
minimum_pnl: pnl,
|
|
55907
56065
|
risk_reward: _no_of_trades,
|
|
55908
56066
|
take_profit: take_profit || this.take_profit,
|
|
55909
|
-
support: kind === "long" ? _stop_loss : this.support
|
|
56067
|
+
support: distribution ? simple_support : kind === "long" ? _stop_loss : this.support,
|
|
56068
|
+
full_distribution: distribution ? {
|
|
56069
|
+
...this.distribution,
|
|
56070
|
+
[kind]: distribution
|
|
56071
|
+
} : undefined
|
|
55910
56072
|
};
|
|
55911
56073
|
const instance = new Signal(derivedConfig);
|
|
55912
56074
|
if (kind === "short") {}
|
|
@@ -56122,12 +56284,31 @@ class Signal {
|
|
|
56122
56284
|
}
|
|
56123
56285
|
this.zone_risk = original;
|
|
56124
56286
|
}
|
|
56287
|
+
get_future_zones_simple({
|
|
56288
|
+
current_price,
|
|
56289
|
+
kind = "long",
|
|
56290
|
+
raw
|
|
56291
|
+
}) {
|
|
56292
|
+
const margin_zones = [this.support, this.resistance];
|
|
56293
|
+
const distribution = this.distribution ? this.distribution[kind] : "geometric";
|
|
56294
|
+
console.log("margin_zones", { margin_zones, distribution });
|
|
56295
|
+
let _kind = distribution === "inverse-exponential" ? kind === "long" ? "short" : "long" : kind;
|
|
56296
|
+
const entries = distributions_default({
|
|
56297
|
+
margin_range: margin_zones,
|
|
56298
|
+
kind: _kind,
|
|
56299
|
+
distribution,
|
|
56300
|
+
risk_reward: this.risk_reward,
|
|
56301
|
+
price_places: this.price_places
|
|
56302
|
+
});
|
|
56303
|
+
return entries.sort((a, b) => a - b);
|
|
56304
|
+
}
|
|
56125
56305
|
get_future_zones({
|
|
56126
56306
|
current_price,
|
|
56127
56307
|
kind = "long",
|
|
56128
56308
|
raw
|
|
56129
56309
|
}) {
|
|
56130
56310
|
if (raw) {}
|
|
56311
|
+
return this.get_future_zones_simple({ current_price, raw, kind });
|
|
56131
56312
|
const margin_range = this.get_margin_range(current_price, kind);
|
|
56132
56313
|
let margin_zones = this.get_margin_zones({ current_price });
|
|
56133
56314
|
let remaining_zones = margin_zones.filter((x) => JSON.stringify(x) != JSON.stringify(margin_range));
|
|
@@ -56786,7 +56967,9 @@ function buildConfig(app_config, {
|
|
|
56786
56967
|
kelly_confidence_factor = 0.95,
|
|
56787
56968
|
kelly_minimum_risk = 0.2,
|
|
56788
56969
|
kelly_prediction_model = "exponential",
|
|
56789
|
-
kelly_func = "theoretical"
|
|
56970
|
+
kelly_func = "theoretical",
|
|
56971
|
+
min_avg_size = 0,
|
|
56972
|
+
distribution
|
|
56790
56973
|
}) {
|
|
56791
56974
|
let fee = app_config.fee / 100;
|
|
56792
56975
|
let working_risk = risk || app_config.risk_per_trade;
|
|
@@ -56833,9 +57016,12 @@ function buildConfig(app_config, {
|
|
|
56833
57016
|
stop_loss: stop,
|
|
56834
57017
|
risk: working_risk,
|
|
56835
57018
|
kind: kind || app_config.kind,
|
|
56836
|
-
no_of_trades: trade_no
|
|
57019
|
+
no_of_trades: trade_no,
|
|
57020
|
+
distribution
|
|
56837
57021
|
}) || [] : [];
|
|
56838
|
-
|
|
57022
|
+
const new_trades = computeTotalAverageForEachTrade(result, config2);
|
|
57023
|
+
let filtered = new_trades.filter((o) => o.avg_size > min_avg_size);
|
|
57024
|
+
return computeTotalAverageForEachTrade(filtered, config2);
|
|
56839
57025
|
}
|
|
56840
57026
|
function buildAvg({
|
|
56841
57027
|
_trades,
|
|
@@ -56900,7 +57086,8 @@ function get_app_config_and_max_size(config2, payload) {
|
|
|
56900
57086
|
kelly_confidence_factor: payload.kelly_confidence_factor,
|
|
56901
57087
|
kelly_minimum_risk: payload.kelly_minimum_risk,
|
|
56902
57088
|
kelly_prediction_model: payload.kelly_prediction_model,
|
|
56903
|
-
kelly_func: payload.kelly_func
|
|
57089
|
+
kelly_func: payload.kelly_func,
|
|
57090
|
+
distribution: payload.distribution
|
|
56904
57091
|
});
|
|
56905
57092
|
const max_size = initialResult[0]?.avg_size;
|
|
56906
57093
|
const last_value = initialResult[0];
|
|
@@ -56938,7 +57125,8 @@ function buildAppConfig(config2, payload) {
|
|
|
56938
57125
|
kelly_confidence_factor: payload.kelly_confidence_factor,
|
|
56939
57126
|
kelly_minimum_risk: payload.kelly_minimum_risk,
|
|
56940
57127
|
kelly_prediction_model: payload.kelly_prediction_model,
|
|
56941
|
-
kelly_func: payload.kelly_func
|
|
57128
|
+
kelly_func: payload.kelly_func,
|
|
57129
|
+
distribution: payload.distribution
|
|
56942
57130
|
});
|
|
56943
57131
|
app_config.max_size = max_size;
|
|
56944
57132
|
app_config.entry = payload.entry || app_config.entry;
|
|
@@ -56955,7 +57143,7 @@ function buildAppConfig(config2, payload) {
|
|
|
56955
57143
|
return app_config;
|
|
56956
57144
|
}
|
|
56957
57145
|
function getOptimumStopAndRisk(app_config, params) {
|
|
56958
|
-
const { max_size, target_stop } = params;
|
|
57146
|
+
const { max_size, target_stop, distribution } = params;
|
|
56959
57147
|
const isLong = app_config.kind === "long";
|
|
56960
57148
|
const stopRange = Math.abs(app_config.entry - target_stop) * 0.5;
|
|
56961
57149
|
let low_stop = isLong ? target_stop - stopRange : Math.max(target_stop - stopRange, app_config.entry);
|
|
@@ -56978,7 +57166,8 @@ function getOptimumStopAndRisk(app_config, params) {
|
|
|
56978
57166
|
increase: true,
|
|
56979
57167
|
gap: app_config.gap,
|
|
56980
57168
|
price_places: app_config.price_places,
|
|
56981
|
-
decimal_places: app_config.decimal_places
|
|
57169
|
+
decimal_places: app_config.decimal_places,
|
|
57170
|
+
distribution
|
|
56982
57171
|
});
|
|
56983
57172
|
if (result.length === 0) {
|
|
56984
57173
|
if (isLong) {
|
|
@@ -57032,7 +57221,8 @@ function getOptimumStopAndRisk(app_config, params) {
|
|
|
57032
57221
|
increase: true,
|
|
57033
57222
|
gap: app_config.gap,
|
|
57034
57223
|
price_places: app_config.price_places,
|
|
57035
|
-
decimal_places: app_config.decimal_places
|
|
57224
|
+
decimal_places: app_config.decimal_places,
|
|
57225
|
+
distribution
|
|
57036
57226
|
});
|
|
57037
57227
|
if (result.length === 0) {
|
|
57038
57228
|
high_risk = mid_risk;
|
|
@@ -57077,7 +57267,8 @@ function getOptimumStopAndRisk(app_config, params) {
|
|
|
57077
57267
|
increase: true,
|
|
57078
57268
|
gap: app_config.gap,
|
|
57079
57269
|
price_places: app_config.price_places,
|
|
57080
|
-
decimal_places: app_config.decimal_places
|
|
57270
|
+
decimal_places: app_config.decimal_places,
|
|
57271
|
+
distribution
|
|
57081
57272
|
});
|
|
57082
57273
|
if (result.length === 0)
|
|
57083
57274
|
continue;
|
|
@@ -57200,7 +57391,8 @@ function generateOptimumAppConfig(config2, payload, position2) {
|
|
|
57200
57391
|
}, {
|
|
57201
57392
|
entry: payload.entry,
|
|
57202
57393
|
stop: payload.stop,
|
|
57203
|
-
kind: position2.kind
|
|
57394
|
+
kind: position2.kind,
|
|
57395
|
+
distribution: payload.distribution
|
|
57204
57396
|
});
|
|
57205
57397
|
current_app_config.max_size = max_size;
|
|
57206
57398
|
current_app_config.last_value = last_value;
|
|
@@ -57215,7 +57407,8 @@ function generateOptimumAppConfig(config2, payload, position2) {
|
|
|
57215
57407
|
increase: true,
|
|
57216
57408
|
gap: current_app_config.gap,
|
|
57217
57409
|
price_places: current_app_config.price_places,
|
|
57218
|
-
decimal_places: current_app_config.decimal_places
|
|
57410
|
+
decimal_places: current_app_config.decimal_places,
|
|
57411
|
+
distribution: payload.distribution
|
|
57219
57412
|
});
|
|
57220
57413
|
if (full_trades.length === 0) {
|
|
57221
57414
|
high_risk = mid_risk;
|
|
@@ -57279,7 +57472,8 @@ function determineOptimumReward(payload) {
|
|
|
57279
57472
|
increase = true,
|
|
57280
57473
|
low_range = 1,
|
|
57281
57474
|
high_range = 199,
|
|
57282
|
-
target_loss
|
|
57475
|
+
target_loss,
|
|
57476
|
+
distribution
|
|
57283
57477
|
} = payload;
|
|
57284
57478
|
const criterion = app_config.strategy || "quantity";
|
|
57285
57479
|
const risk_rewards = createArray(low_range, high_range, 1);
|
|
@@ -57293,7 +57487,8 @@ function determineOptimumReward(payload) {
|
|
|
57293
57487
|
increase,
|
|
57294
57488
|
kind: app_config.kind,
|
|
57295
57489
|
gap: app_config.gap,
|
|
57296
|
-
decimal_places: app_config.decimal_places
|
|
57490
|
+
decimal_places: app_config.decimal_places,
|
|
57491
|
+
distribution
|
|
57297
57492
|
});
|
|
57298
57493
|
let total = 0;
|
|
57299
57494
|
let max = -Infinity;
|
|
@@ -57458,14 +57653,17 @@ function determineOptimumRisk(config2, payload, params) {
|
|
|
57458
57653
|
};
|
|
57459
57654
|
}
|
|
57460
57655
|
function computeRiskReward(payload) {
|
|
57461
|
-
const { app_config, entry, stop, risk_per_trade, target_loss } = payload;
|
|
57656
|
+
const { app_config, entry, stop, risk_per_trade, target_loss, distribution } = payload;
|
|
57462
57657
|
const kind = entry > stop ? "long" : "short";
|
|
57463
57658
|
app_config.kind = kind;
|
|
57464
57659
|
app_config.entry = entry;
|
|
57465
57660
|
app_config.stop = stop;
|
|
57466
57661
|
app_config.risk_per_trade = risk_per_trade;
|
|
57467
|
-
const result = determineOptimumReward({
|
|
57468
|
-
|
|
57662
|
+
const result = determineOptimumReward({
|
|
57663
|
+
app_config,
|
|
57664
|
+
target_loss,
|
|
57665
|
+
distribution
|
|
57666
|
+
});
|
|
57469
57667
|
return result;
|
|
57470
57668
|
}
|
|
57471
57669
|
function getRiskReward(payload) {
|
|
@@ -57475,21 +57673,24 @@ function getRiskReward(payload) {
|
|
|
57475
57673
|
risk,
|
|
57476
57674
|
global_config,
|
|
57477
57675
|
force_exact_risk = false,
|
|
57478
|
-
target_loss
|
|
57676
|
+
target_loss,
|
|
57677
|
+
distribution
|
|
57479
57678
|
} = payload;
|
|
57480
57679
|
const { entries, last_value, ...app_config } = buildAppConfig(global_config, {
|
|
57481
57680
|
entry,
|
|
57482
57681
|
stop,
|
|
57483
57682
|
risk_reward: 30,
|
|
57484
57683
|
risk,
|
|
57485
|
-
symbol: global_config.symbol
|
|
57684
|
+
symbol: global_config.symbol,
|
|
57685
|
+
distribution
|
|
57486
57686
|
});
|
|
57487
57687
|
const risk_reward = computeRiskReward({
|
|
57488
57688
|
app_config,
|
|
57489
57689
|
entry,
|
|
57490
57690
|
stop,
|
|
57491
57691
|
risk_per_trade: risk,
|
|
57492
|
-
target_loss
|
|
57692
|
+
target_loss,
|
|
57693
|
+
distribution
|
|
57493
57694
|
});
|
|
57494
57695
|
if (force_exact_risk) {
|
|
57495
57696
|
const new_risk_per_trade = determineOptimumRisk(global_config, {
|
|
@@ -57497,7 +57698,8 @@ function getRiskReward(payload) {
|
|
|
57497
57698
|
stop,
|
|
57498
57699
|
risk_reward,
|
|
57499
57700
|
risk,
|
|
57500
|
-
symbol: global_config.symbol
|
|
57701
|
+
symbol: global_config.symbol,
|
|
57702
|
+
distribution
|
|
57501
57703
|
}, {
|
|
57502
57704
|
highest_risk: risk
|
|
57503
57705
|
}).optimal_risk;
|
|
@@ -57952,7 +58154,7 @@ function constructAppConfig(payload) {
|
|
|
57952
58154
|
kelly_minimum_risk: kelly_config?.kelly_minimum_risk ?? kelly?.kelly_minimum_risk,
|
|
57953
58155
|
kelly_prediction_model: kelly_config?.kelly_prediction_model ?? kelly?.kelly_prediction_model
|
|
57954
58156
|
};
|
|
57955
|
-
const appConfig = buildAppConfig(global_config, options);
|
|
58157
|
+
const { entries: _entries, ...appConfig } = buildAppConfig(global_config, options);
|
|
57956
58158
|
return appConfig;
|
|
57957
58159
|
}
|
|
57958
58160
|
function generateDangerousConfig(payload) {
|
|
@@ -60950,6 +61152,19 @@ class ExchangePosition {
|
|
|
60950
61152
|
const { p_account } = this.instance.expand;
|
|
60951
61153
|
return p_account;
|
|
60952
61154
|
}
|
|
61155
|
+
get compound() {
|
|
61156
|
+
const { compound_instance } = this.instance.expand;
|
|
61157
|
+
if (compound_instance) {
|
|
61158
|
+
const { ref } = compound_instance.expand;
|
|
61159
|
+
const profit_percent = ref.profit_percent / 100;
|
|
61160
|
+
return {
|
|
61161
|
+
...compound_instance,
|
|
61162
|
+
profit_percent,
|
|
61163
|
+
amount_to_risk: to_f(compound_instance.risk * profit_percent, "%.2f")
|
|
61164
|
+
};
|
|
61165
|
+
}
|
|
61166
|
+
return compound_instance;
|
|
61167
|
+
}
|
|
60953
61168
|
async getProxyForAccount() {
|
|
60954
61169
|
if (this.instance.expand.proxy) {
|
|
60955
61170
|
const result = this.instance.expand.proxy;
|
|
@@ -61075,7 +61290,8 @@ class ExchangePosition {
|
|
|
61075
61290
|
place,
|
|
61076
61291
|
raw: payload.raw,
|
|
61077
61292
|
use_current,
|
|
61078
|
-
stop_percent: config2.stop_percent || 100
|
|
61293
|
+
stop_percent: config2.stop_percent || 100,
|
|
61294
|
+
distribution: config2.distribution
|
|
61079
61295
|
});
|
|
61080
61296
|
}
|
|
61081
61297
|
}
|
|
@@ -61109,7 +61325,8 @@ class ExchangePosition {
|
|
|
61109
61325
|
kelly_confidence_factor: config2.kelly?.kelly_confidence_factor,
|
|
61110
61326
|
kelly_minimum_risk: config2.kelly?.kelly_minimum_risk,
|
|
61111
61327
|
kelly_prediction_model: config2.kelly?.kelly_prediction_model,
|
|
61112
|
-
kelly_func: config2.kelly?.kelly_func
|
|
61328
|
+
kelly_func: config2.kelly?.kelly_func,
|
|
61329
|
+
distribution: config2.distribution
|
|
61113
61330
|
}, false);
|
|
61114
61331
|
if (payload.raw) {
|
|
61115
61332
|
let actual_orders_to_buy = await this.determineAmountToBuy({
|
|
@@ -61232,7 +61449,8 @@ class ExchangePosition {
|
|
|
61232
61449
|
kelly_confidence_factor: solution.kelly_confidence_factor,
|
|
61233
61450
|
kelly_minimum_risk: solution.kelly_minimum_risk,
|
|
61234
61451
|
kelly_prediction_model: solution.kelly_prediction_model,
|
|
61235
|
-
kelly_func: solution.kelly_func
|
|
61452
|
+
kelly_func: solution.kelly_func,
|
|
61453
|
+
distribution: solution.distribution
|
|
61236
61454
|
};
|
|
61237
61455
|
const trades = sortedBuildConfig(app_config, options);
|
|
61238
61456
|
const entry_orders = {
|
|
@@ -61624,6 +61842,7 @@ class ExchangePosition {
|
|
|
61624
61842
|
});
|
|
61625
61843
|
}
|
|
61626
61844
|
async generate_config_params(payload) {
|
|
61845
|
+
const db_config = await this.getConfig();
|
|
61627
61846
|
const { entry, stop, risk_reward, risk, with_trades = false } = payload;
|
|
61628
61847
|
const symbol = this.symbol;
|
|
61629
61848
|
const app_config = await this.buildAppConfig({
|
|
@@ -61656,7 +61875,8 @@ class ExchangePosition {
|
|
|
61656
61875
|
avg_size: 0,
|
|
61657
61876
|
neg_pnl: 0,
|
|
61658
61877
|
min_size: app_config2.min_size,
|
|
61659
|
-
symbol
|
|
61878
|
+
symbol,
|
|
61879
|
+
distribution: db_config.distribution
|
|
61660
61880
|
}, false);
|
|
61661
61881
|
config2.trades = trades;
|
|
61662
61882
|
}
|
|
@@ -61757,7 +61977,8 @@ class ExchangePosition {
|
|
|
61757
61977
|
kelly_confidence_factor: config2.kelly?.kelly_confidence_factor,
|
|
61758
61978
|
kelly_minimum_risk: config2.kelly?.kelly_minimum_risk,
|
|
61759
61979
|
kelly_prediction_model: config2.kelly?.kelly_prediction_model,
|
|
61760
|
-
kelly_func: config2.kelly?.kelly_func
|
|
61980
|
+
kelly_func: config2.kelly?.kelly_func,
|
|
61981
|
+
distribution: config2.distribution
|
|
61761
61982
|
});
|
|
61762
61983
|
const position2 = this.instance;
|
|
61763
61984
|
const orders_to_place = await this.determineAmountToBuy({
|
|
@@ -61955,50 +62176,43 @@ class ExchangePosition {
|
|
|
61955
62176
|
increase: false
|
|
61956
62177
|
});
|
|
61957
62178
|
}
|
|
61958
|
-
|
|
61959
|
-
|
|
61960
|
-
|
|
61961
|
-
|
|
61962
|
-
|
|
61963
|
-
|
|
62179
|
+
get support() {
|
|
62180
|
+
return this.instance.expand?.support;
|
|
62181
|
+
}
|
|
62182
|
+
get linkedConfig() {
|
|
62183
|
+
return this.instance.expand?.b_config;
|
|
62184
|
+
}
|
|
62185
|
+
get isActiveTrade() {
|
|
62186
|
+
const config2 = this.linkedConfig;
|
|
61964
62187
|
return {
|
|
61965
62188
|
config: config2,
|
|
61966
|
-
condition:
|
|
61967
|
-
supportTable
|
|
62189
|
+
condition: this.compound && this.support?.price === config2.stop
|
|
61968
62190
|
};
|
|
61969
62191
|
}
|
|
61970
62192
|
async updateCompound(payload) {
|
|
61971
62193
|
const pb = this.app_db.pb;
|
|
61972
|
-
const item =
|
|
61973
|
-
|
|
61974
|
-
}
|
|
61975
|
-
const {
|
|
61976
|
-
expand: { ref }
|
|
61977
|
-
} = item;
|
|
61978
|
-
const risk = item.risk;
|
|
61979
|
-
const percent = ref.profit_percent / 100;
|
|
61980
|
-
const new_risk = risk * (1 + percent);
|
|
61981
|
-
const { condition, supportTable, config: config2 } = await this.isActiveTrade();
|
|
62194
|
+
const item = this.compound;
|
|
62195
|
+
const new_risk = item.risk + item.amount_to_risk;
|
|
62196
|
+
const { condition, config: config2 } = this.isActiveTrade;
|
|
61982
62197
|
if (payload?.place && condition) {
|
|
61983
62198
|
await pb.collection("compound_instances").update(item.id, {
|
|
61984
62199
|
risk: new_risk
|
|
61985
62200
|
});
|
|
61986
62201
|
await pb.collection("scheduled_trades").update(config2.id, {
|
|
61987
|
-
profit: to_f(new_risk *
|
|
62202
|
+
profit: to_f(new_risk * item.profit_percent, "%.3f")
|
|
61988
62203
|
});
|
|
61989
62204
|
}
|
|
61990
62205
|
return {
|
|
61991
|
-
support:
|
|
61992
|
-
counter:
|
|
61993
|
-
new_risk
|
|
62206
|
+
support: this.support?.price,
|
|
62207
|
+
counter: this.support?.counter,
|
|
62208
|
+
new_risk,
|
|
62209
|
+
condition,
|
|
62210
|
+
stop: config2.stop
|
|
61994
62211
|
};
|
|
61995
62212
|
}
|
|
61996
62213
|
async cleanOnActiveCompoundInstance() {
|
|
61997
|
-
const
|
|
61998
|
-
|
|
61999
|
-
});
|
|
62000
|
-
const { condition } = await this.isActiveTrade();
|
|
62001
|
-
if (item && condition && this.instance.quantity === 0) {
|
|
62214
|
+
const { condition } = this.isActiveTrade;
|
|
62215
|
+
if (condition && this.instance.quantity === 0) {
|
|
62002
62216
|
await this.cancelOrders({ limit: true });
|
|
62003
62217
|
}
|
|
62004
62218
|
}
|