@gbozee/ultimate 0.0.2-129 → 0.0.2-130
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 +22 -0
- package/dist/frontend-index.js +76 -1
- package/dist/index.cjs +76 -1
- package/dist/index.d.ts +22 -0
- package/dist/index.js +76 -1
- package/dist/mcp-server.cjs +75 -1
- package/dist/mcp-server.js +75 -1
- package/package.json +1 -1
package/dist/frontend-index.d.ts
CHANGED
|
@@ -418,6 +418,27 @@ export declare function determineOptimumReward(app_config: AppConfig, increase?:
|
|
|
418
418
|
neg_pnl: any;
|
|
419
419
|
entry: any;
|
|
420
420
|
};
|
|
421
|
+
export declare function determineOptimumRisk(config: GlobalConfig, payload: {
|
|
422
|
+
entry: number;
|
|
423
|
+
stop: number;
|
|
424
|
+
risk_reward: number;
|
|
425
|
+
risk: number;
|
|
426
|
+
symbol: string;
|
|
427
|
+
}, params: {
|
|
428
|
+
highest_risk: number;
|
|
429
|
+
tolerance?: number;
|
|
430
|
+
max_iterations?: number;
|
|
431
|
+
}): {
|
|
432
|
+
optimal_risk: number;
|
|
433
|
+
achieved_neg_pnl: number;
|
|
434
|
+
target_neg_pnl: number;
|
|
435
|
+
difference: number;
|
|
436
|
+
iterations: number;
|
|
437
|
+
converged: boolean;
|
|
438
|
+
last_value: any;
|
|
439
|
+
entries: any[];
|
|
440
|
+
app_config: AppConfig;
|
|
441
|
+
};
|
|
421
442
|
export declare function computeRiskReward(payload: {
|
|
422
443
|
app_config: AppConfig;
|
|
423
444
|
entry: number;
|
|
@@ -438,6 +459,7 @@ export declare function getRiskReward(payload: {
|
|
|
438
459
|
stop: number;
|
|
439
460
|
risk: number;
|
|
440
461
|
global_config: GlobalConfig;
|
|
462
|
+
force_exact_risk?: boolean;
|
|
441
463
|
}): any;
|
|
442
464
|
export declare function computeProfitDetail(payload: {
|
|
443
465
|
focus_position: {
|
package/dist/frontend-index.js
CHANGED
|
@@ -1786,6 +1786,62 @@ function findIndexByCondition(lst, kind, condition, defaultKey = "neg_pnl") {
|
|
|
1786
1786
|
}, found[0]);
|
|
1787
1787
|
return maximum;
|
|
1788
1788
|
}
|
|
1789
|
+
function determineOptimumRisk(config, payload, params) {
|
|
1790
|
+
const { highest_risk, tolerance = 0.01, max_iterations = 200 } = params;
|
|
1791
|
+
let low_risk = 1;
|
|
1792
|
+
let high_risk = Math.max(highest_risk * 5, payload.risk * 10);
|
|
1793
|
+
let best_risk = payload.risk;
|
|
1794
|
+
let best_neg_pnl = 0;
|
|
1795
|
+
let best_diff = Infinity;
|
|
1796
|
+
console.log(`Finding optimal risk for target neg_pnl: ${highest_risk}`);
|
|
1797
|
+
let iterations = 0;
|
|
1798
|
+
while (iterations < max_iterations && high_risk - low_risk > tolerance) {
|
|
1799
|
+
iterations++;
|
|
1800
|
+
const mid_risk = (low_risk + high_risk) / 2;
|
|
1801
|
+
const test_payload = {
|
|
1802
|
+
...payload,
|
|
1803
|
+
risk: mid_risk
|
|
1804
|
+
};
|
|
1805
|
+
const { last_value } = buildAppConfig(config, test_payload);
|
|
1806
|
+
if (!last_value || !last_value.neg_pnl) {
|
|
1807
|
+
high_risk = mid_risk;
|
|
1808
|
+
continue;
|
|
1809
|
+
}
|
|
1810
|
+
const current_neg_pnl = Math.abs(last_value.neg_pnl);
|
|
1811
|
+
const diff = Math.abs(current_neg_pnl - highest_risk);
|
|
1812
|
+
console.log(`Iteration ${iterations}: Risk=${mid_risk.toFixed(2)}, neg_pnl=${current_neg_pnl.toFixed(2)}, diff=${diff.toFixed(2)}`);
|
|
1813
|
+
if (diff < best_diff) {
|
|
1814
|
+
best_diff = diff;
|
|
1815
|
+
best_risk = mid_risk;
|
|
1816
|
+
best_neg_pnl = current_neg_pnl;
|
|
1817
|
+
}
|
|
1818
|
+
if (diff <= tolerance) {
|
|
1819
|
+
console.log(`Converged! Optimal risk: ${mid_risk.toFixed(2)}`);
|
|
1820
|
+
break;
|
|
1821
|
+
}
|
|
1822
|
+
if (current_neg_pnl < highest_risk) {
|
|
1823
|
+
low_risk = mid_risk;
|
|
1824
|
+
} else {
|
|
1825
|
+
high_risk = mid_risk;
|
|
1826
|
+
}
|
|
1827
|
+
}
|
|
1828
|
+
const final_payload = {
|
|
1829
|
+
...payload,
|
|
1830
|
+
risk: best_risk
|
|
1831
|
+
};
|
|
1832
|
+
const final_result = buildAppConfig(config, final_payload);
|
|
1833
|
+
return {
|
|
1834
|
+
optimal_risk: to_f(best_risk, "%.2f"),
|
|
1835
|
+
achieved_neg_pnl: to_f(best_neg_pnl, "%.2f"),
|
|
1836
|
+
target_neg_pnl: to_f(highest_risk, "%.2f"),
|
|
1837
|
+
difference: to_f(best_diff, "%.2f"),
|
|
1838
|
+
iterations,
|
|
1839
|
+
converged: best_diff <= tolerance,
|
|
1840
|
+
last_value: final_result.last_value,
|
|
1841
|
+
entries: final_result.entries,
|
|
1842
|
+
app_config: final_result
|
|
1843
|
+
};
|
|
1844
|
+
}
|
|
1789
1845
|
function computeRiskReward(payload) {
|
|
1790
1846
|
const { app_config, entry, stop, risk_per_trade } = payload;
|
|
1791
1847
|
const kind = entry > stop ? "long" : "short";
|
|
@@ -1797,7 +1853,13 @@ function computeRiskReward(payload) {
|
|
|
1797
1853
|
return result;
|
|
1798
1854
|
}
|
|
1799
1855
|
function getRiskReward(payload) {
|
|
1800
|
-
const {
|
|
1856
|
+
const {
|
|
1857
|
+
entry,
|
|
1858
|
+
stop,
|
|
1859
|
+
risk,
|
|
1860
|
+
global_config,
|
|
1861
|
+
force_exact_risk = false
|
|
1862
|
+
} = payload;
|
|
1801
1863
|
const { entries, last_value, ...app_config } = buildAppConfig(global_config, {
|
|
1802
1864
|
entry,
|
|
1803
1865
|
stop,
|
|
@@ -1811,6 +1873,18 @@ function getRiskReward(payload) {
|
|
|
1811
1873
|
stop,
|
|
1812
1874
|
risk_per_trade: risk
|
|
1813
1875
|
});
|
|
1876
|
+
if (force_exact_risk) {
|
|
1877
|
+
const new_risk_per_trade = determineOptimumRisk(global_config, {
|
|
1878
|
+
entry,
|
|
1879
|
+
stop,
|
|
1880
|
+
risk_reward,
|
|
1881
|
+
risk,
|
|
1882
|
+
symbol: global_config.symbol
|
|
1883
|
+
}, {
|
|
1884
|
+
highest_risk: risk
|
|
1885
|
+
}).optimal_risk;
|
|
1886
|
+
return { risk: new_risk_per_trade, risk_reward };
|
|
1887
|
+
}
|
|
1814
1888
|
return risk_reward;
|
|
1815
1889
|
}
|
|
1816
1890
|
function computeProfitDetail(payload) {
|
|
@@ -2589,6 +2663,7 @@ export {
|
|
|
2589
2663
|
determine_amount_to_buy,
|
|
2590
2664
|
determineTPSl,
|
|
2591
2665
|
determineRewardFactor,
|
|
2666
|
+
determineOptimumRisk,
|
|
2592
2667
|
determineOptimumReward,
|
|
2593
2668
|
createGapPairs,
|
|
2594
2669
|
createArray,
|
package/dist/index.cjs
CHANGED
|
@@ -41961,6 +41961,7 @@ __export(exports_src, {
|
|
|
41961
41961
|
determine_average_entry_and_size: () => determine_average_entry_and_size,
|
|
41962
41962
|
determine_amount_to_buy: () => determine_amount_to_buy,
|
|
41963
41963
|
determineRewardFactor: () => determineRewardFactor,
|
|
41964
|
+
determineOptimumRisk: () => determineOptimumRisk,
|
|
41964
41965
|
determineOptimumReward: () => determineOptimumReward,
|
|
41965
41966
|
database: () => exports_database,
|
|
41966
41967
|
createArray: () => createArray,
|
|
@@ -54090,6 +54091,62 @@ function findIndexByCondition(lst, kind, condition, defaultKey = "neg_pnl") {
|
|
|
54090
54091
|
}, found[0]);
|
|
54091
54092
|
return maximum;
|
|
54092
54093
|
}
|
|
54094
|
+
function determineOptimumRisk(config2, payload, params) {
|
|
54095
|
+
const { highest_risk, tolerance = 0.01, max_iterations = 200 } = params;
|
|
54096
|
+
let low_risk = 1;
|
|
54097
|
+
let high_risk = Math.max(highest_risk * 5, payload.risk * 10);
|
|
54098
|
+
let best_risk = payload.risk;
|
|
54099
|
+
let best_neg_pnl = 0;
|
|
54100
|
+
let best_diff = Infinity;
|
|
54101
|
+
console.log(`Finding optimal risk for target neg_pnl: ${highest_risk}`);
|
|
54102
|
+
let iterations = 0;
|
|
54103
|
+
while (iterations < max_iterations && high_risk - low_risk > tolerance) {
|
|
54104
|
+
iterations++;
|
|
54105
|
+
const mid_risk = (low_risk + high_risk) / 2;
|
|
54106
|
+
const test_payload = {
|
|
54107
|
+
...payload,
|
|
54108
|
+
risk: mid_risk
|
|
54109
|
+
};
|
|
54110
|
+
const { last_value } = buildAppConfig(config2, test_payload);
|
|
54111
|
+
if (!last_value || !last_value.neg_pnl) {
|
|
54112
|
+
high_risk = mid_risk;
|
|
54113
|
+
continue;
|
|
54114
|
+
}
|
|
54115
|
+
const current_neg_pnl = Math.abs(last_value.neg_pnl);
|
|
54116
|
+
const diff = Math.abs(current_neg_pnl - highest_risk);
|
|
54117
|
+
console.log(`Iteration ${iterations}: Risk=${mid_risk.toFixed(2)}, neg_pnl=${current_neg_pnl.toFixed(2)}, diff=${diff.toFixed(2)}`);
|
|
54118
|
+
if (diff < best_diff) {
|
|
54119
|
+
best_diff = diff;
|
|
54120
|
+
best_risk = mid_risk;
|
|
54121
|
+
best_neg_pnl = current_neg_pnl;
|
|
54122
|
+
}
|
|
54123
|
+
if (diff <= tolerance) {
|
|
54124
|
+
console.log(`Converged! Optimal risk: ${mid_risk.toFixed(2)}`);
|
|
54125
|
+
break;
|
|
54126
|
+
}
|
|
54127
|
+
if (current_neg_pnl < highest_risk) {
|
|
54128
|
+
low_risk = mid_risk;
|
|
54129
|
+
} else {
|
|
54130
|
+
high_risk = mid_risk;
|
|
54131
|
+
}
|
|
54132
|
+
}
|
|
54133
|
+
const final_payload = {
|
|
54134
|
+
...payload,
|
|
54135
|
+
risk: best_risk
|
|
54136
|
+
};
|
|
54137
|
+
const final_result = buildAppConfig(config2, final_payload);
|
|
54138
|
+
return {
|
|
54139
|
+
optimal_risk: to_f2(best_risk, "%.2f"),
|
|
54140
|
+
achieved_neg_pnl: to_f2(best_neg_pnl, "%.2f"),
|
|
54141
|
+
target_neg_pnl: to_f2(highest_risk, "%.2f"),
|
|
54142
|
+
difference: to_f2(best_diff, "%.2f"),
|
|
54143
|
+
iterations,
|
|
54144
|
+
converged: best_diff <= tolerance,
|
|
54145
|
+
last_value: final_result.last_value,
|
|
54146
|
+
entries: final_result.entries,
|
|
54147
|
+
app_config: final_result
|
|
54148
|
+
};
|
|
54149
|
+
}
|
|
54093
54150
|
function computeRiskReward(payload) {
|
|
54094
54151
|
const { app_config, entry, stop, risk_per_trade } = payload;
|
|
54095
54152
|
const kind = entry > stop ? "long" : "short";
|
|
@@ -54101,7 +54158,13 @@ function computeRiskReward(payload) {
|
|
|
54101
54158
|
return result;
|
|
54102
54159
|
}
|
|
54103
54160
|
function getRiskReward(payload) {
|
|
54104
|
-
const {
|
|
54161
|
+
const {
|
|
54162
|
+
entry,
|
|
54163
|
+
stop,
|
|
54164
|
+
risk,
|
|
54165
|
+
global_config,
|
|
54166
|
+
force_exact_risk = false
|
|
54167
|
+
} = payload;
|
|
54105
54168
|
const { entries, last_value, ...app_config } = buildAppConfig(global_config, {
|
|
54106
54169
|
entry,
|
|
54107
54170
|
stop,
|
|
@@ -54115,6 +54178,18 @@ function getRiskReward(payload) {
|
|
|
54115
54178
|
stop,
|
|
54116
54179
|
risk_per_trade: risk
|
|
54117
54180
|
});
|
|
54181
|
+
if (force_exact_risk) {
|
|
54182
|
+
const new_risk_per_trade = determineOptimumRisk(global_config, {
|
|
54183
|
+
entry,
|
|
54184
|
+
stop,
|
|
54185
|
+
risk_reward,
|
|
54186
|
+
risk,
|
|
54187
|
+
symbol: global_config.symbol
|
|
54188
|
+
}, {
|
|
54189
|
+
highest_risk: risk
|
|
54190
|
+
}).optimal_risk;
|
|
54191
|
+
return { risk: new_risk_per_trade, risk_reward };
|
|
54192
|
+
}
|
|
54118
54193
|
return risk_reward;
|
|
54119
54194
|
}
|
|
54120
54195
|
function computeProfitDetail(payload) {
|
package/dist/index.d.ts
CHANGED
|
@@ -1347,6 +1347,27 @@ export declare function determineOptimumReward(app_config: AppConfig, increase?:
|
|
|
1347
1347
|
neg_pnl: any;
|
|
1348
1348
|
entry: any;
|
|
1349
1349
|
};
|
|
1350
|
+
export declare function determineOptimumRisk(config: GlobalConfig, payload: {
|
|
1351
|
+
entry: number;
|
|
1352
|
+
stop: number;
|
|
1353
|
+
risk_reward: number;
|
|
1354
|
+
risk: number;
|
|
1355
|
+
symbol: string;
|
|
1356
|
+
}, params: {
|
|
1357
|
+
highest_risk: number;
|
|
1358
|
+
tolerance?: number;
|
|
1359
|
+
max_iterations?: number;
|
|
1360
|
+
}): {
|
|
1361
|
+
optimal_risk: number;
|
|
1362
|
+
achieved_neg_pnl: number;
|
|
1363
|
+
target_neg_pnl: number;
|
|
1364
|
+
difference: number;
|
|
1365
|
+
iterations: number;
|
|
1366
|
+
converged: boolean;
|
|
1367
|
+
last_value: any;
|
|
1368
|
+
entries: any[];
|
|
1369
|
+
app_config: AppConfig;
|
|
1370
|
+
};
|
|
1350
1371
|
export declare function computeRiskReward(payload: {
|
|
1351
1372
|
app_config: AppConfig;
|
|
1352
1373
|
entry: number;
|
|
@@ -1367,6 +1388,7 @@ export declare function getRiskReward(payload: {
|
|
|
1367
1388
|
stop: number;
|
|
1368
1389
|
risk: number;
|
|
1369
1390
|
global_config: GlobalConfig;
|
|
1391
|
+
force_exact_risk?: boolean;
|
|
1370
1392
|
}): any;
|
|
1371
1393
|
export declare function computeProfitDetail(payload: {
|
|
1372
1394
|
focus_position: {
|
package/dist/index.js
CHANGED
|
@@ -54040,6 +54040,62 @@ function findIndexByCondition(lst, kind, condition, defaultKey = "neg_pnl") {
|
|
|
54040
54040
|
}, found[0]);
|
|
54041
54041
|
return maximum;
|
|
54042
54042
|
}
|
|
54043
|
+
function determineOptimumRisk(config2, payload, params) {
|
|
54044
|
+
const { highest_risk, tolerance = 0.01, max_iterations = 200 } = params;
|
|
54045
|
+
let low_risk = 1;
|
|
54046
|
+
let high_risk = Math.max(highest_risk * 5, payload.risk * 10);
|
|
54047
|
+
let best_risk = payload.risk;
|
|
54048
|
+
let best_neg_pnl = 0;
|
|
54049
|
+
let best_diff = Infinity;
|
|
54050
|
+
console.log(`Finding optimal risk for target neg_pnl: ${highest_risk}`);
|
|
54051
|
+
let iterations = 0;
|
|
54052
|
+
while (iterations < max_iterations && high_risk - low_risk > tolerance) {
|
|
54053
|
+
iterations++;
|
|
54054
|
+
const mid_risk = (low_risk + high_risk) / 2;
|
|
54055
|
+
const test_payload = {
|
|
54056
|
+
...payload,
|
|
54057
|
+
risk: mid_risk
|
|
54058
|
+
};
|
|
54059
|
+
const { last_value } = buildAppConfig(config2, test_payload);
|
|
54060
|
+
if (!last_value || !last_value.neg_pnl) {
|
|
54061
|
+
high_risk = mid_risk;
|
|
54062
|
+
continue;
|
|
54063
|
+
}
|
|
54064
|
+
const current_neg_pnl = Math.abs(last_value.neg_pnl);
|
|
54065
|
+
const diff = Math.abs(current_neg_pnl - highest_risk);
|
|
54066
|
+
console.log(`Iteration ${iterations}: Risk=${mid_risk.toFixed(2)}, neg_pnl=${current_neg_pnl.toFixed(2)}, diff=${diff.toFixed(2)}`);
|
|
54067
|
+
if (diff < best_diff) {
|
|
54068
|
+
best_diff = diff;
|
|
54069
|
+
best_risk = mid_risk;
|
|
54070
|
+
best_neg_pnl = current_neg_pnl;
|
|
54071
|
+
}
|
|
54072
|
+
if (diff <= tolerance) {
|
|
54073
|
+
console.log(`Converged! Optimal risk: ${mid_risk.toFixed(2)}`);
|
|
54074
|
+
break;
|
|
54075
|
+
}
|
|
54076
|
+
if (current_neg_pnl < highest_risk) {
|
|
54077
|
+
low_risk = mid_risk;
|
|
54078
|
+
} else {
|
|
54079
|
+
high_risk = mid_risk;
|
|
54080
|
+
}
|
|
54081
|
+
}
|
|
54082
|
+
const final_payload = {
|
|
54083
|
+
...payload,
|
|
54084
|
+
risk: best_risk
|
|
54085
|
+
};
|
|
54086
|
+
const final_result = buildAppConfig(config2, final_payload);
|
|
54087
|
+
return {
|
|
54088
|
+
optimal_risk: to_f2(best_risk, "%.2f"),
|
|
54089
|
+
achieved_neg_pnl: to_f2(best_neg_pnl, "%.2f"),
|
|
54090
|
+
target_neg_pnl: to_f2(highest_risk, "%.2f"),
|
|
54091
|
+
difference: to_f2(best_diff, "%.2f"),
|
|
54092
|
+
iterations,
|
|
54093
|
+
converged: best_diff <= tolerance,
|
|
54094
|
+
last_value: final_result.last_value,
|
|
54095
|
+
entries: final_result.entries,
|
|
54096
|
+
app_config: final_result
|
|
54097
|
+
};
|
|
54098
|
+
}
|
|
54043
54099
|
function computeRiskReward(payload) {
|
|
54044
54100
|
const { app_config, entry, stop, risk_per_trade } = payload;
|
|
54045
54101
|
const kind = entry > stop ? "long" : "short";
|
|
@@ -54051,7 +54107,13 @@ function computeRiskReward(payload) {
|
|
|
54051
54107
|
return result;
|
|
54052
54108
|
}
|
|
54053
54109
|
function getRiskReward(payload) {
|
|
54054
|
-
const {
|
|
54110
|
+
const {
|
|
54111
|
+
entry,
|
|
54112
|
+
stop,
|
|
54113
|
+
risk,
|
|
54114
|
+
global_config,
|
|
54115
|
+
force_exact_risk = false
|
|
54116
|
+
} = payload;
|
|
54055
54117
|
const { entries, last_value, ...app_config } = buildAppConfig(global_config, {
|
|
54056
54118
|
entry,
|
|
54057
54119
|
stop,
|
|
@@ -54065,6 +54127,18 @@ function getRiskReward(payload) {
|
|
|
54065
54127
|
stop,
|
|
54066
54128
|
risk_per_trade: risk
|
|
54067
54129
|
});
|
|
54130
|
+
if (force_exact_risk) {
|
|
54131
|
+
const new_risk_per_trade = determineOptimumRisk(global_config, {
|
|
54132
|
+
entry,
|
|
54133
|
+
stop,
|
|
54134
|
+
risk_reward,
|
|
54135
|
+
risk,
|
|
54136
|
+
symbol: global_config.symbol
|
|
54137
|
+
}, {
|
|
54138
|
+
highest_risk: risk
|
|
54139
|
+
}).optimal_risk;
|
|
54140
|
+
return { risk: new_risk_per_trade, risk_reward };
|
|
54141
|
+
}
|
|
54068
54142
|
return risk_reward;
|
|
54069
54143
|
}
|
|
54070
54144
|
function computeProfitDetail(payload) {
|
|
@@ -60431,6 +60505,7 @@ export {
|
|
|
60431
60505
|
determine_average_entry_and_size,
|
|
60432
60506
|
determine_amount_to_buy,
|
|
60433
60507
|
determineRewardFactor,
|
|
60508
|
+
determineOptimumRisk,
|
|
60434
60509
|
determineOptimumReward,
|
|
60435
60510
|
exports_database as database,
|
|
60436
60511
|
createArray,
|
package/dist/mcp-server.cjs
CHANGED
|
@@ -60774,6 +60774,62 @@ function findIndexByCondition(lst, kind, condition, defaultKey = "neg_pnl") {
|
|
|
60774
60774
|
}, found[0]);
|
|
60775
60775
|
return maximum;
|
|
60776
60776
|
}
|
|
60777
|
+
function determineOptimumRisk(config2, payload, params) {
|
|
60778
|
+
const { highest_risk, tolerance = 0.01, max_iterations = 200 } = params;
|
|
60779
|
+
let low_risk = 1;
|
|
60780
|
+
let high_risk = Math.max(highest_risk * 5, payload.risk * 10);
|
|
60781
|
+
let best_risk = payload.risk;
|
|
60782
|
+
let best_neg_pnl = 0;
|
|
60783
|
+
let best_diff = Infinity;
|
|
60784
|
+
console.log(`Finding optimal risk for target neg_pnl: ${highest_risk}`);
|
|
60785
|
+
let iterations = 0;
|
|
60786
|
+
while (iterations < max_iterations && high_risk - low_risk > tolerance) {
|
|
60787
|
+
iterations++;
|
|
60788
|
+
const mid_risk = (low_risk + high_risk) / 2;
|
|
60789
|
+
const test_payload = {
|
|
60790
|
+
...payload,
|
|
60791
|
+
risk: mid_risk
|
|
60792
|
+
};
|
|
60793
|
+
const { last_value } = buildAppConfig(config2, test_payload);
|
|
60794
|
+
if (!last_value || !last_value.neg_pnl) {
|
|
60795
|
+
high_risk = mid_risk;
|
|
60796
|
+
continue;
|
|
60797
|
+
}
|
|
60798
|
+
const current_neg_pnl = Math.abs(last_value.neg_pnl);
|
|
60799
|
+
const diff = Math.abs(current_neg_pnl - highest_risk);
|
|
60800
|
+
console.log(`Iteration ${iterations}: Risk=${mid_risk.toFixed(2)}, neg_pnl=${current_neg_pnl.toFixed(2)}, diff=${diff.toFixed(2)}`);
|
|
60801
|
+
if (diff < best_diff) {
|
|
60802
|
+
best_diff = diff;
|
|
60803
|
+
best_risk = mid_risk;
|
|
60804
|
+
best_neg_pnl = current_neg_pnl;
|
|
60805
|
+
}
|
|
60806
|
+
if (diff <= tolerance) {
|
|
60807
|
+
console.log(`Converged! Optimal risk: ${mid_risk.toFixed(2)}`);
|
|
60808
|
+
break;
|
|
60809
|
+
}
|
|
60810
|
+
if (current_neg_pnl < highest_risk) {
|
|
60811
|
+
low_risk = mid_risk;
|
|
60812
|
+
} else {
|
|
60813
|
+
high_risk = mid_risk;
|
|
60814
|
+
}
|
|
60815
|
+
}
|
|
60816
|
+
const final_payload = {
|
|
60817
|
+
...payload,
|
|
60818
|
+
risk: best_risk
|
|
60819
|
+
};
|
|
60820
|
+
const final_result = buildAppConfig(config2, final_payload);
|
|
60821
|
+
return {
|
|
60822
|
+
optimal_risk: to_f2(best_risk, "%.2f"),
|
|
60823
|
+
achieved_neg_pnl: to_f2(best_neg_pnl, "%.2f"),
|
|
60824
|
+
target_neg_pnl: to_f2(highest_risk, "%.2f"),
|
|
60825
|
+
difference: to_f2(best_diff, "%.2f"),
|
|
60826
|
+
iterations,
|
|
60827
|
+
converged: best_diff <= tolerance,
|
|
60828
|
+
last_value: final_result.last_value,
|
|
60829
|
+
entries: final_result.entries,
|
|
60830
|
+
app_config: final_result
|
|
60831
|
+
};
|
|
60832
|
+
}
|
|
60777
60833
|
function computeRiskReward(payload) {
|
|
60778
60834
|
const { app_config, entry, stop, risk_per_trade } = payload;
|
|
60779
60835
|
const kind = entry > stop ? "long" : "short";
|
|
@@ -60785,7 +60841,13 @@ function computeRiskReward(payload) {
|
|
|
60785
60841
|
return result;
|
|
60786
60842
|
}
|
|
60787
60843
|
function getRiskReward(payload) {
|
|
60788
|
-
const {
|
|
60844
|
+
const {
|
|
60845
|
+
entry,
|
|
60846
|
+
stop,
|
|
60847
|
+
risk,
|
|
60848
|
+
global_config,
|
|
60849
|
+
force_exact_risk = false
|
|
60850
|
+
} = payload;
|
|
60789
60851
|
const { entries, last_value, ...app_config } = buildAppConfig(global_config, {
|
|
60790
60852
|
entry,
|
|
60791
60853
|
stop,
|
|
@@ -60799,6 +60861,18 @@ function getRiskReward(payload) {
|
|
|
60799
60861
|
stop,
|
|
60800
60862
|
risk_per_trade: risk
|
|
60801
60863
|
});
|
|
60864
|
+
if (force_exact_risk) {
|
|
60865
|
+
const new_risk_per_trade = determineOptimumRisk(global_config, {
|
|
60866
|
+
entry,
|
|
60867
|
+
stop,
|
|
60868
|
+
risk_reward,
|
|
60869
|
+
risk,
|
|
60870
|
+
symbol: global_config.symbol
|
|
60871
|
+
}, {
|
|
60872
|
+
highest_risk: risk
|
|
60873
|
+
}).optimal_risk;
|
|
60874
|
+
return { risk: new_risk_per_trade, risk_reward };
|
|
60875
|
+
}
|
|
60802
60876
|
return risk_reward;
|
|
60803
60877
|
}
|
|
60804
60878
|
function computeProfitDetail(payload) {
|
package/dist/mcp-server.js
CHANGED
|
@@ -60751,6 +60751,62 @@ function findIndexByCondition(lst, kind, condition, defaultKey = "neg_pnl") {
|
|
|
60751
60751
|
}, found[0]);
|
|
60752
60752
|
return maximum;
|
|
60753
60753
|
}
|
|
60754
|
+
function determineOptimumRisk(config2, payload, params) {
|
|
60755
|
+
const { highest_risk, tolerance = 0.01, max_iterations = 200 } = params;
|
|
60756
|
+
let low_risk = 1;
|
|
60757
|
+
let high_risk = Math.max(highest_risk * 5, payload.risk * 10);
|
|
60758
|
+
let best_risk = payload.risk;
|
|
60759
|
+
let best_neg_pnl = 0;
|
|
60760
|
+
let best_diff = Infinity;
|
|
60761
|
+
console.log(`Finding optimal risk for target neg_pnl: ${highest_risk}`);
|
|
60762
|
+
let iterations = 0;
|
|
60763
|
+
while (iterations < max_iterations && high_risk - low_risk > tolerance) {
|
|
60764
|
+
iterations++;
|
|
60765
|
+
const mid_risk = (low_risk + high_risk) / 2;
|
|
60766
|
+
const test_payload = {
|
|
60767
|
+
...payload,
|
|
60768
|
+
risk: mid_risk
|
|
60769
|
+
};
|
|
60770
|
+
const { last_value } = buildAppConfig(config2, test_payload);
|
|
60771
|
+
if (!last_value || !last_value.neg_pnl) {
|
|
60772
|
+
high_risk = mid_risk;
|
|
60773
|
+
continue;
|
|
60774
|
+
}
|
|
60775
|
+
const current_neg_pnl = Math.abs(last_value.neg_pnl);
|
|
60776
|
+
const diff = Math.abs(current_neg_pnl - highest_risk);
|
|
60777
|
+
console.log(`Iteration ${iterations}: Risk=${mid_risk.toFixed(2)}, neg_pnl=${current_neg_pnl.toFixed(2)}, diff=${diff.toFixed(2)}`);
|
|
60778
|
+
if (diff < best_diff) {
|
|
60779
|
+
best_diff = diff;
|
|
60780
|
+
best_risk = mid_risk;
|
|
60781
|
+
best_neg_pnl = current_neg_pnl;
|
|
60782
|
+
}
|
|
60783
|
+
if (diff <= tolerance) {
|
|
60784
|
+
console.log(`Converged! Optimal risk: ${mid_risk.toFixed(2)}`);
|
|
60785
|
+
break;
|
|
60786
|
+
}
|
|
60787
|
+
if (current_neg_pnl < highest_risk) {
|
|
60788
|
+
low_risk = mid_risk;
|
|
60789
|
+
} else {
|
|
60790
|
+
high_risk = mid_risk;
|
|
60791
|
+
}
|
|
60792
|
+
}
|
|
60793
|
+
const final_payload = {
|
|
60794
|
+
...payload,
|
|
60795
|
+
risk: best_risk
|
|
60796
|
+
};
|
|
60797
|
+
const final_result = buildAppConfig(config2, final_payload);
|
|
60798
|
+
return {
|
|
60799
|
+
optimal_risk: to_f2(best_risk, "%.2f"),
|
|
60800
|
+
achieved_neg_pnl: to_f2(best_neg_pnl, "%.2f"),
|
|
60801
|
+
target_neg_pnl: to_f2(highest_risk, "%.2f"),
|
|
60802
|
+
difference: to_f2(best_diff, "%.2f"),
|
|
60803
|
+
iterations,
|
|
60804
|
+
converged: best_diff <= tolerance,
|
|
60805
|
+
last_value: final_result.last_value,
|
|
60806
|
+
entries: final_result.entries,
|
|
60807
|
+
app_config: final_result
|
|
60808
|
+
};
|
|
60809
|
+
}
|
|
60754
60810
|
function computeRiskReward(payload) {
|
|
60755
60811
|
const { app_config, entry, stop, risk_per_trade } = payload;
|
|
60756
60812
|
const kind = entry > stop ? "long" : "short";
|
|
@@ -60762,7 +60818,13 @@ function computeRiskReward(payload) {
|
|
|
60762
60818
|
return result;
|
|
60763
60819
|
}
|
|
60764
60820
|
function getRiskReward(payload) {
|
|
60765
|
-
const {
|
|
60821
|
+
const {
|
|
60822
|
+
entry,
|
|
60823
|
+
stop,
|
|
60824
|
+
risk,
|
|
60825
|
+
global_config,
|
|
60826
|
+
force_exact_risk = false
|
|
60827
|
+
} = payload;
|
|
60766
60828
|
const { entries, last_value, ...app_config } = buildAppConfig(global_config, {
|
|
60767
60829
|
entry,
|
|
60768
60830
|
stop,
|
|
@@ -60776,6 +60838,18 @@ function getRiskReward(payload) {
|
|
|
60776
60838
|
stop,
|
|
60777
60839
|
risk_per_trade: risk
|
|
60778
60840
|
});
|
|
60841
|
+
if (force_exact_risk) {
|
|
60842
|
+
const new_risk_per_trade = determineOptimumRisk(global_config, {
|
|
60843
|
+
entry,
|
|
60844
|
+
stop,
|
|
60845
|
+
risk_reward,
|
|
60846
|
+
risk,
|
|
60847
|
+
symbol: global_config.symbol
|
|
60848
|
+
}, {
|
|
60849
|
+
highest_risk: risk
|
|
60850
|
+
}).optimal_risk;
|
|
60851
|
+
return { risk: new_risk_per_trade, risk_reward };
|
|
60852
|
+
}
|
|
60779
60853
|
return risk_reward;
|
|
60780
60854
|
}
|
|
60781
60855
|
function computeProfitDetail(payload) {
|