@gbozee/ultimate 0.0.2-200 → 0.0.2-202
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 +308 -13
- package/dist/frontend-index.js +419 -6
- package/dist/index.cjs +457 -44
- package/dist/index.d.ts +309 -11
- package/dist/index.js +457 -44
- package/dist/mcp-server.cjs +737 -4
- package/dist/mcp-server.js +737 -4
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -38677,20 +38677,20 @@ var require_axios2 = __commonJS((exports2, module2) => {
|
|
|
38677
38677
|
var reduceDescriptors = (obj, reducer) => {
|
|
38678
38678
|
const descriptors2 = Object.getOwnPropertyDescriptors(obj);
|
|
38679
38679
|
const reducedDescriptors = {};
|
|
38680
|
-
forEach2(descriptors2, (descriptor,
|
|
38680
|
+
forEach2(descriptors2, (descriptor, name2) => {
|
|
38681
38681
|
let ret;
|
|
38682
|
-
if ((ret = reducer(descriptor,
|
|
38683
|
-
reducedDescriptors[
|
|
38682
|
+
if ((ret = reducer(descriptor, name2, obj)) !== false) {
|
|
38683
|
+
reducedDescriptors[name2] = ret || descriptor;
|
|
38684
38684
|
}
|
|
38685
38685
|
});
|
|
38686
38686
|
Object.defineProperties(obj, reducedDescriptors);
|
|
38687
38687
|
};
|
|
38688
38688
|
var freezeMethods = (obj) => {
|
|
38689
|
-
reduceDescriptors(obj, (descriptor,
|
|
38690
|
-
if (isFunction(obj) && ["arguments", "caller", "callee"].indexOf(
|
|
38689
|
+
reduceDescriptors(obj, (descriptor, name2) => {
|
|
38690
|
+
if (isFunction(obj) && ["arguments", "caller", "callee"].indexOf(name2) !== -1) {
|
|
38691
38691
|
return false;
|
|
38692
38692
|
}
|
|
38693
|
-
const value2 = obj[
|
|
38693
|
+
const value2 = obj[name2];
|
|
38694
38694
|
if (!isFunction(value2))
|
|
38695
38695
|
return;
|
|
38696
38696
|
descriptor.enumerable = false;
|
|
@@ -38700,7 +38700,7 @@ var require_axios2 = __commonJS((exports2, module2) => {
|
|
|
38700
38700
|
}
|
|
38701
38701
|
if (!descriptor.set) {
|
|
38702
38702
|
descriptor.set = () => {
|
|
38703
|
-
throw Error("Can not rewrite read-only method '" +
|
|
38703
|
+
throw Error("Can not rewrite read-only method '" + name2 + "'");
|
|
38704
38704
|
};
|
|
38705
38705
|
}
|
|
38706
38706
|
});
|
|
@@ -39008,8 +39008,8 @@ var require_axios2 = __commonJS((exports2, module2) => {
|
|
|
39008
39008
|
params && toFormData(params, this, options);
|
|
39009
39009
|
}
|
|
39010
39010
|
var prototype = AxiosURLSearchParams.prototype;
|
|
39011
|
-
prototype.append = function append(
|
|
39012
|
-
this._pairs.push([
|
|
39011
|
+
prototype.append = function append(name2, value2) {
|
|
39012
|
+
this._pairs.push([name2, value2]);
|
|
39013
39013
|
};
|
|
39014
39014
|
prototype.toString = function toString(encoder2) {
|
|
39015
39015
|
const _encode = encoder2 ? function(value2) {
|
|
@@ -39145,8 +39145,8 @@ var require_axios2 = __commonJS((exports2, module2) => {
|
|
|
39145
39145
|
}
|
|
39146
39146
|
}, options));
|
|
39147
39147
|
}
|
|
39148
|
-
function parsePropPath(
|
|
39149
|
-
return utils$1.matchAll(/\w+|\[(\w*)]/g,
|
|
39148
|
+
function parsePropPath(name2) {
|
|
39149
|
+
return utils$1.matchAll(/\w+|\[(\w*)]/g, name2).map((match) => {
|
|
39150
39150
|
return match[0] === "[]" ? "" : match[1] || match[0];
|
|
39151
39151
|
});
|
|
39152
39152
|
}
|
|
@@ -39164,33 +39164,33 @@ var require_axios2 = __commonJS((exports2, module2) => {
|
|
|
39164
39164
|
}
|
|
39165
39165
|
function formDataToJSON(formData) {
|
|
39166
39166
|
function buildPath(path, value2, target, index) {
|
|
39167
|
-
let
|
|
39168
|
-
if (
|
|
39167
|
+
let name2 = path[index++];
|
|
39168
|
+
if (name2 === "__proto__")
|
|
39169
39169
|
return true;
|
|
39170
|
-
const isNumericKey = Number.isFinite(+
|
|
39170
|
+
const isNumericKey = Number.isFinite(+name2);
|
|
39171
39171
|
const isLast = index >= path.length;
|
|
39172
|
-
|
|
39172
|
+
name2 = !name2 && utils$1.isArray(target) ? target.length : name2;
|
|
39173
39173
|
if (isLast) {
|
|
39174
|
-
if (utils$1.hasOwnProp(target,
|
|
39175
|
-
target[
|
|
39174
|
+
if (utils$1.hasOwnProp(target, name2)) {
|
|
39175
|
+
target[name2] = [target[name2], value2];
|
|
39176
39176
|
} else {
|
|
39177
|
-
target[
|
|
39177
|
+
target[name2] = value2;
|
|
39178
39178
|
}
|
|
39179
39179
|
return !isNumericKey;
|
|
39180
39180
|
}
|
|
39181
|
-
if (!target[
|
|
39182
|
-
target[
|
|
39181
|
+
if (!target[name2] || !utils$1.isObject(target[name2])) {
|
|
39182
|
+
target[name2] = [];
|
|
39183
39183
|
}
|
|
39184
|
-
const result = buildPath(path, value2, target[
|
|
39185
|
-
if (result && utils$1.isArray(target[
|
|
39186
|
-
target[
|
|
39184
|
+
const result = buildPath(path, value2, target[name2], index);
|
|
39185
|
+
if (result && utils$1.isArray(target[name2])) {
|
|
39186
|
+
target[name2] = arrayToObject(target[name2]);
|
|
39187
39187
|
}
|
|
39188
39188
|
return !isNumericKey;
|
|
39189
39189
|
}
|
|
39190
39190
|
if (utils$1.isFormData(formData) && utils$1.isFunction(formData.entries)) {
|
|
39191
39191
|
const obj = {};
|
|
39192
|
-
utils$1.forEachEntry(formData, (
|
|
39193
|
-
buildPath(parsePropPath(
|
|
39192
|
+
utils$1.forEachEntry(formData, (name2, value2) => {
|
|
39193
|
+
buildPath(parsePropPath(name2), value2, obj, 0);
|
|
39194
39194
|
});
|
|
39195
39195
|
return obj;
|
|
39196
39196
|
}
|
|
@@ -39769,10 +39769,10 @@ var require_axios2 = __commonJS((exports2, module2) => {
|
|
|
39769
39769
|
var CRLF_BYTES_COUNT = 2;
|
|
39770
39770
|
|
|
39771
39771
|
class FormDataPart {
|
|
39772
|
-
constructor(
|
|
39772
|
+
constructor(name2, value2) {
|
|
39773
39773
|
const { escapeName } = this.constructor;
|
|
39774
39774
|
const isStringValue = utils$1.isString(value2);
|
|
39775
|
-
let headers = `Content-Disposition: form-data; name="${escapeName(
|
|
39775
|
+
let headers = `Content-Disposition: form-data; name="${escapeName(name2)}"${!isStringValue && value2.name ? `; filename="${escapeName(value2.name)}"` : ""}${CRLF}`;
|
|
39776
39776
|
if (isStringValue) {
|
|
39777
39777
|
value2 = textEncoder.encode(String(value2).replace(/\r?\n|\r\n?/g, CRLF));
|
|
39778
39778
|
} else {
|
|
@@ -39781,7 +39781,7 @@ var require_axios2 = __commonJS((exports2, module2) => {
|
|
|
39781
39781
|
this.headers = textEncoder.encode(headers + CRLF);
|
|
39782
39782
|
this.contentLength = isStringValue ? value2.byteLength : value2.size;
|
|
39783
39783
|
this.size = this.headers.byteLength + this.contentLength + CRLF_BYTES_COUNT;
|
|
39784
|
-
this.name =
|
|
39784
|
+
this.name = name2;
|
|
39785
39785
|
this.value = value2;
|
|
39786
39786
|
}
|
|
39787
39787
|
async* encode() {
|
|
@@ -39794,8 +39794,8 @@ var require_axios2 = __commonJS((exports2, module2) => {
|
|
|
39794
39794
|
}
|
|
39795
39795
|
yield CRLF_BYTES;
|
|
39796
39796
|
}
|
|
39797
|
-
static escapeName(
|
|
39798
|
-
return String(
|
|
39797
|
+
static escapeName(name2) {
|
|
39798
|
+
return String(name2).replace(/[\r\n"]/g, (match) => ({
|
|
39799
39799
|
"\r": "%0D",
|
|
39800
39800
|
"\n": "%0A",
|
|
39801
39801
|
'"': "%22"
|
|
@@ -39817,8 +39817,8 @@ var require_axios2 = __commonJS((exports2, module2) => {
|
|
|
39817
39817
|
const boundaryBytes = textEncoder.encode("--" + boundary + CRLF);
|
|
39818
39818
|
const footerBytes = textEncoder.encode("--" + boundary + "--" + CRLF + CRLF);
|
|
39819
39819
|
let contentLength = footerBytes.byteLength;
|
|
39820
|
-
const parts = Array.from(form.entries()).map(([
|
|
39821
|
-
const part = new FormDataPart(
|
|
39820
|
+
const parts = Array.from(form.entries()).map(([name2, value2]) => {
|
|
39821
|
+
const part = new FormDataPart(name2, value2);
|
|
39822
39822
|
contentLength += part.size;
|
|
39823
39823
|
return part;
|
|
39824
39824
|
});
|
|
@@ -40426,20 +40426,20 @@ var require_axios2 = __commonJS((exports2, module2) => {
|
|
|
40426
40426
|
return origin2.protocol === url2.protocol && origin2.host === url2.host && (isMSIE || origin2.port === url2.port);
|
|
40427
40427
|
})(new URL(platform.origin), platform.navigator && /(msie|trident)/i.test(platform.navigator.userAgent)) : () => true;
|
|
40428
40428
|
var cookies = platform.hasStandardBrowserEnv ? {
|
|
40429
|
-
write(
|
|
40430
|
-
const cookie = [
|
|
40429
|
+
write(name2, value2, expires, path, domain, secure) {
|
|
40430
|
+
const cookie = [name2 + "=" + encodeURIComponent(value2)];
|
|
40431
40431
|
utils$1.isNumber(expires) && cookie.push("expires=" + new Date(expires).toGMTString());
|
|
40432
40432
|
utils$1.isString(path) && cookie.push("path=" + path);
|
|
40433
40433
|
utils$1.isString(domain) && cookie.push("domain=" + domain);
|
|
40434
40434
|
secure === true && cookie.push("secure");
|
|
40435
40435
|
document.cookie = cookie.join("; ");
|
|
40436
40436
|
},
|
|
40437
|
-
read(
|
|
40438
|
-
const match = document.cookie.match(new RegExp("(^|;\\s*)(" +
|
|
40437
|
+
read(name2) {
|
|
40438
|
+
const match = document.cookie.match(new RegExp("(^|;\\s*)(" + name2 + ")=([^;]*)"));
|
|
40439
40439
|
return match ? decodeURIComponent(match[3]) : null;
|
|
40440
40440
|
},
|
|
40441
|
-
remove(
|
|
40442
|
-
this.write(
|
|
40441
|
+
remove(name2) {
|
|
40442
|
+
this.write(name2, "", Date.now() - 86400000);
|
|
40443
40443
|
}
|
|
40444
40444
|
} : {
|
|
40445
40445
|
write() {},
|
|
@@ -44876,7 +44876,6 @@ var require_lib3 = __commonJS((exports2) => {
|
|
|
44876
44876
|
var exports_src = {};
|
|
44877
44877
|
__export(exports_src, {
|
|
44878
44878
|
sortedBuildConfig: () => sortedBuildConfig,
|
|
44879
|
-
name: () => name2,
|
|
44880
44879
|
initialize: () => initialize,
|
|
44881
44880
|
initApp: () => initApp,
|
|
44882
44881
|
get_app_config_and_max_size: () => get_app_config_and_max_size,
|
|
@@ -44902,6 +44901,7 @@ __export(exports_src, {
|
|
|
44902
44901
|
constructAppConfig: () => constructAppConfig,
|
|
44903
44902
|
computeRiskReward: () => computeRiskReward,
|
|
44904
44903
|
computeProfitDetail: () => computeProfitDetail,
|
|
44904
|
+
compoundAPI: () => compoundAPI,
|
|
44905
44905
|
calculateFactorFromTakeProfit: () => calculateFactorFromTakeProfit,
|
|
44906
44906
|
calculateFactorFromSellQuantity: () => calculateFactorFromSellQuantity,
|
|
44907
44907
|
buildConfig: () => buildConfig,
|
|
@@ -56150,7 +56150,6 @@ class Signal {
|
|
|
56150
56150
|
let potentials = new_result.filter((x) => condition(x["entry"], i2["risk_sell"])).map((x) => x["entry"]);
|
|
56151
56151
|
if (potentials.length && max_index) {
|
|
56152
56152
|
if (kind === "long") {
|
|
56153
|
-
console.log("slice: ", potentials.slice(0, max_index));
|
|
56154
56153
|
i2["risk_sell"] = Math.max(...potentials.slice(0, max_index));
|
|
56155
56154
|
} else {
|
|
56156
56155
|
i2["risk_sell"] = Math.min(...potentials.slice(0, max_index));
|
|
@@ -56214,7 +56213,6 @@ class Signal {
|
|
|
56214
56213
|
}) {
|
|
56215
56214
|
const margin_zones = [this.support, this.resistance];
|
|
56216
56215
|
const distribution = this.distribution ? this.distribution[kind] : "geometric";
|
|
56217
|
-
console.log("margin_zones", { margin_zones, distribution });
|
|
56218
56216
|
let _kind = distribution === "inverse-exponential" ? kind === "long" ? "short" : "long" : kind;
|
|
56219
56217
|
const entries = distributions_default({
|
|
56220
56218
|
margin_range: margin_zones,
|
|
@@ -56433,7 +56431,6 @@ class Signal {
|
|
|
56433
56431
|
}
|
|
56434
56432
|
});
|
|
56435
56433
|
risk_to_use = theoretical_kelly * risk_per_trade / this.kelly_minimum_risk;
|
|
56436
|
-
console.log({ risk_per_trade, theoretical_kelly });
|
|
56437
56434
|
}
|
|
56438
56435
|
const y = this.build_trade_dict({
|
|
56439
56436
|
entry: x,
|
|
@@ -56933,7 +56930,6 @@ function buildConfig(app_config, {
|
|
|
56933
56930
|
}
|
|
56934
56931
|
const condition = (kind === "long" ? entry > app_config.support : entry >= app_config.support) && stop >= app_config.support * 0.999;
|
|
56935
56932
|
if (kind === "short") {}
|
|
56936
|
-
console.log({ entry, stop, condition, working_risk, config: config2 });
|
|
56937
56933
|
const result = entry === stop ? [] : condition ? instance.build_entry({
|
|
56938
56934
|
current_price: entry,
|
|
56939
56935
|
stop_loss: stop,
|
|
@@ -57589,6 +57585,7 @@ function computeRiskReward(payload) {
|
|
|
57589
57585
|
risk_per_trade,
|
|
57590
57586
|
target_loss,
|
|
57591
57587
|
distribution,
|
|
57588
|
+
high_range,
|
|
57592
57589
|
max_size
|
|
57593
57590
|
} = payload;
|
|
57594
57591
|
const kind = entry > stop ? "long" : "short";
|
|
@@ -57600,12 +57597,14 @@ function computeRiskReward(payload) {
|
|
|
57600
57597
|
app_config,
|
|
57601
57598
|
target_loss,
|
|
57602
57599
|
distribution,
|
|
57600
|
+
high_range,
|
|
57603
57601
|
max_size
|
|
57604
57602
|
});
|
|
57605
57603
|
return result;
|
|
57606
57604
|
}
|
|
57607
57605
|
function getRiskReward(payload) {
|
|
57608
57606
|
const {
|
|
57607
|
+
high_range,
|
|
57609
57608
|
max_size,
|
|
57610
57609
|
entry,
|
|
57611
57610
|
stop,
|
|
@@ -57629,6 +57628,7 @@ function getRiskReward(payload) {
|
|
|
57629
57628
|
entry,
|
|
57630
57629
|
stop,
|
|
57631
57630
|
risk_per_trade: risk,
|
|
57631
|
+
high_range,
|
|
57632
57632
|
target_loss,
|
|
57633
57633
|
distribution,
|
|
57634
57634
|
max_size
|
|
@@ -58623,7 +58623,420 @@ class Strategy {
|
|
|
58623
58623
|
}
|
|
58624
58624
|
}
|
|
58625
58625
|
// src/helpers/compound.ts
|
|
58626
|
-
|
|
58626
|
+
function buildTrades(payload) {
|
|
58627
|
+
const { appConfig, settings, kind } = payload;
|
|
58628
|
+
const kelly_config = settings.kelly;
|
|
58629
|
+
const current_app_config = { ...appConfig[kind] };
|
|
58630
|
+
const entryNum = parseFloat(settings.entry);
|
|
58631
|
+
const stopNum = parseFloat(settings.stop);
|
|
58632
|
+
current_app_config.entry = entryNum;
|
|
58633
|
+
current_app_config.stop = stopNum;
|
|
58634
|
+
current_app_config.risk_per_trade = parseFloat(settings.risk);
|
|
58635
|
+
current_app_config.risk_reward = parseFloat(settings.risk_reward);
|
|
58636
|
+
current_app_config.kind = kind;
|
|
58637
|
+
current_app_config.kelly = kelly_config;
|
|
58638
|
+
const options = {
|
|
58639
|
+
take_profit: null,
|
|
58640
|
+
entry: current_app_config.entry,
|
|
58641
|
+
stop: current_app_config.stop,
|
|
58642
|
+
raw_instance: null,
|
|
58643
|
+
risk: current_app_config.risk_per_trade,
|
|
58644
|
+
no_of_trades: undefined,
|
|
58645
|
+
risk_reward: current_app_config.risk_reward,
|
|
58646
|
+
kind: current_app_config.kind,
|
|
58647
|
+
increase: true,
|
|
58648
|
+
gap: current_app_config.gap,
|
|
58649
|
+
rr: current_app_config.rr,
|
|
58650
|
+
price_places: current_app_config.price_places,
|
|
58651
|
+
decimal_places: current_app_config.decimal_places,
|
|
58652
|
+
use_kelly: kelly_config?.use_kelly,
|
|
58653
|
+
kelly_confidence_factor: kelly_config?.kelly_confidence_factor,
|
|
58654
|
+
kelly_minimum_risk: kelly_config?.kelly_minimum_risk,
|
|
58655
|
+
kelly_prediction_model: kelly_config?.kelly_prediction_model,
|
|
58656
|
+
kelly_func: kelly_config?.kelly_func,
|
|
58657
|
+
distribution: settings.distribution
|
|
58658
|
+
};
|
|
58659
|
+
if (kind === "long" && entryNum <= stopNum) {
|
|
58660
|
+
return [];
|
|
58661
|
+
}
|
|
58662
|
+
if (kind === "short" && entryNum >= stopNum) {
|
|
58663
|
+
return [];
|
|
58664
|
+
}
|
|
58665
|
+
try {
|
|
58666
|
+
const generatedTrades = sortedBuildConfig(current_app_config, options);
|
|
58667
|
+
return generatedTrades ?? [];
|
|
58668
|
+
} catch (error) {
|
|
58669
|
+
console.error("Error generating orders:", error);
|
|
58670
|
+
return [];
|
|
58671
|
+
}
|
|
58672
|
+
}
|
|
58673
|
+
function generateSummary({
|
|
58674
|
+
trades,
|
|
58675
|
+
fee_percent = 0.05,
|
|
58676
|
+
anchor
|
|
58677
|
+
}) {
|
|
58678
|
+
const avg_entry = trades[0].avg_entry;
|
|
58679
|
+
const avg_size = trades[0].avg_size;
|
|
58680
|
+
const expected_fee = avg_entry * avg_size * fee_percent / 100;
|
|
58681
|
+
return {
|
|
58682
|
+
first_entry: trades.at(-1).entry,
|
|
58683
|
+
last_entry: trades[0].entry,
|
|
58684
|
+
quantity: avg_size,
|
|
58685
|
+
entry: avg_entry,
|
|
58686
|
+
loss: trades[0].neg_pnl,
|
|
58687
|
+
number_of_trades: trades.length,
|
|
58688
|
+
fee: to_f(expected_fee, "%.2f"),
|
|
58689
|
+
anchor_pnl: anchor?.target_pnl
|
|
58690
|
+
};
|
|
58691
|
+
}
|
|
58692
|
+
function helperFuncToBuildTrades({
|
|
58693
|
+
custom_b_config,
|
|
58694
|
+
symbol_config,
|
|
58695
|
+
app_config_kind,
|
|
58696
|
+
appConfig,
|
|
58697
|
+
force_exact_risk = true
|
|
58698
|
+
}) {
|
|
58699
|
+
const risk = custom_b_config.risk * (custom_b_config.risk_factor || 1);
|
|
58700
|
+
let result = getRiskReward({
|
|
58701
|
+
entry: custom_b_config.entry,
|
|
58702
|
+
stop: custom_b_config.stop,
|
|
58703
|
+
risk,
|
|
58704
|
+
global_config: symbol_config,
|
|
58705
|
+
force_exact_risk,
|
|
58706
|
+
target_loss: custom_b_config.risk * (custom_b_config.risk_factor || 1),
|
|
58707
|
+
distribution: custom_b_config.distribution
|
|
58708
|
+
});
|
|
58709
|
+
if (!force_exact_risk) {
|
|
58710
|
+
result = {
|
|
58711
|
+
risk_reward: result,
|
|
58712
|
+
risk
|
|
58713
|
+
};
|
|
58714
|
+
}
|
|
58715
|
+
const trades = result.risk_reward ? buildTrades({
|
|
58716
|
+
appConfig: { [app_config_kind]: appConfig },
|
|
58717
|
+
kind: app_config_kind,
|
|
58718
|
+
settings: {
|
|
58719
|
+
entry: custom_b_config.entry,
|
|
58720
|
+
stop: custom_b_config.stop,
|
|
58721
|
+
risk: result.risk || custom_b_config.risk,
|
|
58722
|
+
risk_reward: result.risk_reward,
|
|
58723
|
+
distribution: custom_b_config.distribution
|
|
58724
|
+
}
|
|
58725
|
+
}) : [];
|
|
58726
|
+
const summary = trades.length > 0 ? generateSummary({ trades }) : {};
|
|
58727
|
+
return { trades, result, summary };
|
|
58728
|
+
}
|
|
58729
|
+
function constructAppConfig2({
|
|
58730
|
+
config: config2,
|
|
58731
|
+
global_config
|
|
58732
|
+
}) {
|
|
58733
|
+
const options = {
|
|
58734
|
+
entry: config2?.entry,
|
|
58735
|
+
stop: config2?.stop,
|
|
58736
|
+
risk_reward: config2?.risk_reward,
|
|
58737
|
+
risk: config2?.risk,
|
|
58738
|
+
symbol: config2.symbol
|
|
58739
|
+
};
|
|
58740
|
+
const { entries: _entries, ...appConfig } = buildAppConfig(global_config, options);
|
|
58741
|
+
return appConfig;
|
|
58742
|
+
}
|
|
58743
|
+
function buildWithOptimumReward({
|
|
58744
|
+
config: config2,
|
|
58745
|
+
settings,
|
|
58746
|
+
global_config,
|
|
58747
|
+
force_exact
|
|
58748
|
+
}) {
|
|
58749
|
+
const kind = config2.entry > config2.stop ? "long" : "short";
|
|
58750
|
+
let stop = settings.stop;
|
|
58751
|
+
let entry = settings.entry;
|
|
58752
|
+
const risk = settings.risk;
|
|
58753
|
+
const stop_ratio = settings.stop_ratio || 1;
|
|
58754
|
+
const distribution = settings.distribution || config2?.distribution;
|
|
58755
|
+
const custom_b_config = {
|
|
58756
|
+
entry,
|
|
58757
|
+
stop,
|
|
58758
|
+
risk,
|
|
58759
|
+
distribution
|
|
58760
|
+
};
|
|
58761
|
+
const appConfig = constructAppConfig2({
|
|
58762
|
+
config: config2,
|
|
58763
|
+
global_config
|
|
58764
|
+
});
|
|
58765
|
+
const { trades, summary, result } = helperFuncToBuildTrades({
|
|
58766
|
+
custom_b_config,
|
|
58767
|
+
app_config_kind: kind,
|
|
58768
|
+
appConfig,
|
|
58769
|
+
symbol_config: global_config,
|
|
58770
|
+
force_exact_risk: force_exact
|
|
58771
|
+
});
|
|
58772
|
+
const adjusted_size = summary.quantity;
|
|
58773
|
+
const symbol_config = global_config;
|
|
58774
|
+
const entryDetails = {
|
|
58775
|
+
entry: to_f(custom_b_config.entry, symbol_config.price_places),
|
|
58776
|
+
stop: to_f(custom_b_config.stop, symbol_config.price_places),
|
|
58777
|
+
risk: to_f(result.risk, "%.2f"),
|
|
58778
|
+
risk_reward: result.risk_reward,
|
|
58779
|
+
avg_entry: to_f(summary.entry, symbol_config.price_places),
|
|
58780
|
+
avg_size: to_f(adjusted_size, symbol_config.decimal_places),
|
|
58781
|
+
first_entry: to_f(summary.first_entry, symbol_config.price_places),
|
|
58782
|
+
pnl: to_f(custom_b_config.risk, "%.2f"),
|
|
58783
|
+
fee: to_f(summary.fee, "%.2f"),
|
|
58784
|
+
loss: to_f(summary.loss, "%.2f"),
|
|
58785
|
+
last_entry: to_f(summary.last_entry, symbol_config.price_places),
|
|
58786
|
+
margin: to_f(summary.entry * adjusted_size / symbol_config.leverage, "%.2f")
|
|
58787
|
+
};
|
|
58788
|
+
return {
|
|
58789
|
+
trades,
|
|
58790
|
+
summary: entryDetails,
|
|
58791
|
+
config: {
|
|
58792
|
+
...custom_b_config,
|
|
58793
|
+
...result,
|
|
58794
|
+
stop_ratio
|
|
58795
|
+
},
|
|
58796
|
+
stop_order: {
|
|
58797
|
+
quantity: entryDetails.avg_size * stop_ratio,
|
|
58798
|
+
price: entryDetails.stop
|
|
58799
|
+
},
|
|
58800
|
+
kind
|
|
58801
|
+
};
|
|
58802
|
+
}
|
|
58803
|
+
function generateOppositeOptimum({
|
|
58804
|
+
config: config2,
|
|
58805
|
+
global_config,
|
|
58806
|
+
settings,
|
|
58807
|
+
ratio = 1,
|
|
58808
|
+
distribution,
|
|
58809
|
+
risk_factor = 1
|
|
58810
|
+
}) {
|
|
58811
|
+
const configKind = config2.entry > config2.stop ? "long" : "short";
|
|
58812
|
+
if (configKind === "long" && config2.entry > config2.stop) {
|
|
58813
|
+
if (settings.stop <= settings.entry) {
|
|
58814
|
+
throw new Error("Invalid input: For long config positions, opposite settings must have stop > entry");
|
|
58815
|
+
}
|
|
58816
|
+
} else if (configKind === "short" && config2.entry < config2.stop) {
|
|
58817
|
+
if (settings.stop >= settings.entry) {
|
|
58818
|
+
throw new Error("Invalid input: For short config positions, opposite settings must have stop < entry");
|
|
58819
|
+
}
|
|
58820
|
+
}
|
|
58821
|
+
const kind = config2.entry > config2.stop ? "long" : "short";
|
|
58822
|
+
const app_config_kind = kind === "long" ? "short" : "long";
|
|
58823
|
+
let risk = settings.risk;
|
|
58824
|
+
const custom_b_config = {
|
|
58825
|
+
entry: settings.entry,
|
|
58826
|
+
stop: settings.stop,
|
|
58827
|
+
risk: risk * ratio,
|
|
58828
|
+
distribution: distribution || "inverse-exponential",
|
|
58829
|
+
risk_factor
|
|
58830
|
+
};
|
|
58831
|
+
const appConfig = constructAppConfig2({
|
|
58832
|
+
config: {
|
|
58833
|
+
...config2,
|
|
58834
|
+
...custom_b_config
|
|
58835
|
+
},
|
|
58836
|
+
global_config
|
|
58837
|
+
});
|
|
58838
|
+
const { result, trades, summary } = helperFuncToBuildTrades({
|
|
58839
|
+
custom_b_config,
|
|
58840
|
+
symbol_config: global_config,
|
|
58841
|
+
app_config_kind,
|
|
58842
|
+
appConfig
|
|
58843
|
+
});
|
|
58844
|
+
if (Object.keys(summary).length === 0) {
|
|
58845
|
+
return {
|
|
58846
|
+
trades,
|
|
58847
|
+
summary,
|
|
58848
|
+
config: custom_b_config,
|
|
58849
|
+
kind: app_config_kind
|
|
58850
|
+
};
|
|
58851
|
+
}
|
|
58852
|
+
const symbol_config = global_config;
|
|
58853
|
+
const entryDetails = {
|
|
58854
|
+
entry: to_f(custom_b_config.entry, symbol_config.price_places),
|
|
58855
|
+
stop: to_f(custom_b_config.stop, symbol_config.price_places),
|
|
58856
|
+
risk: to_f(result.risk, "%.2f"),
|
|
58857
|
+
risk_reward: result.risk_reward,
|
|
58858
|
+
avg_entry: to_f(summary.entry, symbol_config.price_places),
|
|
58859
|
+
avg_size: to_f(summary.quantity, symbol_config.decimal_places),
|
|
58860
|
+
first_entry: to_f(summary.first_entry, symbol_config.price_places),
|
|
58861
|
+
pnl: to_f(custom_b_config.risk, "%.2f"),
|
|
58862
|
+
fee: to_f(summary.fee, "%.2f"),
|
|
58863
|
+
loss: to_f(summary.loss, "%.2f"),
|
|
58864
|
+
last_entry: to_f(summary.last_entry, symbol_config.price_places),
|
|
58865
|
+
defaultEntry: settings.entry ? to_f(settings.entry, symbol_config.price_places) : null
|
|
58866
|
+
};
|
|
58867
|
+
return {
|
|
58868
|
+
trades,
|
|
58869
|
+
summary: entryDetails,
|
|
58870
|
+
config: {
|
|
58871
|
+
...custom_b_config,
|
|
58872
|
+
...result
|
|
58873
|
+
},
|
|
58874
|
+
kind: app_config_kind
|
|
58875
|
+
};
|
|
58876
|
+
}
|
|
58877
|
+
function defaultTradeFromCurrentState({
|
|
58878
|
+
config: config2,
|
|
58879
|
+
global_config
|
|
58880
|
+
}) {
|
|
58881
|
+
const kind = config2.entry > config2.stop ? "long" : "short";
|
|
58882
|
+
const settings = {
|
|
58883
|
+
entry: config2?.entry,
|
|
58884
|
+
stop: config2?.stop,
|
|
58885
|
+
risk: config2?.risk,
|
|
58886
|
+
distribution: config2?.distribution,
|
|
58887
|
+
risk_reward: config2?.risk_reward
|
|
58888
|
+
};
|
|
58889
|
+
const appConfig = constructAppConfig2({
|
|
58890
|
+
config: config2,
|
|
58891
|
+
global_config
|
|
58892
|
+
});
|
|
58893
|
+
const trades = buildTrades({
|
|
58894
|
+
appConfig: { [kind]: appConfig },
|
|
58895
|
+
kind,
|
|
58896
|
+
settings
|
|
58897
|
+
});
|
|
58898
|
+
return {
|
|
58899
|
+
trades,
|
|
58900
|
+
summary: generateSummary({
|
|
58901
|
+
trades,
|
|
58902
|
+
fee_percent: global_config.fee_percent
|
|
58903
|
+
})
|
|
58904
|
+
};
|
|
58905
|
+
}
|
|
58906
|
+
function increaseTradeHelper({
|
|
58907
|
+
increase_qty,
|
|
58908
|
+
stop,
|
|
58909
|
+
config: config2,
|
|
58910
|
+
global_config,
|
|
58911
|
+
style,
|
|
58912
|
+
entry,
|
|
58913
|
+
position: position2,
|
|
58914
|
+
stop_ratio = 1,
|
|
58915
|
+
distribution: default_distribution
|
|
58916
|
+
}) {
|
|
58917
|
+
const symbol_config = global_config;
|
|
58918
|
+
const kind = config2.entry > config2.stop ? "long" : "short";
|
|
58919
|
+
const distribution = default_distribution || config2.distribution || "inverse-exponential";
|
|
58920
|
+
const appConfig = constructAppConfig2({
|
|
58921
|
+
config: config2,
|
|
58922
|
+
global_config
|
|
58923
|
+
});
|
|
58924
|
+
const currentState = defaultTradeFromCurrentState({
|
|
58925
|
+
config: config2,
|
|
58926
|
+
global_config
|
|
58927
|
+
});
|
|
58928
|
+
const { optimal_risk, neg_pnl } = getOptimumStopAndRisk(appConfig, {
|
|
58929
|
+
max_size: increase_qty,
|
|
58930
|
+
target_stop: stop,
|
|
58931
|
+
distribution
|
|
58932
|
+
});
|
|
58933
|
+
if (neg_pnl === 0) {
|
|
58934
|
+
return {
|
|
58935
|
+
trades: [],
|
|
58936
|
+
summary: {},
|
|
58937
|
+
config: {},
|
|
58938
|
+
kind,
|
|
58939
|
+
current: currentState
|
|
58940
|
+
};
|
|
58941
|
+
}
|
|
58942
|
+
const custom_b_config = {
|
|
58943
|
+
entry,
|
|
58944
|
+
stop,
|
|
58945
|
+
risk: style === "minimum" ? Math.abs(neg_pnl) : optimal_risk,
|
|
58946
|
+
distribution
|
|
58947
|
+
};
|
|
58948
|
+
const { result, trades, summary } = helperFuncToBuildTrades({
|
|
58949
|
+
custom_b_config,
|
|
58950
|
+
symbol_config,
|
|
58951
|
+
appConfig,
|
|
58952
|
+
app_config_kind: kind
|
|
58953
|
+
});
|
|
58954
|
+
if (Object.keys(summary).length === 0) {
|
|
58955
|
+
return {
|
|
58956
|
+
trades,
|
|
58957
|
+
summary,
|
|
58958
|
+
config: {
|
|
58959
|
+
...custom_b_config,
|
|
58960
|
+
...result
|
|
58961
|
+
},
|
|
58962
|
+
kind,
|
|
58963
|
+
current: currentState
|
|
58964
|
+
};
|
|
58965
|
+
}
|
|
58966
|
+
const new_avg_values = determine_average_entry_and_size([
|
|
58967
|
+
{
|
|
58968
|
+
price: position2.entry,
|
|
58969
|
+
quantity: position2.quantity
|
|
58970
|
+
},
|
|
58971
|
+
{
|
|
58972
|
+
price: summary?.entry,
|
|
58973
|
+
quantity: summary?.quantity
|
|
58974
|
+
}
|
|
58975
|
+
], symbol_config.decimal_places, symbol_config.price_places);
|
|
58976
|
+
summary.entry = new_avg_values.entry;
|
|
58977
|
+
summary.quantity = new_avg_values.quantity;
|
|
58978
|
+
const loss = Math.abs(summary.entry - custom_b_config.stop) * summary.quantity;
|
|
58979
|
+
const entryDetails = {
|
|
58980
|
+
entry: to_f(custom_b_config.entry, symbol_config.price_places),
|
|
58981
|
+
stop: to_f(custom_b_config.stop, symbol_config.price_places),
|
|
58982
|
+
risk: to_f(result.risk, symbol_config.price_places),
|
|
58983
|
+
risk_reward: result.risk_reward,
|
|
58984
|
+
avg_entry: to_f(summary.entry, symbol_config.price_places),
|
|
58985
|
+
avg_size: to_f(summary.quantity, symbol_config.decimal_places),
|
|
58986
|
+
first_entry: to_f(summary.first_entry, symbol_config.price_places),
|
|
58987
|
+
pnl: to_f(custom_b_config.risk, "%.2f"),
|
|
58988
|
+
fee: to_f(summary.fee, "%.2f"),
|
|
58989
|
+
loss: to_f(loss, "%.2f"),
|
|
58990
|
+
last_entry: to_f(summary.last_entry, symbol_config.price_places),
|
|
58991
|
+
margin: to_f(summary.entry * summary.quantity / global_config.leverage, "%.2f")
|
|
58992
|
+
};
|
|
58993
|
+
return {
|
|
58994
|
+
trades,
|
|
58995
|
+
summary: entryDetails,
|
|
58996
|
+
stop_order: {
|
|
58997
|
+
quantity: entryDetails.avg_size * stop_ratio,
|
|
58998
|
+
price: entryDetails.stop
|
|
58999
|
+
},
|
|
59000
|
+
config: {
|
|
59001
|
+
...custom_b_config,
|
|
59002
|
+
...result
|
|
59003
|
+
},
|
|
59004
|
+
kind,
|
|
59005
|
+
current: currentState
|
|
59006
|
+
};
|
|
59007
|
+
}
|
|
59008
|
+
function generatePositionIncreaseTrade({
|
|
59009
|
+
account,
|
|
59010
|
+
zoneAccount,
|
|
59011
|
+
ratio = 0.1,
|
|
59012
|
+
config: config2,
|
|
59013
|
+
global_config,
|
|
59014
|
+
style = "minimum",
|
|
59015
|
+
distribution = "inverse-exponential"
|
|
59016
|
+
}) {
|
|
59017
|
+
const kind = config2.entry > config2.stop ? "long" : "short";
|
|
59018
|
+
const target_max_quantity = kind === "long" ? account.short.quantity : account.long.quantity;
|
|
59019
|
+
const increase_qty = target_max_quantity * ratio;
|
|
59020
|
+
const entry = zoneAccount.entry;
|
|
59021
|
+
const stop = zoneAccount.stop;
|
|
59022
|
+
return increaseTradeHelper({
|
|
59023
|
+
config: config2,
|
|
59024
|
+
position: account[kind],
|
|
59025
|
+
global_config,
|
|
59026
|
+
entry,
|
|
59027
|
+
stop,
|
|
59028
|
+
style,
|
|
59029
|
+
increase_qty,
|
|
59030
|
+
distribution
|
|
59031
|
+
});
|
|
59032
|
+
}
|
|
59033
|
+
var compoundAPI = {
|
|
59034
|
+
buildWithOptimumReward,
|
|
59035
|
+
constructAppConfig: constructAppConfig2,
|
|
59036
|
+
generateOppositeOptimum,
|
|
59037
|
+
increaseTradeHelper,
|
|
59038
|
+
generatePositionIncreaseTrade
|
|
59039
|
+
};
|
|
58627
59040
|
// src/types/index.ts
|
|
58628
59041
|
class BaseExchange {
|
|
58629
59042
|
client;
|