@gbozee/ultimate 0.0.2-next.5 → 0.0.2-next.50
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 +32 -3
- package/dist/frontend-index.js +134 -19
- package/dist/index.cjs +17450 -4624
- package/dist/index.d.ts +4426 -31
- package/dist/index.js +17747 -4921
- package/dist/mcp-server.cjs +2253 -118
- package/dist/mcp-server.js +2227 -92
- package/package.json +16 -11
- package/dist/frontend/frontend-index.js +0 -1318
- package/dist/mcp.d.ts +0 -5
package/dist/frontend-index.d.ts
CHANGED
|
@@ -120,7 +120,7 @@ export declare function determineTPSl(payload: {
|
|
|
120
120
|
};
|
|
121
121
|
export interface GetEntriesParams {
|
|
122
122
|
kind: "long" | "short";
|
|
123
|
-
distribution: "arithmetic" | "geometric" | "normal" | "exponential" | "inverse-exponential";
|
|
123
|
+
distribution: "arithmetic" | "geometric" | "normal" | "exponential" | "lognormal" | "inverse-exponential";
|
|
124
124
|
margin_range: [
|
|
125
125
|
number,
|
|
126
126
|
number
|
|
@@ -133,6 +133,7 @@ export interface GetEntriesParams {
|
|
|
133
133
|
lambda?: number;
|
|
134
134
|
};
|
|
135
135
|
}
|
|
136
|
+
export declare function determine_pnl(entry: number, close_price: number, quantity: number, kind?: string, contract_size?: number): number;
|
|
136
137
|
export type SignalConfigType = {
|
|
137
138
|
symbol?: string;
|
|
138
139
|
focus: number;
|
|
@@ -181,7 +182,7 @@ export type SignalConfigType = {
|
|
|
181
182
|
}>;
|
|
182
183
|
};
|
|
183
184
|
};
|
|
184
|
-
declare class Signal {
|
|
185
|
+
export declare class Signal {
|
|
185
186
|
focus: number;
|
|
186
187
|
budget: number;
|
|
187
188
|
percent_change: number;
|
|
@@ -1135,6 +1136,33 @@ export declare function generateDangerousConfig(payload: {
|
|
|
1135
1136
|
entry: any;
|
|
1136
1137
|
};
|
|
1137
1138
|
};
|
|
1139
|
+
export declare function computeMarginProtection({ entry, quantity, tp, stop_loss, avg_price, avg_qty, next_order, base_asset, symbol, }: {
|
|
1140
|
+
symbol: string;
|
|
1141
|
+
base_asset: number;
|
|
1142
|
+
next_order: number;
|
|
1143
|
+
entry: number;
|
|
1144
|
+
quantity: number;
|
|
1145
|
+
tp: {
|
|
1146
|
+
price: number;
|
|
1147
|
+
};
|
|
1148
|
+
stop_loss: {
|
|
1149
|
+
price: number;
|
|
1150
|
+
};
|
|
1151
|
+
avg_price: number;
|
|
1152
|
+
avg_qty: number;
|
|
1153
|
+
}): {
|
|
1154
|
+
existing_quantity: number;
|
|
1155
|
+
quantity_to_place: number;
|
|
1156
|
+
quantity: number;
|
|
1157
|
+
price: number;
|
|
1158
|
+
tp: number;
|
|
1159
|
+
risk: number;
|
|
1160
|
+
protect_quantity: number;
|
|
1161
|
+
ideal_protect_quantity: number;
|
|
1162
|
+
hedge: number;
|
|
1163
|
+
price_place: string;
|
|
1164
|
+
decimal_place: string;
|
|
1165
|
+
};
|
|
1138
1166
|
export type StrategyPosition = {
|
|
1139
1167
|
entry: number;
|
|
1140
1168
|
quantity: number;
|
|
@@ -1494,7 +1522,8 @@ declare function constructAppConfig$1({ config, global_config, }: {
|
|
|
1494
1522
|
lambda?: number;
|
|
1495
1523
|
};
|
|
1496
1524
|
};
|
|
1497
|
-
declare function buildWithOptimumReward({ config, settings, global_config, force_exact, }: {
|
|
1525
|
+
declare function buildWithOptimumReward({ config, settings, global_config, force_exact, use_default, }: {
|
|
1526
|
+
use_default?: boolean;
|
|
1498
1527
|
config: TradeConfig;
|
|
1499
1528
|
global_config: GlobalConfig;
|
|
1500
1529
|
settings: {
|
package/dist/frontend-index.js
CHANGED
|
@@ -9,7 +9,13 @@ function generateArithmetic(payload) {
|
|
|
9
9
|
});
|
|
10
10
|
}
|
|
11
11
|
function generateGeometric(payload) {
|
|
12
|
-
const {
|
|
12
|
+
const {
|
|
13
|
+
margin_range,
|
|
14
|
+
risk_reward,
|
|
15
|
+
kind,
|
|
16
|
+
price_places = "%.1f",
|
|
17
|
+
percent_change
|
|
18
|
+
} = payload;
|
|
13
19
|
const effectivePercentChange = percent_change ?? Math.abs(margin_range[1] / margin_range[0] - 1) / risk_reward;
|
|
14
20
|
return Array.from({ length: risk_reward + 1 }, (_, i) => {
|
|
15
21
|
const price = kind === "long" ? margin_range[1] * Math.pow(1 - effectivePercentChange, i) : margin_range[0] * Math.pow(1 + effectivePercentChange, i);
|
|
@@ -31,7 +37,13 @@ function approximateInverseNormal(p) {
|
|
|
31
37
|
}
|
|
32
38
|
}
|
|
33
39
|
function generateNormal(payload) {
|
|
34
|
-
const {
|
|
40
|
+
const {
|
|
41
|
+
margin_range,
|
|
42
|
+
risk_reward,
|
|
43
|
+
kind,
|
|
44
|
+
price_places = "%.1f",
|
|
45
|
+
stdDevFactor = 6
|
|
46
|
+
} = payload;
|
|
35
47
|
const mean = (margin_range[0] + margin_range[1]) / 2;
|
|
36
48
|
const stdDev = Math.abs(margin_range[1] - margin_range[0]) / stdDevFactor;
|
|
37
49
|
const skew = kind === "long" ? -0.2 : 0.2;
|
|
@@ -46,7 +58,13 @@ function generateNormal(payload) {
|
|
|
46
58
|
return entries.sort((a, b) => a - b);
|
|
47
59
|
}
|
|
48
60
|
function generateExponential(payload) {
|
|
49
|
-
const {
|
|
61
|
+
const {
|
|
62
|
+
margin_range,
|
|
63
|
+
risk_reward,
|
|
64
|
+
kind,
|
|
65
|
+
price_places = "%.1f",
|
|
66
|
+
lambda
|
|
67
|
+
} = payload;
|
|
50
68
|
const range = Math.abs(margin_range[1] - margin_range[0]);
|
|
51
69
|
const effectiveLambda = lambda || 2.5;
|
|
52
70
|
return Array.from({ length: risk_reward + 1 }, (_, i) => {
|
|
@@ -57,7 +75,13 @@ function generateExponential(payload) {
|
|
|
57
75
|
});
|
|
58
76
|
}
|
|
59
77
|
function generateInverseExponential(payload) {
|
|
60
|
-
const {
|
|
78
|
+
const {
|
|
79
|
+
margin_range,
|
|
80
|
+
risk_reward,
|
|
81
|
+
kind,
|
|
82
|
+
price_places = "%.1f",
|
|
83
|
+
curveFactor = 2
|
|
84
|
+
} = payload;
|
|
61
85
|
const range = Math.abs(margin_range[1] - margin_range[0]);
|
|
62
86
|
return Array.from({ length: risk_reward + 1 }, (_, i) => {
|
|
63
87
|
const t = i / risk_reward;
|
|
@@ -91,8 +115,7 @@ function getEntries(params) {
|
|
|
91
115
|
margin_range,
|
|
92
116
|
risk_reward,
|
|
93
117
|
kind,
|
|
94
|
-
price_places
|
|
95
|
-
percent_change: distribution_params?.curveFactor
|
|
118
|
+
price_places
|
|
96
119
|
});
|
|
97
120
|
break;
|
|
98
121
|
case "normal":
|
|
@@ -122,12 +145,43 @@ function getEntries(params) {
|
|
|
122
145
|
curveFactor: distribution_params?.curveFactor
|
|
123
146
|
});
|
|
124
147
|
break;
|
|
148
|
+
case "lognormal":
|
|
149
|
+
entries = generateLognormal({
|
|
150
|
+
margin_range,
|
|
151
|
+
risk_reward,
|
|
152
|
+
kind,
|
|
153
|
+
price_places,
|
|
154
|
+
stdDevFactor: distribution_params?.stdDevFactor
|
|
155
|
+
});
|
|
156
|
+
break;
|
|
125
157
|
default:
|
|
126
158
|
throw new Error(`Unknown distribution type: ${distribution}`);
|
|
127
159
|
}
|
|
128
160
|
return entries.sort((a, b) => a - b);
|
|
129
161
|
}
|
|
130
162
|
var distributions_default = getEntries;
|
|
163
|
+
function generateLognormal(payload) {
|
|
164
|
+
const {
|
|
165
|
+
margin_range,
|
|
166
|
+
risk_reward,
|
|
167
|
+
kind,
|
|
168
|
+
price_places = "%.1f",
|
|
169
|
+
stdDevFactor = 6
|
|
170
|
+
} = payload;
|
|
171
|
+
const logMin = Math.log(margin_range[0]);
|
|
172
|
+
const logMax = Math.log(margin_range[1]);
|
|
173
|
+
const mean = (logMin + logMax) / 2;
|
|
174
|
+
const stdDev = Math.abs(logMax - logMin) / stdDevFactor;
|
|
175
|
+
const entries = Array.from({ length: risk_reward + 1 }, (_, i) => {
|
|
176
|
+
const p = (i + 0.5) / (risk_reward + 1);
|
|
177
|
+
const z = approximateInverseNormal(p);
|
|
178
|
+
let logPrice = mean + stdDev * z;
|
|
179
|
+
logPrice = Math.max(logMin, Math.min(logMax, logPrice));
|
|
180
|
+
const price = Math.exp(logPrice);
|
|
181
|
+
return to_f(kind === "long" ? Math.min(price, margin_range[1]) : Math.max(price, margin_range[0]), price_places);
|
|
182
|
+
});
|
|
183
|
+
return entries.sort((a, b) => a - b);
|
|
184
|
+
}
|
|
131
185
|
|
|
132
186
|
// src/helpers/optimizations.ts
|
|
133
187
|
function calculateTheoreticalKelly({
|
|
@@ -501,7 +555,7 @@ class Signal {
|
|
|
501
555
|
const simple_support = Math.min(current_price, stop_loss);
|
|
502
556
|
const simple_resistance = Math.max(current_price, stop_loss);
|
|
503
557
|
const risk_per_trade = risk / this.risk_reward;
|
|
504
|
-
const use_progressive = distribution_params
|
|
558
|
+
const use_progressive = distribution_params?.use_progressive || this.use_progressive_risk;
|
|
505
559
|
const risk_distribution = use_progressive ? {
|
|
506
560
|
enabled: true,
|
|
507
561
|
total_risk_budget: risk,
|
|
@@ -970,7 +1024,6 @@ class Signal {
|
|
|
970
1024
|
const defaultStopLoss = i === 0 ? stop_loss : _base;
|
|
971
1025
|
const new_stop = kind === "long" ? this.support : stop_loss;
|
|
972
1026
|
let risk_to_use = this.getZoneRisk(i, limit_orders.length, this);
|
|
973
|
-
console.log("index: ", i, " risk: ", risk_to_use);
|
|
974
1027
|
if (this.use_kelly) {
|
|
975
1028
|
const func = this.kelly_func === "theoretical" ? calculateTheoreticalKelly : this.kelly_func === "position_based" ? calculatePositionBasedKelly : calculateTheoreticalKellyFixed;
|
|
976
1029
|
const theoretical_kelly = func({
|
|
@@ -1297,6 +1350,9 @@ function formatPrice(value2, opts = {}) {
|
|
|
1297
1350
|
return formatter.format(value2);
|
|
1298
1351
|
}
|
|
1299
1352
|
function to_f(value2, places = "%.1f") {
|
|
1353
|
+
if (!value2) {
|
|
1354
|
+
return null;
|
|
1355
|
+
}
|
|
1300
1356
|
let v = typeof value2 === "string" ? parseFloat(value2) : value2;
|
|
1301
1357
|
const formattedValue = places.replace("%.", "").replace("f", "");
|
|
1302
1358
|
return parseFloat(v.toFixed(parseInt(formattedValue)));
|
|
@@ -1655,7 +1711,7 @@ function buildConfig(app_config, {
|
|
|
1655
1711
|
min_avg_size = 0,
|
|
1656
1712
|
distribution,
|
|
1657
1713
|
distribution_params,
|
|
1658
|
-
use_progressive_risk
|
|
1714
|
+
use_progressive_risk = false
|
|
1659
1715
|
}) {
|
|
1660
1716
|
let fee = app_config.fee / 100;
|
|
1661
1717
|
let working_risk = risk || app_config.risk_per_trade;
|
|
@@ -1697,7 +1753,7 @@ function buildConfig(app_config, {
|
|
|
1697
1753
|
if (!stop) {
|
|
1698
1754
|
return [];
|
|
1699
1755
|
}
|
|
1700
|
-
const condition =
|
|
1756
|
+
const condition = true;
|
|
1701
1757
|
if (kind === "short") {}
|
|
1702
1758
|
const result = entry === stop ? [] : condition ? instance.build_entry({
|
|
1703
1759
|
current_price: entry,
|
|
@@ -2180,7 +2236,7 @@ function determineOptimumReward(payload) {
|
|
|
2180
2236
|
const criterion = app_config.strategy || "quantity";
|
|
2181
2237
|
const risk_rewards = createArray(low_range, high_range, 1);
|
|
2182
2238
|
let func = risk_rewards.map((trade_no) => {
|
|
2183
|
-
|
|
2239
|
+
const pp = {
|
|
2184
2240
|
take_profit: app_config.take_profit,
|
|
2185
2241
|
entry: app_config.entry,
|
|
2186
2242
|
stop: app_config.stop,
|
|
@@ -2192,7 +2248,8 @@ function determineOptimumReward(payload) {
|
|
|
2192
2248
|
decimal_places: app_config.decimal_places,
|
|
2193
2249
|
distribution,
|
|
2194
2250
|
distribution_params: payload.distribution_params
|
|
2195
|
-
}
|
|
2251
|
+
};
|
|
2252
|
+
let trades = sortedBuildConfig(app_config, pp);
|
|
2196
2253
|
let total = 0;
|
|
2197
2254
|
let max = -Infinity;
|
|
2198
2255
|
let min = Infinity;
|
|
@@ -2283,7 +2340,6 @@ function findIndexByCondition(lst, kind, condition, defaultKey = "neg_pnl") {
|
|
|
2283
2340
|
return b.net_diff - a.net_diff;
|
|
2284
2341
|
}
|
|
2285
2342
|
});
|
|
2286
|
-
console.log("found", sortedFound);
|
|
2287
2343
|
if (defaultKey === "quantity") {
|
|
2288
2344
|
return sortedFound[0].index;
|
|
2289
2345
|
}
|
|
@@ -2914,6 +2970,55 @@ function generateDangerousConfig(payload) {
|
|
|
2914
2970
|
risk_reward: optimumRiskReward
|
|
2915
2971
|
};
|
|
2916
2972
|
}
|
|
2973
|
+
function computeMarginProtection({
|
|
2974
|
+
entry,
|
|
2975
|
+
quantity,
|
|
2976
|
+
tp,
|
|
2977
|
+
stop_loss,
|
|
2978
|
+
avg_price,
|
|
2979
|
+
avg_qty,
|
|
2980
|
+
next_order,
|
|
2981
|
+
base_asset,
|
|
2982
|
+
symbol
|
|
2983
|
+
}) {
|
|
2984
|
+
const pnl = Math.abs(tp.price - entry) * quantity;
|
|
2985
|
+
const loss = Math.abs(avg_price - stop_loss.price) * avg_qty;
|
|
2986
|
+
const margin_position = pnl / Math.abs(next_order - tp.price);
|
|
2987
|
+
const protect_position = loss / Math.abs(stop_loss.price - tp.price);
|
|
2988
|
+
const ideal_protect_position = loss / Math.abs(next_order - tp.price);
|
|
2989
|
+
const places = {
|
|
2990
|
+
BTCUSDT: "%.5f",
|
|
2991
|
+
ETHUSDT: "%.4f",
|
|
2992
|
+
BNBUSDT: "%.3f"
|
|
2993
|
+
};
|
|
2994
|
+
const price_places = {
|
|
2995
|
+
BTCUSDT: "%.2f",
|
|
2996
|
+
ETHUSDT: "%.2f",
|
|
2997
|
+
BNBUSDT: "%.2f"
|
|
2998
|
+
};
|
|
2999
|
+
let quantity_to_place = protect_position;
|
|
3000
|
+
if (base_asset > 0) {
|
|
3001
|
+
let diff = quantity_to_place - base_asset;
|
|
3002
|
+
if (diff < 0) {
|
|
3003
|
+
return;
|
|
3004
|
+
}
|
|
3005
|
+
quantity_to_place = diff;
|
|
3006
|
+
}
|
|
3007
|
+
const payload = {
|
|
3008
|
+
existing_quantity: base_asset,
|
|
3009
|
+
quantity_to_place: to_f(quantity_to_place, places[symbol]),
|
|
3010
|
+
quantity: to_f(margin_position, places[symbol]),
|
|
3011
|
+
price: tp.price,
|
|
3012
|
+
tp: next_order,
|
|
3013
|
+
risk: to_f(pnl, "%.1f"),
|
|
3014
|
+
protect_quantity: to_f(protect_position, places[symbol]),
|
|
3015
|
+
ideal_protect_quantity: to_f(ideal_protect_position, places[symbol]),
|
|
3016
|
+
hedge: to_f(loss, "%.1f"),
|
|
3017
|
+
price_place: price_places[symbol],
|
|
3018
|
+
decimal_place: places[symbol]
|
|
3019
|
+
};
|
|
3020
|
+
return payload;
|
|
3021
|
+
}
|
|
2917
3022
|
// src/helpers/strategy.ts
|
|
2918
3023
|
class Strategy {
|
|
2919
3024
|
position;
|
|
@@ -3488,10 +3593,14 @@ function helperFuncToBuildTrades({
|
|
|
3488
3593
|
symbol_config,
|
|
3489
3594
|
app_config_kind,
|
|
3490
3595
|
appConfig,
|
|
3491
|
-
force_exact_risk = true
|
|
3596
|
+
force_exact_risk = true,
|
|
3597
|
+
use_default = false
|
|
3492
3598
|
}) {
|
|
3493
3599
|
const risk = custom_b_config.risk * (custom_b_config.risk_factor || 1);
|
|
3494
|
-
let result =
|
|
3600
|
+
let result = use_default ? {
|
|
3601
|
+
risk,
|
|
3602
|
+
risk_reward: custom_b_config.risk_reward
|
|
3603
|
+
} : getRiskReward({
|
|
3495
3604
|
entry: custom_b_config.entry,
|
|
3496
3605
|
stop: custom_b_config.stop,
|
|
3497
3606
|
risk,
|
|
@@ -3540,7 +3649,8 @@ function buildWithOptimumReward({
|
|
|
3540
3649
|
config,
|
|
3541
3650
|
settings,
|
|
3542
3651
|
global_config,
|
|
3543
|
-
force_exact
|
|
3652
|
+
force_exact,
|
|
3653
|
+
use_default = false
|
|
3544
3654
|
}) {
|
|
3545
3655
|
const kind = config.entry > config.stop ? "long" : "short";
|
|
3546
3656
|
let stop = settings.stop;
|
|
@@ -3554,7 +3664,8 @@ function buildWithOptimumReward({
|
|
|
3554
3664
|
stop,
|
|
3555
3665
|
risk,
|
|
3556
3666
|
distribution,
|
|
3557
|
-
distribution_params
|
|
3667
|
+
distribution_params,
|
|
3668
|
+
risk_reward: settings.risk_reward || config?.risk_reward
|
|
3558
3669
|
};
|
|
3559
3670
|
const appConfig = constructAppConfig2({
|
|
3560
3671
|
config,
|
|
@@ -3565,7 +3676,8 @@ function buildWithOptimumReward({
|
|
|
3565
3676
|
app_config_kind: kind,
|
|
3566
3677
|
appConfig,
|
|
3567
3678
|
symbol_config: global_config,
|
|
3568
|
-
force_exact_risk: force_exact
|
|
3679
|
+
force_exact_risk: force_exact,
|
|
3680
|
+
use_default
|
|
3569
3681
|
});
|
|
3570
3682
|
const adjusted_size = summary.quantity;
|
|
3571
3683
|
const symbol_config = global_config;
|
|
@@ -3905,6 +4017,7 @@ export {
|
|
|
3905
4017
|
determine_stop_and_size,
|
|
3906
4018
|
determine_remaining_entry,
|
|
3907
4019
|
determine_position_size,
|
|
4020
|
+
determine_pnl,
|
|
3908
4021
|
determine_break_even_price,
|
|
3909
4022
|
determine_average_entry_and_size,
|
|
3910
4023
|
determine_amount_to_sell2 as determine_amount_to_sell,
|
|
@@ -3921,6 +4034,7 @@ export {
|
|
|
3921
4034
|
computeSellZones,
|
|
3922
4035
|
computeRiskReward,
|
|
3923
4036
|
computeProfitDetail,
|
|
4037
|
+
computeMarginProtection,
|
|
3924
4038
|
compoundAPI,
|
|
3925
4039
|
calculateFactorFromTakeProfit,
|
|
3926
4040
|
calculateFactorFromSellQuantity,
|
|
@@ -3930,5 +4044,6 @@ export {
|
|
|
3930
4044
|
asCoins,
|
|
3931
4045
|
allCoins,
|
|
3932
4046
|
Strategy,
|
|
3933
|
-
SpecialCoins
|
|
4047
|
+
SpecialCoins,
|
|
4048
|
+
Signal
|
|
3934
4049
|
};
|