@gbozee/ultimate 0.0.2-57 → 0.0.2-60
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 +42 -1
- package/dist/frontend-index.js +75 -7
- package/dist/index.cjs +1662 -1492
- package/dist/index.d.ts +137 -69
- package/dist/index.js +1662 -1492
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -16426,8 +16426,8 @@ var require_combined_stream = __commonJS((exports, module) => {
|
|
|
16426
16426
|
stream2.pipe(this, { end: false });
|
|
16427
16427
|
return;
|
|
16428
16428
|
}
|
|
16429
|
-
var
|
|
16430
|
-
this.write(
|
|
16429
|
+
var value2 = stream2;
|
|
16430
|
+
this.write(value2);
|
|
16431
16431
|
this._getNext();
|
|
16432
16432
|
};
|
|
16433
16433
|
CombinedStream.prototype._handleErrors = function(stream2) {
|
|
@@ -25640,8 +25640,8 @@ var require_get = __commonJS((exports, module) => {
|
|
|
25640
25640
|
var desc = !!hasProtoAccessor && gOPD && gOPD(Object.prototype, "__proto__");
|
|
25641
25641
|
var $Object = Object;
|
|
25642
25642
|
var $getPrototypeOf = $Object.getPrototypeOf;
|
|
25643
|
-
module.exports = desc && typeof desc.get === "function" ? callBind([desc.get]) : typeof $getPrototypeOf === "function" ? function getDunder(
|
|
25644
|
-
return $getPrototypeOf(
|
|
25643
|
+
module.exports = desc && typeof desc.get === "function" ? callBind([desc.get]) : typeof $getPrototypeOf === "function" ? function getDunder(value2) {
|
|
25644
|
+
return $getPrototypeOf(value2 == null ? value2 : $Object(value2));
|
|
25645
25645
|
} : false;
|
|
25646
25646
|
});
|
|
25647
25647
|
|
|
@@ -25813,26 +25813,26 @@ var require_get_intrinsic = __commonJS((exports, module) => {
|
|
|
25813
25813
|
}
|
|
25814
25814
|
var errorProto;
|
|
25815
25815
|
var doEval = function doEval(name2) {
|
|
25816
|
-
var
|
|
25816
|
+
var value2;
|
|
25817
25817
|
if (name2 === "%AsyncFunction%") {
|
|
25818
|
-
|
|
25818
|
+
value2 = getEvalledConstructor("async function () {}");
|
|
25819
25819
|
} else if (name2 === "%GeneratorFunction%") {
|
|
25820
|
-
|
|
25820
|
+
value2 = getEvalledConstructor("function* () {}");
|
|
25821
25821
|
} else if (name2 === "%AsyncGeneratorFunction%") {
|
|
25822
|
-
|
|
25822
|
+
value2 = getEvalledConstructor("async function* () {}");
|
|
25823
25823
|
} else if (name2 === "%AsyncGenerator%") {
|
|
25824
25824
|
var fn = doEval("%AsyncGeneratorFunction%");
|
|
25825
25825
|
if (fn) {
|
|
25826
|
-
|
|
25826
|
+
value2 = fn.prototype;
|
|
25827
25827
|
}
|
|
25828
25828
|
} else if (name2 === "%AsyncIteratorPrototype%") {
|
|
25829
25829
|
var gen = doEval("%AsyncGenerator%");
|
|
25830
25830
|
if (gen && getProto) {
|
|
25831
|
-
|
|
25831
|
+
value2 = getProto(gen.prototype);
|
|
25832
25832
|
}
|
|
25833
25833
|
}
|
|
25834
|
-
INTRINSICS[name2] =
|
|
25835
|
-
return
|
|
25834
|
+
INTRINSICS[name2] = value2;
|
|
25835
|
+
return value2;
|
|
25836
25836
|
};
|
|
25837
25837
|
var LEGACY_ALIASES = {
|
|
25838
25838
|
__proto__: null,
|
|
@@ -25919,17 +25919,17 @@ var require_get_intrinsic = __commonJS((exports, module) => {
|
|
|
25919
25919
|
intrinsicName = "%" + alias[0] + "%";
|
|
25920
25920
|
}
|
|
25921
25921
|
if (hasOwn(INTRINSICS, intrinsicName)) {
|
|
25922
|
-
var
|
|
25923
|
-
if (
|
|
25924
|
-
|
|
25922
|
+
var value2 = INTRINSICS[intrinsicName];
|
|
25923
|
+
if (value2 === needsEval) {
|
|
25924
|
+
value2 = doEval(intrinsicName);
|
|
25925
25925
|
}
|
|
25926
|
-
if (typeof
|
|
25926
|
+
if (typeof value2 === "undefined" && !allowMissing) {
|
|
25927
25927
|
throw new $TypeError("intrinsic " + name2 + " exists, but is not available. Please file an issue!");
|
|
25928
25928
|
}
|
|
25929
25929
|
return {
|
|
25930
25930
|
alias,
|
|
25931
25931
|
name: intrinsicName,
|
|
25932
|
-
value
|
|
25932
|
+
value: value2
|
|
25933
25933
|
};
|
|
25934
25934
|
}
|
|
25935
25935
|
throw new $SyntaxError("intrinsic " + name2 + " does not exist!");
|
|
@@ -25948,7 +25948,7 @@ var require_get_intrinsic = __commonJS((exports, module) => {
|
|
|
25948
25948
|
var intrinsicBaseName = parts.length > 0 ? parts[0] : "";
|
|
25949
25949
|
var intrinsic = getBaseIntrinsic("%" + intrinsicBaseName + "%", allowMissing);
|
|
25950
25950
|
var intrinsicRealName = intrinsic.name;
|
|
25951
|
-
var
|
|
25951
|
+
var value2 = intrinsic.value;
|
|
25952
25952
|
var skipFurtherCaching = false;
|
|
25953
25953
|
var alias = intrinsic.alias;
|
|
25954
25954
|
if (alias) {
|
|
@@ -25968,32 +25968,32 @@ var require_get_intrinsic = __commonJS((exports, module) => {
|
|
|
25968
25968
|
intrinsicBaseName += "." + part;
|
|
25969
25969
|
intrinsicRealName = "%" + intrinsicBaseName + "%";
|
|
25970
25970
|
if (hasOwn(INTRINSICS, intrinsicRealName)) {
|
|
25971
|
-
|
|
25972
|
-
} else if (
|
|
25973
|
-
if (!(part in
|
|
25971
|
+
value2 = INTRINSICS[intrinsicRealName];
|
|
25972
|
+
} else if (value2 != null) {
|
|
25973
|
+
if (!(part in value2)) {
|
|
25974
25974
|
if (!allowMissing) {
|
|
25975
25975
|
throw new $TypeError("base intrinsic for " + name2 + " exists, but the property is not available.");
|
|
25976
25976
|
}
|
|
25977
25977
|
return;
|
|
25978
25978
|
}
|
|
25979
25979
|
if ($gOPD && i2 + 1 >= parts.length) {
|
|
25980
|
-
var desc = $gOPD(
|
|
25980
|
+
var desc = $gOPD(value2, part);
|
|
25981
25981
|
isOwn = !!desc;
|
|
25982
25982
|
if (isOwn && "get" in desc && !("originalValue" in desc.get)) {
|
|
25983
|
-
|
|
25983
|
+
value2 = desc.get;
|
|
25984
25984
|
} else {
|
|
25985
|
-
|
|
25985
|
+
value2 = value2[part];
|
|
25986
25986
|
}
|
|
25987
25987
|
} else {
|
|
25988
|
-
isOwn = hasOwn(
|
|
25989
|
-
|
|
25988
|
+
isOwn = hasOwn(value2, part);
|
|
25989
|
+
value2 = value2[part];
|
|
25990
25990
|
}
|
|
25991
25991
|
if (isOwn && !skipFurtherCaching) {
|
|
25992
|
-
INTRINSICS[intrinsicRealName] =
|
|
25992
|
+
INTRINSICS[intrinsicRealName] = value2;
|
|
25993
25993
|
}
|
|
25994
25994
|
}
|
|
25995
25995
|
}
|
|
25996
|
-
return
|
|
25996
|
+
return value2;
|
|
25997
25997
|
};
|
|
25998
25998
|
});
|
|
25999
25999
|
|
|
@@ -26013,7 +26013,7 @@ var require_es_set_tostringtag = __commonJS((exports, module) => {
|
|
|
26013
26013
|
var hasOwn = require_hasown();
|
|
26014
26014
|
var $TypeError = require_type();
|
|
26015
26015
|
var toStringTag = hasToStringTag ? Symbol.toStringTag : null;
|
|
26016
|
-
module.exports = function setToStringTag(object,
|
|
26016
|
+
module.exports = function setToStringTag(object, value2) {
|
|
26017
26017
|
var overrideIfSet = arguments.length > 2 && !!arguments[2] && arguments[2].force;
|
|
26018
26018
|
var nonConfigurable = arguments.length > 2 && !!arguments[2] && arguments[2].nonConfigurable;
|
|
26019
26019
|
if (typeof overrideIfSet !== "undefined" && typeof overrideIfSet !== "boolean" || typeof nonConfigurable !== "undefined" && typeof nonConfigurable !== "boolean") {
|
|
@@ -26024,11 +26024,11 @@ var require_es_set_tostringtag = __commonJS((exports, module) => {
|
|
|
26024
26024
|
$defineProperty(object, toStringTag, {
|
|
26025
26025
|
configurable: !nonConfigurable,
|
|
26026
26026
|
enumerable: false,
|
|
26027
|
-
value,
|
|
26027
|
+
value: value2,
|
|
26028
26028
|
writable: false
|
|
26029
26029
|
});
|
|
26030
26030
|
} else {
|
|
26031
|
-
object[toStringTag] =
|
|
26031
|
+
object[toStringTag] = value2;
|
|
26032
26032
|
}
|
|
26033
26033
|
}
|
|
26034
26034
|
};
|
|
@@ -26076,77 +26076,77 @@ var require_form_data = __commonJS((exports, module) => {
|
|
|
26076
26076
|
FormData2.LINE_BREAK = `\r
|
|
26077
26077
|
`;
|
|
26078
26078
|
FormData2.DEFAULT_CONTENT_TYPE = "application/octet-stream";
|
|
26079
|
-
FormData2.prototype.append = function(field,
|
|
26079
|
+
FormData2.prototype.append = function(field, value2, options) {
|
|
26080
26080
|
options = options || {};
|
|
26081
26081
|
if (typeof options == "string") {
|
|
26082
26082
|
options = { filename: options };
|
|
26083
26083
|
}
|
|
26084
26084
|
var append = CombinedStream.prototype.append.bind(this);
|
|
26085
|
-
if (typeof
|
|
26086
|
-
|
|
26085
|
+
if (typeof value2 == "number") {
|
|
26086
|
+
value2 = "" + value2;
|
|
26087
26087
|
}
|
|
26088
|
-
if (Array.isArray(
|
|
26088
|
+
if (Array.isArray(value2)) {
|
|
26089
26089
|
this._error(new Error("Arrays are not supported."));
|
|
26090
26090
|
return;
|
|
26091
26091
|
}
|
|
26092
|
-
var header = this._multiPartHeader(field,
|
|
26092
|
+
var header = this._multiPartHeader(field, value2, options);
|
|
26093
26093
|
var footer = this._multiPartFooter();
|
|
26094
26094
|
append(header);
|
|
26095
|
-
append(
|
|
26095
|
+
append(value2);
|
|
26096
26096
|
append(footer);
|
|
26097
|
-
this._trackLength(header,
|
|
26097
|
+
this._trackLength(header, value2, options);
|
|
26098
26098
|
};
|
|
26099
|
-
FormData2.prototype._trackLength = function(header,
|
|
26099
|
+
FormData2.prototype._trackLength = function(header, value2, options) {
|
|
26100
26100
|
var valueLength = 0;
|
|
26101
26101
|
if (options.knownLength != null) {
|
|
26102
26102
|
valueLength += +options.knownLength;
|
|
26103
|
-
} else if (Buffer.isBuffer(
|
|
26104
|
-
valueLength =
|
|
26105
|
-
} else if (typeof
|
|
26106
|
-
valueLength = Buffer.byteLength(
|
|
26103
|
+
} else if (Buffer.isBuffer(value2)) {
|
|
26104
|
+
valueLength = value2.length;
|
|
26105
|
+
} else if (typeof value2 === "string") {
|
|
26106
|
+
valueLength = Buffer.byteLength(value2);
|
|
26107
26107
|
}
|
|
26108
26108
|
this._valueLength += valueLength;
|
|
26109
26109
|
this._overheadLength += Buffer.byteLength(header) + FormData2.LINE_BREAK.length;
|
|
26110
|
-
if (!
|
|
26110
|
+
if (!value2 || !value2.path && !(value2.readable && Object.prototype.hasOwnProperty.call(value2, "httpVersion")) && !(value2 instanceof Stream)) {
|
|
26111
26111
|
return;
|
|
26112
26112
|
}
|
|
26113
26113
|
if (!options.knownLength) {
|
|
26114
|
-
this._valuesToMeasure.push(
|
|
26114
|
+
this._valuesToMeasure.push(value2);
|
|
26115
26115
|
}
|
|
26116
26116
|
};
|
|
26117
|
-
FormData2.prototype._lengthRetriever = function(
|
|
26118
|
-
if (Object.prototype.hasOwnProperty.call(
|
|
26119
|
-
if (
|
|
26120
|
-
callback(null,
|
|
26117
|
+
FormData2.prototype._lengthRetriever = function(value2, callback) {
|
|
26118
|
+
if (Object.prototype.hasOwnProperty.call(value2, "fd")) {
|
|
26119
|
+
if (value2.end != null && value2.end != Infinity && value2.start != null) {
|
|
26120
|
+
callback(null, value2.end + 1 - (value2.start ? value2.start : 0));
|
|
26121
26121
|
} else {
|
|
26122
|
-
fs.stat(
|
|
26122
|
+
fs.stat(value2.path, function(err, stat) {
|
|
26123
26123
|
var fileSize;
|
|
26124
26124
|
if (err) {
|
|
26125
26125
|
callback(err);
|
|
26126
26126
|
return;
|
|
26127
26127
|
}
|
|
26128
|
-
fileSize = stat.size - (
|
|
26128
|
+
fileSize = stat.size - (value2.start ? value2.start : 0);
|
|
26129
26129
|
callback(null, fileSize);
|
|
26130
26130
|
});
|
|
26131
26131
|
}
|
|
26132
|
-
} else if (Object.prototype.hasOwnProperty.call(
|
|
26133
|
-
callback(null, +
|
|
26134
|
-
} else if (Object.prototype.hasOwnProperty.call(
|
|
26135
|
-
|
|
26136
|
-
|
|
26132
|
+
} else if (Object.prototype.hasOwnProperty.call(value2, "httpVersion")) {
|
|
26133
|
+
callback(null, +value2.headers["content-length"]);
|
|
26134
|
+
} else if (Object.prototype.hasOwnProperty.call(value2, "httpModule")) {
|
|
26135
|
+
value2.on("response", function(response) {
|
|
26136
|
+
value2.pause();
|
|
26137
26137
|
callback(null, +response.headers["content-length"]);
|
|
26138
26138
|
});
|
|
26139
|
-
|
|
26139
|
+
value2.resume();
|
|
26140
26140
|
} else {
|
|
26141
26141
|
callback("Unknown stream");
|
|
26142
26142
|
}
|
|
26143
26143
|
};
|
|
26144
|
-
FormData2.prototype._multiPartHeader = function(field,
|
|
26144
|
+
FormData2.prototype._multiPartHeader = function(field, value2, options) {
|
|
26145
26145
|
if (typeof options.header == "string") {
|
|
26146
26146
|
return options.header;
|
|
26147
26147
|
}
|
|
26148
|
-
var contentDisposition = this._getContentDisposition(
|
|
26149
|
-
var contentType = this._getContentType(
|
|
26148
|
+
var contentDisposition = this._getContentDisposition(value2, options);
|
|
26149
|
+
var contentType = this._getContentType(value2, options);
|
|
26150
26150
|
var contents = "";
|
|
26151
26151
|
var headers = {
|
|
26152
26152
|
"Content-Disposition": ["form-data", 'name="' + field + '"'].concat(contentDisposition || []),
|
|
@@ -26172,35 +26172,35 @@ var require_form_data = __commonJS((exports, module) => {
|
|
|
26172
26172
|
}
|
|
26173
26173
|
return "--" + this.getBoundary() + FormData2.LINE_BREAK + contents + FormData2.LINE_BREAK;
|
|
26174
26174
|
};
|
|
26175
|
-
FormData2.prototype._getContentDisposition = function(
|
|
26175
|
+
FormData2.prototype._getContentDisposition = function(value2, options) {
|
|
26176
26176
|
var filename, contentDisposition;
|
|
26177
26177
|
if (typeof options.filepath === "string") {
|
|
26178
26178
|
filename = path.normalize(options.filepath).replace(/\\/g, "/");
|
|
26179
|
-
} else if (options.filename ||
|
|
26180
|
-
filename = path.basename(options.filename ||
|
|
26181
|
-
} else if (
|
|
26182
|
-
filename = path.basename(
|
|
26179
|
+
} else if (options.filename || value2.name || value2.path) {
|
|
26180
|
+
filename = path.basename(options.filename || value2.name || value2.path);
|
|
26181
|
+
} else if (value2.readable && Object.prototype.hasOwnProperty.call(value2, "httpVersion")) {
|
|
26182
|
+
filename = path.basename(value2.client._httpMessage.path || "");
|
|
26183
26183
|
}
|
|
26184
26184
|
if (filename) {
|
|
26185
26185
|
contentDisposition = 'filename="' + filename + '"';
|
|
26186
26186
|
}
|
|
26187
26187
|
return contentDisposition;
|
|
26188
26188
|
};
|
|
26189
|
-
FormData2.prototype._getContentType = function(
|
|
26189
|
+
FormData2.prototype._getContentType = function(value2, options) {
|
|
26190
26190
|
var contentType = options.contentType;
|
|
26191
|
-
if (!contentType &&
|
|
26192
|
-
contentType = mime.lookup(
|
|
26191
|
+
if (!contentType && value2.name) {
|
|
26192
|
+
contentType = mime.lookup(value2.name);
|
|
26193
26193
|
}
|
|
26194
|
-
if (!contentType &&
|
|
26195
|
-
contentType = mime.lookup(
|
|
26194
|
+
if (!contentType && value2.path) {
|
|
26195
|
+
contentType = mime.lookup(value2.path);
|
|
26196
26196
|
}
|
|
26197
|
-
if (!contentType &&
|
|
26198
|
-
contentType =
|
|
26197
|
+
if (!contentType && value2.readable && Object.prototype.hasOwnProperty.call(value2, "httpVersion")) {
|
|
26198
|
+
contentType = value2.headers["content-type"];
|
|
26199
26199
|
}
|
|
26200
26200
|
if (!contentType && (options.filepath || options.filename)) {
|
|
26201
26201
|
contentType = mime.lookup(options.filepath || options.filename);
|
|
26202
26202
|
}
|
|
26203
|
-
if (!contentType && typeof
|
|
26203
|
+
if (!contentType && typeof value2 == "object") {
|
|
26204
26204
|
contentType = FormData2.DEFAULT_CONTENT_TYPE;
|
|
26205
26205
|
}
|
|
26206
26206
|
return contentType;
|
|
@@ -26573,9 +26573,9 @@ var require_follow_redirects = __commonJS((exports, module) => {
|
|
|
26573
26573
|
this._ending = true;
|
|
26574
26574
|
}
|
|
26575
26575
|
};
|
|
26576
|
-
RedirectableRequest.prototype.setHeader = function(name2,
|
|
26577
|
-
this._options.headers[name2] =
|
|
26578
|
-
this._currentRequest.setHeader(name2,
|
|
26576
|
+
RedirectableRequest.prototype.setHeader = function(name2, value2) {
|
|
26577
|
+
this._options.headers[name2] = value2;
|
|
26578
|
+
this._currentRequest.setHeader(name2, value2);
|
|
26579
26579
|
};
|
|
26580
26580
|
RedirectableRequest.prototype.removeHeader = function(name2) {
|
|
26581
26581
|
delete this._options.headers[name2];
|
|
@@ -26895,17 +26895,17 @@ var require_follow_redirects = __commonJS((exports, module) => {
|
|
|
26895
26895
|
var dot = subdomain.length - domain.length - 1;
|
|
26896
26896
|
return dot > 0 && subdomain[dot] === "." && subdomain.endsWith(domain);
|
|
26897
26897
|
}
|
|
26898
|
-
function isString2(
|
|
26899
|
-
return typeof
|
|
26898
|
+
function isString2(value2) {
|
|
26899
|
+
return typeof value2 === "string" || value2 instanceof String;
|
|
26900
26900
|
}
|
|
26901
|
-
function isFunction(
|
|
26902
|
-
return typeof
|
|
26901
|
+
function isFunction(value2) {
|
|
26902
|
+
return typeof value2 === "function";
|
|
26903
26903
|
}
|
|
26904
|
-
function isBuffer(
|
|
26905
|
-
return typeof
|
|
26904
|
+
function isBuffer(value2) {
|
|
26905
|
+
return typeof value2 === "object" && "length" in value2;
|
|
26906
26906
|
}
|
|
26907
|
-
function isURL2(
|
|
26908
|
-
return URL2 &&
|
|
26907
|
+
function isURL2(value2) {
|
|
26908
|
+
return URL2 && value2 instanceof URL2;
|
|
26909
26909
|
}
|
|
26910
26910
|
module.exports = wrap3({ http: http2, https: https2 });
|
|
26911
26911
|
module.exports.wrap = wrap3;
|
|
@@ -27101,14 +27101,14 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
27101
27101
|
} while (sourceObj && (!filter || filter(sourceObj, destObj)) && sourceObj !== Object.prototype);
|
|
27102
27102
|
return destObj;
|
|
27103
27103
|
};
|
|
27104
|
-
var endsWith = (str, searchString,
|
|
27104
|
+
var endsWith = (str, searchString, position2) => {
|
|
27105
27105
|
str = String(str);
|
|
27106
|
-
if (
|
|
27107
|
-
|
|
27106
|
+
if (position2 === undefined || position2 > str.length) {
|
|
27107
|
+
position2 = str.length;
|
|
27108
27108
|
}
|
|
27109
|
-
|
|
27110
|
-
const lastIndex = str.indexOf(searchString,
|
|
27111
|
-
return lastIndex !== -1 && lastIndex ===
|
|
27109
|
+
position2 -= searchString.length;
|
|
27110
|
+
const lastIndex = str.indexOf(searchString, position2);
|
|
27111
|
+
return lastIndex !== -1 && lastIndex === position2;
|
|
27112
27112
|
};
|
|
27113
27113
|
var toArray = (thing) => {
|
|
27114
27114
|
if (!thing)
|
|
@@ -27170,8 +27170,8 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
27170
27170
|
if (isFunction(obj) && ["arguments", "caller", "callee"].indexOf(name2) !== -1) {
|
|
27171
27171
|
return false;
|
|
27172
27172
|
}
|
|
27173
|
-
const
|
|
27174
|
-
if (!isFunction(
|
|
27173
|
+
const value2 = obj[name2];
|
|
27174
|
+
if (!isFunction(value2))
|
|
27175
27175
|
return;
|
|
27176
27176
|
descriptor.enumerable = false;
|
|
27177
27177
|
if ("writable" in descriptor) {
|
|
@@ -27188,8 +27188,8 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
27188
27188
|
var toObjectSet = (arrayOrString, delimiter) => {
|
|
27189
27189
|
const obj = {};
|
|
27190
27190
|
const define2 = (arr) => {
|
|
27191
|
-
arr.forEach((
|
|
27192
|
-
obj[
|
|
27191
|
+
arr.forEach((value2) => {
|
|
27192
|
+
obj[value2] = true;
|
|
27193
27193
|
});
|
|
27194
27194
|
};
|
|
27195
27195
|
isArray3(arrayOrString) ? define2(arrayOrString) : define2(String(arrayOrString).split(delimiter));
|
|
@@ -27197,8 +27197,8 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
27197
27197
|
};
|
|
27198
27198
|
var noop2 = () => {
|
|
27199
27199
|
};
|
|
27200
|
-
var toFiniteNumber = (
|
|
27201
|
-
return
|
|
27200
|
+
var toFiniteNumber = (value2, defaultValue) => {
|
|
27201
|
+
return value2 != null && Number.isFinite(value2 = +value2) ? value2 : defaultValue;
|
|
27202
27202
|
};
|
|
27203
27203
|
function isSpecCompliantForm(thing) {
|
|
27204
27204
|
return !!(thing && isFunction(thing.append) && thing[Symbol.toStringTag] === "FormData" && thing[Symbol.iterator]);
|
|
@@ -27213,8 +27213,8 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
27213
27213
|
if (!("toJSON" in source)) {
|
|
27214
27214
|
stack[i2] = source;
|
|
27215
27215
|
const target = isArray3(source) ? [] : {};
|
|
27216
|
-
forEach2(source, (
|
|
27217
|
-
const reducedValue = visit(
|
|
27216
|
+
forEach2(source, (value2, key) => {
|
|
27217
|
+
const reducedValue = visit(value2, i2 + 1);
|
|
27218
27218
|
!isUndefined3(reducedValue) && (target[key] = reducedValue);
|
|
27219
27219
|
});
|
|
27220
27220
|
stack[i2] = undefined;
|
|
@@ -27409,27 +27409,27 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
27409
27409
|
if (!utils$1.isFunction(visitor)) {
|
|
27410
27410
|
throw new TypeError("visitor must be a function");
|
|
27411
27411
|
}
|
|
27412
|
-
function convertValue(
|
|
27413
|
-
if (
|
|
27412
|
+
function convertValue(value2) {
|
|
27413
|
+
if (value2 === null)
|
|
27414
27414
|
return "";
|
|
27415
|
-
if (utils$1.isDate(
|
|
27416
|
-
return
|
|
27415
|
+
if (utils$1.isDate(value2)) {
|
|
27416
|
+
return value2.toISOString();
|
|
27417
27417
|
}
|
|
27418
|
-
if (!useBlob && utils$1.isBlob(
|
|
27418
|
+
if (!useBlob && utils$1.isBlob(value2)) {
|
|
27419
27419
|
throw new AxiosError("Blob is not supported. Use a Buffer instead.");
|
|
27420
27420
|
}
|
|
27421
|
-
if (utils$1.isArrayBuffer(
|
|
27422
|
-
return useBlob && typeof Blob === "function" ? new Blob([
|
|
27421
|
+
if (utils$1.isArrayBuffer(value2) || utils$1.isTypedArray(value2)) {
|
|
27422
|
+
return useBlob && typeof Blob === "function" ? new Blob([value2]) : Buffer.from(value2);
|
|
27423
27423
|
}
|
|
27424
|
-
return
|
|
27424
|
+
return value2;
|
|
27425
27425
|
}
|
|
27426
|
-
function defaultVisitor(
|
|
27427
|
-
let arr =
|
|
27428
|
-
if (
|
|
27426
|
+
function defaultVisitor(value2, key, path) {
|
|
27427
|
+
let arr = value2;
|
|
27428
|
+
if (value2 && !path && typeof value2 === "object") {
|
|
27429
27429
|
if (utils$1.endsWith(key, "{}")) {
|
|
27430
27430
|
key = metaTokens ? key : key.slice(0, -2);
|
|
27431
|
-
|
|
27432
|
-
} else if (utils$1.isArray(
|
|
27431
|
+
value2 = JSON.stringify(value2);
|
|
27432
|
+
} else if (utils$1.isArray(value2) && isFlatArray(value2) || (utils$1.isFileList(value2) || utils$1.endsWith(key, "[]")) && (arr = utils$1.toArray(value2))) {
|
|
27433
27433
|
key = removeBrackets(key);
|
|
27434
27434
|
arr.forEach(function each(el, index) {
|
|
27435
27435
|
!(utils$1.isUndefined(el) || el === null) && formData.append(indexes === true ? renderKey([key], index, dots) : indexes === null ? key : key + "[]", convertValue(el));
|
|
@@ -27437,10 +27437,10 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
27437
27437
|
return false;
|
|
27438
27438
|
}
|
|
27439
27439
|
}
|
|
27440
|
-
if (isVisitable(
|
|
27440
|
+
if (isVisitable(value2)) {
|
|
27441
27441
|
return true;
|
|
27442
27442
|
}
|
|
27443
|
-
formData.append(renderKey(path, key, dots), convertValue(
|
|
27443
|
+
formData.append(renderKey(path, key, dots), convertValue(value2));
|
|
27444
27444
|
return false;
|
|
27445
27445
|
}
|
|
27446
27446
|
const stack = [];
|
|
@@ -27449,14 +27449,14 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
27449
27449
|
convertValue,
|
|
27450
27450
|
isVisitable
|
|
27451
27451
|
});
|
|
27452
|
-
function build(
|
|
27453
|
-
if (utils$1.isUndefined(
|
|
27452
|
+
function build(value2, path) {
|
|
27453
|
+
if (utils$1.isUndefined(value2))
|
|
27454
27454
|
return;
|
|
27455
|
-
if (stack.indexOf(
|
|
27455
|
+
if (stack.indexOf(value2) !== -1) {
|
|
27456
27456
|
throw Error("Circular reference detected in " + path.join("."));
|
|
27457
27457
|
}
|
|
27458
|
-
stack.push(
|
|
27459
|
-
utils$1.forEach(
|
|
27458
|
+
stack.push(value2);
|
|
27459
|
+
utils$1.forEach(value2, function each(el, key) {
|
|
27460
27460
|
const result = !(utils$1.isUndefined(el) || el === null) && visitor.call(formData, el, utils$1.isString(key) ? key.trim() : key, path, exposedHelpers);
|
|
27461
27461
|
if (result === true) {
|
|
27462
27462
|
build(el, path ? path.concat(key) : [key]);
|
|
@@ -27489,12 +27489,12 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
27489
27489
|
params && toFormData(params, this, options);
|
|
27490
27490
|
}
|
|
27491
27491
|
var prototype = AxiosURLSearchParams.prototype;
|
|
27492
|
-
prototype.append = function append(name2,
|
|
27493
|
-
this._pairs.push([name2,
|
|
27492
|
+
prototype.append = function append(name2, value2) {
|
|
27493
|
+
this._pairs.push([name2, value2]);
|
|
27494
27494
|
};
|
|
27495
27495
|
prototype.toString = function toString(encoder2) {
|
|
27496
|
-
const _encode = encoder2 ? function(
|
|
27497
|
-
return encoder2.call(this,
|
|
27496
|
+
const _encode = encoder2 ? function(value2) {
|
|
27497
|
+
return encoder2.call(this, value2, encode$1);
|
|
27498
27498
|
} : encode$1;
|
|
27499
27499
|
return this._pairs.map(function each(pair) {
|
|
27500
27500
|
return _encode(pair[0]) + "=" + _encode(pair[1]);
|
|
@@ -27617,9 +27617,9 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
27617
27617
|
};
|
|
27618
27618
|
function toURLEncodedForm(data, options) {
|
|
27619
27619
|
return toFormData(data, new platform.classes.URLSearchParams, Object.assign({
|
|
27620
|
-
visitor: function(
|
|
27621
|
-
if (platform.isNode && utils$1.isBuffer(
|
|
27622
|
-
this.append(key,
|
|
27620
|
+
visitor: function(value2, key, path, helpers) {
|
|
27621
|
+
if (platform.isNode && utils$1.isBuffer(value2)) {
|
|
27622
|
+
this.append(key, value2.toString("base64"));
|
|
27623
27623
|
return false;
|
|
27624
27624
|
}
|
|
27625
27625
|
return helpers.defaultVisitor.apply(this, arguments);
|
|
@@ -27644,7 +27644,7 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
27644
27644
|
return obj;
|
|
27645
27645
|
}
|
|
27646
27646
|
function formDataToJSON(formData) {
|
|
27647
|
-
function buildPath(path,
|
|
27647
|
+
function buildPath(path, value2, target, index) {
|
|
27648
27648
|
let name2 = path[index++];
|
|
27649
27649
|
if (name2 === "__proto__")
|
|
27650
27650
|
return true;
|
|
@@ -27653,16 +27653,16 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
27653
27653
|
name2 = !name2 && utils$1.isArray(target) ? target.length : name2;
|
|
27654
27654
|
if (isLast) {
|
|
27655
27655
|
if (utils$1.hasOwnProp(target, name2)) {
|
|
27656
|
-
target[name2] = [target[name2],
|
|
27656
|
+
target[name2] = [target[name2], value2];
|
|
27657
27657
|
} else {
|
|
27658
|
-
target[name2] =
|
|
27658
|
+
target[name2] = value2;
|
|
27659
27659
|
}
|
|
27660
27660
|
return !isNumericKey;
|
|
27661
27661
|
}
|
|
27662
27662
|
if (!target[name2] || !utils$1.isObject(target[name2])) {
|
|
27663
27663
|
target[name2] = [];
|
|
27664
27664
|
}
|
|
27665
|
-
const result = buildPath(path,
|
|
27665
|
+
const result = buildPath(path, value2, target[name2], index);
|
|
27666
27666
|
if (result && utils$1.isArray(target[name2])) {
|
|
27667
27667
|
target[name2] = arrayToObject(target[name2]);
|
|
27668
27668
|
}
|
|
@@ -27670,8 +27670,8 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
27670
27670
|
}
|
|
27671
27671
|
if (utils$1.isFormData(formData) && utils$1.isFunction(formData.entries)) {
|
|
27672
27672
|
const obj = {};
|
|
27673
|
-
utils$1.forEachEntry(formData, (name2,
|
|
27674
|
-
buildPath(parsePropPath(name2),
|
|
27673
|
+
utils$1.forEachEntry(formData, (name2, value2) => {
|
|
27674
|
+
buildPath(parsePropPath(name2), value2, obj, 0);
|
|
27675
27675
|
});
|
|
27676
27676
|
return obj;
|
|
27677
27677
|
}
|
|
@@ -27824,11 +27824,11 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
27824
27824
|
function normalizeHeader(header) {
|
|
27825
27825
|
return header && String(header).trim().toLowerCase();
|
|
27826
27826
|
}
|
|
27827
|
-
function normalizeValue(
|
|
27828
|
-
if (
|
|
27829
|
-
return
|
|
27827
|
+
function normalizeValue(value2) {
|
|
27828
|
+
if (value2 === false || value2 == null) {
|
|
27829
|
+
return value2;
|
|
27830
27830
|
}
|
|
27831
|
-
return utils$1.isArray(
|
|
27831
|
+
return utils$1.isArray(value2) ? value2.map(normalizeValue) : String(value2);
|
|
27832
27832
|
}
|
|
27833
27833
|
function parseTokens(str) {
|
|
27834
27834
|
const tokens = Object.create(null);
|
|
@@ -27840,20 +27840,20 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
27840
27840
|
return tokens;
|
|
27841
27841
|
}
|
|
27842
27842
|
var isValidHeaderName = (str) => /^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(str.trim());
|
|
27843
|
-
function matchHeaderValue(context3,
|
|
27843
|
+
function matchHeaderValue(context3, value2, header, filter, isHeaderNameFilter) {
|
|
27844
27844
|
if (utils$1.isFunction(filter)) {
|
|
27845
|
-
return filter.call(this,
|
|
27845
|
+
return filter.call(this, value2, header);
|
|
27846
27846
|
}
|
|
27847
27847
|
if (isHeaderNameFilter) {
|
|
27848
|
-
|
|
27848
|
+
value2 = header;
|
|
27849
27849
|
}
|
|
27850
|
-
if (!utils$1.isString(
|
|
27850
|
+
if (!utils$1.isString(value2))
|
|
27851
27851
|
return;
|
|
27852
27852
|
if (utils$1.isString(filter)) {
|
|
27853
|
-
return
|
|
27853
|
+
return value2.indexOf(filter) !== -1;
|
|
27854
27854
|
}
|
|
27855
27855
|
if (utils$1.isRegExp(filter)) {
|
|
27856
|
-
return filter.test(
|
|
27856
|
+
return filter.test(value2);
|
|
27857
27857
|
}
|
|
27858
27858
|
}
|
|
27859
27859
|
function formatHeader(header) {
|
|
@@ -27895,8 +27895,8 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
27895
27895
|
} else if (utils$1.isString(header) && (header = header.trim()) && !isValidHeaderName(header)) {
|
|
27896
27896
|
setHeaders(parseHeaders(header), valueOrRewrite);
|
|
27897
27897
|
} else if (utils$1.isHeaders(header)) {
|
|
27898
|
-
for (const [key,
|
|
27899
|
-
setHeader(
|
|
27898
|
+
for (const [key, value2] of header.entries()) {
|
|
27899
|
+
setHeader(value2, key, rewrite);
|
|
27900
27900
|
}
|
|
27901
27901
|
} else {
|
|
27902
27902
|
header != null && setHeader(valueOrRewrite, header, rewrite);
|
|
@@ -27908,18 +27908,18 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
27908
27908
|
if (header) {
|
|
27909
27909
|
const key = utils$1.findKey(this, header);
|
|
27910
27910
|
if (key) {
|
|
27911
|
-
const
|
|
27911
|
+
const value2 = this[key];
|
|
27912
27912
|
if (!parser) {
|
|
27913
|
-
return
|
|
27913
|
+
return value2;
|
|
27914
27914
|
}
|
|
27915
27915
|
if (parser === true) {
|
|
27916
|
-
return parseTokens(
|
|
27916
|
+
return parseTokens(value2);
|
|
27917
27917
|
}
|
|
27918
27918
|
if (utils$1.isFunction(parser)) {
|
|
27919
|
-
return parser.call(this,
|
|
27919
|
+
return parser.call(this, value2, key);
|
|
27920
27920
|
}
|
|
27921
27921
|
if (utils$1.isRegExp(parser)) {
|
|
27922
|
-
return parser.exec(
|
|
27922
|
+
return parser.exec(value2);
|
|
27923
27923
|
}
|
|
27924
27924
|
throw new TypeError("parser must be boolean|regexp|function");
|
|
27925
27925
|
}
|
|
@@ -27969,10 +27969,10 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
27969
27969
|
normalize(format) {
|
|
27970
27970
|
const self2 = this;
|
|
27971
27971
|
const headers = {};
|
|
27972
|
-
utils$1.forEach(this, (
|
|
27972
|
+
utils$1.forEach(this, (value2, header) => {
|
|
27973
27973
|
const key = utils$1.findKey(headers, header);
|
|
27974
27974
|
if (key) {
|
|
27975
|
-
self2[key] = normalizeValue(
|
|
27975
|
+
self2[key] = normalizeValue(value2);
|
|
27976
27976
|
delete self2[header];
|
|
27977
27977
|
return;
|
|
27978
27978
|
}
|
|
@@ -27980,7 +27980,7 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
27980
27980
|
if (normalized !== header) {
|
|
27981
27981
|
delete self2[header];
|
|
27982
27982
|
}
|
|
27983
|
-
self2[normalized] = normalizeValue(
|
|
27983
|
+
self2[normalized] = normalizeValue(value2);
|
|
27984
27984
|
headers[normalized] = true;
|
|
27985
27985
|
});
|
|
27986
27986
|
return this;
|
|
@@ -27990,8 +27990,8 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
27990
27990
|
}
|
|
27991
27991
|
toJSON(asStrings) {
|
|
27992
27992
|
const obj = Object.create(null);
|
|
27993
|
-
utils$1.forEach(this, (
|
|
27994
|
-
|
|
27993
|
+
utils$1.forEach(this, (value2, header) => {
|
|
27994
|
+
value2 != null && value2 !== false && (obj[header] = asStrings && utils$1.isArray(value2) ? value2.join(", ") : value2);
|
|
27995
27995
|
});
|
|
27996
27996
|
return obj;
|
|
27997
27997
|
}
|
|
@@ -27999,7 +27999,7 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
27999
27999
|
return Object.entries(this.toJSON())[Symbol.iterator]();
|
|
28000
28000
|
}
|
|
28001
28001
|
toString() {
|
|
28002
|
-
return Object.entries(this.toJSON()).map(([header,
|
|
28002
|
+
return Object.entries(this.toJSON()).map(([header, value2]) => header + ": " + value2).join(`
|
|
28003
28003
|
`);
|
|
28004
28004
|
}
|
|
28005
28005
|
get [Symbol.toStringTag]() {
|
|
@@ -28031,10 +28031,10 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
28031
28031
|
}
|
|
28032
28032
|
}
|
|
28033
28033
|
AxiosHeaders.accessor(["Content-Type", "Content-Length", "Accept", "Accept-Encoding", "User-Agent", "Authorization"]);
|
|
28034
|
-
utils$1.reduceDescriptors(AxiosHeaders.prototype, ({ value }, key) => {
|
|
28034
|
+
utils$1.reduceDescriptors(AxiosHeaders.prototype, ({ value: value2 }, key) => {
|
|
28035
28035
|
let mapped = key[0].toUpperCase() + key.slice(1);
|
|
28036
28036
|
return {
|
|
28037
|
-
get: () =>
|
|
28037
|
+
get: () => value2,
|
|
28038
28038
|
set(headerValue) {
|
|
28039
28039
|
this[mapped] = headerValue;
|
|
28040
28040
|
}
|
|
@@ -28053,8 +28053,8 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
28053
28053
|
headers.normalize();
|
|
28054
28054
|
return data;
|
|
28055
28055
|
}
|
|
28056
|
-
function isCancel(
|
|
28057
|
-
return !!(
|
|
28056
|
+
function isCancel(value2) {
|
|
28057
|
+
return !!(value2 && value2.__CANCEL__);
|
|
28058
28058
|
}
|
|
28059
28059
|
function CanceledError(message2, config2, request) {
|
|
28060
28060
|
AxiosError.call(this, message2 == null ? "canceled" : message2, AxiosError.ERR_CANCELED, config2, request);
|
|
@@ -28250,28 +28250,28 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
28250
28250
|
var CRLF_BYTES_COUNT = 2;
|
|
28251
28251
|
|
|
28252
28252
|
class FormDataPart {
|
|
28253
|
-
constructor(name2,
|
|
28253
|
+
constructor(name2, value2) {
|
|
28254
28254
|
const { escapeName } = this.constructor;
|
|
28255
|
-
const isStringValue = utils$1.isString(
|
|
28256
|
-
let headers = `Content-Disposition: form-data; name="${escapeName(name2)}"${!isStringValue &&
|
|
28255
|
+
const isStringValue = utils$1.isString(value2);
|
|
28256
|
+
let headers = `Content-Disposition: form-data; name="${escapeName(name2)}"${!isStringValue && value2.name ? `; filename="${escapeName(value2.name)}"` : ""}${CRLF}`;
|
|
28257
28257
|
if (isStringValue) {
|
|
28258
|
-
|
|
28258
|
+
value2 = textEncoder.encode(String(value2).replace(/\r?\n|\r\n?/g, CRLF));
|
|
28259
28259
|
} else {
|
|
28260
|
-
headers += `Content-Type: ${
|
|
28260
|
+
headers += `Content-Type: ${value2.type || "application/octet-stream"}${CRLF}`;
|
|
28261
28261
|
}
|
|
28262
28262
|
this.headers = textEncoder.encode(headers + CRLF);
|
|
28263
|
-
this.contentLength = isStringValue ?
|
|
28263
|
+
this.contentLength = isStringValue ? value2.byteLength : value2.size;
|
|
28264
28264
|
this.size = this.headers.byteLength + this.contentLength + CRLF_BYTES_COUNT;
|
|
28265
28265
|
this.name = name2;
|
|
28266
|
-
this.value =
|
|
28266
|
+
this.value = value2;
|
|
28267
28267
|
}
|
|
28268
28268
|
async* encode() {
|
|
28269
28269
|
yield this.headers;
|
|
28270
|
-
const { value } = this;
|
|
28271
|
-
if (utils$1.isTypedArray(
|
|
28272
|
-
yield
|
|
28270
|
+
const { value: value2 } = this;
|
|
28271
|
+
if (utils$1.isTypedArray(value2)) {
|
|
28272
|
+
yield value2;
|
|
28273
28273
|
} else {
|
|
28274
|
-
yield* readBlob$1(
|
|
28274
|
+
yield* readBlob$1(value2);
|
|
28275
28275
|
}
|
|
28276
28276
|
yield CRLF_BYTES;
|
|
28277
28277
|
}
|
|
@@ -28298,8 +28298,8 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
28298
28298
|
const boundaryBytes = textEncoder.encode("--" + boundary + CRLF);
|
|
28299
28299
|
const footerBytes = textEncoder.encode("--" + boundary + "--" + CRLF + CRLF);
|
|
28300
28300
|
let contentLength = footerBytes.byteLength;
|
|
28301
|
-
const parts = Array.from(form.entries()).map(([name2,
|
|
28302
|
-
const part = new FormDataPart(name2,
|
|
28301
|
+
const parts = Array.from(form.entries()).map(([name2, value2]) => {
|
|
28302
|
+
const part = new FormDataPart(name2, value2);
|
|
28303
28303
|
contentLength += part.size;
|
|
28304
28304
|
return part;
|
|
28305
28305
|
});
|
|
@@ -28344,9 +28344,9 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
28344
28344
|
var callbackify = (fn, reducer) => {
|
|
28345
28345
|
return utils$1.isAsyncFn(fn) ? function(...args) {
|
|
28346
28346
|
const cb = args.pop();
|
|
28347
|
-
fn.apply(this, args).then((
|
|
28347
|
+
fn.apply(this, args).then((value2) => {
|
|
28348
28348
|
try {
|
|
28349
|
-
reducer ? cb(null, ...reducer(
|
|
28349
|
+
reducer ? cb(null, ...reducer(value2)) : cb(null, value2);
|
|
28350
28350
|
} catch (err) {
|
|
28351
28351
|
cb(err);
|
|
28352
28352
|
}
|
|
@@ -28516,15 +28516,15 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
28516
28516
|
return new Promise((resolve, reject) => {
|
|
28517
28517
|
let onDone;
|
|
28518
28518
|
let isDone;
|
|
28519
|
-
const done = (
|
|
28519
|
+
const done = (value2, isRejected) => {
|
|
28520
28520
|
if (isDone)
|
|
28521
28521
|
return;
|
|
28522
28522
|
isDone = true;
|
|
28523
|
-
onDone && onDone(
|
|
28523
|
+
onDone && onDone(value2, isRejected);
|
|
28524
28524
|
};
|
|
28525
|
-
const _resolve = (
|
|
28526
|
-
done(
|
|
28527
|
-
resolve(
|
|
28525
|
+
const _resolve = (value2) => {
|
|
28526
|
+
done(value2);
|
|
28527
|
+
resolve(value2);
|
|
28528
28528
|
};
|
|
28529
28529
|
const _reject = (reason) => {
|
|
28530
28530
|
done(reason, true);
|
|
@@ -28552,7 +28552,7 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
28552
28552
|
let rejected = false;
|
|
28553
28553
|
let req;
|
|
28554
28554
|
if (lookup) {
|
|
28555
|
-
const _lookup = callbackify$1(lookup, (
|
|
28555
|
+
const _lookup = callbackify$1(lookup, (value2) => utils$1.isArray(value2) ? value2 : [value2]);
|
|
28556
28556
|
lookup = (hostname, opt, cb) => {
|
|
28557
28557
|
_lookup(hostname, opt, (err, arg0, arg1) => {
|
|
28558
28558
|
if (err) {
|
|
@@ -28573,7 +28573,7 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
28573
28573
|
}
|
|
28574
28574
|
emitter.removeAllListeners();
|
|
28575
28575
|
};
|
|
28576
|
-
onDone((
|
|
28576
|
+
onDone((value2, isRejected) => {
|
|
28577
28577
|
isDone = true;
|
|
28578
28578
|
if (isRejected) {
|
|
28579
28579
|
rejected = true;
|
|
@@ -28908,8 +28908,8 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
28908
28908
|
return origin2.protocol === url2.protocol && origin2.host === url2.host && (isMSIE || origin2.port === url2.port);
|
|
28909
28909
|
})(new URL(platform.origin), platform.navigator && /(msie|trident)/i.test(platform.navigator.userAgent)) : () => true;
|
|
28910
28910
|
var cookies = platform.hasStandardBrowserEnv ? {
|
|
28911
|
-
write(name2,
|
|
28912
|
-
const cookie = [name2 + "=" + encodeURIComponent(
|
|
28911
|
+
write(name2, value2, expires, path, domain, secure) {
|
|
28912
|
+
const cookie = [name2 + "=" + encodeURIComponent(value2)];
|
|
28913
28913
|
utils$1.isNumber(expires) && cookie.push("expires=" + new Date(expires).toGMTString());
|
|
28914
28914
|
utils$1.isString(path) && cookie.push("path=" + path);
|
|
28915
28915
|
utils$1.isString(domain) && cookie.push("domain=" + domain);
|
|
@@ -29071,8 +29071,8 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
29071
29071
|
config: config2,
|
|
29072
29072
|
request
|
|
29073
29073
|
};
|
|
29074
|
-
settle(function _resolve(
|
|
29075
|
-
resolve(
|
|
29074
|
+
settle(function _resolve(value2) {
|
|
29075
|
+
resolve(value2);
|
|
29076
29076
|
done();
|
|
29077
29077
|
}, function _reject(err) {
|
|
29078
29078
|
reject(err);
|
|
@@ -29217,11 +29217,11 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
29217
29217
|
const reader = stream3.getReader();
|
|
29218
29218
|
try {
|
|
29219
29219
|
for (;; ) {
|
|
29220
|
-
const { done, value } = await reader.read();
|
|
29220
|
+
const { done, value: value2 } = await reader.read();
|
|
29221
29221
|
if (done) {
|
|
29222
29222
|
break;
|
|
29223
29223
|
}
|
|
29224
|
-
yield
|
|
29224
|
+
yield value2;
|
|
29225
29225
|
}
|
|
29226
29226
|
} finally {
|
|
29227
29227
|
await reader.cancel();
|
|
@@ -29240,18 +29240,18 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
29240
29240
|
return new ReadableStream({
|
|
29241
29241
|
async pull(controller) {
|
|
29242
29242
|
try {
|
|
29243
|
-
const { done: done2, value } = await iterator.next();
|
|
29243
|
+
const { done: done2, value: value2 } = await iterator.next();
|
|
29244
29244
|
if (done2) {
|
|
29245
29245
|
_onFinish();
|
|
29246
29246
|
controller.close();
|
|
29247
29247
|
return;
|
|
29248
29248
|
}
|
|
29249
|
-
let len =
|
|
29249
|
+
let len = value2.byteLength;
|
|
29250
29250
|
if (onProgress) {
|
|
29251
29251
|
let loadedBytes = bytes += len;
|
|
29252
29252
|
onProgress(loadedBytes);
|
|
29253
29253
|
}
|
|
29254
|
-
controller.enqueue(new Uint8Array(
|
|
29254
|
+
controller.enqueue(new Uint8Array(value2));
|
|
29255
29255
|
} catch (err) {
|
|
29256
29256
|
_onFinish(err);
|
|
29257
29257
|
throw err;
|
|
@@ -29420,13 +29420,13 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
29420
29420
|
xhr: xhrAdapter,
|
|
29421
29421
|
fetch: fetchAdapter
|
|
29422
29422
|
};
|
|
29423
|
-
utils$1.forEach(knownAdapters, (fn,
|
|
29423
|
+
utils$1.forEach(knownAdapters, (fn, value2) => {
|
|
29424
29424
|
if (fn) {
|
|
29425
29425
|
try {
|
|
29426
|
-
Object.defineProperty(fn, "name", { value });
|
|
29426
|
+
Object.defineProperty(fn, "name", { value: value2 });
|
|
29427
29427
|
} catch (e2) {
|
|
29428
29428
|
}
|
|
29429
|
-
Object.defineProperty(fn, "adapterName", { value });
|
|
29429
|
+
Object.defineProperty(fn, "adapterName", { value: value2 });
|
|
29430
29430
|
}
|
|
29431
29431
|
});
|
|
29432
29432
|
var renderReason = (reason) => `- ${reason}`;
|
|
@@ -29507,7 +29507,7 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
29507
29507
|
function formatMessage(opt, desc) {
|
|
29508
29508
|
return "[Axios v" + VERSION3 + "] Transitional option '" + opt + "'" + desc + (message2 ? ". " + message2 : "");
|
|
29509
29509
|
}
|
|
29510
|
-
return (
|
|
29510
|
+
return (value2, opt, opts) => {
|
|
29511
29511
|
if (validator2 === false) {
|
|
29512
29512
|
throw new AxiosError(formatMessage(opt, " has been removed" + (version ? " in " + version : "")), AxiosError.ERR_DEPRECATED);
|
|
29513
29513
|
}
|
|
@@ -29515,11 +29515,11 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
29515
29515
|
deprecatedWarnings[opt] = true;
|
|
29516
29516
|
console.warn(formatMessage(opt, " has been deprecated since v" + version + " and will be removed in the near future"));
|
|
29517
29517
|
}
|
|
29518
|
-
return validator2 ? validator2(
|
|
29518
|
+
return validator2 ? validator2(value2, opt, opts) : true;
|
|
29519
29519
|
};
|
|
29520
29520
|
};
|
|
29521
29521
|
validators$1.spelling = function spelling(correctSpelling) {
|
|
29522
|
-
return (
|
|
29522
|
+
return (value2, opt) => {
|
|
29523
29523
|
console.warn(`${opt} is likely a misspelling of ${correctSpelling}`);
|
|
29524
29524
|
return true;
|
|
29525
29525
|
};
|
|
@@ -29534,8 +29534,8 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
29534
29534
|
const opt = keys[i2];
|
|
29535
29535
|
const validator2 = schema[opt];
|
|
29536
29536
|
if (validator2) {
|
|
29537
|
-
const
|
|
29538
|
-
const result =
|
|
29537
|
+
const value2 = options[opt];
|
|
29538
|
+
const result = value2 === undefined || validator2(value2, opt, options);
|
|
29539
29539
|
if (result !== true) {
|
|
29540
29540
|
throw new AxiosError("option " + opt + " must be " + result, AxiosError.ERR_BAD_OPTION_VALUE);
|
|
29541
29541
|
}
|
|
@@ -29868,8 +29868,8 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
29868
29868
|
NotExtended: 510,
|
|
29869
29869
|
NetworkAuthenticationRequired: 511
|
|
29870
29870
|
};
|
|
29871
|
-
Object.entries(HttpStatusCode).forEach(([key,
|
|
29872
|
-
HttpStatusCode[
|
|
29871
|
+
Object.entries(HttpStatusCode).forEach(([key, value2]) => {
|
|
29872
|
+
HttpStatusCode[value2] = key;
|
|
29873
29873
|
});
|
|
29874
29874
|
var HttpStatusCode$1 = HttpStatusCode;
|
|
29875
29875
|
function createInstance(defaultConfig) {
|
|
@@ -30615,23 +30615,23 @@ var require_beautifier = __commonJS((exports) => {
|
|
|
30615
30615
|
}
|
|
30616
30616
|
const newItem = {};
|
|
30617
30617
|
for (const key2 in data) {
|
|
30618
|
-
const
|
|
30619
|
-
const valueType = typeof
|
|
30618
|
+
const value2 = data[key2];
|
|
30619
|
+
const valueType = typeof value2;
|
|
30620
30620
|
let newKey = knownBeautification[key2] || key2;
|
|
30621
30621
|
if (Array.isArray(newKey)) {
|
|
30622
30622
|
newKey = newKey[0];
|
|
30623
30623
|
}
|
|
30624
|
-
if (!Array.isArray(
|
|
30625
|
-
if (valueType === "object" &&
|
|
30626
|
-
newItem[newKey] = this.beautify(
|
|
30624
|
+
if (!Array.isArray(value2)) {
|
|
30625
|
+
if (valueType === "object" && value2 !== null) {
|
|
30626
|
+
newItem[newKey] = this.beautify(value2, knownBeautification[key2]);
|
|
30627
30627
|
} else {
|
|
30628
|
-
newItem[newKey] = this.beautifyValueWithKey(newKey,
|
|
30628
|
+
newItem[newKey] = this.beautifyValueWithKey(newKey, value2);
|
|
30629
30629
|
}
|
|
30630
30630
|
continue;
|
|
30631
30631
|
}
|
|
30632
30632
|
const newArray = [];
|
|
30633
30633
|
if (Array.isArray(this.beautificationMap[newKey])) {
|
|
30634
|
-
for (const elementValue of
|
|
30634
|
+
for (const elementValue of value2) {
|
|
30635
30635
|
const mappedBeautification = this.beautificationMap[knownBeautification[key2]];
|
|
30636
30636
|
const childMapping = mappedBeautification[0];
|
|
30637
30637
|
if (typeof childMapping === "object" && childMapping !== null) {
|
|
@@ -30728,22 +30728,22 @@ var require_nanoid = __commonJS((exports, module) => {
|
|
|
30728
30728
|
// node_modules/binance/lib/util/browser-support.js
|
|
30729
30729
|
var require_browser_support = __commonJS((exports) => {
|
|
30730
30730
|
var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) {
|
|
30731
|
-
function adopt(
|
|
30732
|
-
return
|
|
30733
|
-
resolve(
|
|
30731
|
+
function adopt(value2) {
|
|
30732
|
+
return value2 instanceof P ? value2 : new P(function(resolve) {
|
|
30733
|
+
resolve(value2);
|
|
30734
30734
|
});
|
|
30735
30735
|
}
|
|
30736
30736
|
return new (P || (P = Promise))(function(resolve, reject) {
|
|
30737
|
-
function fulfilled(
|
|
30737
|
+
function fulfilled(value2) {
|
|
30738
30738
|
try {
|
|
30739
|
-
step(generator.next(
|
|
30739
|
+
step(generator.next(value2));
|
|
30740
30740
|
} catch (e2) {
|
|
30741
30741
|
reject(e2);
|
|
30742
30742
|
}
|
|
30743
30743
|
}
|
|
30744
|
-
function rejected(
|
|
30744
|
+
function rejected(value2) {
|
|
30745
30745
|
try {
|
|
30746
|
-
step(generator["throw"](
|
|
30746
|
+
step(generator["throw"](value2));
|
|
30747
30747
|
} catch (e2) {
|
|
30748
30748
|
reject(e2);
|
|
30749
30749
|
}
|
|
@@ -30820,22 +30820,22 @@ var require_node_support = __commonJS((exports) => {
|
|
|
30820
30820
|
return result;
|
|
30821
30821
|
};
|
|
30822
30822
|
var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) {
|
|
30823
|
-
function adopt(
|
|
30824
|
-
return
|
|
30825
|
-
resolve(
|
|
30823
|
+
function adopt(value2) {
|
|
30824
|
+
return value2 instanceof P ? value2 : new P(function(resolve) {
|
|
30825
|
+
resolve(value2);
|
|
30826
30826
|
});
|
|
30827
30827
|
}
|
|
30828
30828
|
return new (P || (P = Promise))(function(resolve, reject) {
|
|
30829
|
-
function fulfilled(
|
|
30829
|
+
function fulfilled(value2) {
|
|
30830
30830
|
try {
|
|
30831
|
-
step(generator.next(
|
|
30831
|
+
step(generator.next(value2));
|
|
30832
30832
|
} catch (e2) {
|
|
30833
30833
|
reject(e2);
|
|
30834
30834
|
}
|
|
30835
30835
|
}
|
|
30836
|
-
function rejected(
|
|
30836
|
+
function rejected(value2) {
|
|
30837
30837
|
try {
|
|
30838
|
-
step(generator["throw"](
|
|
30838
|
+
step(generator["throw"](value2));
|
|
30839
30839
|
} catch (e2) {
|
|
30840
30840
|
reject(e2);
|
|
30841
30841
|
}
|
|
@@ -30867,22 +30867,22 @@ var require_node_support = __commonJS((exports) => {
|
|
|
30867
30867
|
// node_modules/binance/lib/util/requestUtils.js
|
|
30868
30868
|
var require_requestUtils = __commonJS((exports) => {
|
|
30869
30869
|
var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) {
|
|
30870
|
-
function adopt(
|
|
30871
|
-
return
|
|
30872
|
-
resolve(
|
|
30870
|
+
function adopt(value2) {
|
|
30871
|
+
return value2 instanceof P ? value2 : new P(function(resolve) {
|
|
30872
|
+
resolve(value2);
|
|
30873
30873
|
});
|
|
30874
30874
|
}
|
|
30875
30875
|
return new (P || (P = Promise))(function(resolve, reject) {
|
|
30876
|
-
function fulfilled(
|
|
30876
|
+
function fulfilled(value2) {
|
|
30877
30877
|
try {
|
|
30878
|
-
step(generator.next(
|
|
30878
|
+
step(generator.next(value2));
|
|
30879
30879
|
} catch (e2) {
|
|
30880
30880
|
reject(e2);
|
|
30881
30881
|
}
|
|
30882
30882
|
}
|
|
30883
|
-
function rejected(
|
|
30883
|
+
function rejected(value2) {
|
|
30884
30884
|
try {
|
|
30885
|
-
step(generator["throw"](
|
|
30885
|
+
step(generator["throw"](value2));
|
|
30886
30886
|
} catch (e2) {
|
|
30887
30887
|
reject(e2);
|
|
30888
30888
|
}
|
|
@@ -30928,11 +30928,11 @@ var require_requestUtils = __commonJS((exports) => {
|
|
|
30928
30928
|
function serialiseParams(params = {}, strict_validation = false, encodeValues = false, filterUndefinedParams = false) {
|
|
30929
30929
|
const paramKeys = !filterUndefinedParams ? Object.keys(params) : Object.keys(params).filter((key) => typeof params[key] !== "undefined");
|
|
30930
30930
|
return paramKeys.map((key) => {
|
|
30931
|
-
const
|
|
30932
|
-
if (strict_validation === true && typeof
|
|
30931
|
+
const value2 = params[key];
|
|
30932
|
+
if (strict_validation === true && typeof value2 === "undefined") {
|
|
30933
30933
|
throw new Error("Failed to sign API request due to undefined parameter");
|
|
30934
30934
|
}
|
|
30935
|
-
const encodedValue = encodeValues ? encodeURIComponent(
|
|
30935
|
+
const encodedValue = encodeValues ? encodeURIComponent(value2) : value2;
|
|
30936
30936
|
return `${key}=${encodedValue}`;
|
|
30937
30937
|
}).join("&");
|
|
30938
30938
|
}
|
|
@@ -31071,22 +31071,22 @@ var require_requestUtils = __commonJS((exports) => {
|
|
|
31071
31071
|
// node_modules/binance/lib/util/BaseRestClient.js
|
|
31072
31072
|
var require_BaseRestClient = __commonJS((exports) => {
|
|
31073
31073
|
var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) {
|
|
31074
|
-
function adopt(
|
|
31075
|
-
return
|
|
31076
|
-
resolve(
|
|
31074
|
+
function adopt(value2) {
|
|
31075
|
+
return value2 instanceof P ? value2 : new P(function(resolve) {
|
|
31076
|
+
resolve(value2);
|
|
31077
31077
|
});
|
|
31078
31078
|
}
|
|
31079
31079
|
return new (P || (P = Promise))(function(resolve, reject) {
|
|
31080
|
-
function fulfilled(
|
|
31080
|
+
function fulfilled(value2) {
|
|
31081
31081
|
try {
|
|
31082
|
-
step(generator.next(
|
|
31082
|
+
step(generator.next(value2));
|
|
31083
31083
|
} catch (e2) {
|
|
31084
31084
|
reject(e2);
|
|
31085
31085
|
}
|
|
31086
31086
|
}
|
|
31087
|
-
function rejected(
|
|
31087
|
+
function rejected(value2) {
|
|
31088
31088
|
try {
|
|
31089
|
-
step(generator["throw"](
|
|
31089
|
+
step(generator["throw"](value2));
|
|
31090
31090
|
} catch (e2) {
|
|
31091
31091
|
reject(e2);
|
|
31092
31092
|
}
|
|
@@ -31158,8 +31158,8 @@ var require_BaseRestClient = __commonJS((exports) => {
|
|
|
31158
31158
|
getTimeOffset() {
|
|
31159
31159
|
return this.timeOffset;
|
|
31160
31160
|
}
|
|
31161
|
-
setTimeOffset(
|
|
31162
|
-
this.timeOffset =
|
|
31161
|
+
setTimeOffset(value2) {
|
|
31162
|
+
this.timeOffset = value2;
|
|
31163
31163
|
}
|
|
31164
31164
|
get(endpoint, params) {
|
|
31165
31165
|
return this._call("GET", endpoint, params);
|
|
@@ -31253,18 +31253,18 @@ var require_BaseRestClient = __commonJS((exports) => {
|
|
|
31253
31253
|
const delta = {};
|
|
31254
31254
|
for (const headerKey in this.apiLimitTrackers) {
|
|
31255
31255
|
const headerValue = responseHeaders[headerKey];
|
|
31256
|
-
const
|
|
31257
|
-
if (headerValue !== undefined && !isNaN(
|
|
31258
|
-
this.apiLimitTrackers[headerKey] =
|
|
31256
|
+
const value2 = parseInt(headerValue);
|
|
31257
|
+
if (headerValue !== undefined && !isNaN(value2)) {
|
|
31258
|
+
this.apiLimitTrackers[headerKey] = value2;
|
|
31259
31259
|
delta[headerKey] = {
|
|
31260
31260
|
updated: true,
|
|
31261
|
-
valueParsed:
|
|
31261
|
+
valueParsed: value2,
|
|
31262
31262
|
valueRaw: headerValue
|
|
31263
31263
|
};
|
|
31264
31264
|
} else {
|
|
31265
31265
|
delta[headerKey] = {
|
|
31266
31266
|
updated: false,
|
|
31267
|
-
valueParsed:
|
|
31267
|
+
valueParsed: value2,
|
|
31268
31268
|
valueRaw: headerValue
|
|
31269
31269
|
};
|
|
31270
31270
|
}
|
|
@@ -31305,22 +31305,22 @@ var require_BaseRestClient = __commonJS((exports) => {
|
|
|
31305
31305
|
// node_modules/binance/lib/coinm-client.js
|
|
31306
31306
|
var require_coinm_client = __commonJS((exports) => {
|
|
31307
31307
|
var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) {
|
|
31308
|
-
function adopt(
|
|
31309
|
-
return
|
|
31310
|
-
resolve(
|
|
31308
|
+
function adopt(value2) {
|
|
31309
|
+
return value2 instanceof P ? value2 : new P(function(resolve) {
|
|
31310
|
+
resolve(value2);
|
|
31311
31311
|
});
|
|
31312
31312
|
}
|
|
31313
31313
|
return new (P || (P = Promise))(function(resolve, reject) {
|
|
31314
|
-
function fulfilled(
|
|
31314
|
+
function fulfilled(value2) {
|
|
31315
31315
|
try {
|
|
31316
|
-
step(generator.next(
|
|
31316
|
+
step(generator.next(value2));
|
|
31317
31317
|
} catch (e2) {
|
|
31318
31318
|
reject(e2);
|
|
31319
31319
|
}
|
|
31320
31320
|
}
|
|
31321
|
-
function rejected(
|
|
31321
|
+
function rejected(value2) {
|
|
31322
31322
|
try {
|
|
31323
|
-
step(generator["throw"](
|
|
31323
|
+
step(generator["throw"](value2));
|
|
31324
31324
|
} catch (e2) {
|
|
31325
31325
|
reject(e2);
|
|
31326
31326
|
}
|
|
@@ -31672,22 +31672,22 @@ var require_logger = __commonJS((exports) => {
|
|
|
31672
31672
|
// node_modules/binance/lib/main-client.js
|
|
31673
31673
|
var require_main_client = __commonJS((exports) => {
|
|
31674
31674
|
var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) {
|
|
31675
|
-
function adopt(
|
|
31676
|
-
return
|
|
31677
|
-
resolve(
|
|
31675
|
+
function adopt(value2) {
|
|
31676
|
+
return value2 instanceof P ? value2 : new P(function(resolve) {
|
|
31677
|
+
resolve(value2);
|
|
31678
31678
|
});
|
|
31679
31679
|
}
|
|
31680
31680
|
return new (P || (P = Promise))(function(resolve, reject) {
|
|
31681
|
-
function fulfilled(
|
|
31681
|
+
function fulfilled(value2) {
|
|
31682
31682
|
try {
|
|
31683
|
-
step(generator.next(
|
|
31683
|
+
step(generator.next(value2));
|
|
31684
31684
|
} catch (e2) {
|
|
31685
31685
|
reject(e2);
|
|
31686
31686
|
}
|
|
31687
31687
|
}
|
|
31688
|
-
function rejected(
|
|
31688
|
+
function rejected(value2) {
|
|
31689
31689
|
try {
|
|
31690
|
-
step(generator["throw"](
|
|
31690
|
+
step(generator["throw"](value2));
|
|
31691
31691
|
} catch (e2) {
|
|
31692
31692
|
reject(e2);
|
|
31693
31693
|
}
|
|
@@ -33218,22 +33218,22 @@ var require_main_client = __commonJS((exports) => {
|
|
|
33218
33218
|
// node_modules/binance/lib/portfolio-client.js
|
|
33219
33219
|
var require_portfolio_client = __commonJS((exports) => {
|
|
33220
33220
|
var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) {
|
|
33221
|
-
function adopt(
|
|
33222
|
-
return
|
|
33223
|
-
resolve(
|
|
33221
|
+
function adopt(value2) {
|
|
33222
|
+
return value2 instanceof P ? value2 : new P(function(resolve) {
|
|
33223
|
+
resolve(value2);
|
|
33224
33224
|
});
|
|
33225
33225
|
}
|
|
33226
33226
|
return new (P || (P = Promise))(function(resolve, reject) {
|
|
33227
|
-
function fulfilled(
|
|
33227
|
+
function fulfilled(value2) {
|
|
33228
33228
|
try {
|
|
33229
|
-
step(generator.next(
|
|
33229
|
+
step(generator.next(value2));
|
|
33230
33230
|
} catch (e2) {
|
|
33231
33231
|
reject(e2);
|
|
33232
33232
|
}
|
|
33233
33233
|
}
|
|
33234
|
-
function rejected(
|
|
33234
|
+
function rejected(value2) {
|
|
33235
33235
|
try {
|
|
33236
|
-
step(generator["throw"](
|
|
33236
|
+
step(generator["throw"](value2));
|
|
33237
33237
|
} catch (e2) {
|
|
33238
33238
|
reject(e2);
|
|
33239
33239
|
}
|
|
@@ -33692,22 +33692,22 @@ var require_websockets = __commonJS((exports) => {
|
|
|
33692
33692
|
// node_modules/binance/lib/usdm-client.js
|
|
33693
33693
|
var require_usdm_client = __commonJS((exports) => {
|
|
33694
33694
|
var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) {
|
|
33695
|
-
function adopt(
|
|
33696
|
-
return
|
|
33697
|
-
resolve(
|
|
33695
|
+
function adopt(value2) {
|
|
33696
|
+
return value2 instanceof P ? value2 : new P(function(resolve) {
|
|
33697
|
+
resolve(value2);
|
|
33698
33698
|
});
|
|
33699
33699
|
}
|
|
33700
33700
|
return new (P || (P = Promise))(function(resolve, reject) {
|
|
33701
|
-
function fulfilled(
|
|
33701
|
+
function fulfilled(value2) {
|
|
33702
33702
|
try {
|
|
33703
|
-
step(generator.next(
|
|
33703
|
+
step(generator.next(value2));
|
|
33704
33704
|
} catch (e2) {
|
|
33705
33705
|
reject(e2);
|
|
33706
33706
|
}
|
|
33707
33707
|
}
|
|
33708
|
-
function rejected(
|
|
33708
|
+
function rejected(value2) {
|
|
33709
33709
|
try {
|
|
33710
|
-
step(generator["throw"](
|
|
33710
|
+
step(generator["throw"](value2));
|
|
33711
33711
|
} catch (e2) {
|
|
33712
33712
|
reject(e2);
|
|
33713
33713
|
}
|
|
@@ -34622,35 +34622,35 @@ var require_permessage_deflate = __commonJS((exports, module) => {
|
|
|
34622
34622
|
normalizeParams(configurations) {
|
|
34623
34623
|
configurations.forEach((params) => {
|
|
34624
34624
|
Object.keys(params).forEach((key) => {
|
|
34625
|
-
let
|
|
34626
|
-
if (
|
|
34625
|
+
let value2 = params[key];
|
|
34626
|
+
if (value2.length > 1) {
|
|
34627
34627
|
throw new Error(`Parameter "${key}" must have only a single value`);
|
|
34628
34628
|
}
|
|
34629
|
-
|
|
34629
|
+
value2 = value2[0];
|
|
34630
34630
|
if (key === "client_max_window_bits") {
|
|
34631
|
-
if (
|
|
34632
|
-
const num = +
|
|
34631
|
+
if (value2 !== true) {
|
|
34632
|
+
const num = +value2;
|
|
34633
34633
|
if (!Number.isInteger(num) || num < 8 || num > 15) {
|
|
34634
|
-
throw new TypeError(`Invalid value for parameter "${key}": ${
|
|
34634
|
+
throw new TypeError(`Invalid value for parameter "${key}": ${value2}`);
|
|
34635
34635
|
}
|
|
34636
|
-
|
|
34636
|
+
value2 = num;
|
|
34637
34637
|
} else if (!this._isServer) {
|
|
34638
|
-
throw new TypeError(`Invalid value for parameter "${key}": ${
|
|
34638
|
+
throw new TypeError(`Invalid value for parameter "${key}": ${value2}`);
|
|
34639
34639
|
}
|
|
34640
34640
|
} else if (key === "server_max_window_bits") {
|
|
34641
|
-
const num = +
|
|
34641
|
+
const num = +value2;
|
|
34642
34642
|
if (!Number.isInteger(num) || num < 8 || num > 15) {
|
|
34643
|
-
throw new TypeError(`Invalid value for parameter "${key}": ${
|
|
34643
|
+
throw new TypeError(`Invalid value for parameter "${key}": ${value2}`);
|
|
34644
34644
|
}
|
|
34645
|
-
|
|
34645
|
+
value2 = num;
|
|
34646
34646
|
} else if (key === "client_no_context_takeover" || key === "server_no_context_takeover") {
|
|
34647
|
-
if (
|
|
34648
|
-
throw new TypeError(`Invalid value for parameter "${key}": ${
|
|
34647
|
+
if (value2 !== true) {
|
|
34648
|
+
throw new TypeError(`Invalid value for parameter "${key}": ${value2}`);
|
|
34649
34649
|
}
|
|
34650
34650
|
} else {
|
|
34651
34651
|
throw new Error(`Unknown parameter "${key}"`);
|
|
34652
34652
|
}
|
|
34653
|
-
params[key] =
|
|
34653
|
+
params[key] = value2;
|
|
34654
34654
|
});
|
|
34655
34655
|
});
|
|
34656
34656
|
return configurations;
|
|
@@ -34933,8 +34933,8 @@ var require_validation = __commonJS((exports, module) => {
|
|
|
34933
34933
|
}
|
|
34934
34934
|
return true;
|
|
34935
34935
|
}
|
|
34936
|
-
function isBlob(
|
|
34937
|
-
return hasBlob && typeof
|
|
34936
|
+
function isBlob(value2) {
|
|
34937
|
+
return hasBlob && typeof value2 === "object" && typeof value2.arrayBuffer === "function" && typeof value2.type === "string" && typeof value2.stream === "function" && (value2[Symbol.toStringTag] === "Blob" || value2[Symbol.toStringTag] === "File");
|
|
34938
34938
|
}
|
|
34939
34939
|
module.exports = {
|
|
34940
34940
|
isBlob,
|
|
@@ -35952,12 +35952,12 @@ var require_extension = __commonJS((exports, module) => {
|
|
|
35952
35952
|
}
|
|
35953
35953
|
if (end === -1)
|
|
35954
35954
|
end = i2;
|
|
35955
|
-
let
|
|
35955
|
+
let value2 = header.slice(start, end);
|
|
35956
35956
|
if (mustUnescape) {
|
|
35957
|
-
|
|
35957
|
+
value2 = value2.replace(/\\/g, "");
|
|
35958
35958
|
mustUnescape = false;
|
|
35959
35959
|
}
|
|
35960
|
-
push(params, paramName,
|
|
35960
|
+
push(params, paramName, value2);
|
|
35961
35961
|
if (code === 44) {
|
|
35962
35962
|
push(offers, extensionName, params);
|
|
35963
35963
|
params = Object.create(null);
|
|
@@ -36480,8 +36480,8 @@ var require_websocket = __commonJS((exports, module) => {
|
|
|
36480
36480
|
const headers = options && options.headers;
|
|
36481
36481
|
options = { ...options, headers: {} };
|
|
36482
36482
|
if (headers) {
|
|
36483
|
-
for (const [key2,
|
|
36484
|
-
options.headers[key2.toLowerCase()] =
|
|
36483
|
+
for (const [key2, value2] of Object.entries(headers)) {
|
|
36484
|
+
options.headers[key2.toLowerCase()] = value2;
|
|
36485
36485
|
}
|
|
36486
36486
|
}
|
|
36487
36487
|
} else if (websocket.listenerCount("redirect") === 0) {
|
|
@@ -37143,10 +37143,10 @@ var require_websocket_server = __commonJS((exports, module) => {
|
|
|
37143
37143
|
}
|
|
37144
37144
|
if (extensions[PerMessageDeflate.extensionName]) {
|
|
37145
37145
|
const params = extensions[PerMessageDeflate.extensionName].params;
|
|
37146
|
-
const
|
|
37146
|
+
const value2 = extension.format({
|
|
37147
37147
|
[PerMessageDeflate.extensionName]: [params]
|
|
37148
37148
|
});
|
|
37149
|
-
headers.push(`Sec-WebSocket-Extensions: ${
|
|
37149
|
+
headers.push(`Sec-WebSocket-Extensions: ${value2}`);
|
|
37150
37150
|
ws._extensions = extensions;
|
|
37151
37151
|
}
|
|
37152
37152
|
this.emit("headers", headers, req);
|
|
@@ -37273,22 +37273,22 @@ var require_websocket_client = __commonJS((exports) => {
|
|
|
37273
37273
|
return result;
|
|
37274
37274
|
};
|
|
37275
37275
|
var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) {
|
|
37276
|
-
function adopt(
|
|
37277
|
-
return
|
|
37278
|
-
resolve(
|
|
37276
|
+
function adopt(value2) {
|
|
37277
|
+
return value2 instanceof P ? value2 : new P(function(resolve) {
|
|
37278
|
+
resolve(value2);
|
|
37279
37279
|
});
|
|
37280
37280
|
}
|
|
37281
37281
|
return new (P || (P = Promise))(function(resolve, reject) {
|
|
37282
|
-
function fulfilled(
|
|
37282
|
+
function fulfilled(value2) {
|
|
37283
37283
|
try {
|
|
37284
|
-
step(generator.next(
|
|
37284
|
+
step(generator.next(value2));
|
|
37285
37285
|
} catch (e2) {
|
|
37286
37286
|
reject(e2);
|
|
37287
37287
|
}
|
|
37288
37288
|
}
|
|
37289
|
-
function rejected(
|
|
37289
|
+
function rejected(value2) {
|
|
37290
37290
|
try {
|
|
37291
|
-
step(generator["throw"](
|
|
37291
|
+
step(generator["throw"](value2));
|
|
37292
37292
|
} catch (e2) {
|
|
37293
37293
|
reject(e2);
|
|
37294
37294
|
}
|
|
@@ -37780,10 +37780,10 @@ var require_websocket_client = __commonJS((exports) => {
|
|
|
37780
37780
|
});
|
|
37781
37781
|
this.tryWsSend(wsKey, wsMessage);
|
|
37782
37782
|
}
|
|
37783
|
-
requestSetProperty(wsKey, property,
|
|
37783
|
+
requestSetProperty(wsKey, property, value2, requestId) {
|
|
37784
37784
|
const wsMessage = JSON.stringify({
|
|
37785
37785
|
method: "SET_PROPERTY",
|
|
37786
|
-
params: [property,
|
|
37786
|
+
params: [property, value2],
|
|
37787
37787
|
id: requestId
|
|
37788
37788
|
});
|
|
37789
37789
|
this.tryWsSend(wsKey, wsMessage);
|
|
@@ -52032,11 +52032,264 @@ __export(exports_exchange_account, {
|
|
|
52032
52032
|
ExchangeAccount: () => ExchangeAccount
|
|
52033
52033
|
});
|
|
52034
52034
|
|
|
52035
|
-
// src/
|
|
52036
|
-
|
|
52035
|
+
// src/helpers/pnl.ts
|
|
52036
|
+
function determine_position_size(entry, stop, budget) {
|
|
52037
|
+
let stop_percent = Math.abs(entry - stop) / entry;
|
|
52038
|
+
let size = budget / stop_percent / entry;
|
|
52039
|
+
return size;
|
|
52040
|
+
}
|
|
52041
|
+
function determine_risk(entry, stop, quantity) {
|
|
52042
|
+
let stop_percent = Math.abs(entry - stop) / entry;
|
|
52043
|
+
let risk = quantity * stop_percent * entry;
|
|
52044
|
+
return risk;
|
|
52045
|
+
}
|
|
52046
|
+
function determine_close_price(entry, pnl, quantity, kind, single = false, leverage = 1) {
|
|
52047
|
+
const dollar_value = entry / leverage;
|
|
52048
|
+
const position = dollar_value * quantity;
|
|
52049
|
+
if (position) {
|
|
52050
|
+
let percent = pnl / position;
|
|
52051
|
+
let difference = position * percent / quantity;
|
|
52052
|
+
let result;
|
|
52053
|
+
if (kind === "long") {
|
|
52054
|
+
result = difference + entry;
|
|
52055
|
+
} else {
|
|
52056
|
+
result = entry - difference;
|
|
52057
|
+
}
|
|
52058
|
+
if (single) {
|
|
52059
|
+
return result;
|
|
52060
|
+
}
|
|
52061
|
+
return result;
|
|
52062
|
+
}
|
|
52063
|
+
return 0;
|
|
52064
|
+
}
|
|
52065
|
+
function determine_amount_to_sell(entry, quantity, sell_price, pnl, kind, places = "%.3f") {
|
|
52066
|
+
const _pnl = determine_pnl(entry, sell_price, quantity, kind);
|
|
52067
|
+
const ratio = pnl / to_f(Math.abs(_pnl), places);
|
|
52068
|
+
quantity = quantity * ratio;
|
|
52069
|
+
return to_f(quantity, places);
|
|
52070
|
+
}
|
|
52071
|
+
function determine_pnl(entry, close_price, quantity, kind, contract_size, places = "%.2f") {
|
|
52072
|
+
if (contract_size) {
|
|
52073
|
+
const direction = kind === "long" ? 1 : -1;
|
|
52074
|
+
return quantity * contract_size * direction * (1 / entry - 1 / close_price);
|
|
52075
|
+
}
|
|
52076
|
+
let difference = entry - close_price;
|
|
52077
|
+
if (kind === "long") {
|
|
52078
|
+
difference = close_price - entry;
|
|
52079
|
+
}
|
|
52080
|
+
return to_f(difference * quantity, places);
|
|
52081
|
+
}
|
|
52082
|
+
function position(entry, quantity, kind, leverage = 1) {
|
|
52083
|
+
const direction = { long: 1, short: -1 };
|
|
52084
|
+
return parseFloat((direction[kind] * quantity * (entry / leverage)).toFixed(3));
|
|
52085
|
+
}
|
|
52086
|
+
function to_f(value, places) {
|
|
52087
|
+
if (value) {
|
|
52088
|
+
let pp = parseInt(places.replace("%.", "").replace("f", ""));
|
|
52089
|
+
return parseFloat(value.toFixed(pp));
|
|
52090
|
+
}
|
|
52091
|
+
return value;
|
|
52092
|
+
}
|
|
52093
|
+
var value = {
|
|
52094
|
+
determine_risk,
|
|
52095
|
+
determine_position_size,
|
|
52096
|
+
determine_close_price,
|
|
52097
|
+
determine_pnl,
|
|
52098
|
+
position,
|
|
52099
|
+
determine_amount_to_sell,
|
|
52100
|
+
to_f
|
|
52101
|
+
};
|
|
52102
|
+
var pnl_default = value;
|
|
52103
|
+
|
|
52104
|
+
// src/helpers/trade_utils.ts
|
|
52105
|
+
function to_f2(value2, places = "%.1f") {
|
|
52106
|
+
let v = typeof value2 === "string" ? parseFloat(value2) : value2;
|
|
52107
|
+
const formattedValue = places.replace("%.", "").replace("f", "");
|
|
52108
|
+
return parseFloat(v.toFixed(parseInt(formattedValue)));
|
|
52109
|
+
}
|
|
52110
|
+
function determine_position_size2({
|
|
52111
|
+
entry,
|
|
52112
|
+
stop,
|
|
52113
|
+
budget,
|
|
52114
|
+
percent,
|
|
52115
|
+
min_size,
|
|
52116
|
+
notional_value,
|
|
52117
|
+
as_coin = true,
|
|
52118
|
+
places = "%.3f"
|
|
52119
|
+
}) {
|
|
52120
|
+
let stop_percent = stop ? Math.abs(entry - stop) / entry : percent;
|
|
52121
|
+
if (stop_percent && budget) {
|
|
52122
|
+
let size = budget / stop_percent;
|
|
52123
|
+
let notion_value = size * entry;
|
|
52124
|
+
if (notional_value && notional_value > notion_value) {
|
|
52125
|
+
size = notional_value / entry;
|
|
52126
|
+
}
|
|
52127
|
+
if (as_coin) {
|
|
52128
|
+
size = size / entry;
|
|
52129
|
+
if (min_size && min_size === 1) {
|
|
52130
|
+
return to_f2(Math.round(size), places);
|
|
52131
|
+
}
|
|
52132
|
+
}
|
|
52133
|
+
return to_f2(size, places);
|
|
52134
|
+
}
|
|
52135
|
+
return;
|
|
52136
|
+
}
|
|
52137
|
+
function determine_average_entry_and_size(orders, places = "%.3f", price_places = "%.1f") {
|
|
52138
|
+
const sum_values = orders.reduce((sum, order) => sum + order.price * order.quantity, 0);
|
|
52139
|
+
const total_quantity = orders.reduce((sum, order) => sum + order.quantity, 0);
|
|
52140
|
+
const avg_price = total_quantity ? to_f2(sum_values / total_quantity, price_places) : 0;
|
|
52141
|
+
return {
|
|
52142
|
+
entry: avg_price,
|
|
52143
|
+
price: avg_price,
|
|
52144
|
+
quantity: to_f2(total_quantity, places)
|
|
52145
|
+
};
|
|
52146
|
+
}
|
|
52147
|
+
var createArray = (start, stop, step) => {
|
|
52148
|
+
const result = [];
|
|
52149
|
+
let current = start;
|
|
52150
|
+
while (current <= stop) {
|
|
52151
|
+
result.push(current);
|
|
52152
|
+
current += step;
|
|
52153
|
+
}
|
|
52154
|
+
return result;
|
|
52155
|
+
};
|
|
52156
|
+
var groupIntoPairsWithSumLessThan = (arr, targetSum, key = "quantity", firstSize = 0) => {
|
|
52157
|
+
if (firstSize) {
|
|
52158
|
+
const totalSize = arr.reduce((sum, order) => sum + order[key], 0);
|
|
52159
|
+
const remainingSize = totalSize - firstSize;
|
|
52160
|
+
let newSum = 0;
|
|
52161
|
+
let newArray = [];
|
|
52162
|
+
let lastIndex = 0;
|
|
52163
|
+
for (let i2 = 0;i2 < arr.length; i2++) {
|
|
52164
|
+
if (newSum < remainingSize) {
|
|
52165
|
+
newSum += arr[i2][key];
|
|
52166
|
+
newArray.push(arr[i2]);
|
|
52167
|
+
lastIndex = i2;
|
|
52168
|
+
}
|
|
52169
|
+
}
|
|
52170
|
+
const lastGroup = arr.slice(lastIndex + 1);
|
|
52171
|
+
const previousPair = groupInPairs(newArray, key, targetSum);
|
|
52172
|
+
if (lastGroup.length > 0) {
|
|
52173
|
+
previousPair.push(lastGroup);
|
|
52174
|
+
}
|
|
52175
|
+
return previousPair;
|
|
52176
|
+
}
|
|
52177
|
+
return groupInPairs(arr, key, targetSum);
|
|
52178
|
+
};
|
|
52179
|
+
function groupInPairs(_arr, key, targetSum) {
|
|
52180
|
+
const result = [];
|
|
52181
|
+
let currentSum = 0;
|
|
52182
|
+
let currentGroup = [];
|
|
52183
|
+
for (let i2 = 0;i2 < _arr.length; i2++) {
|
|
52184
|
+
currentSum += _arr[i2][key];
|
|
52185
|
+
currentGroup.push(_arr[i2]);
|
|
52186
|
+
if (currentSum >= targetSum) {
|
|
52187
|
+
result.push(currentGroup);
|
|
52188
|
+
currentGroup = [];
|
|
52189
|
+
currentSum = 0;
|
|
52190
|
+
}
|
|
52191
|
+
}
|
|
52192
|
+
return result;
|
|
52193
|
+
}
|
|
52194
|
+
var computeTotalAverageForEachTrade = (trades, config2) => {
|
|
52195
|
+
let _take_profit = config2.take_profit;
|
|
52196
|
+
let kind = config2.kind;
|
|
52197
|
+
let entryToUse = kind === "short" ? Math.min(config2.entry, config2.stop) : Math.max(config2.entry, config2.stop);
|
|
52198
|
+
let _currentEntry = config2.currentEntry || entryToUse;
|
|
52199
|
+
let less = trades.filter((p) => kind === "long" ? p.entry <= _currentEntry : p.entry >= _currentEntry);
|
|
52200
|
+
let rrr = trades.map((r2, i2) => {
|
|
52201
|
+
let considered = [];
|
|
52202
|
+
if (kind === "long") {
|
|
52203
|
+
considered = trades.filter((p) => p.entry > _currentEntry);
|
|
52204
|
+
} else {
|
|
52205
|
+
considered = trades.filter((p) => p.entry < _currentEntry);
|
|
52206
|
+
}
|
|
52207
|
+
const x_pnl = 0;
|
|
52208
|
+
const remaining = less.filter((o) => {
|
|
52209
|
+
if (kind === "long") {
|
|
52210
|
+
return o.entry >= r2.entry;
|
|
52211
|
+
}
|
|
52212
|
+
return o.entry <= r2.entry;
|
|
52213
|
+
});
|
|
52214
|
+
if (remaining.length === 0) {
|
|
52215
|
+
return { ...r2, pnl: x_pnl };
|
|
52216
|
+
}
|
|
52217
|
+
const start = kind === "long" ? Math.max(...remaining.map((o) => o.entry)) : Math.min(...remaining.map((o) => o.entry));
|
|
52218
|
+
considered = considered.map((o) => ({ ...o, entry: start }));
|
|
52219
|
+
considered = considered.concat(remaining);
|
|
52220
|
+
let avg_entry = determine_average_entry_and_size([
|
|
52221
|
+
...considered.map((o) => ({
|
|
52222
|
+
price: o.entry,
|
|
52223
|
+
quantity: o.quantity
|
|
52224
|
+
})),
|
|
52225
|
+
{
|
|
52226
|
+
price: _currentEntry,
|
|
52227
|
+
quantity: config2.currentQty || 0
|
|
52228
|
+
}
|
|
52229
|
+
], config2.decimal_places, config2.price_places);
|
|
52230
|
+
let _pnl = r2.pnl;
|
|
52231
|
+
let sell_price = r2.sell_price;
|
|
52232
|
+
let entry_pnl = r2.pnl;
|
|
52233
|
+
if (_take_profit) {
|
|
52234
|
+
_pnl = pnl_default.determine_pnl(avg_entry.price, _take_profit, avg_entry.quantity, kind);
|
|
52235
|
+
sell_price = _take_profit;
|
|
52236
|
+
entry_pnl = pnl_default.determine_pnl(r2.entry, _take_profit, avg_entry.quantity, kind);
|
|
52237
|
+
}
|
|
52238
|
+
const loss = pnl_default.determine_pnl(avg_entry.price, r2.stop, avg_entry.quantity, kind);
|
|
52239
|
+
let new_stop = r2.new_stop;
|
|
52240
|
+
const entry_loss = pnl_default.determine_pnl(r2.entry, new_stop, avg_entry.quantity, kind);
|
|
52241
|
+
let min_profit = 0;
|
|
52242
|
+
let min_entry_profit = 0;
|
|
52243
|
+
if (config2.min_profit) {
|
|
52244
|
+
min_profit = pnl_default.determine_close_price(avg_entry.price, config2.min_profit, avg_entry.quantity, kind);
|
|
52245
|
+
min_entry_profit = pnl_default.determine_close_price(r2.entry, config2.min_profit, avg_entry.quantity, kind);
|
|
52246
|
+
}
|
|
52247
|
+
let x_fee = r2.fee;
|
|
52248
|
+
if (config2.fee) {
|
|
52249
|
+
x_fee = config2.fee * r2.stop * avg_entry.quantity;
|
|
52250
|
+
}
|
|
52251
|
+
let tp_close = pnl_default.determine_close_price(r2.entry, Math.abs(entry_loss) * (config2.rr || 1) + x_fee, avg_entry.quantity, kind);
|
|
52252
|
+
return {
|
|
52253
|
+
...r2,
|
|
52254
|
+
x_fee: to_f2(x_fee, "%.2f"),
|
|
52255
|
+
avg_entry: avg_entry.price,
|
|
52256
|
+
avg_size: avg_entry.quantity,
|
|
52257
|
+
entry_pnl: to_f2(entry_pnl, "%.2f"),
|
|
52258
|
+
entry_loss: to_f2(entry_loss, "%.2f"),
|
|
52259
|
+
min_entry_pnl: to_f2(min_entry_profit, "%.2f"),
|
|
52260
|
+
pnl: _pnl,
|
|
52261
|
+
neg_pnl: to_f2(loss, "%.2f"),
|
|
52262
|
+
sell_price,
|
|
52263
|
+
close_p: to_f2(tp_close, "%.2f"),
|
|
52264
|
+
min_pnl: to_f2(min_profit, "%.2f"),
|
|
52265
|
+
new_stop
|
|
52266
|
+
};
|
|
52267
|
+
});
|
|
52268
|
+
return rrr;
|
|
52269
|
+
};
|
|
52270
|
+
function createGapPairs(arr, gap, item) {
|
|
52271
|
+
if (arr.length === 0) {
|
|
52272
|
+
return [];
|
|
52273
|
+
}
|
|
52274
|
+
const result = [];
|
|
52275
|
+
const firstElement = arr[0];
|
|
52276
|
+
for (let i2 = arr.length - 1;i2 >= 0; i2--) {
|
|
52277
|
+
const current = arr[i2];
|
|
52278
|
+
const gapIndex = i2 - gap;
|
|
52279
|
+
const pairedElement = gapIndex < 0 ? firstElement : arr[gapIndex];
|
|
52280
|
+
if (current !== pairedElement) {
|
|
52281
|
+
result.push([current, pairedElement]);
|
|
52282
|
+
}
|
|
52283
|
+
}
|
|
52284
|
+
if (item) {
|
|
52285
|
+
let r2 = result.find((o) => o[0] === item);
|
|
52286
|
+
return r2 ? [r2] : [];
|
|
52287
|
+
}
|
|
52288
|
+
return result;
|
|
52289
|
+
}
|
|
52037
52290
|
|
|
52038
52291
|
// src/helpers/trade_signal.ts
|
|
52039
|
-
function
|
|
52292
|
+
function determine_close_price2({
|
|
52040
52293
|
entry,
|
|
52041
52294
|
pnl,
|
|
52042
52295
|
quantity,
|
|
@@ -52044,16 +52297,16 @@ function determine_close_price({
|
|
|
52044
52297
|
kind = "long"
|
|
52045
52298
|
}) {
|
|
52046
52299
|
const dollar_value = entry / leverage;
|
|
52047
|
-
const
|
|
52048
|
-
if (
|
|
52049
|
-
const percent = pnl /
|
|
52050
|
-
const difference =
|
|
52300
|
+
const position2 = dollar_value * quantity;
|
|
52301
|
+
if (position2) {
|
|
52302
|
+
const percent = pnl / position2;
|
|
52303
|
+
const difference = position2 * percent / quantity;
|
|
52051
52304
|
const result = kind === "long" ? difference + entry : entry - difference;
|
|
52052
52305
|
return result;
|
|
52053
52306
|
}
|
|
52054
52307
|
return 0;
|
|
52055
52308
|
}
|
|
52056
|
-
function
|
|
52309
|
+
function determine_pnl2(entry, close_price, quantity, kind = "long", contract_size) {
|
|
52057
52310
|
if (contract_size) {
|
|
52058
52311
|
const direction = kind === "long" ? 1 : -1;
|
|
52059
52312
|
return quantity * contract_size * direction * (1 / entry - 1 / close_price);
|
|
@@ -52072,7 +52325,7 @@ function* _get_zones({
|
|
|
52072
52325
|
let focus_low = last * Math.pow(1 + percent_change, -1);
|
|
52073
52326
|
if (focus_high > current_price) {
|
|
52074
52327
|
while (focus_high > current_price) {
|
|
52075
|
-
yield
|
|
52328
|
+
yield to_f2(last, places);
|
|
52076
52329
|
focus_high = last;
|
|
52077
52330
|
last = focus_high * Math.pow(1 + percent_change, -1);
|
|
52078
52331
|
focus_low = last * Math.pow(1 + percent_change, -1);
|
|
@@ -52080,14 +52333,14 @@ function* _get_zones({
|
|
|
52080
52333
|
} else {
|
|
52081
52334
|
if (focus_high <= current_price) {
|
|
52082
52335
|
while (focus_high <= current_price) {
|
|
52083
|
-
yield
|
|
52336
|
+
yield to_f2(focus_high, places);
|
|
52084
52337
|
focus_low = focus_high;
|
|
52085
52338
|
last = focus_low * (1 + percent_change);
|
|
52086
52339
|
focus_high = last * (1 + percent_change);
|
|
52087
52340
|
}
|
|
52088
52341
|
} else {
|
|
52089
52342
|
while (focus_low <= current_price) {
|
|
52090
|
-
yield
|
|
52343
|
+
yield to_f2(focus_high, places);
|
|
52091
52344
|
focus_low = focus_high;
|
|
52092
52345
|
last = focus_low * (1 + percent_change);
|
|
52093
52346
|
focus_high = last * (1 + percent_change);
|
|
@@ -52351,7 +52604,7 @@ class Signal {
|
|
|
52351
52604
|
} else {
|
|
52352
52605
|
i2["risk_sell"] = Math.min(...potentials.slice(0, max_index));
|
|
52353
52606
|
}
|
|
52354
|
-
i2["pnl"] = this.to_df(
|
|
52607
|
+
i2["pnl"] = this.to_df(determine_pnl2(i2["entry"], i2["risk_sell"], i2["quantity"], kind));
|
|
52355
52608
|
}
|
|
52356
52609
|
}
|
|
52357
52610
|
}
|
|
@@ -52415,13 +52668,13 @@ class Signal {
|
|
|
52415
52668
|
let remaining_zones = margin_zones.filter((x) => JSON.stringify(x) != JSON.stringify(margin_range));
|
|
52416
52669
|
if (margin_range) {
|
|
52417
52670
|
const difference = Math.abs(margin_range[0] - margin_range[1]);
|
|
52418
|
-
const spread =
|
|
52671
|
+
const spread = to_f2(difference / this.risk_reward, this.price_places);
|
|
52419
52672
|
let entries;
|
|
52420
52673
|
const percent_change = this.percent_change / this.risk_reward;
|
|
52421
52674
|
if (kind === "long") {
|
|
52422
|
-
entries = Array.from({ length: Math.floor(this.risk_reward) + 1 }, (_, x) =>
|
|
52675
|
+
entries = Array.from({ length: Math.floor(this.risk_reward) + 1 }, (_, x) => to_f2(margin_range[1] - spread * x, this.price_places));
|
|
52423
52676
|
} else {
|
|
52424
|
-
entries = Array.from({ length: Math.floor(this.risk_reward) + 1 }, (_, x) =>
|
|
52677
|
+
entries = Array.from({ length: Math.floor(this.risk_reward) + 1 }, (_, x) => to_f2(margin_range[1] * Math.pow(1 + percent_change, x), this.price_places));
|
|
52425
52678
|
}
|
|
52426
52679
|
if (Math.min(...entries) < this.to_f(current_price) && this.to_f(current_price) < Math.max(...entries)) {
|
|
52427
52680
|
return entries.sort((a, b) => a - b);
|
|
@@ -52433,14 +52686,14 @@ class Signal {
|
|
|
52433
52686
|
if (new_range) {
|
|
52434
52687
|
while (entries2.length < this.risk_reward + 1) {
|
|
52435
52688
|
if (kind === "long") {
|
|
52436
|
-
let
|
|
52437
|
-
if (
|
|
52438
|
-
entries2.push(
|
|
52689
|
+
let value2 = this.to_f(new_range[1] - spread * x);
|
|
52690
|
+
if (value2 <= current_price) {
|
|
52691
|
+
entries2.push(value2);
|
|
52439
52692
|
}
|
|
52440
52693
|
} else {
|
|
52441
|
-
let
|
|
52442
|
-
if (
|
|
52443
|
-
entries2.push(
|
|
52694
|
+
let value2 = this.to_f(new_range[1] * Math.pow(1 + percent_change, x));
|
|
52695
|
+
if (value2 >= current_price) {
|
|
52696
|
+
entries2.push(value2);
|
|
52444
52697
|
}
|
|
52445
52698
|
}
|
|
52446
52699
|
x += 1;
|
|
@@ -52454,14 +52707,14 @@ class Signal {
|
|
|
52454
52707
|
let x = 0;
|
|
52455
52708
|
while (entries2.length < this.risk_reward + 1) {
|
|
52456
52709
|
if (kind === "long") {
|
|
52457
|
-
let
|
|
52458
|
-
if (
|
|
52459
|
-
entries2.push(
|
|
52710
|
+
let value2 = this.to_f(next_focus - spread * x);
|
|
52711
|
+
if (value2 <= this.to_f(current_price)) {
|
|
52712
|
+
entries2.push(value2);
|
|
52460
52713
|
}
|
|
52461
52714
|
} else {
|
|
52462
|
-
let
|
|
52463
|
-
if (
|
|
52464
|
-
entries2.push(
|
|
52715
|
+
let value2 = this.to_f(next_focus * Math.pow(1 + percent_change, x));
|
|
52716
|
+
if (value2 >= this.to_f(current_price)) {
|
|
52717
|
+
entries2.push(value2);
|
|
52465
52718
|
}
|
|
52466
52719
|
}
|
|
52467
52720
|
x += 1;
|
|
@@ -52472,8 +52725,8 @@ class Signal {
|
|
|
52472
52725
|
}
|
|
52473
52726
|
return [];
|
|
52474
52727
|
}
|
|
52475
|
-
to_f(
|
|
52476
|
-
return
|
|
52728
|
+
to_f(value2, places) {
|
|
52729
|
+
return to_f2(value2, places || this.price_places);
|
|
52477
52730
|
}
|
|
52478
52731
|
get_margin_zones({
|
|
52479
52732
|
current_price,
|
|
@@ -52675,7 +52928,7 @@ class Signal {
|
|
|
52675
52928
|
}) {
|
|
52676
52929
|
const considered = arr.map((x, i2) => i2).filter((i2) => i2 > index);
|
|
52677
52930
|
const with_quantity = considered.map((x) => {
|
|
52678
|
-
const q =
|
|
52931
|
+
const q = determine_position_size2({
|
|
52679
52932
|
entry: arr[x],
|
|
52680
52933
|
stop: arr[x - 1],
|
|
52681
52934
|
budget: risk,
|
|
@@ -52709,7 +52962,7 @@ class Signal {
|
|
|
52709
52962
|
const incurred_fees = fees.reduce((a, b) => a + b, 0) + previous_risks.reduce((a, b) => a + b, 0);
|
|
52710
52963
|
if (index === 0) {
|
|
52711
52964
|
}
|
|
52712
|
-
let quantity =
|
|
52965
|
+
let quantity = determine_position_size2({
|
|
52713
52966
|
entry,
|
|
52714
52967
|
stop,
|
|
52715
52968
|
budget: risk,
|
|
@@ -52721,7 +52974,7 @@ class Signal {
|
|
|
52721
52974
|
}
|
|
52722
52975
|
if (this.increase_size) {
|
|
52723
52976
|
quantity = quantity * multiplier;
|
|
52724
|
-
const new_risk =
|
|
52977
|
+
const new_risk = determine_pnl2(entry, stop, quantity, kind);
|
|
52725
52978
|
risk = Math.abs(new_risk);
|
|
52726
52979
|
}
|
|
52727
52980
|
const fee = this.to_df(this.fee * quantity * entry);
|
|
@@ -52730,12 +52983,12 @@ class Signal {
|
|
|
52730
52983
|
if (this.minimum_pnl) {
|
|
52731
52984
|
pnl = this.minimum_pnl + fee;
|
|
52732
52985
|
}
|
|
52733
|
-
let sell_price =
|
|
52986
|
+
let sell_price = determine_close_price2({ entry, pnl, quantity, kind });
|
|
52734
52987
|
if (take_profit && !this.minimum_pnl) {
|
|
52735
52988
|
sell_price = take_profit;
|
|
52736
|
-
pnl = this.to_df(
|
|
52989
|
+
pnl = this.to_df(determine_pnl2(entry, sell_price, quantity, kind));
|
|
52737
52990
|
pnl = pnl + fee;
|
|
52738
|
-
sell_price =
|
|
52991
|
+
sell_price = determine_close_price2({ entry, pnl, quantity, kind });
|
|
52739
52992
|
}
|
|
52740
52993
|
let risk_sell = sell_price;
|
|
52741
52994
|
return {
|
|
@@ -52753,284 +53006,790 @@ class Signal {
|
|
|
52753
53006
|
};
|
|
52754
53007
|
}
|
|
52755
53008
|
to_df(currentPrice, places = "%.3f") {
|
|
52756
|
-
return
|
|
53009
|
+
return to_f2(currentPrice, places);
|
|
52757
53010
|
}
|
|
52758
53011
|
}
|
|
52759
53012
|
|
|
52760
|
-
// src/helpers/
|
|
52761
|
-
function
|
|
52762
|
-
|
|
52763
|
-
|
|
52764
|
-
|
|
52765
|
-
|
|
52766
|
-
|
|
52767
|
-
|
|
52768
|
-
|
|
52769
|
-
|
|
52770
|
-
|
|
52771
|
-
|
|
52772
|
-
|
|
52773
|
-
|
|
52774
|
-
|
|
52775
|
-
|
|
52776
|
-
|
|
52777
|
-
|
|
52778
|
-
|
|
52779
|
-
|
|
52780
|
-
|
|
52781
|
-
|
|
52782
|
-
|
|
52783
|
-
|
|
52784
|
-
|
|
52785
|
-
|
|
52786
|
-
|
|
52787
|
-
|
|
52788
|
-
|
|
52789
|
-
|
|
52790
|
-
|
|
52791
|
-
|
|
52792
|
-
|
|
52793
|
-
|
|
52794
|
-
|
|
52795
|
-
|
|
52796
|
-
|
|
52797
|
-
|
|
52798
|
-
|
|
52799
|
-
|
|
53013
|
+
// src/helpers/shared.ts
|
|
53014
|
+
function buildConfig(app_config, {
|
|
53015
|
+
take_profit,
|
|
53016
|
+
entry,
|
|
53017
|
+
stop,
|
|
53018
|
+
raw_instance,
|
|
53019
|
+
risk,
|
|
53020
|
+
no_of_trades,
|
|
53021
|
+
min_profit = 0,
|
|
53022
|
+
risk_reward,
|
|
53023
|
+
kind,
|
|
53024
|
+
increase,
|
|
53025
|
+
gap,
|
|
53026
|
+
rr = 1,
|
|
53027
|
+
price_places = "%.1f",
|
|
53028
|
+
decimal_places = "%.3f"
|
|
53029
|
+
}) {
|
|
53030
|
+
let fee = app_config.fee / 100;
|
|
53031
|
+
let working_risk = risk || app_config.risk_per_trade;
|
|
53032
|
+
let trade_no = no_of_trades || app_config.risk_reward;
|
|
53033
|
+
const config2 = {
|
|
53034
|
+
focus: app_config.focus,
|
|
53035
|
+
fee,
|
|
53036
|
+
budget: app_config.budget,
|
|
53037
|
+
risk_reward: risk_reward || trade_no,
|
|
53038
|
+
support: app_config.support,
|
|
53039
|
+
resistance: app_config.resistance,
|
|
53040
|
+
price_places: app_config.price_places || price_places,
|
|
53041
|
+
decimal_places,
|
|
53042
|
+
percent_change: app_config.percent_change / app_config.tradeSplit,
|
|
53043
|
+
risk_per_trade: working_risk,
|
|
53044
|
+
take_profit: take_profit || app_config.take_profit,
|
|
53045
|
+
increase_position: increase,
|
|
53046
|
+
minimum_size: app_config.min_size,
|
|
53047
|
+
entry,
|
|
53048
|
+
stop,
|
|
53049
|
+
kind: app_config.kind,
|
|
53050
|
+
gap,
|
|
53051
|
+
min_profit: min_profit || app_config.min_profit,
|
|
53052
|
+
rr: rr || 1
|
|
53053
|
+
};
|
|
53054
|
+
const instance = new Signal(config2);
|
|
53055
|
+
if (raw_instance) {
|
|
53056
|
+
return instance;
|
|
52800
53057
|
}
|
|
52801
|
-
|
|
52802
|
-
|
|
52803
|
-
difference = close_price - entry;
|
|
53058
|
+
if (!stop) {
|
|
53059
|
+
return [];
|
|
52804
53060
|
}
|
|
52805
|
-
|
|
52806
|
-
|
|
52807
|
-
|
|
52808
|
-
const direction = { long: 1, short: -1 };
|
|
52809
|
-
return parseFloat((direction[kind] * quantity * (entry / leverage)).toFixed(3));
|
|
52810
|
-
}
|
|
52811
|
-
function to_f2(value, places) {
|
|
52812
|
-
if (value) {
|
|
52813
|
-
let pp = parseInt(places.replace("%.", "").replace("f", ""));
|
|
52814
|
-
return parseFloat(value.toFixed(pp));
|
|
53061
|
+
const condition = (kind === "long" ? entry > app_config.support : entry >= app_config.support) && stop >= app_config.support * 0.999;
|
|
53062
|
+
if (kind === "short") {
|
|
53063
|
+
console.log("condition", condition, entry === stop);
|
|
52815
53064
|
}
|
|
52816
|
-
|
|
52817
|
-
|
|
52818
|
-
|
|
52819
|
-
|
|
52820
|
-
|
|
52821
|
-
|
|
52822
|
-
|
|
52823
|
-
|
|
52824
|
-
|
|
52825
|
-
to_f: to_f2
|
|
52826
|
-
};
|
|
52827
|
-
var pnl_default = value;
|
|
52828
|
-
|
|
52829
|
-
// src/helpers/trade_utils.ts
|
|
52830
|
-
function to_f(value2, places = "%.1f") {
|
|
52831
|
-
let v = typeof value2 === "string" ? parseFloat(value2) : value2;
|
|
52832
|
-
const formattedValue = places.replace("%.", "").replace("f", "");
|
|
52833
|
-
return parseFloat(v.toFixed(parseInt(formattedValue)));
|
|
53065
|
+
console.log({ entry, support: app_config.support, stop });
|
|
53066
|
+
const result = entry === stop ? [] : condition ? instance.build_entry({
|
|
53067
|
+
current_price: entry,
|
|
53068
|
+
stop_loss: stop,
|
|
53069
|
+
risk: working_risk,
|
|
53070
|
+
kind: kind || app_config.kind,
|
|
53071
|
+
no_of_trades: trade_no
|
|
53072
|
+
}) || [] : [];
|
|
53073
|
+
return computeTotalAverageForEachTrade(result, config2);
|
|
52834
53074
|
}
|
|
52835
|
-
function
|
|
52836
|
-
|
|
52837
|
-
|
|
52838
|
-
budget,
|
|
52839
|
-
percent,
|
|
52840
|
-
min_size,
|
|
52841
|
-
notional_value,
|
|
52842
|
-
as_coin = true,
|
|
52843
|
-
places = "%.3f"
|
|
53075
|
+
function buildAvg({
|
|
53076
|
+
_trades,
|
|
53077
|
+
kind
|
|
52844
53078
|
}) {
|
|
52845
|
-
let
|
|
52846
|
-
|
|
52847
|
-
|
|
52848
|
-
|
|
52849
|
-
|
|
52850
|
-
|
|
52851
|
-
|
|
52852
|
-
|
|
52853
|
-
|
|
52854
|
-
|
|
52855
|
-
|
|
52856
|
-
|
|
53079
|
+
let avg = determine_average_entry_and_size(_trades?.map((r2) => ({
|
|
53080
|
+
price: r2.entry,
|
|
53081
|
+
quantity: r2.quantity
|
|
53082
|
+
})) || []);
|
|
53083
|
+
const stop_prices = _trades.map((o) => o.stop);
|
|
53084
|
+
const stop_loss = kind === "long" ? Math.min(...stop_prices) : Math.max(...stop_prices);
|
|
53085
|
+
avg.pnl = pnl_default.determine_pnl(avg.price, stop_loss, avg.quantity, kind);
|
|
53086
|
+
return avg;
|
|
53087
|
+
}
|
|
53088
|
+
function sortedBuildConfig(app_config, options) {
|
|
53089
|
+
const sorted = buildConfig(app_config, options).sort((a, b) => app_config.kind === "long" ? a.entry - b.entry : b.entry - b.entry).filter((x) => {
|
|
53090
|
+
if (app_config.symbol === "BTCUSDT") {
|
|
53091
|
+
return x.quantity <= 0.03;
|
|
52857
53092
|
}
|
|
52858
|
-
return
|
|
52859
|
-
}
|
|
52860
|
-
return
|
|
53093
|
+
return true;
|
|
53094
|
+
});
|
|
53095
|
+
return sorted.map((k, i2) => {
|
|
53096
|
+
const arrSet = sorted.slice(0, i2 + 1);
|
|
53097
|
+
const avg_values = determine_average_entry_and_size(arrSet.map((u) => ({ price: u.entry, quantity: u.quantity })), app_config.decimal_places, app_config.price_places);
|
|
53098
|
+
return {
|
|
53099
|
+
...k,
|
|
53100
|
+
reverse_avg_entry: avg_values.price,
|
|
53101
|
+
reverse_avg_quantity: avg_values.quantity
|
|
53102
|
+
};
|
|
53103
|
+
});
|
|
52861
53104
|
}
|
|
52862
|
-
function
|
|
52863
|
-
const
|
|
52864
|
-
|
|
52865
|
-
|
|
53105
|
+
function get_app_config_and_max_size(config2, payload) {
|
|
53106
|
+
const app_config = {
|
|
53107
|
+
kind: payload.kind,
|
|
53108
|
+
entry: payload.entry,
|
|
53109
|
+
stop: payload.stop,
|
|
53110
|
+
risk_per_trade: config2.risk,
|
|
53111
|
+
risk_reward: config2.risk_reward || 199,
|
|
53112
|
+
support: to_f2(config2.support, config2.price_places),
|
|
53113
|
+
resistance: to_f2(config2.resistance, config2.price_places),
|
|
53114
|
+
focus: payload.entry,
|
|
53115
|
+
fee: 0,
|
|
53116
|
+
percent_change: config2.stop_percent / 100,
|
|
53117
|
+
tradeSplit: 1,
|
|
53118
|
+
gap: 1,
|
|
53119
|
+
min_size: config2.min_size,
|
|
53120
|
+
budget: 0,
|
|
53121
|
+
price_places: config2.price_places,
|
|
53122
|
+
decimal_places: config2.decimal_places,
|
|
53123
|
+
min_profit: config2.profit_percent * config2.profit / 100
|
|
53124
|
+
};
|
|
53125
|
+
const initialResult = sortedBuildConfig(app_config, {
|
|
53126
|
+
entry: app_config.entry,
|
|
53127
|
+
stop: app_config.stop,
|
|
53128
|
+
kind: app_config.kind,
|
|
53129
|
+
risk: app_config.risk_per_trade,
|
|
53130
|
+
risk_reward: app_config.risk_reward,
|
|
53131
|
+
increase: true,
|
|
53132
|
+
gap: app_config.gap,
|
|
53133
|
+
price_places: app_config.price_places,
|
|
53134
|
+
decimal_places: app_config.decimal_places
|
|
53135
|
+
});
|
|
53136
|
+
const max_size = initialResult[0]?.avg_size;
|
|
53137
|
+
const last_value = initialResult[0];
|
|
53138
|
+
const entries = initialResult.map((x) => ({
|
|
53139
|
+
entry: x.entry,
|
|
53140
|
+
avg_entry: x.avg_entry,
|
|
53141
|
+
avg_size: x.avg_size,
|
|
53142
|
+
neg_pnl: x.neg_pnl,
|
|
53143
|
+
quantity: x.quantity
|
|
53144
|
+
}));
|
|
52866
53145
|
return {
|
|
52867
|
-
|
|
52868
|
-
|
|
52869
|
-
|
|
53146
|
+
app_config,
|
|
53147
|
+
max_size,
|
|
53148
|
+
last_value,
|
|
53149
|
+
entries
|
|
52870
53150
|
};
|
|
52871
53151
|
}
|
|
52872
|
-
|
|
52873
|
-
const
|
|
52874
|
-
|
|
52875
|
-
|
|
52876
|
-
|
|
52877
|
-
|
|
52878
|
-
|
|
52879
|
-
|
|
52880
|
-
|
|
52881
|
-
|
|
52882
|
-
|
|
52883
|
-
|
|
52884
|
-
|
|
52885
|
-
|
|
52886
|
-
|
|
52887
|
-
|
|
52888
|
-
|
|
52889
|
-
|
|
52890
|
-
|
|
52891
|
-
|
|
52892
|
-
|
|
53152
|
+
function buildAppConfig(config2, payload) {
|
|
53153
|
+
const { app_config, max_size, last_value, entries } = get_app_config_and_max_size({
|
|
53154
|
+
...config2,
|
|
53155
|
+
risk: payload.risk,
|
|
53156
|
+
profit: payload.profit || 500,
|
|
53157
|
+
risk_reward: payload.risk_reward,
|
|
53158
|
+
accounts: [],
|
|
53159
|
+
reduce_percent: 90,
|
|
53160
|
+
reverse_factor: 1,
|
|
53161
|
+
profit_percent: 0,
|
|
53162
|
+
kind: payload.entry > payload.stop ? "long" : "short",
|
|
53163
|
+
symbol: payload.symbol
|
|
53164
|
+
}, {
|
|
53165
|
+
entry: payload.entry,
|
|
53166
|
+
stop: payload.stop,
|
|
53167
|
+
kind: payload.entry > payload.stop ? "long" : "short"
|
|
53168
|
+
});
|
|
53169
|
+
app_config.max_size = max_size;
|
|
53170
|
+
app_config.entry = payload.entry || app_config.entry;
|
|
53171
|
+
app_config.stop = payload.stop || app_config.stop;
|
|
53172
|
+
app_config.last_value = last_value;
|
|
53173
|
+
app_config.entries = entries;
|
|
53174
|
+
return app_config;
|
|
53175
|
+
}
|
|
53176
|
+
function getOptimumStopAndRisk(app_config, params) {
|
|
53177
|
+
const { max_size, target_stop } = params;
|
|
53178
|
+
const isLong = app_config.kind === "long";
|
|
53179
|
+
const stopRange = Math.abs(app_config.entry - target_stop) * 0.5;
|
|
53180
|
+
let low_stop = isLong ? target_stop - stopRange : Math.max(target_stop - stopRange, app_config.entry);
|
|
53181
|
+
let high_stop = isLong ? Math.min(target_stop + stopRange, app_config.entry) : target_stop + stopRange;
|
|
53182
|
+
let optimal_stop = target_stop;
|
|
53183
|
+
let best_stop_result = null;
|
|
53184
|
+
let best_entry_diff = Infinity;
|
|
53185
|
+
console.log(`Finding optimal stop for ${isLong ? "LONG" : "SHORT"} position. Target: ${target_stop}, Search range: ${low_stop} to ${high_stop}`);
|
|
53186
|
+
let iterations = 0;
|
|
53187
|
+
const MAX_ITERATIONS = 50;
|
|
53188
|
+
while (Math.abs(high_stop - low_stop) > 0.1 && iterations < MAX_ITERATIONS) {
|
|
53189
|
+
iterations++;
|
|
53190
|
+
const mid_stop = (low_stop + high_stop) / 2;
|
|
53191
|
+
const result = sortedBuildConfig(app_config, {
|
|
53192
|
+
entry: app_config.entry,
|
|
53193
|
+
stop: mid_stop,
|
|
53194
|
+
kind: app_config.kind,
|
|
53195
|
+
risk: app_config.risk_per_trade,
|
|
53196
|
+
risk_reward: app_config.risk_reward,
|
|
53197
|
+
increase: true,
|
|
53198
|
+
gap: app_config.gap,
|
|
53199
|
+
price_places: app_config.price_places,
|
|
53200
|
+
decimal_places: app_config.decimal_places
|
|
53201
|
+
});
|
|
53202
|
+
if (result.length === 0) {
|
|
53203
|
+
if (isLong) {
|
|
53204
|
+
low_stop = mid_stop;
|
|
53205
|
+
} else {
|
|
53206
|
+
high_stop = mid_stop;
|
|
52893
53207
|
}
|
|
53208
|
+
continue;
|
|
52894
53209
|
}
|
|
52895
|
-
const
|
|
52896
|
-
const
|
|
52897
|
-
|
|
52898
|
-
|
|
52899
|
-
|
|
52900
|
-
|
|
52901
|
-
|
|
52902
|
-
return groupInPairs(arr, key, targetSum);
|
|
52903
|
-
};
|
|
52904
|
-
function groupInPairs(_arr, key, targetSum) {
|
|
52905
|
-
const result = [];
|
|
52906
|
-
let currentSum = 0;
|
|
52907
|
-
let currentGroup = [];
|
|
52908
|
-
for (let i2 = 0;i2 < _arr.length; i2++) {
|
|
52909
|
-
currentSum += _arr[i2][key];
|
|
52910
|
-
currentGroup.push(_arr[i2]);
|
|
52911
|
-
if (currentSum >= targetSum) {
|
|
52912
|
-
result.push(currentGroup);
|
|
52913
|
-
currentGroup = [];
|
|
52914
|
-
currentSum = 0;
|
|
53210
|
+
const first_entry = result[0].entry;
|
|
53211
|
+
const entry_diff = Math.abs(first_entry - target_stop);
|
|
53212
|
+
console.log(`Stop: ${mid_stop.toFixed(2)}, First Entry: ${first_entry.toFixed(2)}, Diff: ${entry_diff.toFixed(2)}`);
|
|
53213
|
+
if (entry_diff < best_entry_diff) {
|
|
53214
|
+
best_entry_diff = entry_diff;
|
|
53215
|
+
optimal_stop = mid_stop;
|
|
53216
|
+
best_stop_result = result;
|
|
52915
53217
|
}
|
|
52916
|
-
|
|
52917
|
-
|
|
52918
|
-
|
|
52919
|
-
|
|
52920
|
-
|
|
52921
|
-
|
|
52922
|
-
let entryToUse = kind === "short" ? Math.min(config2.entry, config2.stop) : Math.max(config2.entry, config2.stop);
|
|
52923
|
-
let _currentEntry = config2.currentEntry || entryToUse;
|
|
52924
|
-
let less = trades.filter((p) => kind === "long" ? p.entry <= _currentEntry : p.entry >= _currentEntry);
|
|
52925
|
-
let rrr = trades.map((r2, i2) => {
|
|
52926
|
-
let considered = [];
|
|
52927
|
-
if (kind === "long") {
|
|
52928
|
-
considered = trades.filter((p) => p.entry > _currentEntry);
|
|
53218
|
+
if (first_entry < target_stop) {
|
|
53219
|
+
if (isLong) {
|
|
53220
|
+
low_stop = mid_stop;
|
|
53221
|
+
} else {
|
|
53222
|
+
low_stop = mid_stop;
|
|
53223
|
+
}
|
|
52929
53224
|
} else {
|
|
52930
|
-
|
|
52931
|
-
|
|
52932
|
-
|
|
52933
|
-
|
|
52934
|
-
if (kind === "long") {
|
|
52935
|
-
return o.entry >= r2.entry;
|
|
53225
|
+
if (isLong) {
|
|
53226
|
+
high_stop = mid_stop;
|
|
53227
|
+
} else {
|
|
53228
|
+
high_stop = mid_stop;
|
|
52936
53229
|
}
|
|
52937
|
-
|
|
53230
|
+
}
|
|
53231
|
+
if (entry_diff < 1)
|
|
53232
|
+
break;
|
|
53233
|
+
}
|
|
53234
|
+
console.log(`Found optimal stop: ${optimal_stop.toFixed(2)} that gives first_entry: ${best_stop_result?.[0]?.entry?.toFixed(2)}, difference: ${best_entry_diff.toFixed(2)} after ${iterations} iterations`);
|
|
53235
|
+
let low_risk = 10;
|
|
53236
|
+
let high_risk = params.highest_risk || 2000;
|
|
53237
|
+
let optimal_risk = app_config.risk_per_trade;
|
|
53238
|
+
let best_size_result = best_stop_result;
|
|
53239
|
+
let best_size_diff = Infinity;
|
|
53240
|
+
console.log(`Finding optimal risk_per_trade for size target: ${max_size} (never exceeding it)`);
|
|
53241
|
+
iterations = 0;
|
|
53242
|
+
while (Math.abs(high_risk - low_risk) > 0.1 && iterations < MAX_ITERATIONS) {
|
|
53243
|
+
iterations++;
|
|
53244
|
+
const mid_risk = (low_risk + high_risk) / 2;
|
|
53245
|
+
const result = sortedBuildConfig(app_config, {
|
|
53246
|
+
entry: app_config.entry,
|
|
53247
|
+
stop: optimal_stop,
|
|
53248
|
+
kind: app_config.kind,
|
|
53249
|
+
risk: mid_risk,
|
|
53250
|
+
risk_reward: app_config.risk_reward,
|
|
53251
|
+
increase: true,
|
|
53252
|
+
gap: app_config.gap,
|
|
53253
|
+
price_places: app_config.price_places,
|
|
53254
|
+
decimal_places: app_config.decimal_places
|
|
52938
53255
|
});
|
|
52939
|
-
if (
|
|
52940
|
-
|
|
53256
|
+
if (result.length === 0) {
|
|
53257
|
+
high_risk = mid_risk;
|
|
53258
|
+
continue;
|
|
52941
53259
|
}
|
|
52942
|
-
const
|
|
52943
|
-
|
|
52944
|
-
|
|
52945
|
-
|
|
52946
|
-
|
|
52947
|
-
|
|
52948
|
-
|
|
52949
|
-
|
|
52950
|
-
|
|
52951
|
-
price: _currentEntry,
|
|
52952
|
-
quantity: config2.currentQty || 0
|
|
53260
|
+
const first_entry = result[0];
|
|
53261
|
+
const avg_size = first_entry.avg_size;
|
|
53262
|
+
console.log(`Risk: ${mid_risk.toFixed(2)}, Avg Size: ${avg_size.toFixed(4)}, Target: ${max_size}`);
|
|
53263
|
+
if (avg_size <= max_size) {
|
|
53264
|
+
const size_diff = max_size - avg_size;
|
|
53265
|
+
if (size_diff < best_size_diff) {
|
|
53266
|
+
best_size_diff = size_diff;
|
|
53267
|
+
optimal_risk = mid_risk;
|
|
53268
|
+
best_size_result = result;
|
|
52953
53269
|
}
|
|
52954
|
-
|
|
52955
|
-
|
|
52956
|
-
|
|
52957
|
-
let entry_pnl = r2.pnl;
|
|
52958
|
-
if (_take_profit) {
|
|
52959
|
-
_pnl = pnl_default.determine_pnl(avg_entry.price, _take_profit, avg_entry.quantity, kind);
|
|
52960
|
-
sell_price = _take_profit;
|
|
52961
|
-
entry_pnl = pnl_default.determine_pnl(r2.entry, _take_profit, avg_entry.quantity, kind);
|
|
52962
|
-
}
|
|
52963
|
-
const loss = pnl_default.determine_pnl(avg_entry.price, r2.stop, avg_entry.quantity, kind);
|
|
52964
|
-
let new_stop = r2.new_stop;
|
|
52965
|
-
const entry_loss = pnl_default.determine_pnl(r2.entry, new_stop, avg_entry.quantity, kind);
|
|
52966
|
-
let min_profit = 0;
|
|
52967
|
-
let min_entry_profit = 0;
|
|
52968
|
-
if (config2.min_profit) {
|
|
52969
|
-
min_profit = pnl_default.determine_close_price(avg_entry.price, config2.min_profit, avg_entry.quantity, kind);
|
|
52970
|
-
min_entry_profit = pnl_default.determine_close_price(r2.entry, config2.min_profit, avg_entry.quantity, kind);
|
|
52971
|
-
}
|
|
52972
|
-
let x_fee = r2.fee;
|
|
52973
|
-
if (config2.fee) {
|
|
52974
|
-
x_fee = config2.fee * r2.stop * avg_entry.quantity;
|
|
53270
|
+
low_risk = mid_risk;
|
|
53271
|
+
} else {
|
|
53272
|
+
high_risk = mid_risk;
|
|
52975
53273
|
}
|
|
52976
|
-
|
|
52977
|
-
|
|
52978
|
-
...r2,
|
|
52979
|
-
x_fee: to_f(x_fee, "%.2f"),
|
|
52980
|
-
avg_entry: avg_entry.price,
|
|
52981
|
-
avg_size: avg_entry.quantity,
|
|
52982
|
-
entry_pnl: to_f(entry_pnl, "%.2f"),
|
|
52983
|
-
entry_loss: to_f(entry_loss, "%.2f"),
|
|
52984
|
-
min_entry_pnl: to_f(min_entry_profit, "%.2f"),
|
|
52985
|
-
pnl: _pnl,
|
|
52986
|
-
neg_pnl: to_f(loss, "%.2f"),
|
|
52987
|
-
sell_price,
|
|
52988
|
-
close_p: to_f(tp_close, "%.2f"),
|
|
52989
|
-
min_pnl: to_f(min_profit, "%.2f"),
|
|
52990
|
-
new_stop
|
|
52991
|
-
};
|
|
52992
|
-
});
|
|
52993
|
-
return rrr;
|
|
52994
|
-
};
|
|
52995
|
-
function createGapPairs(arr, gap, item) {
|
|
52996
|
-
if (arr.length === 0) {
|
|
52997
|
-
return [];
|
|
53274
|
+
if (best_size_diff < 0.001)
|
|
53275
|
+
break;
|
|
52998
53276
|
}
|
|
52999
|
-
|
|
53000
|
-
|
|
53001
|
-
|
|
53002
|
-
|
|
53003
|
-
|
|
53004
|
-
|
|
53005
|
-
|
|
53006
|
-
|
|
53277
|
+
console.log(`Found optimal risk_per_trade: ${optimal_risk.toFixed(2)} that gives avg_size: ${best_size_result?.[0]?.avg_size?.toFixed(4)}, difference: ${best_size_diff.toFixed(4)} after ${iterations} iterations`);
|
|
53278
|
+
let final_risk = optimal_risk;
|
|
53279
|
+
let final_result = best_size_result;
|
|
53280
|
+
if (best_size_result?.[0]?.avg_size < max_size) {
|
|
53281
|
+
console.log(`Current avg_size (${best_size_result?.[0].avg_size.toFixed(4)}) is less than target (${max_size}). Increasing risk to reach target...`);
|
|
53282
|
+
let current_risk = optimal_risk;
|
|
53283
|
+
const risk_increment = 5;
|
|
53284
|
+
iterations = 0;
|
|
53285
|
+
while (iterations < MAX_ITERATIONS) {
|
|
53286
|
+
iterations++;
|
|
53287
|
+
current_risk += risk_increment;
|
|
53288
|
+
if (current_risk > 5000)
|
|
53289
|
+
break;
|
|
53290
|
+
const result = sortedBuildConfig(app_config, {
|
|
53291
|
+
entry: app_config.entry,
|
|
53292
|
+
stop: optimal_stop,
|
|
53293
|
+
kind: app_config.kind,
|
|
53294
|
+
risk: current_risk,
|
|
53295
|
+
risk_reward: app_config.risk_reward,
|
|
53296
|
+
increase: true,
|
|
53297
|
+
gap: app_config.gap,
|
|
53298
|
+
price_places: app_config.price_places,
|
|
53299
|
+
decimal_places: app_config.decimal_places
|
|
53300
|
+
});
|
|
53301
|
+
if (result.length === 0)
|
|
53302
|
+
continue;
|
|
53303
|
+
const avg_size = result[0].avg_size;
|
|
53304
|
+
console.log(`Increased Risk: ${current_risk.toFixed(2)}, New Avg Size: ${avg_size.toFixed(4)}`);
|
|
53305
|
+
if (avg_size >= max_size) {
|
|
53306
|
+
final_risk = current_risk;
|
|
53307
|
+
final_result = result;
|
|
53308
|
+
console.log(`Target size reached! Final risk: ${final_risk.toFixed(2)}, Final avg_size: ${avg_size.toFixed(4)}`);
|
|
53309
|
+
break;
|
|
53310
|
+
}
|
|
53007
53311
|
}
|
|
53008
53312
|
}
|
|
53009
|
-
|
|
53010
|
-
|
|
53011
|
-
|
|
53012
|
-
|
|
53013
|
-
|
|
53313
|
+
return {
|
|
53314
|
+
optimal_stop: to_f2(optimal_stop, app_config.price_places),
|
|
53315
|
+
optimal_risk: to_f2(final_risk, app_config.price_places),
|
|
53316
|
+
avg_size: final_result?.[0]?.avg_size || 0,
|
|
53317
|
+
avg_entry: final_result?.[0]?.avg_entry || 0,
|
|
53318
|
+
result: final_result,
|
|
53319
|
+
first_entry: final_result?.[0]?.entry || 0,
|
|
53320
|
+
neg_pnl: final_result?.[0]?.neg_pnl || 0,
|
|
53321
|
+
risk_reward: app_config.risk_reward,
|
|
53322
|
+
size_diff: Math.abs((final_result?.[0]?.avg_size || 0) - max_size),
|
|
53323
|
+
entry_diff: best_entry_diff
|
|
53324
|
+
};
|
|
53014
53325
|
}
|
|
53015
|
-
|
|
53016
|
-
|
|
53017
|
-
|
|
53018
|
-
|
|
53019
|
-
|
|
53020
|
-
|
|
53021
|
-
|
|
53022
|
-
|
|
53023
|
-
|
|
53024
|
-
|
|
53025
|
-
|
|
53026
|
-
|
|
53027
|
-
|
|
53028
|
-
|
|
53029
|
-
|
|
53030
|
-
|
|
53031
|
-
|
|
53032
|
-
|
|
53033
|
-
|
|
53326
|
+
function generate_config_params(app_config, payload) {
|
|
53327
|
+
const { result, ...optimum } = getOptimumStopAndRisk(app_config, {
|
|
53328
|
+
max_size: app_config.max_size,
|
|
53329
|
+
highest_risk: payload.risk * 2,
|
|
53330
|
+
target_stop: app_config.stop
|
|
53331
|
+
});
|
|
53332
|
+
return {
|
|
53333
|
+
entry: payload.entry,
|
|
53334
|
+
stop: optimum.optimal_stop,
|
|
53335
|
+
avg_size: optimum.avg_size,
|
|
53336
|
+
avg_entry: optimum.avg_entry,
|
|
53337
|
+
risk_reward: payload.risk_reward,
|
|
53338
|
+
neg_pnl: optimum.neg_pnl,
|
|
53339
|
+
risk: payload.risk
|
|
53340
|
+
};
|
|
53341
|
+
}
|
|
53342
|
+
function determine_break_even_price(payload) {
|
|
53343
|
+
const { long_position, short_position, fee_percent = 0.05 / 100 } = payload;
|
|
53344
|
+
const long_notional = long_position.entry * long_position.quantity;
|
|
53345
|
+
const short_notional = short_position.entry * short_position.quantity;
|
|
53346
|
+
const net_quantity = long_position.quantity - short_position.quantity;
|
|
53347
|
+
const net_capital = Math.abs(long_notional - short_notional);
|
|
53348
|
+
const break_even_price = net_capital / (Math.abs(net_quantity) + fee_percent * Math.abs(net_quantity));
|
|
53349
|
+
return {
|
|
53350
|
+
price: break_even_price,
|
|
53351
|
+
direction: net_quantity > 0 ? "long" : "short"
|
|
53352
|
+
};
|
|
53353
|
+
}
|
|
53354
|
+
function determine_amount_to_buy(payload) {
|
|
53355
|
+
const {
|
|
53356
|
+
orders,
|
|
53357
|
+
kind,
|
|
53358
|
+
decimal_places = "%.3f",
|
|
53359
|
+
position: position2,
|
|
53360
|
+
existingOrders
|
|
53361
|
+
} = payload;
|
|
53362
|
+
const totalQuantity = orders.reduce((sum, order) => sum + (order.quantity || 0), 0);
|
|
53363
|
+
let runningTotal = to_f2(totalQuantity, decimal_places);
|
|
53364
|
+
let sortedOrders = [...orders].sort((a, b) => (a.entry || 0) - (b.entry || 0));
|
|
53365
|
+
if (kind === "short") {
|
|
53366
|
+
sortedOrders.reverse();
|
|
53367
|
+
}
|
|
53368
|
+
const withCumulative = [];
|
|
53369
|
+
for (const order of sortedOrders) {
|
|
53370
|
+
withCumulative.push({
|
|
53371
|
+
...order,
|
|
53372
|
+
cumulative_quantity: runningTotal
|
|
53373
|
+
});
|
|
53374
|
+
runningTotal -= order.quantity;
|
|
53375
|
+
runningTotal = to_f2(runningTotal, decimal_places);
|
|
53376
|
+
}
|
|
53377
|
+
let filteredOrders = withCumulative.filter((order) => (order.cumulative_quantity || 0) > position2?.quantity).map((order) => ({
|
|
53378
|
+
...order,
|
|
53379
|
+
price: order.entry,
|
|
53380
|
+
kind,
|
|
53381
|
+
side: kind.toLowerCase() === "long" ? "buy" : "sell"
|
|
53382
|
+
}));
|
|
53383
|
+
filteredOrders = filteredOrders.filter((k) => !existingOrders.map((j) => j.price).includes(k.price));
|
|
53384
|
+
return filteredOrders;
|
|
53385
|
+
}
|
|
53386
|
+
function generateOptimumAppConfig(config2, payload, position2) {
|
|
53387
|
+
let low_risk = payload.start_risk;
|
|
53388
|
+
let high_risk = payload.max_risk || 50000;
|
|
53389
|
+
let best_risk = null;
|
|
53390
|
+
let best_app_config = null;
|
|
53391
|
+
const tolerance = 0.1;
|
|
53392
|
+
const max_iterations = 150;
|
|
53393
|
+
let iterations = 0;
|
|
53394
|
+
console.log(`Starting risk search for ${position2.kind} position. Target Entry: ${position2.entry}, Initial Risk Range: [${low_risk}, ${high_risk}]`);
|
|
53395
|
+
while (high_risk - low_risk > tolerance && iterations < max_iterations) {
|
|
53396
|
+
iterations++;
|
|
53397
|
+
const mid_risk = (low_risk + high_risk) / 2;
|
|
53398
|
+
const {
|
|
53399
|
+
app_config: current_app_config,
|
|
53400
|
+
max_size,
|
|
53401
|
+
last_value,
|
|
53402
|
+
entries
|
|
53403
|
+
} = get_app_config_and_max_size({
|
|
53404
|
+
...config2,
|
|
53405
|
+
risk: mid_risk,
|
|
53406
|
+
profit_percent: config2.profit_percent || 0,
|
|
53407
|
+
profit: config2.profit || 500,
|
|
53408
|
+
risk_reward: payload.risk_reward,
|
|
53409
|
+
kind: position2.kind,
|
|
53410
|
+
price_places: config2.price_places,
|
|
53411
|
+
decimal_places: config2.decimal_places,
|
|
53412
|
+
accounts: config2.accounts || [],
|
|
53413
|
+
reduce_percent: config2.reduce_percent || 90,
|
|
53414
|
+
reverse_factor: config2.reverse_factor || 1,
|
|
53415
|
+
symbol: config2.symbol || "",
|
|
53416
|
+
support: config2.support || 0,
|
|
53417
|
+
resistance: config2.resistance || 0,
|
|
53418
|
+
min_size: config2.min_size || 0,
|
|
53419
|
+
stop_percent: config2.stop_percent || 0
|
|
53420
|
+
}, {
|
|
53421
|
+
entry: payload.entry,
|
|
53422
|
+
stop: payload.stop,
|
|
53423
|
+
kind: position2.kind
|
|
53424
|
+
});
|
|
53425
|
+
current_app_config.max_size = max_size;
|
|
53426
|
+
current_app_config.last_value = last_value;
|
|
53427
|
+
current_app_config.entries = entries;
|
|
53428
|
+
current_app_config.risk_reward = payload.risk_reward;
|
|
53429
|
+
const full_trades = sortedBuildConfig(current_app_config, {
|
|
53430
|
+
entry: current_app_config.entry,
|
|
53431
|
+
stop: current_app_config.stop,
|
|
53432
|
+
kind: current_app_config.kind,
|
|
53433
|
+
risk: current_app_config.risk_per_trade,
|
|
53434
|
+
risk_reward: current_app_config.risk_reward,
|
|
53435
|
+
increase: true,
|
|
53436
|
+
gap: current_app_config.gap,
|
|
53437
|
+
price_places: current_app_config.price_places,
|
|
53438
|
+
decimal_places: current_app_config.decimal_places
|
|
53439
|
+
});
|
|
53440
|
+
console.log(`Iteration ${iterations}: Risk=${mid_risk.toFixed(2)}, Low=${low_risk.toFixed(2)}, High=${high_risk.toFixed(2)}`);
|
|
53441
|
+
if (full_trades.length === 0) {
|
|
53442
|
+
console.log(` -> No trades generated by sortedBuildConfig at Risk=${mid_risk.toFixed(2)}. Adjusting high_risk down.`);
|
|
53443
|
+
high_risk = mid_risk;
|
|
53444
|
+
continue;
|
|
53445
|
+
}
|
|
53446
|
+
const trades = determine_amount_to_buy({
|
|
53447
|
+
orders: full_trades,
|
|
53448
|
+
kind: position2.kind,
|
|
53449
|
+
decimal_places: current_app_config.decimal_places,
|
|
53450
|
+
price_places: current_app_config.price_places,
|
|
53451
|
+
position: position2,
|
|
53452
|
+
existingOrders: []
|
|
53453
|
+
});
|
|
53454
|
+
if (trades.length === 0) {
|
|
53455
|
+
console.log(` -> No trades met quantity requirement after filtering at Risk=${mid_risk.toFixed(2)}. Adjusting low_risk up.`);
|
|
53456
|
+
low_risk = mid_risk;
|
|
53457
|
+
continue;
|
|
53458
|
+
}
|
|
53459
|
+
const last_trade = trades[trades.length - 1];
|
|
53460
|
+
const last_entry = last_trade.entry;
|
|
53461
|
+
console.log(` -> Last Trade Entry (Filtered): ${last_entry.toFixed(4)}`);
|
|
53462
|
+
if (position2.kind === "long") {
|
|
53463
|
+
if (last_entry > position2.entry) {
|
|
53464
|
+
console.log(` -> Constraint VIOLATED (Long): last_entry (${last_entry.toFixed(4)}) > position.entry (${position2.entry.toFixed(4)}). Reducing high_risk.`);
|
|
53465
|
+
high_risk = mid_risk;
|
|
53466
|
+
} else {
|
|
53467
|
+
console.log(` -> Constraint MET (Long): last_entry (${last_entry.toFixed(4)}) <= position.entry (${position2.entry.toFixed(4)}). Storing as best, increasing low_risk.`);
|
|
53468
|
+
best_risk = mid_risk;
|
|
53469
|
+
best_app_config = current_app_config;
|
|
53470
|
+
low_risk = mid_risk;
|
|
53471
|
+
}
|
|
53472
|
+
} else {
|
|
53473
|
+
if (last_entry < position2.entry) {
|
|
53474
|
+
console.log(` -> Constraint VIOLATED (Short): last_entry (${last_entry.toFixed(4)}) < position.entry (${position2.entry.toFixed(4)}). Reducing high_risk.`);
|
|
53475
|
+
high_risk = mid_risk;
|
|
53476
|
+
} else {
|
|
53477
|
+
console.log(` -> Constraint MET (Short): last_entry (${last_entry.toFixed(4)}) >= position.entry (${position2.entry.toFixed(4)}). Storing as best, increasing low_risk.`);
|
|
53478
|
+
best_risk = mid_risk;
|
|
53479
|
+
best_app_config = current_app_config;
|
|
53480
|
+
low_risk = mid_risk;
|
|
53481
|
+
}
|
|
53482
|
+
}
|
|
53483
|
+
}
|
|
53484
|
+
if (iterations >= max_iterations) {
|
|
53485
|
+
console.warn(`generateAppConfig: Reached max iterations (${max_iterations}) without converging. Returning best found result.`);
|
|
53486
|
+
} else if (best_app_config) {
|
|
53487
|
+
console.log(`Search finished. Best Risk: ${best_risk?.toFixed(2)}, Final Last Entry: ${best_app_config.last_value?.entry?.toFixed(4)}`);
|
|
53488
|
+
} else {
|
|
53489
|
+
console.warn(`generateAppConfig: Could not find a valid risk configuration.`);
|
|
53490
|
+
}
|
|
53491
|
+
if (!best_app_config) {
|
|
53492
|
+
return null;
|
|
53493
|
+
}
|
|
53494
|
+
best_app_config.entries = determine_amount_to_buy({
|
|
53495
|
+
orders: best_app_config.entries,
|
|
53496
|
+
kind: position2.kind,
|
|
53497
|
+
decimal_places: best_app_config.decimal_places,
|
|
53498
|
+
price_places: best_app_config.price_places,
|
|
53499
|
+
position: position2,
|
|
53500
|
+
existingOrders: []
|
|
53501
|
+
});
|
|
53502
|
+
return best_app_config;
|
|
53503
|
+
}
|
|
53504
|
+
|
|
53505
|
+
// src/helpers/strategy.ts
|
|
53506
|
+
class Strategy {
|
|
53507
|
+
position;
|
|
53508
|
+
config;
|
|
53509
|
+
constructor(payload) {
|
|
53510
|
+
this.position = {
|
|
53511
|
+
long: payload.long,
|
|
53512
|
+
short: payload.short
|
|
53513
|
+
};
|
|
53514
|
+
this.config = payload.config;
|
|
53515
|
+
if (!this.config.fee_percent) {
|
|
53516
|
+
this.config.fee_percent = 0.05;
|
|
53517
|
+
}
|
|
53518
|
+
}
|
|
53519
|
+
get price_places() {
|
|
53520
|
+
return this.config.global_config.price_places;
|
|
53521
|
+
}
|
|
53522
|
+
get decimal_places() {
|
|
53523
|
+
return this.config.global_config.decimal_places;
|
|
53524
|
+
}
|
|
53525
|
+
to_f(price) {
|
|
53526
|
+
return to_f2(price, this.price_places);
|
|
53527
|
+
}
|
|
53528
|
+
to_df(quantity) {
|
|
53529
|
+
return to_f2(quantity, this.decimal_places);
|
|
53530
|
+
}
|
|
53531
|
+
pnl(kind, _position) {
|
|
53532
|
+
const position2 = _position || this.position[kind];
|
|
53533
|
+
const { entry, quantity } = position2;
|
|
53534
|
+
const notional = entry * quantity;
|
|
53535
|
+
let tp_percent = this.config.tp_percent;
|
|
53536
|
+
if (kind == "short") {
|
|
53537
|
+
tp_percent = tp_percent * this.config.short_tp_factor;
|
|
53538
|
+
}
|
|
53539
|
+
const profit = notional * (tp_percent / 100);
|
|
53540
|
+
return this.to_f(profit);
|
|
53541
|
+
}
|
|
53542
|
+
tp(kind) {
|
|
53543
|
+
let position2 = this.position[kind];
|
|
53544
|
+
if (position2.quantity == 0) {
|
|
53545
|
+
const reverse_kind = kind == "long" ? "short" : "long";
|
|
53546
|
+
position2 = this.position[reverse_kind];
|
|
53547
|
+
}
|
|
53548
|
+
const { entry, quantity } = position2;
|
|
53549
|
+
const profit = this.pnl(kind, position2);
|
|
53550
|
+
const diff = profit / (quantity || 1);
|
|
53551
|
+
return this.to_f(kind == "long" ? entry + diff : entry - diff);
|
|
53552
|
+
}
|
|
53553
|
+
calculate_fee(position2) {
|
|
53554
|
+
const { price, quantity } = position2;
|
|
53555
|
+
const fee = price * quantity * this.config.fee_percent / 100;
|
|
53556
|
+
return this.to_f(fee);
|
|
53557
|
+
}
|
|
53558
|
+
get long_tp() {
|
|
53559
|
+
return this.tp("long");
|
|
53560
|
+
}
|
|
53561
|
+
get short_tp() {
|
|
53562
|
+
return this.tp("short");
|
|
53563
|
+
}
|
|
53564
|
+
generateGapClosingAlgorithm(payload) {
|
|
53565
|
+
const { kind } = payload;
|
|
53566
|
+
const { entry, quantity } = this.position[kind];
|
|
53567
|
+
const focus_position = this.position[kind];
|
|
53568
|
+
const reverse_kind = kind == "long" ? "short" : "long";
|
|
53569
|
+
const reverse_position = this.position[reverse_kind];
|
|
53570
|
+
let _entry = this.tp(kind);
|
|
53571
|
+
let _stop = this.tp(reverse_kind);
|
|
53572
|
+
if (!_entry && !_stop) {
|
|
53573
|
+
return null;
|
|
53574
|
+
}
|
|
53575
|
+
const second_payload = {
|
|
53576
|
+
entry: _entry,
|
|
53577
|
+
stop: _stop,
|
|
53578
|
+
risk_reward: this.config.risk_reward,
|
|
53579
|
+
start_risk: this.pnl(reverse_kind),
|
|
53580
|
+
max_risk: this.config.budget
|
|
53581
|
+
};
|
|
53582
|
+
const third_payload = {
|
|
53583
|
+
entry,
|
|
53584
|
+
quantity,
|
|
53585
|
+
kind
|
|
53586
|
+
};
|
|
53587
|
+
console.log({ second_payload, third_payload });
|
|
53588
|
+
const app_config = generateOptimumAppConfig(this.config.global_config, second_payload, third_payload);
|
|
53589
|
+
if (!app_config) {
|
|
53590
|
+
return null;
|
|
53591
|
+
}
|
|
53592
|
+
const { entries, ...rest } = app_config;
|
|
53593
|
+
const risk = this.to_f(rest.risk_per_trade);
|
|
53594
|
+
const adjusted_focus_entries = entries.map((entry2) => {
|
|
53595
|
+
let adjusted_price = entry2.price;
|
|
53596
|
+
if (focus_position.quantity > 0) {
|
|
53597
|
+
if (kind === "long" && entry2.price >= focus_position.entry) {
|
|
53598
|
+
adjusted_price = focus_position.entry;
|
|
53599
|
+
} else if (kind === "short" && entry2.price <= focus_position.entry) {
|
|
53600
|
+
adjusted_price = focus_position.entry;
|
|
53601
|
+
}
|
|
53602
|
+
}
|
|
53603
|
+
return {
|
|
53604
|
+
price: adjusted_price,
|
|
53605
|
+
quantity: entry2.quantity
|
|
53606
|
+
};
|
|
53607
|
+
});
|
|
53608
|
+
const avg = determine_average_entry_and_size(adjusted_focus_entries.concat([
|
|
53609
|
+
{
|
|
53610
|
+
price: entry,
|
|
53611
|
+
quantity
|
|
53612
|
+
}
|
|
53613
|
+
]), rest.decimal_places, rest.price_places);
|
|
53614
|
+
const focus_loss = this.to_f((avg.price - second_payload.stop) * avg.quantity);
|
|
53615
|
+
let below_reverse_entries = kind === "long" ? entries.filter((u) => {
|
|
53616
|
+
return u.entry < (reverse_position.entry || focus_position.entry);
|
|
53617
|
+
}) : entries.filter((u) => {
|
|
53618
|
+
return u.entry > (reverse_position.entry || focus_position.entry);
|
|
53619
|
+
});
|
|
53620
|
+
const threshold = below_reverse_entries.at(-1);
|
|
53621
|
+
let adjusted_reverse_entries = entries.map((entry2) => {
|
|
53622
|
+
let adjusted_price = entry2.price;
|
|
53623
|
+
if (threshold) {
|
|
53624
|
+
if (reverse_kind === "short" && entry2.price > threshold.entry) {
|
|
53625
|
+
adjusted_price = threshold.entry;
|
|
53626
|
+
} else if (reverse_kind === "long" && entry2.price < threshold.entry) {
|
|
53627
|
+
adjusted_price = threshold.entry;
|
|
53628
|
+
}
|
|
53629
|
+
}
|
|
53630
|
+
return {
|
|
53631
|
+
price: adjusted_price,
|
|
53632
|
+
quantity: entry2.quantity
|
|
53633
|
+
};
|
|
53634
|
+
});
|
|
53635
|
+
const reverse_avg = determine_average_entry_and_size(adjusted_reverse_entries.concat([
|
|
53636
|
+
{
|
|
53637
|
+
price: reverse_position.entry,
|
|
53638
|
+
quantity: reverse_position.quantity
|
|
53639
|
+
}
|
|
53640
|
+
]), rest.decimal_places, rest.price_places);
|
|
53641
|
+
const reverse_pnl = this.to_f((reverse_avg.price - second_payload.stop) * reverse_avg.quantity);
|
|
53642
|
+
const fee_to_pay = this.calculate_fee({
|
|
53643
|
+
price: avg.entry,
|
|
53644
|
+
quantity: avg.quantity
|
|
53645
|
+
}) + this.calculate_fee({
|
|
53646
|
+
price: reverse_avg.entry,
|
|
53647
|
+
quantity: reverse_avg.quantity
|
|
53648
|
+
});
|
|
53649
|
+
const net_reverse_pnl = reverse_pnl - fee_to_pay;
|
|
53650
|
+
const ratio = net_reverse_pnl / focus_loss;
|
|
53651
|
+
const quantity_to_sell = this.to_df(ratio * avg.quantity);
|
|
53652
|
+
const remaining_quantity = this.to_df(avg.quantity - quantity_to_sell);
|
|
53653
|
+
return {
|
|
53654
|
+
risk,
|
|
53655
|
+
risk_reward: this.config.risk_reward,
|
|
53656
|
+
[kind]: {
|
|
53657
|
+
avg_entry: avg.entry,
|
|
53658
|
+
avg_size: avg.quantity,
|
|
53659
|
+
loss: focus_loss,
|
|
53660
|
+
stop: second_payload.stop,
|
|
53661
|
+
stop_quantity: quantity_to_sell,
|
|
53662
|
+
re_entry_quantity: remaining_quantity,
|
|
53663
|
+
initial_pnl: this.pnl(kind),
|
|
53664
|
+
tp: second_payload.entry
|
|
53665
|
+
},
|
|
53666
|
+
[reverse_kind]: {
|
|
53667
|
+
avg_entry: reverse_avg.entry,
|
|
53668
|
+
avg_size: reverse_avg.quantity,
|
|
53669
|
+
pnl: reverse_pnl,
|
|
53670
|
+
tp: second_payload.stop,
|
|
53671
|
+
re_entry_quantity: remaining_quantity,
|
|
53672
|
+
initial_pnl: this.pnl(reverse_kind)
|
|
53673
|
+
},
|
|
53674
|
+
last_entry: rest.last_value.entry,
|
|
53675
|
+
first_entry: entries.at(-1).entry,
|
|
53676
|
+
threshold
|
|
53677
|
+
};
|
|
53678
|
+
}
|
|
53679
|
+
runIterations(payload) {
|
|
53680
|
+
const { kind, iterations } = payload;
|
|
53681
|
+
const reverse_kind = kind == "long" ? "short" : "long";
|
|
53682
|
+
const result = [];
|
|
53683
|
+
let position2 = {
|
|
53684
|
+
long: this.position.long,
|
|
53685
|
+
short: this.position.short
|
|
53686
|
+
};
|
|
53687
|
+
for (let i2 = 0;i2 < iterations; i2++) {
|
|
53688
|
+
const instance = new Strategy({
|
|
53689
|
+
long: position2.long,
|
|
53690
|
+
short: position2.short,
|
|
53691
|
+
config: {
|
|
53692
|
+
...this.config,
|
|
53693
|
+
tp_percent: this.config.tp_percent + i2 * 4
|
|
53694
|
+
}
|
|
53695
|
+
});
|
|
53696
|
+
const algorithm = instance.generateGapClosingAlgorithm({
|
|
53697
|
+
kind
|
|
53698
|
+
});
|
|
53699
|
+
if (!algorithm) {
|
|
53700
|
+
console.log("No algorithm found");
|
|
53701
|
+
return result;
|
|
53702
|
+
break;
|
|
53703
|
+
}
|
|
53704
|
+
result.push(algorithm);
|
|
53705
|
+
position2[kind] = {
|
|
53706
|
+
entry: algorithm[kind].avg_entry,
|
|
53707
|
+
quantity: algorithm[kind].re_entry_quantity
|
|
53708
|
+
};
|
|
53709
|
+
position2[reverse_kind] = {
|
|
53710
|
+
entry: algorithm[reverse_kind].tp,
|
|
53711
|
+
quantity: algorithm[reverse_kind].re_entry_quantity
|
|
53712
|
+
};
|
|
53713
|
+
}
|
|
53714
|
+
return result;
|
|
53715
|
+
}
|
|
53716
|
+
getPositionAfterTp(payload) {
|
|
53717
|
+
const { kind, include_fees = false } = payload;
|
|
53718
|
+
const focus_position = this.position[kind];
|
|
53719
|
+
const reverse_kind = kind == "long" ? "short" : "long";
|
|
53720
|
+
const reverse_position = this.position[reverse_kind];
|
|
53721
|
+
const focus_tp = this.tp(kind);
|
|
53722
|
+
const focus_pnl = this.pnl(kind);
|
|
53723
|
+
const fees = include_fees ? this.calculate_fee({
|
|
53724
|
+
price: focus_tp,
|
|
53725
|
+
quantity: focus_position.quantity
|
|
53726
|
+
}) * 2 : 0;
|
|
53727
|
+
const expected_loss = (focus_pnl - fees) * this.config.reduce_ratio;
|
|
53728
|
+
const actual_loss = Math.abs(focus_tp - reverse_position.entry) * reverse_position.quantity;
|
|
53729
|
+
const ratio = expected_loss / actual_loss;
|
|
53730
|
+
const loss_quantity = this.to_df(ratio * reverse_position.quantity);
|
|
53731
|
+
const remaining_quantity = this.to_df(reverse_position.quantity - loss_quantity);
|
|
53732
|
+
return {
|
|
53733
|
+
[kind]: {
|
|
53734
|
+
entry: focus_tp,
|
|
53735
|
+
quantity: remaining_quantity
|
|
53736
|
+
},
|
|
53737
|
+
[reverse_kind]: {
|
|
53738
|
+
entry: reverse_position.entry,
|
|
53739
|
+
quantity: remaining_quantity
|
|
53740
|
+
},
|
|
53741
|
+
pnl: {
|
|
53742
|
+
[kind]: focus_pnl,
|
|
53743
|
+
[reverse_kind]: -expected_loss
|
|
53744
|
+
},
|
|
53745
|
+
spread: this.to_f(Math.abs(focus_tp - reverse_position.entry) * remaining_quantity)
|
|
53746
|
+
};
|
|
53747
|
+
}
|
|
53748
|
+
getPositionAfterIteration(payload) {
|
|
53749
|
+
const { kind, iterations, with_fees = false } = payload;
|
|
53750
|
+
let _result = this.getPositionAfterTp({
|
|
53751
|
+
kind,
|
|
53752
|
+
include_fees: with_fees
|
|
53753
|
+
});
|
|
53754
|
+
const result = [_result];
|
|
53755
|
+
for (let i2 = 0;i2 < iterations - 1; i2++) {
|
|
53756
|
+
const instance = new Strategy({
|
|
53757
|
+
long: _result.long,
|
|
53758
|
+
short: _result.short,
|
|
53759
|
+
config: {
|
|
53760
|
+
...this.config,
|
|
53761
|
+
tp_percent: this.config.tp_percent + (i2 + 1) * 0.3
|
|
53762
|
+
}
|
|
53763
|
+
});
|
|
53764
|
+
_result = instance.getPositionAfterTp({
|
|
53765
|
+
kind,
|
|
53766
|
+
include_fees: with_fees
|
|
53767
|
+
});
|
|
53768
|
+
result.push(_result);
|
|
53769
|
+
}
|
|
53770
|
+
return result;
|
|
53771
|
+
}
|
|
53772
|
+
}
|
|
53773
|
+
|
|
53774
|
+
// src/exchanges/binance.ts
|
|
53775
|
+
var import_binance = __toESM(require_lib2(), 1);
|
|
53776
|
+
var CONSTANTS = {
|
|
53777
|
+
SPOT_TO_FIAT: "MAIN_C2C",
|
|
53778
|
+
SPOT_TO_USDT_FUTURE: "MAIN_UMFUTURE",
|
|
53779
|
+
SPOT_TO_COIN_FUTURE: "MAIN_CMFUTURE",
|
|
53780
|
+
SPOT_TO_MARGIN_CROSS: "MAIN_MARGIN",
|
|
53781
|
+
SPOT_TO_MINING: "MAIN_MINING",
|
|
53782
|
+
FIAT_TO_SPOT: "C2C_MAIN",
|
|
53783
|
+
FIAT_TO_USDT_FUTURE: "C2C_UMFUTURE",
|
|
53784
|
+
FIAT_TO_MINING: "C2C_MINING",
|
|
53785
|
+
USDT_FUTURE_TO_SPOT: "UMFUTURE_MAIN",
|
|
53786
|
+
USDT_FUTURE_TO_FIAT: "UMFUTURE_C2C",
|
|
53787
|
+
USDT_FUTURE_TO_MARGIN_CROSS: "UMFUTURE_MARGIN",
|
|
53788
|
+
COIN_FUTURE_TO_SPOT: "CMFUTURE_MAIN",
|
|
53789
|
+
MARGIN_CROSS_TO_SPOT: "MARGIN_MAIN",
|
|
53790
|
+
MARGIN_CROSS_TO_USDT_FUTURE: "MARGIN_UMFUTURE",
|
|
53791
|
+
MINING_TO_SPOT: "MINING_MAIN",
|
|
53792
|
+
MINING_TO_USDT_FUTURE: "MINING_UMFUTURE",
|
|
53034
53793
|
MINING_TO_FIAT: "MINING_C2C"
|
|
53035
53794
|
};
|
|
53036
53795
|
|
|
@@ -53260,8 +54019,8 @@ async function createLimitPurchaseOrders(client, symbol, priceFormat, quantityFo
|
|
|
53260
54019
|
const createOrder = (x) => {
|
|
53261
54020
|
const v = {
|
|
53262
54021
|
symbol: symbol.toUpperCase(),
|
|
53263
|
-
price: x.price ?
|
|
53264
|
-
quantity: x.quantity ?
|
|
54022
|
+
price: x.price ? to_f2(x.price, priceFormat) : 0,
|
|
54023
|
+
quantity: x.quantity ? to_f2(x.quantity, quantityFormat) : 0,
|
|
53265
54024
|
side: x.side?.toUpperCase() || "",
|
|
53266
54025
|
type: "LIMIT",
|
|
53267
54026
|
positionSide: x.kind.toUpperCase(),
|
|
@@ -53276,7 +54035,7 @@ async function createLimitPurchaseOrders(client, symbol, priceFormat, quantityFo
|
|
|
53276
54035
|
delete v.timeInForce;
|
|
53277
54036
|
v.type = `${v.type}_MARKET`.toUpperCase();
|
|
53278
54037
|
} else if (typeof x.stop === "number") {
|
|
53279
|
-
v.stopPrice =
|
|
54038
|
+
v.stopPrice = to_f2(x.stop, priceFormat);
|
|
53280
54039
|
}
|
|
53281
54040
|
}
|
|
53282
54041
|
if (x.force_market) {
|
|
@@ -53414,7 +54173,28 @@ async function placeTpOrder(client, payload) {
|
|
|
53414
54173
|
return { error: "No quantity" };
|
|
53415
54174
|
}
|
|
53416
54175
|
async function placeStopOrder(client, payload) {
|
|
53417
|
-
const {
|
|
54176
|
+
const {
|
|
54177
|
+
price_places = "%.1f",
|
|
54178
|
+
decimal_places = "%.3f",
|
|
54179
|
+
symbol,
|
|
54180
|
+
current_price,
|
|
54181
|
+
kind,
|
|
54182
|
+
stop,
|
|
54183
|
+
quantity,
|
|
54184
|
+
cancel
|
|
54185
|
+
} = payload;
|
|
54186
|
+
if (kind === "long" && current_price < stop || kind === "short" && current_price > stop) {
|
|
54187
|
+
console.log(`Diverting to TP order for ${symbol} (${kind}). Current: ${current_price}, Stop: ${stop}`);
|
|
54188
|
+
return placeTpOrder(client, {
|
|
54189
|
+
symbol,
|
|
54190
|
+
tp: stop,
|
|
54191
|
+
quantity,
|
|
54192
|
+
kind,
|
|
54193
|
+
cancel,
|
|
54194
|
+
price_places,
|
|
54195
|
+
decimal_places
|
|
54196
|
+
});
|
|
54197
|
+
}
|
|
53418
54198
|
if (payload.cancel) {
|
|
53419
54199
|
await cancelAllOrders(client, symbol, {
|
|
53420
54200
|
type: "stop",
|
|
@@ -53515,14 +54295,14 @@ async function getOpenOrders(client, symbol, type) {
|
|
|
53515
54295
|
async function getWalletBalance(client, asset = "USDT") {
|
|
53516
54296
|
const response = await client.getBalanceV3();
|
|
53517
54297
|
const balance = response.find((x) => x.asset.toLowerCase() === asset.toLowerCase())?.balance;
|
|
53518
|
-
return balance ?
|
|
54298
|
+
return balance ? to_f2(balance, "%.2f") : 0;
|
|
53519
54299
|
}
|
|
53520
54300
|
async function allWalletBalances(client) {
|
|
53521
54301
|
const response = await client.getBalanceV3();
|
|
53522
54302
|
return response.map((x) => ({
|
|
53523
54303
|
type: "future",
|
|
53524
54304
|
asset: x.asset,
|
|
53525
|
-
balance:
|
|
54305
|
+
balance: to_f2(x.balance, "%.8f")
|
|
53526
54306
|
}));
|
|
53527
54307
|
}
|
|
53528
54308
|
function buildPosition(position2, orders, options) {
|
|
@@ -53778,6 +54558,7 @@ class BinanceExchange {
|
|
|
53778
54558
|
}
|
|
53779
54559
|
async placeStopOrders(payload) {
|
|
53780
54560
|
if (payload.place) {
|
|
54561
|
+
const current_price = await this.get_current_price(payload.symbol);
|
|
53781
54562
|
return placeStopOrder(this.client, {
|
|
53782
54563
|
symbol: payload.symbol,
|
|
53783
54564
|
stop: payload.stop,
|
|
@@ -53787,7 +54568,8 @@ class BinanceExchange {
|
|
|
53787
54568
|
cancel: true,
|
|
53788
54569
|
is_limit: true,
|
|
53789
54570
|
price_places: payload.price_places,
|
|
53790
|
-
decimal_places: payload.decimal_places
|
|
54571
|
+
decimal_places: payload.decimal_places,
|
|
54572
|
+
current_price
|
|
53791
54573
|
});
|
|
53792
54574
|
}
|
|
53793
54575
|
}
|
|
@@ -53817,7 +54599,7 @@ class BinanceExchange {
|
|
|
53817
54599
|
place = false
|
|
53818
54600
|
} = payload;
|
|
53819
54601
|
const totalQuantity = orders.reduce((sum, order) => sum + (order.quantity || 0), 0);
|
|
53820
|
-
let runningTotal =
|
|
54602
|
+
let runningTotal = to_f2(totalQuantity, decimal_places);
|
|
53821
54603
|
let sortedOrders = [...orders].sort((a, b) => (a.entry || 0) - (b.entry || 0));
|
|
53822
54604
|
if (kind === "short") {
|
|
53823
54605
|
sortedOrders.reverse();
|
|
@@ -53829,7 +54611,7 @@ class BinanceExchange {
|
|
|
53829
54611
|
cumulative_quantity: runningTotal
|
|
53830
54612
|
});
|
|
53831
54613
|
runningTotal -= order.quantity;
|
|
53832
|
-
runningTotal =
|
|
54614
|
+
runningTotal = to_f2(runningTotal, decimal_places);
|
|
53833
54615
|
}
|
|
53834
54616
|
const positions = await getPositionInfo(this.client, symbol);
|
|
53835
54617
|
const position2 = positions[kind] || {
|
|
@@ -53892,6 +54674,7 @@ class BinanceExchange {
|
|
|
53892
54674
|
symbol: payload.symbol,
|
|
53893
54675
|
tp: payload.take_profit,
|
|
53894
54676
|
kind: payload.kind,
|
|
54677
|
+
quantity: payload.quantity,
|
|
53895
54678
|
cancel: true,
|
|
53896
54679
|
price_places: payload.price_places,
|
|
53897
54680
|
decimal_places: payload.decimal_places
|
|
@@ -53912,6 +54695,7 @@ class BinanceExchange {
|
|
|
53912
54695
|
});
|
|
53913
54696
|
}
|
|
53914
54697
|
async placeStopOrder(payload) {
|
|
54698
|
+
const current_price = await this.get_current_price(payload.symbol);
|
|
53915
54699
|
return await placeStopOrder(this.client, {
|
|
53916
54700
|
symbol: payload.symbol,
|
|
53917
54701
|
stop: payload.stop,
|
|
@@ -53921,7 +54705,8 @@ class BinanceExchange {
|
|
|
53921
54705
|
cancel: true,
|
|
53922
54706
|
is_limit: true,
|
|
53923
54707
|
price_places: payload.price_places,
|
|
53924
|
-
decimal_places: payload.decimal_places
|
|
54708
|
+
decimal_places: payload.decimal_places,
|
|
54709
|
+
current_price
|
|
53925
54710
|
});
|
|
53926
54711
|
}
|
|
53927
54712
|
async setLeverage(payload) {
|
|
@@ -53975,7 +54760,7 @@ class BinanceExchange {
|
|
|
53975
54760
|
const currentPrice = await getCurrentPrice(this.client, symbol);
|
|
53976
54761
|
const price_places = isBTC ? "%.1f" : `%.${getPricePlaces(currentPrice)}f`;
|
|
53977
54762
|
const decimal_places = `%.${target.quantityPrecision}f`;
|
|
53978
|
-
const min_size =
|
|
54763
|
+
const min_size = to_f2((minNotional || 0) / support, decimal_places);
|
|
53979
54764
|
const configObj = {
|
|
53980
54765
|
support,
|
|
53981
54766
|
resistance,
|
|
@@ -54131,8 +54916,8 @@ async function createLimitPurchaseOrders2(client, symbol, priceFormat, quantityF
|
|
|
54131
54916
|
const createOrder = (x) => {
|
|
54132
54917
|
const v = {
|
|
54133
54918
|
symbol: symbol.toUpperCase(),
|
|
54134
|
-
price: (x.price ?
|
|
54135
|
-
qty: (x.quantity ?
|
|
54919
|
+
price: (x.price ? to_f2(x.price, priceFormat) : 0).toString(),
|
|
54920
|
+
qty: (x.quantity ? to_f2(x.quantity, quantityFormat) : 0).toString(),
|
|
54136
54921
|
side: titleCase(x.side || ""),
|
|
54137
54922
|
orderType: "LIMIT",
|
|
54138
54923
|
positionIdx: x.kind === "long" ? 1 : 2,
|
|
@@ -54149,12 +54934,12 @@ async function createLimitPurchaseOrders2(client, symbol, priceFormat, quantityF
|
|
|
54149
54934
|
delete v.timeInForce;
|
|
54150
54935
|
v.orderType = `MARKET`;
|
|
54151
54936
|
} else if (typeof x.stop === "number") {
|
|
54152
|
-
v.triggerPrice =
|
|
54937
|
+
v.triggerPrice = to_f2(x.stop, priceFormat).toString();
|
|
54153
54938
|
}
|
|
54154
54939
|
if (x.kind === "long" && x.side === "sell" || x.kind === "short" && x.side === "buy") {
|
|
54155
54940
|
v.tpslMode = "Partial";
|
|
54156
54941
|
v.slOrderType = "Limit";
|
|
54157
|
-
v.slLimitPrice =
|
|
54942
|
+
v.slLimitPrice = to_f2(v.triggerPrice, priceFormat).toString();
|
|
54158
54943
|
if (x.is_market) {
|
|
54159
54944
|
v.slOrderType = "Market";
|
|
54160
54945
|
v.tpslMode = "Full";
|
|
@@ -54378,7 +55163,7 @@ async function getWalletBalance2(client, asset = "USDT") {
|
|
|
54378
55163
|
accountType: "UNIFIED",
|
|
54379
55164
|
coin: asset
|
|
54380
55165
|
});
|
|
54381
|
-
return
|
|
55166
|
+
return to_f2(response.result.list[0].totalWalletBalance, "%.2f");
|
|
54382
55167
|
}
|
|
54383
55168
|
async function allWalletBalances2(client) {
|
|
54384
55169
|
const response = await client.getWalletBalance({
|
|
@@ -54388,7 +55173,7 @@ async function allWalletBalances2(client) {
|
|
|
54388
55173
|
return response.result.list[0].coin.map((x) => ({
|
|
54389
55174
|
type: "future",
|
|
54390
55175
|
asset: x.coin,
|
|
54391
|
-
balance:
|
|
55176
|
+
balance: to_f2(x.walletBalance, "%.8f")
|
|
54392
55177
|
}));
|
|
54393
55178
|
}
|
|
54394
55179
|
function buildPosition2(position2, orders, options) {
|
|
@@ -54604,7 +55389,7 @@ class BybitExchange {
|
|
|
54604
55389
|
place = false
|
|
54605
55390
|
} = payload;
|
|
54606
55391
|
const totalQuantity = orders.reduce((sum, order) => sum + (order.quantity || 0), 0);
|
|
54607
|
-
let runningTotal =
|
|
55392
|
+
let runningTotal = to_f2(totalQuantity, decimal_places);
|
|
54608
55393
|
let sortedOrders = [...orders].sort((a, b) => (a.entry || 0) - (b.entry || 0));
|
|
54609
55394
|
if (kind === "short") {
|
|
54610
55395
|
sortedOrders.reverse();
|
|
@@ -54616,7 +55401,7 @@ class BybitExchange {
|
|
|
54616
55401
|
cumulative_quantity: runningTotal
|
|
54617
55402
|
});
|
|
54618
55403
|
runningTotal -= order.quantity;
|
|
54619
|
-
runningTotal =
|
|
55404
|
+
runningTotal = to_f2(runningTotal, decimal_places);
|
|
54620
55405
|
}
|
|
54621
55406
|
const positions = await getPositionInfo2(this.client, symbol);
|
|
54622
55407
|
const position2 = positions[kind] || {
|
|
@@ -54755,7 +55540,7 @@ class BybitExchange {
|
|
|
54755
55540
|
function determine_liquidation(balance_diff, position2) {
|
|
54756
55541
|
const long_liquidation = position2.price - balance_diff / position2.quantity;
|
|
54757
55542
|
const short_liquidation = position2.price + balance_diff / position2.quantity;
|
|
54758
|
-
return position2.kind === "long" ?
|
|
55543
|
+
return position2.kind === "long" ? to_f2(long_liquidation, "%.2f") : to_f2(short_liquidation, "%.2f");
|
|
54759
55544
|
}
|
|
54760
55545
|
function calculate_avg_entry(kind, {
|
|
54761
55546
|
orders: _orders,
|
|
@@ -54888,28 +55673,43 @@ function calculate_avg_entry2(kind, {
|
|
|
54888
55673
|
], decimal_places, price_places);
|
|
54889
55674
|
return avg_entry;
|
|
54890
55675
|
}
|
|
54891
|
-
function calculateHedge(
|
|
55676
|
+
function calculateHedge(payload) {
|
|
55677
|
+
const {
|
|
55678
|
+
kind,
|
|
55679
|
+
active_account,
|
|
55680
|
+
targetPnl: _targetPnl = 100,
|
|
55681
|
+
ratio = 0.9,
|
|
55682
|
+
use_full = false,
|
|
55683
|
+
not_reduce: _not_reduce = false,
|
|
55684
|
+
sell_ratio: _sell_ratio = 1
|
|
55685
|
+
} = payload;
|
|
55686
|
+
let sell_ratio = _sell_ratio;
|
|
55687
|
+
if (sell_ratio === 0) {
|
|
55688
|
+
sell_ratio = 1;
|
|
55689
|
+
}
|
|
54892
55690
|
const oppositeKind = kind === "long" ? "short" : "long";
|
|
54893
55691
|
const avg_values = {
|
|
54894
55692
|
long: calculate_avg_entry2("long", active_account),
|
|
54895
55693
|
short: calculate_avg_entry2("short", active_account)
|
|
54896
55694
|
};
|
|
55695
|
+
const targetPnl = _targetPnl * sell_ratio;
|
|
54897
55696
|
const position2 = active_account.position[kind];
|
|
55697
|
+
const position_quantity = position2.quantity * sell_ratio;
|
|
54898
55698
|
const oppositePosition = use_full ? avg_values[oppositeKind] : active_account.position[oppositeKind];
|
|
54899
|
-
const takeProfitPrice = kind === "long" ? position2.entry + targetPnl /
|
|
55699
|
+
const takeProfitPrice = kind === "long" ? position2.entry + targetPnl / position_quantity : position2.entry - targetPnl / position_quantity;
|
|
54900
55700
|
const stopLossPrice = takeProfitPrice;
|
|
54901
55701
|
const priceDifference = oppositeKind === "short" ? stopLossPrice - oppositePosition.entry : oppositePosition.entry - stopLossPrice;
|
|
54902
55702
|
const stopLossAmount = targetPnl * ratio;
|
|
54903
55703
|
const stopLossQuantity = Math.min(stopLossAmount / priceDifference, oppositePosition.quantity);
|
|
54904
55704
|
return {
|
|
54905
55705
|
[kind]: {
|
|
54906
|
-
price:
|
|
54907
|
-
quantity:
|
|
55706
|
+
price: to_f2(takeProfitPrice, active_account.price_places),
|
|
55707
|
+
quantity: to_f2(position_quantity || 0, active_account.decimal_places),
|
|
54908
55708
|
type: "TAKE_PROFIT"
|
|
54909
55709
|
},
|
|
54910
55710
|
[oppositeKind]: {
|
|
54911
|
-
stop_price:
|
|
54912
|
-
quantity:
|
|
55711
|
+
stop_price: to_f2(stopLossPrice, active_account.price_places),
|
|
55712
|
+
quantity: to_f2(stopLossQuantity || 0, active_account.decimal_places),
|
|
54913
55713
|
type: "STOP_LOSS"
|
|
54914
55714
|
}
|
|
54915
55715
|
};
|
|
@@ -54930,669 +55730,189 @@ function findStopOrders(kind, account) {
|
|
|
54930
55730
|
}
|
|
54931
55731
|
function findEntryLimitOrders(kind, account, current_price, minimum_pnl) {
|
|
54932
55732
|
const position2 = account.position[kind];
|
|
54933
|
-
const pnl = (current_price - position2.entry) * position2.quantity;
|
|
54934
|
-
const orders = account.orders[kind].entries;
|
|
54935
|
-
const side = kind === "long" ? "buy" : "sell";
|
|
54936
|
-
let limit_orders = orders.filter((order) => order.stop === 0 && order.side === side).filter((o) => {
|
|
54937
|
-
if (kind === "long" && pnl < 0 && Math.abs(pnl) > minimum_pnl) {
|
|
54938
|
-
return true;
|
|
54939
|
-
}
|
|
54940
|
-
if (kind === "short" && pnl > 0 && Math.abs(pnl) > minimum_pnl) {
|
|
54941
|
-
return true;
|
|
54942
|
-
}
|
|
54943
|
-
return false;
|
|
54944
|
-
});
|
|
54945
|
-
if (limit_orders.length > 1) {
|
|
54946
|
-
limit_orders = [limit_orders[limit_orders.length - 1]];
|
|
54947
|
-
}
|
|
54948
|
-
return limit_orders.map((o) => ({ ...o, id: o.order_id }));
|
|
54949
|
-
}
|
|
54950
|
-
function processPosition(codeNode, input, kind) {
|
|
54951
|
-
const { active_account, current_price } = input;
|
|
54952
|
-
const { use_full = false } = codeNode;
|
|
54953
|
-
const long_position = active_account.position.long;
|
|
54954
|
-
const short_position = active_account.position.short;
|
|
54955
|
-
const vv = calculateHedge(kind, active_account, codeNode.profit || 50, codeNode.ratio, use_full, codeNode.not_reduce);
|
|
54956
|
-
const reverse_kind = kind === "long" ? "short" : "long";
|
|
54957
|
-
const a_stops = findStopOrders(reverse_kind, active_account);
|
|
54958
|
-
const a_limits = findEntryLimitOrders(reverse_kind, active_account, current_price, codeNode.minimum_pnl).filter((u) => codeNode.increase);
|
|
54959
|
-
const orders_to_cancel = a_limits.concat(a_stops);
|
|
54960
|
-
return {
|
|
54961
|
-
exchange: input.exchange,
|
|
54962
|
-
result: vv,
|
|
54963
|
-
to_place: {
|
|
54964
|
-
...vv[reverse_kind],
|
|
54965
|
-
kind: reverse_kind,
|
|
54966
|
-
side: reverse_kind === "long" ? "buy" : "sell"
|
|
54967
|
-
},
|
|
54968
|
-
orders_to_cancel,
|
|
54969
|
-
stop: to_f(vv[kind].price, active_account.price_places),
|
|
54970
|
-
quantity: vv[kind].quantity,
|
|
54971
|
-
kind,
|
|
54972
|
-
type: JSON.stringify("TAKE_PROFIT"),
|
|
54973
|
-
id: active_account.id,
|
|
54974
|
-
position: kind === "long" ? long_position : short_position,
|
|
54975
|
-
opposite_position: kind === "long" ? short_position : long_position,
|
|
54976
|
-
long_position,
|
|
54977
|
-
short_position,
|
|
54978
|
-
owner: active_account.owner,
|
|
54979
|
-
risk: codeNode.profit || 150,
|
|
54980
|
-
increase: codeNode.increase,
|
|
54981
|
-
not_reduce: codeNode.not_reduce,
|
|
54982
|
-
price_places: active_account.price_places,
|
|
54983
|
-
decimal_places: active_account.decimal_places
|
|
54984
|
-
};
|
|
54985
|
-
}
|
|
54986
|
-
async function reduceMajorPositionCalculation(input, exchange_instance) {
|
|
54987
|
-
try {
|
|
54988
|
-
let conditionsCheck = input.position.tp_quantity !== input.quantity || input.position.take_profit !== to_f(input.stop, input.price_places);
|
|
54989
|
-
if (input.opposite_position.stop_quantity) {
|
|
54990
|
-
conditionsCheck = conditionsCheck || input.opposite_position.stop_quantity !== input.to_place.quantity;
|
|
54991
|
-
}
|
|
54992
|
-
console.log("conditionsCheck for ", input.position.kind, conditionsCheck);
|
|
54993
|
-
console.log("opposite_check", {
|
|
54994
|
-
kind: input.opposite_position.kind,
|
|
54995
|
-
stop_loss: input.opposite_position.stop_loss,
|
|
54996
|
-
stop_price: input.to_place.stop_price,
|
|
54997
|
-
owner: input.owner,
|
|
54998
|
-
not_reduce: input.to_place,
|
|
54999
|
-
stop_to_place: {
|
|
55000
|
-
owner: input.owner,
|
|
55001
|
-
symbol: input.position.symbol,
|
|
55002
|
-
kind: input.to_place.kind,
|
|
55003
|
-
stop: input.to_place.stop_price,
|
|
55004
|
-
quantity: Math.abs(input.to_place.quantity)
|
|
55005
|
-
}
|
|
55006
|
-
});
|
|
55007
|
-
if (conditionsCheck) {
|
|
55008
|
-
const async_tp = async () => {
|
|
55009
|
-
if (input.stop && input.stop !== Infinity) {
|
|
55010
|
-
await exchange_instance.placeTpOrder({
|
|
55011
|
-
symbol: input.position.symbol,
|
|
55012
|
-
kind: input.kind,
|
|
55013
|
-
take_profit: input.stop,
|
|
55014
|
-
price_places: input.price_places,
|
|
55015
|
-
decimal_places: input.decimal_places
|
|
55016
|
-
});
|
|
55017
|
-
}
|
|
55018
|
-
};
|
|
55019
|
-
const async_increase = async () => {
|
|
55020
|
-
if (input.increase && input.to_place.stop_price) {
|
|
55021
|
-
await exchange_instance.placeLimitOrder({
|
|
55022
|
-
symbol: input.position.symbol,
|
|
55023
|
-
kind: input.to_place.kind,
|
|
55024
|
-
price: input.to_place.stop_price,
|
|
55025
|
-
quantity: input.to_place.quantity,
|
|
55026
|
-
price_places: input.price_places,
|
|
55027
|
-
decimal_places: input.decimal_places
|
|
55028
|
-
}).then((r2) => {
|
|
55029
|
-
console.log("placeNewOrderData", r2);
|
|
55030
|
-
});
|
|
55031
|
-
}
|
|
55032
|
-
};
|
|
55033
|
-
let placeNewOrderData = null;
|
|
55034
|
-
const async_place_stop = async () => {
|
|
55035
|
-
if (!input.not_reduce && input.to_place.stop_price && input.to_place.quantity) {
|
|
55036
|
-
await exchange_instance.placeStopOrder({
|
|
55037
|
-
symbol: input.position.symbol,
|
|
55038
|
-
kind: input.to_place.kind,
|
|
55039
|
-
stop: input.to_place.stop_price,
|
|
55040
|
-
quantity: Math.abs(input.to_place.quantity),
|
|
55041
|
-
price_places: input.price_places,
|
|
55042
|
-
decimal_places: input.decimal_places
|
|
55043
|
-
});
|
|
55044
|
-
}
|
|
55045
|
-
};
|
|
55046
|
-
const [_tp, _increase, _place_stop] = await Promise.all([
|
|
55047
|
-
async_tp(),
|
|
55048
|
-
async_increase(),
|
|
55049
|
-
async_place_stop()
|
|
55050
|
-
]);
|
|
55051
|
-
return {
|
|
55052
|
-
newOrderResponse: placeNewOrderData
|
|
55053
|
-
};
|
|
55054
|
-
} else {
|
|
55055
|
-
return {
|
|
55056
|
-
message: "No changes needed, conditions not met",
|
|
55057
|
-
input
|
|
55058
|
-
};
|
|
55059
|
-
}
|
|
55060
|
-
} catch (error) {
|
|
55061
|
-
console.error("Error in reduceMajorPositionCalculation:", error);
|
|
55062
|
-
throw error;
|
|
55063
|
-
}
|
|
55064
|
-
}
|
|
55065
|
-
async function reduceMajorPositionEntry(input, accountInfo, trigger2, exchange_instance) {
|
|
55066
|
-
let results = {};
|
|
55067
|
-
try {
|
|
55068
|
-
const async_long = async () => {
|
|
55069
|
-
if (input.long) {
|
|
55070
|
-
const workflowInput = processPosition(input.long, accountInfo, "long");
|
|
55071
|
-
if (trigger2.long) {
|
|
55072
|
-
try {
|
|
55073
|
-
await reduceMajorPositionCalculation(workflowInput, exchange_instance);
|
|
55074
|
-
} catch (error) {
|
|
55075
|
-
console.error("Error in reduceMajorPositionCalculation:", error);
|
|
55076
|
-
}
|
|
55077
|
-
}
|
|
55078
|
-
return workflowInput;
|
|
55079
|
-
}
|
|
55080
|
-
return null;
|
|
55081
|
-
};
|
|
55082
|
-
const async_short = async () => {
|
|
55083
|
-
if (input.short) {
|
|
55084
|
-
const workflowInput = processPosition(input.short, accountInfo, "short");
|
|
55085
|
-
if (trigger2.short) {
|
|
55086
|
-
try {
|
|
55087
|
-
await reduceMajorPositionCalculation(workflowInput, exchange_instance);
|
|
55088
|
-
} catch (error) {
|
|
55089
|
-
console.error("Error in reduceMajorPositionCalculation:", error);
|
|
55090
|
-
}
|
|
55091
|
-
}
|
|
55092
|
-
return workflowInput;
|
|
55093
|
-
}
|
|
55094
|
-
return null;
|
|
55095
|
-
};
|
|
55096
|
-
const [long, short] = await Promise.all([async_long(), async_short()]);
|
|
55097
|
-
results.long = long;
|
|
55098
|
-
results.short = short;
|
|
55099
|
-
return results;
|
|
55100
|
-
} catch (error) {
|
|
55101
|
-
console.error("Error in reduceMajorPositionEntry:", error);
|
|
55102
|
-
throw error;
|
|
55103
|
-
}
|
|
55104
|
-
}
|
|
55105
|
-
|
|
55106
|
-
// src/helpers/shared.ts
|
|
55107
|
-
function buildConfig(app_config, {
|
|
55108
|
-
take_profit,
|
|
55109
|
-
entry,
|
|
55110
|
-
stop,
|
|
55111
|
-
raw_instance,
|
|
55112
|
-
risk,
|
|
55113
|
-
no_of_trades,
|
|
55114
|
-
min_profit = 0,
|
|
55115
|
-
risk_reward,
|
|
55116
|
-
kind,
|
|
55117
|
-
increase,
|
|
55118
|
-
gap,
|
|
55119
|
-
rr = 1,
|
|
55120
|
-
price_places = "%.1f",
|
|
55121
|
-
decimal_places = "%.3f"
|
|
55122
|
-
}) {
|
|
55123
|
-
let fee = app_config.fee / 100;
|
|
55124
|
-
let working_risk = risk || app_config.risk_per_trade;
|
|
55125
|
-
let trade_no = no_of_trades || app_config.risk_reward;
|
|
55126
|
-
const config2 = {
|
|
55127
|
-
focus: app_config.focus,
|
|
55128
|
-
fee,
|
|
55129
|
-
budget: app_config.budget,
|
|
55130
|
-
risk_reward: risk_reward || trade_no,
|
|
55131
|
-
support: app_config.support,
|
|
55132
|
-
resistance: app_config.resistance,
|
|
55133
|
-
price_places: app_config.price_places || price_places,
|
|
55134
|
-
decimal_places,
|
|
55135
|
-
percent_change: app_config.percent_change / app_config.tradeSplit,
|
|
55136
|
-
risk_per_trade: working_risk,
|
|
55137
|
-
take_profit: take_profit || app_config.take_profit,
|
|
55138
|
-
increase_position: increase,
|
|
55139
|
-
minimum_size: app_config.min_size,
|
|
55140
|
-
entry,
|
|
55141
|
-
stop,
|
|
55142
|
-
kind: app_config.kind,
|
|
55143
|
-
gap,
|
|
55144
|
-
min_profit: min_profit || app_config.min_profit,
|
|
55145
|
-
rr: rr || 1
|
|
55146
|
-
};
|
|
55147
|
-
const instance = new Signal(config2);
|
|
55148
|
-
if (raw_instance) {
|
|
55149
|
-
return instance;
|
|
55150
|
-
}
|
|
55151
|
-
if (!stop) {
|
|
55152
|
-
return [];
|
|
55153
|
-
}
|
|
55154
|
-
const condition = (kind === "long" ? entry > app_config.support : entry >= app_config.support) && stop >= app_config.support * 0.999;
|
|
55155
|
-
if (kind === "short") {
|
|
55156
|
-
console.log("condition", condition, entry === stop);
|
|
55157
|
-
}
|
|
55158
|
-
console.log({ entry, support: app_config.support, stop });
|
|
55159
|
-
const result = entry === stop ? [] : condition ? instance.build_entry({
|
|
55160
|
-
current_price: entry,
|
|
55161
|
-
stop_loss: stop,
|
|
55162
|
-
risk: working_risk,
|
|
55163
|
-
kind: kind || app_config.kind,
|
|
55164
|
-
no_of_trades: trade_no
|
|
55165
|
-
}) || [] : [];
|
|
55166
|
-
return computeTotalAverageForEachTrade(result, config2);
|
|
55167
|
-
}
|
|
55168
|
-
function buildAvg({
|
|
55169
|
-
_trades,
|
|
55170
|
-
kind
|
|
55171
|
-
}) {
|
|
55172
|
-
let avg = determine_average_entry_and_size(_trades?.map((r2) => ({
|
|
55173
|
-
price: r2.entry,
|
|
55174
|
-
quantity: r2.quantity
|
|
55175
|
-
})) || []);
|
|
55176
|
-
const stop_prices = _trades.map((o) => o.stop);
|
|
55177
|
-
const stop_loss = kind === "long" ? Math.min(...stop_prices) : Math.max(...stop_prices);
|
|
55178
|
-
avg.pnl = pnl_default.determine_pnl(avg.price, stop_loss, avg.quantity, kind);
|
|
55179
|
-
return avg;
|
|
55180
|
-
}
|
|
55181
|
-
function sortedBuildConfig(app_config, options) {
|
|
55182
|
-
const sorted = buildConfig(app_config, options).sort((a, b) => app_config.kind === "long" ? a.entry - b.entry : b.entry - b.entry).filter((x) => {
|
|
55183
|
-
if (app_config.symbol === "BTCUSDT") {
|
|
55184
|
-
return x.quantity <= 0.03;
|
|
55185
|
-
}
|
|
55186
|
-
return true;
|
|
55187
|
-
});
|
|
55188
|
-
return sorted.map((k, i2) => {
|
|
55189
|
-
const arrSet = sorted.slice(0, i2 + 1);
|
|
55190
|
-
const avg_values = determine_average_entry_and_size(arrSet.map((u) => ({ price: u.entry, quantity: u.quantity })), app_config.decimal_places, app_config.price_places);
|
|
55191
|
-
return {
|
|
55192
|
-
...k,
|
|
55193
|
-
reverse_avg_entry: avg_values.price,
|
|
55194
|
-
reverse_avg_quantity: avg_values.quantity
|
|
55195
|
-
};
|
|
55196
|
-
});
|
|
55197
|
-
}
|
|
55198
|
-
function get_app_config_and_max_size(config2, payload) {
|
|
55199
|
-
const app_config = {
|
|
55200
|
-
kind: payload.kind,
|
|
55201
|
-
entry: payload.entry,
|
|
55202
|
-
stop: payload.stop,
|
|
55203
|
-
risk_per_trade: config2.risk,
|
|
55204
|
-
risk_reward: config2.risk_reward || 199,
|
|
55205
|
-
support: to_f(config2.support, config2.price_places),
|
|
55206
|
-
resistance: to_f(config2.resistance, config2.price_places),
|
|
55207
|
-
focus: payload.entry,
|
|
55208
|
-
fee: 0,
|
|
55209
|
-
percent_change: config2.stop_percent / 100,
|
|
55210
|
-
tradeSplit: 1,
|
|
55211
|
-
gap: 1,
|
|
55212
|
-
min_size: config2.min_size,
|
|
55213
|
-
budget: 0,
|
|
55214
|
-
price_places: config2.price_places,
|
|
55215
|
-
decimal_places: config2.decimal_places,
|
|
55216
|
-
min_profit: config2.profit_percent * config2.profit / 100
|
|
55217
|
-
};
|
|
55218
|
-
const initialResult = sortedBuildConfig(app_config, {
|
|
55219
|
-
entry: app_config.entry,
|
|
55220
|
-
stop: app_config.stop,
|
|
55221
|
-
kind: app_config.kind,
|
|
55222
|
-
risk: app_config.risk_per_trade,
|
|
55223
|
-
risk_reward: app_config.risk_reward,
|
|
55224
|
-
increase: true,
|
|
55225
|
-
gap: app_config.gap,
|
|
55226
|
-
price_places: app_config.price_places,
|
|
55227
|
-
decimal_places: app_config.decimal_places
|
|
55228
|
-
});
|
|
55229
|
-
const max_size = initialResult[0]?.avg_size;
|
|
55230
|
-
const last_value = initialResult[0];
|
|
55231
|
-
const entries = initialResult.map((x) => ({
|
|
55232
|
-
entry: x.entry,
|
|
55233
|
-
avg_entry: x.avg_entry,
|
|
55234
|
-
avg_size: x.avg_size,
|
|
55235
|
-
neg_pnl: x.neg_pnl,
|
|
55236
|
-
quantity: x.quantity
|
|
55237
|
-
}));
|
|
55238
|
-
return {
|
|
55239
|
-
app_config,
|
|
55240
|
-
max_size,
|
|
55241
|
-
last_value,
|
|
55242
|
-
entries
|
|
55243
|
-
};
|
|
55244
|
-
}
|
|
55245
|
-
function buildAppConfig(config2, payload) {
|
|
55246
|
-
const { app_config, max_size, last_value, entries } = get_app_config_and_max_size({
|
|
55247
|
-
...config2,
|
|
55248
|
-
risk: payload.risk,
|
|
55249
|
-
profit: payload.profit || 500,
|
|
55250
|
-
risk_reward: payload.risk_reward,
|
|
55251
|
-
accounts: [],
|
|
55252
|
-
reduce_percent: 90,
|
|
55253
|
-
reverse_factor: 1,
|
|
55254
|
-
profit_percent: 0,
|
|
55255
|
-
kind: payload.entry > payload.stop ? "long" : "short",
|
|
55256
|
-
symbol: payload.symbol
|
|
55257
|
-
}, {
|
|
55258
|
-
entry: payload.entry,
|
|
55259
|
-
stop: payload.stop,
|
|
55260
|
-
kind: payload.entry > payload.stop ? "long" : "short"
|
|
55261
|
-
});
|
|
55262
|
-
app_config.max_size = max_size;
|
|
55263
|
-
app_config.entry = payload.entry || app_config.entry;
|
|
55264
|
-
app_config.stop = payload.stop || app_config.stop;
|
|
55265
|
-
app_config.last_value = last_value;
|
|
55266
|
-
app_config.entries = entries;
|
|
55267
|
-
return app_config;
|
|
55268
|
-
}
|
|
55269
|
-
function getOptimumStopAndRisk(app_config, params) {
|
|
55270
|
-
const { max_size, target_stop } = params;
|
|
55271
|
-
const isLong = app_config.kind === "long";
|
|
55272
|
-
const stopRange = Math.abs(app_config.entry - target_stop) * 0.5;
|
|
55273
|
-
let low_stop = isLong ? target_stop - stopRange : Math.max(target_stop - stopRange, app_config.entry);
|
|
55274
|
-
let high_stop = isLong ? Math.min(target_stop + stopRange, app_config.entry) : target_stop + stopRange;
|
|
55275
|
-
let optimal_stop = target_stop;
|
|
55276
|
-
let best_stop_result = null;
|
|
55277
|
-
let best_entry_diff = Infinity;
|
|
55278
|
-
console.log(`Finding optimal stop for ${isLong ? "LONG" : "SHORT"} position. Target: ${target_stop}, Search range: ${low_stop} to ${high_stop}`);
|
|
55279
|
-
let iterations = 0;
|
|
55280
|
-
const MAX_ITERATIONS = 50;
|
|
55281
|
-
while (Math.abs(high_stop - low_stop) > 0.1 && iterations < MAX_ITERATIONS) {
|
|
55282
|
-
iterations++;
|
|
55283
|
-
const mid_stop = (low_stop + high_stop) / 2;
|
|
55284
|
-
const result = sortedBuildConfig(app_config, {
|
|
55285
|
-
entry: app_config.entry,
|
|
55286
|
-
stop: mid_stop,
|
|
55287
|
-
kind: app_config.kind,
|
|
55288
|
-
risk: app_config.risk_per_trade,
|
|
55289
|
-
risk_reward: app_config.risk_reward,
|
|
55290
|
-
increase: true,
|
|
55291
|
-
gap: app_config.gap,
|
|
55292
|
-
price_places: app_config.price_places,
|
|
55293
|
-
decimal_places: app_config.decimal_places
|
|
55294
|
-
});
|
|
55295
|
-
if (result.length === 0) {
|
|
55296
|
-
if (isLong) {
|
|
55297
|
-
low_stop = mid_stop;
|
|
55298
|
-
} else {
|
|
55299
|
-
high_stop = mid_stop;
|
|
55300
|
-
}
|
|
55301
|
-
continue;
|
|
55302
|
-
}
|
|
55303
|
-
const first_entry = result[0].entry;
|
|
55304
|
-
const entry_diff = Math.abs(first_entry - target_stop);
|
|
55305
|
-
console.log(`Stop: ${mid_stop.toFixed(2)}, First Entry: ${first_entry.toFixed(2)}, Diff: ${entry_diff.toFixed(2)}`);
|
|
55306
|
-
if (entry_diff < best_entry_diff) {
|
|
55307
|
-
best_entry_diff = entry_diff;
|
|
55308
|
-
optimal_stop = mid_stop;
|
|
55309
|
-
best_stop_result = result;
|
|
55310
|
-
}
|
|
55311
|
-
if (first_entry < target_stop) {
|
|
55312
|
-
if (isLong) {
|
|
55313
|
-
low_stop = mid_stop;
|
|
55314
|
-
} else {
|
|
55315
|
-
low_stop = mid_stop;
|
|
55316
|
-
}
|
|
55317
|
-
} else {
|
|
55318
|
-
if (isLong) {
|
|
55319
|
-
high_stop = mid_stop;
|
|
55320
|
-
} else {
|
|
55321
|
-
high_stop = mid_stop;
|
|
55322
|
-
}
|
|
55323
|
-
}
|
|
55324
|
-
if (entry_diff < 1)
|
|
55325
|
-
break;
|
|
55326
|
-
}
|
|
55327
|
-
console.log(`Found optimal stop: ${optimal_stop.toFixed(2)} that gives first_entry: ${best_stop_result?.[0]?.entry?.toFixed(2)}, difference: ${best_entry_diff.toFixed(2)} after ${iterations} iterations`);
|
|
55328
|
-
let low_risk = 10;
|
|
55329
|
-
let high_risk = params.highest_risk || 2000;
|
|
55330
|
-
let optimal_risk = app_config.risk_per_trade;
|
|
55331
|
-
let best_size_result = best_stop_result;
|
|
55332
|
-
let best_size_diff = Infinity;
|
|
55333
|
-
console.log(`Finding optimal risk_per_trade for size target: ${max_size} (never exceeding it)`);
|
|
55334
|
-
iterations = 0;
|
|
55335
|
-
while (Math.abs(high_risk - low_risk) > 0.1 && iterations < MAX_ITERATIONS) {
|
|
55336
|
-
iterations++;
|
|
55337
|
-
const mid_risk = (low_risk + high_risk) / 2;
|
|
55338
|
-
const result = sortedBuildConfig(app_config, {
|
|
55339
|
-
entry: app_config.entry,
|
|
55340
|
-
stop: optimal_stop,
|
|
55341
|
-
kind: app_config.kind,
|
|
55342
|
-
risk: mid_risk,
|
|
55343
|
-
risk_reward: app_config.risk_reward,
|
|
55344
|
-
increase: true,
|
|
55345
|
-
gap: app_config.gap,
|
|
55346
|
-
price_places: app_config.price_places,
|
|
55347
|
-
decimal_places: app_config.decimal_places
|
|
55348
|
-
});
|
|
55349
|
-
if (result.length === 0) {
|
|
55350
|
-
high_risk = mid_risk;
|
|
55351
|
-
continue;
|
|
55352
|
-
}
|
|
55353
|
-
const first_entry = result[0];
|
|
55354
|
-
const avg_size = first_entry.avg_size;
|
|
55355
|
-
console.log(`Risk: ${mid_risk.toFixed(2)}, Avg Size: ${avg_size.toFixed(4)}, Target: ${max_size}`);
|
|
55356
|
-
if (avg_size <= max_size) {
|
|
55357
|
-
const size_diff = max_size - avg_size;
|
|
55358
|
-
if (size_diff < best_size_diff) {
|
|
55359
|
-
best_size_diff = size_diff;
|
|
55360
|
-
optimal_risk = mid_risk;
|
|
55361
|
-
best_size_result = result;
|
|
55362
|
-
}
|
|
55363
|
-
low_risk = mid_risk;
|
|
55364
|
-
} else {
|
|
55365
|
-
high_risk = mid_risk;
|
|
55366
|
-
}
|
|
55367
|
-
if (best_size_diff < 0.001)
|
|
55368
|
-
break;
|
|
55369
|
-
}
|
|
55370
|
-
console.log(`Found optimal risk_per_trade: ${optimal_risk.toFixed(2)} that gives avg_size: ${best_size_result?.[0]?.avg_size?.toFixed(4)}, difference: ${best_size_diff.toFixed(4)} after ${iterations} iterations`);
|
|
55371
|
-
let final_risk = optimal_risk;
|
|
55372
|
-
let final_result = best_size_result;
|
|
55373
|
-
if (best_size_result?.[0]?.avg_size < max_size) {
|
|
55374
|
-
console.log(`Current avg_size (${best_size_result?.[0].avg_size.toFixed(4)}) is less than target (${max_size}). Increasing risk to reach target...`);
|
|
55375
|
-
let current_risk = optimal_risk;
|
|
55376
|
-
const risk_increment = 5;
|
|
55377
|
-
iterations = 0;
|
|
55378
|
-
while (iterations < MAX_ITERATIONS) {
|
|
55379
|
-
iterations++;
|
|
55380
|
-
current_risk += risk_increment;
|
|
55381
|
-
if (current_risk > 5000)
|
|
55382
|
-
break;
|
|
55383
|
-
const result = sortedBuildConfig(app_config, {
|
|
55384
|
-
entry: app_config.entry,
|
|
55385
|
-
stop: optimal_stop,
|
|
55386
|
-
kind: app_config.kind,
|
|
55387
|
-
risk: current_risk,
|
|
55388
|
-
risk_reward: app_config.risk_reward,
|
|
55389
|
-
increase: true,
|
|
55390
|
-
gap: app_config.gap,
|
|
55391
|
-
price_places: app_config.price_places,
|
|
55392
|
-
decimal_places: app_config.decimal_places
|
|
55393
|
-
});
|
|
55394
|
-
if (result.length === 0)
|
|
55395
|
-
continue;
|
|
55396
|
-
const avg_size = result[0].avg_size;
|
|
55397
|
-
console.log(`Increased Risk: ${current_risk.toFixed(2)}, New Avg Size: ${avg_size.toFixed(4)}`);
|
|
55398
|
-
if (avg_size >= max_size) {
|
|
55399
|
-
final_risk = current_risk;
|
|
55400
|
-
final_result = result;
|
|
55401
|
-
console.log(`Target size reached! Final risk: ${final_risk.toFixed(2)}, Final avg_size: ${avg_size.toFixed(4)}`);
|
|
55402
|
-
break;
|
|
55403
|
-
}
|
|
55404
|
-
}
|
|
55405
|
-
}
|
|
55406
|
-
return {
|
|
55407
|
-
optimal_stop: to_f(optimal_stop, app_config.price_places),
|
|
55408
|
-
optimal_risk: to_f(final_risk, app_config.price_places),
|
|
55409
|
-
avg_size: final_result?.[0]?.avg_size || 0,
|
|
55410
|
-
avg_entry: final_result?.[0]?.avg_entry || 0,
|
|
55411
|
-
result: final_result,
|
|
55412
|
-
first_entry: final_result?.[0]?.entry || 0,
|
|
55413
|
-
neg_pnl: final_result?.[0]?.neg_pnl || 0,
|
|
55414
|
-
risk_reward: app_config.risk_reward,
|
|
55415
|
-
size_diff: Math.abs((final_result?.[0]?.avg_size || 0) - max_size),
|
|
55416
|
-
entry_diff: best_entry_diff
|
|
55417
|
-
};
|
|
55418
|
-
}
|
|
55419
|
-
function generate_config_params(app_config, payload) {
|
|
55420
|
-
const { result, ...optimum } = getOptimumStopAndRisk(app_config, {
|
|
55421
|
-
max_size: app_config.max_size,
|
|
55422
|
-
highest_risk: payload.risk * 2,
|
|
55423
|
-
target_stop: app_config.stop
|
|
55424
|
-
});
|
|
55425
|
-
return {
|
|
55426
|
-
entry: payload.entry,
|
|
55427
|
-
stop: optimum.optimal_stop,
|
|
55428
|
-
avg_size: optimum.avg_size,
|
|
55429
|
-
avg_entry: optimum.avg_entry,
|
|
55430
|
-
risk_reward: payload.risk_reward,
|
|
55431
|
-
neg_pnl: optimum.neg_pnl,
|
|
55432
|
-
risk: payload.risk
|
|
55433
|
-
};
|
|
55434
|
-
}
|
|
55435
|
-
function determine_break_even_price(payload) {
|
|
55436
|
-
const { long_position, short_position, fee_percent = 0.05 / 100 } = payload;
|
|
55437
|
-
const long_notional = long_position.entry * long_position.quantity;
|
|
55438
|
-
const short_notional = short_position.entry * short_position.quantity;
|
|
55439
|
-
const net_quantity = long_position.quantity - short_position.quantity;
|
|
55440
|
-
const net_capital = Math.abs(long_notional - short_notional);
|
|
55441
|
-
const break_even_price = net_capital / (Math.abs(net_quantity) + fee_percent * Math.abs(net_quantity));
|
|
55442
|
-
return {
|
|
55443
|
-
price: break_even_price,
|
|
55444
|
-
direction: net_quantity > 0 ? "long" : "short"
|
|
55445
|
-
};
|
|
55446
|
-
}
|
|
55447
|
-
function determine_amount_to_buy(payload) {
|
|
55448
|
-
const {
|
|
55449
|
-
orders,
|
|
55450
|
-
kind,
|
|
55451
|
-
decimal_places = "%.3f",
|
|
55452
|
-
position: position2,
|
|
55453
|
-
existingOrders
|
|
55454
|
-
} = payload;
|
|
55455
|
-
const totalQuantity = orders.reduce((sum, order) => sum + (order.quantity || 0), 0);
|
|
55456
|
-
let runningTotal = to_f(totalQuantity, decimal_places);
|
|
55457
|
-
let sortedOrders = [...orders].sort((a, b) => (a.entry || 0) - (b.entry || 0));
|
|
55458
|
-
if (kind === "short") {
|
|
55459
|
-
sortedOrders.reverse();
|
|
55460
|
-
}
|
|
55461
|
-
const withCumulative = [];
|
|
55462
|
-
for (const order of sortedOrders) {
|
|
55463
|
-
withCumulative.push({
|
|
55464
|
-
...order,
|
|
55465
|
-
cumulative_quantity: runningTotal
|
|
55466
|
-
});
|
|
55467
|
-
runningTotal -= order.quantity;
|
|
55468
|
-
runningTotal = to_f(runningTotal, decimal_places);
|
|
55733
|
+
const pnl = (current_price - position2.entry) * position2.quantity;
|
|
55734
|
+
const orders = account.orders[kind].entries;
|
|
55735
|
+
const side = kind === "long" ? "buy" : "sell";
|
|
55736
|
+
let limit_orders = orders.filter((order) => order.stop === 0 && order.side === side).filter((o) => {
|
|
55737
|
+
if (kind === "long" && pnl < 0 && Math.abs(pnl) > minimum_pnl) {
|
|
55738
|
+
return true;
|
|
55739
|
+
}
|
|
55740
|
+
if (kind === "short" && pnl > 0 && Math.abs(pnl) > minimum_pnl) {
|
|
55741
|
+
return true;
|
|
55742
|
+
}
|
|
55743
|
+
return false;
|
|
55744
|
+
});
|
|
55745
|
+
if (limit_orders.length > 1) {
|
|
55746
|
+
limit_orders = [limit_orders[limit_orders.length - 1]];
|
|
55469
55747
|
}
|
|
55470
|
-
|
|
55471
|
-
|
|
55472
|
-
|
|
55748
|
+
return limit_orders.map((o) => ({ ...o, id: o.order_id }));
|
|
55749
|
+
}
|
|
55750
|
+
function processPosition(codeNode, input, kind) {
|
|
55751
|
+
const { active_account, current_price } = input;
|
|
55752
|
+
const { use_full = false } = codeNode;
|
|
55753
|
+
const long_position = active_account.position.long;
|
|
55754
|
+
const short_position = active_account.position.short;
|
|
55755
|
+
const vv = calculateHedge({
|
|
55473
55756
|
kind,
|
|
55474
|
-
|
|
55475
|
-
|
|
55476
|
-
|
|
55477
|
-
|
|
55757
|
+
active_account,
|
|
55758
|
+
targetPnl: codeNode.profit || 50,
|
|
55759
|
+
ratio: codeNode.ratio,
|
|
55760
|
+
use_full,
|
|
55761
|
+
not_reduce: codeNode.not_reduce,
|
|
55762
|
+
sell_ratio: codeNode.sell_ratio
|
|
55763
|
+
});
|
|
55764
|
+
const reverse_kind = kind === "long" ? "short" : "long";
|
|
55765
|
+
const a_stops = findStopOrders(reverse_kind, active_account);
|
|
55766
|
+
const a_limits = findEntryLimitOrders(reverse_kind, active_account, current_price, codeNode.minimum_pnl).filter((u) => codeNode.increase);
|
|
55767
|
+
const orders_to_cancel = a_limits.concat(a_stops);
|
|
55768
|
+
return {
|
|
55769
|
+
exchange: input.exchange,
|
|
55770
|
+
result: vv,
|
|
55771
|
+
to_place: {
|
|
55772
|
+
...vv[reverse_kind],
|
|
55773
|
+
kind: reverse_kind,
|
|
55774
|
+
side: reverse_kind === "long" ? "buy" : "sell"
|
|
55775
|
+
},
|
|
55776
|
+
orders_to_cancel,
|
|
55777
|
+
stop: to_f2(vv[kind].price, active_account.price_places),
|
|
55778
|
+
quantity: vv[kind].quantity,
|
|
55779
|
+
kind,
|
|
55780
|
+
type: JSON.stringify("TAKE_PROFIT"),
|
|
55781
|
+
id: active_account.id,
|
|
55782
|
+
position: kind === "long" ? long_position : short_position,
|
|
55783
|
+
opposite_position: kind === "long" ? short_position : long_position,
|
|
55784
|
+
long_position,
|
|
55785
|
+
short_position,
|
|
55786
|
+
owner: active_account.owner,
|
|
55787
|
+
risk: codeNode.profit || 150,
|
|
55788
|
+
increase: codeNode.increase,
|
|
55789
|
+
not_reduce: codeNode.not_reduce,
|
|
55790
|
+
price_places: active_account.price_places,
|
|
55791
|
+
decimal_places: active_account.decimal_places
|
|
55792
|
+
};
|
|
55478
55793
|
}
|
|
55479
|
-
function
|
|
55480
|
-
|
|
55481
|
-
|
|
55482
|
-
|
|
55483
|
-
|
|
55484
|
-
const tolerance = 0.1;
|
|
55485
|
-
const max_iterations = 150;
|
|
55486
|
-
let iterations = 0;
|
|
55487
|
-
console.log(`Starting risk search for ${position2.kind} position. Target Entry: ${position2.entry}, Initial Risk Range: [${low_risk}, ${high_risk}]`);
|
|
55488
|
-
while (high_risk - low_risk > tolerance && iterations < max_iterations) {
|
|
55489
|
-
iterations++;
|
|
55490
|
-
const mid_risk = (low_risk + high_risk) / 2;
|
|
55491
|
-
const {
|
|
55492
|
-
app_config: current_app_config,
|
|
55493
|
-
max_size,
|
|
55494
|
-
last_value,
|
|
55495
|
-
entries
|
|
55496
|
-
} = get_app_config_and_max_size({
|
|
55497
|
-
...config2,
|
|
55498
|
-
risk: mid_risk,
|
|
55499
|
-
profit_percent: config2.profit_percent || 0,
|
|
55500
|
-
profit: config2.profit || 500,
|
|
55501
|
-
risk_reward: payload.risk_reward,
|
|
55502
|
-
kind: position2.kind,
|
|
55503
|
-
price_places: config2.price_places,
|
|
55504
|
-
decimal_places: config2.decimal_places,
|
|
55505
|
-
accounts: config2.accounts || [],
|
|
55506
|
-
reduce_percent: config2.reduce_percent || 90,
|
|
55507
|
-
reverse_factor: config2.reverse_factor || 1,
|
|
55508
|
-
symbol: config2.symbol || "",
|
|
55509
|
-
support: config2.support || 0,
|
|
55510
|
-
resistance: config2.resistance || 0,
|
|
55511
|
-
min_size: config2.min_size || 0,
|
|
55512
|
-
stop_percent: config2.stop_percent || 0
|
|
55513
|
-
}, {
|
|
55514
|
-
entry: payload.entry,
|
|
55515
|
-
stop: payload.stop,
|
|
55516
|
-
kind: position2.kind
|
|
55517
|
-
});
|
|
55518
|
-
current_app_config.max_size = max_size;
|
|
55519
|
-
current_app_config.last_value = last_value;
|
|
55520
|
-
current_app_config.entries = entries;
|
|
55521
|
-
current_app_config.risk_reward = payload.risk_reward;
|
|
55522
|
-
const full_trades = sortedBuildConfig(current_app_config, {
|
|
55523
|
-
entry: current_app_config.entry,
|
|
55524
|
-
stop: current_app_config.stop,
|
|
55525
|
-
kind: current_app_config.kind,
|
|
55526
|
-
risk: current_app_config.risk_per_trade,
|
|
55527
|
-
risk_reward: current_app_config.risk_reward,
|
|
55528
|
-
increase: true,
|
|
55529
|
-
gap: current_app_config.gap,
|
|
55530
|
-
price_places: current_app_config.price_places,
|
|
55531
|
-
decimal_places: current_app_config.decimal_places
|
|
55532
|
-
});
|
|
55533
|
-
console.log(`Iteration ${iterations}: Risk=${mid_risk.toFixed(2)}, Low=${low_risk.toFixed(2)}, High=${high_risk.toFixed(2)}`);
|
|
55534
|
-
if (full_trades.length === 0) {
|
|
55535
|
-
console.log(` -> No trades generated by sortedBuildConfig at Risk=${mid_risk.toFixed(2)}. Adjusting high_risk down.`);
|
|
55536
|
-
high_risk = mid_risk;
|
|
55537
|
-
continue;
|
|
55794
|
+
async function reduceMajorPositionCalculation(input, exchange_instance) {
|
|
55795
|
+
try {
|
|
55796
|
+
let conditionsCheck = input.position.tp_quantity !== input.quantity || input.position.take_profit !== to_f2(input.stop, input.price_places);
|
|
55797
|
+
if (!isNaN(input.opposite_position.stop_quantity) && input.opposite_position.stop_quantity > -1) {
|
|
55798
|
+
conditionsCheck = conditionsCheck || input.opposite_position.stop_quantity !== input.to_place.quantity;
|
|
55538
55799
|
}
|
|
55539
|
-
|
|
55540
|
-
|
|
55541
|
-
|
|
55542
|
-
|
|
55543
|
-
|
|
55544
|
-
|
|
55545
|
-
|
|
55800
|
+
console.log("conditionsCheck for ", input.position.kind, conditionsCheck);
|
|
55801
|
+
const sell_quantity = input.result[input.position.kind].quantity;
|
|
55802
|
+
console.log("opposite_check", {
|
|
55803
|
+
kind: input.opposite_position.kind,
|
|
55804
|
+
stop_loss: input.opposite_position.stop_loss,
|
|
55805
|
+
stop_price: input.to_place.stop_price,
|
|
55806
|
+
owner: input.owner,
|
|
55807
|
+
not_reduce: input.to_place,
|
|
55808
|
+
result: input.result,
|
|
55809
|
+
stop_to_place: {
|
|
55810
|
+
owner: input.owner,
|
|
55811
|
+
symbol: input.position.symbol,
|
|
55812
|
+
kind: input.to_place.kind,
|
|
55813
|
+
stop: input.to_place.stop_price,
|
|
55814
|
+
quantity: Math.abs(input.to_place.quantity)
|
|
55815
|
+
},
|
|
55816
|
+
sell_quantity
|
|
55546
55817
|
});
|
|
55547
|
-
if (
|
|
55548
|
-
|
|
55549
|
-
|
|
55550
|
-
|
|
55551
|
-
|
|
55552
|
-
|
|
55553
|
-
|
|
55554
|
-
|
|
55555
|
-
|
|
55556
|
-
|
|
55557
|
-
|
|
55558
|
-
|
|
55559
|
-
}
|
|
55560
|
-
|
|
55561
|
-
|
|
55562
|
-
|
|
55563
|
-
|
|
55564
|
-
|
|
55818
|
+
if (conditionsCheck) {
|
|
55819
|
+
const async_tp = async () => {
|
|
55820
|
+
if (input.stop && input.stop !== Infinity) {
|
|
55821
|
+
await exchange_instance.placeTpOrder({
|
|
55822
|
+
symbol: input.position.symbol,
|
|
55823
|
+
kind: input.kind,
|
|
55824
|
+
quantity: sell_quantity,
|
|
55825
|
+
take_profit: input.stop,
|
|
55826
|
+
price_places: input.price_places,
|
|
55827
|
+
decimal_places: input.decimal_places
|
|
55828
|
+
});
|
|
55829
|
+
}
|
|
55830
|
+
};
|
|
55831
|
+
const async_increase = async () => {
|
|
55832
|
+
if (input.increase && input.to_place.stop_price) {
|
|
55833
|
+
await exchange_instance.placeLimitOrder({
|
|
55834
|
+
symbol: input.position.symbol,
|
|
55835
|
+
kind: input.to_place.kind,
|
|
55836
|
+
price: input.to_place.stop_price,
|
|
55837
|
+
quantity: input.to_place.quantity,
|
|
55838
|
+
price_places: input.price_places,
|
|
55839
|
+
decimal_places: input.decimal_places
|
|
55840
|
+
}).then((r2) => {
|
|
55841
|
+
console.log("placeNewOrderData", r2);
|
|
55842
|
+
});
|
|
55843
|
+
}
|
|
55844
|
+
};
|
|
55845
|
+
let placeNewOrderData = null;
|
|
55846
|
+
const async_place_stop = async () => {
|
|
55847
|
+
if (!input.not_reduce && input.to_place.stop_price && input.to_place.quantity) {
|
|
55848
|
+
await exchange_instance.placeStopOrder({
|
|
55849
|
+
symbol: input.position.symbol,
|
|
55850
|
+
kind: input.to_place.kind,
|
|
55851
|
+
stop: input.to_place.stop_price,
|
|
55852
|
+
quantity: Math.abs(input.to_place.quantity),
|
|
55853
|
+
price_places: input.price_places,
|
|
55854
|
+
decimal_places: input.decimal_places
|
|
55855
|
+
});
|
|
55856
|
+
}
|
|
55857
|
+
};
|
|
55858
|
+
const [_tp, _increase, _place_stop] = await Promise.all([
|
|
55859
|
+
async_tp(),
|
|
55860
|
+
async_increase(),
|
|
55861
|
+
async_place_stop()
|
|
55862
|
+
]);
|
|
55863
|
+
return {
|
|
55864
|
+
newOrderResponse: placeNewOrderData
|
|
55865
|
+
};
|
|
55565
55866
|
} else {
|
|
55566
|
-
|
|
55567
|
-
|
|
55568
|
-
|
|
55569
|
-
}
|
|
55570
|
-
console.log(` -> Constraint MET (Short): last_entry (${last_entry.toFixed(4)}) >= position.entry (${position2.entry.toFixed(4)}). Storing as best, increasing low_risk.`);
|
|
55571
|
-
best_risk = mid_risk;
|
|
55572
|
-
best_app_config = current_app_config;
|
|
55573
|
-
low_risk = mid_risk;
|
|
55574
|
-
}
|
|
55867
|
+
return {
|
|
55868
|
+
message: "No changes needed, conditions not met",
|
|
55869
|
+
input
|
|
55870
|
+
};
|
|
55575
55871
|
}
|
|
55872
|
+
} catch (error) {
|
|
55873
|
+
console.error("Error in reduceMajorPositionCalculation:", error);
|
|
55874
|
+
throw error;
|
|
55576
55875
|
}
|
|
55577
|
-
|
|
55578
|
-
|
|
55579
|
-
|
|
55580
|
-
|
|
55581
|
-
|
|
55582
|
-
|
|
55583
|
-
|
|
55584
|
-
|
|
55585
|
-
|
|
55876
|
+
}
|
|
55877
|
+
async function reduceMajorPositionEntry(input, accountInfo, trigger2, exchange_instance) {
|
|
55878
|
+
let results = {};
|
|
55879
|
+
try {
|
|
55880
|
+
const async_long = async () => {
|
|
55881
|
+
if (input.long) {
|
|
55882
|
+
const workflowInput = processPosition(input.long, accountInfo, "long");
|
|
55883
|
+
if (trigger2.long) {
|
|
55884
|
+
try {
|
|
55885
|
+
await reduceMajorPositionCalculation(workflowInput, exchange_instance);
|
|
55886
|
+
} catch (error) {
|
|
55887
|
+
console.error("Error in reduceMajorPositionCalculation:", error);
|
|
55888
|
+
}
|
|
55889
|
+
}
|
|
55890
|
+
return workflowInput;
|
|
55891
|
+
}
|
|
55892
|
+
return null;
|
|
55893
|
+
};
|
|
55894
|
+
const async_short = async () => {
|
|
55895
|
+
if (input.short) {
|
|
55896
|
+
const workflowInput = processPosition(input.short, accountInfo, "short");
|
|
55897
|
+
if (trigger2.short) {
|
|
55898
|
+
try {
|
|
55899
|
+
await reduceMajorPositionCalculation(workflowInput, exchange_instance);
|
|
55900
|
+
} catch (error) {
|
|
55901
|
+
console.error("Error in reduceMajorPositionCalculation:", error);
|
|
55902
|
+
}
|
|
55903
|
+
}
|
|
55904
|
+
return workflowInput;
|
|
55905
|
+
}
|
|
55906
|
+
return null;
|
|
55907
|
+
};
|
|
55908
|
+
const [long, short] = await Promise.all([async_long(), async_short()]);
|
|
55909
|
+
results.long = long;
|
|
55910
|
+
results.short = short;
|
|
55911
|
+
return results;
|
|
55912
|
+
} catch (error) {
|
|
55913
|
+
console.error("Error in reduceMajorPositionEntry:", error);
|
|
55914
|
+
throw error;
|
|
55586
55915
|
}
|
|
55587
|
-
best_app_config.entries = determine_amount_to_buy({
|
|
55588
|
-
orders: best_app_config.entries,
|
|
55589
|
-
kind: position2.kind,
|
|
55590
|
-
decimal_places: best_app_config.decimal_places,
|
|
55591
|
-
price_places: best_app_config.price_places,
|
|
55592
|
-
position: position2,
|
|
55593
|
-
existingOrders: []
|
|
55594
|
-
});
|
|
55595
|
-
return best_app_config;
|
|
55596
55916
|
}
|
|
55597
55917
|
|
|
55598
55918
|
// src/position.ts
|
|
@@ -55669,7 +55989,7 @@ class ExchangePosition {
|
|
|
55669
55989
|
let _profit = config2.profit;
|
|
55670
55990
|
let _profit_percent = config2?.profit_percent;
|
|
55671
55991
|
if (_profit_percent && (position2?.quantity || 0) > 0) {
|
|
55672
|
-
_profit =
|
|
55992
|
+
_profit = to_f2(position2.quantity * _profit_percent * position2.entry / 100);
|
|
55673
55993
|
}
|
|
55674
55994
|
await this.app_db.update_db_position(position2, {
|
|
55675
55995
|
target_pnl: _profit
|
|
@@ -55888,7 +56208,7 @@ class ExchangePosition {
|
|
|
55888
56208
|
async determineAmountToBuy(payload) {
|
|
55889
56209
|
const { orders, kind, decimal_places = "%.3f", refresh, cancel } = payload;
|
|
55890
56210
|
const totalQuantity = orders.reduce((sum, order) => sum + (order.quantity || 0), 0);
|
|
55891
|
-
let runningTotal =
|
|
56211
|
+
let runningTotal = to_f2(totalQuantity, decimal_places);
|
|
55892
56212
|
let sortedOrders = [...orders].sort((a, b) => (a.entry || 0) - (b.entry || 0));
|
|
55893
56213
|
if (kind === "short") {
|
|
55894
56214
|
sortedOrders.reverse();
|
|
@@ -55900,7 +56220,7 @@ class ExchangePosition {
|
|
|
55900
56220
|
cumulative_quantity: runningTotal
|
|
55901
56221
|
});
|
|
55902
56222
|
runningTotal -= order.quantity;
|
|
55903
|
-
runningTotal =
|
|
56223
|
+
runningTotal = to_f2(runningTotal, decimal_places);
|
|
55904
56224
|
}
|
|
55905
56225
|
const { instance: position2, existingOrders } = await this.refresh(refresh);
|
|
55906
56226
|
let filteredOrders = withCumulative.filter((order) => (order.cumulative_quantity || 0) > position2?.quantity).map((order) => ({
|
|
@@ -56222,6 +56542,21 @@ class ExchangeAccount {
|
|
|
56222
56542
|
}
|
|
56223
56543
|
return app_config;
|
|
56224
56544
|
}
|
|
56545
|
+
async tradeConfig(payload) {
|
|
56546
|
+
const { symbol, kind } = payload;
|
|
56547
|
+
const config2 = await this.getPositionConfig({
|
|
56548
|
+
symbol,
|
|
56549
|
+
kind
|
|
56550
|
+
});
|
|
56551
|
+
const app_config = await this.buildAppConfig({
|
|
56552
|
+
entry: config2.entry,
|
|
56553
|
+
stop: config2.stop,
|
|
56554
|
+
risk_reward: config2.risk_reward,
|
|
56555
|
+
risk: config2.risk,
|
|
56556
|
+
symbol
|
|
56557
|
+
});
|
|
56558
|
+
return app_config;
|
|
56559
|
+
}
|
|
56225
56560
|
async buildTrades(payload) {
|
|
56226
56561
|
const { symbol, kind, risk } = payload;
|
|
56227
56562
|
const config2 = await this.getPositionConfig({
|
|
@@ -56358,7 +56693,7 @@ class ExchangeAccount {
|
|
|
56358
56693
|
cancel
|
|
56359
56694
|
} = payload;
|
|
56360
56695
|
const totalQuantity = orders.reduce((sum, order) => sum + (order.quantity || 0), 0);
|
|
56361
|
-
let runningTotal =
|
|
56696
|
+
let runningTotal = to_f2(totalQuantity, decimal_places);
|
|
56362
56697
|
let sortedOrders = [...orders].sort((a, b) => (a.entry || 0) - (b.entry || 0));
|
|
56363
56698
|
if (kind === "short") {
|
|
56364
56699
|
sortedOrders.reverse();
|
|
@@ -56370,7 +56705,7 @@ class ExchangeAccount {
|
|
|
56370
56705
|
cumulative_quantity: runningTotal
|
|
56371
56706
|
});
|
|
56372
56707
|
runningTotal -= order.quantity;
|
|
56373
|
-
runningTotal =
|
|
56708
|
+
runningTotal = to_f2(runningTotal, decimal_places);
|
|
56374
56709
|
}
|
|
56375
56710
|
const position2 = await this.syncAccount({
|
|
56376
56711
|
symbol,
|
|
@@ -56549,6 +56884,8 @@ class ExchangeAccount {
|
|
|
56549
56884
|
const positions = await this.syncAccount({
|
|
56550
56885
|
symbol: payload.symbol
|
|
56551
56886
|
});
|
|
56887
|
+
const long_position = positions.find((x) => x.kind === "long");
|
|
56888
|
+
const short_position = positions.find((x) => x.kind === "short");
|
|
56552
56889
|
const config2 = build_reduce_config({
|
|
56553
56890
|
account: this.instance,
|
|
56554
56891
|
symbol: payload.symbol,
|
|
@@ -56563,7 +56900,8 @@ class ExchangeAccount {
|
|
|
56563
56900
|
increase: false,
|
|
56564
56901
|
not_reduce: config2?.not_reduce,
|
|
56565
56902
|
ratio: config2?.reduce_ratio_long,
|
|
56566
|
-
use_full: payload.use_full ? payload.kind == "long" ? true : false : undefined
|
|
56903
|
+
use_full: payload.use_full ? payload.kind == "long" ? true : false : undefined,
|
|
56904
|
+
sell_ratio: long_position?.sell_ratio
|
|
56567
56905
|
},
|
|
56568
56906
|
short: {
|
|
56569
56907
|
minimum_pnl: config2?.short_minimum_pnl || 0.0001,
|
|
@@ -56572,7 +56910,8 @@ class ExchangeAccount {
|
|
|
56572
56910
|
increase: false,
|
|
56573
56911
|
not_reduce: config2?.not_reduce,
|
|
56574
56912
|
ratio: config2?.reduce_ratio_short,
|
|
56575
|
-
use_full: payload.use_full ? payload.kind == "short" ? true : false : undefined
|
|
56913
|
+
use_full: payload.use_full ? payload.kind == "short" ? true : false : undefined,
|
|
56914
|
+
sell_ratio: short_position?.sell_ratio
|
|
56576
56915
|
},
|
|
56577
56916
|
trigger: {
|
|
56578
56917
|
long: payload.trigger?.long ? config2.trigger_long : false,
|
|
@@ -57093,7 +57432,7 @@ class ExchangeAccount {
|
|
|
57093
57432
|
let _profit = config2.profit;
|
|
57094
57433
|
let _profit_percent = config2?.profit_percent;
|
|
57095
57434
|
if (_profit_percent && (position2?.quantity || 0) > 0) {
|
|
57096
|
-
_profit =
|
|
57435
|
+
_profit = to_f2(position2.quantity * _profit_percent * position2.entry / 100);
|
|
57097
57436
|
}
|
|
57098
57437
|
await this.app_db.update_db_position(position2, {
|
|
57099
57438
|
target_pnl: _profit
|
|
@@ -57102,6 +57441,45 @@ class ExchangeAccount {
|
|
|
57102
57441
|
}
|
|
57103
57442
|
return 0;
|
|
57104
57443
|
}
|
|
57444
|
+
async runSimulation(payload) {
|
|
57445
|
+
const { symbol, kind, iterations = 2, raw = false } = payload;
|
|
57446
|
+
const positions = await this.syncAccount({
|
|
57447
|
+
symbol
|
|
57448
|
+
});
|
|
57449
|
+
const symbol_config = await this.recomputeSymbolConfig({
|
|
57450
|
+
symbol
|
|
57451
|
+
});
|
|
57452
|
+
const long_position = positions.find((x) => x.kind === "long");
|
|
57453
|
+
const short_position = positions.find((x) => x.kind === "short");
|
|
57454
|
+
const strategy_instance = await this.getPositionStrategy();
|
|
57455
|
+
const strategy_config = {
|
|
57456
|
+
tp_percent: strategy_instance?.tp_percent,
|
|
57457
|
+
short_tp_factor: strategy_instance?.short_tp_factor,
|
|
57458
|
+
fee_percent: strategy_instance?.fee_percent,
|
|
57459
|
+
budget: strategy_instance?.budget,
|
|
57460
|
+
risk_reward: strategy_instance?.risk_reward,
|
|
57461
|
+
reduce_ratio: strategy_instance?.reduce_ratio,
|
|
57462
|
+
global_config: symbol_config
|
|
57463
|
+
};
|
|
57464
|
+
const strategy = new Strategy({
|
|
57465
|
+
long: {
|
|
57466
|
+
entry: long_position.entry,
|
|
57467
|
+
quantity: long_position.quantity
|
|
57468
|
+
},
|
|
57469
|
+
short: {
|
|
57470
|
+
entry: short_position.entry,
|
|
57471
|
+
quantity: short_position.quantity
|
|
57472
|
+
},
|
|
57473
|
+
config: strategy_config
|
|
57474
|
+
});
|
|
57475
|
+
if (raw) {
|
|
57476
|
+
return strategy;
|
|
57477
|
+
}
|
|
57478
|
+
return strategy.runIterations({
|
|
57479
|
+
iterations,
|
|
57480
|
+
kind
|
|
57481
|
+
});
|
|
57482
|
+
}
|
|
57105
57483
|
async getCurrentRun(payload) {
|
|
57106
57484
|
const { symbol, kind = "long", pnl } = payload;
|
|
57107
57485
|
const instances = await this.app_db.pb.collection("strategy_runs").getFullList({
|
|
@@ -57626,7 +58004,7 @@ class ExchangeAccount {
|
|
|
57626
58004
|
if (reverse_position?.expand?.config && root_position.quantity > 0) {
|
|
57627
58005
|
const reverse_config = reverse_position.expand.config;
|
|
57628
58006
|
const diff = Math.abs(reverse_config.stop - root_position.entry);
|
|
57629
|
-
const result =
|
|
58007
|
+
const result = to_f2(diff * root_position.quantity);
|
|
57630
58008
|
if (root_position.target_pnl !== result) {
|
|
57631
58009
|
await this.app_db.update_db_position(root_position, {
|
|
57632
58010
|
target_pnl: result
|
|
@@ -57831,12 +58209,12 @@ class App {
|
|
|
57831
58209
|
const balance = active_account.usd_balance || 0;
|
|
57832
58210
|
const long_liquidation = long_db_position.avg_price * long_db_position.avg_qty / long_db_position.leverage - balance / long_db_position.avg_qty + long_db_position.avg_price;
|
|
57833
58211
|
const short_liquidation = -(short_db_position.avg_price * short_db_position.avg_qty / short_db_position.leverage) + balance / short_db_position.avg_qty + short_db_position.avg_price;
|
|
57834
|
-
long_position.avg_liquidation =
|
|
57835
|
-
short_position.avg_liquidation =
|
|
58212
|
+
long_position.avg_liquidation = to_f2(long_liquidation, "%.3f");
|
|
58213
|
+
short_position.avg_liquidation = to_f2(short_liquidation, "%.3f");
|
|
57836
58214
|
const long_ratio = Math.max(long_position.avg_liquidation, long_position.avg_entry) / Math.min(long_position.avg_liquidation, long_position.avg_entry) - 1;
|
|
57837
58215
|
const short_ratio = Math.max(short_position.avg_liquidation, short_position.avg_entry) / Math.min(short_position.avg_liquidation, short_position.avg_entry) - 1;
|
|
57838
|
-
long_position.liquidation_ratio =
|
|
57839
|
-
short_position.liquidation_ratio =
|
|
58216
|
+
long_position.liquidation_ratio = to_f2(long_ratio, "%.3f") * 100;
|
|
58217
|
+
short_position.liquidation_ratio = to_f2(short_ratio, "%.3f") * 100;
|
|
57840
58218
|
return {
|
|
57841
58219
|
long_position,
|
|
57842
58220
|
short_position,
|
|
@@ -58143,214 +58521,6 @@ async function initialize(payload) {
|
|
|
58143
58521
|
});
|
|
58144
58522
|
return app;
|
|
58145
58523
|
}
|
|
58146
|
-
// src/helpers/strategy.ts
|
|
58147
|
-
class Strategy {
|
|
58148
|
-
position;
|
|
58149
|
-
config;
|
|
58150
|
-
constructor(payload) {
|
|
58151
|
-
this.position = {
|
|
58152
|
-
long: payload.long,
|
|
58153
|
-
short: payload.short
|
|
58154
|
-
};
|
|
58155
|
-
this.config = payload.config;
|
|
58156
|
-
if (!this.config.fee_percent) {
|
|
58157
|
-
this.config.fee_percent = 0.05;
|
|
58158
|
-
}
|
|
58159
|
-
}
|
|
58160
|
-
get price_places() {
|
|
58161
|
-
return this.config.global_config.price_places;
|
|
58162
|
-
}
|
|
58163
|
-
get decimal_places() {
|
|
58164
|
-
return this.config.global_config.decimal_places;
|
|
58165
|
-
}
|
|
58166
|
-
to_f(price) {
|
|
58167
|
-
return to_f(price, this.price_places);
|
|
58168
|
-
}
|
|
58169
|
-
to_df(quantity) {
|
|
58170
|
-
return to_f(quantity, this.decimal_places);
|
|
58171
|
-
}
|
|
58172
|
-
pnl(kind) {
|
|
58173
|
-
const position2 = this.position[kind];
|
|
58174
|
-
const { entry, quantity } = position2;
|
|
58175
|
-
const notional = entry * quantity;
|
|
58176
|
-
let tp_percent = this.config.tp_percent;
|
|
58177
|
-
if (kind == "short") {
|
|
58178
|
-
tp_percent = tp_percent * this.config.short_tp_factor;
|
|
58179
|
-
}
|
|
58180
|
-
const profit = notional * (tp_percent / 100);
|
|
58181
|
-
return this.to_f(profit);
|
|
58182
|
-
}
|
|
58183
|
-
tp(kind) {
|
|
58184
|
-
const position2 = this.position[kind];
|
|
58185
|
-
const { entry, quantity } = position2;
|
|
58186
|
-
const profit = this.pnl(kind);
|
|
58187
|
-
const diff = profit / quantity;
|
|
58188
|
-
return this.to_f(kind == "long" ? entry + diff : entry - diff);
|
|
58189
|
-
}
|
|
58190
|
-
calculate_fee(position2) {
|
|
58191
|
-
const { price, quantity } = position2;
|
|
58192
|
-
const fee = price * quantity * this.config.fee_percent / 100;
|
|
58193
|
-
return this.to_f(fee);
|
|
58194
|
-
}
|
|
58195
|
-
get long_tp() {
|
|
58196
|
-
return this.tp("long");
|
|
58197
|
-
}
|
|
58198
|
-
get short_tp() {
|
|
58199
|
-
return this.tp("short");
|
|
58200
|
-
}
|
|
58201
|
-
generateGapClosingAlgorithm(payload) {
|
|
58202
|
-
const { kind } = payload;
|
|
58203
|
-
const { entry, quantity } = this.position[kind];
|
|
58204
|
-
const focus_position = this.position[kind];
|
|
58205
|
-
const reverse_kind = kind == "long" ? "short" : "long";
|
|
58206
|
-
const reverse_position = this.position[reverse_kind];
|
|
58207
|
-
let _entry = this.tp(kind);
|
|
58208
|
-
let _stop = this.tp(reverse_kind);
|
|
58209
|
-
if (!_entry && !_stop) {
|
|
58210
|
-
return null;
|
|
58211
|
-
}
|
|
58212
|
-
const second_payload = {
|
|
58213
|
-
entry: _entry,
|
|
58214
|
-
stop: _stop,
|
|
58215
|
-
risk_reward: this.config.risk_reward,
|
|
58216
|
-
start_risk: this.pnl(reverse_kind),
|
|
58217
|
-
max_risk: this.config.budget
|
|
58218
|
-
};
|
|
58219
|
-
const third_payload = {
|
|
58220
|
-
entry,
|
|
58221
|
-
quantity,
|
|
58222
|
-
kind
|
|
58223
|
-
};
|
|
58224
|
-
console.log({ second_payload, third_payload });
|
|
58225
|
-
const app_config = generateOptimumAppConfig(this.config.global_config, second_payload, third_payload);
|
|
58226
|
-
if (!app_config) {
|
|
58227
|
-
return null;
|
|
58228
|
-
}
|
|
58229
|
-
const { entries, ...rest } = app_config;
|
|
58230
|
-
const risk = this.to_f(rest.risk_per_trade);
|
|
58231
|
-
const adjusted_focus_entries = entries.map((entry2) => {
|
|
58232
|
-
let adjusted_price = entry2.price;
|
|
58233
|
-
if (focus_position.quantity > 0) {
|
|
58234
|
-
if (kind === "long" && entry2.price >= focus_position.entry) {
|
|
58235
|
-
adjusted_price = focus_position.entry;
|
|
58236
|
-
} else if (kind === "short" && entry2.price <= focus_position.entry) {
|
|
58237
|
-
adjusted_price = focus_position.entry;
|
|
58238
|
-
}
|
|
58239
|
-
}
|
|
58240
|
-
return {
|
|
58241
|
-
price: adjusted_price,
|
|
58242
|
-
quantity: entry2.quantity
|
|
58243
|
-
};
|
|
58244
|
-
});
|
|
58245
|
-
const avg = determine_average_entry_and_size(adjusted_focus_entries.concat([
|
|
58246
|
-
{
|
|
58247
|
-
price: entry,
|
|
58248
|
-
quantity
|
|
58249
|
-
}
|
|
58250
|
-
]), rest.decimal_places, rest.price_places);
|
|
58251
|
-
const focus_loss = this.to_f((avg.price - second_payload.stop) * avg.quantity);
|
|
58252
|
-
let below_reverse_entries = kind === "long" ? entries.filter((u) => {
|
|
58253
|
-
return u.entry < reverse_position.entry;
|
|
58254
|
-
}) : entries.filter((u) => {
|
|
58255
|
-
return u.entry > reverse_position.entry;
|
|
58256
|
-
});
|
|
58257
|
-
const threshold = below_reverse_entries.at(-1);
|
|
58258
|
-
let adjusted_reverse_entries = entries.map((entry2) => {
|
|
58259
|
-
let adjusted_price = entry2.price;
|
|
58260
|
-
if (threshold) {
|
|
58261
|
-
if (reverse_kind === "short" && entry2.price > threshold.entry) {
|
|
58262
|
-
adjusted_price = threshold.entry;
|
|
58263
|
-
} else if (reverse_kind === "long" && entry2.price < threshold.entry) {
|
|
58264
|
-
adjusted_price = threshold.entry;
|
|
58265
|
-
}
|
|
58266
|
-
}
|
|
58267
|
-
return {
|
|
58268
|
-
price: adjusted_price,
|
|
58269
|
-
quantity: entry2.quantity
|
|
58270
|
-
};
|
|
58271
|
-
});
|
|
58272
|
-
const reverse_avg = determine_average_entry_and_size(adjusted_reverse_entries.concat([
|
|
58273
|
-
{
|
|
58274
|
-
price: reverse_position.entry,
|
|
58275
|
-
quantity: reverse_position.quantity
|
|
58276
|
-
}
|
|
58277
|
-
]), rest.decimal_places, rest.price_places);
|
|
58278
|
-
const reverse_pnl = this.to_f((reverse_avg.price - second_payload.stop) * reverse_avg.quantity);
|
|
58279
|
-
const fee_to_pay = this.calculate_fee({
|
|
58280
|
-
price: avg.entry,
|
|
58281
|
-
quantity: avg.quantity
|
|
58282
|
-
}) + this.calculate_fee({
|
|
58283
|
-
price: reverse_avg.entry,
|
|
58284
|
-
quantity: reverse_avg.quantity
|
|
58285
|
-
});
|
|
58286
|
-
const net_reverse_pnl = reverse_pnl - fee_to_pay;
|
|
58287
|
-
const ratio = net_reverse_pnl / focus_loss;
|
|
58288
|
-
const quantity_to_sell = this.to_df(ratio * avg.quantity);
|
|
58289
|
-
const remaining_quantity = this.to_df(avg.quantity - quantity_to_sell);
|
|
58290
|
-
return {
|
|
58291
|
-
risk,
|
|
58292
|
-
risk_reward: this.config.risk_reward,
|
|
58293
|
-
[kind]: {
|
|
58294
|
-
avg_entry: avg.entry,
|
|
58295
|
-
avg_size: avg.quantity,
|
|
58296
|
-
loss: focus_loss,
|
|
58297
|
-
stop: second_payload.stop,
|
|
58298
|
-
stop_quantity: quantity_to_sell,
|
|
58299
|
-
re_entry_quantity: remaining_quantity,
|
|
58300
|
-
initial_pnl: this.pnl(kind),
|
|
58301
|
-
tp: second_payload.entry
|
|
58302
|
-
},
|
|
58303
|
-
[reverse_kind]: {
|
|
58304
|
-
avg_entry: reverse_avg.entry,
|
|
58305
|
-
avg_size: reverse_avg.quantity,
|
|
58306
|
-
pnl: reverse_pnl,
|
|
58307
|
-
tp: second_payload.stop,
|
|
58308
|
-
re_entry_quantity: remaining_quantity,
|
|
58309
|
-
initial_pnl: this.pnl(reverse_kind)
|
|
58310
|
-
},
|
|
58311
|
-
last_entry: rest.last_value.entry,
|
|
58312
|
-
first_entry: entries.at(-1).entry,
|
|
58313
|
-
threshold
|
|
58314
|
-
};
|
|
58315
|
-
}
|
|
58316
|
-
runIterations(payload) {
|
|
58317
|
-
const { kind, iterations } = payload;
|
|
58318
|
-
const reverse_kind = kind == "long" ? "short" : "long";
|
|
58319
|
-
const result = [];
|
|
58320
|
-
let position2 = {
|
|
58321
|
-
long: this.position.long,
|
|
58322
|
-
short: this.position.short
|
|
58323
|
-
};
|
|
58324
|
-
for (let i2 = 0;i2 < iterations; i2++) {
|
|
58325
|
-
const instance = new Strategy({
|
|
58326
|
-
long: position2.long,
|
|
58327
|
-
short: position2.short,
|
|
58328
|
-
config: {
|
|
58329
|
-
...this.config,
|
|
58330
|
-
tp_percent: this.config.tp_percent + i2 * 4
|
|
58331
|
-
}
|
|
58332
|
-
});
|
|
58333
|
-
const algorithm = instance.generateGapClosingAlgorithm({
|
|
58334
|
-
kind
|
|
58335
|
-
});
|
|
58336
|
-
if (!algorithm) {
|
|
58337
|
-
console.log("No algorithm found");
|
|
58338
|
-
return result;
|
|
58339
|
-
break;
|
|
58340
|
-
}
|
|
58341
|
-
result.push(algorithm);
|
|
58342
|
-
position2[kind] = {
|
|
58343
|
-
entry: algorithm[kind].avg_entry,
|
|
58344
|
-
quantity: algorithm[kind].re_entry_quantity
|
|
58345
|
-
};
|
|
58346
|
-
position2[reverse_kind] = {
|
|
58347
|
-
entry: algorithm[reverse_kind].tp,
|
|
58348
|
-
quantity: algorithm[reverse_kind].re_entry_quantity
|
|
58349
|
-
};
|
|
58350
|
-
}
|
|
58351
|
-
return result;
|
|
58352
|
-
}
|
|
58353
|
-
}
|
|
58354
58524
|
export {
|
|
58355
58525
|
sortedBuildConfig,
|
|
58356
58526
|
initialize,
|