@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.cjs
CHANGED
|
@@ -16442,8 +16442,8 @@ var require_combined_stream = __commonJS((exports2, module2) => {
|
|
|
16442
16442
|
stream2.pipe(this, { end: false });
|
|
16443
16443
|
return;
|
|
16444
16444
|
}
|
|
16445
|
-
var
|
|
16446
|
-
this.write(
|
|
16445
|
+
var value2 = stream2;
|
|
16446
|
+
this.write(value2);
|
|
16447
16447
|
this._getNext();
|
|
16448
16448
|
};
|
|
16449
16449
|
CombinedStream.prototype._handleErrors = function(stream2) {
|
|
@@ -25656,8 +25656,8 @@ var require_get = __commonJS((exports2, module2) => {
|
|
|
25656
25656
|
var desc = !!hasProtoAccessor && gOPD && gOPD(Object.prototype, "__proto__");
|
|
25657
25657
|
var $Object = Object;
|
|
25658
25658
|
var $getPrototypeOf = $Object.getPrototypeOf;
|
|
25659
|
-
module2.exports = desc && typeof desc.get === "function" ? callBind([desc.get]) : typeof $getPrototypeOf === "function" ? function getDunder(
|
|
25660
|
-
return $getPrototypeOf(
|
|
25659
|
+
module2.exports = desc && typeof desc.get === "function" ? callBind([desc.get]) : typeof $getPrototypeOf === "function" ? function getDunder(value2) {
|
|
25660
|
+
return $getPrototypeOf(value2 == null ? value2 : $Object(value2));
|
|
25661
25661
|
} : false;
|
|
25662
25662
|
});
|
|
25663
25663
|
|
|
@@ -25829,26 +25829,26 @@ var require_get_intrinsic = __commonJS((exports2, module2) => {
|
|
|
25829
25829
|
}
|
|
25830
25830
|
var errorProto;
|
|
25831
25831
|
var doEval = function doEval(name2) {
|
|
25832
|
-
var
|
|
25832
|
+
var value2;
|
|
25833
25833
|
if (name2 === "%AsyncFunction%") {
|
|
25834
|
-
|
|
25834
|
+
value2 = getEvalledConstructor("async function () {}");
|
|
25835
25835
|
} else if (name2 === "%GeneratorFunction%") {
|
|
25836
|
-
|
|
25836
|
+
value2 = getEvalledConstructor("function* () {}");
|
|
25837
25837
|
} else if (name2 === "%AsyncGeneratorFunction%") {
|
|
25838
|
-
|
|
25838
|
+
value2 = getEvalledConstructor("async function* () {}");
|
|
25839
25839
|
} else if (name2 === "%AsyncGenerator%") {
|
|
25840
25840
|
var fn = doEval("%AsyncGeneratorFunction%");
|
|
25841
25841
|
if (fn) {
|
|
25842
|
-
|
|
25842
|
+
value2 = fn.prototype;
|
|
25843
25843
|
}
|
|
25844
25844
|
} else if (name2 === "%AsyncIteratorPrototype%") {
|
|
25845
25845
|
var gen = doEval("%AsyncGenerator%");
|
|
25846
25846
|
if (gen && getProto) {
|
|
25847
|
-
|
|
25847
|
+
value2 = getProto(gen.prototype);
|
|
25848
25848
|
}
|
|
25849
25849
|
}
|
|
25850
|
-
INTRINSICS[name2] =
|
|
25851
|
-
return
|
|
25850
|
+
INTRINSICS[name2] = value2;
|
|
25851
|
+
return value2;
|
|
25852
25852
|
};
|
|
25853
25853
|
var LEGACY_ALIASES = {
|
|
25854
25854
|
__proto__: null,
|
|
@@ -25935,17 +25935,17 @@ var require_get_intrinsic = __commonJS((exports2, module2) => {
|
|
|
25935
25935
|
intrinsicName = "%" + alias[0] + "%";
|
|
25936
25936
|
}
|
|
25937
25937
|
if (hasOwn(INTRINSICS, intrinsicName)) {
|
|
25938
|
-
var
|
|
25939
|
-
if (
|
|
25940
|
-
|
|
25938
|
+
var value2 = INTRINSICS[intrinsicName];
|
|
25939
|
+
if (value2 === needsEval) {
|
|
25940
|
+
value2 = doEval(intrinsicName);
|
|
25941
25941
|
}
|
|
25942
|
-
if (typeof
|
|
25942
|
+
if (typeof value2 === "undefined" && !allowMissing) {
|
|
25943
25943
|
throw new $TypeError("intrinsic " + name2 + " exists, but is not available. Please file an issue!");
|
|
25944
25944
|
}
|
|
25945
25945
|
return {
|
|
25946
25946
|
alias,
|
|
25947
25947
|
name: intrinsicName,
|
|
25948
|
-
value
|
|
25948
|
+
value: value2
|
|
25949
25949
|
};
|
|
25950
25950
|
}
|
|
25951
25951
|
throw new $SyntaxError("intrinsic " + name2 + " does not exist!");
|
|
@@ -25964,7 +25964,7 @@ var require_get_intrinsic = __commonJS((exports2, module2) => {
|
|
|
25964
25964
|
var intrinsicBaseName = parts.length > 0 ? parts[0] : "";
|
|
25965
25965
|
var intrinsic = getBaseIntrinsic("%" + intrinsicBaseName + "%", allowMissing);
|
|
25966
25966
|
var intrinsicRealName = intrinsic.name;
|
|
25967
|
-
var
|
|
25967
|
+
var value2 = intrinsic.value;
|
|
25968
25968
|
var skipFurtherCaching = false;
|
|
25969
25969
|
var alias = intrinsic.alias;
|
|
25970
25970
|
if (alias) {
|
|
@@ -25984,32 +25984,32 @@ var require_get_intrinsic = __commonJS((exports2, module2) => {
|
|
|
25984
25984
|
intrinsicBaseName += "." + part;
|
|
25985
25985
|
intrinsicRealName = "%" + intrinsicBaseName + "%";
|
|
25986
25986
|
if (hasOwn(INTRINSICS, intrinsicRealName)) {
|
|
25987
|
-
|
|
25988
|
-
} else if (
|
|
25989
|
-
if (!(part in
|
|
25987
|
+
value2 = INTRINSICS[intrinsicRealName];
|
|
25988
|
+
} else if (value2 != null) {
|
|
25989
|
+
if (!(part in value2)) {
|
|
25990
25990
|
if (!allowMissing) {
|
|
25991
25991
|
throw new $TypeError("base intrinsic for " + name2 + " exists, but the property is not available.");
|
|
25992
25992
|
}
|
|
25993
25993
|
return;
|
|
25994
25994
|
}
|
|
25995
25995
|
if ($gOPD && i2 + 1 >= parts.length) {
|
|
25996
|
-
var desc = $gOPD(
|
|
25996
|
+
var desc = $gOPD(value2, part);
|
|
25997
25997
|
isOwn = !!desc;
|
|
25998
25998
|
if (isOwn && "get" in desc && !("originalValue" in desc.get)) {
|
|
25999
|
-
|
|
25999
|
+
value2 = desc.get;
|
|
26000
26000
|
} else {
|
|
26001
|
-
|
|
26001
|
+
value2 = value2[part];
|
|
26002
26002
|
}
|
|
26003
26003
|
} else {
|
|
26004
|
-
isOwn = hasOwn(
|
|
26005
|
-
|
|
26004
|
+
isOwn = hasOwn(value2, part);
|
|
26005
|
+
value2 = value2[part];
|
|
26006
26006
|
}
|
|
26007
26007
|
if (isOwn && !skipFurtherCaching) {
|
|
26008
|
-
INTRINSICS[intrinsicRealName] =
|
|
26008
|
+
INTRINSICS[intrinsicRealName] = value2;
|
|
26009
26009
|
}
|
|
26010
26010
|
}
|
|
26011
26011
|
}
|
|
26012
|
-
return
|
|
26012
|
+
return value2;
|
|
26013
26013
|
};
|
|
26014
26014
|
});
|
|
26015
26015
|
|
|
@@ -26029,7 +26029,7 @@ var require_es_set_tostringtag = __commonJS((exports2, module2) => {
|
|
|
26029
26029
|
var hasOwn = require_hasown();
|
|
26030
26030
|
var $TypeError = require_type();
|
|
26031
26031
|
var toStringTag = hasToStringTag ? Symbol.toStringTag : null;
|
|
26032
|
-
module2.exports = function setToStringTag(object,
|
|
26032
|
+
module2.exports = function setToStringTag(object, value2) {
|
|
26033
26033
|
var overrideIfSet = arguments.length > 2 && !!arguments[2] && arguments[2].force;
|
|
26034
26034
|
var nonConfigurable = arguments.length > 2 && !!arguments[2] && arguments[2].nonConfigurable;
|
|
26035
26035
|
if (typeof overrideIfSet !== "undefined" && typeof overrideIfSet !== "boolean" || typeof nonConfigurable !== "undefined" && typeof nonConfigurable !== "boolean") {
|
|
@@ -26040,11 +26040,11 @@ var require_es_set_tostringtag = __commonJS((exports2, module2) => {
|
|
|
26040
26040
|
$defineProperty(object, toStringTag, {
|
|
26041
26041
|
configurable: !nonConfigurable,
|
|
26042
26042
|
enumerable: false,
|
|
26043
|
-
value,
|
|
26043
|
+
value: value2,
|
|
26044
26044
|
writable: false
|
|
26045
26045
|
});
|
|
26046
26046
|
} else {
|
|
26047
|
-
object[toStringTag] =
|
|
26047
|
+
object[toStringTag] = value2;
|
|
26048
26048
|
}
|
|
26049
26049
|
}
|
|
26050
26050
|
};
|
|
@@ -26092,77 +26092,77 @@ var require_form_data = __commonJS((exports2, module2) => {
|
|
|
26092
26092
|
FormData2.LINE_BREAK = `\r
|
|
26093
26093
|
`;
|
|
26094
26094
|
FormData2.DEFAULT_CONTENT_TYPE = "application/octet-stream";
|
|
26095
|
-
FormData2.prototype.append = function(field,
|
|
26095
|
+
FormData2.prototype.append = function(field, value2, options) {
|
|
26096
26096
|
options = options || {};
|
|
26097
26097
|
if (typeof options == "string") {
|
|
26098
26098
|
options = { filename: options };
|
|
26099
26099
|
}
|
|
26100
26100
|
var append = CombinedStream.prototype.append.bind(this);
|
|
26101
|
-
if (typeof
|
|
26102
|
-
|
|
26101
|
+
if (typeof value2 == "number") {
|
|
26102
|
+
value2 = "" + value2;
|
|
26103
26103
|
}
|
|
26104
|
-
if (Array.isArray(
|
|
26104
|
+
if (Array.isArray(value2)) {
|
|
26105
26105
|
this._error(new Error("Arrays are not supported."));
|
|
26106
26106
|
return;
|
|
26107
26107
|
}
|
|
26108
|
-
var header = this._multiPartHeader(field,
|
|
26108
|
+
var header = this._multiPartHeader(field, value2, options);
|
|
26109
26109
|
var footer = this._multiPartFooter();
|
|
26110
26110
|
append(header);
|
|
26111
|
-
append(
|
|
26111
|
+
append(value2);
|
|
26112
26112
|
append(footer);
|
|
26113
|
-
this._trackLength(header,
|
|
26113
|
+
this._trackLength(header, value2, options);
|
|
26114
26114
|
};
|
|
26115
|
-
FormData2.prototype._trackLength = function(header,
|
|
26115
|
+
FormData2.prototype._trackLength = function(header, value2, options) {
|
|
26116
26116
|
var valueLength = 0;
|
|
26117
26117
|
if (options.knownLength != null) {
|
|
26118
26118
|
valueLength += +options.knownLength;
|
|
26119
|
-
} else if (Buffer.isBuffer(
|
|
26120
|
-
valueLength =
|
|
26121
|
-
} else if (typeof
|
|
26122
|
-
valueLength = Buffer.byteLength(
|
|
26119
|
+
} else if (Buffer.isBuffer(value2)) {
|
|
26120
|
+
valueLength = value2.length;
|
|
26121
|
+
} else if (typeof value2 === "string") {
|
|
26122
|
+
valueLength = Buffer.byteLength(value2);
|
|
26123
26123
|
}
|
|
26124
26124
|
this._valueLength += valueLength;
|
|
26125
26125
|
this._overheadLength += Buffer.byteLength(header) + FormData2.LINE_BREAK.length;
|
|
26126
|
-
if (!
|
|
26126
|
+
if (!value2 || !value2.path && !(value2.readable && Object.prototype.hasOwnProperty.call(value2, "httpVersion")) && !(value2 instanceof Stream)) {
|
|
26127
26127
|
return;
|
|
26128
26128
|
}
|
|
26129
26129
|
if (!options.knownLength) {
|
|
26130
|
-
this._valuesToMeasure.push(
|
|
26130
|
+
this._valuesToMeasure.push(value2);
|
|
26131
26131
|
}
|
|
26132
26132
|
};
|
|
26133
|
-
FormData2.prototype._lengthRetriever = function(
|
|
26134
|
-
if (Object.prototype.hasOwnProperty.call(
|
|
26135
|
-
if (
|
|
26136
|
-
callback(null,
|
|
26133
|
+
FormData2.prototype._lengthRetriever = function(value2, callback) {
|
|
26134
|
+
if (Object.prototype.hasOwnProperty.call(value2, "fd")) {
|
|
26135
|
+
if (value2.end != null && value2.end != Infinity && value2.start != null) {
|
|
26136
|
+
callback(null, value2.end + 1 - (value2.start ? value2.start : 0));
|
|
26137
26137
|
} else {
|
|
26138
|
-
fs.stat(
|
|
26138
|
+
fs.stat(value2.path, function(err, stat) {
|
|
26139
26139
|
var fileSize;
|
|
26140
26140
|
if (err) {
|
|
26141
26141
|
callback(err);
|
|
26142
26142
|
return;
|
|
26143
26143
|
}
|
|
26144
|
-
fileSize = stat.size - (
|
|
26144
|
+
fileSize = stat.size - (value2.start ? value2.start : 0);
|
|
26145
26145
|
callback(null, fileSize);
|
|
26146
26146
|
});
|
|
26147
26147
|
}
|
|
26148
|
-
} else if (Object.prototype.hasOwnProperty.call(
|
|
26149
|
-
callback(null, +
|
|
26150
|
-
} else if (Object.prototype.hasOwnProperty.call(
|
|
26151
|
-
|
|
26152
|
-
|
|
26148
|
+
} else if (Object.prototype.hasOwnProperty.call(value2, "httpVersion")) {
|
|
26149
|
+
callback(null, +value2.headers["content-length"]);
|
|
26150
|
+
} else if (Object.prototype.hasOwnProperty.call(value2, "httpModule")) {
|
|
26151
|
+
value2.on("response", function(response) {
|
|
26152
|
+
value2.pause();
|
|
26153
26153
|
callback(null, +response.headers["content-length"]);
|
|
26154
26154
|
});
|
|
26155
|
-
|
|
26155
|
+
value2.resume();
|
|
26156
26156
|
} else {
|
|
26157
26157
|
callback("Unknown stream");
|
|
26158
26158
|
}
|
|
26159
26159
|
};
|
|
26160
|
-
FormData2.prototype._multiPartHeader = function(field,
|
|
26160
|
+
FormData2.prototype._multiPartHeader = function(field, value2, options) {
|
|
26161
26161
|
if (typeof options.header == "string") {
|
|
26162
26162
|
return options.header;
|
|
26163
26163
|
}
|
|
26164
|
-
var contentDisposition = this._getContentDisposition(
|
|
26165
|
-
var contentType = this._getContentType(
|
|
26164
|
+
var contentDisposition = this._getContentDisposition(value2, options);
|
|
26165
|
+
var contentType = this._getContentType(value2, options);
|
|
26166
26166
|
var contents = "";
|
|
26167
26167
|
var headers = {
|
|
26168
26168
|
"Content-Disposition": ["form-data", 'name="' + field + '"'].concat(contentDisposition || []),
|
|
@@ -26188,35 +26188,35 @@ var require_form_data = __commonJS((exports2, module2) => {
|
|
|
26188
26188
|
}
|
|
26189
26189
|
return "--" + this.getBoundary() + FormData2.LINE_BREAK + contents + FormData2.LINE_BREAK;
|
|
26190
26190
|
};
|
|
26191
|
-
FormData2.prototype._getContentDisposition = function(
|
|
26191
|
+
FormData2.prototype._getContentDisposition = function(value2, options) {
|
|
26192
26192
|
var filename, contentDisposition;
|
|
26193
26193
|
if (typeof options.filepath === "string") {
|
|
26194
26194
|
filename = path.normalize(options.filepath).replace(/\\/g, "/");
|
|
26195
|
-
} else if (options.filename ||
|
|
26196
|
-
filename = path.basename(options.filename ||
|
|
26197
|
-
} else if (
|
|
26198
|
-
filename = path.basename(
|
|
26195
|
+
} else if (options.filename || value2.name || value2.path) {
|
|
26196
|
+
filename = path.basename(options.filename || value2.name || value2.path);
|
|
26197
|
+
} else if (value2.readable && Object.prototype.hasOwnProperty.call(value2, "httpVersion")) {
|
|
26198
|
+
filename = path.basename(value2.client._httpMessage.path || "");
|
|
26199
26199
|
}
|
|
26200
26200
|
if (filename) {
|
|
26201
26201
|
contentDisposition = 'filename="' + filename + '"';
|
|
26202
26202
|
}
|
|
26203
26203
|
return contentDisposition;
|
|
26204
26204
|
};
|
|
26205
|
-
FormData2.prototype._getContentType = function(
|
|
26205
|
+
FormData2.prototype._getContentType = function(value2, options) {
|
|
26206
26206
|
var contentType = options.contentType;
|
|
26207
|
-
if (!contentType &&
|
|
26208
|
-
contentType = mime.lookup(
|
|
26207
|
+
if (!contentType && value2.name) {
|
|
26208
|
+
contentType = mime.lookup(value2.name);
|
|
26209
26209
|
}
|
|
26210
|
-
if (!contentType &&
|
|
26211
|
-
contentType = mime.lookup(
|
|
26210
|
+
if (!contentType && value2.path) {
|
|
26211
|
+
contentType = mime.lookup(value2.path);
|
|
26212
26212
|
}
|
|
26213
|
-
if (!contentType &&
|
|
26214
|
-
contentType =
|
|
26213
|
+
if (!contentType && value2.readable && Object.prototype.hasOwnProperty.call(value2, "httpVersion")) {
|
|
26214
|
+
contentType = value2.headers["content-type"];
|
|
26215
26215
|
}
|
|
26216
26216
|
if (!contentType && (options.filepath || options.filename)) {
|
|
26217
26217
|
contentType = mime.lookup(options.filepath || options.filename);
|
|
26218
26218
|
}
|
|
26219
|
-
if (!contentType && typeof
|
|
26219
|
+
if (!contentType && typeof value2 == "object") {
|
|
26220
26220
|
contentType = FormData2.DEFAULT_CONTENT_TYPE;
|
|
26221
26221
|
}
|
|
26222
26222
|
return contentType;
|
|
@@ -26589,9 +26589,9 @@ var require_follow_redirects = __commonJS((exports2, module2) => {
|
|
|
26589
26589
|
this._ending = true;
|
|
26590
26590
|
}
|
|
26591
26591
|
};
|
|
26592
|
-
RedirectableRequest.prototype.setHeader = function(name2,
|
|
26593
|
-
this._options.headers[name2] =
|
|
26594
|
-
this._currentRequest.setHeader(name2,
|
|
26592
|
+
RedirectableRequest.prototype.setHeader = function(name2, value2) {
|
|
26593
|
+
this._options.headers[name2] = value2;
|
|
26594
|
+
this._currentRequest.setHeader(name2, value2);
|
|
26595
26595
|
};
|
|
26596
26596
|
RedirectableRequest.prototype.removeHeader = function(name2) {
|
|
26597
26597
|
delete this._options.headers[name2];
|
|
@@ -26911,17 +26911,17 @@ var require_follow_redirects = __commonJS((exports2, module2) => {
|
|
|
26911
26911
|
var dot = subdomain.length - domain.length - 1;
|
|
26912
26912
|
return dot > 0 && subdomain[dot] === "." && subdomain.endsWith(domain);
|
|
26913
26913
|
}
|
|
26914
|
-
function isString2(
|
|
26915
|
-
return typeof
|
|
26914
|
+
function isString2(value2) {
|
|
26915
|
+
return typeof value2 === "string" || value2 instanceof String;
|
|
26916
26916
|
}
|
|
26917
|
-
function isFunction(
|
|
26918
|
-
return typeof
|
|
26917
|
+
function isFunction(value2) {
|
|
26918
|
+
return typeof value2 === "function";
|
|
26919
26919
|
}
|
|
26920
|
-
function isBuffer(
|
|
26921
|
-
return typeof
|
|
26920
|
+
function isBuffer(value2) {
|
|
26921
|
+
return typeof value2 === "object" && "length" in value2;
|
|
26922
26922
|
}
|
|
26923
|
-
function isURL2(
|
|
26924
|
-
return URL2 &&
|
|
26923
|
+
function isURL2(value2) {
|
|
26924
|
+
return URL2 && value2 instanceof URL2;
|
|
26925
26925
|
}
|
|
26926
26926
|
module2.exports = wrap3({ http: http2, https: https2 });
|
|
26927
26927
|
module2.exports.wrap = wrap3;
|
|
@@ -27117,14 +27117,14 @@ var require_axios = __commonJS((exports2, module2) => {
|
|
|
27117
27117
|
} while (sourceObj && (!filter || filter(sourceObj, destObj)) && sourceObj !== Object.prototype);
|
|
27118
27118
|
return destObj;
|
|
27119
27119
|
};
|
|
27120
|
-
var endsWith = (str, searchString,
|
|
27120
|
+
var endsWith = (str, searchString, position2) => {
|
|
27121
27121
|
str = String(str);
|
|
27122
|
-
if (
|
|
27123
|
-
|
|
27122
|
+
if (position2 === undefined || position2 > str.length) {
|
|
27123
|
+
position2 = str.length;
|
|
27124
27124
|
}
|
|
27125
|
-
|
|
27126
|
-
const lastIndex = str.indexOf(searchString,
|
|
27127
|
-
return lastIndex !== -1 && lastIndex ===
|
|
27125
|
+
position2 -= searchString.length;
|
|
27126
|
+
const lastIndex = str.indexOf(searchString, position2);
|
|
27127
|
+
return lastIndex !== -1 && lastIndex === position2;
|
|
27128
27128
|
};
|
|
27129
27129
|
var toArray = (thing) => {
|
|
27130
27130
|
if (!thing)
|
|
@@ -27186,8 +27186,8 @@ var require_axios = __commonJS((exports2, module2) => {
|
|
|
27186
27186
|
if (isFunction(obj) && ["arguments", "caller", "callee"].indexOf(name2) !== -1) {
|
|
27187
27187
|
return false;
|
|
27188
27188
|
}
|
|
27189
|
-
const
|
|
27190
|
-
if (!isFunction(
|
|
27189
|
+
const value2 = obj[name2];
|
|
27190
|
+
if (!isFunction(value2))
|
|
27191
27191
|
return;
|
|
27192
27192
|
descriptor.enumerable = false;
|
|
27193
27193
|
if ("writable" in descriptor) {
|
|
@@ -27204,8 +27204,8 @@ var require_axios = __commonJS((exports2, module2) => {
|
|
|
27204
27204
|
var toObjectSet = (arrayOrString, delimiter) => {
|
|
27205
27205
|
const obj = {};
|
|
27206
27206
|
const define2 = (arr) => {
|
|
27207
|
-
arr.forEach((
|
|
27208
|
-
obj[
|
|
27207
|
+
arr.forEach((value2) => {
|
|
27208
|
+
obj[value2] = true;
|
|
27209
27209
|
});
|
|
27210
27210
|
};
|
|
27211
27211
|
isArray3(arrayOrString) ? define2(arrayOrString) : define2(String(arrayOrString).split(delimiter));
|
|
@@ -27213,8 +27213,8 @@ var require_axios = __commonJS((exports2, module2) => {
|
|
|
27213
27213
|
};
|
|
27214
27214
|
var noop2 = () => {
|
|
27215
27215
|
};
|
|
27216
|
-
var toFiniteNumber = (
|
|
27217
|
-
return
|
|
27216
|
+
var toFiniteNumber = (value2, defaultValue) => {
|
|
27217
|
+
return value2 != null && Number.isFinite(value2 = +value2) ? value2 : defaultValue;
|
|
27218
27218
|
};
|
|
27219
27219
|
function isSpecCompliantForm(thing) {
|
|
27220
27220
|
return !!(thing && isFunction(thing.append) && thing[Symbol.toStringTag] === "FormData" && thing[Symbol.iterator]);
|
|
@@ -27229,8 +27229,8 @@ var require_axios = __commonJS((exports2, module2) => {
|
|
|
27229
27229
|
if (!("toJSON" in source)) {
|
|
27230
27230
|
stack[i2] = source;
|
|
27231
27231
|
const target = isArray3(source) ? [] : {};
|
|
27232
|
-
forEach2(source, (
|
|
27233
|
-
const reducedValue = visit(
|
|
27232
|
+
forEach2(source, (value2, key) => {
|
|
27233
|
+
const reducedValue = visit(value2, i2 + 1);
|
|
27234
27234
|
!isUndefined3(reducedValue) && (target[key] = reducedValue);
|
|
27235
27235
|
});
|
|
27236
27236
|
stack[i2] = undefined;
|
|
@@ -27425,27 +27425,27 @@ var require_axios = __commonJS((exports2, module2) => {
|
|
|
27425
27425
|
if (!utils$1.isFunction(visitor)) {
|
|
27426
27426
|
throw new TypeError("visitor must be a function");
|
|
27427
27427
|
}
|
|
27428
|
-
function convertValue(
|
|
27429
|
-
if (
|
|
27428
|
+
function convertValue(value2) {
|
|
27429
|
+
if (value2 === null)
|
|
27430
27430
|
return "";
|
|
27431
|
-
if (utils$1.isDate(
|
|
27432
|
-
return
|
|
27431
|
+
if (utils$1.isDate(value2)) {
|
|
27432
|
+
return value2.toISOString();
|
|
27433
27433
|
}
|
|
27434
|
-
if (!useBlob && utils$1.isBlob(
|
|
27434
|
+
if (!useBlob && utils$1.isBlob(value2)) {
|
|
27435
27435
|
throw new AxiosError("Blob is not supported. Use a Buffer instead.");
|
|
27436
27436
|
}
|
|
27437
|
-
if (utils$1.isArrayBuffer(
|
|
27438
|
-
return useBlob && typeof Blob === "function" ? new Blob([
|
|
27437
|
+
if (utils$1.isArrayBuffer(value2) || utils$1.isTypedArray(value2)) {
|
|
27438
|
+
return useBlob && typeof Blob === "function" ? new Blob([value2]) : Buffer.from(value2);
|
|
27439
27439
|
}
|
|
27440
|
-
return
|
|
27440
|
+
return value2;
|
|
27441
27441
|
}
|
|
27442
|
-
function defaultVisitor(
|
|
27443
|
-
let arr =
|
|
27444
|
-
if (
|
|
27442
|
+
function defaultVisitor(value2, key, path) {
|
|
27443
|
+
let arr = value2;
|
|
27444
|
+
if (value2 && !path && typeof value2 === "object") {
|
|
27445
27445
|
if (utils$1.endsWith(key, "{}")) {
|
|
27446
27446
|
key = metaTokens ? key : key.slice(0, -2);
|
|
27447
|
-
|
|
27448
|
-
} else if (utils$1.isArray(
|
|
27447
|
+
value2 = JSON.stringify(value2);
|
|
27448
|
+
} else if (utils$1.isArray(value2) && isFlatArray(value2) || (utils$1.isFileList(value2) || utils$1.endsWith(key, "[]")) && (arr = utils$1.toArray(value2))) {
|
|
27449
27449
|
key = removeBrackets(key);
|
|
27450
27450
|
arr.forEach(function each(el, index) {
|
|
27451
27451
|
!(utils$1.isUndefined(el) || el === null) && formData.append(indexes === true ? renderKey([key], index, dots) : indexes === null ? key : key + "[]", convertValue(el));
|
|
@@ -27453,10 +27453,10 @@ var require_axios = __commonJS((exports2, module2) => {
|
|
|
27453
27453
|
return false;
|
|
27454
27454
|
}
|
|
27455
27455
|
}
|
|
27456
|
-
if (isVisitable(
|
|
27456
|
+
if (isVisitable(value2)) {
|
|
27457
27457
|
return true;
|
|
27458
27458
|
}
|
|
27459
|
-
formData.append(renderKey(path, key, dots), convertValue(
|
|
27459
|
+
formData.append(renderKey(path, key, dots), convertValue(value2));
|
|
27460
27460
|
return false;
|
|
27461
27461
|
}
|
|
27462
27462
|
const stack = [];
|
|
@@ -27465,14 +27465,14 @@ var require_axios = __commonJS((exports2, module2) => {
|
|
|
27465
27465
|
convertValue,
|
|
27466
27466
|
isVisitable
|
|
27467
27467
|
});
|
|
27468
|
-
function build(
|
|
27469
|
-
if (utils$1.isUndefined(
|
|
27468
|
+
function build(value2, path) {
|
|
27469
|
+
if (utils$1.isUndefined(value2))
|
|
27470
27470
|
return;
|
|
27471
|
-
if (stack.indexOf(
|
|
27471
|
+
if (stack.indexOf(value2) !== -1) {
|
|
27472
27472
|
throw Error("Circular reference detected in " + path.join("."));
|
|
27473
27473
|
}
|
|
27474
|
-
stack.push(
|
|
27475
|
-
utils$1.forEach(
|
|
27474
|
+
stack.push(value2);
|
|
27475
|
+
utils$1.forEach(value2, function each(el, key) {
|
|
27476
27476
|
const result = !(utils$1.isUndefined(el) || el === null) && visitor.call(formData, el, utils$1.isString(key) ? key.trim() : key, path, exposedHelpers);
|
|
27477
27477
|
if (result === true) {
|
|
27478
27478
|
build(el, path ? path.concat(key) : [key]);
|
|
@@ -27505,12 +27505,12 @@ var require_axios = __commonJS((exports2, module2) => {
|
|
|
27505
27505
|
params && toFormData(params, this, options);
|
|
27506
27506
|
}
|
|
27507
27507
|
var prototype = AxiosURLSearchParams.prototype;
|
|
27508
|
-
prototype.append = function append(name2,
|
|
27509
|
-
this._pairs.push([name2,
|
|
27508
|
+
prototype.append = function append(name2, value2) {
|
|
27509
|
+
this._pairs.push([name2, value2]);
|
|
27510
27510
|
};
|
|
27511
27511
|
prototype.toString = function toString(encoder2) {
|
|
27512
|
-
const _encode = encoder2 ? function(
|
|
27513
|
-
return encoder2.call(this,
|
|
27512
|
+
const _encode = encoder2 ? function(value2) {
|
|
27513
|
+
return encoder2.call(this, value2, encode$1);
|
|
27514
27514
|
} : encode$1;
|
|
27515
27515
|
return this._pairs.map(function each(pair) {
|
|
27516
27516
|
return _encode(pair[0]) + "=" + _encode(pair[1]);
|
|
@@ -27633,9 +27633,9 @@ var require_axios = __commonJS((exports2, module2) => {
|
|
|
27633
27633
|
};
|
|
27634
27634
|
function toURLEncodedForm(data, options) {
|
|
27635
27635
|
return toFormData(data, new platform.classes.URLSearchParams, Object.assign({
|
|
27636
|
-
visitor: function(
|
|
27637
|
-
if (platform.isNode && utils$1.isBuffer(
|
|
27638
|
-
this.append(key,
|
|
27636
|
+
visitor: function(value2, key, path, helpers) {
|
|
27637
|
+
if (platform.isNode && utils$1.isBuffer(value2)) {
|
|
27638
|
+
this.append(key, value2.toString("base64"));
|
|
27639
27639
|
return false;
|
|
27640
27640
|
}
|
|
27641
27641
|
return helpers.defaultVisitor.apply(this, arguments);
|
|
@@ -27660,7 +27660,7 @@ var require_axios = __commonJS((exports2, module2) => {
|
|
|
27660
27660
|
return obj;
|
|
27661
27661
|
}
|
|
27662
27662
|
function formDataToJSON(formData) {
|
|
27663
|
-
function buildPath(path,
|
|
27663
|
+
function buildPath(path, value2, target, index) {
|
|
27664
27664
|
let name2 = path[index++];
|
|
27665
27665
|
if (name2 === "__proto__")
|
|
27666
27666
|
return true;
|
|
@@ -27669,16 +27669,16 @@ var require_axios = __commonJS((exports2, module2) => {
|
|
|
27669
27669
|
name2 = !name2 && utils$1.isArray(target) ? target.length : name2;
|
|
27670
27670
|
if (isLast) {
|
|
27671
27671
|
if (utils$1.hasOwnProp(target, name2)) {
|
|
27672
|
-
target[name2] = [target[name2],
|
|
27672
|
+
target[name2] = [target[name2], value2];
|
|
27673
27673
|
} else {
|
|
27674
|
-
target[name2] =
|
|
27674
|
+
target[name2] = value2;
|
|
27675
27675
|
}
|
|
27676
27676
|
return !isNumericKey;
|
|
27677
27677
|
}
|
|
27678
27678
|
if (!target[name2] || !utils$1.isObject(target[name2])) {
|
|
27679
27679
|
target[name2] = [];
|
|
27680
27680
|
}
|
|
27681
|
-
const result = buildPath(path,
|
|
27681
|
+
const result = buildPath(path, value2, target[name2], index);
|
|
27682
27682
|
if (result && utils$1.isArray(target[name2])) {
|
|
27683
27683
|
target[name2] = arrayToObject(target[name2]);
|
|
27684
27684
|
}
|
|
@@ -27686,8 +27686,8 @@ var require_axios = __commonJS((exports2, module2) => {
|
|
|
27686
27686
|
}
|
|
27687
27687
|
if (utils$1.isFormData(formData) && utils$1.isFunction(formData.entries)) {
|
|
27688
27688
|
const obj = {};
|
|
27689
|
-
utils$1.forEachEntry(formData, (name2,
|
|
27690
|
-
buildPath(parsePropPath(name2),
|
|
27689
|
+
utils$1.forEachEntry(formData, (name2, value2) => {
|
|
27690
|
+
buildPath(parsePropPath(name2), value2, obj, 0);
|
|
27691
27691
|
});
|
|
27692
27692
|
return obj;
|
|
27693
27693
|
}
|
|
@@ -27840,11 +27840,11 @@ var require_axios = __commonJS((exports2, module2) => {
|
|
|
27840
27840
|
function normalizeHeader(header) {
|
|
27841
27841
|
return header && String(header).trim().toLowerCase();
|
|
27842
27842
|
}
|
|
27843
|
-
function normalizeValue(
|
|
27844
|
-
if (
|
|
27845
|
-
return
|
|
27843
|
+
function normalizeValue(value2) {
|
|
27844
|
+
if (value2 === false || value2 == null) {
|
|
27845
|
+
return value2;
|
|
27846
27846
|
}
|
|
27847
|
-
return utils$1.isArray(
|
|
27847
|
+
return utils$1.isArray(value2) ? value2.map(normalizeValue) : String(value2);
|
|
27848
27848
|
}
|
|
27849
27849
|
function parseTokens(str) {
|
|
27850
27850
|
const tokens = Object.create(null);
|
|
@@ -27856,20 +27856,20 @@ var require_axios = __commonJS((exports2, module2) => {
|
|
|
27856
27856
|
return tokens;
|
|
27857
27857
|
}
|
|
27858
27858
|
var isValidHeaderName = (str) => /^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(str.trim());
|
|
27859
|
-
function matchHeaderValue(context3,
|
|
27859
|
+
function matchHeaderValue(context3, value2, header, filter, isHeaderNameFilter) {
|
|
27860
27860
|
if (utils$1.isFunction(filter)) {
|
|
27861
|
-
return filter.call(this,
|
|
27861
|
+
return filter.call(this, value2, header);
|
|
27862
27862
|
}
|
|
27863
27863
|
if (isHeaderNameFilter) {
|
|
27864
|
-
|
|
27864
|
+
value2 = header;
|
|
27865
27865
|
}
|
|
27866
|
-
if (!utils$1.isString(
|
|
27866
|
+
if (!utils$1.isString(value2))
|
|
27867
27867
|
return;
|
|
27868
27868
|
if (utils$1.isString(filter)) {
|
|
27869
|
-
return
|
|
27869
|
+
return value2.indexOf(filter) !== -1;
|
|
27870
27870
|
}
|
|
27871
27871
|
if (utils$1.isRegExp(filter)) {
|
|
27872
|
-
return filter.test(
|
|
27872
|
+
return filter.test(value2);
|
|
27873
27873
|
}
|
|
27874
27874
|
}
|
|
27875
27875
|
function formatHeader(header) {
|
|
@@ -27911,8 +27911,8 @@ var require_axios = __commonJS((exports2, module2) => {
|
|
|
27911
27911
|
} else if (utils$1.isString(header) && (header = header.trim()) && !isValidHeaderName(header)) {
|
|
27912
27912
|
setHeaders(parseHeaders(header), valueOrRewrite);
|
|
27913
27913
|
} else if (utils$1.isHeaders(header)) {
|
|
27914
|
-
for (const [key,
|
|
27915
|
-
setHeader(
|
|
27914
|
+
for (const [key, value2] of header.entries()) {
|
|
27915
|
+
setHeader(value2, key, rewrite);
|
|
27916
27916
|
}
|
|
27917
27917
|
} else {
|
|
27918
27918
|
header != null && setHeader(valueOrRewrite, header, rewrite);
|
|
@@ -27924,18 +27924,18 @@ var require_axios = __commonJS((exports2, module2) => {
|
|
|
27924
27924
|
if (header) {
|
|
27925
27925
|
const key = utils$1.findKey(this, header);
|
|
27926
27926
|
if (key) {
|
|
27927
|
-
const
|
|
27927
|
+
const value2 = this[key];
|
|
27928
27928
|
if (!parser) {
|
|
27929
|
-
return
|
|
27929
|
+
return value2;
|
|
27930
27930
|
}
|
|
27931
27931
|
if (parser === true) {
|
|
27932
|
-
return parseTokens(
|
|
27932
|
+
return parseTokens(value2);
|
|
27933
27933
|
}
|
|
27934
27934
|
if (utils$1.isFunction(parser)) {
|
|
27935
|
-
return parser.call(this,
|
|
27935
|
+
return parser.call(this, value2, key);
|
|
27936
27936
|
}
|
|
27937
27937
|
if (utils$1.isRegExp(parser)) {
|
|
27938
|
-
return parser.exec(
|
|
27938
|
+
return parser.exec(value2);
|
|
27939
27939
|
}
|
|
27940
27940
|
throw new TypeError("parser must be boolean|regexp|function");
|
|
27941
27941
|
}
|
|
@@ -27985,10 +27985,10 @@ var require_axios = __commonJS((exports2, module2) => {
|
|
|
27985
27985
|
normalize(format) {
|
|
27986
27986
|
const self2 = this;
|
|
27987
27987
|
const headers = {};
|
|
27988
|
-
utils$1.forEach(this, (
|
|
27988
|
+
utils$1.forEach(this, (value2, header) => {
|
|
27989
27989
|
const key = utils$1.findKey(headers, header);
|
|
27990
27990
|
if (key) {
|
|
27991
|
-
self2[key] = normalizeValue(
|
|
27991
|
+
self2[key] = normalizeValue(value2);
|
|
27992
27992
|
delete self2[header];
|
|
27993
27993
|
return;
|
|
27994
27994
|
}
|
|
@@ -27996,7 +27996,7 @@ var require_axios = __commonJS((exports2, module2) => {
|
|
|
27996
27996
|
if (normalized !== header) {
|
|
27997
27997
|
delete self2[header];
|
|
27998
27998
|
}
|
|
27999
|
-
self2[normalized] = normalizeValue(
|
|
27999
|
+
self2[normalized] = normalizeValue(value2);
|
|
28000
28000
|
headers[normalized] = true;
|
|
28001
28001
|
});
|
|
28002
28002
|
return this;
|
|
@@ -28006,8 +28006,8 @@ var require_axios = __commonJS((exports2, module2) => {
|
|
|
28006
28006
|
}
|
|
28007
28007
|
toJSON(asStrings) {
|
|
28008
28008
|
const obj = Object.create(null);
|
|
28009
|
-
utils$1.forEach(this, (
|
|
28010
|
-
|
|
28009
|
+
utils$1.forEach(this, (value2, header) => {
|
|
28010
|
+
value2 != null && value2 !== false && (obj[header] = asStrings && utils$1.isArray(value2) ? value2.join(", ") : value2);
|
|
28011
28011
|
});
|
|
28012
28012
|
return obj;
|
|
28013
28013
|
}
|
|
@@ -28015,7 +28015,7 @@ var require_axios = __commonJS((exports2, module2) => {
|
|
|
28015
28015
|
return Object.entries(this.toJSON())[Symbol.iterator]();
|
|
28016
28016
|
}
|
|
28017
28017
|
toString() {
|
|
28018
|
-
return Object.entries(this.toJSON()).map(([header,
|
|
28018
|
+
return Object.entries(this.toJSON()).map(([header, value2]) => header + ": " + value2).join(`
|
|
28019
28019
|
`);
|
|
28020
28020
|
}
|
|
28021
28021
|
get [Symbol.toStringTag]() {
|
|
@@ -28047,10 +28047,10 @@ var require_axios = __commonJS((exports2, module2) => {
|
|
|
28047
28047
|
}
|
|
28048
28048
|
}
|
|
28049
28049
|
AxiosHeaders.accessor(["Content-Type", "Content-Length", "Accept", "Accept-Encoding", "User-Agent", "Authorization"]);
|
|
28050
|
-
utils$1.reduceDescriptors(AxiosHeaders.prototype, ({ value }, key) => {
|
|
28050
|
+
utils$1.reduceDescriptors(AxiosHeaders.prototype, ({ value: value2 }, key) => {
|
|
28051
28051
|
let mapped = key[0].toUpperCase() + key.slice(1);
|
|
28052
28052
|
return {
|
|
28053
|
-
get: () =>
|
|
28053
|
+
get: () => value2,
|
|
28054
28054
|
set(headerValue) {
|
|
28055
28055
|
this[mapped] = headerValue;
|
|
28056
28056
|
}
|
|
@@ -28069,8 +28069,8 @@ var require_axios = __commonJS((exports2, module2) => {
|
|
|
28069
28069
|
headers.normalize();
|
|
28070
28070
|
return data;
|
|
28071
28071
|
}
|
|
28072
|
-
function isCancel(
|
|
28073
|
-
return !!(
|
|
28072
|
+
function isCancel(value2) {
|
|
28073
|
+
return !!(value2 && value2.__CANCEL__);
|
|
28074
28074
|
}
|
|
28075
28075
|
function CanceledError(message2, config2, request) {
|
|
28076
28076
|
AxiosError.call(this, message2 == null ? "canceled" : message2, AxiosError.ERR_CANCELED, config2, request);
|
|
@@ -28266,28 +28266,28 @@ var require_axios = __commonJS((exports2, module2) => {
|
|
|
28266
28266
|
var CRLF_BYTES_COUNT = 2;
|
|
28267
28267
|
|
|
28268
28268
|
class FormDataPart {
|
|
28269
|
-
constructor(name2,
|
|
28269
|
+
constructor(name2, value2) {
|
|
28270
28270
|
const { escapeName } = this.constructor;
|
|
28271
|
-
const isStringValue = utils$1.isString(
|
|
28272
|
-
let headers = `Content-Disposition: form-data; name="${escapeName(name2)}"${!isStringValue &&
|
|
28271
|
+
const isStringValue = utils$1.isString(value2);
|
|
28272
|
+
let headers = `Content-Disposition: form-data; name="${escapeName(name2)}"${!isStringValue && value2.name ? `; filename="${escapeName(value2.name)}"` : ""}${CRLF}`;
|
|
28273
28273
|
if (isStringValue) {
|
|
28274
|
-
|
|
28274
|
+
value2 = textEncoder.encode(String(value2).replace(/\r?\n|\r\n?/g, CRLF));
|
|
28275
28275
|
} else {
|
|
28276
|
-
headers += `Content-Type: ${
|
|
28276
|
+
headers += `Content-Type: ${value2.type || "application/octet-stream"}${CRLF}`;
|
|
28277
28277
|
}
|
|
28278
28278
|
this.headers = textEncoder.encode(headers + CRLF);
|
|
28279
|
-
this.contentLength = isStringValue ?
|
|
28279
|
+
this.contentLength = isStringValue ? value2.byteLength : value2.size;
|
|
28280
28280
|
this.size = this.headers.byteLength + this.contentLength + CRLF_BYTES_COUNT;
|
|
28281
28281
|
this.name = name2;
|
|
28282
|
-
this.value =
|
|
28282
|
+
this.value = value2;
|
|
28283
28283
|
}
|
|
28284
28284
|
async* encode() {
|
|
28285
28285
|
yield this.headers;
|
|
28286
|
-
const { value } = this;
|
|
28287
|
-
if (utils$1.isTypedArray(
|
|
28288
|
-
yield
|
|
28286
|
+
const { value: value2 } = this;
|
|
28287
|
+
if (utils$1.isTypedArray(value2)) {
|
|
28288
|
+
yield value2;
|
|
28289
28289
|
} else {
|
|
28290
|
-
yield* readBlob$1(
|
|
28290
|
+
yield* readBlob$1(value2);
|
|
28291
28291
|
}
|
|
28292
28292
|
yield CRLF_BYTES;
|
|
28293
28293
|
}
|
|
@@ -28314,8 +28314,8 @@ var require_axios = __commonJS((exports2, module2) => {
|
|
|
28314
28314
|
const boundaryBytes = textEncoder.encode("--" + boundary + CRLF);
|
|
28315
28315
|
const footerBytes = textEncoder.encode("--" + boundary + "--" + CRLF + CRLF);
|
|
28316
28316
|
let contentLength = footerBytes.byteLength;
|
|
28317
|
-
const parts = Array.from(form.entries()).map(([name2,
|
|
28318
|
-
const part = new FormDataPart(name2,
|
|
28317
|
+
const parts = Array.from(form.entries()).map(([name2, value2]) => {
|
|
28318
|
+
const part = new FormDataPart(name2, value2);
|
|
28319
28319
|
contentLength += part.size;
|
|
28320
28320
|
return part;
|
|
28321
28321
|
});
|
|
@@ -28360,9 +28360,9 @@ var require_axios = __commonJS((exports2, module2) => {
|
|
|
28360
28360
|
var callbackify = (fn, reducer) => {
|
|
28361
28361
|
return utils$1.isAsyncFn(fn) ? function(...args) {
|
|
28362
28362
|
const cb = args.pop();
|
|
28363
|
-
fn.apply(this, args).then((
|
|
28363
|
+
fn.apply(this, args).then((value2) => {
|
|
28364
28364
|
try {
|
|
28365
|
-
reducer ? cb(null, ...reducer(
|
|
28365
|
+
reducer ? cb(null, ...reducer(value2)) : cb(null, value2);
|
|
28366
28366
|
} catch (err) {
|
|
28367
28367
|
cb(err);
|
|
28368
28368
|
}
|
|
@@ -28532,15 +28532,15 @@ var require_axios = __commonJS((exports2, module2) => {
|
|
|
28532
28532
|
return new Promise((resolve, reject) => {
|
|
28533
28533
|
let onDone;
|
|
28534
28534
|
let isDone;
|
|
28535
|
-
const done = (
|
|
28535
|
+
const done = (value2, isRejected) => {
|
|
28536
28536
|
if (isDone)
|
|
28537
28537
|
return;
|
|
28538
28538
|
isDone = true;
|
|
28539
|
-
onDone && onDone(
|
|
28539
|
+
onDone && onDone(value2, isRejected);
|
|
28540
28540
|
};
|
|
28541
|
-
const _resolve = (
|
|
28542
|
-
done(
|
|
28543
|
-
resolve(
|
|
28541
|
+
const _resolve = (value2) => {
|
|
28542
|
+
done(value2);
|
|
28543
|
+
resolve(value2);
|
|
28544
28544
|
};
|
|
28545
28545
|
const _reject = (reason) => {
|
|
28546
28546
|
done(reason, true);
|
|
@@ -28568,7 +28568,7 @@ var require_axios = __commonJS((exports2, module2) => {
|
|
|
28568
28568
|
let rejected = false;
|
|
28569
28569
|
let req;
|
|
28570
28570
|
if (lookup) {
|
|
28571
|
-
const _lookup = callbackify$1(lookup, (
|
|
28571
|
+
const _lookup = callbackify$1(lookup, (value2) => utils$1.isArray(value2) ? value2 : [value2]);
|
|
28572
28572
|
lookup = (hostname, opt, cb) => {
|
|
28573
28573
|
_lookup(hostname, opt, (err, arg0, arg1) => {
|
|
28574
28574
|
if (err) {
|
|
@@ -28589,7 +28589,7 @@ var require_axios = __commonJS((exports2, module2) => {
|
|
|
28589
28589
|
}
|
|
28590
28590
|
emitter.removeAllListeners();
|
|
28591
28591
|
};
|
|
28592
|
-
onDone((
|
|
28592
|
+
onDone((value2, isRejected) => {
|
|
28593
28593
|
isDone = true;
|
|
28594
28594
|
if (isRejected) {
|
|
28595
28595
|
rejected = true;
|
|
@@ -28924,8 +28924,8 @@ var require_axios = __commonJS((exports2, module2) => {
|
|
|
28924
28924
|
return origin2.protocol === url2.protocol && origin2.host === url2.host && (isMSIE || origin2.port === url2.port);
|
|
28925
28925
|
})(new URL(platform.origin), platform.navigator && /(msie|trident)/i.test(platform.navigator.userAgent)) : () => true;
|
|
28926
28926
|
var cookies = platform.hasStandardBrowserEnv ? {
|
|
28927
|
-
write(name2,
|
|
28928
|
-
const cookie = [name2 + "=" + encodeURIComponent(
|
|
28927
|
+
write(name2, value2, expires, path, domain, secure) {
|
|
28928
|
+
const cookie = [name2 + "=" + encodeURIComponent(value2)];
|
|
28929
28929
|
utils$1.isNumber(expires) && cookie.push("expires=" + new Date(expires).toGMTString());
|
|
28930
28930
|
utils$1.isString(path) && cookie.push("path=" + path);
|
|
28931
28931
|
utils$1.isString(domain) && cookie.push("domain=" + domain);
|
|
@@ -29087,8 +29087,8 @@ var require_axios = __commonJS((exports2, module2) => {
|
|
|
29087
29087
|
config: config2,
|
|
29088
29088
|
request
|
|
29089
29089
|
};
|
|
29090
|
-
settle(function _resolve(
|
|
29091
|
-
resolve(
|
|
29090
|
+
settle(function _resolve(value2) {
|
|
29091
|
+
resolve(value2);
|
|
29092
29092
|
done();
|
|
29093
29093
|
}, function _reject(err) {
|
|
29094
29094
|
reject(err);
|
|
@@ -29233,11 +29233,11 @@ var require_axios = __commonJS((exports2, module2) => {
|
|
|
29233
29233
|
const reader = stream3.getReader();
|
|
29234
29234
|
try {
|
|
29235
29235
|
for (;; ) {
|
|
29236
|
-
const { done, value } = await reader.read();
|
|
29236
|
+
const { done, value: value2 } = await reader.read();
|
|
29237
29237
|
if (done) {
|
|
29238
29238
|
break;
|
|
29239
29239
|
}
|
|
29240
|
-
yield
|
|
29240
|
+
yield value2;
|
|
29241
29241
|
}
|
|
29242
29242
|
} finally {
|
|
29243
29243
|
await reader.cancel();
|
|
@@ -29256,18 +29256,18 @@ var require_axios = __commonJS((exports2, module2) => {
|
|
|
29256
29256
|
return new ReadableStream({
|
|
29257
29257
|
async pull(controller) {
|
|
29258
29258
|
try {
|
|
29259
|
-
const { done: done2, value } = await iterator.next();
|
|
29259
|
+
const { done: done2, value: value2 } = await iterator.next();
|
|
29260
29260
|
if (done2) {
|
|
29261
29261
|
_onFinish();
|
|
29262
29262
|
controller.close();
|
|
29263
29263
|
return;
|
|
29264
29264
|
}
|
|
29265
|
-
let len =
|
|
29265
|
+
let len = value2.byteLength;
|
|
29266
29266
|
if (onProgress) {
|
|
29267
29267
|
let loadedBytes = bytes += len;
|
|
29268
29268
|
onProgress(loadedBytes);
|
|
29269
29269
|
}
|
|
29270
|
-
controller.enqueue(new Uint8Array(
|
|
29270
|
+
controller.enqueue(new Uint8Array(value2));
|
|
29271
29271
|
} catch (err) {
|
|
29272
29272
|
_onFinish(err);
|
|
29273
29273
|
throw err;
|
|
@@ -29436,13 +29436,13 @@ var require_axios = __commonJS((exports2, module2) => {
|
|
|
29436
29436
|
xhr: xhrAdapter,
|
|
29437
29437
|
fetch: fetchAdapter
|
|
29438
29438
|
};
|
|
29439
|
-
utils$1.forEach(knownAdapters, (fn,
|
|
29439
|
+
utils$1.forEach(knownAdapters, (fn, value2) => {
|
|
29440
29440
|
if (fn) {
|
|
29441
29441
|
try {
|
|
29442
|
-
Object.defineProperty(fn, "name", { value });
|
|
29442
|
+
Object.defineProperty(fn, "name", { value: value2 });
|
|
29443
29443
|
} catch (e2) {
|
|
29444
29444
|
}
|
|
29445
|
-
Object.defineProperty(fn, "adapterName", { value });
|
|
29445
|
+
Object.defineProperty(fn, "adapterName", { value: value2 });
|
|
29446
29446
|
}
|
|
29447
29447
|
});
|
|
29448
29448
|
var renderReason = (reason) => `- ${reason}`;
|
|
@@ -29523,7 +29523,7 @@ var require_axios = __commonJS((exports2, module2) => {
|
|
|
29523
29523
|
function formatMessage(opt, desc) {
|
|
29524
29524
|
return "[Axios v" + VERSION3 + "] Transitional option '" + opt + "'" + desc + (message2 ? ". " + message2 : "");
|
|
29525
29525
|
}
|
|
29526
|
-
return (
|
|
29526
|
+
return (value2, opt, opts) => {
|
|
29527
29527
|
if (validator2 === false) {
|
|
29528
29528
|
throw new AxiosError(formatMessage(opt, " has been removed" + (version ? " in " + version : "")), AxiosError.ERR_DEPRECATED);
|
|
29529
29529
|
}
|
|
@@ -29531,11 +29531,11 @@ var require_axios = __commonJS((exports2, module2) => {
|
|
|
29531
29531
|
deprecatedWarnings[opt] = true;
|
|
29532
29532
|
console.warn(formatMessage(opt, " has been deprecated since v" + version + " and will be removed in the near future"));
|
|
29533
29533
|
}
|
|
29534
|
-
return validator2 ? validator2(
|
|
29534
|
+
return validator2 ? validator2(value2, opt, opts) : true;
|
|
29535
29535
|
};
|
|
29536
29536
|
};
|
|
29537
29537
|
validators$1.spelling = function spelling(correctSpelling) {
|
|
29538
|
-
return (
|
|
29538
|
+
return (value2, opt) => {
|
|
29539
29539
|
console.warn(`${opt} is likely a misspelling of ${correctSpelling}`);
|
|
29540
29540
|
return true;
|
|
29541
29541
|
};
|
|
@@ -29550,8 +29550,8 @@ var require_axios = __commonJS((exports2, module2) => {
|
|
|
29550
29550
|
const opt = keys[i2];
|
|
29551
29551
|
const validator2 = schema[opt];
|
|
29552
29552
|
if (validator2) {
|
|
29553
|
-
const
|
|
29554
|
-
const result =
|
|
29553
|
+
const value2 = options[opt];
|
|
29554
|
+
const result = value2 === undefined || validator2(value2, opt, options);
|
|
29555
29555
|
if (result !== true) {
|
|
29556
29556
|
throw new AxiosError("option " + opt + " must be " + result, AxiosError.ERR_BAD_OPTION_VALUE);
|
|
29557
29557
|
}
|
|
@@ -29884,8 +29884,8 @@ var require_axios = __commonJS((exports2, module2) => {
|
|
|
29884
29884
|
NotExtended: 510,
|
|
29885
29885
|
NetworkAuthenticationRequired: 511
|
|
29886
29886
|
};
|
|
29887
|
-
Object.entries(HttpStatusCode).forEach(([key,
|
|
29888
|
-
HttpStatusCode[
|
|
29887
|
+
Object.entries(HttpStatusCode).forEach(([key, value2]) => {
|
|
29888
|
+
HttpStatusCode[value2] = key;
|
|
29889
29889
|
});
|
|
29890
29890
|
var HttpStatusCode$1 = HttpStatusCode;
|
|
29891
29891
|
function createInstance(defaultConfig) {
|
|
@@ -30631,23 +30631,23 @@ var require_beautifier = __commonJS((exports2) => {
|
|
|
30631
30631
|
}
|
|
30632
30632
|
const newItem = {};
|
|
30633
30633
|
for (const key2 in data) {
|
|
30634
|
-
const
|
|
30635
|
-
const valueType = typeof
|
|
30634
|
+
const value2 = data[key2];
|
|
30635
|
+
const valueType = typeof value2;
|
|
30636
30636
|
let newKey = knownBeautification[key2] || key2;
|
|
30637
30637
|
if (Array.isArray(newKey)) {
|
|
30638
30638
|
newKey = newKey[0];
|
|
30639
30639
|
}
|
|
30640
|
-
if (!Array.isArray(
|
|
30641
|
-
if (valueType === "object" &&
|
|
30642
|
-
newItem[newKey] = this.beautify(
|
|
30640
|
+
if (!Array.isArray(value2)) {
|
|
30641
|
+
if (valueType === "object" && value2 !== null) {
|
|
30642
|
+
newItem[newKey] = this.beautify(value2, knownBeautification[key2]);
|
|
30643
30643
|
} else {
|
|
30644
|
-
newItem[newKey] = this.beautifyValueWithKey(newKey,
|
|
30644
|
+
newItem[newKey] = this.beautifyValueWithKey(newKey, value2);
|
|
30645
30645
|
}
|
|
30646
30646
|
continue;
|
|
30647
30647
|
}
|
|
30648
30648
|
const newArray = [];
|
|
30649
30649
|
if (Array.isArray(this.beautificationMap[newKey])) {
|
|
30650
|
-
for (const elementValue of
|
|
30650
|
+
for (const elementValue of value2) {
|
|
30651
30651
|
const mappedBeautification = this.beautificationMap[knownBeautification[key2]];
|
|
30652
30652
|
const childMapping = mappedBeautification[0];
|
|
30653
30653
|
if (typeof childMapping === "object" && childMapping !== null) {
|
|
@@ -30744,22 +30744,22 @@ var require_nanoid = __commonJS((exports2, module2) => {
|
|
|
30744
30744
|
// node_modules/binance/lib/util/browser-support.js
|
|
30745
30745
|
var require_browser_support = __commonJS((exports2) => {
|
|
30746
30746
|
var __awaiter = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) {
|
|
30747
|
-
function adopt(
|
|
30748
|
-
return
|
|
30749
|
-
resolve(
|
|
30747
|
+
function adopt(value2) {
|
|
30748
|
+
return value2 instanceof P ? value2 : new P(function(resolve) {
|
|
30749
|
+
resolve(value2);
|
|
30750
30750
|
});
|
|
30751
30751
|
}
|
|
30752
30752
|
return new (P || (P = Promise))(function(resolve, reject) {
|
|
30753
|
-
function fulfilled(
|
|
30753
|
+
function fulfilled(value2) {
|
|
30754
30754
|
try {
|
|
30755
|
-
step(generator.next(
|
|
30755
|
+
step(generator.next(value2));
|
|
30756
30756
|
} catch (e2) {
|
|
30757
30757
|
reject(e2);
|
|
30758
30758
|
}
|
|
30759
30759
|
}
|
|
30760
|
-
function rejected(
|
|
30760
|
+
function rejected(value2) {
|
|
30761
30761
|
try {
|
|
30762
|
-
step(generator["throw"](
|
|
30762
|
+
step(generator["throw"](value2));
|
|
30763
30763
|
} catch (e2) {
|
|
30764
30764
|
reject(e2);
|
|
30765
30765
|
}
|
|
@@ -30836,22 +30836,22 @@ var require_node_support = __commonJS((exports2) => {
|
|
|
30836
30836
|
return result;
|
|
30837
30837
|
};
|
|
30838
30838
|
var __awaiter = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) {
|
|
30839
|
-
function adopt(
|
|
30840
|
-
return
|
|
30841
|
-
resolve(
|
|
30839
|
+
function adopt(value2) {
|
|
30840
|
+
return value2 instanceof P ? value2 : new P(function(resolve) {
|
|
30841
|
+
resolve(value2);
|
|
30842
30842
|
});
|
|
30843
30843
|
}
|
|
30844
30844
|
return new (P || (P = Promise))(function(resolve, reject) {
|
|
30845
|
-
function fulfilled(
|
|
30845
|
+
function fulfilled(value2) {
|
|
30846
30846
|
try {
|
|
30847
|
-
step(generator.next(
|
|
30847
|
+
step(generator.next(value2));
|
|
30848
30848
|
} catch (e2) {
|
|
30849
30849
|
reject(e2);
|
|
30850
30850
|
}
|
|
30851
30851
|
}
|
|
30852
|
-
function rejected(
|
|
30852
|
+
function rejected(value2) {
|
|
30853
30853
|
try {
|
|
30854
|
-
step(generator["throw"](
|
|
30854
|
+
step(generator["throw"](value2));
|
|
30855
30855
|
} catch (e2) {
|
|
30856
30856
|
reject(e2);
|
|
30857
30857
|
}
|
|
@@ -30883,22 +30883,22 @@ var require_node_support = __commonJS((exports2) => {
|
|
|
30883
30883
|
// node_modules/binance/lib/util/requestUtils.js
|
|
30884
30884
|
var require_requestUtils = __commonJS((exports2) => {
|
|
30885
30885
|
var __awaiter = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) {
|
|
30886
|
-
function adopt(
|
|
30887
|
-
return
|
|
30888
|
-
resolve(
|
|
30886
|
+
function adopt(value2) {
|
|
30887
|
+
return value2 instanceof P ? value2 : new P(function(resolve) {
|
|
30888
|
+
resolve(value2);
|
|
30889
30889
|
});
|
|
30890
30890
|
}
|
|
30891
30891
|
return new (P || (P = Promise))(function(resolve, reject) {
|
|
30892
|
-
function fulfilled(
|
|
30892
|
+
function fulfilled(value2) {
|
|
30893
30893
|
try {
|
|
30894
|
-
step(generator.next(
|
|
30894
|
+
step(generator.next(value2));
|
|
30895
30895
|
} catch (e2) {
|
|
30896
30896
|
reject(e2);
|
|
30897
30897
|
}
|
|
30898
30898
|
}
|
|
30899
|
-
function rejected(
|
|
30899
|
+
function rejected(value2) {
|
|
30900
30900
|
try {
|
|
30901
|
-
step(generator["throw"](
|
|
30901
|
+
step(generator["throw"](value2));
|
|
30902
30902
|
} catch (e2) {
|
|
30903
30903
|
reject(e2);
|
|
30904
30904
|
}
|
|
@@ -30944,11 +30944,11 @@ var require_requestUtils = __commonJS((exports2) => {
|
|
|
30944
30944
|
function serialiseParams(params = {}, strict_validation = false, encodeValues = false, filterUndefinedParams = false) {
|
|
30945
30945
|
const paramKeys = !filterUndefinedParams ? Object.keys(params) : Object.keys(params).filter((key) => typeof params[key] !== "undefined");
|
|
30946
30946
|
return paramKeys.map((key) => {
|
|
30947
|
-
const
|
|
30948
|
-
if (strict_validation === true && typeof
|
|
30947
|
+
const value2 = params[key];
|
|
30948
|
+
if (strict_validation === true && typeof value2 === "undefined") {
|
|
30949
30949
|
throw new Error("Failed to sign API request due to undefined parameter");
|
|
30950
30950
|
}
|
|
30951
|
-
const encodedValue = encodeValues ? encodeURIComponent(
|
|
30951
|
+
const encodedValue = encodeValues ? encodeURIComponent(value2) : value2;
|
|
30952
30952
|
return `${key}=${encodedValue}`;
|
|
30953
30953
|
}).join("&");
|
|
30954
30954
|
}
|
|
@@ -31087,22 +31087,22 @@ var require_requestUtils = __commonJS((exports2) => {
|
|
|
31087
31087
|
// node_modules/binance/lib/util/BaseRestClient.js
|
|
31088
31088
|
var require_BaseRestClient = __commonJS((exports2) => {
|
|
31089
31089
|
var __awaiter = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) {
|
|
31090
|
-
function adopt(
|
|
31091
|
-
return
|
|
31092
|
-
resolve(
|
|
31090
|
+
function adopt(value2) {
|
|
31091
|
+
return value2 instanceof P ? value2 : new P(function(resolve) {
|
|
31092
|
+
resolve(value2);
|
|
31093
31093
|
});
|
|
31094
31094
|
}
|
|
31095
31095
|
return new (P || (P = Promise))(function(resolve, reject) {
|
|
31096
|
-
function fulfilled(
|
|
31096
|
+
function fulfilled(value2) {
|
|
31097
31097
|
try {
|
|
31098
|
-
step(generator.next(
|
|
31098
|
+
step(generator.next(value2));
|
|
31099
31099
|
} catch (e2) {
|
|
31100
31100
|
reject(e2);
|
|
31101
31101
|
}
|
|
31102
31102
|
}
|
|
31103
|
-
function rejected(
|
|
31103
|
+
function rejected(value2) {
|
|
31104
31104
|
try {
|
|
31105
|
-
step(generator["throw"](
|
|
31105
|
+
step(generator["throw"](value2));
|
|
31106
31106
|
} catch (e2) {
|
|
31107
31107
|
reject(e2);
|
|
31108
31108
|
}
|
|
@@ -31174,8 +31174,8 @@ var require_BaseRestClient = __commonJS((exports2) => {
|
|
|
31174
31174
|
getTimeOffset() {
|
|
31175
31175
|
return this.timeOffset;
|
|
31176
31176
|
}
|
|
31177
|
-
setTimeOffset(
|
|
31178
|
-
this.timeOffset =
|
|
31177
|
+
setTimeOffset(value2) {
|
|
31178
|
+
this.timeOffset = value2;
|
|
31179
31179
|
}
|
|
31180
31180
|
get(endpoint, params) {
|
|
31181
31181
|
return this._call("GET", endpoint, params);
|
|
@@ -31269,18 +31269,18 @@ var require_BaseRestClient = __commonJS((exports2) => {
|
|
|
31269
31269
|
const delta = {};
|
|
31270
31270
|
for (const headerKey in this.apiLimitTrackers) {
|
|
31271
31271
|
const headerValue = responseHeaders[headerKey];
|
|
31272
|
-
const
|
|
31273
|
-
if (headerValue !== undefined && !isNaN(
|
|
31274
|
-
this.apiLimitTrackers[headerKey] =
|
|
31272
|
+
const value2 = parseInt(headerValue);
|
|
31273
|
+
if (headerValue !== undefined && !isNaN(value2)) {
|
|
31274
|
+
this.apiLimitTrackers[headerKey] = value2;
|
|
31275
31275
|
delta[headerKey] = {
|
|
31276
31276
|
updated: true,
|
|
31277
|
-
valueParsed:
|
|
31277
|
+
valueParsed: value2,
|
|
31278
31278
|
valueRaw: headerValue
|
|
31279
31279
|
};
|
|
31280
31280
|
} else {
|
|
31281
31281
|
delta[headerKey] = {
|
|
31282
31282
|
updated: false,
|
|
31283
|
-
valueParsed:
|
|
31283
|
+
valueParsed: value2,
|
|
31284
31284
|
valueRaw: headerValue
|
|
31285
31285
|
};
|
|
31286
31286
|
}
|
|
@@ -31321,22 +31321,22 @@ var require_BaseRestClient = __commonJS((exports2) => {
|
|
|
31321
31321
|
// node_modules/binance/lib/coinm-client.js
|
|
31322
31322
|
var require_coinm_client = __commonJS((exports2) => {
|
|
31323
31323
|
var __awaiter = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) {
|
|
31324
|
-
function adopt(
|
|
31325
|
-
return
|
|
31326
|
-
resolve(
|
|
31324
|
+
function adopt(value2) {
|
|
31325
|
+
return value2 instanceof P ? value2 : new P(function(resolve) {
|
|
31326
|
+
resolve(value2);
|
|
31327
31327
|
});
|
|
31328
31328
|
}
|
|
31329
31329
|
return new (P || (P = Promise))(function(resolve, reject) {
|
|
31330
|
-
function fulfilled(
|
|
31330
|
+
function fulfilled(value2) {
|
|
31331
31331
|
try {
|
|
31332
|
-
step(generator.next(
|
|
31332
|
+
step(generator.next(value2));
|
|
31333
31333
|
} catch (e2) {
|
|
31334
31334
|
reject(e2);
|
|
31335
31335
|
}
|
|
31336
31336
|
}
|
|
31337
|
-
function rejected(
|
|
31337
|
+
function rejected(value2) {
|
|
31338
31338
|
try {
|
|
31339
|
-
step(generator["throw"](
|
|
31339
|
+
step(generator["throw"](value2));
|
|
31340
31340
|
} catch (e2) {
|
|
31341
31341
|
reject(e2);
|
|
31342
31342
|
}
|
|
@@ -31688,22 +31688,22 @@ var require_logger = __commonJS((exports2) => {
|
|
|
31688
31688
|
// node_modules/binance/lib/main-client.js
|
|
31689
31689
|
var require_main_client = __commonJS((exports2) => {
|
|
31690
31690
|
var __awaiter = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) {
|
|
31691
|
-
function adopt(
|
|
31692
|
-
return
|
|
31693
|
-
resolve(
|
|
31691
|
+
function adopt(value2) {
|
|
31692
|
+
return value2 instanceof P ? value2 : new P(function(resolve) {
|
|
31693
|
+
resolve(value2);
|
|
31694
31694
|
});
|
|
31695
31695
|
}
|
|
31696
31696
|
return new (P || (P = Promise))(function(resolve, reject) {
|
|
31697
|
-
function fulfilled(
|
|
31697
|
+
function fulfilled(value2) {
|
|
31698
31698
|
try {
|
|
31699
|
-
step(generator.next(
|
|
31699
|
+
step(generator.next(value2));
|
|
31700
31700
|
} catch (e2) {
|
|
31701
31701
|
reject(e2);
|
|
31702
31702
|
}
|
|
31703
31703
|
}
|
|
31704
|
-
function rejected(
|
|
31704
|
+
function rejected(value2) {
|
|
31705
31705
|
try {
|
|
31706
|
-
step(generator["throw"](
|
|
31706
|
+
step(generator["throw"](value2));
|
|
31707
31707
|
} catch (e2) {
|
|
31708
31708
|
reject(e2);
|
|
31709
31709
|
}
|
|
@@ -33234,22 +33234,22 @@ var require_main_client = __commonJS((exports2) => {
|
|
|
33234
33234
|
// node_modules/binance/lib/portfolio-client.js
|
|
33235
33235
|
var require_portfolio_client = __commonJS((exports2) => {
|
|
33236
33236
|
var __awaiter = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) {
|
|
33237
|
-
function adopt(
|
|
33238
|
-
return
|
|
33239
|
-
resolve(
|
|
33237
|
+
function adopt(value2) {
|
|
33238
|
+
return value2 instanceof P ? value2 : new P(function(resolve) {
|
|
33239
|
+
resolve(value2);
|
|
33240
33240
|
});
|
|
33241
33241
|
}
|
|
33242
33242
|
return new (P || (P = Promise))(function(resolve, reject) {
|
|
33243
|
-
function fulfilled(
|
|
33243
|
+
function fulfilled(value2) {
|
|
33244
33244
|
try {
|
|
33245
|
-
step(generator.next(
|
|
33245
|
+
step(generator.next(value2));
|
|
33246
33246
|
} catch (e2) {
|
|
33247
33247
|
reject(e2);
|
|
33248
33248
|
}
|
|
33249
33249
|
}
|
|
33250
|
-
function rejected(
|
|
33250
|
+
function rejected(value2) {
|
|
33251
33251
|
try {
|
|
33252
|
-
step(generator["throw"](
|
|
33252
|
+
step(generator["throw"](value2));
|
|
33253
33253
|
} catch (e2) {
|
|
33254
33254
|
reject(e2);
|
|
33255
33255
|
}
|
|
@@ -33708,22 +33708,22 @@ var require_websockets = __commonJS((exports2) => {
|
|
|
33708
33708
|
// node_modules/binance/lib/usdm-client.js
|
|
33709
33709
|
var require_usdm_client = __commonJS((exports2) => {
|
|
33710
33710
|
var __awaiter = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) {
|
|
33711
|
-
function adopt(
|
|
33712
|
-
return
|
|
33713
|
-
resolve(
|
|
33711
|
+
function adopt(value2) {
|
|
33712
|
+
return value2 instanceof P ? value2 : new P(function(resolve) {
|
|
33713
|
+
resolve(value2);
|
|
33714
33714
|
});
|
|
33715
33715
|
}
|
|
33716
33716
|
return new (P || (P = Promise))(function(resolve, reject) {
|
|
33717
|
-
function fulfilled(
|
|
33717
|
+
function fulfilled(value2) {
|
|
33718
33718
|
try {
|
|
33719
|
-
step(generator.next(
|
|
33719
|
+
step(generator.next(value2));
|
|
33720
33720
|
} catch (e2) {
|
|
33721
33721
|
reject(e2);
|
|
33722
33722
|
}
|
|
33723
33723
|
}
|
|
33724
|
-
function rejected(
|
|
33724
|
+
function rejected(value2) {
|
|
33725
33725
|
try {
|
|
33726
|
-
step(generator["throw"](
|
|
33726
|
+
step(generator["throw"](value2));
|
|
33727
33727
|
} catch (e2) {
|
|
33728
33728
|
reject(e2);
|
|
33729
33729
|
}
|
|
@@ -34638,35 +34638,35 @@ var require_permessage_deflate = __commonJS((exports2, module2) => {
|
|
|
34638
34638
|
normalizeParams(configurations) {
|
|
34639
34639
|
configurations.forEach((params) => {
|
|
34640
34640
|
Object.keys(params).forEach((key) => {
|
|
34641
|
-
let
|
|
34642
|
-
if (
|
|
34641
|
+
let value2 = params[key];
|
|
34642
|
+
if (value2.length > 1) {
|
|
34643
34643
|
throw new Error(`Parameter "${key}" must have only a single value`);
|
|
34644
34644
|
}
|
|
34645
|
-
|
|
34645
|
+
value2 = value2[0];
|
|
34646
34646
|
if (key === "client_max_window_bits") {
|
|
34647
|
-
if (
|
|
34648
|
-
const num = +
|
|
34647
|
+
if (value2 !== true) {
|
|
34648
|
+
const num = +value2;
|
|
34649
34649
|
if (!Number.isInteger(num) || num < 8 || num > 15) {
|
|
34650
|
-
throw new TypeError(`Invalid value for parameter "${key}": ${
|
|
34650
|
+
throw new TypeError(`Invalid value for parameter "${key}": ${value2}`);
|
|
34651
34651
|
}
|
|
34652
|
-
|
|
34652
|
+
value2 = num;
|
|
34653
34653
|
} else if (!this._isServer) {
|
|
34654
|
-
throw new TypeError(`Invalid value for parameter "${key}": ${
|
|
34654
|
+
throw new TypeError(`Invalid value for parameter "${key}": ${value2}`);
|
|
34655
34655
|
}
|
|
34656
34656
|
} else if (key === "server_max_window_bits") {
|
|
34657
|
-
const num = +
|
|
34657
|
+
const num = +value2;
|
|
34658
34658
|
if (!Number.isInteger(num) || num < 8 || num > 15) {
|
|
34659
|
-
throw new TypeError(`Invalid value for parameter "${key}": ${
|
|
34659
|
+
throw new TypeError(`Invalid value for parameter "${key}": ${value2}`);
|
|
34660
34660
|
}
|
|
34661
|
-
|
|
34661
|
+
value2 = num;
|
|
34662
34662
|
} else if (key === "client_no_context_takeover" || key === "server_no_context_takeover") {
|
|
34663
|
-
if (
|
|
34664
|
-
throw new TypeError(`Invalid value for parameter "${key}": ${
|
|
34663
|
+
if (value2 !== true) {
|
|
34664
|
+
throw new TypeError(`Invalid value for parameter "${key}": ${value2}`);
|
|
34665
34665
|
}
|
|
34666
34666
|
} else {
|
|
34667
34667
|
throw new Error(`Unknown parameter "${key}"`);
|
|
34668
34668
|
}
|
|
34669
|
-
params[key] =
|
|
34669
|
+
params[key] = value2;
|
|
34670
34670
|
});
|
|
34671
34671
|
});
|
|
34672
34672
|
return configurations;
|
|
@@ -34949,8 +34949,8 @@ var require_validation = __commonJS((exports2, module2) => {
|
|
|
34949
34949
|
}
|
|
34950
34950
|
return true;
|
|
34951
34951
|
}
|
|
34952
|
-
function isBlob(
|
|
34953
|
-
return hasBlob && typeof
|
|
34952
|
+
function isBlob(value2) {
|
|
34953
|
+
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");
|
|
34954
34954
|
}
|
|
34955
34955
|
module2.exports = {
|
|
34956
34956
|
isBlob,
|
|
@@ -35968,12 +35968,12 @@ var require_extension = __commonJS((exports2, module2) => {
|
|
|
35968
35968
|
}
|
|
35969
35969
|
if (end === -1)
|
|
35970
35970
|
end = i2;
|
|
35971
|
-
let
|
|
35971
|
+
let value2 = header.slice(start, end);
|
|
35972
35972
|
if (mustUnescape) {
|
|
35973
|
-
|
|
35973
|
+
value2 = value2.replace(/\\/g, "");
|
|
35974
35974
|
mustUnescape = false;
|
|
35975
35975
|
}
|
|
35976
|
-
push(params, paramName,
|
|
35976
|
+
push(params, paramName, value2);
|
|
35977
35977
|
if (code === 44) {
|
|
35978
35978
|
push(offers, extensionName, params);
|
|
35979
35979
|
params = Object.create(null);
|
|
@@ -36496,8 +36496,8 @@ var require_websocket = __commonJS((exports2, module2) => {
|
|
|
36496
36496
|
const headers = options && options.headers;
|
|
36497
36497
|
options = { ...options, headers: {} };
|
|
36498
36498
|
if (headers) {
|
|
36499
|
-
for (const [key2,
|
|
36500
|
-
options.headers[key2.toLowerCase()] =
|
|
36499
|
+
for (const [key2, value2] of Object.entries(headers)) {
|
|
36500
|
+
options.headers[key2.toLowerCase()] = value2;
|
|
36501
36501
|
}
|
|
36502
36502
|
}
|
|
36503
36503
|
} else if (websocket.listenerCount("redirect") === 0) {
|
|
@@ -37159,10 +37159,10 @@ var require_websocket_server = __commonJS((exports2, module2) => {
|
|
|
37159
37159
|
}
|
|
37160
37160
|
if (extensions[PerMessageDeflate.extensionName]) {
|
|
37161
37161
|
const params = extensions[PerMessageDeflate.extensionName].params;
|
|
37162
|
-
const
|
|
37162
|
+
const value2 = extension.format({
|
|
37163
37163
|
[PerMessageDeflate.extensionName]: [params]
|
|
37164
37164
|
});
|
|
37165
|
-
headers.push(`Sec-WebSocket-Extensions: ${
|
|
37165
|
+
headers.push(`Sec-WebSocket-Extensions: ${value2}`);
|
|
37166
37166
|
ws._extensions = extensions;
|
|
37167
37167
|
}
|
|
37168
37168
|
this.emit("headers", headers, req);
|
|
@@ -37294,22 +37294,22 @@ var require_websocket_client = __commonJS((exports2) => {
|
|
|
37294
37294
|
return result;
|
|
37295
37295
|
};
|
|
37296
37296
|
var __awaiter = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) {
|
|
37297
|
-
function adopt(
|
|
37298
|
-
return
|
|
37299
|
-
resolve(
|
|
37297
|
+
function adopt(value2) {
|
|
37298
|
+
return value2 instanceof P ? value2 : new P(function(resolve) {
|
|
37299
|
+
resolve(value2);
|
|
37300
37300
|
});
|
|
37301
37301
|
}
|
|
37302
37302
|
return new (P || (P = Promise))(function(resolve, reject) {
|
|
37303
|
-
function fulfilled(
|
|
37303
|
+
function fulfilled(value2) {
|
|
37304
37304
|
try {
|
|
37305
|
-
step(generator.next(
|
|
37305
|
+
step(generator.next(value2));
|
|
37306
37306
|
} catch (e2) {
|
|
37307
37307
|
reject(e2);
|
|
37308
37308
|
}
|
|
37309
37309
|
}
|
|
37310
|
-
function rejected(
|
|
37310
|
+
function rejected(value2) {
|
|
37311
37311
|
try {
|
|
37312
|
-
step(generator["throw"](
|
|
37312
|
+
step(generator["throw"](value2));
|
|
37313
37313
|
} catch (e2) {
|
|
37314
37314
|
reject(e2);
|
|
37315
37315
|
}
|
|
@@ -37801,10 +37801,10 @@ var require_websocket_client = __commonJS((exports2) => {
|
|
|
37801
37801
|
});
|
|
37802
37802
|
this.tryWsSend(wsKey, wsMessage);
|
|
37803
37803
|
}
|
|
37804
|
-
requestSetProperty(wsKey, property,
|
|
37804
|
+
requestSetProperty(wsKey, property, value2, requestId) {
|
|
37805
37805
|
const wsMessage = JSON.stringify({
|
|
37806
37806
|
method: "SET_PROPERTY",
|
|
37807
|
-
params: [property,
|
|
37807
|
+
params: [property, value2],
|
|
37808
37808
|
id: requestId
|
|
37809
37809
|
});
|
|
37810
37810
|
this.tryWsSend(wsKey, wsMessage);
|
|
@@ -52074,11 +52074,264 @@ __export(exports_exchange_account, {
|
|
|
52074
52074
|
ExchangeAccount: () => ExchangeAccount
|
|
52075
52075
|
});
|
|
52076
52076
|
|
|
52077
|
-
// src/
|
|
52078
|
-
|
|
52077
|
+
// src/helpers/pnl.ts
|
|
52078
|
+
function determine_position_size(entry, stop, budget) {
|
|
52079
|
+
let stop_percent = Math.abs(entry - stop) / entry;
|
|
52080
|
+
let size = budget / stop_percent / entry;
|
|
52081
|
+
return size;
|
|
52082
|
+
}
|
|
52083
|
+
function determine_risk(entry, stop, quantity) {
|
|
52084
|
+
let stop_percent = Math.abs(entry - stop) / entry;
|
|
52085
|
+
let risk = quantity * stop_percent * entry;
|
|
52086
|
+
return risk;
|
|
52087
|
+
}
|
|
52088
|
+
function determine_close_price(entry, pnl, quantity, kind, single = false, leverage = 1) {
|
|
52089
|
+
const dollar_value = entry / leverage;
|
|
52090
|
+
const position = dollar_value * quantity;
|
|
52091
|
+
if (position) {
|
|
52092
|
+
let percent = pnl / position;
|
|
52093
|
+
let difference = position * percent / quantity;
|
|
52094
|
+
let result;
|
|
52095
|
+
if (kind === "long") {
|
|
52096
|
+
result = difference + entry;
|
|
52097
|
+
} else {
|
|
52098
|
+
result = entry - difference;
|
|
52099
|
+
}
|
|
52100
|
+
if (single) {
|
|
52101
|
+
return result;
|
|
52102
|
+
}
|
|
52103
|
+
return result;
|
|
52104
|
+
}
|
|
52105
|
+
return 0;
|
|
52106
|
+
}
|
|
52107
|
+
function determine_amount_to_sell(entry, quantity, sell_price, pnl, kind, places = "%.3f") {
|
|
52108
|
+
const _pnl = determine_pnl(entry, sell_price, quantity, kind);
|
|
52109
|
+
const ratio = pnl / to_f(Math.abs(_pnl), places);
|
|
52110
|
+
quantity = quantity * ratio;
|
|
52111
|
+
return to_f(quantity, places);
|
|
52112
|
+
}
|
|
52113
|
+
function determine_pnl(entry, close_price, quantity, kind, contract_size, places = "%.2f") {
|
|
52114
|
+
if (contract_size) {
|
|
52115
|
+
const direction = kind === "long" ? 1 : -1;
|
|
52116
|
+
return quantity * contract_size * direction * (1 / entry - 1 / close_price);
|
|
52117
|
+
}
|
|
52118
|
+
let difference = entry - close_price;
|
|
52119
|
+
if (kind === "long") {
|
|
52120
|
+
difference = close_price - entry;
|
|
52121
|
+
}
|
|
52122
|
+
return to_f(difference * quantity, places);
|
|
52123
|
+
}
|
|
52124
|
+
function position(entry, quantity, kind, leverage = 1) {
|
|
52125
|
+
const direction = { long: 1, short: -1 };
|
|
52126
|
+
return parseFloat((direction[kind] * quantity * (entry / leverage)).toFixed(3));
|
|
52127
|
+
}
|
|
52128
|
+
function to_f(value, places) {
|
|
52129
|
+
if (value) {
|
|
52130
|
+
let pp = parseInt(places.replace("%.", "").replace("f", ""));
|
|
52131
|
+
return parseFloat(value.toFixed(pp));
|
|
52132
|
+
}
|
|
52133
|
+
return value;
|
|
52134
|
+
}
|
|
52135
|
+
var value = {
|
|
52136
|
+
determine_risk,
|
|
52137
|
+
determine_position_size,
|
|
52138
|
+
determine_close_price,
|
|
52139
|
+
determine_pnl,
|
|
52140
|
+
position,
|
|
52141
|
+
determine_amount_to_sell,
|
|
52142
|
+
to_f
|
|
52143
|
+
};
|
|
52144
|
+
var pnl_default = value;
|
|
52145
|
+
|
|
52146
|
+
// src/helpers/trade_utils.ts
|
|
52147
|
+
function to_f2(value2, places = "%.1f") {
|
|
52148
|
+
let v = typeof value2 === "string" ? parseFloat(value2) : value2;
|
|
52149
|
+
const formattedValue = places.replace("%.", "").replace("f", "");
|
|
52150
|
+
return parseFloat(v.toFixed(parseInt(formattedValue)));
|
|
52151
|
+
}
|
|
52152
|
+
function determine_position_size2({
|
|
52153
|
+
entry,
|
|
52154
|
+
stop,
|
|
52155
|
+
budget,
|
|
52156
|
+
percent,
|
|
52157
|
+
min_size,
|
|
52158
|
+
notional_value,
|
|
52159
|
+
as_coin = true,
|
|
52160
|
+
places = "%.3f"
|
|
52161
|
+
}) {
|
|
52162
|
+
let stop_percent = stop ? Math.abs(entry - stop) / entry : percent;
|
|
52163
|
+
if (stop_percent && budget) {
|
|
52164
|
+
let size = budget / stop_percent;
|
|
52165
|
+
let notion_value = size * entry;
|
|
52166
|
+
if (notional_value && notional_value > notion_value) {
|
|
52167
|
+
size = notional_value / entry;
|
|
52168
|
+
}
|
|
52169
|
+
if (as_coin) {
|
|
52170
|
+
size = size / entry;
|
|
52171
|
+
if (min_size && min_size === 1) {
|
|
52172
|
+
return to_f2(Math.round(size), places);
|
|
52173
|
+
}
|
|
52174
|
+
}
|
|
52175
|
+
return to_f2(size, places);
|
|
52176
|
+
}
|
|
52177
|
+
return;
|
|
52178
|
+
}
|
|
52179
|
+
function determine_average_entry_and_size(orders, places = "%.3f", price_places = "%.1f") {
|
|
52180
|
+
const sum_values = orders.reduce((sum, order) => sum + order.price * order.quantity, 0);
|
|
52181
|
+
const total_quantity = orders.reduce((sum, order) => sum + order.quantity, 0);
|
|
52182
|
+
const avg_price = total_quantity ? to_f2(sum_values / total_quantity, price_places) : 0;
|
|
52183
|
+
return {
|
|
52184
|
+
entry: avg_price,
|
|
52185
|
+
price: avg_price,
|
|
52186
|
+
quantity: to_f2(total_quantity, places)
|
|
52187
|
+
};
|
|
52188
|
+
}
|
|
52189
|
+
var createArray = (start, stop, step) => {
|
|
52190
|
+
const result = [];
|
|
52191
|
+
let current = start;
|
|
52192
|
+
while (current <= stop) {
|
|
52193
|
+
result.push(current);
|
|
52194
|
+
current += step;
|
|
52195
|
+
}
|
|
52196
|
+
return result;
|
|
52197
|
+
};
|
|
52198
|
+
var groupIntoPairsWithSumLessThan = (arr, targetSum, key = "quantity", firstSize = 0) => {
|
|
52199
|
+
if (firstSize) {
|
|
52200
|
+
const totalSize = arr.reduce((sum, order) => sum + order[key], 0);
|
|
52201
|
+
const remainingSize = totalSize - firstSize;
|
|
52202
|
+
let newSum = 0;
|
|
52203
|
+
let newArray = [];
|
|
52204
|
+
let lastIndex = 0;
|
|
52205
|
+
for (let i2 = 0;i2 < arr.length; i2++) {
|
|
52206
|
+
if (newSum < remainingSize) {
|
|
52207
|
+
newSum += arr[i2][key];
|
|
52208
|
+
newArray.push(arr[i2]);
|
|
52209
|
+
lastIndex = i2;
|
|
52210
|
+
}
|
|
52211
|
+
}
|
|
52212
|
+
const lastGroup = arr.slice(lastIndex + 1);
|
|
52213
|
+
const previousPair = groupInPairs(newArray, key, targetSum);
|
|
52214
|
+
if (lastGroup.length > 0) {
|
|
52215
|
+
previousPair.push(lastGroup);
|
|
52216
|
+
}
|
|
52217
|
+
return previousPair;
|
|
52218
|
+
}
|
|
52219
|
+
return groupInPairs(arr, key, targetSum);
|
|
52220
|
+
};
|
|
52221
|
+
function groupInPairs(_arr, key, targetSum) {
|
|
52222
|
+
const result = [];
|
|
52223
|
+
let currentSum = 0;
|
|
52224
|
+
let currentGroup = [];
|
|
52225
|
+
for (let i2 = 0;i2 < _arr.length; i2++) {
|
|
52226
|
+
currentSum += _arr[i2][key];
|
|
52227
|
+
currentGroup.push(_arr[i2]);
|
|
52228
|
+
if (currentSum >= targetSum) {
|
|
52229
|
+
result.push(currentGroup);
|
|
52230
|
+
currentGroup = [];
|
|
52231
|
+
currentSum = 0;
|
|
52232
|
+
}
|
|
52233
|
+
}
|
|
52234
|
+
return result;
|
|
52235
|
+
}
|
|
52236
|
+
var computeTotalAverageForEachTrade = (trades, config2) => {
|
|
52237
|
+
let _take_profit = config2.take_profit;
|
|
52238
|
+
let kind = config2.kind;
|
|
52239
|
+
let entryToUse = kind === "short" ? Math.min(config2.entry, config2.stop) : Math.max(config2.entry, config2.stop);
|
|
52240
|
+
let _currentEntry = config2.currentEntry || entryToUse;
|
|
52241
|
+
let less = trades.filter((p) => kind === "long" ? p.entry <= _currentEntry : p.entry >= _currentEntry);
|
|
52242
|
+
let rrr = trades.map((r2, i2) => {
|
|
52243
|
+
let considered = [];
|
|
52244
|
+
if (kind === "long") {
|
|
52245
|
+
considered = trades.filter((p) => p.entry > _currentEntry);
|
|
52246
|
+
} else {
|
|
52247
|
+
considered = trades.filter((p) => p.entry < _currentEntry);
|
|
52248
|
+
}
|
|
52249
|
+
const x_pnl = 0;
|
|
52250
|
+
const remaining = less.filter((o) => {
|
|
52251
|
+
if (kind === "long") {
|
|
52252
|
+
return o.entry >= r2.entry;
|
|
52253
|
+
}
|
|
52254
|
+
return o.entry <= r2.entry;
|
|
52255
|
+
});
|
|
52256
|
+
if (remaining.length === 0) {
|
|
52257
|
+
return { ...r2, pnl: x_pnl };
|
|
52258
|
+
}
|
|
52259
|
+
const start = kind === "long" ? Math.max(...remaining.map((o) => o.entry)) : Math.min(...remaining.map((o) => o.entry));
|
|
52260
|
+
considered = considered.map((o) => ({ ...o, entry: start }));
|
|
52261
|
+
considered = considered.concat(remaining);
|
|
52262
|
+
let avg_entry = determine_average_entry_and_size([
|
|
52263
|
+
...considered.map((o) => ({
|
|
52264
|
+
price: o.entry,
|
|
52265
|
+
quantity: o.quantity
|
|
52266
|
+
})),
|
|
52267
|
+
{
|
|
52268
|
+
price: _currentEntry,
|
|
52269
|
+
quantity: config2.currentQty || 0
|
|
52270
|
+
}
|
|
52271
|
+
], config2.decimal_places, config2.price_places);
|
|
52272
|
+
let _pnl = r2.pnl;
|
|
52273
|
+
let sell_price = r2.sell_price;
|
|
52274
|
+
let entry_pnl = r2.pnl;
|
|
52275
|
+
if (_take_profit) {
|
|
52276
|
+
_pnl = pnl_default.determine_pnl(avg_entry.price, _take_profit, avg_entry.quantity, kind);
|
|
52277
|
+
sell_price = _take_profit;
|
|
52278
|
+
entry_pnl = pnl_default.determine_pnl(r2.entry, _take_profit, avg_entry.quantity, kind);
|
|
52279
|
+
}
|
|
52280
|
+
const loss = pnl_default.determine_pnl(avg_entry.price, r2.stop, avg_entry.quantity, kind);
|
|
52281
|
+
let new_stop = r2.new_stop;
|
|
52282
|
+
const entry_loss = pnl_default.determine_pnl(r2.entry, new_stop, avg_entry.quantity, kind);
|
|
52283
|
+
let min_profit = 0;
|
|
52284
|
+
let min_entry_profit = 0;
|
|
52285
|
+
if (config2.min_profit) {
|
|
52286
|
+
min_profit = pnl_default.determine_close_price(avg_entry.price, config2.min_profit, avg_entry.quantity, kind);
|
|
52287
|
+
min_entry_profit = pnl_default.determine_close_price(r2.entry, config2.min_profit, avg_entry.quantity, kind);
|
|
52288
|
+
}
|
|
52289
|
+
let x_fee = r2.fee;
|
|
52290
|
+
if (config2.fee) {
|
|
52291
|
+
x_fee = config2.fee * r2.stop * avg_entry.quantity;
|
|
52292
|
+
}
|
|
52293
|
+
let tp_close = pnl_default.determine_close_price(r2.entry, Math.abs(entry_loss) * (config2.rr || 1) + x_fee, avg_entry.quantity, kind);
|
|
52294
|
+
return {
|
|
52295
|
+
...r2,
|
|
52296
|
+
x_fee: to_f2(x_fee, "%.2f"),
|
|
52297
|
+
avg_entry: avg_entry.price,
|
|
52298
|
+
avg_size: avg_entry.quantity,
|
|
52299
|
+
entry_pnl: to_f2(entry_pnl, "%.2f"),
|
|
52300
|
+
entry_loss: to_f2(entry_loss, "%.2f"),
|
|
52301
|
+
min_entry_pnl: to_f2(min_entry_profit, "%.2f"),
|
|
52302
|
+
pnl: _pnl,
|
|
52303
|
+
neg_pnl: to_f2(loss, "%.2f"),
|
|
52304
|
+
sell_price,
|
|
52305
|
+
close_p: to_f2(tp_close, "%.2f"),
|
|
52306
|
+
min_pnl: to_f2(min_profit, "%.2f"),
|
|
52307
|
+
new_stop
|
|
52308
|
+
};
|
|
52309
|
+
});
|
|
52310
|
+
return rrr;
|
|
52311
|
+
};
|
|
52312
|
+
function createGapPairs(arr, gap, item) {
|
|
52313
|
+
if (arr.length === 0) {
|
|
52314
|
+
return [];
|
|
52315
|
+
}
|
|
52316
|
+
const result = [];
|
|
52317
|
+
const firstElement = arr[0];
|
|
52318
|
+
for (let i2 = arr.length - 1;i2 >= 0; i2--) {
|
|
52319
|
+
const current = arr[i2];
|
|
52320
|
+
const gapIndex = i2 - gap;
|
|
52321
|
+
const pairedElement = gapIndex < 0 ? firstElement : arr[gapIndex];
|
|
52322
|
+
if (current !== pairedElement) {
|
|
52323
|
+
result.push([current, pairedElement]);
|
|
52324
|
+
}
|
|
52325
|
+
}
|
|
52326
|
+
if (item) {
|
|
52327
|
+
let r2 = result.find((o) => o[0] === item);
|
|
52328
|
+
return r2 ? [r2] : [];
|
|
52329
|
+
}
|
|
52330
|
+
return result;
|
|
52331
|
+
}
|
|
52079
52332
|
|
|
52080
52333
|
// src/helpers/trade_signal.ts
|
|
52081
|
-
function
|
|
52334
|
+
function determine_close_price2({
|
|
52082
52335
|
entry,
|
|
52083
52336
|
pnl,
|
|
52084
52337
|
quantity,
|
|
@@ -52086,16 +52339,16 @@ function determine_close_price({
|
|
|
52086
52339
|
kind = "long"
|
|
52087
52340
|
}) {
|
|
52088
52341
|
const dollar_value = entry / leverage;
|
|
52089
|
-
const
|
|
52090
|
-
if (
|
|
52091
|
-
const percent = pnl /
|
|
52092
|
-
const difference =
|
|
52342
|
+
const position2 = dollar_value * quantity;
|
|
52343
|
+
if (position2) {
|
|
52344
|
+
const percent = pnl / position2;
|
|
52345
|
+
const difference = position2 * percent / quantity;
|
|
52093
52346
|
const result = kind === "long" ? difference + entry : entry - difference;
|
|
52094
52347
|
return result;
|
|
52095
52348
|
}
|
|
52096
52349
|
return 0;
|
|
52097
52350
|
}
|
|
52098
|
-
function
|
|
52351
|
+
function determine_pnl2(entry, close_price, quantity, kind = "long", contract_size) {
|
|
52099
52352
|
if (contract_size) {
|
|
52100
52353
|
const direction = kind === "long" ? 1 : -1;
|
|
52101
52354
|
return quantity * contract_size * direction * (1 / entry - 1 / close_price);
|
|
@@ -52114,7 +52367,7 @@ function* _get_zones({
|
|
|
52114
52367
|
let focus_low = last * Math.pow(1 + percent_change, -1);
|
|
52115
52368
|
if (focus_high > current_price) {
|
|
52116
52369
|
while (focus_high > current_price) {
|
|
52117
|
-
yield
|
|
52370
|
+
yield to_f2(last, places);
|
|
52118
52371
|
focus_high = last;
|
|
52119
52372
|
last = focus_high * Math.pow(1 + percent_change, -1);
|
|
52120
52373
|
focus_low = last * Math.pow(1 + percent_change, -1);
|
|
@@ -52122,14 +52375,14 @@ function* _get_zones({
|
|
|
52122
52375
|
} else {
|
|
52123
52376
|
if (focus_high <= current_price) {
|
|
52124
52377
|
while (focus_high <= current_price) {
|
|
52125
|
-
yield
|
|
52378
|
+
yield to_f2(focus_high, places);
|
|
52126
52379
|
focus_low = focus_high;
|
|
52127
52380
|
last = focus_low * (1 + percent_change);
|
|
52128
52381
|
focus_high = last * (1 + percent_change);
|
|
52129
52382
|
}
|
|
52130
52383
|
} else {
|
|
52131
52384
|
while (focus_low <= current_price) {
|
|
52132
|
-
yield
|
|
52385
|
+
yield to_f2(focus_high, places);
|
|
52133
52386
|
focus_low = focus_high;
|
|
52134
52387
|
last = focus_low * (1 + percent_change);
|
|
52135
52388
|
focus_high = last * (1 + percent_change);
|
|
@@ -52393,7 +52646,7 @@ class Signal {
|
|
|
52393
52646
|
} else {
|
|
52394
52647
|
i2["risk_sell"] = Math.min(...potentials.slice(0, max_index));
|
|
52395
52648
|
}
|
|
52396
|
-
i2["pnl"] = this.to_df(
|
|
52649
|
+
i2["pnl"] = this.to_df(determine_pnl2(i2["entry"], i2["risk_sell"], i2["quantity"], kind));
|
|
52397
52650
|
}
|
|
52398
52651
|
}
|
|
52399
52652
|
}
|
|
@@ -52457,13 +52710,13 @@ class Signal {
|
|
|
52457
52710
|
let remaining_zones = margin_zones.filter((x) => JSON.stringify(x) != JSON.stringify(margin_range));
|
|
52458
52711
|
if (margin_range) {
|
|
52459
52712
|
const difference = Math.abs(margin_range[0] - margin_range[1]);
|
|
52460
|
-
const spread =
|
|
52713
|
+
const spread = to_f2(difference / this.risk_reward, this.price_places);
|
|
52461
52714
|
let entries;
|
|
52462
52715
|
const percent_change = this.percent_change / this.risk_reward;
|
|
52463
52716
|
if (kind === "long") {
|
|
52464
|
-
entries = Array.from({ length: Math.floor(this.risk_reward) + 1 }, (_, x) =>
|
|
52717
|
+
entries = Array.from({ length: Math.floor(this.risk_reward) + 1 }, (_, x) => to_f2(margin_range[1] - spread * x, this.price_places));
|
|
52465
52718
|
} else {
|
|
52466
|
-
entries = Array.from({ length: Math.floor(this.risk_reward) + 1 }, (_, x) =>
|
|
52719
|
+
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));
|
|
52467
52720
|
}
|
|
52468
52721
|
if (Math.min(...entries) < this.to_f(current_price) && this.to_f(current_price) < Math.max(...entries)) {
|
|
52469
52722
|
return entries.sort((a, b) => a - b);
|
|
@@ -52475,14 +52728,14 @@ class Signal {
|
|
|
52475
52728
|
if (new_range) {
|
|
52476
52729
|
while (entries2.length < this.risk_reward + 1) {
|
|
52477
52730
|
if (kind === "long") {
|
|
52478
|
-
let
|
|
52479
|
-
if (
|
|
52480
|
-
entries2.push(
|
|
52731
|
+
let value2 = this.to_f(new_range[1] - spread * x);
|
|
52732
|
+
if (value2 <= current_price) {
|
|
52733
|
+
entries2.push(value2);
|
|
52481
52734
|
}
|
|
52482
52735
|
} else {
|
|
52483
|
-
let
|
|
52484
|
-
if (
|
|
52485
|
-
entries2.push(
|
|
52736
|
+
let value2 = this.to_f(new_range[1] * Math.pow(1 + percent_change, x));
|
|
52737
|
+
if (value2 >= current_price) {
|
|
52738
|
+
entries2.push(value2);
|
|
52486
52739
|
}
|
|
52487
52740
|
}
|
|
52488
52741
|
x += 1;
|
|
@@ -52496,14 +52749,14 @@ class Signal {
|
|
|
52496
52749
|
let x = 0;
|
|
52497
52750
|
while (entries2.length < this.risk_reward + 1) {
|
|
52498
52751
|
if (kind === "long") {
|
|
52499
|
-
let
|
|
52500
|
-
if (
|
|
52501
|
-
entries2.push(
|
|
52752
|
+
let value2 = this.to_f(next_focus - spread * x);
|
|
52753
|
+
if (value2 <= this.to_f(current_price)) {
|
|
52754
|
+
entries2.push(value2);
|
|
52502
52755
|
}
|
|
52503
52756
|
} else {
|
|
52504
|
-
let
|
|
52505
|
-
if (
|
|
52506
|
-
entries2.push(
|
|
52757
|
+
let value2 = this.to_f(next_focus * Math.pow(1 + percent_change, x));
|
|
52758
|
+
if (value2 >= this.to_f(current_price)) {
|
|
52759
|
+
entries2.push(value2);
|
|
52507
52760
|
}
|
|
52508
52761
|
}
|
|
52509
52762
|
x += 1;
|
|
@@ -52514,8 +52767,8 @@ class Signal {
|
|
|
52514
52767
|
}
|
|
52515
52768
|
return [];
|
|
52516
52769
|
}
|
|
52517
|
-
to_f(
|
|
52518
|
-
return
|
|
52770
|
+
to_f(value2, places) {
|
|
52771
|
+
return to_f2(value2, places || this.price_places);
|
|
52519
52772
|
}
|
|
52520
52773
|
get_margin_zones({
|
|
52521
52774
|
current_price,
|
|
@@ -52717,7 +52970,7 @@ class Signal {
|
|
|
52717
52970
|
}) {
|
|
52718
52971
|
const considered = arr.map((x, i2) => i2).filter((i2) => i2 > index);
|
|
52719
52972
|
const with_quantity = considered.map((x) => {
|
|
52720
|
-
const q =
|
|
52973
|
+
const q = determine_position_size2({
|
|
52721
52974
|
entry: arr[x],
|
|
52722
52975
|
stop: arr[x - 1],
|
|
52723
52976
|
budget: risk,
|
|
@@ -52751,7 +53004,7 @@ class Signal {
|
|
|
52751
53004
|
const incurred_fees = fees.reduce((a, b) => a + b, 0) + previous_risks.reduce((a, b) => a + b, 0);
|
|
52752
53005
|
if (index === 0) {
|
|
52753
53006
|
}
|
|
52754
|
-
let quantity =
|
|
53007
|
+
let quantity = determine_position_size2({
|
|
52755
53008
|
entry,
|
|
52756
53009
|
stop,
|
|
52757
53010
|
budget: risk,
|
|
@@ -52763,7 +53016,7 @@ class Signal {
|
|
|
52763
53016
|
}
|
|
52764
53017
|
if (this.increase_size) {
|
|
52765
53018
|
quantity = quantity * multiplier;
|
|
52766
|
-
const new_risk =
|
|
53019
|
+
const new_risk = determine_pnl2(entry, stop, quantity, kind);
|
|
52767
53020
|
risk = Math.abs(new_risk);
|
|
52768
53021
|
}
|
|
52769
53022
|
const fee = this.to_df(this.fee * quantity * entry);
|
|
@@ -52772,12 +53025,12 @@ class Signal {
|
|
|
52772
53025
|
if (this.minimum_pnl) {
|
|
52773
53026
|
pnl = this.minimum_pnl + fee;
|
|
52774
53027
|
}
|
|
52775
|
-
let sell_price =
|
|
53028
|
+
let sell_price = determine_close_price2({ entry, pnl, quantity, kind });
|
|
52776
53029
|
if (take_profit && !this.minimum_pnl) {
|
|
52777
53030
|
sell_price = take_profit;
|
|
52778
|
-
pnl = this.to_df(
|
|
53031
|
+
pnl = this.to_df(determine_pnl2(entry, sell_price, quantity, kind));
|
|
52779
53032
|
pnl = pnl + fee;
|
|
52780
|
-
sell_price =
|
|
53033
|
+
sell_price = determine_close_price2({ entry, pnl, quantity, kind });
|
|
52781
53034
|
}
|
|
52782
53035
|
let risk_sell = sell_price;
|
|
52783
53036
|
return {
|
|
@@ -52795,284 +53048,790 @@ class Signal {
|
|
|
52795
53048
|
};
|
|
52796
53049
|
}
|
|
52797
53050
|
to_df(currentPrice, places = "%.3f") {
|
|
52798
|
-
return
|
|
53051
|
+
return to_f2(currentPrice, places);
|
|
52799
53052
|
}
|
|
52800
53053
|
}
|
|
52801
53054
|
|
|
52802
|
-
// src/helpers/
|
|
52803
|
-
function
|
|
52804
|
-
|
|
52805
|
-
|
|
52806
|
-
|
|
52807
|
-
|
|
52808
|
-
|
|
52809
|
-
|
|
52810
|
-
|
|
52811
|
-
|
|
52812
|
-
|
|
52813
|
-
|
|
52814
|
-
|
|
52815
|
-
|
|
52816
|
-
|
|
52817
|
-
|
|
52818
|
-
|
|
52819
|
-
|
|
52820
|
-
|
|
52821
|
-
|
|
52822
|
-
|
|
52823
|
-
|
|
52824
|
-
|
|
52825
|
-
|
|
52826
|
-
|
|
52827
|
-
|
|
52828
|
-
|
|
52829
|
-
|
|
52830
|
-
|
|
52831
|
-
|
|
52832
|
-
|
|
52833
|
-
|
|
52834
|
-
|
|
52835
|
-
|
|
52836
|
-
|
|
52837
|
-
|
|
52838
|
-
|
|
52839
|
-
|
|
52840
|
-
|
|
52841
|
-
|
|
53055
|
+
// src/helpers/shared.ts
|
|
53056
|
+
function buildConfig(app_config, {
|
|
53057
|
+
take_profit,
|
|
53058
|
+
entry,
|
|
53059
|
+
stop,
|
|
53060
|
+
raw_instance,
|
|
53061
|
+
risk,
|
|
53062
|
+
no_of_trades,
|
|
53063
|
+
min_profit = 0,
|
|
53064
|
+
risk_reward,
|
|
53065
|
+
kind,
|
|
53066
|
+
increase,
|
|
53067
|
+
gap,
|
|
53068
|
+
rr = 1,
|
|
53069
|
+
price_places = "%.1f",
|
|
53070
|
+
decimal_places = "%.3f"
|
|
53071
|
+
}) {
|
|
53072
|
+
let fee = app_config.fee / 100;
|
|
53073
|
+
let working_risk = risk || app_config.risk_per_trade;
|
|
53074
|
+
let trade_no = no_of_trades || app_config.risk_reward;
|
|
53075
|
+
const config2 = {
|
|
53076
|
+
focus: app_config.focus,
|
|
53077
|
+
fee,
|
|
53078
|
+
budget: app_config.budget,
|
|
53079
|
+
risk_reward: risk_reward || trade_no,
|
|
53080
|
+
support: app_config.support,
|
|
53081
|
+
resistance: app_config.resistance,
|
|
53082
|
+
price_places: app_config.price_places || price_places,
|
|
53083
|
+
decimal_places,
|
|
53084
|
+
percent_change: app_config.percent_change / app_config.tradeSplit,
|
|
53085
|
+
risk_per_trade: working_risk,
|
|
53086
|
+
take_profit: take_profit || app_config.take_profit,
|
|
53087
|
+
increase_position: increase,
|
|
53088
|
+
minimum_size: app_config.min_size,
|
|
53089
|
+
entry,
|
|
53090
|
+
stop,
|
|
53091
|
+
kind: app_config.kind,
|
|
53092
|
+
gap,
|
|
53093
|
+
min_profit: min_profit || app_config.min_profit,
|
|
53094
|
+
rr: rr || 1
|
|
53095
|
+
};
|
|
53096
|
+
const instance = new Signal(config2);
|
|
53097
|
+
if (raw_instance) {
|
|
53098
|
+
return instance;
|
|
52842
53099
|
}
|
|
52843
|
-
|
|
52844
|
-
|
|
52845
|
-
difference = close_price - entry;
|
|
53100
|
+
if (!stop) {
|
|
53101
|
+
return [];
|
|
52846
53102
|
}
|
|
52847
|
-
|
|
52848
|
-
|
|
52849
|
-
|
|
52850
|
-
const direction = { long: 1, short: -1 };
|
|
52851
|
-
return parseFloat((direction[kind] * quantity * (entry / leverage)).toFixed(3));
|
|
52852
|
-
}
|
|
52853
|
-
function to_f2(value, places) {
|
|
52854
|
-
if (value) {
|
|
52855
|
-
let pp = parseInt(places.replace("%.", "").replace("f", ""));
|
|
52856
|
-
return parseFloat(value.toFixed(pp));
|
|
53103
|
+
const condition = (kind === "long" ? entry > app_config.support : entry >= app_config.support) && stop >= app_config.support * 0.999;
|
|
53104
|
+
if (kind === "short") {
|
|
53105
|
+
console.log("condition", condition, entry === stop);
|
|
52857
53106
|
}
|
|
52858
|
-
|
|
52859
|
-
|
|
52860
|
-
|
|
52861
|
-
|
|
52862
|
-
|
|
52863
|
-
|
|
52864
|
-
|
|
52865
|
-
|
|
52866
|
-
|
|
52867
|
-
to_f: to_f2
|
|
52868
|
-
};
|
|
52869
|
-
var pnl_default = value;
|
|
52870
|
-
|
|
52871
|
-
// src/helpers/trade_utils.ts
|
|
52872
|
-
function to_f(value2, places = "%.1f") {
|
|
52873
|
-
let v = typeof value2 === "string" ? parseFloat(value2) : value2;
|
|
52874
|
-
const formattedValue = places.replace("%.", "").replace("f", "");
|
|
52875
|
-
return parseFloat(v.toFixed(parseInt(formattedValue)));
|
|
53107
|
+
console.log({ entry, support: app_config.support, stop });
|
|
53108
|
+
const result = entry === stop ? [] : condition ? instance.build_entry({
|
|
53109
|
+
current_price: entry,
|
|
53110
|
+
stop_loss: stop,
|
|
53111
|
+
risk: working_risk,
|
|
53112
|
+
kind: kind || app_config.kind,
|
|
53113
|
+
no_of_trades: trade_no
|
|
53114
|
+
}) || [] : [];
|
|
53115
|
+
return computeTotalAverageForEachTrade(result, config2);
|
|
52876
53116
|
}
|
|
52877
|
-
function
|
|
52878
|
-
|
|
52879
|
-
|
|
52880
|
-
budget,
|
|
52881
|
-
percent,
|
|
52882
|
-
min_size,
|
|
52883
|
-
notional_value,
|
|
52884
|
-
as_coin = true,
|
|
52885
|
-
places = "%.3f"
|
|
53117
|
+
function buildAvg({
|
|
53118
|
+
_trades,
|
|
53119
|
+
kind
|
|
52886
53120
|
}) {
|
|
52887
|
-
let
|
|
52888
|
-
|
|
52889
|
-
|
|
52890
|
-
|
|
52891
|
-
|
|
52892
|
-
|
|
52893
|
-
|
|
52894
|
-
|
|
52895
|
-
|
|
52896
|
-
|
|
52897
|
-
|
|
52898
|
-
|
|
53121
|
+
let avg = determine_average_entry_and_size(_trades?.map((r2) => ({
|
|
53122
|
+
price: r2.entry,
|
|
53123
|
+
quantity: r2.quantity
|
|
53124
|
+
})) || []);
|
|
53125
|
+
const stop_prices = _trades.map((o) => o.stop);
|
|
53126
|
+
const stop_loss = kind === "long" ? Math.min(...stop_prices) : Math.max(...stop_prices);
|
|
53127
|
+
avg.pnl = pnl_default.determine_pnl(avg.price, stop_loss, avg.quantity, kind);
|
|
53128
|
+
return avg;
|
|
53129
|
+
}
|
|
53130
|
+
function sortedBuildConfig(app_config, options) {
|
|
53131
|
+
const sorted = buildConfig(app_config, options).sort((a, b) => app_config.kind === "long" ? a.entry - b.entry : b.entry - b.entry).filter((x) => {
|
|
53132
|
+
if (app_config.symbol === "BTCUSDT") {
|
|
53133
|
+
return x.quantity <= 0.03;
|
|
52899
53134
|
}
|
|
52900
|
-
return
|
|
52901
|
-
}
|
|
52902
|
-
return
|
|
53135
|
+
return true;
|
|
53136
|
+
});
|
|
53137
|
+
return sorted.map((k, i2) => {
|
|
53138
|
+
const arrSet = sorted.slice(0, i2 + 1);
|
|
53139
|
+
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);
|
|
53140
|
+
return {
|
|
53141
|
+
...k,
|
|
53142
|
+
reverse_avg_entry: avg_values.price,
|
|
53143
|
+
reverse_avg_quantity: avg_values.quantity
|
|
53144
|
+
};
|
|
53145
|
+
});
|
|
52903
53146
|
}
|
|
52904
|
-
function
|
|
52905
|
-
const
|
|
52906
|
-
|
|
52907
|
-
|
|
53147
|
+
function get_app_config_and_max_size(config2, payload) {
|
|
53148
|
+
const app_config = {
|
|
53149
|
+
kind: payload.kind,
|
|
53150
|
+
entry: payload.entry,
|
|
53151
|
+
stop: payload.stop,
|
|
53152
|
+
risk_per_trade: config2.risk,
|
|
53153
|
+
risk_reward: config2.risk_reward || 199,
|
|
53154
|
+
support: to_f2(config2.support, config2.price_places),
|
|
53155
|
+
resistance: to_f2(config2.resistance, config2.price_places),
|
|
53156
|
+
focus: payload.entry,
|
|
53157
|
+
fee: 0,
|
|
53158
|
+
percent_change: config2.stop_percent / 100,
|
|
53159
|
+
tradeSplit: 1,
|
|
53160
|
+
gap: 1,
|
|
53161
|
+
min_size: config2.min_size,
|
|
53162
|
+
budget: 0,
|
|
53163
|
+
price_places: config2.price_places,
|
|
53164
|
+
decimal_places: config2.decimal_places,
|
|
53165
|
+
min_profit: config2.profit_percent * config2.profit / 100
|
|
53166
|
+
};
|
|
53167
|
+
const initialResult = sortedBuildConfig(app_config, {
|
|
53168
|
+
entry: app_config.entry,
|
|
53169
|
+
stop: app_config.stop,
|
|
53170
|
+
kind: app_config.kind,
|
|
53171
|
+
risk: app_config.risk_per_trade,
|
|
53172
|
+
risk_reward: app_config.risk_reward,
|
|
53173
|
+
increase: true,
|
|
53174
|
+
gap: app_config.gap,
|
|
53175
|
+
price_places: app_config.price_places,
|
|
53176
|
+
decimal_places: app_config.decimal_places
|
|
53177
|
+
});
|
|
53178
|
+
const max_size = initialResult[0]?.avg_size;
|
|
53179
|
+
const last_value = initialResult[0];
|
|
53180
|
+
const entries = initialResult.map((x) => ({
|
|
53181
|
+
entry: x.entry,
|
|
53182
|
+
avg_entry: x.avg_entry,
|
|
53183
|
+
avg_size: x.avg_size,
|
|
53184
|
+
neg_pnl: x.neg_pnl,
|
|
53185
|
+
quantity: x.quantity
|
|
53186
|
+
}));
|
|
52908
53187
|
return {
|
|
52909
|
-
|
|
52910
|
-
|
|
52911
|
-
|
|
53188
|
+
app_config,
|
|
53189
|
+
max_size,
|
|
53190
|
+
last_value,
|
|
53191
|
+
entries
|
|
52912
53192
|
};
|
|
52913
53193
|
}
|
|
52914
|
-
|
|
52915
|
-
const
|
|
52916
|
-
|
|
52917
|
-
|
|
52918
|
-
|
|
52919
|
-
|
|
52920
|
-
|
|
52921
|
-
|
|
52922
|
-
|
|
52923
|
-
|
|
52924
|
-
|
|
52925
|
-
|
|
52926
|
-
|
|
52927
|
-
|
|
52928
|
-
|
|
52929
|
-
|
|
52930
|
-
|
|
52931
|
-
|
|
52932
|
-
|
|
52933
|
-
|
|
52934
|
-
|
|
53194
|
+
function buildAppConfig(config2, payload) {
|
|
53195
|
+
const { app_config, max_size, last_value, entries } = get_app_config_and_max_size({
|
|
53196
|
+
...config2,
|
|
53197
|
+
risk: payload.risk,
|
|
53198
|
+
profit: payload.profit || 500,
|
|
53199
|
+
risk_reward: payload.risk_reward,
|
|
53200
|
+
accounts: [],
|
|
53201
|
+
reduce_percent: 90,
|
|
53202
|
+
reverse_factor: 1,
|
|
53203
|
+
profit_percent: 0,
|
|
53204
|
+
kind: payload.entry > payload.stop ? "long" : "short",
|
|
53205
|
+
symbol: payload.symbol
|
|
53206
|
+
}, {
|
|
53207
|
+
entry: payload.entry,
|
|
53208
|
+
stop: payload.stop,
|
|
53209
|
+
kind: payload.entry > payload.stop ? "long" : "short"
|
|
53210
|
+
});
|
|
53211
|
+
app_config.max_size = max_size;
|
|
53212
|
+
app_config.entry = payload.entry || app_config.entry;
|
|
53213
|
+
app_config.stop = payload.stop || app_config.stop;
|
|
53214
|
+
app_config.last_value = last_value;
|
|
53215
|
+
app_config.entries = entries;
|
|
53216
|
+
return app_config;
|
|
53217
|
+
}
|
|
53218
|
+
function getOptimumStopAndRisk(app_config, params) {
|
|
53219
|
+
const { max_size, target_stop } = params;
|
|
53220
|
+
const isLong = app_config.kind === "long";
|
|
53221
|
+
const stopRange = Math.abs(app_config.entry - target_stop) * 0.5;
|
|
53222
|
+
let low_stop = isLong ? target_stop - stopRange : Math.max(target_stop - stopRange, app_config.entry);
|
|
53223
|
+
let high_stop = isLong ? Math.min(target_stop + stopRange, app_config.entry) : target_stop + stopRange;
|
|
53224
|
+
let optimal_stop = target_stop;
|
|
53225
|
+
let best_stop_result = null;
|
|
53226
|
+
let best_entry_diff = Infinity;
|
|
53227
|
+
console.log(`Finding optimal stop for ${isLong ? "LONG" : "SHORT"} position. Target: ${target_stop}, Search range: ${low_stop} to ${high_stop}`);
|
|
53228
|
+
let iterations = 0;
|
|
53229
|
+
const MAX_ITERATIONS = 50;
|
|
53230
|
+
while (Math.abs(high_stop - low_stop) > 0.1 && iterations < MAX_ITERATIONS) {
|
|
53231
|
+
iterations++;
|
|
53232
|
+
const mid_stop = (low_stop + high_stop) / 2;
|
|
53233
|
+
const result = sortedBuildConfig(app_config, {
|
|
53234
|
+
entry: app_config.entry,
|
|
53235
|
+
stop: mid_stop,
|
|
53236
|
+
kind: app_config.kind,
|
|
53237
|
+
risk: app_config.risk_per_trade,
|
|
53238
|
+
risk_reward: app_config.risk_reward,
|
|
53239
|
+
increase: true,
|
|
53240
|
+
gap: app_config.gap,
|
|
53241
|
+
price_places: app_config.price_places,
|
|
53242
|
+
decimal_places: app_config.decimal_places
|
|
53243
|
+
});
|
|
53244
|
+
if (result.length === 0) {
|
|
53245
|
+
if (isLong) {
|
|
53246
|
+
low_stop = mid_stop;
|
|
53247
|
+
} else {
|
|
53248
|
+
high_stop = mid_stop;
|
|
52935
53249
|
}
|
|
53250
|
+
continue;
|
|
52936
53251
|
}
|
|
52937
|
-
const
|
|
52938
|
-
const
|
|
52939
|
-
|
|
52940
|
-
|
|
52941
|
-
|
|
52942
|
-
|
|
52943
|
-
|
|
52944
|
-
return groupInPairs(arr, key, targetSum);
|
|
52945
|
-
};
|
|
52946
|
-
function groupInPairs(_arr, key, targetSum) {
|
|
52947
|
-
const result = [];
|
|
52948
|
-
let currentSum = 0;
|
|
52949
|
-
let currentGroup = [];
|
|
52950
|
-
for (let i2 = 0;i2 < _arr.length; i2++) {
|
|
52951
|
-
currentSum += _arr[i2][key];
|
|
52952
|
-
currentGroup.push(_arr[i2]);
|
|
52953
|
-
if (currentSum >= targetSum) {
|
|
52954
|
-
result.push(currentGroup);
|
|
52955
|
-
currentGroup = [];
|
|
52956
|
-
currentSum = 0;
|
|
53252
|
+
const first_entry = result[0].entry;
|
|
53253
|
+
const entry_diff = Math.abs(first_entry - target_stop);
|
|
53254
|
+
console.log(`Stop: ${mid_stop.toFixed(2)}, First Entry: ${first_entry.toFixed(2)}, Diff: ${entry_diff.toFixed(2)}`);
|
|
53255
|
+
if (entry_diff < best_entry_diff) {
|
|
53256
|
+
best_entry_diff = entry_diff;
|
|
53257
|
+
optimal_stop = mid_stop;
|
|
53258
|
+
best_stop_result = result;
|
|
52957
53259
|
}
|
|
52958
|
-
|
|
52959
|
-
|
|
52960
|
-
|
|
52961
|
-
|
|
52962
|
-
|
|
52963
|
-
|
|
52964
|
-
let entryToUse = kind === "short" ? Math.min(config2.entry, config2.stop) : Math.max(config2.entry, config2.stop);
|
|
52965
|
-
let _currentEntry = config2.currentEntry || entryToUse;
|
|
52966
|
-
let less = trades.filter((p) => kind === "long" ? p.entry <= _currentEntry : p.entry >= _currentEntry);
|
|
52967
|
-
let rrr = trades.map((r2, i2) => {
|
|
52968
|
-
let considered = [];
|
|
52969
|
-
if (kind === "long") {
|
|
52970
|
-
considered = trades.filter((p) => p.entry > _currentEntry);
|
|
53260
|
+
if (first_entry < target_stop) {
|
|
53261
|
+
if (isLong) {
|
|
53262
|
+
low_stop = mid_stop;
|
|
53263
|
+
} else {
|
|
53264
|
+
low_stop = mid_stop;
|
|
53265
|
+
}
|
|
52971
53266
|
} else {
|
|
52972
|
-
|
|
52973
|
-
|
|
52974
|
-
|
|
52975
|
-
|
|
52976
|
-
if (kind === "long") {
|
|
52977
|
-
return o.entry >= r2.entry;
|
|
53267
|
+
if (isLong) {
|
|
53268
|
+
high_stop = mid_stop;
|
|
53269
|
+
} else {
|
|
53270
|
+
high_stop = mid_stop;
|
|
52978
53271
|
}
|
|
52979
|
-
|
|
53272
|
+
}
|
|
53273
|
+
if (entry_diff < 1)
|
|
53274
|
+
break;
|
|
53275
|
+
}
|
|
53276
|
+
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`);
|
|
53277
|
+
let low_risk = 10;
|
|
53278
|
+
let high_risk = params.highest_risk || 2000;
|
|
53279
|
+
let optimal_risk = app_config.risk_per_trade;
|
|
53280
|
+
let best_size_result = best_stop_result;
|
|
53281
|
+
let best_size_diff = Infinity;
|
|
53282
|
+
console.log(`Finding optimal risk_per_trade for size target: ${max_size} (never exceeding it)`);
|
|
53283
|
+
iterations = 0;
|
|
53284
|
+
while (Math.abs(high_risk - low_risk) > 0.1 && iterations < MAX_ITERATIONS) {
|
|
53285
|
+
iterations++;
|
|
53286
|
+
const mid_risk = (low_risk + high_risk) / 2;
|
|
53287
|
+
const result = sortedBuildConfig(app_config, {
|
|
53288
|
+
entry: app_config.entry,
|
|
53289
|
+
stop: optimal_stop,
|
|
53290
|
+
kind: app_config.kind,
|
|
53291
|
+
risk: mid_risk,
|
|
53292
|
+
risk_reward: app_config.risk_reward,
|
|
53293
|
+
increase: true,
|
|
53294
|
+
gap: app_config.gap,
|
|
53295
|
+
price_places: app_config.price_places,
|
|
53296
|
+
decimal_places: app_config.decimal_places
|
|
52980
53297
|
});
|
|
52981
|
-
if (
|
|
52982
|
-
|
|
53298
|
+
if (result.length === 0) {
|
|
53299
|
+
high_risk = mid_risk;
|
|
53300
|
+
continue;
|
|
52983
53301
|
}
|
|
52984
|
-
const
|
|
52985
|
-
|
|
52986
|
-
|
|
52987
|
-
|
|
52988
|
-
|
|
52989
|
-
|
|
52990
|
-
|
|
52991
|
-
|
|
52992
|
-
|
|
52993
|
-
price: _currentEntry,
|
|
52994
|
-
quantity: config2.currentQty || 0
|
|
53302
|
+
const first_entry = result[0];
|
|
53303
|
+
const avg_size = first_entry.avg_size;
|
|
53304
|
+
console.log(`Risk: ${mid_risk.toFixed(2)}, Avg Size: ${avg_size.toFixed(4)}, Target: ${max_size}`);
|
|
53305
|
+
if (avg_size <= max_size) {
|
|
53306
|
+
const size_diff = max_size - avg_size;
|
|
53307
|
+
if (size_diff < best_size_diff) {
|
|
53308
|
+
best_size_diff = size_diff;
|
|
53309
|
+
optimal_risk = mid_risk;
|
|
53310
|
+
best_size_result = result;
|
|
52995
53311
|
}
|
|
52996
|
-
|
|
52997
|
-
|
|
52998
|
-
|
|
52999
|
-
let entry_pnl = r2.pnl;
|
|
53000
|
-
if (_take_profit) {
|
|
53001
|
-
_pnl = pnl_default.determine_pnl(avg_entry.price, _take_profit, avg_entry.quantity, kind);
|
|
53002
|
-
sell_price = _take_profit;
|
|
53003
|
-
entry_pnl = pnl_default.determine_pnl(r2.entry, _take_profit, avg_entry.quantity, kind);
|
|
53004
|
-
}
|
|
53005
|
-
const loss = pnl_default.determine_pnl(avg_entry.price, r2.stop, avg_entry.quantity, kind);
|
|
53006
|
-
let new_stop = r2.new_stop;
|
|
53007
|
-
const entry_loss = pnl_default.determine_pnl(r2.entry, new_stop, avg_entry.quantity, kind);
|
|
53008
|
-
let min_profit = 0;
|
|
53009
|
-
let min_entry_profit = 0;
|
|
53010
|
-
if (config2.min_profit) {
|
|
53011
|
-
min_profit = pnl_default.determine_close_price(avg_entry.price, config2.min_profit, avg_entry.quantity, kind);
|
|
53012
|
-
min_entry_profit = pnl_default.determine_close_price(r2.entry, config2.min_profit, avg_entry.quantity, kind);
|
|
53013
|
-
}
|
|
53014
|
-
let x_fee = r2.fee;
|
|
53015
|
-
if (config2.fee) {
|
|
53016
|
-
x_fee = config2.fee * r2.stop * avg_entry.quantity;
|
|
53312
|
+
low_risk = mid_risk;
|
|
53313
|
+
} else {
|
|
53314
|
+
high_risk = mid_risk;
|
|
53017
53315
|
}
|
|
53018
|
-
|
|
53019
|
-
|
|
53020
|
-
...r2,
|
|
53021
|
-
x_fee: to_f(x_fee, "%.2f"),
|
|
53022
|
-
avg_entry: avg_entry.price,
|
|
53023
|
-
avg_size: avg_entry.quantity,
|
|
53024
|
-
entry_pnl: to_f(entry_pnl, "%.2f"),
|
|
53025
|
-
entry_loss: to_f(entry_loss, "%.2f"),
|
|
53026
|
-
min_entry_pnl: to_f(min_entry_profit, "%.2f"),
|
|
53027
|
-
pnl: _pnl,
|
|
53028
|
-
neg_pnl: to_f(loss, "%.2f"),
|
|
53029
|
-
sell_price,
|
|
53030
|
-
close_p: to_f(tp_close, "%.2f"),
|
|
53031
|
-
min_pnl: to_f(min_profit, "%.2f"),
|
|
53032
|
-
new_stop
|
|
53033
|
-
};
|
|
53034
|
-
});
|
|
53035
|
-
return rrr;
|
|
53036
|
-
};
|
|
53037
|
-
function createGapPairs(arr, gap, item) {
|
|
53038
|
-
if (arr.length === 0) {
|
|
53039
|
-
return [];
|
|
53316
|
+
if (best_size_diff < 0.001)
|
|
53317
|
+
break;
|
|
53040
53318
|
}
|
|
53041
|
-
|
|
53042
|
-
|
|
53043
|
-
|
|
53044
|
-
|
|
53045
|
-
|
|
53046
|
-
|
|
53047
|
-
|
|
53048
|
-
|
|
53319
|
+
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`);
|
|
53320
|
+
let final_risk = optimal_risk;
|
|
53321
|
+
let final_result = best_size_result;
|
|
53322
|
+
if (best_size_result?.[0]?.avg_size < max_size) {
|
|
53323
|
+
console.log(`Current avg_size (${best_size_result?.[0].avg_size.toFixed(4)}) is less than target (${max_size}). Increasing risk to reach target...`);
|
|
53324
|
+
let current_risk = optimal_risk;
|
|
53325
|
+
const risk_increment = 5;
|
|
53326
|
+
iterations = 0;
|
|
53327
|
+
while (iterations < MAX_ITERATIONS) {
|
|
53328
|
+
iterations++;
|
|
53329
|
+
current_risk += risk_increment;
|
|
53330
|
+
if (current_risk > 5000)
|
|
53331
|
+
break;
|
|
53332
|
+
const result = sortedBuildConfig(app_config, {
|
|
53333
|
+
entry: app_config.entry,
|
|
53334
|
+
stop: optimal_stop,
|
|
53335
|
+
kind: app_config.kind,
|
|
53336
|
+
risk: current_risk,
|
|
53337
|
+
risk_reward: app_config.risk_reward,
|
|
53338
|
+
increase: true,
|
|
53339
|
+
gap: app_config.gap,
|
|
53340
|
+
price_places: app_config.price_places,
|
|
53341
|
+
decimal_places: app_config.decimal_places
|
|
53342
|
+
});
|
|
53343
|
+
if (result.length === 0)
|
|
53344
|
+
continue;
|
|
53345
|
+
const avg_size = result[0].avg_size;
|
|
53346
|
+
console.log(`Increased Risk: ${current_risk.toFixed(2)}, New Avg Size: ${avg_size.toFixed(4)}`);
|
|
53347
|
+
if (avg_size >= max_size) {
|
|
53348
|
+
final_risk = current_risk;
|
|
53349
|
+
final_result = result;
|
|
53350
|
+
console.log(`Target size reached! Final risk: ${final_risk.toFixed(2)}, Final avg_size: ${avg_size.toFixed(4)}`);
|
|
53351
|
+
break;
|
|
53352
|
+
}
|
|
53049
53353
|
}
|
|
53050
53354
|
}
|
|
53051
|
-
|
|
53052
|
-
|
|
53053
|
-
|
|
53054
|
-
|
|
53055
|
-
|
|
53355
|
+
return {
|
|
53356
|
+
optimal_stop: to_f2(optimal_stop, app_config.price_places),
|
|
53357
|
+
optimal_risk: to_f2(final_risk, app_config.price_places),
|
|
53358
|
+
avg_size: final_result?.[0]?.avg_size || 0,
|
|
53359
|
+
avg_entry: final_result?.[0]?.avg_entry || 0,
|
|
53360
|
+
result: final_result,
|
|
53361
|
+
first_entry: final_result?.[0]?.entry || 0,
|
|
53362
|
+
neg_pnl: final_result?.[0]?.neg_pnl || 0,
|
|
53363
|
+
risk_reward: app_config.risk_reward,
|
|
53364
|
+
size_diff: Math.abs((final_result?.[0]?.avg_size || 0) - max_size),
|
|
53365
|
+
entry_diff: best_entry_diff
|
|
53366
|
+
};
|
|
53056
53367
|
}
|
|
53057
|
-
|
|
53058
|
-
|
|
53059
|
-
|
|
53060
|
-
|
|
53061
|
-
|
|
53062
|
-
|
|
53063
|
-
|
|
53064
|
-
|
|
53065
|
-
|
|
53066
|
-
|
|
53067
|
-
|
|
53068
|
-
|
|
53069
|
-
|
|
53070
|
-
|
|
53071
|
-
|
|
53072
|
-
|
|
53073
|
-
|
|
53074
|
-
|
|
53075
|
-
|
|
53368
|
+
function generate_config_params(app_config, payload) {
|
|
53369
|
+
const { result, ...optimum } = getOptimumStopAndRisk(app_config, {
|
|
53370
|
+
max_size: app_config.max_size,
|
|
53371
|
+
highest_risk: payload.risk * 2,
|
|
53372
|
+
target_stop: app_config.stop
|
|
53373
|
+
});
|
|
53374
|
+
return {
|
|
53375
|
+
entry: payload.entry,
|
|
53376
|
+
stop: optimum.optimal_stop,
|
|
53377
|
+
avg_size: optimum.avg_size,
|
|
53378
|
+
avg_entry: optimum.avg_entry,
|
|
53379
|
+
risk_reward: payload.risk_reward,
|
|
53380
|
+
neg_pnl: optimum.neg_pnl,
|
|
53381
|
+
risk: payload.risk
|
|
53382
|
+
};
|
|
53383
|
+
}
|
|
53384
|
+
function determine_break_even_price(payload) {
|
|
53385
|
+
const { long_position, short_position, fee_percent = 0.05 / 100 } = payload;
|
|
53386
|
+
const long_notional = long_position.entry * long_position.quantity;
|
|
53387
|
+
const short_notional = short_position.entry * short_position.quantity;
|
|
53388
|
+
const net_quantity = long_position.quantity - short_position.quantity;
|
|
53389
|
+
const net_capital = Math.abs(long_notional - short_notional);
|
|
53390
|
+
const break_even_price = net_capital / (Math.abs(net_quantity) + fee_percent * Math.abs(net_quantity));
|
|
53391
|
+
return {
|
|
53392
|
+
price: break_even_price,
|
|
53393
|
+
direction: net_quantity > 0 ? "long" : "short"
|
|
53394
|
+
};
|
|
53395
|
+
}
|
|
53396
|
+
function determine_amount_to_buy(payload) {
|
|
53397
|
+
const {
|
|
53398
|
+
orders,
|
|
53399
|
+
kind,
|
|
53400
|
+
decimal_places = "%.3f",
|
|
53401
|
+
position: position2,
|
|
53402
|
+
existingOrders
|
|
53403
|
+
} = payload;
|
|
53404
|
+
const totalQuantity = orders.reduce((sum, order) => sum + (order.quantity || 0), 0);
|
|
53405
|
+
let runningTotal = to_f2(totalQuantity, decimal_places);
|
|
53406
|
+
let sortedOrders = [...orders].sort((a, b) => (a.entry || 0) - (b.entry || 0));
|
|
53407
|
+
if (kind === "short") {
|
|
53408
|
+
sortedOrders.reverse();
|
|
53409
|
+
}
|
|
53410
|
+
const withCumulative = [];
|
|
53411
|
+
for (const order of sortedOrders) {
|
|
53412
|
+
withCumulative.push({
|
|
53413
|
+
...order,
|
|
53414
|
+
cumulative_quantity: runningTotal
|
|
53415
|
+
});
|
|
53416
|
+
runningTotal -= order.quantity;
|
|
53417
|
+
runningTotal = to_f2(runningTotal, decimal_places);
|
|
53418
|
+
}
|
|
53419
|
+
let filteredOrders = withCumulative.filter((order) => (order.cumulative_quantity || 0) > position2?.quantity).map((order) => ({
|
|
53420
|
+
...order,
|
|
53421
|
+
price: order.entry,
|
|
53422
|
+
kind,
|
|
53423
|
+
side: kind.toLowerCase() === "long" ? "buy" : "sell"
|
|
53424
|
+
}));
|
|
53425
|
+
filteredOrders = filteredOrders.filter((k) => !existingOrders.map((j) => j.price).includes(k.price));
|
|
53426
|
+
return filteredOrders;
|
|
53427
|
+
}
|
|
53428
|
+
function generateOptimumAppConfig(config2, payload, position2) {
|
|
53429
|
+
let low_risk = payload.start_risk;
|
|
53430
|
+
let high_risk = payload.max_risk || 50000;
|
|
53431
|
+
let best_risk = null;
|
|
53432
|
+
let best_app_config = null;
|
|
53433
|
+
const tolerance = 0.1;
|
|
53434
|
+
const max_iterations = 150;
|
|
53435
|
+
let iterations = 0;
|
|
53436
|
+
console.log(`Starting risk search for ${position2.kind} position. Target Entry: ${position2.entry}, Initial Risk Range: [${low_risk}, ${high_risk}]`);
|
|
53437
|
+
while (high_risk - low_risk > tolerance && iterations < max_iterations) {
|
|
53438
|
+
iterations++;
|
|
53439
|
+
const mid_risk = (low_risk + high_risk) / 2;
|
|
53440
|
+
const {
|
|
53441
|
+
app_config: current_app_config,
|
|
53442
|
+
max_size,
|
|
53443
|
+
last_value,
|
|
53444
|
+
entries
|
|
53445
|
+
} = get_app_config_and_max_size({
|
|
53446
|
+
...config2,
|
|
53447
|
+
risk: mid_risk,
|
|
53448
|
+
profit_percent: config2.profit_percent || 0,
|
|
53449
|
+
profit: config2.profit || 500,
|
|
53450
|
+
risk_reward: payload.risk_reward,
|
|
53451
|
+
kind: position2.kind,
|
|
53452
|
+
price_places: config2.price_places,
|
|
53453
|
+
decimal_places: config2.decimal_places,
|
|
53454
|
+
accounts: config2.accounts || [],
|
|
53455
|
+
reduce_percent: config2.reduce_percent || 90,
|
|
53456
|
+
reverse_factor: config2.reverse_factor || 1,
|
|
53457
|
+
symbol: config2.symbol || "",
|
|
53458
|
+
support: config2.support || 0,
|
|
53459
|
+
resistance: config2.resistance || 0,
|
|
53460
|
+
min_size: config2.min_size || 0,
|
|
53461
|
+
stop_percent: config2.stop_percent || 0
|
|
53462
|
+
}, {
|
|
53463
|
+
entry: payload.entry,
|
|
53464
|
+
stop: payload.stop,
|
|
53465
|
+
kind: position2.kind
|
|
53466
|
+
});
|
|
53467
|
+
current_app_config.max_size = max_size;
|
|
53468
|
+
current_app_config.last_value = last_value;
|
|
53469
|
+
current_app_config.entries = entries;
|
|
53470
|
+
current_app_config.risk_reward = payload.risk_reward;
|
|
53471
|
+
const full_trades = sortedBuildConfig(current_app_config, {
|
|
53472
|
+
entry: current_app_config.entry,
|
|
53473
|
+
stop: current_app_config.stop,
|
|
53474
|
+
kind: current_app_config.kind,
|
|
53475
|
+
risk: current_app_config.risk_per_trade,
|
|
53476
|
+
risk_reward: current_app_config.risk_reward,
|
|
53477
|
+
increase: true,
|
|
53478
|
+
gap: current_app_config.gap,
|
|
53479
|
+
price_places: current_app_config.price_places,
|
|
53480
|
+
decimal_places: current_app_config.decimal_places
|
|
53481
|
+
});
|
|
53482
|
+
console.log(`Iteration ${iterations}: Risk=${mid_risk.toFixed(2)}, Low=${low_risk.toFixed(2)}, High=${high_risk.toFixed(2)}`);
|
|
53483
|
+
if (full_trades.length === 0) {
|
|
53484
|
+
console.log(` -> No trades generated by sortedBuildConfig at Risk=${mid_risk.toFixed(2)}. Adjusting high_risk down.`);
|
|
53485
|
+
high_risk = mid_risk;
|
|
53486
|
+
continue;
|
|
53487
|
+
}
|
|
53488
|
+
const trades = determine_amount_to_buy({
|
|
53489
|
+
orders: full_trades,
|
|
53490
|
+
kind: position2.kind,
|
|
53491
|
+
decimal_places: current_app_config.decimal_places,
|
|
53492
|
+
price_places: current_app_config.price_places,
|
|
53493
|
+
position: position2,
|
|
53494
|
+
existingOrders: []
|
|
53495
|
+
});
|
|
53496
|
+
if (trades.length === 0) {
|
|
53497
|
+
console.log(` -> No trades met quantity requirement after filtering at Risk=${mid_risk.toFixed(2)}. Adjusting low_risk up.`);
|
|
53498
|
+
low_risk = mid_risk;
|
|
53499
|
+
continue;
|
|
53500
|
+
}
|
|
53501
|
+
const last_trade = trades[trades.length - 1];
|
|
53502
|
+
const last_entry = last_trade.entry;
|
|
53503
|
+
console.log(` -> Last Trade Entry (Filtered): ${last_entry.toFixed(4)}`);
|
|
53504
|
+
if (position2.kind === "long") {
|
|
53505
|
+
if (last_entry > position2.entry) {
|
|
53506
|
+
console.log(` -> Constraint VIOLATED (Long): last_entry (${last_entry.toFixed(4)}) > position.entry (${position2.entry.toFixed(4)}). Reducing high_risk.`);
|
|
53507
|
+
high_risk = mid_risk;
|
|
53508
|
+
} else {
|
|
53509
|
+
console.log(` -> Constraint MET (Long): last_entry (${last_entry.toFixed(4)}) <= position.entry (${position2.entry.toFixed(4)}). Storing as best, increasing low_risk.`);
|
|
53510
|
+
best_risk = mid_risk;
|
|
53511
|
+
best_app_config = current_app_config;
|
|
53512
|
+
low_risk = mid_risk;
|
|
53513
|
+
}
|
|
53514
|
+
} else {
|
|
53515
|
+
if (last_entry < position2.entry) {
|
|
53516
|
+
console.log(` -> Constraint VIOLATED (Short): last_entry (${last_entry.toFixed(4)}) < position.entry (${position2.entry.toFixed(4)}). Reducing high_risk.`);
|
|
53517
|
+
high_risk = mid_risk;
|
|
53518
|
+
} else {
|
|
53519
|
+
console.log(` -> Constraint MET (Short): last_entry (${last_entry.toFixed(4)}) >= position.entry (${position2.entry.toFixed(4)}). Storing as best, increasing low_risk.`);
|
|
53520
|
+
best_risk = mid_risk;
|
|
53521
|
+
best_app_config = current_app_config;
|
|
53522
|
+
low_risk = mid_risk;
|
|
53523
|
+
}
|
|
53524
|
+
}
|
|
53525
|
+
}
|
|
53526
|
+
if (iterations >= max_iterations) {
|
|
53527
|
+
console.warn(`generateAppConfig: Reached max iterations (${max_iterations}) without converging. Returning best found result.`);
|
|
53528
|
+
} else if (best_app_config) {
|
|
53529
|
+
console.log(`Search finished. Best Risk: ${best_risk?.toFixed(2)}, Final Last Entry: ${best_app_config.last_value?.entry?.toFixed(4)}`);
|
|
53530
|
+
} else {
|
|
53531
|
+
console.warn(`generateAppConfig: Could not find a valid risk configuration.`);
|
|
53532
|
+
}
|
|
53533
|
+
if (!best_app_config) {
|
|
53534
|
+
return null;
|
|
53535
|
+
}
|
|
53536
|
+
best_app_config.entries = determine_amount_to_buy({
|
|
53537
|
+
orders: best_app_config.entries,
|
|
53538
|
+
kind: position2.kind,
|
|
53539
|
+
decimal_places: best_app_config.decimal_places,
|
|
53540
|
+
price_places: best_app_config.price_places,
|
|
53541
|
+
position: position2,
|
|
53542
|
+
existingOrders: []
|
|
53543
|
+
});
|
|
53544
|
+
return best_app_config;
|
|
53545
|
+
}
|
|
53546
|
+
|
|
53547
|
+
// src/helpers/strategy.ts
|
|
53548
|
+
class Strategy {
|
|
53549
|
+
position;
|
|
53550
|
+
config;
|
|
53551
|
+
constructor(payload) {
|
|
53552
|
+
this.position = {
|
|
53553
|
+
long: payload.long,
|
|
53554
|
+
short: payload.short
|
|
53555
|
+
};
|
|
53556
|
+
this.config = payload.config;
|
|
53557
|
+
if (!this.config.fee_percent) {
|
|
53558
|
+
this.config.fee_percent = 0.05;
|
|
53559
|
+
}
|
|
53560
|
+
}
|
|
53561
|
+
get price_places() {
|
|
53562
|
+
return this.config.global_config.price_places;
|
|
53563
|
+
}
|
|
53564
|
+
get decimal_places() {
|
|
53565
|
+
return this.config.global_config.decimal_places;
|
|
53566
|
+
}
|
|
53567
|
+
to_f(price) {
|
|
53568
|
+
return to_f2(price, this.price_places);
|
|
53569
|
+
}
|
|
53570
|
+
to_df(quantity) {
|
|
53571
|
+
return to_f2(quantity, this.decimal_places);
|
|
53572
|
+
}
|
|
53573
|
+
pnl(kind, _position) {
|
|
53574
|
+
const position2 = _position || this.position[kind];
|
|
53575
|
+
const { entry, quantity } = position2;
|
|
53576
|
+
const notional = entry * quantity;
|
|
53577
|
+
let tp_percent = this.config.tp_percent;
|
|
53578
|
+
if (kind == "short") {
|
|
53579
|
+
tp_percent = tp_percent * this.config.short_tp_factor;
|
|
53580
|
+
}
|
|
53581
|
+
const profit = notional * (tp_percent / 100);
|
|
53582
|
+
return this.to_f(profit);
|
|
53583
|
+
}
|
|
53584
|
+
tp(kind) {
|
|
53585
|
+
let position2 = this.position[kind];
|
|
53586
|
+
if (position2.quantity == 0) {
|
|
53587
|
+
const reverse_kind = kind == "long" ? "short" : "long";
|
|
53588
|
+
position2 = this.position[reverse_kind];
|
|
53589
|
+
}
|
|
53590
|
+
const { entry, quantity } = position2;
|
|
53591
|
+
const profit = this.pnl(kind, position2);
|
|
53592
|
+
const diff = profit / (quantity || 1);
|
|
53593
|
+
return this.to_f(kind == "long" ? entry + diff : entry - diff);
|
|
53594
|
+
}
|
|
53595
|
+
calculate_fee(position2) {
|
|
53596
|
+
const { price, quantity } = position2;
|
|
53597
|
+
const fee = price * quantity * this.config.fee_percent / 100;
|
|
53598
|
+
return this.to_f(fee);
|
|
53599
|
+
}
|
|
53600
|
+
get long_tp() {
|
|
53601
|
+
return this.tp("long");
|
|
53602
|
+
}
|
|
53603
|
+
get short_tp() {
|
|
53604
|
+
return this.tp("short");
|
|
53605
|
+
}
|
|
53606
|
+
generateGapClosingAlgorithm(payload) {
|
|
53607
|
+
const { kind } = payload;
|
|
53608
|
+
const { entry, quantity } = this.position[kind];
|
|
53609
|
+
const focus_position = this.position[kind];
|
|
53610
|
+
const reverse_kind = kind == "long" ? "short" : "long";
|
|
53611
|
+
const reverse_position = this.position[reverse_kind];
|
|
53612
|
+
let _entry = this.tp(kind);
|
|
53613
|
+
let _stop = this.tp(reverse_kind);
|
|
53614
|
+
if (!_entry && !_stop) {
|
|
53615
|
+
return null;
|
|
53616
|
+
}
|
|
53617
|
+
const second_payload = {
|
|
53618
|
+
entry: _entry,
|
|
53619
|
+
stop: _stop,
|
|
53620
|
+
risk_reward: this.config.risk_reward,
|
|
53621
|
+
start_risk: this.pnl(reverse_kind),
|
|
53622
|
+
max_risk: this.config.budget
|
|
53623
|
+
};
|
|
53624
|
+
const third_payload = {
|
|
53625
|
+
entry,
|
|
53626
|
+
quantity,
|
|
53627
|
+
kind
|
|
53628
|
+
};
|
|
53629
|
+
console.log({ second_payload, third_payload });
|
|
53630
|
+
const app_config = generateOptimumAppConfig(this.config.global_config, second_payload, third_payload);
|
|
53631
|
+
if (!app_config) {
|
|
53632
|
+
return null;
|
|
53633
|
+
}
|
|
53634
|
+
const { entries, ...rest } = app_config;
|
|
53635
|
+
const risk = this.to_f(rest.risk_per_trade);
|
|
53636
|
+
const adjusted_focus_entries = entries.map((entry2) => {
|
|
53637
|
+
let adjusted_price = entry2.price;
|
|
53638
|
+
if (focus_position.quantity > 0) {
|
|
53639
|
+
if (kind === "long" && entry2.price >= focus_position.entry) {
|
|
53640
|
+
adjusted_price = focus_position.entry;
|
|
53641
|
+
} else if (kind === "short" && entry2.price <= focus_position.entry) {
|
|
53642
|
+
adjusted_price = focus_position.entry;
|
|
53643
|
+
}
|
|
53644
|
+
}
|
|
53645
|
+
return {
|
|
53646
|
+
price: adjusted_price,
|
|
53647
|
+
quantity: entry2.quantity
|
|
53648
|
+
};
|
|
53649
|
+
});
|
|
53650
|
+
const avg = determine_average_entry_and_size(adjusted_focus_entries.concat([
|
|
53651
|
+
{
|
|
53652
|
+
price: entry,
|
|
53653
|
+
quantity
|
|
53654
|
+
}
|
|
53655
|
+
]), rest.decimal_places, rest.price_places);
|
|
53656
|
+
const focus_loss = this.to_f((avg.price - second_payload.stop) * avg.quantity);
|
|
53657
|
+
let below_reverse_entries = kind === "long" ? entries.filter((u) => {
|
|
53658
|
+
return u.entry < (reverse_position.entry || focus_position.entry);
|
|
53659
|
+
}) : entries.filter((u) => {
|
|
53660
|
+
return u.entry > (reverse_position.entry || focus_position.entry);
|
|
53661
|
+
});
|
|
53662
|
+
const threshold = below_reverse_entries.at(-1);
|
|
53663
|
+
let adjusted_reverse_entries = entries.map((entry2) => {
|
|
53664
|
+
let adjusted_price = entry2.price;
|
|
53665
|
+
if (threshold) {
|
|
53666
|
+
if (reverse_kind === "short" && entry2.price > threshold.entry) {
|
|
53667
|
+
adjusted_price = threshold.entry;
|
|
53668
|
+
} else if (reverse_kind === "long" && entry2.price < threshold.entry) {
|
|
53669
|
+
adjusted_price = threshold.entry;
|
|
53670
|
+
}
|
|
53671
|
+
}
|
|
53672
|
+
return {
|
|
53673
|
+
price: adjusted_price,
|
|
53674
|
+
quantity: entry2.quantity
|
|
53675
|
+
};
|
|
53676
|
+
});
|
|
53677
|
+
const reverse_avg = determine_average_entry_and_size(adjusted_reverse_entries.concat([
|
|
53678
|
+
{
|
|
53679
|
+
price: reverse_position.entry,
|
|
53680
|
+
quantity: reverse_position.quantity
|
|
53681
|
+
}
|
|
53682
|
+
]), rest.decimal_places, rest.price_places);
|
|
53683
|
+
const reverse_pnl = this.to_f((reverse_avg.price - second_payload.stop) * reverse_avg.quantity);
|
|
53684
|
+
const fee_to_pay = this.calculate_fee({
|
|
53685
|
+
price: avg.entry,
|
|
53686
|
+
quantity: avg.quantity
|
|
53687
|
+
}) + this.calculate_fee({
|
|
53688
|
+
price: reverse_avg.entry,
|
|
53689
|
+
quantity: reverse_avg.quantity
|
|
53690
|
+
});
|
|
53691
|
+
const net_reverse_pnl = reverse_pnl - fee_to_pay;
|
|
53692
|
+
const ratio = net_reverse_pnl / focus_loss;
|
|
53693
|
+
const quantity_to_sell = this.to_df(ratio * avg.quantity);
|
|
53694
|
+
const remaining_quantity = this.to_df(avg.quantity - quantity_to_sell);
|
|
53695
|
+
return {
|
|
53696
|
+
risk,
|
|
53697
|
+
risk_reward: this.config.risk_reward,
|
|
53698
|
+
[kind]: {
|
|
53699
|
+
avg_entry: avg.entry,
|
|
53700
|
+
avg_size: avg.quantity,
|
|
53701
|
+
loss: focus_loss,
|
|
53702
|
+
stop: second_payload.stop,
|
|
53703
|
+
stop_quantity: quantity_to_sell,
|
|
53704
|
+
re_entry_quantity: remaining_quantity,
|
|
53705
|
+
initial_pnl: this.pnl(kind),
|
|
53706
|
+
tp: second_payload.entry
|
|
53707
|
+
},
|
|
53708
|
+
[reverse_kind]: {
|
|
53709
|
+
avg_entry: reverse_avg.entry,
|
|
53710
|
+
avg_size: reverse_avg.quantity,
|
|
53711
|
+
pnl: reverse_pnl,
|
|
53712
|
+
tp: second_payload.stop,
|
|
53713
|
+
re_entry_quantity: remaining_quantity,
|
|
53714
|
+
initial_pnl: this.pnl(reverse_kind)
|
|
53715
|
+
},
|
|
53716
|
+
last_entry: rest.last_value.entry,
|
|
53717
|
+
first_entry: entries.at(-1).entry,
|
|
53718
|
+
threshold
|
|
53719
|
+
};
|
|
53720
|
+
}
|
|
53721
|
+
runIterations(payload) {
|
|
53722
|
+
const { kind, iterations } = payload;
|
|
53723
|
+
const reverse_kind = kind == "long" ? "short" : "long";
|
|
53724
|
+
const result = [];
|
|
53725
|
+
let position2 = {
|
|
53726
|
+
long: this.position.long,
|
|
53727
|
+
short: this.position.short
|
|
53728
|
+
};
|
|
53729
|
+
for (let i2 = 0;i2 < iterations; i2++) {
|
|
53730
|
+
const instance = new Strategy({
|
|
53731
|
+
long: position2.long,
|
|
53732
|
+
short: position2.short,
|
|
53733
|
+
config: {
|
|
53734
|
+
...this.config,
|
|
53735
|
+
tp_percent: this.config.tp_percent + i2 * 4
|
|
53736
|
+
}
|
|
53737
|
+
});
|
|
53738
|
+
const algorithm = instance.generateGapClosingAlgorithm({
|
|
53739
|
+
kind
|
|
53740
|
+
});
|
|
53741
|
+
if (!algorithm) {
|
|
53742
|
+
console.log("No algorithm found");
|
|
53743
|
+
return result;
|
|
53744
|
+
break;
|
|
53745
|
+
}
|
|
53746
|
+
result.push(algorithm);
|
|
53747
|
+
position2[kind] = {
|
|
53748
|
+
entry: algorithm[kind].avg_entry,
|
|
53749
|
+
quantity: algorithm[kind].re_entry_quantity
|
|
53750
|
+
};
|
|
53751
|
+
position2[reverse_kind] = {
|
|
53752
|
+
entry: algorithm[reverse_kind].tp,
|
|
53753
|
+
quantity: algorithm[reverse_kind].re_entry_quantity
|
|
53754
|
+
};
|
|
53755
|
+
}
|
|
53756
|
+
return result;
|
|
53757
|
+
}
|
|
53758
|
+
getPositionAfterTp(payload) {
|
|
53759
|
+
const { kind, include_fees = false } = payload;
|
|
53760
|
+
const focus_position = this.position[kind];
|
|
53761
|
+
const reverse_kind = kind == "long" ? "short" : "long";
|
|
53762
|
+
const reverse_position = this.position[reverse_kind];
|
|
53763
|
+
const focus_tp = this.tp(kind);
|
|
53764
|
+
const focus_pnl = this.pnl(kind);
|
|
53765
|
+
const fees = include_fees ? this.calculate_fee({
|
|
53766
|
+
price: focus_tp,
|
|
53767
|
+
quantity: focus_position.quantity
|
|
53768
|
+
}) * 2 : 0;
|
|
53769
|
+
const expected_loss = (focus_pnl - fees) * this.config.reduce_ratio;
|
|
53770
|
+
const actual_loss = Math.abs(focus_tp - reverse_position.entry) * reverse_position.quantity;
|
|
53771
|
+
const ratio = expected_loss / actual_loss;
|
|
53772
|
+
const loss_quantity = this.to_df(ratio * reverse_position.quantity);
|
|
53773
|
+
const remaining_quantity = this.to_df(reverse_position.quantity - loss_quantity);
|
|
53774
|
+
return {
|
|
53775
|
+
[kind]: {
|
|
53776
|
+
entry: focus_tp,
|
|
53777
|
+
quantity: remaining_quantity
|
|
53778
|
+
},
|
|
53779
|
+
[reverse_kind]: {
|
|
53780
|
+
entry: reverse_position.entry,
|
|
53781
|
+
quantity: remaining_quantity
|
|
53782
|
+
},
|
|
53783
|
+
pnl: {
|
|
53784
|
+
[kind]: focus_pnl,
|
|
53785
|
+
[reverse_kind]: -expected_loss
|
|
53786
|
+
},
|
|
53787
|
+
spread: this.to_f(Math.abs(focus_tp - reverse_position.entry) * remaining_quantity)
|
|
53788
|
+
};
|
|
53789
|
+
}
|
|
53790
|
+
getPositionAfterIteration(payload) {
|
|
53791
|
+
const { kind, iterations, with_fees = false } = payload;
|
|
53792
|
+
let _result = this.getPositionAfterTp({
|
|
53793
|
+
kind,
|
|
53794
|
+
include_fees: with_fees
|
|
53795
|
+
});
|
|
53796
|
+
const result = [_result];
|
|
53797
|
+
for (let i2 = 0;i2 < iterations - 1; i2++) {
|
|
53798
|
+
const instance = new Strategy({
|
|
53799
|
+
long: _result.long,
|
|
53800
|
+
short: _result.short,
|
|
53801
|
+
config: {
|
|
53802
|
+
...this.config,
|
|
53803
|
+
tp_percent: this.config.tp_percent + (i2 + 1) * 0.3
|
|
53804
|
+
}
|
|
53805
|
+
});
|
|
53806
|
+
_result = instance.getPositionAfterTp({
|
|
53807
|
+
kind,
|
|
53808
|
+
include_fees: with_fees
|
|
53809
|
+
});
|
|
53810
|
+
result.push(_result);
|
|
53811
|
+
}
|
|
53812
|
+
return result;
|
|
53813
|
+
}
|
|
53814
|
+
}
|
|
53815
|
+
|
|
53816
|
+
// src/exchanges/binance.ts
|
|
53817
|
+
var import_binance = __toESM(require_lib2());
|
|
53818
|
+
var CONSTANTS = {
|
|
53819
|
+
SPOT_TO_FIAT: "MAIN_C2C",
|
|
53820
|
+
SPOT_TO_USDT_FUTURE: "MAIN_UMFUTURE",
|
|
53821
|
+
SPOT_TO_COIN_FUTURE: "MAIN_CMFUTURE",
|
|
53822
|
+
SPOT_TO_MARGIN_CROSS: "MAIN_MARGIN",
|
|
53823
|
+
SPOT_TO_MINING: "MAIN_MINING",
|
|
53824
|
+
FIAT_TO_SPOT: "C2C_MAIN",
|
|
53825
|
+
FIAT_TO_USDT_FUTURE: "C2C_UMFUTURE",
|
|
53826
|
+
FIAT_TO_MINING: "C2C_MINING",
|
|
53827
|
+
USDT_FUTURE_TO_SPOT: "UMFUTURE_MAIN",
|
|
53828
|
+
USDT_FUTURE_TO_FIAT: "UMFUTURE_C2C",
|
|
53829
|
+
USDT_FUTURE_TO_MARGIN_CROSS: "UMFUTURE_MARGIN",
|
|
53830
|
+
COIN_FUTURE_TO_SPOT: "CMFUTURE_MAIN",
|
|
53831
|
+
MARGIN_CROSS_TO_SPOT: "MARGIN_MAIN",
|
|
53832
|
+
MARGIN_CROSS_TO_USDT_FUTURE: "MARGIN_UMFUTURE",
|
|
53833
|
+
MINING_TO_SPOT: "MINING_MAIN",
|
|
53834
|
+
MINING_TO_USDT_FUTURE: "MINING_UMFUTURE",
|
|
53076
53835
|
MINING_TO_FIAT: "MINING_C2C"
|
|
53077
53836
|
};
|
|
53078
53837
|
|
|
@@ -53302,8 +54061,8 @@ async function createLimitPurchaseOrders(client, symbol, priceFormat, quantityFo
|
|
|
53302
54061
|
const createOrder = (x) => {
|
|
53303
54062
|
const v = {
|
|
53304
54063
|
symbol: symbol.toUpperCase(),
|
|
53305
|
-
price: x.price ?
|
|
53306
|
-
quantity: x.quantity ?
|
|
54064
|
+
price: x.price ? to_f2(x.price, priceFormat) : 0,
|
|
54065
|
+
quantity: x.quantity ? to_f2(x.quantity, quantityFormat) : 0,
|
|
53307
54066
|
side: x.side?.toUpperCase() || "",
|
|
53308
54067
|
type: "LIMIT",
|
|
53309
54068
|
positionSide: x.kind.toUpperCase(),
|
|
@@ -53318,7 +54077,7 @@ async function createLimitPurchaseOrders(client, symbol, priceFormat, quantityFo
|
|
|
53318
54077
|
delete v.timeInForce;
|
|
53319
54078
|
v.type = `${v.type}_MARKET`.toUpperCase();
|
|
53320
54079
|
} else if (typeof x.stop === "number") {
|
|
53321
|
-
v.stopPrice =
|
|
54080
|
+
v.stopPrice = to_f2(x.stop, priceFormat);
|
|
53322
54081
|
}
|
|
53323
54082
|
}
|
|
53324
54083
|
if (x.force_market) {
|
|
@@ -53456,7 +54215,28 @@ async function placeTpOrder(client, payload) {
|
|
|
53456
54215
|
return { error: "No quantity" };
|
|
53457
54216
|
}
|
|
53458
54217
|
async function placeStopOrder(client, payload) {
|
|
53459
|
-
const {
|
|
54218
|
+
const {
|
|
54219
|
+
price_places = "%.1f",
|
|
54220
|
+
decimal_places = "%.3f",
|
|
54221
|
+
symbol,
|
|
54222
|
+
current_price,
|
|
54223
|
+
kind,
|
|
54224
|
+
stop,
|
|
54225
|
+
quantity,
|
|
54226
|
+
cancel
|
|
54227
|
+
} = payload;
|
|
54228
|
+
if (kind === "long" && current_price < stop || kind === "short" && current_price > stop) {
|
|
54229
|
+
console.log(`Diverting to TP order for ${symbol} (${kind}). Current: ${current_price}, Stop: ${stop}`);
|
|
54230
|
+
return placeTpOrder(client, {
|
|
54231
|
+
symbol,
|
|
54232
|
+
tp: stop,
|
|
54233
|
+
quantity,
|
|
54234
|
+
kind,
|
|
54235
|
+
cancel,
|
|
54236
|
+
price_places,
|
|
54237
|
+
decimal_places
|
|
54238
|
+
});
|
|
54239
|
+
}
|
|
53460
54240
|
if (payload.cancel) {
|
|
53461
54241
|
await cancelAllOrders(client, symbol, {
|
|
53462
54242
|
type: "stop",
|
|
@@ -53557,14 +54337,14 @@ async function getOpenOrders(client, symbol, type) {
|
|
|
53557
54337
|
async function getWalletBalance(client, asset = "USDT") {
|
|
53558
54338
|
const response = await client.getBalanceV3();
|
|
53559
54339
|
const balance = response.find((x) => x.asset.toLowerCase() === asset.toLowerCase())?.balance;
|
|
53560
|
-
return balance ?
|
|
54340
|
+
return balance ? to_f2(balance, "%.2f") : 0;
|
|
53561
54341
|
}
|
|
53562
54342
|
async function allWalletBalances(client) {
|
|
53563
54343
|
const response = await client.getBalanceV3();
|
|
53564
54344
|
return response.map((x) => ({
|
|
53565
54345
|
type: "future",
|
|
53566
54346
|
asset: x.asset,
|
|
53567
|
-
balance:
|
|
54347
|
+
balance: to_f2(x.balance, "%.8f")
|
|
53568
54348
|
}));
|
|
53569
54349
|
}
|
|
53570
54350
|
function buildPosition(position2, orders, options) {
|
|
@@ -53820,6 +54600,7 @@ class BinanceExchange {
|
|
|
53820
54600
|
}
|
|
53821
54601
|
async placeStopOrders(payload) {
|
|
53822
54602
|
if (payload.place) {
|
|
54603
|
+
const current_price = await this.get_current_price(payload.symbol);
|
|
53823
54604
|
return placeStopOrder(this.client, {
|
|
53824
54605
|
symbol: payload.symbol,
|
|
53825
54606
|
stop: payload.stop,
|
|
@@ -53829,7 +54610,8 @@ class BinanceExchange {
|
|
|
53829
54610
|
cancel: true,
|
|
53830
54611
|
is_limit: true,
|
|
53831
54612
|
price_places: payload.price_places,
|
|
53832
|
-
decimal_places: payload.decimal_places
|
|
54613
|
+
decimal_places: payload.decimal_places,
|
|
54614
|
+
current_price
|
|
53833
54615
|
});
|
|
53834
54616
|
}
|
|
53835
54617
|
}
|
|
@@ -53859,7 +54641,7 @@ class BinanceExchange {
|
|
|
53859
54641
|
place = false
|
|
53860
54642
|
} = payload;
|
|
53861
54643
|
const totalQuantity = orders.reduce((sum, order) => sum + (order.quantity || 0), 0);
|
|
53862
|
-
let runningTotal =
|
|
54644
|
+
let runningTotal = to_f2(totalQuantity, decimal_places);
|
|
53863
54645
|
let sortedOrders = [...orders].sort((a, b) => (a.entry || 0) - (b.entry || 0));
|
|
53864
54646
|
if (kind === "short") {
|
|
53865
54647
|
sortedOrders.reverse();
|
|
@@ -53871,7 +54653,7 @@ class BinanceExchange {
|
|
|
53871
54653
|
cumulative_quantity: runningTotal
|
|
53872
54654
|
});
|
|
53873
54655
|
runningTotal -= order.quantity;
|
|
53874
|
-
runningTotal =
|
|
54656
|
+
runningTotal = to_f2(runningTotal, decimal_places);
|
|
53875
54657
|
}
|
|
53876
54658
|
const positions = await getPositionInfo(this.client, symbol);
|
|
53877
54659
|
const position2 = positions[kind] || {
|
|
@@ -53934,6 +54716,7 @@ class BinanceExchange {
|
|
|
53934
54716
|
symbol: payload.symbol,
|
|
53935
54717
|
tp: payload.take_profit,
|
|
53936
54718
|
kind: payload.kind,
|
|
54719
|
+
quantity: payload.quantity,
|
|
53937
54720
|
cancel: true,
|
|
53938
54721
|
price_places: payload.price_places,
|
|
53939
54722
|
decimal_places: payload.decimal_places
|
|
@@ -53954,6 +54737,7 @@ class BinanceExchange {
|
|
|
53954
54737
|
});
|
|
53955
54738
|
}
|
|
53956
54739
|
async placeStopOrder(payload) {
|
|
54740
|
+
const current_price = await this.get_current_price(payload.symbol);
|
|
53957
54741
|
return await placeStopOrder(this.client, {
|
|
53958
54742
|
symbol: payload.symbol,
|
|
53959
54743
|
stop: payload.stop,
|
|
@@ -53963,7 +54747,8 @@ class BinanceExchange {
|
|
|
53963
54747
|
cancel: true,
|
|
53964
54748
|
is_limit: true,
|
|
53965
54749
|
price_places: payload.price_places,
|
|
53966
|
-
decimal_places: payload.decimal_places
|
|
54750
|
+
decimal_places: payload.decimal_places,
|
|
54751
|
+
current_price
|
|
53967
54752
|
});
|
|
53968
54753
|
}
|
|
53969
54754
|
async setLeverage(payload) {
|
|
@@ -54017,7 +54802,7 @@ class BinanceExchange {
|
|
|
54017
54802
|
const currentPrice = await getCurrentPrice(this.client, symbol);
|
|
54018
54803
|
const price_places = isBTC ? "%.1f" : `%.${getPricePlaces(currentPrice)}f`;
|
|
54019
54804
|
const decimal_places = `%.${target.quantityPrecision}f`;
|
|
54020
|
-
const min_size =
|
|
54805
|
+
const min_size = to_f2((minNotional || 0) / support, decimal_places);
|
|
54021
54806
|
const configObj = {
|
|
54022
54807
|
support,
|
|
54023
54808
|
resistance,
|
|
@@ -54173,8 +54958,8 @@ async function createLimitPurchaseOrders2(client, symbol, priceFormat, quantityF
|
|
|
54173
54958
|
const createOrder = (x) => {
|
|
54174
54959
|
const v = {
|
|
54175
54960
|
symbol: symbol.toUpperCase(),
|
|
54176
|
-
price: (x.price ?
|
|
54177
|
-
qty: (x.quantity ?
|
|
54961
|
+
price: (x.price ? to_f2(x.price, priceFormat) : 0).toString(),
|
|
54962
|
+
qty: (x.quantity ? to_f2(x.quantity, quantityFormat) : 0).toString(),
|
|
54178
54963
|
side: titleCase(x.side || ""),
|
|
54179
54964
|
orderType: "LIMIT",
|
|
54180
54965
|
positionIdx: x.kind === "long" ? 1 : 2,
|
|
@@ -54191,12 +54976,12 @@ async function createLimitPurchaseOrders2(client, symbol, priceFormat, quantityF
|
|
|
54191
54976
|
delete v.timeInForce;
|
|
54192
54977
|
v.orderType = `MARKET`;
|
|
54193
54978
|
} else if (typeof x.stop === "number") {
|
|
54194
|
-
v.triggerPrice =
|
|
54979
|
+
v.triggerPrice = to_f2(x.stop, priceFormat).toString();
|
|
54195
54980
|
}
|
|
54196
54981
|
if (x.kind === "long" && x.side === "sell" || x.kind === "short" && x.side === "buy") {
|
|
54197
54982
|
v.tpslMode = "Partial";
|
|
54198
54983
|
v.slOrderType = "Limit";
|
|
54199
|
-
v.slLimitPrice =
|
|
54984
|
+
v.slLimitPrice = to_f2(v.triggerPrice, priceFormat).toString();
|
|
54200
54985
|
if (x.is_market) {
|
|
54201
54986
|
v.slOrderType = "Market";
|
|
54202
54987
|
v.tpslMode = "Full";
|
|
@@ -54420,7 +55205,7 @@ async function getWalletBalance2(client, asset = "USDT") {
|
|
|
54420
55205
|
accountType: "UNIFIED",
|
|
54421
55206
|
coin: asset
|
|
54422
55207
|
});
|
|
54423
|
-
return
|
|
55208
|
+
return to_f2(response.result.list[0].totalWalletBalance, "%.2f");
|
|
54424
55209
|
}
|
|
54425
55210
|
async function allWalletBalances2(client) {
|
|
54426
55211
|
const response = await client.getWalletBalance({
|
|
@@ -54430,7 +55215,7 @@ async function allWalletBalances2(client) {
|
|
|
54430
55215
|
return response.result.list[0].coin.map((x) => ({
|
|
54431
55216
|
type: "future",
|
|
54432
55217
|
asset: x.coin,
|
|
54433
|
-
balance:
|
|
55218
|
+
balance: to_f2(x.walletBalance, "%.8f")
|
|
54434
55219
|
}));
|
|
54435
55220
|
}
|
|
54436
55221
|
function buildPosition2(position2, orders, options) {
|
|
@@ -54646,7 +55431,7 @@ class BybitExchange {
|
|
|
54646
55431
|
place = false
|
|
54647
55432
|
} = payload;
|
|
54648
55433
|
const totalQuantity = orders.reduce((sum, order) => sum + (order.quantity || 0), 0);
|
|
54649
|
-
let runningTotal =
|
|
55434
|
+
let runningTotal = to_f2(totalQuantity, decimal_places);
|
|
54650
55435
|
let sortedOrders = [...orders].sort((a, b) => (a.entry || 0) - (b.entry || 0));
|
|
54651
55436
|
if (kind === "short") {
|
|
54652
55437
|
sortedOrders.reverse();
|
|
@@ -54658,7 +55443,7 @@ class BybitExchange {
|
|
|
54658
55443
|
cumulative_quantity: runningTotal
|
|
54659
55444
|
});
|
|
54660
55445
|
runningTotal -= order.quantity;
|
|
54661
|
-
runningTotal =
|
|
55446
|
+
runningTotal = to_f2(runningTotal, decimal_places);
|
|
54662
55447
|
}
|
|
54663
55448
|
const positions = await getPositionInfo2(this.client, symbol);
|
|
54664
55449
|
const position2 = positions[kind] || {
|
|
@@ -54797,7 +55582,7 @@ class BybitExchange {
|
|
|
54797
55582
|
function determine_liquidation(balance_diff, position2) {
|
|
54798
55583
|
const long_liquidation = position2.price - balance_diff / position2.quantity;
|
|
54799
55584
|
const short_liquidation = position2.price + balance_diff / position2.quantity;
|
|
54800
|
-
return position2.kind === "long" ?
|
|
55585
|
+
return position2.kind === "long" ? to_f2(long_liquidation, "%.2f") : to_f2(short_liquidation, "%.2f");
|
|
54801
55586
|
}
|
|
54802
55587
|
function calculate_avg_entry(kind, {
|
|
54803
55588
|
orders: _orders,
|
|
@@ -54930,28 +55715,43 @@ function calculate_avg_entry2(kind, {
|
|
|
54930
55715
|
], decimal_places, price_places);
|
|
54931
55716
|
return avg_entry;
|
|
54932
55717
|
}
|
|
54933
|
-
function calculateHedge(
|
|
55718
|
+
function calculateHedge(payload) {
|
|
55719
|
+
const {
|
|
55720
|
+
kind,
|
|
55721
|
+
active_account,
|
|
55722
|
+
targetPnl: _targetPnl = 100,
|
|
55723
|
+
ratio = 0.9,
|
|
55724
|
+
use_full = false,
|
|
55725
|
+
not_reduce: _not_reduce = false,
|
|
55726
|
+
sell_ratio: _sell_ratio = 1
|
|
55727
|
+
} = payload;
|
|
55728
|
+
let sell_ratio = _sell_ratio;
|
|
55729
|
+
if (sell_ratio === 0) {
|
|
55730
|
+
sell_ratio = 1;
|
|
55731
|
+
}
|
|
54934
55732
|
const oppositeKind = kind === "long" ? "short" : "long";
|
|
54935
55733
|
const avg_values = {
|
|
54936
55734
|
long: calculate_avg_entry2("long", active_account),
|
|
54937
55735
|
short: calculate_avg_entry2("short", active_account)
|
|
54938
55736
|
};
|
|
55737
|
+
const targetPnl = _targetPnl * sell_ratio;
|
|
54939
55738
|
const position2 = active_account.position[kind];
|
|
55739
|
+
const position_quantity = position2.quantity * sell_ratio;
|
|
54940
55740
|
const oppositePosition = use_full ? avg_values[oppositeKind] : active_account.position[oppositeKind];
|
|
54941
|
-
const takeProfitPrice = kind === "long" ? position2.entry + targetPnl /
|
|
55741
|
+
const takeProfitPrice = kind === "long" ? position2.entry + targetPnl / position_quantity : position2.entry - targetPnl / position_quantity;
|
|
54942
55742
|
const stopLossPrice = takeProfitPrice;
|
|
54943
55743
|
const priceDifference = oppositeKind === "short" ? stopLossPrice - oppositePosition.entry : oppositePosition.entry - stopLossPrice;
|
|
54944
55744
|
const stopLossAmount = targetPnl * ratio;
|
|
54945
55745
|
const stopLossQuantity = Math.min(stopLossAmount / priceDifference, oppositePosition.quantity);
|
|
54946
55746
|
return {
|
|
54947
55747
|
[kind]: {
|
|
54948
|
-
price:
|
|
54949
|
-
quantity:
|
|
55748
|
+
price: to_f2(takeProfitPrice, active_account.price_places),
|
|
55749
|
+
quantity: to_f2(position_quantity || 0, active_account.decimal_places),
|
|
54950
55750
|
type: "TAKE_PROFIT"
|
|
54951
55751
|
},
|
|
54952
55752
|
[oppositeKind]: {
|
|
54953
|
-
stop_price:
|
|
54954
|
-
quantity:
|
|
55753
|
+
stop_price: to_f2(stopLossPrice, active_account.price_places),
|
|
55754
|
+
quantity: to_f2(stopLossQuantity || 0, active_account.decimal_places),
|
|
54955
55755
|
type: "STOP_LOSS"
|
|
54956
55756
|
}
|
|
54957
55757
|
};
|
|
@@ -54972,669 +55772,189 @@ function findStopOrders(kind, account) {
|
|
|
54972
55772
|
}
|
|
54973
55773
|
function findEntryLimitOrders(kind, account, current_price, minimum_pnl) {
|
|
54974
55774
|
const position2 = account.position[kind];
|
|
54975
|
-
const pnl = (current_price - position2.entry) * position2.quantity;
|
|
54976
|
-
const orders = account.orders[kind].entries;
|
|
54977
|
-
const side = kind === "long" ? "buy" : "sell";
|
|
54978
|
-
let limit_orders = orders.filter((order) => order.stop === 0 && order.side === side).filter((o) => {
|
|
54979
|
-
if (kind === "long" && pnl < 0 && Math.abs(pnl) > minimum_pnl) {
|
|
54980
|
-
return true;
|
|
54981
|
-
}
|
|
54982
|
-
if (kind === "short" && pnl > 0 && Math.abs(pnl) > minimum_pnl) {
|
|
54983
|
-
return true;
|
|
54984
|
-
}
|
|
54985
|
-
return false;
|
|
54986
|
-
});
|
|
54987
|
-
if (limit_orders.length > 1) {
|
|
54988
|
-
limit_orders = [limit_orders[limit_orders.length - 1]];
|
|
54989
|
-
}
|
|
54990
|
-
return limit_orders.map((o) => ({ ...o, id: o.order_id }));
|
|
54991
|
-
}
|
|
54992
|
-
function processPosition(codeNode, input, kind) {
|
|
54993
|
-
const { active_account, current_price } = input;
|
|
54994
|
-
const { use_full = false } = codeNode;
|
|
54995
|
-
const long_position = active_account.position.long;
|
|
54996
|
-
const short_position = active_account.position.short;
|
|
54997
|
-
const vv = calculateHedge(kind, active_account, codeNode.profit || 50, codeNode.ratio, use_full, codeNode.not_reduce);
|
|
54998
|
-
const reverse_kind = kind === "long" ? "short" : "long";
|
|
54999
|
-
const a_stops = findStopOrders(reverse_kind, active_account);
|
|
55000
|
-
const a_limits = findEntryLimitOrders(reverse_kind, active_account, current_price, codeNode.minimum_pnl).filter((u) => codeNode.increase);
|
|
55001
|
-
const orders_to_cancel = a_limits.concat(a_stops);
|
|
55002
|
-
return {
|
|
55003
|
-
exchange: input.exchange,
|
|
55004
|
-
result: vv,
|
|
55005
|
-
to_place: {
|
|
55006
|
-
...vv[reverse_kind],
|
|
55007
|
-
kind: reverse_kind,
|
|
55008
|
-
side: reverse_kind === "long" ? "buy" : "sell"
|
|
55009
|
-
},
|
|
55010
|
-
orders_to_cancel,
|
|
55011
|
-
stop: to_f(vv[kind].price, active_account.price_places),
|
|
55012
|
-
quantity: vv[kind].quantity,
|
|
55013
|
-
kind,
|
|
55014
|
-
type: JSON.stringify("TAKE_PROFIT"),
|
|
55015
|
-
id: active_account.id,
|
|
55016
|
-
position: kind === "long" ? long_position : short_position,
|
|
55017
|
-
opposite_position: kind === "long" ? short_position : long_position,
|
|
55018
|
-
long_position,
|
|
55019
|
-
short_position,
|
|
55020
|
-
owner: active_account.owner,
|
|
55021
|
-
risk: codeNode.profit || 150,
|
|
55022
|
-
increase: codeNode.increase,
|
|
55023
|
-
not_reduce: codeNode.not_reduce,
|
|
55024
|
-
price_places: active_account.price_places,
|
|
55025
|
-
decimal_places: active_account.decimal_places
|
|
55026
|
-
};
|
|
55027
|
-
}
|
|
55028
|
-
async function reduceMajorPositionCalculation(input, exchange_instance) {
|
|
55029
|
-
try {
|
|
55030
|
-
let conditionsCheck = input.position.tp_quantity !== input.quantity || input.position.take_profit !== to_f(input.stop, input.price_places);
|
|
55031
|
-
if (input.opposite_position.stop_quantity) {
|
|
55032
|
-
conditionsCheck = conditionsCheck || input.opposite_position.stop_quantity !== input.to_place.quantity;
|
|
55033
|
-
}
|
|
55034
|
-
console.log("conditionsCheck for ", input.position.kind, conditionsCheck);
|
|
55035
|
-
console.log("opposite_check", {
|
|
55036
|
-
kind: input.opposite_position.kind,
|
|
55037
|
-
stop_loss: input.opposite_position.stop_loss,
|
|
55038
|
-
stop_price: input.to_place.stop_price,
|
|
55039
|
-
owner: input.owner,
|
|
55040
|
-
not_reduce: input.to_place,
|
|
55041
|
-
stop_to_place: {
|
|
55042
|
-
owner: input.owner,
|
|
55043
|
-
symbol: input.position.symbol,
|
|
55044
|
-
kind: input.to_place.kind,
|
|
55045
|
-
stop: input.to_place.stop_price,
|
|
55046
|
-
quantity: Math.abs(input.to_place.quantity)
|
|
55047
|
-
}
|
|
55048
|
-
});
|
|
55049
|
-
if (conditionsCheck) {
|
|
55050
|
-
const async_tp = async () => {
|
|
55051
|
-
if (input.stop && input.stop !== Infinity) {
|
|
55052
|
-
await exchange_instance.placeTpOrder({
|
|
55053
|
-
symbol: input.position.symbol,
|
|
55054
|
-
kind: input.kind,
|
|
55055
|
-
take_profit: input.stop,
|
|
55056
|
-
price_places: input.price_places,
|
|
55057
|
-
decimal_places: input.decimal_places
|
|
55058
|
-
});
|
|
55059
|
-
}
|
|
55060
|
-
};
|
|
55061
|
-
const async_increase = async () => {
|
|
55062
|
-
if (input.increase && input.to_place.stop_price) {
|
|
55063
|
-
await exchange_instance.placeLimitOrder({
|
|
55064
|
-
symbol: input.position.symbol,
|
|
55065
|
-
kind: input.to_place.kind,
|
|
55066
|
-
price: input.to_place.stop_price,
|
|
55067
|
-
quantity: input.to_place.quantity,
|
|
55068
|
-
price_places: input.price_places,
|
|
55069
|
-
decimal_places: input.decimal_places
|
|
55070
|
-
}).then((r2) => {
|
|
55071
|
-
console.log("placeNewOrderData", r2);
|
|
55072
|
-
});
|
|
55073
|
-
}
|
|
55074
|
-
};
|
|
55075
|
-
let placeNewOrderData = null;
|
|
55076
|
-
const async_place_stop = async () => {
|
|
55077
|
-
if (!input.not_reduce && input.to_place.stop_price && input.to_place.quantity) {
|
|
55078
|
-
await exchange_instance.placeStopOrder({
|
|
55079
|
-
symbol: input.position.symbol,
|
|
55080
|
-
kind: input.to_place.kind,
|
|
55081
|
-
stop: input.to_place.stop_price,
|
|
55082
|
-
quantity: Math.abs(input.to_place.quantity),
|
|
55083
|
-
price_places: input.price_places,
|
|
55084
|
-
decimal_places: input.decimal_places
|
|
55085
|
-
});
|
|
55086
|
-
}
|
|
55087
|
-
};
|
|
55088
|
-
const [_tp, _increase, _place_stop] = await Promise.all([
|
|
55089
|
-
async_tp(),
|
|
55090
|
-
async_increase(),
|
|
55091
|
-
async_place_stop()
|
|
55092
|
-
]);
|
|
55093
|
-
return {
|
|
55094
|
-
newOrderResponse: placeNewOrderData
|
|
55095
|
-
};
|
|
55096
|
-
} else {
|
|
55097
|
-
return {
|
|
55098
|
-
message: "No changes needed, conditions not met",
|
|
55099
|
-
input
|
|
55100
|
-
};
|
|
55101
|
-
}
|
|
55102
|
-
} catch (error) {
|
|
55103
|
-
console.error("Error in reduceMajorPositionCalculation:", error);
|
|
55104
|
-
throw error;
|
|
55105
|
-
}
|
|
55106
|
-
}
|
|
55107
|
-
async function reduceMajorPositionEntry(input, accountInfo, trigger2, exchange_instance) {
|
|
55108
|
-
let results = {};
|
|
55109
|
-
try {
|
|
55110
|
-
const async_long = async () => {
|
|
55111
|
-
if (input.long) {
|
|
55112
|
-
const workflowInput = processPosition(input.long, accountInfo, "long");
|
|
55113
|
-
if (trigger2.long) {
|
|
55114
|
-
try {
|
|
55115
|
-
await reduceMajorPositionCalculation(workflowInput, exchange_instance);
|
|
55116
|
-
} catch (error) {
|
|
55117
|
-
console.error("Error in reduceMajorPositionCalculation:", error);
|
|
55118
|
-
}
|
|
55119
|
-
}
|
|
55120
|
-
return workflowInput;
|
|
55121
|
-
}
|
|
55122
|
-
return null;
|
|
55123
|
-
};
|
|
55124
|
-
const async_short = async () => {
|
|
55125
|
-
if (input.short) {
|
|
55126
|
-
const workflowInput = processPosition(input.short, accountInfo, "short");
|
|
55127
|
-
if (trigger2.short) {
|
|
55128
|
-
try {
|
|
55129
|
-
await reduceMajorPositionCalculation(workflowInput, exchange_instance);
|
|
55130
|
-
} catch (error) {
|
|
55131
|
-
console.error("Error in reduceMajorPositionCalculation:", error);
|
|
55132
|
-
}
|
|
55133
|
-
}
|
|
55134
|
-
return workflowInput;
|
|
55135
|
-
}
|
|
55136
|
-
return null;
|
|
55137
|
-
};
|
|
55138
|
-
const [long, short] = await Promise.all([async_long(), async_short()]);
|
|
55139
|
-
results.long = long;
|
|
55140
|
-
results.short = short;
|
|
55141
|
-
return results;
|
|
55142
|
-
} catch (error) {
|
|
55143
|
-
console.error("Error in reduceMajorPositionEntry:", error);
|
|
55144
|
-
throw error;
|
|
55145
|
-
}
|
|
55146
|
-
}
|
|
55147
|
-
|
|
55148
|
-
// src/helpers/shared.ts
|
|
55149
|
-
function buildConfig(app_config, {
|
|
55150
|
-
take_profit,
|
|
55151
|
-
entry,
|
|
55152
|
-
stop,
|
|
55153
|
-
raw_instance,
|
|
55154
|
-
risk,
|
|
55155
|
-
no_of_trades,
|
|
55156
|
-
min_profit = 0,
|
|
55157
|
-
risk_reward,
|
|
55158
|
-
kind,
|
|
55159
|
-
increase,
|
|
55160
|
-
gap,
|
|
55161
|
-
rr = 1,
|
|
55162
|
-
price_places = "%.1f",
|
|
55163
|
-
decimal_places = "%.3f"
|
|
55164
|
-
}) {
|
|
55165
|
-
let fee = app_config.fee / 100;
|
|
55166
|
-
let working_risk = risk || app_config.risk_per_trade;
|
|
55167
|
-
let trade_no = no_of_trades || app_config.risk_reward;
|
|
55168
|
-
const config2 = {
|
|
55169
|
-
focus: app_config.focus,
|
|
55170
|
-
fee,
|
|
55171
|
-
budget: app_config.budget,
|
|
55172
|
-
risk_reward: risk_reward || trade_no,
|
|
55173
|
-
support: app_config.support,
|
|
55174
|
-
resistance: app_config.resistance,
|
|
55175
|
-
price_places: app_config.price_places || price_places,
|
|
55176
|
-
decimal_places,
|
|
55177
|
-
percent_change: app_config.percent_change / app_config.tradeSplit,
|
|
55178
|
-
risk_per_trade: working_risk,
|
|
55179
|
-
take_profit: take_profit || app_config.take_profit,
|
|
55180
|
-
increase_position: increase,
|
|
55181
|
-
minimum_size: app_config.min_size,
|
|
55182
|
-
entry,
|
|
55183
|
-
stop,
|
|
55184
|
-
kind: app_config.kind,
|
|
55185
|
-
gap,
|
|
55186
|
-
min_profit: min_profit || app_config.min_profit,
|
|
55187
|
-
rr: rr || 1
|
|
55188
|
-
};
|
|
55189
|
-
const instance = new Signal(config2);
|
|
55190
|
-
if (raw_instance) {
|
|
55191
|
-
return instance;
|
|
55192
|
-
}
|
|
55193
|
-
if (!stop) {
|
|
55194
|
-
return [];
|
|
55195
|
-
}
|
|
55196
|
-
const condition = (kind === "long" ? entry > app_config.support : entry >= app_config.support) && stop >= app_config.support * 0.999;
|
|
55197
|
-
if (kind === "short") {
|
|
55198
|
-
console.log("condition", condition, entry === stop);
|
|
55199
|
-
}
|
|
55200
|
-
console.log({ entry, support: app_config.support, stop });
|
|
55201
|
-
const result = entry === stop ? [] : condition ? instance.build_entry({
|
|
55202
|
-
current_price: entry,
|
|
55203
|
-
stop_loss: stop,
|
|
55204
|
-
risk: working_risk,
|
|
55205
|
-
kind: kind || app_config.kind,
|
|
55206
|
-
no_of_trades: trade_no
|
|
55207
|
-
}) || [] : [];
|
|
55208
|
-
return computeTotalAverageForEachTrade(result, config2);
|
|
55209
|
-
}
|
|
55210
|
-
function buildAvg({
|
|
55211
|
-
_trades,
|
|
55212
|
-
kind
|
|
55213
|
-
}) {
|
|
55214
|
-
let avg = determine_average_entry_and_size(_trades?.map((r2) => ({
|
|
55215
|
-
price: r2.entry,
|
|
55216
|
-
quantity: r2.quantity
|
|
55217
|
-
})) || []);
|
|
55218
|
-
const stop_prices = _trades.map((o) => o.stop);
|
|
55219
|
-
const stop_loss = kind === "long" ? Math.min(...stop_prices) : Math.max(...stop_prices);
|
|
55220
|
-
avg.pnl = pnl_default.determine_pnl(avg.price, stop_loss, avg.quantity, kind);
|
|
55221
|
-
return avg;
|
|
55222
|
-
}
|
|
55223
|
-
function sortedBuildConfig(app_config, options) {
|
|
55224
|
-
const sorted = buildConfig(app_config, options).sort((a, b) => app_config.kind === "long" ? a.entry - b.entry : b.entry - b.entry).filter((x) => {
|
|
55225
|
-
if (app_config.symbol === "BTCUSDT") {
|
|
55226
|
-
return x.quantity <= 0.03;
|
|
55227
|
-
}
|
|
55228
|
-
return true;
|
|
55229
|
-
});
|
|
55230
|
-
return sorted.map((k, i2) => {
|
|
55231
|
-
const arrSet = sorted.slice(0, i2 + 1);
|
|
55232
|
-
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);
|
|
55233
|
-
return {
|
|
55234
|
-
...k,
|
|
55235
|
-
reverse_avg_entry: avg_values.price,
|
|
55236
|
-
reverse_avg_quantity: avg_values.quantity
|
|
55237
|
-
};
|
|
55238
|
-
});
|
|
55239
|
-
}
|
|
55240
|
-
function get_app_config_and_max_size(config2, payload) {
|
|
55241
|
-
const app_config = {
|
|
55242
|
-
kind: payload.kind,
|
|
55243
|
-
entry: payload.entry,
|
|
55244
|
-
stop: payload.stop,
|
|
55245
|
-
risk_per_trade: config2.risk,
|
|
55246
|
-
risk_reward: config2.risk_reward || 199,
|
|
55247
|
-
support: to_f(config2.support, config2.price_places),
|
|
55248
|
-
resistance: to_f(config2.resistance, config2.price_places),
|
|
55249
|
-
focus: payload.entry,
|
|
55250
|
-
fee: 0,
|
|
55251
|
-
percent_change: config2.stop_percent / 100,
|
|
55252
|
-
tradeSplit: 1,
|
|
55253
|
-
gap: 1,
|
|
55254
|
-
min_size: config2.min_size,
|
|
55255
|
-
budget: 0,
|
|
55256
|
-
price_places: config2.price_places,
|
|
55257
|
-
decimal_places: config2.decimal_places,
|
|
55258
|
-
min_profit: config2.profit_percent * config2.profit / 100
|
|
55259
|
-
};
|
|
55260
|
-
const initialResult = sortedBuildConfig(app_config, {
|
|
55261
|
-
entry: app_config.entry,
|
|
55262
|
-
stop: app_config.stop,
|
|
55263
|
-
kind: app_config.kind,
|
|
55264
|
-
risk: app_config.risk_per_trade,
|
|
55265
|
-
risk_reward: app_config.risk_reward,
|
|
55266
|
-
increase: true,
|
|
55267
|
-
gap: app_config.gap,
|
|
55268
|
-
price_places: app_config.price_places,
|
|
55269
|
-
decimal_places: app_config.decimal_places
|
|
55270
|
-
});
|
|
55271
|
-
const max_size = initialResult[0]?.avg_size;
|
|
55272
|
-
const last_value = initialResult[0];
|
|
55273
|
-
const entries = initialResult.map((x) => ({
|
|
55274
|
-
entry: x.entry,
|
|
55275
|
-
avg_entry: x.avg_entry,
|
|
55276
|
-
avg_size: x.avg_size,
|
|
55277
|
-
neg_pnl: x.neg_pnl,
|
|
55278
|
-
quantity: x.quantity
|
|
55279
|
-
}));
|
|
55280
|
-
return {
|
|
55281
|
-
app_config,
|
|
55282
|
-
max_size,
|
|
55283
|
-
last_value,
|
|
55284
|
-
entries
|
|
55285
|
-
};
|
|
55286
|
-
}
|
|
55287
|
-
function buildAppConfig(config2, payload) {
|
|
55288
|
-
const { app_config, max_size, last_value, entries } = get_app_config_and_max_size({
|
|
55289
|
-
...config2,
|
|
55290
|
-
risk: payload.risk,
|
|
55291
|
-
profit: payload.profit || 500,
|
|
55292
|
-
risk_reward: payload.risk_reward,
|
|
55293
|
-
accounts: [],
|
|
55294
|
-
reduce_percent: 90,
|
|
55295
|
-
reverse_factor: 1,
|
|
55296
|
-
profit_percent: 0,
|
|
55297
|
-
kind: payload.entry > payload.stop ? "long" : "short",
|
|
55298
|
-
symbol: payload.symbol
|
|
55299
|
-
}, {
|
|
55300
|
-
entry: payload.entry,
|
|
55301
|
-
stop: payload.stop,
|
|
55302
|
-
kind: payload.entry > payload.stop ? "long" : "short"
|
|
55303
|
-
});
|
|
55304
|
-
app_config.max_size = max_size;
|
|
55305
|
-
app_config.entry = payload.entry || app_config.entry;
|
|
55306
|
-
app_config.stop = payload.stop || app_config.stop;
|
|
55307
|
-
app_config.last_value = last_value;
|
|
55308
|
-
app_config.entries = entries;
|
|
55309
|
-
return app_config;
|
|
55310
|
-
}
|
|
55311
|
-
function getOptimumStopAndRisk(app_config, params) {
|
|
55312
|
-
const { max_size, target_stop } = params;
|
|
55313
|
-
const isLong = app_config.kind === "long";
|
|
55314
|
-
const stopRange = Math.abs(app_config.entry - target_stop) * 0.5;
|
|
55315
|
-
let low_stop = isLong ? target_stop - stopRange : Math.max(target_stop - stopRange, app_config.entry);
|
|
55316
|
-
let high_stop = isLong ? Math.min(target_stop + stopRange, app_config.entry) : target_stop + stopRange;
|
|
55317
|
-
let optimal_stop = target_stop;
|
|
55318
|
-
let best_stop_result = null;
|
|
55319
|
-
let best_entry_diff = Infinity;
|
|
55320
|
-
console.log(`Finding optimal stop for ${isLong ? "LONG" : "SHORT"} position. Target: ${target_stop}, Search range: ${low_stop} to ${high_stop}`);
|
|
55321
|
-
let iterations = 0;
|
|
55322
|
-
const MAX_ITERATIONS = 50;
|
|
55323
|
-
while (Math.abs(high_stop - low_stop) > 0.1 && iterations < MAX_ITERATIONS) {
|
|
55324
|
-
iterations++;
|
|
55325
|
-
const mid_stop = (low_stop + high_stop) / 2;
|
|
55326
|
-
const result = sortedBuildConfig(app_config, {
|
|
55327
|
-
entry: app_config.entry,
|
|
55328
|
-
stop: mid_stop,
|
|
55329
|
-
kind: app_config.kind,
|
|
55330
|
-
risk: app_config.risk_per_trade,
|
|
55331
|
-
risk_reward: app_config.risk_reward,
|
|
55332
|
-
increase: true,
|
|
55333
|
-
gap: app_config.gap,
|
|
55334
|
-
price_places: app_config.price_places,
|
|
55335
|
-
decimal_places: app_config.decimal_places
|
|
55336
|
-
});
|
|
55337
|
-
if (result.length === 0) {
|
|
55338
|
-
if (isLong) {
|
|
55339
|
-
low_stop = mid_stop;
|
|
55340
|
-
} else {
|
|
55341
|
-
high_stop = mid_stop;
|
|
55342
|
-
}
|
|
55343
|
-
continue;
|
|
55344
|
-
}
|
|
55345
|
-
const first_entry = result[0].entry;
|
|
55346
|
-
const entry_diff = Math.abs(first_entry - target_stop);
|
|
55347
|
-
console.log(`Stop: ${mid_stop.toFixed(2)}, First Entry: ${first_entry.toFixed(2)}, Diff: ${entry_diff.toFixed(2)}`);
|
|
55348
|
-
if (entry_diff < best_entry_diff) {
|
|
55349
|
-
best_entry_diff = entry_diff;
|
|
55350
|
-
optimal_stop = mid_stop;
|
|
55351
|
-
best_stop_result = result;
|
|
55352
|
-
}
|
|
55353
|
-
if (first_entry < target_stop) {
|
|
55354
|
-
if (isLong) {
|
|
55355
|
-
low_stop = mid_stop;
|
|
55356
|
-
} else {
|
|
55357
|
-
low_stop = mid_stop;
|
|
55358
|
-
}
|
|
55359
|
-
} else {
|
|
55360
|
-
if (isLong) {
|
|
55361
|
-
high_stop = mid_stop;
|
|
55362
|
-
} else {
|
|
55363
|
-
high_stop = mid_stop;
|
|
55364
|
-
}
|
|
55365
|
-
}
|
|
55366
|
-
if (entry_diff < 1)
|
|
55367
|
-
break;
|
|
55368
|
-
}
|
|
55369
|
-
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`);
|
|
55370
|
-
let low_risk = 10;
|
|
55371
|
-
let high_risk = params.highest_risk || 2000;
|
|
55372
|
-
let optimal_risk = app_config.risk_per_trade;
|
|
55373
|
-
let best_size_result = best_stop_result;
|
|
55374
|
-
let best_size_diff = Infinity;
|
|
55375
|
-
console.log(`Finding optimal risk_per_trade for size target: ${max_size} (never exceeding it)`);
|
|
55376
|
-
iterations = 0;
|
|
55377
|
-
while (Math.abs(high_risk - low_risk) > 0.1 && iterations < MAX_ITERATIONS) {
|
|
55378
|
-
iterations++;
|
|
55379
|
-
const mid_risk = (low_risk + high_risk) / 2;
|
|
55380
|
-
const result = sortedBuildConfig(app_config, {
|
|
55381
|
-
entry: app_config.entry,
|
|
55382
|
-
stop: optimal_stop,
|
|
55383
|
-
kind: app_config.kind,
|
|
55384
|
-
risk: mid_risk,
|
|
55385
|
-
risk_reward: app_config.risk_reward,
|
|
55386
|
-
increase: true,
|
|
55387
|
-
gap: app_config.gap,
|
|
55388
|
-
price_places: app_config.price_places,
|
|
55389
|
-
decimal_places: app_config.decimal_places
|
|
55390
|
-
});
|
|
55391
|
-
if (result.length === 0) {
|
|
55392
|
-
high_risk = mid_risk;
|
|
55393
|
-
continue;
|
|
55394
|
-
}
|
|
55395
|
-
const first_entry = result[0];
|
|
55396
|
-
const avg_size = first_entry.avg_size;
|
|
55397
|
-
console.log(`Risk: ${mid_risk.toFixed(2)}, Avg Size: ${avg_size.toFixed(4)}, Target: ${max_size}`);
|
|
55398
|
-
if (avg_size <= max_size) {
|
|
55399
|
-
const size_diff = max_size - avg_size;
|
|
55400
|
-
if (size_diff < best_size_diff) {
|
|
55401
|
-
best_size_diff = size_diff;
|
|
55402
|
-
optimal_risk = mid_risk;
|
|
55403
|
-
best_size_result = result;
|
|
55404
|
-
}
|
|
55405
|
-
low_risk = mid_risk;
|
|
55406
|
-
} else {
|
|
55407
|
-
high_risk = mid_risk;
|
|
55408
|
-
}
|
|
55409
|
-
if (best_size_diff < 0.001)
|
|
55410
|
-
break;
|
|
55411
|
-
}
|
|
55412
|
-
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`);
|
|
55413
|
-
let final_risk = optimal_risk;
|
|
55414
|
-
let final_result = best_size_result;
|
|
55415
|
-
if (best_size_result?.[0]?.avg_size < max_size) {
|
|
55416
|
-
console.log(`Current avg_size (${best_size_result?.[0].avg_size.toFixed(4)}) is less than target (${max_size}). Increasing risk to reach target...`);
|
|
55417
|
-
let current_risk = optimal_risk;
|
|
55418
|
-
const risk_increment = 5;
|
|
55419
|
-
iterations = 0;
|
|
55420
|
-
while (iterations < MAX_ITERATIONS) {
|
|
55421
|
-
iterations++;
|
|
55422
|
-
current_risk += risk_increment;
|
|
55423
|
-
if (current_risk > 5000)
|
|
55424
|
-
break;
|
|
55425
|
-
const result = sortedBuildConfig(app_config, {
|
|
55426
|
-
entry: app_config.entry,
|
|
55427
|
-
stop: optimal_stop,
|
|
55428
|
-
kind: app_config.kind,
|
|
55429
|
-
risk: current_risk,
|
|
55430
|
-
risk_reward: app_config.risk_reward,
|
|
55431
|
-
increase: true,
|
|
55432
|
-
gap: app_config.gap,
|
|
55433
|
-
price_places: app_config.price_places,
|
|
55434
|
-
decimal_places: app_config.decimal_places
|
|
55435
|
-
});
|
|
55436
|
-
if (result.length === 0)
|
|
55437
|
-
continue;
|
|
55438
|
-
const avg_size = result[0].avg_size;
|
|
55439
|
-
console.log(`Increased Risk: ${current_risk.toFixed(2)}, New Avg Size: ${avg_size.toFixed(4)}`);
|
|
55440
|
-
if (avg_size >= max_size) {
|
|
55441
|
-
final_risk = current_risk;
|
|
55442
|
-
final_result = result;
|
|
55443
|
-
console.log(`Target size reached! Final risk: ${final_risk.toFixed(2)}, Final avg_size: ${avg_size.toFixed(4)}`);
|
|
55444
|
-
break;
|
|
55445
|
-
}
|
|
55446
|
-
}
|
|
55447
|
-
}
|
|
55448
|
-
return {
|
|
55449
|
-
optimal_stop: to_f(optimal_stop, app_config.price_places),
|
|
55450
|
-
optimal_risk: to_f(final_risk, app_config.price_places),
|
|
55451
|
-
avg_size: final_result?.[0]?.avg_size || 0,
|
|
55452
|
-
avg_entry: final_result?.[0]?.avg_entry || 0,
|
|
55453
|
-
result: final_result,
|
|
55454
|
-
first_entry: final_result?.[0]?.entry || 0,
|
|
55455
|
-
neg_pnl: final_result?.[0]?.neg_pnl || 0,
|
|
55456
|
-
risk_reward: app_config.risk_reward,
|
|
55457
|
-
size_diff: Math.abs((final_result?.[0]?.avg_size || 0) - max_size),
|
|
55458
|
-
entry_diff: best_entry_diff
|
|
55459
|
-
};
|
|
55460
|
-
}
|
|
55461
|
-
function generate_config_params(app_config, payload) {
|
|
55462
|
-
const { result, ...optimum } = getOptimumStopAndRisk(app_config, {
|
|
55463
|
-
max_size: app_config.max_size,
|
|
55464
|
-
highest_risk: payload.risk * 2,
|
|
55465
|
-
target_stop: app_config.stop
|
|
55466
|
-
});
|
|
55467
|
-
return {
|
|
55468
|
-
entry: payload.entry,
|
|
55469
|
-
stop: optimum.optimal_stop,
|
|
55470
|
-
avg_size: optimum.avg_size,
|
|
55471
|
-
avg_entry: optimum.avg_entry,
|
|
55472
|
-
risk_reward: payload.risk_reward,
|
|
55473
|
-
neg_pnl: optimum.neg_pnl,
|
|
55474
|
-
risk: payload.risk
|
|
55475
|
-
};
|
|
55476
|
-
}
|
|
55477
|
-
function determine_break_even_price(payload) {
|
|
55478
|
-
const { long_position, short_position, fee_percent = 0.05 / 100 } = payload;
|
|
55479
|
-
const long_notional = long_position.entry * long_position.quantity;
|
|
55480
|
-
const short_notional = short_position.entry * short_position.quantity;
|
|
55481
|
-
const net_quantity = long_position.quantity - short_position.quantity;
|
|
55482
|
-
const net_capital = Math.abs(long_notional - short_notional);
|
|
55483
|
-
const break_even_price = net_capital / (Math.abs(net_quantity) + fee_percent * Math.abs(net_quantity));
|
|
55484
|
-
return {
|
|
55485
|
-
price: break_even_price,
|
|
55486
|
-
direction: net_quantity > 0 ? "long" : "short"
|
|
55487
|
-
};
|
|
55488
|
-
}
|
|
55489
|
-
function determine_amount_to_buy(payload) {
|
|
55490
|
-
const {
|
|
55491
|
-
orders,
|
|
55492
|
-
kind,
|
|
55493
|
-
decimal_places = "%.3f",
|
|
55494
|
-
position: position2,
|
|
55495
|
-
existingOrders
|
|
55496
|
-
} = payload;
|
|
55497
|
-
const totalQuantity = orders.reduce((sum, order) => sum + (order.quantity || 0), 0);
|
|
55498
|
-
let runningTotal = to_f(totalQuantity, decimal_places);
|
|
55499
|
-
let sortedOrders = [...orders].sort((a, b) => (a.entry || 0) - (b.entry || 0));
|
|
55500
|
-
if (kind === "short") {
|
|
55501
|
-
sortedOrders.reverse();
|
|
55502
|
-
}
|
|
55503
|
-
const withCumulative = [];
|
|
55504
|
-
for (const order of sortedOrders) {
|
|
55505
|
-
withCumulative.push({
|
|
55506
|
-
...order,
|
|
55507
|
-
cumulative_quantity: runningTotal
|
|
55508
|
-
});
|
|
55509
|
-
runningTotal -= order.quantity;
|
|
55510
|
-
runningTotal = to_f(runningTotal, decimal_places);
|
|
55775
|
+
const pnl = (current_price - position2.entry) * position2.quantity;
|
|
55776
|
+
const orders = account.orders[kind].entries;
|
|
55777
|
+
const side = kind === "long" ? "buy" : "sell";
|
|
55778
|
+
let limit_orders = orders.filter((order) => order.stop === 0 && order.side === side).filter((o) => {
|
|
55779
|
+
if (kind === "long" && pnl < 0 && Math.abs(pnl) > minimum_pnl) {
|
|
55780
|
+
return true;
|
|
55781
|
+
}
|
|
55782
|
+
if (kind === "short" && pnl > 0 && Math.abs(pnl) > minimum_pnl) {
|
|
55783
|
+
return true;
|
|
55784
|
+
}
|
|
55785
|
+
return false;
|
|
55786
|
+
});
|
|
55787
|
+
if (limit_orders.length > 1) {
|
|
55788
|
+
limit_orders = [limit_orders[limit_orders.length - 1]];
|
|
55511
55789
|
}
|
|
55512
|
-
|
|
55513
|
-
|
|
55514
|
-
|
|
55790
|
+
return limit_orders.map((o) => ({ ...o, id: o.order_id }));
|
|
55791
|
+
}
|
|
55792
|
+
function processPosition(codeNode, input, kind) {
|
|
55793
|
+
const { active_account, current_price } = input;
|
|
55794
|
+
const { use_full = false } = codeNode;
|
|
55795
|
+
const long_position = active_account.position.long;
|
|
55796
|
+
const short_position = active_account.position.short;
|
|
55797
|
+
const vv = calculateHedge({
|
|
55515
55798
|
kind,
|
|
55516
|
-
|
|
55517
|
-
|
|
55518
|
-
|
|
55519
|
-
|
|
55799
|
+
active_account,
|
|
55800
|
+
targetPnl: codeNode.profit || 50,
|
|
55801
|
+
ratio: codeNode.ratio,
|
|
55802
|
+
use_full,
|
|
55803
|
+
not_reduce: codeNode.not_reduce,
|
|
55804
|
+
sell_ratio: codeNode.sell_ratio
|
|
55805
|
+
});
|
|
55806
|
+
const reverse_kind = kind === "long" ? "short" : "long";
|
|
55807
|
+
const a_stops = findStopOrders(reverse_kind, active_account);
|
|
55808
|
+
const a_limits = findEntryLimitOrders(reverse_kind, active_account, current_price, codeNode.minimum_pnl).filter((u) => codeNode.increase);
|
|
55809
|
+
const orders_to_cancel = a_limits.concat(a_stops);
|
|
55810
|
+
return {
|
|
55811
|
+
exchange: input.exchange,
|
|
55812
|
+
result: vv,
|
|
55813
|
+
to_place: {
|
|
55814
|
+
...vv[reverse_kind],
|
|
55815
|
+
kind: reverse_kind,
|
|
55816
|
+
side: reverse_kind === "long" ? "buy" : "sell"
|
|
55817
|
+
},
|
|
55818
|
+
orders_to_cancel,
|
|
55819
|
+
stop: to_f2(vv[kind].price, active_account.price_places),
|
|
55820
|
+
quantity: vv[kind].quantity,
|
|
55821
|
+
kind,
|
|
55822
|
+
type: JSON.stringify("TAKE_PROFIT"),
|
|
55823
|
+
id: active_account.id,
|
|
55824
|
+
position: kind === "long" ? long_position : short_position,
|
|
55825
|
+
opposite_position: kind === "long" ? short_position : long_position,
|
|
55826
|
+
long_position,
|
|
55827
|
+
short_position,
|
|
55828
|
+
owner: active_account.owner,
|
|
55829
|
+
risk: codeNode.profit || 150,
|
|
55830
|
+
increase: codeNode.increase,
|
|
55831
|
+
not_reduce: codeNode.not_reduce,
|
|
55832
|
+
price_places: active_account.price_places,
|
|
55833
|
+
decimal_places: active_account.decimal_places
|
|
55834
|
+
};
|
|
55520
55835
|
}
|
|
55521
|
-
function
|
|
55522
|
-
|
|
55523
|
-
|
|
55524
|
-
|
|
55525
|
-
|
|
55526
|
-
const tolerance = 0.1;
|
|
55527
|
-
const max_iterations = 150;
|
|
55528
|
-
let iterations = 0;
|
|
55529
|
-
console.log(`Starting risk search for ${position2.kind} position. Target Entry: ${position2.entry}, Initial Risk Range: [${low_risk}, ${high_risk}]`);
|
|
55530
|
-
while (high_risk - low_risk > tolerance && iterations < max_iterations) {
|
|
55531
|
-
iterations++;
|
|
55532
|
-
const mid_risk = (low_risk + high_risk) / 2;
|
|
55533
|
-
const {
|
|
55534
|
-
app_config: current_app_config,
|
|
55535
|
-
max_size,
|
|
55536
|
-
last_value,
|
|
55537
|
-
entries
|
|
55538
|
-
} = get_app_config_and_max_size({
|
|
55539
|
-
...config2,
|
|
55540
|
-
risk: mid_risk,
|
|
55541
|
-
profit_percent: config2.profit_percent || 0,
|
|
55542
|
-
profit: config2.profit || 500,
|
|
55543
|
-
risk_reward: payload.risk_reward,
|
|
55544
|
-
kind: position2.kind,
|
|
55545
|
-
price_places: config2.price_places,
|
|
55546
|
-
decimal_places: config2.decimal_places,
|
|
55547
|
-
accounts: config2.accounts || [],
|
|
55548
|
-
reduce_percent: config2.reduce_percent || 90,
|
|
55549
|
-
reverse_factor: config2.reverse_factor || 1,
|
|
55550
|
-
symbol: config2.symbol || "",
|
|
55551
|
-
support: config2.support || 0,
|
|
55552
|
-
resistance: config2.resistance || 0,
|
|
55553
|
-
min_size: config2.min_size || 0,
|
|
55554
|
-
stop_percent: config2.stop_percent || 0
|
|
55555
|
-
}, {
|
|
55556
|
-
entry: payload.entry,
|
|
55557
|
-
stop: payload.stop,
|
|
55558
|
-
kind: position2.kind
|
|
55559
|
-
});
|
|
55560
|
-
current_app_config.max_size = max_size;
|
|
55561
|
-
current_app_config.last_value = last_value;
|
|
55562
|
-
current_app_config.entries = entries;
|
|
55563
|
-
current_app_config.risk_reward = payload.risk_reward;
|
|
55564
|
-
const full_trades = sortedBuildConfig(current_app_config, {
|
|
55565
|
-
entry: current_app_config.entry,
|
|
55566
|
-
stop: current_app_config.stop,
|
|
55567
|
-
kind: current_app_config.kind,
|
|
55568
|
-
risk: current_app_config.risk_per_trade,
|
|
55569
|
-
risk_reward: current_app_config.risk_reward,
|
|
55570
|
-
increase: true,
|
|
55571
|
-
gap: current_app_config.gap,
|
|
55572
|
-
price_places: current_app_config.price_places,
|
|
55573
|
-
decimal_places: current_app_config.decimal_places
|
|
55574
|
-
});
|
|
55575
|
-
console.log(`Iteration ${iterations}: Risk=${mid_risk.toFixed(2)}, Low=${low_risk.toFixed(2)}, High=${high_risk.toFixed(2)}`);
|
|
55576
|
-
if (full_trades.length === 0) {
|
|
55577
|
-
console.log(` -> No trades generated by sortedBuildConfig at Risk=${mid_risk.toFixed(2)}. Adjusting high_risk down.`);
|
|
55578
|
-
high_risk = mid_risk;
|
|
55579
|
-
continue;
|
|
55836
|
+
async function reduceMajorPositionCalculation(input, exchange_instance) {
|
|
55837
|
+
try {
|
|
55838
|
+
let conditionsCheck = input.position.tp_quantity !== input.quantity || input.position.take_profit !== to_f2(input.stop, input.price_places);
|
|
55839
|
+
if (!isNaN(input.opposite_position.stop_quantity) && input.opposite_position.stop_quantity > -1) {
|
|
55840
|
+
conditionsCheck = conditionsCheck || input.opposite_position.stop_quantity !== input.to_place.quantity;
|
|
55580
55841
|
}
|
|
55581
|
-
|
|
55582
|
-
|
|
55583
|
-
|
|
55584
|
-
|
|
55585
|
-
|
|
55586
|
-
|
|
55587
|
-
|
|
55842
|
+
console.log("conditionsCheck for ", input.position.kind, conditionsCheck);
|
|
55843
|
+
const sell_quantity = input.result[input.position.kind].quantity;
|
|
55844
|
+
console.log("opposite_check", {
|
|
55845
|
+
kind: input.opposite_position.kind,
|
|
55846
|
+
stop_loss: input.opposite_position.stop_loss,
|
|
55847
|
+
stop_price: input.to_place.stop_price,
|
|
55848
|
+
owner: input.owner,
|
|
55849
|
+
not_reduce: input.to_place,
|
|
55850
|
+
result: input.result,
|
|
55851
|
+
stop_to_place: {
|
|
55852
|
+
owner: input.owner,
|
|
55853
|
+
symbol: input.position.symbol,
|
|
55854
|
+
kind: input.to_place.kind,
|
|
55855
|
+
stop: input.to_place.stop_price,
|
|
55856
|
+
quantity: Math.abs(input.to_place.quantity)
|
|
55857
|
+
},
|
|
55858
|
+
sell_quantity
|
|
55588
55859
|
});
|
|
55589
|
-
if (
|
|
55590
|
-
|
|
55591
|
-
|
|
55592
|
-
|
|
55593
|
-
|
|
55594
|
-
|
|
55595
|
-
|
|
55596
|
-
|
|
55597
|
-
|
|
55598
|
-
|
|
55599
|
-
|
|
55600
|
-
|
|
55601
|
-
}
|
|
55602
|
-
|
|
55603
|
-
|
|
55604
|
-
|
|
55605
|
-
|
|
55606
|
-
|
|
55860
|
+
if (conditionsCheck) {
|
|
55861
|
+
const async_tp = async () => {
|
|
55862
|
+
if (input.stop && input.stop !== Infinity) {
|
|
55863
|
+
await exchange_instance.placeTpOrder({
|
|
55864
|
+
symbol: input.position.symbol,
|
|
55865
|
+
kind: input.kind,
|
|
55866
|
+
quantity: sell_quantity,
|
|
55867
|
+
take_profit: input.stop,
|
|
55868
|
+
price_places: input.price_places,
|
|
55869
|
+
decimal_places: input.decimal_places
|
|
55870
|
+
});
|
|
55871
|
+
}
|
|
55872
|
+
};
|
|
55873
|
+
const async_increase = async () => {
|
|
55874
|
+
if (input.increase && input.to_place.stop_price) {
|
|
55875
|
+
await exchange_instance.placeLimitOrder({
|
|
55876
|
+
symbol: input.position.symbol,
|
|
55877
|
+
kind: input.to_place.kind,
|
|
55878
|
+
price: input.to_place.stop_price,
|
|
55879
|
+
quantity: input.to_place.quantity,
|
|
55880
|
+
price_places: input.price_places,
|
|
55881
|
+
decimal_places: input.decimal_places
|
|
55882
|
+
}).then((r2) => {
|
|
55883
|
+
console.log("placeNewOrderData", r2);
|
|
55884
|
+
});
|
|
55885
|
+
}
|
|
55886
|
+
};
|
|
55887
|
+
let placeNewOrderData = null;
|
|
55888
|
+
const async_place_stop = async () => {
|
|
55889
|
+
if (!input.not_reduce && input.to_place.stop_price && input.to_place.quantity) {
|
|
55890
|
+
await exchange_instance.placeStopOrder({
|
|
55891
|
+
symbol: input.position.symbol,
|
|
55892
|
+
kind: input.to_place.kind,
|
|
55893
|
+
stop: input.to_place.stop_price,
|
|
55894
|
+
quantity: Math.abs(input.to_place.quantity),
|
|
55895
|
+
price_places: input.price_places,
|
|
55896
|
+
decimal_places: input.decimal_places
|
|
55897
|
+
});
|
|
55898
|
+
}
|
|
55899
|
+
};
|
|
55900
|
+
const [_tp, _increase, _place_stop] = await Promise.all([
|
|
55901
|
+
async_tp(),
|
|
55902
|
+
async_increase(),
|
|
55903
|
+
async_place_stop()
|
|
55904
|
+
]);
|
|
55905
|
+
return {
|
|
55906
|
+
newOrderResponse: placeNewOrderData
|
|
55907
|
+
};
|
|
55607
55908
|
} else {
|
|
55608
|
-
|
|
55609
|
-
|
|
55610
|
-
|
|
55611
|
-
}
|
|
55612
|
-
console.log(` -> Constraint MET (Short): last_entry (${last_entry.toFixed(4)}) >= position.entry (${position2.entry.toFixed(4)}). Storing as best, increasing low_risk.`);
|
|
55613
|
-
best_risk = mid_risk;
|
|
55614
|
-
best_app_config = current_app_config;
|
|
55615
|
-
low_risk = mid_risk;
|
|
55616
|
-
}
|
|
55909
|
+
return {
|
|
55910
|
+
message: "No changes needed, conditions not met",
|
|
55911
|
+
input
|
|
55912
|
+
};
|
|
55617
55913
|
}
|
|
55914
|
+
} catch (error) {
|
|
55915
|
+
console.error("Error in reduceMajorPositionCalculation:", error);
|
|
55916
|
+
throw error;
|
|
55618
55917
|
}
|
|
55619
|
-
|
|
55620
|
-
|
|
55621
|
-
|
|
55622
|
-
|
|
55623
|
-
|
|
55624
|
-
|
|
55625
|
-
|
|
55626
|
-
|
|
55627
|
-
|
|
55918
|
+
}
|
|
55919
|
+
async function reduceMajorPositionEntry(input, accountInfo, trigger2, exchange_instance) {
|
|
55920
|
+
let results = {};
|
|
55921
|
+
try {
|
|
55922
|
+
const async_long = async () => {
|
|
55923
|
+
if (input.long) {
|
|
55924
|
+
const workflowInput = processPosition(input.long, accountInfo, "long");
|
|
55925
|
+
if (trigger2.long) {
|
|
55926
|
+
try {
|
|
55927
|
+
await reduceMajorPositionCalculation(workflowInput, exchange_instance);
|
|
55928
|
+
} catch (error) {
|
|
55929
|
+
console.error("Error in reduceMajorPositionCalculation:", error);
|
|
55930
|
+
}
|
|
55931
|
+
}
|
|
55932
|
+
return workflowInput;
|
|
55933
|
+
}
|
|
55934
|
+
return null;
|
|
55935
|
+
};
|
|
55936
|
+
const async_short = async () => {
|
|
55937
|
+
if (input.short) {
|
|
55938
|
+
const workflowInput = processPosition(input.short, accountInfo, "short");
|
|
55939
|
+
if (trigger2.short) {
|
|
55940
|
+
try {
|
|
55941
|
+
await reduceMajorPositionCalculation(workflowInput, exchange_instance);
|
|
55942
|
+
} catch (error) {
|
|
55943
|
+
console.error("Error in reduceMajorPositionCalculation:", error);
|
|
55944
|
+
}
|
|
55945
|
+
}
|
|
55946
|
+
return workflowInput;
|
|
55947
|
+
}
|
|
55948
|
+
return null;
|
|
55949
|
+
};
|
|
55950
|
+
const [long, short] = await Promise.all([async_long(), async_short()]);
|
|
55951
|
+
results.long = long;
|
|
55952
|
+
results.short = short;
|
|
55953
|
+
return results;
|
|
55954
|
+
} catch (error) {
|
|
55955
|
+
console.error("Error in reduceMajorPositionEntry:", error);
|
|
55956
|
+
throw error;
|
|
55628
55957
|
}
|
|
55629
|
-
best_app_config.entries = determine_amount_to_buy({
|
|
55630
|
-
orders: best_app_config.entries,
|
|
55631
|
-
kind: position2.kind,
|
|
55632
|
-
decimal_places: best_app_config.decimal_places,
|
|
55633
|
-
price_places: best_app_config.price_places,
|
|
55634
|
-
position: position2,
|
|
55635
|
-
existingOrders: []
|
|
55636
|
-
});
|
|
55637
|
-
return best_app_config;
|
|
55638
55958
|
}
|
|
55639
55959
|
|
|
55640
55960
|
// src/position.ts
|
|
@@ -55711,7 +56031,7 @@ class ExchangePosition {
|
|
|
55711
56031
|
let _profit = config2.profit;
|
|
55712
56032
|
let _profit_percent = config2?.profit_percent;
|
|
55713
56033
|
if (_profit_percent && (position2?.quantity || 0) > 0) {
|
|
55714
|
-
_profit =
|
|
56034
|
+
_profit = to_f2(position2.quantity * _profit_percent * position2.entry / 100);
|
|
55715
56035
|
}
|
|
55716
56036
|
await this.app_db.update_db_position(position2, {
|
|
55717
56037
|
target_pnl: _profit
|
|
@@ -55930,7 +56250,7 @@ class ExchangePosition {
|
|
|
55930
56250
|
async determineAmountToBuy(payload) {
|
|
55931
56251
|
const { orders, kind, decimal_places = "%.3f", refresh, cancel } = payload;
|
|
55932
56252
|
const totalQuantity = orders.reduce((sum, order) => sum + (order.quantity || 0), 0);
|
|
55933
|
-
let runningTotal =
|
|
56253
|
+
let runningTotal = to_f2(totalQuantity, decimal_places);
|
|
55934
56254
|
let sortedOrders = [...orders].sort((a, b) => (a.entry || 0) - (b.entry || 0));
|
|
55935
56255
|
if (kind === "short") {
|
|
55936
56256
|
sortedOrders.reverse();
|
|
@@ -55942,7 +56262,7 @@ class ExchangePosition {
|
|
|
55942
56262
|
cumulative_quantity: runningTotal
|
|
55943
56263
|
});
|
|
55944
56264
|
runningTotal -= order.quantity;
|
|
55945
|
-
runningTotal =
|
|
56265
|
+
runningTotal = to_f2(runningTotal, decimal_places);
|
|
55946
56266
|
}
|
|
55947
56267
|
const { instance: position2, existingOrders } = await this.refresh(refresh);
|
|
55948
56268
|
let filteredOrders = withCumulative.filter((order) => (order.cumulative_quantity || 0) > position2?.quantity).map((order) => ({
|
|
@@ -56264,6 +56584,21 @@ class ExchangeAccount {
|
|
|
56264
56584
|
}
|
|
56265
56585
|
return app_config;
|
|
56266
56586
|
}
|
|
56587
|
+
async tradeConfig(payload) {
|
|
56588
|
+
const { symbol, kind } = payload;
|
|
56589
|
+
const config2 = await this.getPositionConfig({
|
|
56590
|
+
symbol,
|
|
56591
|
+
kind
|
|
56592
|
+
});
|
|
56593
|
+
const app_config = await this.buildAppConfig({
|
|
56594
|
+
entry: config2.entry,
|
|
56595
|
+
stop: config2.stop,
|
|
56596
|
+
risk_reward: config2.risk_reward,
|
|
56597
|
+
risk: config2.risk,
|
|
56598
|
+
symbol
|
|
56599
|
+
});
|
|
56600
|
+
return app_config;
|
|
56601
|
+
}
|
|
56267
56602
|
async buildTrades(payload) {
|
|
56268
56603
|
const { symbol, kind, risk } = payload;
|
|
56269
56604
|
const config2 = await this.getPositionConfig({
|
|
@@ -56400,7 +56735,7 @@ class ExchangeAccount {
|
|
|
56400
56735
|
cancel
|
|
56401
56736
|
} = payload;
|
|
56402
56737
|
const totalQuantity = orders.reduce((sum, order) => sum + (order.quantity || 0), 0);
|
|
56403
|
-
let runningTotal =
|
|
56738
|
+
let runningTotal = to_f2(totalQuantity, decimal_places);
|
|
56404
56739
|
let sortedOrders = [...orders].sort((a, b) => (a.entry || 0) - (b.entry || 0));
|
|
56405
56740
|
if (kind === "short") {
|
|
56406
56741
|
sortedOrders.reverse();
|
|
@@ -56412,7 +56747,7 @@ class ExchangeAccount {
|
|
|
56412
56747
|
cumulative_quantity: runningTotal
|
|
56413
56748
|
});
|
|
56414
56749
|
runningTotal -= order.quantity;
|
|
56415
|
-
runningTotal =
|
|
56750
|
+
runningTotal = to_f2(runningTotal, decimal_places);
|
|
56416
56751
|
}
|
|
56417
56752
|
const position2 = await this.syncAccount({
|
|
56418
56753
|
symbol,
|
|
@@ -56591,6 +56926,8 @@ class ExchangeAccount {
|
|
|
56591
56926
|
const positions = await this.syncAccount({
|
|
56592
56927
|
symbol: payload.symbol
|
|
56593
56928
|
});
|
|
56929
|
+
const long_position = positions.find((x) => x.kind === "long");
|
|
56930
|
+
const short_position = positions.find((x) => x.kind === "short");
|
|
56594
56931
|
const config2 = build_reduce_config({
|
|
56595
56932
|
account: this.instance,
|
|
56596
56933
|
symbol: payload.symbol,
|
|
@@ -56605,7 +56942,8 @@ class ExchangeAccount {
|
|
|
56605
56942
|
increase: false,
|
|
56606
56943
|
not_reduce: config2?.not_reduce,
|
|
56607
56944
|
ratio: config2?.reduce_ratio_long,
|
|
56608
|
-
use_full: payload.use_full ? payload.kind == "long" ? true : false : undefined
|
|
56945
|
+
use_full: payload.use_full ? payload.kind == "long" ? true : false : undefined,
|
|
56946
|
+
sell_ratio: long_position?.sell_ratio
|
|
56609
56947
|
},
|
|
56610
56948
|
short: {
|
|
56611
56949
|
minimum_pnl: config2?.short_minimum_pnl || 0.0001,
|
|
@@ -56614,7 +56952,8 @@ class ExchangeAccount {
|
|
|
56614
56952
|
increase: false,
|
|
56615
56953
|
not_reduce: config2?.not_reduce,
|
|
56616
56954
|
ratio: config2?.reduce_ratio_short,
|
|
56617
|
-
use_full: payload.use_full ? payload.kind == "short" ? true : false : undefined
|
|
56955
|
+
use_full: payload.use_full ? payload.kind == "short" ? true : false : undefined,
|
|
56956
|
+
sell_ratio: short_position?.sell_ratio
|
|
56618
56957
|
},
|
|
56619
56958
|
trigger: {
|
|
56620
56959
|
long: payload.trigger?.long ? config2.trigger_long : false,
|
|
@@ -57135,7 +57474,7 @@ class ExchangeAccount {
|
|
|
57135
57474
|
let _profit = config2.profit;
|
|
57136
57475
|
let _profit_percent = config2?.profit_percent;
|
|
57137
57476
|
if (_profit_percent && (position2?.quantity || 0) > 0) {
|
|
57138
|
-
_profit =
|
|
57477
|
+
_profit = to_f2(position2.quantity * _profit_percent * position2.entry / 100);
|
|
57139
57478
|
}
|
|
57140
57479
|
await this.app_db.update_db_position(position2, {
|
|
57141
57480
|
target_pnl: _profit
|
|
@@ -57144,6 +57483,45 @@ class ExchangeAccount {
|
|
|
57144
57483
|
}
|
|
57145
57484
|
return 0;
|
|
57146
57485
|
}
|
|
57486
|
+
async runSimulation(payload) {
|
|
57487
|
+
const { symbol, kind, iterations = 2, raw = false } = payload;
|
|
57488
|
+
const positions = await this.syncAccount({
|
|
57489
|
+
symbol
|
|
57490
|
+
});
|
|
57491
|
+
const symbol_config = await this.recomputeSymbolConfig({
|
|
57492
|
+
symbol
|
|
57493
|
+
});
|
|
57494
|
+
const long_position = positions.find((x) => x.kind === "long");
|
|
57495
|
+
const short_position = positions.find((x) => x.kind === "short");
|
|
57496
|
+
const strategy_instance = await this.getPositionStrategy();
|
|
57497
|
+
const strategy_config = {
|
|
57498
|
+
tp_percent: strategy_instance?.tp_percent,
|
|
57499
|
+
short_tp_factor: strategy_instance?.short_tp_factor,
|
|
57500
|
+
fee_percent: strategy_instance?.fee_percent,
|
|
57501
|
+
budget: strategy_instance?.budget,
|
|
57502
|
+
risk_reward: strategy_instance?.risk_reward,
|
|
57503
|
+
reduce_ratio: strategy_instance?.reduce_ratio,
|
|
57504
|
+
global_config: symbol_config
|
|
57505
|
+
};
|
|
57506
|
+
const strategy = new Strategy({
|
|
57507
|
+
long: {
|
|
57508
|
+
entry: long_position.entry,
|
|
57509
|
+
quantity: long_position.quantity
|
|
57510
|
+
},
|
|
57511
|
+
short: {
|
|
57512
|
+
entry: short_position.entry,
|
|
57513
|
+
quantity: short_position.quantity
|
|
57514
|
+
},
|
|
57515
|
+
config: strategy_config
|
|
57516
|
+
});
|
|
57517
|
+
if (raw) {
|
|
57518
|
+
return strategy;
|
|
57519
|
+
}
|
|
57520
|
+
return strategy.runIterations({
|
|
57521
|
+
iterations,
|
|
57522
|
+
kind
|
|
57523
|
+
});
|
|
57524
|
+
}
|
|
57147
57525
|
async getCurrentRun(payload) {
|
|
57148
57526
|
const { symbol, kind = "long", pnl } = payload;
|
|
57149
57527
|
const instances = await this.app_db.pb.collection("strategy_runs").getFullList({
|
|
@@ -57668,7 +58046,7 @@ class ExchangeAccount {
|
|
|
57668
58046
|
if (reverse_position?.expand?.config && root_position.quantity > 0) {
|
|
57669
58047
|
const reverse_config = reverse_position.expand.config;
|
|
57670
58048
|
const diff = Math.abs(reverse_config.stop - root_position.entry);
|
|
57671
|
-
const result =
|
|
58049
|
+
const result = to_f2(diff * root_position.quantity);
|
|
57672
58050
|
if (root_position.target_pnl !== result) {
|
|
57673
58051
|
await this.app_db.update_db_position(root_position, {
|
|
57674
58052
|
target_pnl: result
|
|
@@ -57873,12 +58251,12 @@ class App {
|
|
|
57873
58251
|
const balance = active_account.usd_balance || 0;
|
|
57874
58252
|
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;
|
|
57875
58253
|
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;
|
|
57876
|
-
long_position.avg_liquidation =
|
|
57877
|
-
short_position.avg_liquidation =
|
|
58254
|
+
long_position.avg_liquidation = to_f2(long_liquidation, "%.3f");
|
|
58255
|
+
short_position.avg_liquidation = to_f2(short_liquidation, "%.3f");
|
|
57878
58256
|
const long_ratio = Math.max(long_position.avg_liquidation, long_position.avg_entry) / Math.min(long_position.avg_liquidation, long_position.avg_entry) - 1;
|
|
57879
58257
|
const short_ratio = Math.max(short_position.avg_liquidation, short_position.avg_entry) / Math.min(short_position.avg_liquidation, short_position.avg_entry) - 1;
|
|
57880
|
-
long_position.liquidation_ratio =
|
|
57881
|
-
short_position.liquidation_ratio =
|
|
58258
|
+
long_position.liquidation_ratio = to_f2(long_ratio, "%.3f") * 100;
|
|
58259
|
+
short_position.liquidation_ratio = to_f2(short_ratio, "%.3f") * 100;
|
|
57882
58260
|
return {
|
|
57883
58261
|
long_position,
|
|
57884
58262
|
short_position,
|
|
@@ -58185,211 +58563,3 @@ async function initialize(payload) {
|
|
|
58185
58563
|
});
|
|
58186
58564
|
return app;
|
|
58187
58565
|
}
|
|
58188
|
-
// src/helpers/strategy.ts
|
|
58189
|
-
class Strategy {
|
|
58190
|
-
position;
|
|
58191
|
-
config;
|
|
58192
|
-
constructor(payload) {
|
|
58193
|
-
this.position = {
|
|
58194
|
-
long: payload.long,
|
|
58195
|
-
short: payload.short
|
|
58196
|
-
};
|
|
58197
|
-
this.config = payload.config;
|
|
58198
|
-
if (!this.config.fee_percent) {
|
|
58199
|
-
this.config.fee_percent = 0.05;
|
|
58200
|
-
}
|
|
58201
|
-
}
|
|
58202
|
-
get price_places() {
|
|
58203
|
-
return this.config.global_config.price_places;
|
|
58204
|
-
}
|
|
58205
|
-
get decimal_places() {
|
|
58206
|
-
return this.config.global_config.decimal_places;
|
|
58207
|
-
}
|
|
58208
|
-
to_f(price) {
|
|
58209
|
-
return to_f(price, this.price_places);
|
|
58210
|
-
}
|
|
58211
|
-
to_df(quantity) {
|
|
58212
|
-
return to_f(quantity, this.decimal_places);
|
|
58213
|
-
}
|
|
58214
|
-
pnl(kind) {
|
|
58215
|
-
const position2 = this.position[kind];
|
|
58216
|
-
const { entry, quantity } = position2;
|
|
58217
|
-
const notional = entry * quantity;
|
|
58218
|
-
let tp_percent = this.config.tp_percent;
|
|
58219
|
-
if (kind == "short") {
|
|
58220
|
-
tp_percent = tp_percent * this.config.short_tp_factor;
|
|
58221
|
-
}
|
|
58222
|
-
const profit = notional * (tp_percent / 100);
|
|
58223
|
-
return this.to_f(profit);
|
|
58224
|
-
}
|
|
58225
|
-
tp(kind) {
|
|
58226
|
-
const position2 = this.position[kind];
|
|
58227
|
-
const { entry, quantity } = position2;
|
|
58228
|
-
const profit = this.pnl(kind);
|
|
58229
|
-
const diff = profit / quantity;
|
|
58230
|
-
return this.to_f(kind == "long" ? entry + diff : entry - diff);
|
|
58231
|
-
}
|
|
58232
|
-
calculate_fee(position2) {
|
|
58233
|
-
const { price, quantity } = position2;
|
|
58234
|
-
const fee = price * quantity * this.config.fee_percent / 100;
|
|
58235
|
-
return this.to_f(fee);
|
|
58236
|
-
}
|
|
58237
|
-
get long_tp() {
|
|
58238
|
-
return this.tp("long");
|
|
58239
|
-
}
|
|
58240
|
-
get short_tp() {
|
|
58241
|
-
return this.tp("short");
|
|
58242
|
-
}
|
|
58243
|
-
generateGapClosingAlgorithm(payload) {
|
|
58244
|
-
const { kind } = payload;
|
|
58245
|
-
const { entry, quantity } = this.position[kind];
|
|
58246
|
-
const focus_position = this.position[kind];
|
|
58247
|
-
const reverse_kind = kind == "long" ? "short" : "long";
|
|
58248
|
-
const reverse_position = this.position[reverse_kind];
|
|
58249
|
-
let _entry = this.tp(kind);
|
|
58250
|
-
let _stop = this.tp(reverse_kind);
|
|
58251
|
-
if (!_entry && !_stop) {
|
|
58252
|
-
return null;
|
|
58253
|
-
}
|
|
58254
|
-
const second_payload = {
|
|
58255
|
-
entry: _entry,
|
|
58256
|
-
stop: _stop,
|
|
58257
|
-
risk_reward: this.config.risk_reward,
|
|
58258
|
-
start_risk: this.pnl(reverse_kind),
|
|
58259
|
-
max_risk: this.config.budget
|
|
58260
|
-
};
|
|
58261
|
-
const third_payload = {
|
|
58262
|
-
entry,
|
|
58263
|
-
quantity,
|
|
58264
|
-
kind
|
|
58265
|
-
};
|
|
58266
|
-
console.log({ second_payload, third_payload });
|
|
58267
|
-
const app_config = generateOptimumAppConfig(this.config.global_config, second_payload, third_payload);
|
|
58268
|
-
if (!app_config) {
|
|
58269
|
-
return null;
|
|
58270
|
-
}
|
|
58271
|
-
const { entries, ...rest } = app_config;
|
|
58272
|
-
const risk = this.to_f(rest.risk_per_trade);
|
|
58273
|
-
const adjusted_focus_entries = entries.map((entry2) => {
|
|
58274
|
-
let adjusted_price = entry2.price;
|
|
58275
|
-
if (focus_position.quantity > 0) {
|
|
58276
|
-
if (kind === "long" && entry2.price >= focus_position.entry) {
|
|
58277
|
-
adjusted_price = focus_position.entry;
|
|
58278
|
-
} else if (kind === "short" && entry2.price <= focus_position.entry) {
|
|
58279
|
-
adjusted_price = focus_position.entry;
|
|
58280
|
-
}
|
|
58281
|
-
}
|
|
58282
|
-
return {
|
|
58283
|
-
price: adjusted_price,
|
|
58284
|
-
quantity: entry2.quantity
|
|
58285
|
-
};
|
|
58286
|
-
});
|
|
58287
|
-
const avg = determine_average_entry_and_size(adjusted_focus_entries.concat([
|
|
58288
|
-
{
|
|
58289
|
-
price: entry,
|
|
58290
|
-
quantity
|
|
58291
|
-
}
|
|
58292
|
-
]), rest.decimal_places, rest.price_places);
|
|
58293
|
-
const focus_loss = this.to_f((avg.price - second_payload.stop) * avg.quantity);
|
|
58294
|
-
let below_reverse_entries = kind === "long" ? entries.filter((u) => {
|
|
58295
|
-
return u.entry < reverse_position.entry;
|
|
58296
|
-
}) : entries.filter((u) => {
|
|
58297
|
-
return u.entry > reverse_position.entry;
|
|
58298
|
-
});
|
|
58299
|
-
const threshold = below_reverse_entries.at(-1);
|
|
58300
|
-
let adjusted_reverse_entries = entries.map((entry2) => {
|
|
58301
|
-
let adjusted_price = entry2.price;
|
|
58302
|
-
if (threshold) {
|
|
58303
|
-
if (reverse_kind === "short" && entry2.price > threshold.entry) {
|
|
58304
|
-
adjusted_price = threshold.entry;
|
|
58305
|
-
} else if (reverse_kind === "long" && entry2.price < threshold.entry) {
|
|
58306
|
-
adjusted_price = threshold.entry;
|
|
58307
|
-
}
|
|
58308
|
-
}
|
|
58309
|
-
return {
|
|
58310
|
-
price: adjusted_price,
|
|
58311
|
-
quantity: entry2.quantity
|
|
58312
|
-
};
|
|
58313
|
-
});
|
|
58314
|
-
const reverse_avg = determine_average_entry_and_size(adjusted_reverse_entries.concat([
|
|
58315
|
-
{
|
|
58316
|
-
price: reverse_position.entry,
|
|
58317
|
-
quantity: reverse_position.quantity
|
|
58318
|
-
}
|
|
58319
|
-
]), rest.decimal_places, rest.price_places);
|
|
58320
|
-
const reverse_pnl = this.to_f((reverse_avg.price - second_payload.stop) * reverse_avg.quantity);
|
|
58321
|
-
const fee_to_pay = this.calculate_fee({
|
|
58322
|
-
price: avg.entry,
|
|
58323
|
-
quantity: avg.quantity
|
|
58324
|
-
}) + this.calculate_fee({
|
|
58325
|
-
price: reverse_avg.entry,
|
|
58326
|
-
quantity: reverse_avg.quantity
|
|
58327
|
-
});
|
|
58328
|
-
const net_reverse_pnl = reverse_pnl - fee_to_pay;
|
|
58329
|
-
const ratio = net_reverse_pnl / focus_loss;
|
|
58330
|
-
const quantity_to_sell = this.to_df(ratio * avg.quantity);
|
|
58331
|
-
const remaining_quantity = this.to_df(avg.quantity - quantity_to_sell);
|
|
58332
|
-
return {
|
|
58333
|
-
risk,
|
|
58334
|
-
risk_reward: this.config.risk_reward,
|
|
58335
|
-
[kind]: {
|
|
58336
|
-
avg_entry: avg.entry,
|
|
58337
|
-
avg_size: avg.quantity,
|
|
58338
|
-
loss: focus_loss,
|
|
58339
|
-
stop: second_payload.stop,
|
|
58340
|
-
stop_quantity: quantity_to_sell,
|
|
58341
|
-
re_entry_quantity: remaining_quantity,
|
|
58342
|
-
initial_pnl: this.pnl(kind),
|
|
58343
|
-
tp: second_payload.entry
|
|
58344
|
-
},
|
|
58345
|
-
[reverse_kind]: {
|
|
58346
|
-
avg_entry: reverse_avg.entry,
|
|
58347
|
-
avg_size: reverse_avg.quantity,
|
|
58348
|
-
pnl: reverse_pnl,
|
|
58349
|
-
tp: second_payload.stop,
|
|
58350
|
-
re_entry_quantity: remaining_quantity,
|
|
58351
|
-
initial_pnl: this.pnl(reverse_kind)
|
|
58352
|
-
},
|
|
58353
|
-
last_entry: rest.last_value.entry,
|
|
58354
|
-
first_entry: entries.at(-1).entry,
|
|
58355
|
-
threshold
|
|
58356
|
-
};
|
|
58357
|
-
}
|
|
58358
|
-
runIterations(payload) {
|
|
58359
|
-
const { kind, iterations } = payload;
|
|
58360
|
-
const reverse_kind = kind == "long" ? "short" : "long";
|
|
58361
|
-
const result = [];
|
|
58362
|
-
let position2 = {
|
|
58363
|
-
long: this.position.long,
|
|
58364
|
-
short: this.position.short
|
|
58365
|
-
};
|
|
58366
|
-
for (let i2 = 0;i2 < iterations; i2++) {
|
|
58367
|
-
const instance = new Strategy({
|
|
58368
|
-
long: position2.long,
|
|
58369
|
-
short: position2.short,
|
|
58370
|
-
config: {
|
|
58371
|
-
...this.config,
|
|
58372
|
-
tp_percent: this.config.tp_percent + i2 * 4
|
|
58373
|
-
}
|
|
58374
|
-
});
|
|
58375
|
-
const algorithm = instance.generateGapClosingAlgorithm({
|
|
58376
|
-
kind
|
|
58377
|
-
});
|
|
58378
|
-
if (!algorithm) {
|
|
58379
|
-
console.log("No algorithm found");
|
|
58380
|
-
return result;
|
|
58381
|
-
break;
|
|
58382
|
-
}
|
|
58383
|
-
result.push(algorithm);
|
|
58384
|
-
position2[kind] = {
|
|
58385
|
-
entry: algorithm[kind].avg_entry,
|
|
58386
|
-
quantity: algorithm[kind].re_entry_quantity
|
|
58387
|
-
};
|
|
58388
|
-
position2[reverse_kind] = {
|
|
58389
|
-
entry: algorithm[reverse_kind].tp,
|
|
58390
|
-
quantity: algorithm[reverse_kind].re_entry_quantity
|
|
58391
|
-
};
|
|
58392
|
-
}
|
|
58393
|
-
return result;
|
|
58394
|
-
}
|
|
58395
|
-
}
|