@gbozee/ultimate 0.0.2-174 → 0.0.2-177
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 +134 -4
- package/dist/frontend-index.js +305 -25
- package/dist/index.cjs +397 -32
- package/dist/index.d.ts +206 -5
- package/dist/index.js +397 -32
- package/dist/mcp-server.cjs +303 -32
- package/dist/mcp-server.js +303 -32
- package/package.json +1 -1
package/dist/mcp-server.js
CHANGED
|
@@ -61374,7 +61374,7 @@ class AppDatabase {
|
|
|
61374
61374
|
table: "positions_view",
|
|
61375
61375
|
params: {
|
|
61376
61376
|
filter: `symbol:lower="${symbol.toLowerCase()}" && p_account.owner:lower="${account.owner.toLowerCase()}" && p_account.exchange:lower="${account.exchange.toLowerCase()}"`,
|
|
61377
|
-
expand: "b_config, account_strategy, p_account, proxy"
|
|
61377
|
+
expand: "b_config, account_strategy, p_account, proxy, compound_instance.ref,support"
|
|
61378
61378
|
}
|
|
61379
61379
|
} : {
|
|
61380
61380
|
table: "positions",
|
|
@@ -62184,11 +62184,169 @@ class AppDatabase {
|
|
|
62184
62184
|
parent: config_id
|
|
62185
62185
|
});
|
|
62186
62186
|
}
|
|
62187
|
+
async getCompoundInstance(payload) {
|
|
62188
|
+
const { position } = payload;
|
|
62189
|
+
const found = await this.pb.collection("compound_instances").getFullList({
|
|
62190
|
+
filter: `position.id = "${position.id}"`,
|
|
62191
|
+
expand: `ref`
|
|
62192
|
+
});
|
|
62193
|
+
if (found.length == 0) {
|
|
62194
|
+
return;
|
|
62195
|
+
}
|
|
62196
|
+
const item = found[0];
|
|
62197
|
+
return item;
|
|
62198
|
+
}
|
|
62199
|
+
async getSupportTable(payload) {
|
|
62200
|
+
const { symbol, kind } = payload;
|
|
62201
|
+
const found = await this.pb.collection("support_table").getFullList({
|
|
62202
|
+
filter: `symbol = "${symbol}" && kind = "${kind}"`
|
|
62203
|
+
});
|
|
62204
|
+
if (found.length === 0) {
|
|
62205
|
+
return;
|
|
62206
|
+
}
|
|
62207
|
+
const item = found[0];
|
|
62208
|
+
return item;
|
|
62209
|
+
}
|
|
62210
|
+
async updateCompoundInstance(payload) {
|
|
62211
|
+
const { id, params } = payload;
|
|
62212
|
+
return await this.pb.collection("compound_instances").update(id, params);
|
|
62213
|
+
}
|
|
62187
62214
|
}
|
|
62188
62215
|
|
|
62189
62216
|
// src/exchanges/binance/index.ts
|
|
62190
62217
|
var import_binance = __toESM(require_lib2(), 1);
|
|
62191
62218
|
|
|
62219
|
+
// src/helpers/distributions.ts
|
|
62220
|
+
function generateArithmetic(payload) {
|
|
62221
|
+
const { margin_range, risk_reward, kind, price_places = "%.1f" } = payload;
|
|
62222
|
+
const difference = Math.abs(margin_range[1] - margin_range[0]);
|
|
62223
|
+
const spread = difference / risk_reward;
|
|
62224
|
+
return Array.from({ length: risk_reward + 1 }, (_, i2) => {
|
|
62225
|
+
const price = kind === "long" ? margin_range[1] - spread * i2 : margin_range[0] + spread * i2;
|
|
62226
|
+
return to_f(price, price_places);
|
|
62227
|
+
});
|
|
62228
|
+
}
|
|
62229
|
+
function generateGeometric(payload) {
|
|
62230
|
+
const { margin_range, risk_reward, kind, price_places = "%.1f", percent_change } = payload;
|
|
62231
|
+
const effectivePercentChange = percent_change ?? Math.abs(margin_range[1] / margin_range[0] - 1) / risk_reward;
|
|
62232
|
+
return Array.from({ length: risk_reward + 1 }, (_, i2) => {
|
|
62233
|
+
const price = kind === "long" ? margin_range[1] * Math.pow(1 - effectivePercentChange, i2) : margin_range[0] * Math.pow(1 + effectivePercentChange, i2);
|
|
62234
|
+
return to_f(price, price_places);
|
|
62235
|
+
});
|
|
62236
|
+
}
|
|
62237
|
+
function approximateInverseNormal(p) {
|
|
62238
|
+
p = Math.max(0.0001, Math.min(0.9999, p));
|
|
62239
|
+
if (p < 0.5) {
|
|
62240
|
+
const t2 = Math.sqrt(-2 * Math.log(p));
|
|
62241
|
+
const c0 = 2.515517, c1 = 0.802853, c2 = 0.010328;
|
|
62242
|
+
const d1 = 1.432788, d2 = 0.189269, d3 = 0.001308;
|
|
62243
|
+
return -(t2 - (c0 + c1 * t2 + c2 * t2 * t2) / (1 + d1 * t2 + d2 * t2 * t2 + d3 * t2 * t2 * t2));
|
|
62244
|
+
} else {
|
|
62245
|
+
const t2 = Math.sqrt(-2 * Math.log(1 - p));
|
|
62246
|
+
const c0 = 2.515517, c1 = 0.802853, c2 = 0.010328;
|
|
62247
|
+
const d1 = 1.432788, d2 = 0.189269, d3 = 0.001308;
|
|
62248
|
+
return t2 - (c0 + c1 * t2 + c2 * t2 * t2) / (1 + d1 * t2 + d2 * t2 * t2 + d3 * t2 * t2 * t2);
|
|
62249
|
+
}
|
|
62250
|
+
}
|
|
62251
|
+
function generateNormal(payload) {
|
|
62252
|
+
const { margin_range, risk_reward, kind, price_places = "%.1f", stdDevFactor = 6 } = payload;
|
|
62253
|
+
const mean = (margin_range[0] + margin_range[1]) / 2;
|
|
62254
|
+
const stdDev = Math.abs(margin_range[1] - margin_range[0]) / stdDevFactor;
|
|
62255
|
+
const skew = kind === "long" ? -0.2 : 0.2;
|
|
62256
|
+
const adjustedMean = mean + stdDev * skew;
|
|
62257
|
+
const entries = Array.from({ length: risk_reward + 1 }, (_, i2) => {
|
|
62258
|
+
const p = (i2 + 0.5) / (risk_reward + 1);
|
|
62259
|
+
const z3 = approximateInverseNormal(p);
|
|
62260
|
+
let price = adjustedMean + stdDev * z3;
|
|
62261
|
+
price = Math.max(margin_range[0], Math.min(margin_range[1], price));
|
|
62262
|
+
return to_f(price, price_places);
|
|
62263
|
+
});
|
|
62264
|
+
return entries.sort((a, b) => a - b);
|
|
62265
|
+
}
|
|
62266
|
+
function generateExponential(payload) {
|
|
62267
|
+
const { margin_range, risk_reward, kind, price_places = "%.1f", lambda } = payload;
|
|
62268
|
+
const range = Math.abs(margin_range[1] - margin_range[0]);
|
|
62269
|
+
const effectiveLambda = lambda || 2.5;
|
|
62270
|
+
return Array.from({ length: risk_reward + 1 }, (_, i2) => {
|
|
62271
|
+
const t2 = i2 / risk_reward;
|
|
62272
|
+
const exponentialProgress = 1 - Math.exp(-effectiveLambda * t2);
|
|
62273
|
+
const price = kind === "long" ? margin_range[1] - range * exponentialProgress : margin_range[0] + range * exponentialProgress;
|
|
62274
|
+
return to_f(price, price_places);
|
|
62275
|
+
});
|
|
62276
|
+
}
|
|
62277
|
+
function generateInverseExponential(payload) {
|
|
62278
|
+
const { margin_range, risk_reward, kind, price_places = "%.1f", curveFactor = 2 } = payload;
|
|
62279
|
+
const range = Math.abs(margin_range[1] - margin_range[0]);
|
|
62280
|
+
return Array.from({ length: risk_reward + 1 }, (_, i2) => {
|
|
62281
|
+
const t2 = i2 / risk_reward;
|
|
62282
|
+
const progress = (Math.exp(curveFactor * t2) - 1) / (Math.exp(curveFactor) - 1);
|
|
62283
|
+
const price = kind === "long" ? margin_range[1] - range * progress : margin_range[0] + range * progress;
|
|
62284
|
+
return to_f(price, price_places);
|
|
62285
|
+
});
|
|
62286
|
+
}
|
|
62287
|
+
function getEntries(params) {
|
|
62288
|
+
const {
|
|
62289
|
+
kind,
|
|
62290
|
+
distribution,
|
|
62291
|
+
margin_range,
|
|
62292
|
+
risk_reward,
|
|
62293
|
+
price_places = "%.1f",
|
|
62294
|
+
distribution_params = {}
|
|
62295
|
+
} = params;
|
|
62296
|
+
let entries = [];
|
|
62297
|
+
switch (distribution) {
|
|
62298
|
+
case "arithmetic":
|
|
62299
|
+
entries = generateArithmetic({
|
|
62300
|
+
margin_range,
|
|
62301
|
+
risk_reward,
|
|
62302
|
+
kind,
|
|
62303
|
+
price_places,
|
|
62304
|
+
percent_change: distribution_params.curveFactor
|
|
62305
|
+
});
|
|
62306
|
+
break;
|
|
62307
|
+
case "geometric":
|
|
62308
|
+
entries = generateGeometric({
|
|
62309
|
+
margin_range,
|
|
62310
|
+
risk_reward,
|
|
62311
|
+
kind,
|
|
62312
|
+
price_places,
|
|
62313
|
+
percent_change: distribution_params.curveFactor
|
|
62314
|
+
});
|
|
62315
|
+
break;
|
|
62316
|
+
case "normal":
|
|
62317
|
+
entries = generateNormal({
|
|
62318
|
+
margin_range,
|
|
62319
|
+
risk_reward,
|
|
62320
|
+
kind,
|
|
62321
|
+
price_places,
|
|
62322
|
+
stdDevFactor: distribution_params.stdDevFactor
|
|
62323
|
+
});
|
|
62324
|
+
break;
|
|
62325
|
+
case "exponential":
|
|
62326
|
+
entries = generateExponential({
|
|
62327
|
+
margin_range,
|
|
62328
|
+
risk_reward,
|
|
62329
|
+
kind,
|
|
62330
|
+
price_places,
|
|
62331
|
+
lambda: distribution_params.lambda
|
|
62332
|
+
});
|
|
62333
|
+
break;
|
|
62334
|
+
case "inverse-exponential":
|
|
62335
|
+
entries = generateInverseExponential({
|
|
62336
|
+
margin_range,
|
|
62337
|
+
risk_reward,
|
|
62338
|
+
kind,
|
|
62339
|
+
price_places,
|
|
62340
|
+
curveFactor: distribution_params.curveFactor
|
|
62341
|
+
});
|
|
62342
|
+
break;
|
|
62343
|
+
default:
|
|
62344
|
+
throw new Error(`Unknown distribution type: ${distribution}`);
|
|
62345
|
+
}
|
|
62346
|
+
return entries.sort((a, b) => a - b);
|
|
62347
|
+
}
|
|
62348
|
+
var distributions_default = getEntries;
|
|
62349
|
+
|
|
62192
62350
|
// src/helpers/optimizations.ts
|
|
62193
62351
|
function calculateTheoreticalKelly({
|
|
62194
62352
|
current_entry,
|
|
@@ -62458,6 +62616,10 @@ class Signal {
|
|
|
62458
62616
|
kelly_minimum_risk = 0.2;
|
|
62459
62617
|
kelly_func = "theoretical";
|
|
62460
62618
|
symbol;
|
|
62619
|
+
distribution = {
|
|
62620
|
+
long: "arithmetic",
|
|
62621
|
+
short: "geometric"
|
|
62622
|
+
};
|
|
62461
62623
|
constructor({
|
|
62462
62624
|
focus,
|
|
62463
62625
|
symbol,
|
|
@@ -62484,8 +62646,12 @@ class Signal {
|
|
|
62484
62646
|
kelly_prediction_model = "exponential",
|
|
62485
62647
|
kelly_confidence_factor = 0.6,
|
|
62486
62648
|
kelly_minimum_risk = 0.2,
|
|
62487
|
-
kelly_func = "theoretical"
|
|
62649
|
+
kelly_func = "theoretical",
|
|
62650
|
+
full_distribution
|
|
62488
62651
|
}) {
|
|
62652
|
+
if (full_distribution) {
|
|
62653
|
+
this.distribution = full_distribution;
|
|
62654
|
+
}
|
|
62489
62655
|
this.symbol = symbol;
|
|
62490
62656
|
this.minimum_size = minimum_size;
|
|
62491
62657
|
this.first_order_size = first_order_size;
|
|
@@ -62521,7 +62687,8 @@ class Signal {
|
|
|
62521
62687
|
kind = "long",
|
|
62522
62688
|
risk,
|
|
62523
62689
|
no_of_trades = 1,
|
|
62524
|
-
take_profit
|
|
62690
|
+
take_profit,
|
|
62691
|
+
distribution
|
|
62525
62692
|
}) {
|
|
62526
62693
|
let _stop_loss = stop_loss;
|
|
62527
62694
|
if (!_stop_loss && stop_percent) {
|
|
@@ -62530,16 +62697,22 @@ class Signal {
|
|
|
62530
62697
|
const percent_change = _stop_loss ? Math.max(current_price, _stop_loss) / Math.min(current_price, _stop_loss) - 1 : this.percent_change;
|
|
62531
62698
|
const _no_of_trades = no_of_trades || this.risk_reward;
|
|
62532
62699
|
let _resistance = current_price * Math.pow(1 + percent_change, 1);
|
|
62700
|
+
const simple_support = Math.min(current_price, stop_loss);
|
|
62701
|
+
const simple_resistance = Math.max(current_price, stop_loss);
|
|
62533
62702
|
const derivedConfig = {
|
|
62534
62703
|
...this,
|
|
62535
62704
|
percent_change,
|
|
62536
62705
|
focus: current_price,
|
|
62537
|
-
resistance: _resistance,
|
|
62706
|
+
resistance: distribution ? simple_resistance : _resistance,
|
|
62538
62707
|
risk_per_trade: risk / this.risk_reward,
|
|
62539
62708
|
minimum_pnl: pnl,
|
|
62540
62709
|
risk_reward: _no_of_trades,
|
|
62541
62710
|
take_profit: take_profit || this.take_profit,
|
|
62542
|
-
support: kind === "long" ? _stop_loss : this.support
|
|
62711
|
+
support: distribution ? simple_support : kind === "long" ? _stop_loss : this.support,
|
|
62712
|
+
full_distribution: distribution ? {
|
|
62713
|
+
...this.distribution,
|
|
62714
|
+
[kind]: distribution
|
|
62715
|
+
} : undefined
|
|
62543
62716
|
};
|
|
62544
62717
|
const instance = new Signal(derivedConfig);
|
|
62545
62718
|
if (kind === "short") {}
|
|
@@ -62755,12 +62928,31 @@ class Signal {
|
|
|
62755
62928
|
}
|
|
62756
62929
|
this.zone_risk = original;
|
|
62757
62930
|
}
|
|
62931
|
+
get_future_zones_simple({
|
|
62932
|
+
current_price,
|
|
62933
|
+
kind = "long",
|
|
62934
|
+
raw
|
|
62935
|
+
}) {
|
|
62936
|
+
const margin_zones = [this.support, this.resistance];
|
|
62937
|
+
const distribution = this.distribution ? this.distribution[kind] : "geometric";
|
|
62938
|
+
console.log("margin_zones", { margin_zones, distribution });
|
|
62939
|
+
let _kind = distribution === "inverse-exponential" ? kind === "long" ? "short" : "long" : kind;
|
|
62940
|
+
const entries = distributions_default({
|
|
62941
|
+
margin_range: margin_zones,
|
|
62942
|
+
kind: _kind,
|
|
62943
|
+
distribution,
|
|
62944
|
+
risk_reward: this.risk_reward,
|
|
62945
|
+
price_places: this.price_places
|
|
62946
|
+
});
|
|
62947
|
+
return entries.sort((a, b) => a - b);
|
|
62948
|
+
}
|
|
62758
62949
|
get_future_zones({
|
|
62759
62950
|
current_price,
|
|
62760
62951
|
kind = "long",
|
|
62761
62952
|
raw
|
|
62762
62953
|
}) {
|
|
62763
62954
|
if (raw) {}
|
|
62955
|
+
return this.get_future_zones_simple({ current_price, raw, kind });
|
|
62764
62956
|
const margin_range = this.get_margin_range(current_price, kind);
|
|
62765
62957
|
let margin_zones = this.get_margin_zones({ current_price });
|
|
62766
62958
|
let remaining_zones = margin_zones.filter((x) => JSON.stringify(x) != JSON.stringify(margin_range));
|
|
@@ -63419,7 +63611,9 @@ function buildConfig(app_config, {
|
|
|
63419
63611
|
kelly_confidence_factor = 0.95,
|
|
63420
63612
|
kelly_minimum_risk = 0.2,
|
|
63421
63613
|
kelly_prediction_model = "exponential",
|
|
63422
|
-
kelly_func = "theoretical"
|
|
63614
|
+
kelly_func = "theoretical",
|
|
63615
|
+
min_avg_size = 0,
|
|
63616
|
+
distribution
|
|
63423
63617
|
}) {
|
|
63424
63618
|
let fee = app_config.fee / 100;
|
|
63425
63619
|
let working_risk = risk || app_config.risk_per_trade;
|
|
@@ -63466,9 +63660,12 @@ function buildConfig(app_config, {
|
|
|
63466
63660
|
stop_loss: stop,
|
|
63467
63661
|
risk: working_risk,
|
|
63468
63662
|
kind: kind || app_config.kind,
|
|
63469
|
-
no_of_trades: trade_no
|
|
63663
|
+
no_of_trades: trade_no,
|
|
63664
|
+
distribution
|
|
63470
63665
|
}) || [] : [];
|
|
63471
|
-
|
|
63666
|
+
const new_trades = computeTotalAverageForEachTrade(result, config2);
|
|
63667
|
+
let filtered = new_trades.filter((o) => o.avg_size > min_avg_size);
|
|
63668
|
+
return computeTotalAverageForEachTrade(filtered, config2);
|
|
63472
63669
|
}
|
|
63473
63670
|
function sortedBuildConfig(app_config, options) {
|
|
63474
63671
|
const sorted = buildConfig(app_config, options).sort((a, b) => app_config.kind === "long" ? a.entry - b.entry : b.entry - b.entry).filter((x) => {
|
|
@@ -63520,7 +63717,8 @@ function get_app_config_and_max_size(config2, payload) {
|
|
|
63520
63717
|
kelly_confidence_factor: payload.kelly_confidence_factor,
|
|
63521
63718
|
kelly_minimum_risk: payload.kelly_minimum_risk,
|
|
63522
63719
|
kelly_prediction_model: payload.kelly_prediction_model,
|
|
63523
|
-
kelly_func: payload.kelly_func
|
|
63720
|
+
kelly_func: payload.kelly_func,
|
|
63721
|
+
distribution: payload.distribution
|
|
63524
63722
|
});
|
|
63525
63723
|
const max_size = initialResult[0]?.avg_size;
|
|
63526
63724
|
const last_value = initialResult[0];
|
|
@@ -63558,7 +63756,8 @@ function buildAppConfig(config2, payload) {
|
|
|
63558
63756
|
kelly_confidence_factor: payload.kelly_confidence_factor,
|
|
63559
63757
|
kelly_minimum_risk: payload.kelly_minimum_risk,
|
|
63560
63758
|
kelly_prediction_model: payload.kelly_prediction_model,
|
|
63561
|
-
kelly_func: payload.kelly_func
|
|
63759
|
+
kelly_func: payload.kelly_func,
|
|
63760
|
+
distribution: payload.distribution
|
|
63562
63761
|
});
|
|
63563
63762
|
app_config.max_size = max_size;
|
|
63564
63763
|
app_config.entry = payload.entry || app_config.entry;
|
|
@@ -63575,7 +63774,7 @@ function buildAppConfig(config2, payload) {
|
|
|
63575
63774
|
return app_config;
|
|
63576
63775
|
}
|
|
63577
63776
|
function getOptimumStopAndRisk(app_config, params) {
|
|
63578
|
-
const { max_size, target_stop } = params;
|
|
63777
|
+
const { max_size, target_stop, distribution } = params;
|
|
63579
63778
|
const isLong = app_config.kind === "long";
|
|
63580
63779
|
const stopRange = Math.abs(app_config.entry - target_stop) * 0.5;
|
|
63581
63780
|
let low_stop = isLong ? target_stop - stopRange : Math.max(target_stop - stopRange, app_config.entry);
|
|
@@ -63598,7 +63797,8 @@ function getOptimumStopAndRisk(app_config, params) {
|
|
|
63598
63797
|
increase: true,
|
|
63599
63798
|
gap: app_config.gap,
|
|
63600
63799
|
price_places: app_config.price_places,
|
|
63601
|
-
decimal_places: app_config.decimal_places
|
|
63800
|
+
decimal_places: app_config.decimal_places,
|
|
63801
|
+
distribution
|
|
63602
63802
|
});
|
|
63603
63803
|
if (result.length === 0) {
|
|
63604
63804
|
if (isLong) {
|
|
@@ -63652,7 +63852,8 @@ function getOptimumStopAndRisk(app_config, params) {
|
|
|
63652
63852
|
increase: true,
|
|
63653
63853
|
gap: app_config.gap,
|
|
63654
63854
|
price_places: app_config.price_places,
|
|
63655
|
-
decimal_places: app_config.decimal_places
|
|
63855
|
+
decimal_places: app_config.decimal_places,
|
|
63856
|
+
distribution
|
|
63656
63857
|
});
|
|
63657
63858
|
if (result.length === 0) {
|
|
63658
63859
|
high_risk = mid_risk;
|
|
@@ -63697,7 +63898,8 @@ function getOptimumStopAndRisk(app_config, params) {
|
|
|
63697
63898
|
increase: true,
|
|
63698
63899
|
gap: app_config.gap,
|
|
63699
63900
|
price_places: app_config.price_places,
|
|
63700
|
-
decimal_places: app_config.decimal_places
|
|
63901
|
+
decimal_places: app_config.decimal_places,
|
|
63902
|
+
distribution
|
|
63701
63903
|
});
|
|
63702
63904
|
if (result.length === 0)
|
|
63703
63905
|
continue;
|
|
@@ -63820,7 +64022,8 @@ function generateOptimumAppConfig(config2, payload, position2) {
|
|
|
63820
64022
|
}, {
|
|
63821
64023
|
entry: payload.entry,
|
|
63822
64024
|
stop: payload.stop,
|
|
63823
|
-
kind: position2.kind
|
|
64025
|
+
kind: position2.kind,
|
|
64026
|
+
distribution: payload.distribution
|
|
63824
64027
|
});
|
|
63825
64028
|
current_app_config.max_size = max_size;
|
|
63826
64029
|
current_app_config.last_value = last_value;
|
|
@@ -63835,7 +64038,8 @@ function generateOptimumAppConfig(config2, payload, position2) {
|
|
|
63835
64038
|
increase: true,
|
|
63836
64039
|
gap: current_app_config.gap,
|
|
63837
64040
|
price_places: current_app_config.price_places,
|
|
63838
|
-
decimal_places: current_app_config.decimal_places
|
|
64041
|
+
decimal_places: current_app_config.decimal_places,
|
|
64042
|
+
distribution: payload.distribution
|
|
63839
64043
|
});
|
|
63840
64044
|
if (full_trades.length === 0) {
|
|
63841
64045
|
high_risk = mid_risk;
|
|
@@ -63899,7 +64103,8 @@ function determineOptimumReward(payload) {
|
|
|
63899
64103
|
increase = true,
|
|
63900
64104
|
low_range = 1,
|
|
63901
64105
|
high_range = 199,
|
|
63902
|
-
target_loss
|
|
64106
|
+
target_loss,
|
|
64107
|
+
distribution
|
|
63903
64108
|
} = payload;
|
|
63904
64109
|
const criterion = app_config.strategy || "quantity";
|
|
63905
64110
|
const risk_rewards = createArray(low_range, high_range, 1);
|
|
@@ -63913,7 +64118,8 @@ function determineOptimumReward(payload) {
|
|
|
63913
64118
|
increase,
|
|
63914
64119
|
kind: app_config.kind,
|
|
63915
64120
|
gap: app_config.gap,
|
|
63916
|
-
decimal_places: app_config.decimal_places
|
|
64121
|
+
decimal_places: app_config.decimal_places,
|
|
64122
|
+
distribution
|
|
63917
64123
|
});
|
|
63918
64124
|
let total = 0;
|
|
63919
64125
|
let max = -Infinity;
|
|
@@ -64078,14 +64284,17 @@ function determineOptimumRisk(config2, payload, params) {
|
|
|
64078
64284
|
};
|
|
64079
64285
|
}
|
|
64080
64286
|
function computeRiskReward(payload) {
|
|
64081
|
-
const { app_config, entry, stop, risk_per_trade, target_loss } = payload;
|
|
64287
|
+
const { app_config, entry, stop, risk_per_trade, target_loss, distribution } = payload;
|
|
64082
64288
|
const kind = entry > stop ? "long" : "short";
|
|
64083
64289
|
app_config.kind = kind;
|
|
64084
64290
|
app_config.entry = entry;
|
|
64085
64291
|
app_config.stop = stop;
|
|
64086
64292
|
app_config.risk_per_trade = risk_per_trade;
|
|
64087
|
-
const result = determineOptimumReward({
|
|
64088
|
-
|
|
64293
|
+
const result = determineOptimumReward({
|
|
64294
|
+
app_config,
|
|
64295
|
+
target_loss,
|
|
64296
|
+
distribution
|
|
64297
|
+
});
|
|
64089
64298
|
return result;
|
|
64090
64299
|
}
|
|
64091
64300
|
function getRiskReward(payload) {
|
|
@@ -64095,21 +64304,24 @@ function getRiskReward(payload) {
|
|
|
64095
64304
|
risk,
|
|
64096
64305
|
global_config,
|
|
64097
64306
|
force_exact_risk = false,
|
|
64098
|
-
target_loss
|
|
64307
|
+
target_loss,
|
|
64308
|
+
distribution
|
|
64099
64309
|
} = payload;
|
|
64100
64310
|
const { entries, last_value, ...app_config } = buildAppConfig(global_config, {
|
|
64101
64311
|
entry,
|
|
64102
64312
|
stop,
|
|
64103
64313
|
risk_reward: 30,
|
|
64104
64314
|
risk,
|
|
64105
|
-
symbol: global_config.symbol
|
|
64315
|
+
symbol: global_config.symbol,
|
|
64316
|
+
distribution
|
|
64106
64317
|
});
|
|
64107
64318
|
const risk_reward = computeRiskReward({
|
|
64108
64319
|
app_config,
|
|
64109
64320
|
entry,
|
|
64110
64321
|
stop,
|
|
64111
64322
|
risk_per_trade: risk,
|
|
64112
|
-
target_loss
|
|
64323
|
+
target_loss,
|
|
64324
|
+
distribution
|
|
64113
64325
|
});
|
|
64114
64326
|
if (force_exact_risk) {
|
|
64115
64327
|
const new_risk_per_trade = determineOptimumRisk(global_config, {
|
|
@@ -64117,7 +64329,8 @@ function getRiskReward(payload) {
|
|
|
64117
64329
|
stop,
|
|
64118
64330
|
risk_reward,
|
|
64119
64331
|
risk,
|
|
64120
|
-
symbol: global_config.symbol
|
|
64332
|
+
symbol: global_config.symbol,
|
|
64333
|
+
distribution
|
|
64121
64334
|
}, {
|
|
64122
64335
|
highest_risk: risk
|
|
64123
64336
|
}).optimal_risk;
|
|
@@ -64474,7 +64687,7 @@ function constructAppConfig(payload) {
|
|
|
64474
64687
|
kelly_minimum_risk: kelly_config?.kelly_minimum_risk ?? kelly?.kelly_minimum_risk,
|
|
64475
64688
|
kelly_prediction_model: kelly_config?.kelly_prediction_model ?? kelly?.kelly_prediction_model
|
|
64476
64689
|
};
|
|
64477
|
-
const appConfig = buildAppConfig(global_config, options);
|
|
64690
|
+
const { entries: _entries, ...appConfig } = buildAppConfig(global_config, options);
|
|
64478
64691
|
return appConfig;
|
|
64479
64692
|
}
|
|
64480
64693
|
function generateDangerousConfig(payload) {
|
|
@@ -67433,7 +67646,6 @@ async function reduceMajorPositionEntry(input, accountInfo, trigger2, exchange_i
|
|
|
67433
67646
|
// src/position.ts
|
|
67434
67647
|
var import_https_proxy_agent2 = __toESM(require_dist2(), 1);
|
|
67435
67648
|
var import_socks_proxy_agent2 = __toESM(require_dist3(), 1);
|
|
67436
|
-
|
|
67437
67649
|
class ExchangePosition {
|
|
67438
67650
|
exchange;
|
|
67439
67651
|
symbol_config;
|
|
@@ -67473,6 +67685,19 @@ class ExchangePosition {
|
|
|
67473
67685
|
const { p_account } = this.instance.expand;
|
|
67474
67686
|
return p_account;
|
|
67475
67687
|
}
|
|
67688
|
+
get compound() {
|
|
67689
|
+
const { compound_instance } = this.instance.expand;
|
|
67690
|
+
if (compound_instance) {
|
|
67691
|
+
const { ref } = compound_instance.expand;
|
|
67692
|
+
const profit_percent = ref.profit_percent / 100;
|
|
67693
|
+
return {
|
|
67694
|
+
...compound_instance,
|
|
67695
|
+
profit_percent,
|
|
67696
|
+
amount_to_risk: to_f(compound_instance.risk * profit_percent, "%.2f")
|
|
67697
|
+
};
|
|
67698
|
+
}
|
|
67699
|
+
return compound_instance;
|
|
67700
|
+
}
|
|
67476
67701
|
async getProxyForAccount() {
|
|
67477
67702
|
if (this.instance.expand.proxy) {
|
|
67478
67703
|
const result = this.instance.expand.proxy;
|
|
@@ -67598,7 +67823,8 @@ class ExchangePosition {
|
|
|
67598
67823
|
place,
|
|
67599
67824
|
raw: payload.raw,
|
|
67600
67825
|
use_current,
|
|
67601
|
-
stop_percent: config2.stop_percent || 100
|
|
67826
|
+
stop_percent: config2.stop_percent || 100,
|
|
67827
|
+
distribution: config2.distribution
|
|
67602
67828
|
});
|
|
67603
67829
|
}
|
|
67604
67830
|
}
|
|
@@ -67632,7 +67858,8 @@ class ExchangePosition {
|
|
|
67632
67858
|
kelly_confidence_factor: config2.kelly?.kelly_confidence_factor,
|
|
67633
67859
|
kelly_minimum_risk: config2.kelly?.kelly_minimum_risk,
|
|
67634
67860
|
kelly_prediction_model: config2.kelly?.kelly_prediction_model,
|
|
67635
|
-
kelly_func: config2.kelly?.kelly_func
|
|
67861
|
+
kelly_func: config2.kelly?.kelly_func,
|
|
67862
|
+
distribution: config2.distribution
|
|
67636
67863
|
}, false);
|
|
67637
67864
|
if (payload.raw) {
|
|
67638
67865
|
let actual_orders_to_buy = await this.determineAmountToBuy({
|
|
@@ -67755,7 +67982,8 @@ class ExchangePosition {
|
|
|
67755
67982
|
kelly_confidence_factor: solution.kelly_confidence_factor,
|
|
67756
67983
|
kelly_minimum_risk: solution.kelly_minimum_risk,
|
|
67757
67984
|
kelly_prediction_model: solution.kelly_prediction_model,
|
|
67758
|
-
kelly_func: solution.kelly_func
|
|
67985
|
+
kelly_func: solution.kelly_func,
|
|
67986
|
+
distribution: solution.distribution
|
|
67759
67987
|
};
|
|
67760
67988
|
const trades = sortedBuildConfig(app_config, options);
|
|
67761
67989
|
const entry_orders = {
|
|
@@ -68147,6 +68375,7 @@ class ExchangePosition {
|
|
|
68147
68375
|
});
|
|
68148
68376
|
}
|
|
68149
68377
|
async generate_config_params(payload) {
|
|
68378
|
+
const db_config = await this.getConfig();
|
|
68150
68379
|
const { entry, stop, risk_reward, risk, with_trades = false } = payload;
|
|
68151
68380
|
const symbol = this.symbol;
|
|
68152
68381
|
const app_config = await this.buildAppConfig({
|
|
@@ -68179,7 +68408,8 @@ class ExchangePosition {
|
|
|
68179
68408
|
avg_size: 0,
|
|
68180
68409
|
neg_pnl: 0,
|
|
68181
68410
|
min_size: app_config2.min_size,
|
|
68182
|
-
symbol
|
|
68411
|
+
symbol,
|
|
68412
|
+
distribution: db_config.distribution
|
|
68183
68413
|
}, false);
|
|
68184
68414
|
config2.trades = trades;
|
|
68185
68415
|
}
|
|
@@ -68280,7 +68510,8 @@ class ExchangePosition {
|
|
|
68280
68510
|
kelly_confidence_factor: config2.kelly?.kelly_confidence_factor,
|
|
68281
68511
|
kelly_minimum_risk: config2.kelly?.kelly_minimum_risk,
|
|
68282
68512
|
kelly_prediction_model: config2.kelly?.kelly_prediction_model,
|
|
68283
|
-
kelly_func: config2.kelly?.kelly_func
|
|
68513
|
+
kelly_func: config2.kelly?.kelly_func,
|
|
68514
|
+
distribution: config2.distribution
|
|
68284
68515
|
});
|
|
68285
68516
|
const position2 = this.instance;
|
|
68286
68517
|
const orders_to_place = await this.determineAmountToBuy({
|
|
@@ -68478,6 +68709,46 @@ class ExchangePosition {
|
|
|
68478
68709
|
increase: false
|
|
68479
68710
|
});
|
|
68480
68711
|
}
|
|
68712
|
+
get support() {
|
|
68713
|
+
return this.instance.expand?.support;
|
|
68714
|
+
}
|
|
68715
|
+
get linkedConfig() {
|
|
68716
|
+
return this.instance.expand?.b_config;
|
|
68717
|
+
}
|
|
68718
|
+
get isActiveTrade() {
|
|
68719
|
+
const config2 = this.linkedConfig;
|
|
68720
|
+
return {
|
|
68721
|
+
config: config2,
|
|
68722
|
+
condition: this.compound && this.support?.price === config2.stop
|
|
68723
|
+
};
|
|
68724
|
+
}
|
|
68725
|
+
async updateCompound(payload) {
|
|
68726
|
+
const pb = this.app_db.pb;
|
|
68727
|
+
const item = this.compound;
|
|
68728
|
+
const new_risk = item.risk + item.amount_to_risk;
|
|
68729
|
+
const { condition, config: config2 } = this.isActiveTrade;
|
|
68730
|
+
if (payload?.place && condition) {
|
|
68731
|
+
await pb.collection("compound_instances").update(item.id, {
|
|
68732
|
+
risk: new_risk
|
|
68733
|
+
});
|
|
68734
|
+
await pb.collection("scheduled_trades").update(config2.id, {
|
|
68735
|
+
profit: to_f(new_risk * item.profit_percent, "%.3f")
|
|
68736
|
+
});
|
|
68737
|
+
}
|
|
68738
|
+
return {
|
|
68739
|
+
support: this.support?.price,
|
|
68740
|
+
counter: this.support?.counter,
|
|
68741
|
+
new_risk,
|
|
68742
|
+
condition,
|
|
68743
|
+
stop: config2.stop
|
|
68744
|
+
};
|
|
68745
|
+
}
|
|
68746
|
+
async cleanOnActiveCompoundInstance() {
|
|
68747
|
+
const { condition } = this.isActiveTrade;
|
|
68748
|
+
if (condition && this.instance.quantity === 0) {
|
|
68749
|
+
await this.cancelOrders({ limit: true });
|
|
68750
|
+
}
|
|
68751
|
+
}
|
|
68481
68752
|
}
|
|
68482
68753
|
function convert_to_exchange_order(order) {
|
|
68483
68754
|
return {
|