@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.
@@ -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: {
@@ -9,7 +9,13 @@ function generateArithmetic(payload) {
9
9
  });
10
10
  }
11
11
  function generateGeometric(payload) {
12
- const { margin_range, risk_reward, kind, price_places = "%.1f", percent_change } = payload;
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 { margin_range, risk_reward, kind, price_places = "%.1f", stdDevFactor = 6 } = payload;
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 { margin_range, risk_reward, kind, price_places = "%.1f", lambda } = payload;
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 { margin_range, risk_reward, kind, price_places = "%.1f", curveFactor = 2 } = payload;
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.use_progressive || this.use_progressive_risk;
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 = (kind === "long" ? entry > app_config.support : entry >= app_config.support) && stop >= app_config.support * 0.999;
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
- let trades = sortedBuildConfig(app_config, {
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 = getRiskReward({
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
  };