@gbozee/ultimate 0.0.2-147 → 0.0.2-149
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 +9 -2
- package/dist/frontend-index.js +111 -7
- package/dist/index.cjs +142 -10
- package/dist/index.d.ts +18 -2
- package/dist/index.js +142 -10
- package/dist/mcp-server.cjs +142 -10
- package/dist/mcp-server.js +142 -10
- package/package.json +1 -1
package/dist/mcp-server.js
CHANGED
|
@@ -59627,6 +59627,101 @@ function calculateZoneVolatility(zone_prices) {
|
|
|
59627
59627
|
const price_changes = zone_prices.slice(1).map((price, i2) => Math.abs(price - zone_prices[i2]) / zone_prices[i2]);
|
|
59628
59628
|
return price_changes.reduce((sum, change) => sum + change, 0) / price_changes.length;
|
|
59629
59629
|
}
|
|
59630
|
+
function calculateTheoreticalKellyFixed({
|
|
59631
|
+
current_entry,
|
|
59632
|
+
zone_prices,
|
|
59633
|
+
kind = "long",
|
|
59634
|
+
config: config2 = {}
|
|
59635
|
+
}) {
|
|
59636
|
+
const {
|
|
59637
|
+
price_prediction_model = "uniform",
|
|
59638
|
+
confidence_factor = 0.6,
|
|
59639
|
+
volatility_adjustment = true
|
|
59640
|
+
} = config2;
|
|
59641
|
+
const sorted_prices = zone_prices;
|
|
59642
|
+
const current_index = sorted_prices.findIndex((price) => price === current_entry);
|
|
59643
|
+
if (current_index === -1)
|
|
59644
|
+
return 0.02;
|
|
59645
|
+
let stop_loss;
|
|
59646
|
+
let target_zones;
|
|
59647
|
+
if (kind === "long") {
|
|
59648
|
+
stop_loss = Math.min(...zone_prices);
|
|
59649
|
+
target_zones = zone_prices.filter((price) => price > current_entry);
|
|
59650
|
+
} else {
|
|
59651
|
+
stop_loss = Math.max(...zone_prices);
|
|
59652
|
+
target_zones = zone_prices.filter((price) => price < current_entry);
|
|
59653
|
+
}
|
|
59654
|
+
const risk_amount = Math.abs(current_entry - stop_loss);
|
|
59655
|
+
const avg_reward = target_zones.length > 0 ? target_zones.reduce((sum, price) => sum + Math.abs(price - current_entry), 0) / target_zones.length : risk_amount;
|
|
59656
|
+
const risk_reward_ratio = avg_reward / risk_amount;
|
|
59657
|
+
let position_quality;
|
|
59658
|
+
if (kind === "long") {
|
|
59659
|
+
const distance_from_stop = current_entry - stop_loss;
|
|
59660
|
+
const max_distance = Math.max(...zone_prices) - stop_loss;
|
|
59661
|
+
position_quality = 1 - distance_from_stop / max_distance;
|
|
59662
|
+
} else {
|
|
59663
|
+
const distance_from_stop = stop_loss - current_entry;
|
|
59664
|
+
const max_distance = stop_loss - Math.min(...zone_prices);
|
|
59665
|
+
position_quality = 1 - distance_from_stop / max_distance;
|
|
59666
|
+
}
|
|
59667
|
+
let base_probability = 0.5;
|
|
59668
|
+
switch (price_prediction_model) {
|
|
59669
|
+
case "uniform":
|
|
59670
|
+
base_probability = 0.5;
|
|
59671
|
+
break;
|
|
59672
|
+
case "normal":
|
|
59673
|
+
base_probability = 0.3 + position_quality * 0.4;
|
|
59674
|
+
break;
|
|
59675
|
+
case "exponential":
|
|
59676
|
+
base_probability = 0.2 + Math.pow(position_quality, 0.5) * 0.6;
|
|
59677
|
+
break;
|
|
59678
|
+
}
|
|
59679
|
+
const win_probability = base_probability * confidence_factor + (1 - confidence_factor) * 0.5;
|
|
59680
|
+
const odds_ratio = Math.max(risk_reward_ratio, 0.5);
|
|
59681
|
+
const loss_probability = 1 - win_probability;
|
|
59682
|
+
let kelly_fraction = (win_probability * odds_ratio - loss_probability) / odds_ratio;
|
|
59683
|
+
if (volatility_adjustment) {
|
|
59684
|
+
const zone_volatility = calculateZoneVolatility(sorted_prices);
|
|
59685
|
+
const vol_adjustment = 1 / (1 + zone_volatility);
|
|
59686
|
+
kelly_fraction *= vol_adjustment;
|
|
59687
|
+
}
|
|
59688
|
+
kelly_fraction = Math.max(0.005, Math.min(kelly_fraction, 0.5));
|
|
59689
|
+
return to_f2(kelly_fraction, "%.4f");
|
|
59690
|
+
}
|
|
59691
|
+
function calculatePositionBasedKelly({
|
|
59692
|
+
current_entry,
|
|
59693
|
+
zone_prices,
|
|
59694
|
+
kind = "long",
|
|
59695
|
+
config: config2 = {}
|
|
59696
|
+
}) {
|
|
59697
|
+
const {
|
|
59698
|
+
price_prediction_model = "uniform",
|
|
59699
|
+
confidence_factor: _confidence_factor = 0.6
|
|
59700
|
+
} = config2;
|
|
59701
|
+
const current_index = zone_prices.findIndex((price) => price === current_entry);
|
|
59702
|
+
if (current_index === -1)
|
|
59703
|
+
return 0.02;
|
|
59704
|
+
const total_zones = zone_prices.length;
|
|
59705
|
+
const position_score = (total_zones - current_index) / total_zones;
|
|
59706
|
+
let adjusted_score;
|
|
59707
|
+
switch (price_prediction_model) {
|
|
59708
|
+
case "uniform":
|
|
59709
|
+
adjusted_score = 0.5;
|
|
59710
|
+
break;
|
|
59711
|
+
case "normal":
|
|
59712
|
+
adjusted_score = 0.3 + position_score * 0.4;
|
|
59713
|
+
break;
|
|
59714
|
+
case "exponential":
|
|
59715
|
+
adjusted_score = 0.2 + Math.pow(position_score, 0.3) * 0.6;
|
|
59716
|
+
break;
|
|
59717
|
+
default:
|
|
59718
|
+
adjusted_score = 0.5;
|
|
59719
|
+
}
|
|
59720
|
+
const base_kelly = 0.02;
|
|
59721
|
+
const max_kelly = 0.2;
|
|
59722
|
+
const kelly_fraction = base_kelly + adjusted_score * (max_kelly - base_kelly);
|
|
59723
|
+
return to_f2(kelly_fraction, "%.4f");
|
|
59724
|
+
}
|
|
59630
59725
|
|
|
59631
59726
|
// src/helpers/trade_signal.ts
|
|
59632
59727
|
function determine_close_price2({
|
|
@@ -59714,6 +59809,7 @@ class Signal {
|
|
|
59714
59809
|
kelly_prediction_model = "exponential";
|
|
59715
59810
|
kelly_confidence_factor = 0.6;
|
|
59716
59811
|
kelly_minimum_risk = 0.2;
|
|
59812
|
+
kelly_func = "theoretical";
|
|
59717
59813
|
constructor({
|
|
59718
59814
|
focus,
|
|
59719
59815
|
budget,
|
|
@@ -59738,7 +59834,8 @@ class Signal {
|
|
|
59738
59834
|
use_kelly = false,
|
|
59739
59835
|
kelly_prediction_model = "exponential",
|
|
59740
59836
|
kelly_confidence_factor = 0.6,
|
|
59741
|
-
kelly_minimum_risk = 0.2
|
|
59837
|
+
kelly_minimum_risk = 0.2,
|
|
59838
|
+
kelly_func = "theoretical"
|
|
59742
59839
|
}) {
|
|
59743
59840
|
this.minimum_size = minimum_size;
|
|
59744
59841
|
this.first_order_size = first_order_size;
|
|
@@ -59764,6 +59861,7 @@ class Signal {
|
|
|
59764
59861
|
this.kelly_prediction_model = kelly_prediction_model;
|
|
59765
59862
|
this.kelly_confidence_factor = kelly_confidence_factor;
|
|
59766
59863
|
this.kelly_minimum_risk = kelly_minimum_risk;
|
|
59864
|
+
this.kelly_func = kelly_func;
|
|
59767
59865
|
}
|
|
59768
59866
|
build_entry({
|
|
59769
59867
|
current_price,
|
|
@@ -60204,7 +60302,8 @@ class Signal {
|
|
|
60204
60302
|
const new_stop = kind === "long" ? this.support : stop_loss;
|
|
60205
60303
|
let risk_to_use = risk_per_trade;
|
|
60206
60304
|
if (this.use_kelly) {
|
|
60207
|
-
const
|
|
60305
|
+
const func = this.kelly_func === "theoretical" ? calculateTheoreticalKelly : this.kelly_func === "position_based" ? calculatePositionBasedKelly : calculateTheoreticalKellyFixed;
|
|
60306
|
+
const theoretical_kelly = func({
|
|
60208
60307
|
current_entry: x,
|
|
60209
60308
|
zone_prices: limit_orders,
|
|
60210
60309
|
kind,
|
|
@@ -60412,7 +60511,8 @@ function buildConfig(app_config, {
|
|
|
60412
60511
|
use_kelly = false,
|
|
60413
60512
|
kelly_confidence_factor = 0.95,
|
|
60414
60513
|
kelly_minimum_risk = 0.2,
|
|
60415
|
-
kelly_prediction_model = "exponential"
|
|
60514
|
+
kelly_prediction_model = "exponential",
|
|
60515
|
+
kelly_func = "theoretical"
|
|
60416
60516
|
}) {
|
|
60417
60517
|
let fee = app_config.fee / 100;
|
|
60418
60518
|
let working_risk = risk || app_config.risk_per_trade;
|
|
@@ -60440,7 +60540,8 @@ function buildConfig(app_config, {
|
|
|
60440
60540
|
use_kelly: use_kelly || app_config.kelly?.use_kelly,
|
|
60441
60541
|
kelly_confidence_factor: kelly_confidence_factor || app_config.kelly?.kelly_confidence_factor,
|
|
60442
60542
|
kelly_minimum_risk: kelly_minimum_risk || app_config.kelly?.kelly_minimum_risk,
|
|
60443
|
-
kelly_prediction_model: kelly_prediction_model || app_config.kelly?.kelly_prediction_model
|
|
60543
|
+
kelly_prediction_model: kelly_prediction_model || app_config.kelly?.kelly_prediction_model,
|
|
60544
|
+
kelly_func: kelly_func || app_config.kelly?.kelly_func
|
|
60444
60545
|
};
|
|
60445
60546
|
const instance = new Signal(config2);
|
|
60446
60547
|
if (raw_instance) {
|
|
@@ -60510,7 +60611,8 @@ function get_app_config_and_max_size(config2, payload) {
|
|
|
60510
60611
|
use_kelly: payload.use_kelly,
|
|
60511
60612
|
kelly_confidence_factor: payload.kelly_confidence_factor,
|
|
60512
60613
|
kelly_minimum_risk: payload.kelly_minimum_risk,
|
|
60513
|
-
kelly_prediction_model: payload.kelly_prediction_model
|
|
60614
|
+
kelly_prediction_model: payload.kelly_prediction_model,
|
|
60615
|
+
kelly_func: payload.kelly_func
|
|
60514
60616
|
});
|
|
60515
60617
|
const max_size = initialResult[0]?.avg_size;
|
|
60516
60618
|
const last_value = initialResult[0];
|
|
@@ -60547,7 +60649,8 @@ function buildAppConfig(config2, payload) {
|
|
|
60547
60649
|
use_kelly: payload.use_kelly,
|
|
60548
60650
|
kelly_confidence_factor: payload.kelly_confidence_factor,
|
|
60549
60651
|
kelly_minimum_risk: payload.kelly_minimum_risk,
|
|
60550
|
-
kelly_prediction_model: payload.kelly_prediction_model
|
|
60652
|
+
kelly_prediction_model: payload.kelly_prediction_model,
|
|
60653
|
+
kelly_func: payload.kelly_func
|
|
60551
60654
|
});
|
|
60552
60655
|
app_config.max_size = max_size;
|
|
60553
60656
|
app_config.entry = payload.entry || app_config.entry;
|
|
@@ -60558,7 +60661,8 @@ function buildAppConfig(config2, payload) {
|
|
|
60558
60661
|
use_kelly: payload.use_kelly,
|
|
60559
60662
|
kelly_confidence_factor: payload.kelly_confidence_factor,
|
|
60560
60663
|
kelly_minimum_risk: payload.kelly_minimum_risk,
|
|
60561
|
-
kelly_prediction_model: payload.kelly_prediction_model
|
|
60664
|
+
kelly_prediction_model: payload.kelly_prediction_model,
|
|
60665
|
+
kelly_func: payload.kelly_func
|
|
60562
60666
|
};
|
|
60563
60667
|
return app_config;
|
|
60564
60668
|
}
|
|
@@ -64939,6 +65043,7 @@ class ExchangeAccount {
|
|
|
64939
65043
|
kelly_confidence_factor: config2.kelly?.kelly_confidence_factor,
|
|
64940
65044
|
kelly_minimum_risk: config2.kelly?.kelly_minimum_risk,
|
|
64941
65045
|
kelly_prediction_model: config2.kelly?.kelly_prediction_model,
|
|
65046
|
+
kelly_func: config2.kelly?.kelly_func,
|
|
64942
65047
|
...override
|
|
64943
65048
|
});
|
|
64944
65049
|
return app_config;
|
|
@@ -65060,6 +65165,13 @@ class ExchangeAccount {
|
|
|
65060
65165
|
app_config.risk_per_trade = solution.risk_per_trade;
|
|
65061
65166
|
app_config.min_size = solution.min_size;
|
|
65062
65167
|
app_config.risk_reward = solution.risk_reward;
|
|
65168
|
+
app_config.kelly = {
|
|
65169
|
+
use_kelly: solution.use_kelly,
|
|
65170
|
+
kelly_confidence_factor: solution.kelly_confidence_factor,
|
|
65171
|
+
kelly_minimum_risk: solution.kelly_minimum_risk,
|
|
65172
|
+
kelly_prediction_model: solution.kelly_prediction_model,
|
|
65173
|
+
kelly_func: solution.kelly_func
|
|
65174
|
+
};
|
|
65063
65175
|
const options = {
|
|
65064
65176
|
take_profit: null,
|
|
65065
65177
|
entry: app_config.entry,
|
|
@@ -65073,7 +65185,12 @@ class ExchangeAccount {
|
|
|
65073
65185
|
gap: app_config.gap,
|
|
65074
65186
|
rr: app_config.rr,
|
|
65075
65187
|
price_places: app_config.price_places,
|
|
65076
|
-
decimal_places: app_config.decimal_places
|
|
65188
|
+
decimal_places: app_config.decimal_places,
|
|
65189
|
+
use_kelly: solution.use_kelly,
|
|
65190
|
+
kelly_confidence_factor: solution.kelly_confidence_factor,
|
|
65191
|
+
kelly_minimum_risk: solution.kelly_minimum_risk,
|
|
65192
|
+
kelly_prediction_model: solution.kelly_prediction_model,
|
|
65193
|
+
kelly_func: solution.kelly_func
|
|
65077
65194
|
};
|
|
65078
65195
|
const trades = sortedBuildConfig(app_config, options);
|
|
65079
65196
|
const entry_orders = {
|
|
@@ -65190,6 +65307,11 @@ class ExchangeAccount {
|
|
|
65190
65307
|
}
|
|
65191
65308
|
async placeSharedOrder(action, payload) {
|
|
65192
65309
|
const { stop_percent = 100 } = payload;
|
|
65310
|
+
const kind = payload.entry > payload.stop ? "long" : "short";
|
|
65311
|
+
const config2 = await this.getPositionConfig({
|
|
65312
|
+
symbol: payload.symbol,
|
|
65313
|
+
kind
|
|
65314
|
+
});
|
|
65193
65315
|
const app_config = await this.buildAppConfig({
|
|
65194
65316
|
entry: payload.entry,
|
|
65195
65317
|
stop: payload.stop,
|
|
@@ -65197,7 +65319,12 @@ class ExchangeAccount {
|
|
|
65197
65319
|
risk: payload.risk,
|
|
65198
65320
|
symbol: payload.symbol,
|
|
65199
65321
|
profit: 0,
|
|
65200
|
-
update_db: payload.update_db
|
|
65322
|
+
update_db: payload.update_db,
|
|
65323
|
+
use_kelly: config2.kelly?.use_kelly,
|
|
65324
|
+
kelly_confidence_factor: config2.kelly?.kelly_confidence_factor,
|
|
65325
|
+
kelly_minimum_risk: config2.kelly?.kelly_minimum_risk,
|
|
65326
|
+
kelly_prediction_model: config2.kelly?.kelly_prediction_model,
|
|
65327
|
+
kelly_func: config2.kelly?.kelly_func
|
|
65201
65328
|
});
|
|
65202
65329
|
const { entry_orders, stop_orders, trades } = await this.placeConfigOrders(app_config, {
|
|
65203
65330
|
risk_reward: payload.risk_reward,
|
|
@@ -65208,7 +65335,12 @@ class ExchangeAccount {
|
|
|
65208
65335
|
neg_pnl: 0,
|
|
65209
65336
|
min_size: app_config.min_size,
|
|
65210
65337
|
symbol: payload.symbol,
|
|
65211
|
-
stop_percent
|
|
65338
|
+
stop_percent,
|
|
65339
|
+
use_kelly: config2.kelly?.use_kelly,
|
|
65340
|
+
kelly_confidence_factor: config2.kelly?.kelly_confidence_factor,
|
|
65341
|
+
kelly_minimum_risk: config2.kelly?.kelly_minimum_risk,
|
|
65342
|
+
kelly_prediction_model: config2.kelly?.kelly_prediction_model,
|
|
65343
|
+
kelly_func: config2.kelly?.kelly_func
|
|
65212
65344
|
}, false);
|
|
65213
65345
|
if (payload.raw) {
|
|
65214
65346
|
let actual_orders_to_buy = await this.determineAmountToBuy({
|