@gbozee/ultimate 0.0.2-147 → 0.0.2-148
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 +112 -7
- package/dist/index.d.ts +13 -2
- package/dist/index.js +112 -7
- package/dist/mcp-server.cjs +112 -7
- package/dist/mcp-server.js +112 -7
- package/package.json +1 -1
package/dist/frontend-index.d.ts
CHANGED
|
@@ -143,6 +143,7 @@ export type SignalConfigType = {
|
|
|
143
143
|
kelly_prediction_model?: "exponential" | "normal" | "uniform";
|
|
144
144
|
kelly_confidence_factor?: number;
|
|
145
145
|
kelly_minimum_risk?: number;
|
|
146
|
+
kelly_func?: "theoretical" | "position_based" | "theoretical_fixed";
|
|
146
147
|
};
|
|
147
148
|
declare class Signal {
|
|
148
149
|
focus: number;
|
|
@@ -169,7 +170,8 @@ declare class Signal {
|
|
|
169
170
|
kelly_prediction_model: "exponential" | "normal" | "uniform";
|
|
170
171
|
kelly_confidence_factor: number;
|
|
171
172
|
kelly_minimum_risk: number;
|
|
172
|
-
|
|
173
|
+
kelly_func: "theoretical" | "position_based" | "theoretical_fixed";
|
|
174
|
+
constructor({ focus, budget, percent_change, price_places, decimal_places, zone_risk, fee, support, risk_reward, resistance, risk_per_trade, increase_size, additional_increase, minimum_pnl, take_profit, increase_position, minimum_size, first_order_size, gap, max_size, use_kelly, kelly_prediction_model, kelly_confidence_factor, kelly_minimum_risk, kelly_func, }: SignalConfigType);
|
|
173
175
|
build_entry({ current_price, stop_loss, pnl, stop_percent, kind, risk, no_of_trades, take_profit, }: {
|
|
174
176
|
take_profit?: number;
|
|
175
177
|
no_of_trades?: number;
|
|
@@ -309,6 +311,7 @@ export type AppConfig = {
|
|
|
309
311
|
kelly_confidence_factor?: number;
|
|
310
312
|
kelly_minimum_risk?: number;
|
|
311
313
|
kelly_prediction_model?: "exponential" | "normal" | "uniform";
|
|
314
|
+
kelly_func?: "theoretical" | "position_based" | "theoretical_fixed";
|
|
312
315
|
};
|
|
313
316
|
};
|
|
314
317
|
export type ExtendConfigType = {
|
|
@@ -330,8 +333,9 @@ export type ExtendConfigType = {
|
|
|
330
333
|
kelly_confidence_factor?: number;
|
|
331
334
|
kelly_minimum_risk?: number;
|
|
332
335
|
kelly_prediction_model?: "exponential" | "normal" | "uniform";
|
|
336
|
+
kelly_func?: "theoretical" | "position_based" | "theoretical_fixed";
|
|
333
337
|
};
|
|
334
|
-
export declare function buildConfig(app_config: AppConfig, { take_profit, entry, stop, raw_instance, risk, no_of_trades, min_profit, risk_reward, kind, increase, gap, rr, price_places, decimal_places, use_kelly, kelly_confidence_factor, kelly_minimum_risk, kelly_prediction_model, }: ExtendConfigType): any[] | Signal;
|
|
338
|
+
export declare function buildConfig(app_config: AppConfig, { take_profit, entry, stop, raw_instance, risk, no_of_trades, min_profit, risk_reward, kind, increase, gap, rr, price_places, decimal_places, use_kelly, kelly_confidence_factor, kelly_minimum_risk, kelly_prediction_model, kelly_func, }: ExtendConfigType): any[] | Signal;
|
|
335
339
|
export declare function buildAvg({ _trades, kind, }: {
|
|
336
340
|
_trades: any[];
|
|
337
341
|
kind: "long" | "short";
|
|
@@ -345,6 +349,7 @@ export declare function get_app_config_and_max_size(config: GlobalConfig, payloa
|
|
|
345
349
|
kelly_confidence_factor?: number;
|
|
346
350
|
kelly_minimum_risk?: number;
|
|
347
351
|
kelly_prediction_model?: "exponential" | "normal" | "uniform";
|
|
352
|
+
kelly_func?: "theoretical" | "position_based" | "theoretical_fixed";
|
|
348
353
|
}): {
|
|
349
354
|
app_config: AppConfig;
|
|
350
355
|
max_size: any;
|
|
@@ -368,6 +373,7 @@ export declare function buildAppConfig(config: GlobalConfig, payload: {
|
|
|
368
373
|
kelly_confidence_factor?: number;
|
|
369
374
|
kelly_minimum_risk?: number;
|
|
370
375
|
kelly_prediction_model?: "exponential" | "normal" | "uniform";
|
|
376
|
+
kelly_func?: "theoretical" | "position_based" | "theoretical_fixed";
|
|
371
377
|
}): AppConfig;
|
|
372
378
|
export declare function getOptimumStopAndRisk(app_config: AppConfig, params: {
|
|
373
379
|
max_size: number;
|
|
@@ -845,6 +851,7 @@ export declare class Strategy {
|
|
|
845
851
|
kelly_confidence_factor?: number;
|
|
846
852
|
kelly_minimum_risk?: number;
|
|
847
853
|
kelly_prediction_model?: "exponential" | "normal" | "uniform";
|
|
854
|
+
kelly_func?: "theoretical" | "position_based" | "theoretical_fixed";
|
|
848
855
|
};
|
|
849
856
|
};
|
|
850
857
|
identifyGapConfig(payload: {
|
package/dist/frontend-index.js
CHANGED
|
@@ -83,6 +83,101 @@ function calculateZoneVolatility(zone_prices) {
|
|
|
83
83
|
const price_changes = zone_prices.slice(1).map((price, i) => Math.abs(price - zone_prices[i]) / zone_prices[i]);
|
|
84
84
|
return price_changes.reduce((sum, change) => sum + change, 0) / price_changes.length;
|
|
85
85
|
}
|
|
86
|
+
function calculateTheoreticalKellyFixed({
|
|
87
|
+
current_entry,
|
|
88
|
+
zone_prices,
|
|
89
|
+
kind = "long",
|
|
90
|
+
config = {}
|
|
91
|
+
}) {
|
|
92
|
+
const {
|
|
93
|
+
price_prediction_model = "uniform",
|
|
94
|
+
confidence_factor = 0.6,
|
|
95
|
+
volatility_adjustment = true
|
|
96
|
+
} = config;
|
|
97
|
+
const sorted_prices = zone_prices;
|
|
98
|
+
const current_index = sorted_prices.findIndex((price) => price === current_entry);
|
|
99
|
+
if (current_index === -1)
|
|
100
|
+
return 0.02;
|
|
101
|
+
let stop_loss;
|
|
102
|
+
let target_zones;
|
|
103
|
+
if (kind === "long") {
|
|
104
|
+
stop_loss = Math.min(...zone_prices);
|
|
105
|
+
target_zones = zone_prices.filter((price) => price > current_entry);
|
|
106
|
+
} else {
|
|
107
|
+
stop_loss = Math.max(...zone_prices);
|
|
108
|
+
target_zones = zone_prices.filter((price) => price < current_entry);
|
|
109
|
+
}
|
|
110
|
+
const risk_amount = Math.abs(current_entry - stop_loss);
|
|
111
|
+
const avg_reward = target_zones.length > 0 ? target_zones.reduce((sum, price) => sum + Math.abs(price - current_entry), 0) / target_zones.length : risk_amount;
|
|
112
|
+
const risk_reward_ratio = avg_reward / risk_amount;
|
|
113
|
+
let position_quality;
|
|
114
|
+
if (kind === "long") {
|
|
115
|
+
const distance_from_stop = current_entry - stop_loss;
|
|
116
|
+
const max_distance = Math.max(...zone_prices) - stop_loss;
|
|
117
|
+
position_quality = 1 - distance_from_stop / max_distance;
|
|
118
|
+
} else {
|
|
119
|
+
const distance_from_stop = stop_loss - current_entry;
|
|
120
|
+
const max_distance = stop_loss - Math.min(...zone_prices);
|
|
121
|
+
position_quality = 1 - distance_from_stop / max_distance;
|
|
122
|
+
}
|
|
123
|
+
let base_probability = 0.5;
|
|
124
|
+
switch (price_prediction_model) {
|
|
125
|
+
case "uniform":
|
|
126
|
+
base_probability = 0.5;
|
|
127
|
+
break;
|
|
128
|
+
case "normal":
|
|
129
|
+
base_probability = 0.3 + position_quality * 0.4;
|
|
130
|
+
break;
|
|
131
|
+
case "exponential":
|
|
132
|
+
base_probability = 0.2 + Math.pow(position_quality, 0.5) * 0.6;
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
const win_probability = base_probability * confidence_factor + (1 - confidence_factor) * 0.5;
|
|
136
|
+
const odds_ratio = Math.max(risk_reward_ratio, 0.5);
|
|
137
|
+
const loss_probability = 1 - win_probability;
|
|
138
|
+
let kelly_fraction = (win_probability * odds_ratio - loss_probability) / odds_ratio;
|
|
139
|
+
if (volatility_adjustment) {
|
|
140
|
+
const zone_volatility = calculateZoneVolatility(sorted_prices);
|
|
141
|
+
const vol_adjustment = 1 / (1 + zone_volatility);
|
|
142
|
+
kelly_fraction *= vol_adjustment;
|
|
143
|
+
}
|
|
144
|
+
kelly_fraction = Math.max(0.005, Math.min(kelly_fraction, 0.5));
|
|
145
|
+
return to_f(kelly_fraction, "%.4f");
|
|
146
|
+
}
|
|
147
|
+
function calculatePositionBasedKelly({
|
|
148
|
+
current_entry,
|
|
149
|
+
zone_prices,
|
|
150
|
+
kind = "long",
|
|
151
|
+
config = {}
|
|
152
|
+
}) {
|
|
153
|
+
const {
|
|
154
|
+
price_prediction_model = "uniform",
|
|
155
|
+
confidence_factor: _confidence_factor = 0.6
|
|
156
|
+
} = config;
|
|
157
|
+
const current_index = zone_prices.findIndex((price) => price === current_entry);
|
|
158
|
+
if (current_index === -1)
|
|
159
|
+
return 0.02;
|
|
160
|
+
const total_zones = zone_prices.length;
|
|
161
|
+
const position_score = (total_zones - current_index) / total_zones;
|
|
162
|
+
let adjusted_score;
|
|
163
|
+
switch (price_prediction_model) {
|
|
164
|
+
case "uniform":
|
|
165
|
+
adjusted_score = 0.5;
|
|
166
|
+
break;
|
|
167
|
+
case "normal":
|
|
168
|
+
adjusted_score = 0.3 + position_score * 0.4;
|
|
169
|
+
break;
|
|
170
|
+
case "exponential":
|
|
171
|
+
adjusted_score = 0.2 + Math.pow(position_score, 0.3) * 0.6;
|
|
172
|
+
break;
|
|
173
|
+
default:
|
|
174
|
+
adjusted_score = 0.5;
|
|
175
|
+
}
|
|
176
|
+
const base_kelly = 0.02;
|
|
177
|
+
const max_kelly = 0.2;
|
|
178
|
+
const kelly_fraction = base_kelly + adjusted_score * (max_kelly - base_kelly);
|
|
179
|
+
return to_f(kelly_fraction, "%.4f");
|
|
180
|
+
}
|
|
86
181
|
|
|
87
182
|
// src/helpers/trade_signal.ts
|
|
88
183
|
function determine_close_price({
|
|
@@ -170,6 +265,7 @@ class Signal {
|
|
|
170
265
|
kelly_prediction_model = "exponential";
|
|
171
266
|
kelly_confidence_factor = 0.6;
|
|
172
267
|
kelly_minimum_risk = 0.2;
|
|
268
|
+
kelly_func = "theoretical";
|
|
173
269
|
constructor({
|
|
174
270
|
focus,
|
|
175
271
|
budget,
|
|
@@ -194,7 +290,8 @@ class Signal {
|
|
|
194
290
|
use_kelly = false,
|
|
195
291
|
kelly_prediction_model = "exponential",
|
|
196
292
|
kelly_confidence_factor = 0.6,
|
|
197
|
-
kelly_minimum_risk = 0.2
|
|
293
|
+
kelly_minimum_risk = 0.2,
|
|
294
|
+
kelly_func = "theoretical"
|
|
198
295
|
}) {
|
|
199
296
|
this.minimum_size = minimum_size;
|
|
200
297
|
this.first_order_size = first_order_size;
|
|
@@ -220,6 +317,7 @@ class Signal {
|
|
|
220
317
|
this.kelly_prediction_model = kelly_prediction_model;
|
|
221
318
|
this.kelly_confidence_factor = kelly_confidence_factor;
|
|
222
319
|
this.kelly_minimum_risk = kelly_minimum_risk;
|
|
320
|
+
this.kelly_func = kelly_func;
|
|
223
321
|
}
|
|
224
322
|
build_entry({
|
|
225
323
|
current_price,
|
|
@@ -660,7 +758,8 @@ class Signal {
|
|
|
660
758
|
const new_stop = kind === "long" ? this.support : stop_loss;
|
|
661
759
|
let risk_to_use = risk_per_trade;
|
|
662
760
|
if (this.use_kelly) {
|
|
663
|
-
const
|
|
761
|
+
const func = this.kelly_func === "theoretical" ? calculateTheoreticalKelly : this.kelly_func === "position_based" ? calculatePositionBasedKelly : calculateTheoreticalKellyFixed;
|
|
762
|
+
const theoretical_kelly = func({
|
|
664
763
|
current_entry: x,
|
|
665
764
|
zone_prices: limit_orders,
|
|
666
765
|
kind,
|
|
@@ -1342,7 +1441,8 @@ function buildConfig(app_config, {
|
|
|
1342
1441
|
use_kelly = false,
|
|
1343
1442
|
kelly_confidence_factor = 0.95,
|
|
1344
1443
|
kelly_minimum_risk = 0.2,
|
|
1345
|
-
kelly_prediction_model = "exponential"
|
|
1444
|
+
kelly_prediction_model = "exponential",
|
|
1445
|
+
kelly_func = "theoretical"
|
|
1346
1446
|
}) {
|
|
1347
1447
|
let fee = app_config.fee / 100;
|
|
1348
1448
|
let working_risk = risk || app_config.risk_per_trade;
|
|
@@ -1370,7 +1470,8 @@ function buildConfig(app_config, {
|
|
|
1370
1470
|
use_kelly: use_kelly || app_config.kelly?.use_kelly,
|
|
1371
1471
|
kelly_confidence_factor: kelly_confidence_factor || app_config.kelly?.kelly_confidence_factor,
|
|
1372
1472
|
kelly_minimum_risk: kelly_minimum_risk || app_config.kelly?.kelly_minimum_risk,
|
|
1373
|
-
kelly_prediction_model: kelly_prediction_model || app_config.kelly?.kelly_prediction_model
|
|
1473
|
+
kelly_prediction_model: kelly_prediction_model || app_config.kelly?.kelly_prediction_model,
|
|
1474
|
+
kelly_func: kelly_func || app_config.kelly?.kelly_func
|
|
1374
1475
|
};
|
|
1375
1476
|
const instance = new Signal(config);
|
|
1376
1477
|
if (raw_instance) {
|
|
@@ -1453,7 +1554,8 @@ function get_app_config_and_max_size(config, payload) {
|
|
|
1453
1554
|
use_kelly: payload.use_kelly,
|
|
1454
1555
|
kelly_confidence_factor: payload.kelly_confidence_factor,
|
|
1455
1556
|
kelly_minimum_risk: payload.kelly_minimum_risk,
|
|
1456
|
-
kelly_prediction_model: payload.kelly_prediction_model
|
|
1557
|
+
kelly_prediction_model: payload.kelly_prediction_model,
|
|
1558
|
+
kelly_func: payload.kelly_func
|
|
1457
1559
|
});
|
|
1458
1560
|
const max_size = initialResult[0]?.avg_size;
|
|
1459
1561
|
const last_value = initialResult[0];
|
|
@@ -1490,7 +1592,8 @@ function buildAppConfig(config, payload) {
|
|
|
1490
1592
|
use_kelly: payload.use_kelly,
|
|
1491
1593
|
kelly_confidence_factor: payload.kelly_confidence_factor,
|
|
1492
1594
|
kelly_minimum_risk: payload.kelly_minimum_risk,
|
|
1493
|
-
kelly_prediction_model: payload.kelly_prediction_model
|
|
1595
|
+
kelly_prediction_model: payload.kelly_prediction_model,
|
|
1596
|
+
kelly_func: payload.kelly_func
|
|
1494
1597
|
});
|
|
1495
1598
|
app_config.max_size = max_size;
|
|
1496
1599
|
app_config.entry = payload.entry || app_config.entry;
|
|
@@ -1501,7 +1604,8 @@ function buildAppConfig(config, payload) {
|
|
|
1501
1604
|
use_kelly: payload.use_kelly,
|
|
1502
1605
|
kelly_confidence_factor: payload.kelly_confidence_factor,
|
|
1503
1606
|
kelly_minimum_risk: payload.kelly_minimum_risk,
|
|
1504
|
-
kelly_prediction_model: payload.kelly_prediction_model
|
|
1607
|
+
kelly_prediction_model: payload.kelly_prediction_model,
|
|
1608
|
+
kelly_func: payload.kelly_func
|
|
1505
1609
|
};
|
|
1506
1610
|
return app_config;
|
|
1507
1611
|
}
|
package/dist/index.cjs
CHANGED
|
@@ -52955,6 +52955,101 @@ function calculateZoneVolatility(zone_prices) {
|
|
|
52955
52955
|
const price_changes = zone_prices.slice(1).map((price, i2) => Math.abs(price - zone_prices[i2]) / zone_prices[i2]);
|
|
52956
52956
|
return price_changes.reduce((sum, change) => sum + change, 0) / price_changes.length;
|
|
52957
52957
|
}
|
|
52958
|
+
function calculateTheoreticalKellyFixed({
|
|
52959
|
+
current_entry,
|
|
52960
|
+
zone_prices,
|
|
52961
|
+
kind = "long",
|
|
52962
|
+
config: config2 = {}
|
|
52963
|
+
}) {
|
|
52964
|
+
const {
|
|
52965
|
+
price_prediction_model = "uniform",
|
|
52966
|
+
confidence_factor = 0.6,
|
|
52967
|
+
volatility_adjustment = true
|
|
52968
|
+
} = config2;
|
|
52969
|
+
const sorted_prices = zone_prices;
|
|
52970
|
+
const current_index = sorted_prices.findIndex((price) => price === current_entry);
|
|
52971
|
+
if (current_index === -1)
|
|
52972
|
+
return 0.02;
|
|
52973
|
+
let stop_loss;
|
|
52974
|
+
let target_zones;
|
|
52975
|
+
if (kind === "long") {
|
|
52976
|
+
stop_loss = Math.min(...zone_prices);
|
|
52977
|
+
target_zones = zone_prices.filter((price) => price > current_entry);
|
|
52978
|
+
} else {
|
|
52979
|
+
stop_loss = Math.max(...zone_prices);
|
|
52980
|
+
target_zones = zone_prices.filter((price) => price < current_entry);
|
|
52981
|
+
}
|
|
52982
|
+
const risk_amount = Math.abs(current_entry - stop_loss);
|
|
52983
|
+
const avg_reward = target_zones.length > 0 ? target_zones.reduce((sum, price) => sum + Math.abs(price - current_entry), 0) / target_zones.length : risk_amount;
|
|
52984
|
+
const risk_reward_ratio = avg_reward / risk_amount;
|
|
52985
|
+
let position_quality;
|
|
52986
|
+
if (kind === "long") {
|
|
52987
|
+
const distance_from_stop = current_entry - stop_loss;
|
|
52988
|
+
const max_distance = Math.max(...zone_prices) - stop_loss;
|
|
52989
|
+
position_quality = 1 - distance_from_stop / max_distance;
|
|
52990
|
+
} else {
|
|
52991
|
+
const distance_from_stop = stop_loss - current_entry;
|
|
52992
|
+
const max_distance = stop_loss - Math.min(...zone_prices);
|
|
52993
|
+
position_quality = 1 - distance_from_stop / max_distance;
|
|
52994
|
+
}
|
|
52995
|
+
let base_probability = 0.5;
|
|
52996
|
+
switch (price_prediction_model) {
|
|
52997
|
+
case "uniform":
|
|
52998
|
+
base_probability = 0.5;
|
|
52999
|
+
break;
|
|
53000
|
+
case "normal":
|
|
53001
|
+
base_probability = 0.3 + position_quality * 0.4;
|
|
53002
|
+
break;
|
|
53003
|
+
case "exponential":
|
|
53004
|
+
base_probability = 0.2 + Math.pow(position_quality, 0.5) * 0.6;
|
|
53005
|
+
break;
|
|
53006
|
+
}
|
|
53007
|
+
const win_probability = base_probability * confidence_factor + (1 - confidence_factor) * 0.5;
|
|
53008
|
+
const odds_ratio = Math.max(risk_reward_ratio, 0.5);
|
|
53009
|
+
const loss_probability = 1 - win_probability;
|
|
53010
|
+
let kelly_fraction = (win_probability * odds_ratio - loss_probability) / odds_ratio;
|
|
53011
|
+
if (volatility_adjustment) {
|
|
53012
|
+
const zone_volatility = calculateZoneVolatility(sorted_prices);
|
|
53013
|
+
const vol_adjustment = 1 / (1 + zone_volatility);
|
|
53014
|
+
kelly_fraction *= vol_adjustment;
|
|
53015
|
+
}
|
|
53016
|
+
kelly_fraction = Math.max(0.005, Math.min(kelly_fraction, 0.5));
|
|
53017
|
+
return to_f2(kelly_fraction, "%.4f");
|
|
53018
|
+
}
|
|
53019
|
+
function calculatePositionBasedKelly({
|
|
53020
|
+
current_entry,
|
|
53021
|
+
zone_prices,
|
|
53022
|
+
kind = "long",
|
|
53023
|
+
config: config2 = {}
|
|
53024
|
+
}) {
|
|
53025
|
+
const {
|
|
53026
|
+
price_prediction_model = "uniform",
|
|
53027
|
+
confidence_factor: _confidence_factor = 0.6
|
|
53028
|
+
} = config2;
|
|
53029
|
+
const current_index = zone_prices.findIndex((price) => price === current_entry);
|
|
53030
|
+
if (current_index === -1)
|
|
53031
|
+
return 0.02;
|
|
53032
|
+
const total_zones = zone_prices.length;
|
|
53033
|
+
const position_score = (total_zones - current_index) / total_zones;
|
|
53034
|
+
let adjusted_score;
|
|
53035
|
+
switch (price_prediction_model) {
|
|
53036
|
+
case "uniform":
|
|
53037
|
+
adjusted_score = 0.5;
|
|
53038
|
+
break;
|
|
53039
|
+
case "normal":
|
|
53040
|
+
adjusted_score = 0.3 + position_score * 0.4;
|
|
53041
|
+
break;
|
|
53042
|
+
case "exponential":
|
|
53043
|
+
adjusted_score = 0.2 + Math.pow(position_score, 0.3) * 0.6;
|
|
53044
|
+
break;
|
|
53045
|
+
default:
|
|
53046
|
+
adjusted_score = 0.5;
|
|
53047
|
+
}
|
|
53048
|
+
const base_kelly = 0.02;
|
|
53049
|
+
const max_kelly = 0.2;
|
|
53050
|
+
const kelly_fraction = base_kelly + adjusted_score * (max_kelly - base_kelly);
|
|
53051
|
+
return to_f2(kelly_fraction, "%.4f");
|
|
53052
|
+
}
|
|
52958
53053
|
|
|
52959
53054
|
// src/helpers/trade_signal.ts
|
|
52960
53055
|
function determine_close_price2({
|
|
@@ -53042,6 +53137,7 @@ class Signal {
|
|
|
53042
53137
|
kelly_prediction_model = "exponential";
|
|
53043
53138
|
kelly_confidence_factor = 0.6;
|
|
53044
53139
|
kelly_minimum_risk = 0.2;
|
|
53140
|
+
kelly_func = "theoretical";
|
|
53045
53141
|
constructor({
|
|
53046
53142
|
focus,
|
|
53047
53143
|
budget,
|
|
@@ -53066,7 +53162,8 @@ class Signal {
|
|
|
53066
53162
|
use_kelly = false,
|
|
53067
53163
|
kelly_prediction_model = "exponential",
|
|
53068
53164
|
kelly_confidence_factor = 0.6,
|
|
53069
|
-
kelly_minimum_risk = 0.2
|
|
53165
|
+
kelly_minimum_risk = 0.2,
|
|
53166
|
+
kelly_func = "theoretical"
|
|
53070
53167
|
}) {
|
|
53071
53168
|
this.minimum_size = minimum_size;
|
|
53072
53169
|
this.first_order_size = first_order_size;
|
|
@@ -53092,6 +53189,7 @@ class Signal {
|
|
|
53092
53189
|
this.kelly_prediction_model = kelly_prediction_model;
|
|
53093
53190
|
this.kelly_confidence_factor = kelly_confidence_factor;
|
|
53094
53191
|
this.kelly_minimum_risk = kelly_minimum_risk;
|
|
53192
|
+
this.kelly_func = kelly_func;
|
|
53095
53193
|
}
|
|
53096
53194
|
build_entry({
|
|
53097
53195
|
current_price,
|
|
@@ -53532,7 +53630,8 @@ class Signal {
|
|
|
53532
53630
|
const new_stop = kind === "long" ? this.support : stop_loss;
|
|
53533
53631
|
let risk_to_use = risk_per_trade;
|
|
53534
53632
|
if (this.use_kelly) {
|
|
53535
|
-
const
|
|
53633
|
+
const func = this.kelly_func === "theoretical" ? calculateTheoreticalKelly : this.kelly_func === "position_based" ? calculatePositionBasedKelly : calculateTheoreticalKellyFixed;
|
|
53634
|
+
const theoretical_kelly = func({
|
|
53536
53635
|
current_entry: x,
|
|
53537
53636
|
zone_prices: limit_orders,
|
|
53538
53637
|
kind,
|
|
@@ -53740,7 +53839,8 @@ function buildConfig(app_config, {
|
|
|
53740
53839
|
use_kelly = false,
|
|
53741
53840
|
kelly_confidence_factor = 0.95,
|
|
53742
53841
|
kelly_minimum_risk = 0.2,
|
|
53743
|
-
kelly_prediction_model = "exponential"
|
|
53842
|
+
kelly_prediction_model = "exponential",
|
|
53843
|
+
kelly_func = "theoretical"
|
|
53744
53844
|
}) {
|
|
53745
53845
|
let fee = app_config.fee / 100;
|
|
53746
53846
|
let working_risk = risk || app_config.risk_per_trade;
|
|
@@ -53768,7 +53868,8 @@ function buildConfig(app_config, {
|
|
|
53768
53868
|
use_kelly: use_kelly || app_config.kelly?.use_kelly,
|
|
53769
53869
|
kelly_confidence_factor: kelly_confidence_factor || app_config.kelly?.kelly_confidence_factor,
|
|
53770
53870
|
kelly_minimum_risk: kelly_minimum_risk || app_config.kelly?.kelly_minimum_risk,
|
|
53771
|
-
kelly_prediction_model: kelly_prediction_model || app_config.kelly?.kelly_prediction_model
|
|
53871
|
+
kelly_prediction_model: kelly_prediction_model || app_config.kelly?.kelly_prediction_model,
|
|
53872
|
+
kelly_func: kelly_func || app_config.kelly?.kelly_func
|
|
53772
53873
|
};
|
|
53773
53874
|
const instance = new Signal(config2);
|
|
53774
53875
|
if (raw_instance) {
|
|
@@ -53851,7 +53952,8 @@ function get_app_config_and_max_size(config2, payload) {
|
|
|
53851
53952
|
use_kelly: payload.use_kelly,
|
|
53852
53953
|
kelly_confidence_factor: payload.kelly_confidence_factor,
|
|
53853
53954
|
kelly_minimum_risk: payload.kelly_minimum_risk,
|
|
53854
|
-
kelly_prediction_model: payload.kelly_prediction_model
|
|
53955
|
+
kelly_prediction_model: payload.kelly_prediction_model,
|
|
53956
|
+
kelly_func: payload.kelly_func
|
|
53855
53957
|
});
|
|
53856
53958
|
const max_size = initialResult[0]?.avg_size;
|
|
53857
53959
|
const last_value = initialResult[0];
|
|
@@ -53888,7 +53990,8 @@ function buildAppConfig(config2, payload) {
|
|
|
53888
53990
|
use_kelly: payload.use_kelly,
|
|
53889
53991
|
kelly_confidence_factor: payload.kelly_confidence_factor,
|
|
53890
53992
|
kelly_minimum_risk: payload.kelly_minimum_risk,
|
|
53891
|
-
kelly_prediction_model: payload.kelly_prediction_model
|
|
53993
|
+
kelly_prediction_model: payload.kelly_prediction_model,
|
|
53994
|
+
kelly_func: payload.kelly_func
|
|
53892
53995
|
});
|
|
53893
53996
|
app_config.max_size = max_size;
|
|
53894
53997
|
app_config.entry = payload.entry || app_config.entry;
|
|
@@ -53899,7 +54002,8 @@ function buildAppConfig(config2, payload) {
|
|
|
53899
54002
|
use_kelly: payload.use_kelly,
|
|
53900
54003
|
kelly_confidence_factor: payload.kelly_confidence_factor,
|
|
53901
54004
|
kelly_minimum_risk: payload.kelly_minimum_risk,
|
|
53902
|
-
kelly_prediction_model: payload.kelly_prediction_model
|
|
54005
|
+
kelly_prediction_model: payload.kelly_prediction_model,
|
|
54006
|
+
kelly_func: payload.kelly_func
|
|
53903
54007
|
};
|
|
53904
54008
|
return app_config;
|
|
53905
54009
|
}
|
|
@@ -58286,6 +58390,7 @@ class ExchangeAccount {
|
|
|
58286
58390
|
kelly_confidence_factor: config2.kelly?.kelly_confidence_factor,
|
|
58287
58391
|
kelly_minimum_risk: config2.kelly?.kelly_minimum_risk,
|
|
58288
58392
|
kelly_prediction_model: config2.kelly?.kelly_prediction_model,
|
|
58393
|
+
kelly_func: config2.kelly?.kelly_func,
|
|
58289
58394
|
...override
|
|
58290
58395
|
});
|
|
58291
58396
|
return app_config;
|
package/dist/index.d.ts
CHANGED
|
@@ -1027,6 +1027,7 @@ export declare class Strategy {
|
|
|
1027
1027
|
kelly_confidence_factor?: number;
|
|
1028
1028
|
kelly_minimum_risk?: number;
|
|
1029
1029
|
kelly_prediction_model?: "exponential" | "normal" | "uniform";
|
|
1030
|
+
kelly_func?: "theoretical" | "position_based" | "theoretical_fixed";
|
|
1030
1031
|
};
|
|
1031
1032
|
};
|
|
1032
1033
|
identifyGapConfig(payload: {
|
|
@@ -1145,6 +1146,7 @@ export type SignalConfigType = {
|
|
|
1145
1146
|
kelly_prediction_model?: "exponential" | "normal" | "uniform";
|
|
1146
1147
|
kelly_confidence_factor?: number;
|
|
1147
1148
|
kelly_minimum_risk?: number;
|
|
1149
|
+
kelly_func?: "theoretical" | "position_based" | "theoretical_fixed";
|
|
1148
1150
|
};
|
|
1149
1151
|
declare class Signal {
|
|
1150
1152
|
focus: number;
|
|
@@ -1171,7 +1173,8 @@ declare class Signal {
|
|
|
1171
1173
|
kelly_prediction_model: "exponential" | "normal" | "uniform";
|
|
1172
1174
|
kelly_confidence_factor: number;
|
|
1173
1175
|
kelly_minimum_risk: number;
|
|
1174
|
-
|
|
1176
|
+
kelly_func: "theoretical" | "position_based" | "theoretical_fixed";
|
|
1177
|
+
constructor({ focus, budget, percent_change, price_places, decimal_places, zone_risk, fee, support, risk_reward, resistance, risk_per_trade, increase_size, additional_increase, minimum_pnl, take_profit, increase_position, minimum_size, first_order_size, gap, max_size, use_kelly, kelly_prediction_model, kelly_confidence_factor, kelly_minimum_risk, kelly_func, }: SignalConfigType);
|
|
1175
1178
|
build_entry({ current_price, stop_loss, pnl, stop_percent, kind, risk, no_of_trades, take_profit, }: {
|
|
1176
1179
|
take_profit?: number;
|
|
1177
1180
|
no_of_trades?: number;
|
|
@@ -1299,6 +1302,7 @@ export type AppConfig = {
|
|
|
1299
1302
|
kelly_confidence_factor?: number;
|
|
1300
1303
|
kelly_minimum_risk?: number;
|
|
1301
1304
|
kelly_prediction_model?: "exponential" | "normal" | "uniform";
|
|
1305
|
+
kelly_func?: "theoretical" | "position_based" | "theoretical_fixed";
|
|
1302
1306
|
};
|
|
1303
1307
|
};
|
|
1304
1308
|
export type ExtendConfigType = {
|
|
@@ -1320,8 +1324,9 @@ export type ExtendConfigType = {
|
|
|
1320
1324
|
kelly_confidence_factor?: number;
|
|
1321
1325
|
kelly_minimum_risk?: number;
|
|
1322
1326
|
kelly_prediction_model?: "exponential" | "normal" | "uniform";
|
|
1327
|
+
kelly_func?: "theoretical" | "position_based" | "theoretical_fixed";
|
|
1323
1328
|
};
|
|
1324
|
-
export declare function buildConfig(app_config: AppConfig, { take_profit, entry, stop, raw_instance, risk, no_of_trades, min_profit, risk_reward, kind, increase, gap, rr, price_places, decimal_places, use_kelly, kelly_confidence_factor, kelly_minimum_risk, kelly_prediction_model, }: ExtendConfigType): any[] | Signal;
|
|
1329
|
+
export declare function buildConfig(app_config: AppConfig, { take_profit, entry, stop, raw_instance, risk, no_of_trades, min_profit, risk_reward, kind, increase, gap, rr, price_places, decimal_places, use_kelly, kelly_confidence_factor, kelly_minimum_risk, kelly_prediction_model, kelly_func, }: ExtendConfigType): any[] | Signal;
|
|
1325
1330
|
export declare function buildAvg({ _trades, kind, }: {
|
|
1326
1331
|
_trades: any[];
|
|
1327
1332
|
kind: "long" | "short";
|
|
@@ -1335,6 +1340,7 @@ export declare function get_app_config_and_max_size(config: GlobalConfig, payloa
|
|
|
1335
1340
|
kelly_confidence_factor?: number;
|
|
1336
1341
|
kelly_minimum_risk?: number;
|
|
1337
1342
|
kelly_prediction_model?: "exponential" | "normal" | "uniform";
|
|
1343
|
+
kelly_func?: "theoretical" | "position_based" | "theoretical_fixed";
|
|
1338
1344
|
}): {
|
|
1339
1345
|
app_config: AppConfig;
|
|
1340
1346
|
max_size: any;
|
|
@@ -1358,6 +1364,7 @@ export declare function buildAppConfig(config: GlobalConfig, payload: {
|
|
|
1358
1364
|
kelly_confidence_factor?: number;
|
|
1359
1365
|
kelly_minimum_risk?: number;
|
|
1360
1366
|
kelly_prediction_model?: "exponential" | "normal" | "uniform";
|
|
1367
|
+
kelly_func?: "theoretical" | "position_based" | "theoretical_fixed";
|
|
1361
1368
|
}): AppConfig;
|
|
1362
1369
|
export declare function getOptimumStopAndRisk(app_config: AppConfig, params: {
|
|
1363
1370
|
max_size: number;
|
|
@@ -1896,6 +1903,7 @@ declare class ExchangeAccount$1 {
|
|
|
1896
1903
|
kelly_confidence_factor?: number;
|
|
1897
1904
|
kelly_minimum_risk?: number;
|
|
1898
1905
|
kelly_prediction_model?: "exponential" | "normal" | "uniform";
|
|
1906
|
+
kelly_func?: "theoretical" | "position_based" | "theoretical_fixed";
|
|
1899
1907
|
}): Promise<AppConfig>;
|
|
1900
1908
|
tradeConfig(payload: {
|
|
1901
1909
|
symbol: string;
|
|
@@ -2249,6 +2257,7 @@ declare class ExchangeAccount$1 {
|
|
|
2249
2257
|
kelly_confidence_factor?: number;
|
|
2250
2258
|
kelly_minimum_risk?: number;
|
|
2251
2259
|
kelly_prediction_model?: "exponential" | "normal" | "uniform";
|
|
2260
|
+
kelly_func?: "theoretical" | "position_based" | "theoretical_fixed";
|
|
2252
2261
|
};
|
|
2253
2262
|
}>;
|
|
2254
2263
|
runSimulation(payload: {
|
|
@@ -2435,6 +2444,7 @@ declare class ExchangeAccount$1 {
|
|
|
2435
2444
|
kelly_confidence_factor?: number;
|
|
2436
2445
|
kelly_minimum_risk?: number;
|
|
2437
2446
|
kelly_prediction_model?: "exponential" | "normal" | "uniform";
|
|
2447
|
+
kelly_func?: "theoretical" | "position_based" | "theoretical_fixed";
|
|
2438
2448
|
};
|
|
2439
2449
|
};
|
|
2440
2450
|
last_value: any;
|
|
@@ -2708,6 +2718,7 @@ declare class App {
|
|
|
2708
2718
|
kelly_confidence_factor?: number;
|
|
2709
2719
|
kelly_minimum_risk?: number;
|
|
2710
2720
|
kelly_prediction_model?: "exponential" | "normal" | "uniform";
|
|
2721
|
+
kelly_func?: "theoretical" | "position_based" | "theoretical_fixed";
|
|
2711
2722
|
};
|
|
2712
2723
|
};
|
|
2713
2724
|
last_value: any;
|
package/dist/index.js
CHANGED
|
@@ -52903,6 +52903,101 @@ function calculateZoneVolatility(zone_prices) {
|
|
|
52903
52903
|
const price_changes = zone_prices.slice(1).map((price, i2) => Math.abs(price - zone_prices[i2]) / zone_prices[i2]);
|
|
52904
52904
|
return price_changes.reduce((sum, change) => sum + change, 0) / price_changes.length;
|
|
52905
52905
|
}
|
|
52906
|
+
function calculateTheoreticalKellyFixed({
|
|
52907
|
+
current_entry,
|
|
52908
|
+
zone_prices,
|
|
52909
|
+
kind = "long",
|
|
52910
|
+
config: config2 = {}
|
|
52911
|
+
}) {
|
|
52912
|
+
const {
|
|
52913
|
+
price_prediction_model = "uniform",
|
|
52914
|
+
confidence_factor = 0.6,
|
|
52915
|
+
volatility_adjustment = true
|
|
52916
|
+
} = config2;
|
|
52917
|
+
const sorted_prices = zone_prices;
|
|
52918
|
+
const current_index = sorted_prices.findIndex((price) => price === current_entry);
|
|
52919
|
+
if (current_index === -1)
|
|
52920
|
+
return 0.02;
|
|
52921
|
+
let stop_loss;
|
|
52922
|
+
let target_zones;
|
|
52923
|
+
if (kind === "long") {
|
|
52924
|
+
stop_loss = Math.min(...zone_prices);
|
|
52925
|
+
target_zones = zone_prices.filter((price) => price > current_entry);
|
|
52926
|
+
} else {
|
|
52927
|
+
stop_loss = Math.max(...zone_prices);
|
|
52928
|
+
target_zones = zone_prices.filter((price) => price < current_entry);
|
|
52929
|
+
}
|
|
52930
|
+
const risk_amount = Math.abs(current_entry - stop_loss);
|
|
52931
|
+
const avg_reward = target_zones.length > 0 ? target_zones.reduce((sum, price) => sum + Math.abs(price - current_entry), 0) / target_zones.length : risk_amount;
|
|
52932
|
+
const risk_reward_ratio = avg_reward / risk_amount;
|
|
52933
|
+
let position_quality;
|
|
52934
|
+
if (kind === "long") {
|
|
52935
|
+
const distance_from_stop = current_entry - stop_loss;
|
|
52936
|
+
const max_distance = Math.max(...zone_prices) - stop_loss;
|
|
52937
|
+
position_quality = 1 - distance_from_stop / max_distance;
|
|
52938
|
+
} else {
|
|
52939
|
+
const distance_from_stop = stop_loss - current_entry;
|
|
52940
|
+
const max_distance = stop_loss - Math.min(...zone_prices);
|
|
52941
|
+
position_quality = 1 - distance_from_stop / max_distance;
|
|
52942
|
+
}
|
|
52943
|
+
let base_probability = 0.5;
|
|
52944
|
+
switch (price_prediction_model) {
|
|
52945
|
+
case "uniform":
|
|
52946
|
+
base_probability = 0.5;
|
|
52947
|
+
break;
|
|
52948
|
+
case "normal":
|
|
52949
|
+
base_probability = 0.3 + position_quality * 0.4;
|
|
52950
|
+
break;
|
|
52951
|
+
case "exponential":
|
|
52952
|
+
base_probability = 0.2 + Math.pow(position_quality, 0.5) * 0.6;
|
|
52953
|
+
break;
|
|
52954
|
+
}
|
|
52955
|
+
const win_probability = base_probability * confidence_factor + (1 - confidence_factor) * 0.5;
|
|
52956
|
+
const odds_ratio = Math.max(risk_reward_ratio, 0.5);
|
|
52957
|
+
const loss_probability = 1 - win_probability;
|
|
52958
|
+
let kelly_fraction = (win_probability * odds_ratio - loss_probability) / odds_ratio;
|
|
52959
|
+
if (volatility_adjustment) {
|
|
52960
|
+
const zone_volatility = calculateZoneVolatility(sorted_prices);
|
|
52961
|
+
const vol_adjustment = 1 / (1 + zone_volatility);
|
|
52962
|
+
kelly_fraction *= vol_adjustment;
|
|
52963
|
+
}
|
|
52964
|
+
kelly_fraction = Math.max(0.005, Math.min(kelly_fraction, 0.5));
|
|
52965
|
+
return to_f2(kelly_fraction, "%.4f");
|
|
52966
|
+
}
|
|
52967
|
+
function calculatePositionBasedKelly({
|
|
52968
|
+
current_entry,
|
|
52969
|
+
zone_prices,
|
|
52970
|
+
kind = "long",
|
|
52971
|
+
config: config2 = {}
|
|
52972
|
+
}) {
|
|
52973
|
+
const {
|
|
52974
|
+
price_prediction_model = "uniform",
|
|
52975
|
+
confidence_factor: _confidence_factor = 0.6
|
|
52976
|
+
} = config2;
|
|
52977
|
+
const current_index = zone_prices.findIndex((price) => price === current_entry);
|
|
52978
|
+
if (current_index === -1)
|
|
52979
|
+
return 0.02;
|
|
52980
|
+
const total_zones = zone_prices.length;
|
|
52981
|
+
const position_score = (total_zones - current_index) / total_zones;
|
|
52982
|
+
let adjusted_score;
|
|
52983
|
+
switch (price_prediction_model) {
|
|
52984
|
+
case "uniform":
|
|
52985
|
+
adjusted_score = 0.5;
|
|
52986
|
+
break;
|
|
52987
|
+
case "normal":
|
|
52988
|
+
adjusted_score = 0.3 + position_score * 0.4;
|
|
52989
|
+
break;
|
|
52990
|
+
case "exponential":
|
|
52991
|
+
adjusted_score = 0.2 + Math.pow(position_score, 0.3) * 0.6;
|
|
52992
|
+
break;
|
|
52993
|
+
default:
|
|
52994
|
+
adjusted_score = 0.5;
|
|
52995
|
+
}
|
|
52996
|
+
const base_kelly = 0.02;
|
|
52997
|
+
const max_kelly = 0.2;
|
|
52998
|
+
const kelly_fraction = base_kelly + adjusted_score * (max_kelly - base_kelly);
|
|
52999
|
+
return to_f2(kelly_fraction, "%.4f");
|
|
53000
|
+
}
|
|
52906
53001
|
|
|
52907
53002
|
// src/helpers/trade_signal.ts
|
|
52908
53003
|
function determine_close_price2({
|
|
@@ -52990,6 +53085,7 @@ class Signal {
|
|
|
52990
53085
|
kelly_prediction_model = "exponential";
|
|
52991
53086
|
kelly_confidence_factor = 0.6;
|
|
52992
53087
|
kelly_minimum_risk = 0.2;
|
|
53088
|
+
kelly_func = "theoretical";
|
|
52993
53089
|
constructor({
|
|
52994
53090
|
focus,
|
|
52995
53091
|
budget,
|
|
@@ -53014,7 +53110,8 @@ class Signal {
|
|
|
53014
53110
|
use_kelly = false,
|
|
53015
53111
|
kelly_prediction_model = "exponential",
|
|
53016
53112
|
kelly_confidence_factor = 0.6,
|
|
53017
|
-
kelly_minimum_risk = 0.2
|
|
53113
|
+
kelly_minimum_risk = 0.2,
|
|
53114
|
+
kelly_func = "theoretical"
|
|
53018
53115
|
}) {
|
|
53019
53116
|
this.minimum_size = minimum_size;
|
|
53020
53117
|
this.first_order_size = first_order_size;
|
|
@@ -53040,6 +53137,7 @@ class Signal {
|
|
|
53040
53137
|
this.kelly_prediction_model = kelly_prediction_model;
|
|
53041
53138
|
this.kelly_confidence_factor = kelly_confidence_factor;
|
|
53042
53139
|
this.kelly_minimum_risk = kelly_minimum_risk;
|
|
53140
|
+
this.kelly_func = kelly_func;
|
|
53043
53141
|
}
|
|
53044
53142
|
build_entry({
|
|
53045
53143
|
current_price,
|
|
@@ -53480,7 +53578,8 @@ class Signal {
|
|
|
53480
53578
|
const new_stop = kind === "long" ? this.support : stop_loss;
|
|
53481
53579
|
let risk_to_use = risk_per_trade;
|
|
53482
53580
|
if (this.use_kelly) {
|
|
53483
|
-
const
|
|
53581
|
+
const func = this.kelly_func === "theoretical" ? calculateTheoreticalKelly : this.kelly_func === "position_based" ? calculatePositionBasedKelly : calculateTheoreticalKellyFixed;
|
|
53582
|
+
const theoretical_kelly = func({
|
|
53484
53583
|
current_entry: x,
|
|
53485
53584
|
zone_prices: limit_orders,
|
|
53486
53585
|
kind,
|
|
@@ -53688,7 +53787,8 @@ function buildConfig(app_config, {
|
|
|
53688
53787
|
use_kelly = false,
|
|
53689
53788
|
kelly_confidence_factor = 0.95,
|
|
53690
53789
|
kelly_minimum_risk = 0.2,
|
|
53691
|
-
kelly_prediction_model = "exponential"
|
|
53790
|
+
kelly_prediction_model = "exponential",
|
|
53791
|
+
kelly_func = "theoretical"
|
|
53692
53792
|
}) {
|
|
53693
53793
|
let fee = app_config.fee / 100;
|
|
53694
53794
|
let working_risk = risk || app_config.risk_per_trade;
|
|
@@ -53716,7 +53816,8 @@ function buildConfig(app_config, {
|
|
|
53716
53816
|
use_kelly: use_kelly || app_config.kelly?.use_kelly,
|
|
53717
53817
|
kelly_confidence_factor: kelly_confidence_factor || app_config.kelly?.kelly_confidence_factor,
|
|
53718
53818
|
kelly_minimum_risk: kelly_minimum_risk || app_config.kelly?.kelly_minimum_risk,
|
|
53719
|
-
kelly_prediction_model: kelly_prediction_model || app_config.kelly?.kelly_prediction_model
|
|
53819
|
+
kelly_prediction_model: kelly_prediction_model || app_config.kelly?.kelly_prediction_model,
|
|
53820
|
+
kelly_func: kelly_func || app_config.kelly?.kelly_func
|
|
53720
53821
|
};
|
|
53721
53822
|
const instance = new Signal(config2);
|
|
53722
53823
|
if (raw_instance) {
|
|
@@ -53799,7 +53900,8 @@ function get_app_config_and_max_size(config2, payload) {
|
|
|
53799
53900
|
use_kelly: payload.use_kelly,
|
|
53800
53901
|
kelly_confidence_factor: payload.kelly_confidence_factor,
|
|
53801
53902
|
kelly_minimum_risk: payload.kelly_minimum_risk,
|
|
53802
|
-
kelly_prediction_model: payload.kelly_prediction_model
|
|
53903
|
+
kelly_prediction_model: payload.kelly_prediction_model,
|
|
53904
|
+
kelly_func: payload.kelly_func
|
|
53803
53905
|
});
|
|
53804
53906
|
const max_size = initialResult[0]?.avg_size;
|
|
53805
53907
|
const last_value = initialResult[0];
|
|
@@ -53836,7 +53938,8 @@ function buildAppConfig(config2, payload) {
|
|
|
53836
53938
|
use_kelly: payload.use_kelly,
|
|
53837
53939
|
kelly_confidence_factor: payload.kelly_confidence_factor,
|
|
53838
53940
|
kelly_minimum_risk: payload.kelly_minimum_risk,
|
|
53839
|
-
kelly_prediction_model: payload.kelly_prediction_model
|
|
53941
|
+
kelly_prediction_model: payload.kelly_prediction_model,
|
|
53942
|
+
kelly_func: payload.kelly_func
|
|
53840
53943
|
});
|
|
53841
53944
|
app_config.max_size = max_size;
|
|
53842
53945
|
app_config.entry = payload.entry || app_config.entry;
|
|
@@ -53847,7 +53950,8 @@ function buildAppConfig(config2, payload) {
|
|
|
53847
53950
|
use_kelly: payload.use_kelly,
|
|
53848
53951
|
kelly_confidence_factor: payload.kelly_confidence_factor,
|
|
53849
53952
|
kelly_minimum_risk: payload.kelly_minimum_risk,
|
|
53850
|
-
kelly_prediction_model: payload.kelly_prediction_model
|
|
53953
|
+
kelly_prediction_model: payload.kelly_prediction_model,
|
|
53954
|
+
kelly_func: payload.kelly_func
|
|
53851
53955
|
};
|
|
53852
53956
|
return app_config;
|
|
53853
53957
|
}
|
|
@@ -58234,6 +58338,7 @@ class ExchangeAccount {
|
|
|
58234
58338
|
kelly_confidence_factor: config2.kelly?.kelly_confidence_factor,
|
|
58235
58339
|
kelly_minimum_risk: config2.kelly?.kelly_minimum_risk,
|
|
58236
58340
|
kelly_prediction_model: config2.kelly?.kelly_prediction_model,
|
|
58341
|
+
kelly_func: config2.kelly?.kelly_func,
|
|
58237
58342
|
...override
|
|
58238
58343
|
});
|
|
58239
58344
|
return app_config;
|
package/dist/mcp-server.cjs
CHANGED
|
@@ -59650,6 +59650,101 @@ function calculateZoneVolatility(zone_prices) {
|
|
|
59650
59650
|
const price_changes = zone_prices.slice(1).map((price, i2) => Math.abs(price - zone_prices[i2]) / zone_prices[i2]);
|
|
59651
59651
|
return price_changes.reduce((sum, change) => sum + change, 0) / price_changes.length;
|
|
59652
59652
|
}
|
|
59653
|
+
function calculateTheoreticalKellyFixed({
|
|
59654
|
+
current_entry,
|
|
59655
|
+
zone_prices,
|
|
59656
|
+
kind = "long",
|
|
59657
|
+
config: config2 = {}
|
|
59658
|
+
}) {
|
|
59659
|
+
const {
|
|
59660
|
+
price_prediction_model = "uniform",
|
|
59661
|
+
confidence_factor = 0.6,
|
|
59662
|
+
volatility_adjustment = true
|
|
59663
|
+
} = config2;
|
|
59664
|
+
const sorted_prices = zone_prices;
|
|
59665
|
+
const current_index = sorted_prices.findIndex((price) => price === current_entry);
|
|
59666
|
+
if (current_index === -1)
|
|
59667
|
+
return 0.02;
|
|
59668
|
+
let stop_loss;
|
|
59669
|
+
let target_zones;
|
|
59670
|
+
if (kind === "long") {
|
|
59671
|
+
stop_loss = Math.min(...zone_prices);
|
|
59672
|
+
target_zones = zone_prices.filter((price) => price > current_entry);
|
|
59673
|
+
} else {
|
|
59674
|
+
stop_loss = Math.max(...zone_prices);
|
|
59675
|
+
target_zones = zone_prices.filter((price) => price < current_entry);
|
|
59676
|
+
}
|
|
59677
|
+
const risk_amount = Math.abs(current_entry - stop_loss);
|
|
59678
|
+
const avg_reward = target_zones.length > 0 ? target_zones.reduce((sum, price) => sum + Math.abs(price - current_entry), 0) / target_zones.length : risk_amount;
|
|
59679
|
+
const risk_reward_ratio = avg_reward / risk_amount;
|
|
59680
|
+
let position_quality;
|
|
59681
|
+
if (kind === "long") {
|
|
59682
|
+
const distance_from_stop = current_entry - stop_loss;
|
|
59683
|
+
const max_distance = Math.max(...zone_prices) - stop_loss;
|
|
59684
|
+
position_quality = 1 - distance_from_stop / max_distance;
|
|
59685
|
+
} else {
|
|
59686
|
+
const distance_from_stop = stop_loss - current_entry;
|
|
59687
|
+
const max_distance = stop_loss - Math.min(...zone_prices);
|
|
59688
|
+
position_quality = 1 - distance_from_stop / max_distance;
|
|
59689
|
+
}
|
|
59690
|
+
let base_probability = 0.5;
|
|
59691
|
+
switch (price_prediction_model) {
|
|
59692
|
+
case "uniform":
|
|
59693
|
+
base_probability = 0.5;
|
|
59694
|
+
break;
|
|
59695
|
+
case "normal":
|
|
59696
|
+
base_probability = 0.3 + position_quality * 0.4;
|
|
59697
|
+
break;
|
|
59698
|
+
case "exponential":
|
|
59699
|
+
base_probability = 0.2 + Math.pow(position_quality, 0.5) * 0.6;
|
|
59700
|
+
break;
|
|
59701
|
+
}
|
|
59702
|
+
const win_probability = base_probability * confidence_factor + (1 - confidence_factor) * 0.5;
|
|
59703
|
+
const odds_ratio = Math.max(risk_reward_ratio, 0.5);
|
|
59704
|
+
const loss_probability = 1 - win_probability;
|
|
59705
|
+
let kelly_fraction = (win_probability * odds_ratio - loss_probability) / odds_ratio;
|
|
59706
|
+
if (volatility_adjustment) {
|
|
59707
|
+
const zone_volatility = calculateZoneVolatility(sorted_prices);
|
|
59708
|
+
const vol_adjustment = 1 / (1 + zone_volatility);
|
|
59709
|
+
kelly_fraction *= vol_adjustment;
|
|
59710
|
+
}
|
|
59711
|
+
kelly_fraction = Math.max(0.005, Math.min(kelly_fraction, 0.5));
|
|
59712
|
+
return to_f2(kelly_fraction, "%.4f");
|
|
59713
|
+
}
|
|
59714
|
+
function calculatePositionBasedKelly({
|
|
59715
|
+
current_entry,
|
|
59716
|
+
zone_prices,
|
|
59717
|
+
kind = "long",
|
|
59718
|
+
config: config2 = {}
|
|
59719
|
+
}) {
|
|
59720
|
+
const {
|
|
59721
|
+
price_prediction_model = "uniform",
|
|
59722
|
+
confidence_factor: _confidence_factor = 0.6
|
|
59723
|
+
} = config2;
|
|
59724
|
+
const current_index = zone_prices.findIndex((price) => price === current_entry);
|
|
59725
|
+
if (current_index === -1)
|
|
59726
|
+
return 0.02;
|
|
59727
|
+
const total_zones = zone_prices.length;
|
|
59728
|
+
const position_score = (total_zones - current_index) / total_zones;
|
|
59729
|
+
let adjusted_score;
|
|
59730
|
+
switch (price_prediction_model) {
|
|
59731
|
+
case "uniform":
|
|
59732
|
+
adjusted_score = 0.5;
|
|
59733
|
+
break;
|
|
59734
|
+
case "normal":
|
|
59735
|
+
adjusted_score = 0.3 + position_score * 0.4;
|
|
59736
|
+
break;
|
|
59737
|
+
case "exponential":
|
|
59738
|
+
adjusted_score = 0.2 + Math.pow(position_score, 0.3) * 0.6;
|
|
59739
|
+
break;
|
|
59740
|
+
default:
|
|
59741
|
+
adjusted_score = 0.5;
|
|
59742
|
+
}
|
|
59743
|
+
const base_kelly = 0.02;
|
|
59744
|
+
const max_kelly = 0.2;
|
|
59745
|
+
const kelly_fraction = base_kelly + adjusted_score * (max_kelly - base_kelly);
|
|
59746
|
+
return to_f2(kelly_fraction, "%.4f");
|
|
59747
|
+
}
|
|
59653
59748
|
|
|
59654
59749
|
// src/helpers/trade_signal.ts
|
|
59655
59750
|
function determine_close_price2({
|
|
@@ -59737,6 +59832,7 @@ class Signal {
|
|
|
59737
59832
|
kelly_prediction_model = "exponential";
|
|
59738
59833
|
kelly_confidence_factor = 0.6;
|
|
59739
59834
|
kelly_minimum_risk = 0.2;
|
|
59835
|
+
kelly_func = "theoretical";
|
|
59740
59836
|
constructor({
|
|
59741
59837
|
focus,
|
|
59742
59838
|
budget,
|
|
@@ -59761,7 +59857,8 @@ class Signal {
|
|
|
59761
59857
|
use_kelly = false,
|
|
59762
59858
|
kelly_prediction_model = "exponential",
|
|
59763
59859
|
kelly_confidence_factor = 0.6,
|
|
59764
|
-
kelly_minimum_risk = 0.2
|
|
59860
|
+
kelly_minimum_risk = 0.2,
|
|
59861
|
+
kelly_func = "theoretical"
|
|
59765
59862
|
}) {
|
|
59766
59863
|
this.minimum_size = minimum_size;
|
|
59767
59864
|
this.first_order_size = first_order_size;
|
|
@@ -59787,6 +59884,7 @@ class Signal {
|
|
|
59787
59884
|
this.kelly_prediction_model = kelly_prediction_model;
|
|
59788
59885
|
this.kelly_confidence_factor = kelly_confidence_factor;
|
|
59789
59886
|
this.kelly_minimum_risk = kelly_minimum_risk;
|
|
59887
|
+
this.kelly_func = kelly_func;
|
|
59790
59888
|
}
|
|
59791
59889
|
build_entry({
|
|
59792
59890
|
current_price,
|
|
@@ -60227,7 +60325,8 @@ class Signal {
|
|
|
60227
60325
|
const new_stop = kind === "long" ? this.support : stop_loss;
|
|
60228
60326
|
let risk_to_use = risk_per_trade;
|
|
60229
60327
|
if (this.use_kelly) {
|
|
60230
|
-
const
|
|
60328
|
+
const func = this.kelly_func === "theoretical" ? calculateTheoreticalKelly : this.kelly_func === "position_based" ? calculatePositionBasedKelly : calculateTheoreticalKellyFixed;
|
|
60329
|
+
const theoretical_kelly = func({
|
|
60231
60330
|
current_entry: x,
|
|
60232
60331
|
zone_prices: limit_orders,
|
|
60233
60332
|
kind,
|
|
@@ -60435,7 +60534,8 @@ function buildConfig(app_config, {
|
|
|
60435
60534
|
use_kelly = false,
|
|
60436
60535
|
kelly_confidence_factor = 0.95,
|
|
60437
60536
|
kelly_minimum_risk = 0.2,
|
|
60438
|
-
kelly_prediction_model = "exponential"
|
|
60537
|
+
kelly_prediction_model = "exponential",
|
|
60538
|
+
kelly_func = "theoretical"
|
|
60439
60539
|
}) {
|
|
60440
60540
|
let fee = app_config.fee / 100;
|
|
60441
60541
|
let working_risk = risk || app_config.risk_per_trade;
|
|
@@ -60463,7 +60563,8 @@ function buildConfig(app_config, {
|
|
|
60463
60563
|
use_kelly: use_kelly || app_config.kelly?.use_kelly,
|
|
60464
60564
|
kelly_confidence_factor: kelly_confidence_factor || app_config.kelly?.kelly_confidence_factor,
|
|
60465
60565
|
kelly_minimum_risk: kelly_minimum_risk || app_config.kelly?.kelly_minimum_risk,
|
|
60466
|
-
kelly_prediction_model: kelly_prediction_model || app_config.kelly?.kelly_prediction_model
|
|
60566
|
+
kelly_prediction_model: kelly_prediction_model || app_config.kelly?.kelly_prediction_model,
|
|
60567
|
+
kelly_func: kelly_func || app_config.kelly?.kelly_func
|
|
60467
60568
|
};
|
|
60468
60569
|
const instance = new Signal(config2);
|
|
60469
60570
|
if (raw_instance) {
|
|
@@ -60533,7 +60634,8 @@ function get_app_config_and_max_size(config2, payload) {
|
|
|
60533
60634
|
use_kelly: payload.use_kelly,
|
|
60534
60635
|
kelly_confidence_factor: payload.kelly_confidence_factor,
|
|
60535
60636
|
kelly_minimum_risk: payload.kelly_minimum_risk,
|
|
60536
|
-
kelly_prediction_model: payload.kelly_prediction_model
|
|
60637
|
+
kelly_prediction_model: payload.kelly_prediction_model,
|
|
60638
|
+
kelly_func: payload.kelly_func
|
|
60537
60639
|
});
|
|
60538
60640
|
const max_size = initialResult[0]?.avg_size;
|
|
60539
60641
|
const last_value = initialResult[0];
|
|
@@ -60570,7 +60672,8 @@ function buildAppConfig(config2, payload) {
|
|
|
60570
60672
|
use_kelly: payload.use_kelly,
|
|
60571
60673
|
kelly_confidence_factor: payload.kelly_confidence_factor,
|
|
60572
60674
|
kelly_minimum_risk: payload.kelly_minimum_risk,
|
|
60573
|
-
kelly_prediction_model: payload.kelly_prediction_model
|
|
60675
|
+
kelly_prediction_model: payload.kelly_prediction_model,
|
|
60676
|
+
kelly_func: payload.kelly_func
|
|
60574
60677
|
});
|
|
60575
60678
|
app_config.max_size = max_size;
|
|
60576
60679
|
app_config.entry = payload.entry || app_config.entry;
|
|
@@ -60581,7 +60684,8 @@ function buildAppConfig(config2, payload) {
|
|
|
60581
60684
|
use_kelly: payload.use_kelly,
|
|
60582
60685
|
kelly_confidence_factor: payload.kelly_confidence_factor,
|
|
60583
60686
|
kelly_minimum_risk: payload.kelly_minimum_risk,
|
|
60584
|
-
kelly_prediction_model: payload.kelly_prediction_model
|
|
60687
|
+
kelly_prediction_model: payload.kelly_prediction_model,
|
|
60688
|
+
kelly_func: payload.kelly_func
|
|
60585
60689
|
};
|
|
60586
60690
|
return app_config;
|
|
60587
60691
|
}
|
|
@@ -64962,6 +65066,7 @@ class ExchangeAccount {
|
|
|
64962
65066
|
kelly_confidence_factor: config2.kelly?.kelly_confidence_factor,
|
|
64963
65067
|
kelly_minimum_risk: config2.kelly?.kelly_minimum_risk,
|
|
64964
65068
|
kelly_prediction_model: config2.kelly?.kelly_prediction_model,
|
|
65069
|
+
kelly_func: config2.kelly?.kelly_func,
|
|
64965
65070
|
...override
|
|
64966
65071
|
});
|
|
64967
65072
|
return app_config;
|
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;
|