@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.js
CHANGED
|
@@ -54639,13 +54639,29 @@ class AppDatabase {
|
|
|
54639
54639
|
});
|
|
54640
54640
|
return result;
|
|
54641
54641
|
}
|
|
54642
|
+
get positionExpand() {
|
|
54643
|
+
return "b_config, account_strategy, p_account, proxy, compound_instance.ref,support";
|
|
54644
|
+
}
|
|
54645
|
+
async fetchCentralPositions(payload) {
|
|
54646
|
+
const { asset: assetName, symbol } = payload;
|
|
54647
|
+
const pb = this.pb;
|
|
54648
|
+
let symbolFilter = assetName ? `symbol ~ "${assetName}"` : `symbol = "${symbol}"`;
|
|
54649
|
+
if (this.email) {
|
|
54650
|
+
symbolFilter = `${symbolFilter} && p_account.user.email="${this.email}"`;
|
|
54651
|
+
}
|
|
54652
|
+
let positionsWithAssetName = await pb.collection("positions_view").getFullList({
|
|
54653
|
+
filter: symbolFilter,
|
|
54654
|
+
expand: this.positionExpand
|
|
54655
|
+
});
|
|
54656
|
+
return positionsWithAssetName;
|
|
54657
|
+
}
|
|
54642
54658
|
async getPositions(options) {
|
|
54643
54659
|
const { symbol, as_view = false, account, custom_filter } = options;
|
|
54644
54660
|
let default_params = as_view ? {
|
|
54645
54661
|
table: "positions_view",
|
|
54646
54662
|
params: {
|
|
54647
54663
|
filter: `symbol:lower="${symbol.toLowerCase()}" && p_account.owner:lower="${account.owner.toLowerCase()}" && p_account.exchange:lower="${account.exchange.toLowerCase()}"`,
|
|
54648
|
-
expand:
|
|
54664
|
+
expand: this.positionExpand
|
|
54649
54665
|
}
|
|
54650
54666
|
} : {
|
|
54651
54667
|
table: "positions",
|
|
@@ -55494,6 +55510,137 @@ __export(exports_exchange_account, {
|
|
|
55494
55510
|
// src/exchanges/binance/index.ts
|
|
55495
55511
|
var import_binance = __toESM(require_lib2(), 1);
|
|
55496
55512
|
|
|
55513
|
+
// src/helpers/distributions.ts
|
|
55514
|
+
function generateArithmetic(payload) {
|
|
55515
|
+
const { margin_range, risk_reward, kind, price_places = "%.1f" } = payload;
|
|
55516
|
+
const difference = Math.abs(margin_range[1] - margin_range[0]);
|
|
55517
|
+
const spread = difference / risk_reward;
|
|
55518
|
+
return Array.from({ length: risk_reward + 1 }, (_, i2) => {
|
|
55519
|
+
const price = kind === "long" ? margin_range[1] - spread * i2 : margin_range[0] + spread * i2;
|
|
55520
|
+
return to_f(price, price_places);
|
|
55521
|
+
});
|
|
55522
|
+
}
|
|
55523
|
+
function generateGeometric(payload) {
|
|
55524
|
+
const { margin_range, risk_reward, kind, price_places = "%.1f", percent_change } = payload;
|
|
55525
|
+
const effectivePercentChange = percent_change ?? Math.abs(margin_range[1] / margin_range[0] - 1) / risk_reward;
|
|
55526
|
+
return Array.from({ length: risk_reward + 1 }, (_, i2) => {
|
|
55527
|
+
const price = kind === "long" ? margin_range[1] * Math.pow(1 - effectivePercentChange, i2) : margin_range[0] * Math.pow(1 + effectivePercentChange, i2);
|
|
55528
|
+
return to_f(price, price_places);
|
|
55529
|
+
});
|
|
55530
|
+
}
|
|
55531
|
+
function approximateInverseNormal(p) {
|
|
55532
|
+
p = Math.max(0.0001, Math.min(0.9999, p));
|
|
55533
|
+
if (p < 0.5) {
|
|
55534
|
+
const t2 = Math.sqrt(-2 * Math.log(p));
|
|
55535
|
+
const c0 = 2.515517, c1 = 0.802853, c2 = 0.010328;
|
|
55536
|
+
const d1 = 1.432788, d2 = 0.189269, d3 = 0.001308;
|
|
55537
|
+
return -(t2 - (c0 + c1 * t2 + c2 * t2 * t2) / (1 + d1 * t2 + d2 * t2 * t2 + d3 * t2 * t2 * t2));
|
|
55538
|
+
} else {
|
|
55539
|
+
const t2 = Math.sqrt(-2 * Math.log(1 - p));
|
|
55540
|
+
const c0 = 2.515517, c1 = 0.802853, c2 = 0.010328;
|
|
55541
|
+
const d1 = 1.432788, d2 = 0.189269, d3 = 0.001308;
|
|
55542
|
+
return t2 - (c0 + c1 * t2 + c2 * t2 * t2) / (1 + d1 * t2 + d2 * t2 * t2 + d3 * t2 * t2 * t2);
|
|
55543
|
+
}
|
|
55544
|
+
}
|
|
55545
|
+
function generateNormal(payload) {
|
|
55546
|
+
const { margin_range, risk_reward, kind, price_places = "%.1f", stdDevFactor = 6 } = payload;
|
|
55547
|
+
const mean = (margin_range[0] + margin_range[1]) / 2;
|
|
55548
|
+
const stdDev = Math.abs(margin_range[1] - margin_range[0]) / stdDevFactor;
|
|
55549
|
+
const skew = kind === "long" ? -0.2 : 0.2;
|
|
55550
|
+
const adjustedMean = mean + stdDev * skew;
|
|
55551
|
+
const entries = Array.from({ length: risk_reward + 1 }, (_, i2) => {
|
|
55552
|
+
const p = (i2 + 0.5) / (risk_reward + 1);
|
|
55553
|
+
const z2 = approximateInverseNormal(p);
|
|
55554
|
+
let price = adjustedMean + stdDev * z2;
|
|
55555
|
+
price = Math.max(margin_range[0], Math.min(margin_range[1], price));
|
|
55556
|
+
return to_f(price, price_places);
|
|
55557
|
+
});
|
|
55558
|
+
return entries.sort((a, b) => a - b);
|
|
55559
|
+
}
|
|
55560
|
+
function generateExponential(payload) {
|
|
55561
|
+
const { margin_range, risk_reward, kind, price_places = "%.1f", lambda } = payload;
|
|
55562
|
+
const range = Math.abs(margin_range[1] - margin_range[0]);
|
|
55563
|
+
const effectiveLambda = lambda || 2.5;
|
|
55564
|
+
return Array.from({ length: risk_reward + 1 }, (_, i2) => {
|
|
55565
|
+
const t2 = i2 / risk_reward;
|
|
55566
|
+
const exponentialProgress = 1 - Math.exp(-effectiveLambda * t2);
|
|
55567
|
+
const price = kind === "long" ? margin_range[1] - range * exponentialProgress : margin_range[0] + range * exponentialProgress;
|
|
55568
|
+
return to_f(price, price_places);
|
|
55569
|
+
});
|
|
55570
|
+
}
|
|
55571
|
+
function generateInverseExponential(payload) {
|
|
55572
|
+
const { margin_range, risk_reward, kind, price_places = "%.1f", curveFactor = 2 } = payload;
|
|
55573
|
+
const range = Math.abs(margin_range[1] - margin_range[0]);
|
|
55574
|
+
return Array.from({ length: risk_reward + 1 }, (_, i2) => {
|
|
55575
|
+
const t2 = i2 / risk_reward;
|
|
55576
|
+
const progress = (Math.exp(curveFactor * t2) - 1) / (Math.exp(curveFactor) - 1);
|
|
55577
|
+
const price = kind === "long" ? margin_range[1] - range * progress : margin_range[0] + range * progress;
|
|
55578
|
+
return to_f(price, price_places);
|
|
55579
|
+
});
|
|
55580
|
+
}
|
|
55581
|
+
function getEntries(params) {
|
|
55582
|
+
const {
|
|
55583
|
+
kind,
|
|
55584
|
+
distribution,
|
|
55585
|
+
margin_range,
|
|
55586
|
+
risk_reward,
|
|
55587
|
+
price_places = "%.1f",
|
|
55588
|
+
distribution_params = {}
|
|
55589
|
+
} = params;
|
|
55590
|
+
let entries = [];
|
|
55591
|
+
switch (distribution) {
|
|
55592
|
+
case "arithmetic":
|
|
55593
|
+
entries = generateArithmetic({
|
|
55594
|
+
margin_range,
|
|
55595
|
+
risk_reward,
|
|
55596
|
+
kind,
|
|
55597
|
+
price_places,
|
|
55598
|
+
percent_change: distribution_params.curveFactor
|
|
55599
|
+
});
|
|
55600
|
+
break;
|
|
55601
|
+
case "geometric":
|
|
55602
|
+
entries = generateGeometric({
|
|
55603
|
+
margin_range,
|
|
55604
|
+
risk_reward,
|
|
55605
|
+
kind,
|
|
55606
|
+
price_places,
|
|
55607
|
+
percent_change: distribution_params.curveFactor
|
|
55608
|
+
});
|
|
55609
|
+
break;
|
|
55610
|
+
case "normal":
|
|
55611
|
+
entries = generateNormal({
|
|
55612
|
+
margin_range,
|
|
55613
|
+
risk_reward,
|
|
55614
|
+
kind,
|
|
55615
|
+
price_places,
|
|
55616
|
+
stdDevFactor: distribution_params.stdDevFactor
|
|
55617
|
+
});
|
|
55618
|
+
break;
|
|
55619
|
+
case "exponential":
|
|
55620
|
+
entries = generateExponential({
|
|
55621
|
+
margin_range,
|
|
55622
|
+
risk_reward,
|
|
55623
|
+
kind,
|
|
55624
|
+
price_places,
|
|
55625
|
+
lambda: distribution_params.lambda
|
|
55626
|
+
});
|
|
55627
|
+
break;
|
|
55628
|
+
case "inverse-exponential":
|
|
55629
|
+
entries = generateInverseExponential({
|
|
55630
|
+
margin_range,
|
|
55631
|
+
risk_reward,
|
|
55632
|
+
kind,
|
|
55633
|
+
price_places,
|
|
55634
|
+
curveFactor: distribution_params.curveFactor
|
|
55635
|
+
});
|
|
55636
|
+
break;
|
|
55637
|
+
default:
|
|
55638
|
+
throw new Error(`Unknown distribution type: ${distribution}`);
|
|
55639
|
+
}
|
|
55640
|
+
return entries.sort((a, b) => a - b);
|
|
55641
|
+
}
|
|
55642
|
+
var distributions_default = getEntries;
|
|
55643
|
+
|
|
55497
55644
|
// src/helpers/optimizations.ts
|
|
55498
55645
|
function calculateTheoreticalKelly({
|
|
55499
55646
|
current_entry,
|
|
@@ -55763,6 +55910,10 @@ class Signal {
|
|
|
55763
55910
|
kelly_minimum_risk = 0.2;
|
|
55764
55911
|
kelly_func = "theoretical";
|
|
55765
55912
|
symbol;
|
|
55913
|
+
distribution = {
|
|
55914
|
+
long: "arithmetic",
|
|
55915
|
+
short: "geometric"
|
|
55916
|
+
};
|
|
55766
55917
|
constructor({
|
|
55767
55918
|
focus,
|
|
55768
55919
|
symbol,
|
|
@@ -55789,8 +55940,12 @@ class Signal {
|
|
|
55789
55940
|
kelly_prediction_model = "exponential",
|
|
55790
55941
|
kelly_confidence_factor = 0.6,
|
|
55791
55942
|
kelly_minimum_risk = 0.2,
|
|
55792
|
-
kelly_func = "theoretical"
|
|
55943
|
+
kelly_func = "theoretical",
|
|
55944
|
+
full_distribution
|
|
55793
55945
|
}) {
|
|
55946
|
+
if (full_distribution) {
|
|
55947
|
+
this.distribution = full_distribution;
|
|
55948
|
+
}
|
|
55794
55949
|
this.symbol = symbol;
|
|
55795
55950
|
this.minimum_size = minimum_size;
|
|
55796
55951
|
this.first_order_size = first_order_size;
|
|
@@ -55826,7 +55981,8 @@ class Signal {
|
|
|
55826
55981
|
kind = "long",
|
|
55827
55982
|
risk,
|
|
55828
55983
|
no_of_trades = 1,
|
|
55829
|
-
take_profit
|
|
55984
|
+
take_profit,
|
|
55985
|
+
distribution
|
|
55830
55986
|
}) {
|
|
55831
55987
|
let _stop_loss = stop_loss;
|
|
55832
55988
|
if (!_stop_loss && stop_percent) {
|
|
@@ -55835,16 +55991,22 @@ class Signal {
|
|
|
55835
55991
|
const percent_change = _stop_loss ? Math.max(current_price, _stop_loss) / Math.min(current_price, _stop_loss) - 1 : this.percent_change;
|
|
55836
55992
|
const _no_of_trades = no_of_trades || this.risk_reward;
|
|
55837
55993
|
let _resistance = current_price * Math.pow(1 + percent_change, 1);
|
|
55994
|
+
const simple_support = Math.min(current_price, stop_loss);
|
|
55995
|
+
const simple_resistance = Math.max(current_price, stop_loss);
|
|
55838
55996
|
const derivedConfig = {
|
|
55839
55997
|
...this,
|
|
55840
55998
|
percent_change,
|
|
55841
55999
|
focus: current_price,
|
|
55842
|
-
resistance: _resistance,
|
|
56000
|
+
resistance: distribution ? simple_resistance : _resistance,
|
|
55843
56001
|
risk_per_trade: risk / this.risk_reward,
|
|
55844
56002
|
minimum_pnl: pnl,
|
|
55845
56003
|
risk_reward: _no_of_trades,
|
|
55846
56004
|
take_profit: take_profit || this.take_profit,
|
|
55847
|
-
support: kind === "long" ? _stop_loss : this.support
|
|
56005
|
+
support: distribution ? simple_support : kind === "long" ? _stop_loss : this.support,
|
|
56006
|
+
full_distribution: distribution ? {
|
|
56007
|
+
...this.distribution,
|
|
56008
|
+
[kind]: distribution
|
|
56009
|
+
} : undefined
|
|
55848
56010
|
};
|
|
55849
56011
|
const instance = new Signal(derivedConfig);
|
|
55850
56012
|
if (kind === "short") {}
|
|
@@ -56060,12 +56222,31 @@ class Signal {
|
|
|
56060
56222
|
}
|
|
56061
56223
|
this.zone_risk = original;
|
|
56062
56224
|
}
|
|
56225
|
+
get_future_zones_simple({
|
|
56226
|
+
current_price,
|
|
56227
|
+
kind = "long",
|
|
56228
|
+
raw
|
|
56229
|
+
}) {
|
|
56230
|
+
const margin_zones = [this.support, this.resistance];
|
|
56231
|
+
const distribution = this.distribution ? this.distribution[kind] : "geometric";
|
|
56232
|
+
console.log("margin_zones", { margin_zones, distribution });
|
|
56233
|
+
let _kind = distribution === "inverse-exponential" ? kind === "long" ? "short" : "long" : kind;
|
|
56234
|
+
const entries = distributions_default({
|
|
56235
|
+
margin_range: margin_zones,
|
|
56236
|
+
kind: _kind,
|
|
56237
|
+
distribution,
|
|
56238
|
+
risk_reward: this.risk_reward,
|
|
56239
|
+
price_places: this.price_places
|
|
56240
|
+
});
|
|
56241
|
+
return entries.sort((a, b) => a - b);
|
|
56242
|
+
}
|
|
56063
56243
|
get_future_zones({
|
|
56064
56244
|
current_price,
|
|
56065
56245
|
kind = "long",
|
|
56066
56246
|
raw
|
|
56067
56247
|
}) {
|
|
56068
56248
|
if (raw) {}
|
|
56249
|
+
return this.get_future_zones_simple({ current_price, raw, kind });
|
|
56069
56250
|
const margin_range = this.get_margin_range(current_price, kind);
|
|
56070
56251
|
let margin_zones = this.get_margin_zones({ current_price });
|
|
56071
56252
|
let remaining_zones = margin_zones.filter((x) => JSON.stringify(x) != JSON.stringify(margin_range));
|
|
@@ -56724,7 +56905,9 @@ function buildConfig(app_config, {
|
|
|
56724
56905
|
kelly_confidence_factor = 0.95,
|
|
56725
56906
|
kelly_minimum_risk = 0.2,
|
|
56726
56907
|
kelly_prediction_model = "exponential",
|
|
56727
|
-
kelly_func = "theoretical"
|
|
56908
|
+
kelly_func = "theoretical",
|
|
56909
|
+
min_avg_size = 0,
|
|
56910
|
+
distribution
|
|
56728
56911
|
}) {
|
|
56729
56912
|
let fee = app_config.fee / 100;
|
|
56730
56913
|
let working_risk = risk || app_config.risk_per_trade;
|
|
@@ -56771,9 +56954,12 @@ function buildConfig(app_config, {
|
|
|
56771
56954
|
stop_loss: stop,
|
|
56772
56955
|
risk: working_risk,
|
|
56773
56956
|
kind: kind || app_config.kind,
|
|
56774
|
-
no_of_trades: trade_no
|
|
56957
|
+
no_of_trades: trade_no,
|
|
56958
|
+
distribution
|
|
56775
56959
|
}) || [] : [];
|
|
56776
|
-
|
|
56960
|
+
const new_trades = computeTotalAverageForEachTrade(result, config2);
|
|
56961
|
+
let filtered = new_trades.filter((o) => o.avg_size > min_avg_size);
|
|
56962
|
+
return computeTotalAverageForEachTrade(filtered, config2);
|
|
56777
56963
|
}
|
|
56778
56964
|
function buildAvg({
|
|
56779
56965
|
_trades,
|
|
@@ -56838,7 +57024,8 @@ function get_app_config_and_max_size(config2, payload) {
|
|
|
56838
57024
|
kelly_confidence_factor: payload.kelly_confidence_factor,
|
|
56839
57025
|
kelly_minimum_risk: payload.kelly_minimum_risk,
|
|
56840
57026
|
kelly_prediction_model: payload.kelly_prediction_model,
|
|
56841
|
-
kelly_func: payload.kelly_func
|
|
57027
|
+
kelly_func: payload.kelly_func,
|
|
57028
|
+
distribution: payload.distribution
|
|
56842
57029
|
});
|
|
56843
57030
|
const max_size = initialResult[0]?.avg_size;
|
|
56844
57031
|
const last_value = initialResult[0];
|
|
@@ -56876,7 +57063,8 @@ function buildAppConfig(config2, payload) {
|
|
|
56876
57063
|
kelly_confidence_factor: payload.kelly_confidence_factor,
|
|
56877
57064
|
kelly_minimum_risk: payload.kelly_minimum_risk,
|
|
56878
57065
|
kelly_prediction_model: payload.kelly_prediction_model,
|
|
56879
|
-
kelly_func: payload.kelly_func
|
|
57066
|
+
kelly_func: payload.kelly_func,
|
|
57067
|
+
distribution: payload.distribution
|
|
56880
57068
|
});
|
|
56881
57069
|
app_config.max_size = max_size;
|
|
56882
57070
|
app_config.entry = payload.entry || app_config.entry;
|
|
@@ -56893,7 +57081,7 @@ function buildAppConfig(config2, payload) {
|
|
|
56893
57081
|
return app_config;
|
|
56894
57082
|
}
|
|
56895
57083
|
function getOptimumStopAndRisk(app_config, params) {
|
|
56896
|
-
const { max_size, target_stop } = params;
|
|
57084
|
+
const { max_size, target_stop, distribution } = params;
|
|
56897
57085
|
const isLong = app_config.kind === "long";
|
|
56898
57086
|
const stopRange = Math.abs(app_config.entry - target_stop) * 0.5;
|
|
56899
57087
|
let low_stop = isLong ? target_stop - stopRange : Math.max(target_stop - stopRange, app_config.entry);
|
|
@@ -56916,7 +57104,8 @@ function getOptimumStopAndRisk(app_config, params) {
|
|
|
56916
57104
|
increase: true,
|
|
56917
57105
|
gap: app_config.gap,
|
|
56918
57106
|
price_places: app_config.price_places,
|
|
56919
|
-
decimal_places: app_config.decimal_places
|
|
57107
|
+
decimal_places: app_config.decimal_places,
|
|
57108
|
+
distribution
|
|
56920
57109
|
});
|
|
56921
57110
|
if (result.length === 0) {
|
|
56922
57111
|
if (isLong) {
|
|
@@ -56970,7 +57159,8 @@ function getOptimumStopAndRisk(app_config, params) {
|
|
|
56970
57159
|
increase: true,
|
|
56971
57160
|
gap: app_config.gap,
|
|
56972
57161
|
price_places: app_config.price_places,
|
|
56973
|
-
decimal_places: app_config.decimal_places
|
|
57162
|
+
decimal_places: app_config.decimal_places,
|
|
57163
|
+
distribution
|
|
56974
57164
|
});
|
|
56975
57165
|
if (result.length === 0) {
|
|
56976
57166
|
high_risk = mid_risk;
|
|
@@ -57015,7 +57205,8 @@ function getOptimumStopAndRisk(app_config, params) {
|
|
|
57015
57205
|
increase: true,
|
|
57016
57206
|
gap: app_config.gap,
|
|
57017
57207
|
price_places: app_config.price_places,
|
|
57018
|
-
decimal_places: app_config.decimal_places
|
|
57208
|
+
decimal_places: app_config.decimal_places,
|
|
57209
|
+
distribution
|
|
57019
57210
|
});
|
|
57020
57211
|
if (result.length === 0)
|
|
57021
57212
|
continue;
|
|
@@ -57138,7 +57329,8 @@ function generateOptimumAppConfig(config2, payload, position2) {
|
|
|
57138
57329
|
}, {
|
|
57139
57330
|
entry: payload.entry,
|
|
57140
57331
|
stop: payload.stop,
|
|
57141
|
-
kind: position2.kind
|
|
57332
|
+
kind: position2.kind,
|
|
57333
|
+
distribution: payload.distribution
|
|
57142
57334
|
});
|
|
57143
57335
|
current_app_config.max_size = max_size;
|
|
57144
57336
|
current_app_config.last_value = last_value;
|
|
@@ -57153,7 +57345,8 @@ function generateOptimumAppConfig(config2, payload, position2) {
|
|
|
57153
57345
|
increase: true,
|
|
57154
57346
|
gap: current_app_config.gap,
|
|
57155
57347
|
price_places: current_app_config.price_places,
|
|
57156
|
-
decimal_places: current_app_config.decimal_places
|
|
57348
|
+
decimal_places: current_app_config.decimal_places,
|
|
57349
|
+
distribution: payload.distribution
|
|
57157
57350
|
});
|
|
57158
57351
|
if (full_trades.length === 0) {
|
|
57159
57352
|
high_risk = mid_risk;
|
|
@@ -57217,7 +57410,8 @@ function determineOptimumReward(payload) {
|
|
|
57217
57410
|
increase = true,
|
|
57218
57411
|
low_range = 1,
|
|
57219
57412
|
high_range = 199,
|
|
57220
|
-
target_loss
|
|
57413
|
+
target_loss,
|
|
57414
|
+
distribution
|
|
57221
57415
|
} = payload;
|
|
57222
57416
|
const criterion = app_config.strategy || "quantity";
|
|
57223
57417
|
const risk_rewards = createArray(low_range, high_range, 1);
|
|
@@ -57231,7 +57425,8 @@ function determineOptimumReward(payload) {
|
|
|
57231
57425
|
increase,
|
|
57232
57426
|
kind: app_config.kind,
|
|
57233
57427
|
gap: app_config.gap,
|
|
57234
|
-
decimal_places: app_config.decimal_places
|
|
57428
|
+
decimal_places: app_config.decimal_places,
|
|
57429
|
+
distribution
|
|
57235
57430
|
});
|
|
57236
57431
|
let total = 0;
|
|
57237
57432
|
let max = -Infinity;
|
|
@@ -57396,14 +57591,17 @@ function determineOptimumRisk(config2, payload, params) {
|
|
|
57396
57591
|
};
|
|
57397
57592
|
}
|
|
57398
57593
|
function computeRiskReward(payload) {
|
|
57399
|
-
const { app_config, entry, stop, risk_per_trade, target_loss } = payload;
|
|
57594
|
+
const { app_config, entry, stop, risk_per_trade, target_loss, distribution } = payload;
|
|
57400
57595
|
const kind = entry > stop ? "long" : "short";
|
|
57401
57596
|
app_config.kind = kind;
|
|
57402
57597
|
app_config.entry = entry;
|
|
57403
57598
|
app_config.stop = stop;
|
|
57404
57599
|
app_config.risk_per_trade = risk_per_trade;
|
|
57405
|
-
const result = determineOptimumReward({
|
|
57406
|
-
|
|
57600
|
+
const result = determineOptimumReward({
|
|
57601
|
+
app_config,
|
|
57602
|
+
target_loss,
|
|
57603
|
+
distribution
|
|
57604
|
+
});
|
|
57407
57605
|
return result;
|
|
57408
57606
|
}
|
|
57409
57607
|
function getRiskReward(payload) {
|
|
@@ -57413,21 +57611,24 @@ function getRiskReward(payload) {
|
|
|
57413
57611
|
risk,
|
|
57414
57612
|
global_config,
|
|
57415
57613
|
force_exact_risk = false,
|
|
57416
|
-
target_loss
|
|
57614
|
+
target_loss,
|
|
57615
|
+
distribution
|
|
57417
57616
|
} = payload;
|
|
57418
57617
|
const { entries, last_value, ...app_config } = buildAppConfig(global_config, {
|
|
57419
57618
|
entry,
|
|
57420
57619
|
stop,
|
|
57421
57620
|
risk_reward: 30,
|
|
57422
57621
|
risk,
|
|
57423
|
-
symbol: global_config.symbol
|
|
57622
|
+
symbol: global_config.symbol,
|
|
57623
|
+
distribution
|
|
57424
57624
|
});
|
|
57425
57625
|
const risk_reward = computeRiskReward({
|
|
57426
57626
|
app_config,
|
|
57427
57627
|
entry,
|
|
57428
57628
|
stop,
|
|
57429
57629
|
risk_per_trade: risk,
|
|
57430
|
-
target_loss
|
|
57630
|
+
target_loss,
|
|
57631
|
+
distribution
|
|
57431
57632
|
});
|
|
57432
57633
|
if (force_exact_risk) {
|
|
57433
57634
|
const new_risk_per_trade = determineOptimumRisk(global_config, {
|
|
@@ -57435,7 +57636,8 @@ function getRiskReward(payload) {
|
|
|
57435
57636
|
stop,
|
|
57436
57637
|
risk_reward,
|
|
57437
57638
|
risk,
|
|
57438
|
-
symbol: global_config.symbol
|
|
57639
|
+
symbol: global_config.symbol,
|
|
57640
|
+
distribution
|
|
57439
57641
|
}, {
|
|
57440
57642
|
highest_risk: risk
|
|
57441
57643
|
}).optimal_risk;
|
|
@@ -57890,7 +58092,7 @@ function constructAppConfig(payload) {
|
|
|
57890
58092
|
kelly_minimum_risk: kelly_config?.kelly_minimum_risk ?? kelly?.kelly_minimum_risk,
|
|
57891
58093
|
kelly_prediction_model: kelly_config?.kelly_prediction_model ?? kelly?.kelly_prediction_model
|
|
57892
58094
|
};
|
|
57893
|
-
const appConfig = buildAppConfig(global_config, options);
|
|
58095
|
+
const { entries: _entries, ...appConfig } = buildAppConfig(global_config, options);
|
|
57894
58096
|
return appConfig;
|
|
57895
58097
|
}
|
|
57896
58098
|
function generateDangerousConfig(payload) {
|
|
@@ -60888,6 +61090,19 @@ class ExchangePosition {
|
|
|
60888
61090
|
const { p_account } = this.instance.expand;
|
|
60889
61091
|
return p_account;
|
|
60890
61092
|
}
|
|
61093
|
+
get compound() {
|
|
61094
|
+
const { compound_instance } = this.instance.expand;
|
|
61095
|
+
if (compound_instance) {
|
|
61096
|
+
const { ref } = compound_instance.expand;
|
|
61097
|
+
const profit_percent = ref.profit_percent / 100;
|
|
61098
|
+
return {
|
|
61099
|
+
...compound_instance,
|
|
61100
|
+
profit_percent,
|
|
61101
|
+
amount_to_risk: to_f(compound_instance.risk * profit_percent, "%.2f")
|
|
61102
|
+
};
|
|
61103
|
+
}
|
|
61104
|
+
return compound_instance;
|
|
61105
|
+
}
|
|
60891
61106
|
async getProxyForAccount() {
|
|
60892
61107
|
if (this.instance.expand.proxy) {
|
|
60893
61108
|
const result = this.instance.expand.proxy;
|
|
@@ -61013,7 +61228,8 @@ class ExchangePosition {
|
|
|
61013
61228
|
place,
|
|
61014
61229
|
raw: payload.raw,
|
|
61015
61230
|
use_current,
|
|
61016
|
-
stop_percent: config2.stop_percent || 100
|
|
61231
|
+
stop_percent: config2.stop_percent || 100,
|
|
61232
|
+
distribution: config2.distribution
|
|
61017
61233
|
});
|
|
61018
61234
|
}
|
|
61019
61235
|
}
|
|
@@ -61047,7 +61263,8 @@ class ExchangePosition {
|
|
|
61047
61263
|
kelly_confidence_factor: config2.kelly?.kelly_confidence_factor,
|
|
61048
61264
|
kelly_minimum_risk: config2.kelly?.kelly_minimum_risk,
|
|
61049
61265
|
kelly_prediction_model: config2.kelly?.kelly_prediction_model,
|
|
61050
|
-
kelly_func: config2.kelly?.kelly_func
|
|
61266
|
+
kelly_func: config2.kelly?.kelly_func,
|
|
61267
|
+
distribution: config2.distribution
|
|
61051
61268
|
}, false);
|
|
61052
61269
|
if (payload.raw) {
|
|
61053
61270
|
let actual_orders_to_buy = await this.determineAmountToBuy({
|
|
@@ -61170,7 +61387,8 @@ class ExchangePosition {
|
|
|
61170
61387
|
kelly_confidence_factor: solution.kelly_confidence_factor,
|
|
61171
61388
|
kelly_minimum_risk: solution.kelly_minimum_risk,
|
|
61172
61389
|
kelly_prediction_model: solution.kelly_prediction_model,
|
|
61173
|
-
kelly_func: solution.kelly_func
|
|
61390
|
+
kelly_func: solution.kelly_func,
|
|
61391
|
+
distribution: solution.distribution
|
|
61174
61392
|
};
|
|
61175
61393
|
const trades = sortedBuildConfig(app_config, options);
|
|
61176
61394
|
const entry_orders = {
|
|
@@ -61562,6 +61780,7 @@ class ExchangePosition {
|
|
|
61562
61780
|
});
|
|
61563
61781
|
}
|
|
61564
61782
|
async generate_config_params(payload) {
|
|
61783
|
+
const db_config = await this.getConfig();
|
|
61565
61784
|
const { entry, stop, risk_reward, risk, with_trades = false } = payload;
|
|
61566
61785
|
const symbol = this.symbol;
|
|
61567
61786
|
const app_config = await this.buildAppConfig({
|
|
@@ -61594,7 +61813,8 @@ class ExchangePosition {
|
|
|
61594
61813
|
avg_size: 0,
|
|
61595
61814
|
neg_pnl: 0,
|
|
61596
61815
|
min_size: app_config2.min_size,
|
|
61597
|
-
symbol
|
|
61816
|
+
symbol,
|
|
61817
|
+
distribution: db_config.distribution
|
|
61598
61818
|
}, false);
|
|
61599
61819
|
config2.trades = trades;
|
|
61600
61820
|
}
|
|
@@ -61695,7 +61915,8 @@ class ExchangePosition {
|
|
|
61695
61915
|
kelly_confidence_factor: config2.kelly?.kelly_confidence_factor,
|
|
61696
61916
|
kelly_minimum_risk: config2.kelly?.kelly_minimum_risk,
|
|
61697
61917
|
kelly_prediction_model: config2.kelly?.kelly_prediction_model,
|
|
61698
|
-
kelly_func: config2.kelly?.kelly_func
|
|
61918
|
+
kelly_func: config2.kelly?.kelly_func,
|
|
61919
|
+
distribution: config2.distribution
|
|
61699
61920
|
});
|
|
61700
61921
|
const position2 = this.instance;
|
|
61701
61922
|
const orders_to_place = await this.determineAmountToBuy({
|
|
@@ -61893,50 +62114,43 @@ class ExchangePosition {
|
|
|
61893
62114
|
increase: false
|
|
61894
62115
|
});
|
|
61895
62116
|
}
|
|
61896
|
-
|
|
61897
|
-
|
|
61898
|
-
|
|
61899
|
-
|
|
61900
|
-
|
|
61901
|
-
|
|
62117
|
+
get support() {
|
|
62118
|
+
return this.instance.expand?.support;
|
|
62119
|
+
}
|
|
62120
|
+
get linkedConfig() {
|
|
62121
|
+
return this.instance.expand?.b_config;
|
|
62122
|
+
}
|
|
62123
|
+
get isActiveTrade() {
|
|
62124
|
+
const config2 = this.linkedConfig;
|
|
61902
62125
|
return {
|
|
61903
62126
|
config: config2,
|
|
61904
|
-
condition:
|
|
61905
|
-
supportTable
|
|
62127
|
+
condition: this.compound && this.support?.price === config2.stop
|
|
61906
62128
|
};
|
|
61907
62129
|
}
|
|
61908
62130
|
async updateCompound(payload) {
|
|
61909
62131
|
const pb = this.app_db.pb;
|
|
61910
|
-
const item =
|
|
61911
|
-
|
|
61912
|
-
}
|
|
61913
|
-
const {
|
|
61914
|
-
expand: { ref }
|
|
61915
|
-
} = item;
|
|
61916
|
-
const risk = item.risk;
|
|
61917
|
-
const percent = ref.profit_percent / 100;
|
|
61918
|
-
const new_risk = risk * (1 + percent);
|
|
61919
|
-
const { condition, supportTable, config: config2 } = await this.isActiveTrade();
|
|
62132
|
+
const item = this.compound;
|
|
62133
|
+
const new_risk = item.risk + item.amount_to_risk;
|
|
62134
|
+
const { condition, config: config2 } = this.isActiveTrade;
|
|
61920
62135
|
if (payload?.place && condition) {
|
|
61921
62136
|
await pb.collection("compound_instances").update(item.id, {
|
|
61922
62137
|
risk: new_risk
|
|
61923
62138
|
});
|
|
61924
62139
|
await pb.collection("scheduled_trades").update(config2.id, {
|
|
61925
|
-
profit: to_f(new_risk *
|
|
62140
|
+
profit: to_f(new_risk * item.profit_percent, "%.3f")
|
|
61926
62141
|
});
|
|
61927
62142
|
}
|
|
61928
62143
|
return {
|
|
61929
|
-
support:
|
|
61930
|
-
counter:
|
|
61931
|
-
new_risk
|
|
62144
|
+
support: this.support?.price,
|
|
62145
|
+
counter: this.support?.counter,
|
|
62146
|
+
new_risk,
|
|
62147
|
+
condition,
|
|
62148
|
+
stop: config2.stop
|
|
61932
62149
|
};
|
|
61933
62150
|
}
|
|
61934
62151
|
async cleanOnActiveCompoundInstance() {
|
|
61935
|
-
const
|
|
61936
|
-
|
|
61937
|
-
});
|
|
61938
|
-
const { condition } = await this.isActiveTrade();
|
|
61939
|
-
if (item && condition && this.instance.quantity === 0) {
|
|
62152
|
+
const { condition } = this.isActiveTrade;
|
|
62153
|
+
if (condition && this.instance.quantity === 0) {
|
|
61940
62154
|
await this.cancelOrders({ limit: true });
|
|
61941
62155
|
}
|
|
61942
62156
|
}
|