@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/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 value = stream2;
16446
- this.write(value);
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(value) {
25660
- return $getPrototypeOf(value == null ? value : $Object(value));
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 value;
25832
+ var value2;
25833
25833
  if (name2 === "%AsyncFunction%") {
25834
- value = getEvalledConstructor("async function () {}");
25834
+ value2 = getEvalledConstructor("async function () {}");
25835
25835
  } else if (name2 === "%GeneratorFunction%") {
25836
- value = getEvalledConstructor("function* () {}");
25836
+ value2 = getEvalledConstructor("function* () {}");
25837
25837
  } else if (name2 === "%AsyncGeneratorFunction%") {
25838
- value = getEvalledConstructor("async function* () {}");
25838
+ value2 = getEvalledConstructor("async function* () {}");
25839
25839
  } else if (name2 === "%AsyncGenerator%") {
25840
25840
  var fn = doEval("%AsyncGeneratorFunction%");
25841
25841
  if (fn) {
25842
- value = fn.prototype;
25842
+ value2 = fn.prototype;
25843
25843
  }
25844
25844
  } else if (name2 === "%AsyncIteratorPrototype%") {
25845
25845
  var gen = doEval("%AsyncGenerator%");
25846
25846
  if (gen && getProto) {
25847
- value = getProto(gen.prototype);
25847
+ value2 = getProto(gen.prototype);
25848
25848
  }
25849
25849
  }
25850
- INTRINSICS[name2] = value;
25851
- return value;
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 value = INTRINSICS[intrinsicName];
25939
- if (value === needsEval) {
25940
- value = doEval(intrinsicName);
25938
+ var value2 = INTRINSICS[intrinsicName];
25939
+ if (value2 === needsEval) {
25940
+ value2 = doEval(intrinsicName);
25941
25941
  }
25942
- if (typeof value === "undefined" && !allowMissing) {
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 value = intrinsic.value;
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
- value = INTRINSICS[intrinsicRealName];
25988
- } else if (value != null) {
25989
- if (!(part in value)) {
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(value, part);
25996
+ var desc = $gOPD(value2, part);
25997
25997
  isOwn = !!desc;
25998
25998
  if (isOwn && "get" in desc && !("originalValue" in desc.get)) {
25999
- value = desc.get;
25999
+ value2 = desc.get;
26000
26000
  } else {
26001
- value = value[part];
26001
+ value2 = value2[part];
26002
26002
  }
26003
26003
  } else {
26004
- isOwn = hasOwn(value, part);
26005
- value = value[part];
26004
+ isOwn = hasOwn(value2, part);
26005
+ value2 = value2[part];
26006
26006
  }
26007
26007
  if (isOwn && !skipFurtherCaching) {
26008
- INTRINSICS[intrinsicRealName] = value;
26008
+ INTRINSICS[intrinsicRealName] = value2;
26009
26009
  }
26010
26010
  }
26011
26011
  }
26012
- return value;
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, value) {
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] = value;
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, value, options) {
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 value == "number") {
26102
- value = "" + value;
26101
+ if (typeof value2 == "number") {
26102
+ value2 = "" + value2;
26103
26103
  }
26104
- if (Array.isArray(value)) {
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, value, options);
26108
+ var header = this._multiPartHeader(field, value2, options);
26109
26109
  var footer = this._multiPartFooter();
26110
26110
  append(header);
26111
- append(value);
26111
+ append(value2);
26112
26112
  append(footer);
26113
- this._trackLength(header, value, options);
26113
+ this._trackLength(header, value2, options);
26114
26114
  };
26115
- FormData2.prototype._trackLength = function(header, value, options) {
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(value)) {
26120
- valueLength = value.length;
26121
- } else if (typeof value === "string") {
26122
- valueLength = Buffer.byteLength(value);
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 (!value || !value.path && !(value.readable && Object.prototype.hasOwnProperty.call(value, "httpVersion")) && !(value instanceof Stream)) {
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(value);
26130
+ this._valuesToMeasure.push(value2);
26131
26131
  }
26132
26132
  };
26133
- FormData2.prototype._lengthRetriever = function(value, callback) {
26134
- if (Object.prototype.hasOwnProperty.call(value, "fd")) {
26135
- if (value.end != null && value.end != Infinity && value.start != null) {
26136
- callback(null, value.end + 1 - (value.start ? value.start : 0));
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(value.path, function(err, 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 - (value.start ? value.start : 0);
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(value, "httpVersion")) {
26149
- callback(null, +value.headers["content-length"]);
26150
- } else if (Object.prototype.hasOwnProperty.call(value, "httpModule")) {
26151
- value.on("response", function(response) {
26152
- value.pause();
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
- value.resume();
26155
+ value2.resume();
26156
26156
  } else {
26157
26157
  callback("Unknown stream");
26158
26158
  }
26159
26159
  };
26160
- FormData2.prototype._multiPartHeader = function(field, value, options) {
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(value, options);
26165
- var contentType = this._getContentType(value, options);
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(value, options) {
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 || value.name || value.path) {
26196
- filename = path.basename(options.filename || value.name || value.path);
26197
- } else if (value.readable && Object.prototype.hasOwnProperty.call(value, "httpVersion")) {
26198
- filename = path.basename(value.client._httpMessage.path || "");
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(value, options) {
26205
+ FormData2.prototype._getContentType = function(value2, options) {
26206
26206
  var contentType = options.contentType;
26207
- if (!contentType && value.name) {
26208
- contentType = mime.lookup(value.name);
26207
+ if (!contentType && value2.name) {
26208
+ contentType = mime.lookup(value2.name);
26209
26209
  }
26210
- if (!contentType && value.path) {
26211
- contentType = mime.lookup(value.path);
26210
+ if (!contentType && value2.path) {
26211
+ contentType = mime.lookup(value2.path);
26212
26212
  }
26213
- if (!contentType && value.readable && Object.prototype.hasOwnProperty.call(value, "httpVersion")) {
26214
- contentType = value.headers["content-type"];
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 value == "object") {
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, value) {
26593
- this._options.headers[name2] = value;
26594
- this._currentRequest.setHeader(name2, value);
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(value) {
26915
- return typeof value === "string" || value instanceof String;
26914
+ function isString2(value2) {
26915
+ return typeof value2 === "string" || value2 instanceof String;
26916
26916
  }
26917
- function isFunction(value) {
26918
- return typeof value === "function";
26917
+ function isFunction(value2) {
26918
+ return typeof value2 === "function";
26919
26919
  }
26920
- function isBuffer(value) {
26921
- return typeof value === "object" && "length" in value;
26920
+ function isBuffer(value2) {
26921
+ return typeof value2 === "object" && "length" in value2;
26922
26922
  }
26923
- function isURL2(value) {
26924
- return URL2 && value instanceof 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, position) => {
27120
+ var endsWith = (str, searchString, position2) => {
27121
27121
  str = String(str);
27122
- if (position === undefined || position > str.length) {
27123
- position = str.length;
27122
+ if (position2 === undefined || position2 > str.length) {
27123
+ position2 = str.length;
27124
27124
  }
27125
- position -= searchString.length;
27126
- const lastIndex = str.indexOf(searchString, position);
27127
- return lastIndex !== -1 && lastIndex === position;
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 value = obj[name2];
27190
- if (!isFunction(value))
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((value) => {
27208
- obj[value] = true;
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 = (value, defaultValue) => {
27217
- return value != null && Number.isFinite(value = +value) ? value : defaultValue;
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, (value, key) => {
27233
- const reducedValue = visit(value, i2 + 1);
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(value) {
27429
- if (value === null)
27428
+ function convertValue(value2) {
27429
+ if (value2 === null)
27430
27430
  return "";
27431
- if (utils$1.isDate(value)) {
27432
- return value.toISOString();
27431
+ if (utils$1.isDate(value2)) {
27432
+ return value2.toISOString();
27433
27433
  }
27434
- if (!useBlob && utils$1.isBlob(value)) {
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(value) || utils$1.isTypedArray(value)) {
27438
- return useBlob && typeof Blob === "function" ? new Blob([value]) : Buffer.from(value);
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 value;
27440
+ return value2;
27441
27441
  }
27442
- function defaultVisitor(value, key, path) {
27443
- let arr = value;
27444
- if (value && !path && typeof value === "object") {
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
- value = JSON.stringify(value);
27448
- } else if (utils$1.isArray(value) && isFlatArray(value) || (utils$1.isFileList(value) || utils$1.endsWith(key, "[]")) && (arr = utils$1.toArray(value))) {
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(value)) {
27456
+ if (isVisitable(value2)) {
27457
27457
  return true;
27458
27458
  }
27459
- formData.append(renderKey(path, key, dots), convertValue(value));
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(value, path) {
27469
- if (utils$1.isUndefined(value))
27468
+ function build(value2, path) {
27469
+ if (utils$1.isUndefined(value2))
27470
27470
  return;
27471
- if (stack.indexOf(value) !== -1) {
27471
+ if (stack.indexOf(value2) !== -1) {
27472
27472
  throw Error("Circular reference detected in " + path.join("."));
27473
27473
  }
27474
- stack.push(value);
27475
- utils$1.forEach(value, function each(el, key) {
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, value) {
27509
- this._pairs.push([name2, value]);
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(value) {
27513
- return encoder2.call(this, value, encode$1);
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(value, key, path, helpers) {
27637
- if (platform.isNode && utils$1.isBuffer(value)) {
27638
- this.append(key, value.toString("base64"));
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, value, target, index) {
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], value];
27672
+ target[name2] = [target[name2], value2];
27673
27673
  } else {
27674
- target[name2] = value;
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, value, target[name2], index);
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, value) => {
27690
- buildPath(parsePropPath(name2), value, obj, 0);
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(value) {
27844
- if (value === false || value == null) {
27845
- return value;
27843
+ function normalizeValue(value2) {
27844
+ if (value2 === false || value2 == null) {
27845
+ return value2;
27846
27846
  }
27847
- return utils$1.isArray(value) ? value.map(normalizeValue) : String(value);
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, value, header, filter, isHeaderNameFilter) {
27859
+ function matchHeaderValue(context3, value2, header, filter, isHeaderNameFilter) {
27860
27860
  if (utils$1.isFunction(filter)) {
27861
- return filter.call(this, value, header);
27861
+ return filter.call(this, value2, header);
27862
27862
  }
27863
27863
  if (isHeaderNameFilter) {
27864
- value = header;
27864
+ value2 = header;
27865
27865
  }
27866
- if (!utils$1.isString(value))
27866
+ if (!utils$1.isString(value2))
27867
27867
  return;
27868
27868
  if (utils$1.isString(filter)) {
27869
- return value.indexOf(filter) !== -1;
27869
+ return value2.indexOf(filter) !== -1;
27870
27870
  }
27871
27871
  if (utils$1.isRegExp(filter)) {
27872
- return filter.test(value);
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, value] of header.entries()) {
27915
- setHeader(value, key, rewrite);
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 value = this[key];
27927
+ const value2 = this[key];
27928
27928
  if (!parser) {
27929
- return value;
27929
+ return value2;
27930
27930
  }
27931
27931
  if (parser === true) {
27932
- return parseTokens(value);
27932
+ return parseTokens(value2);
27933
27933
  }
27934
27934
  if (utils$1.isFunction(parser)) {
27935
- return parser.call(this, value, key);
27935
+ return parser.call(this, value2, key);
27936
27936
  }
27937
27937
  if (utils$1.isRegExp(parser)) {
27938
- return parser.exec(value);
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, (value, header) => {
27988
+ utils$1.forEach(this, (value2, header) => {
27989
27989
  const key = utils$1.findKey(headers, header);
27990
27990
  if (key) {
27991
- self2[key] = normalizeValue(value);
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(value);
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, (value, header) => {
28010
- value != null && value !== false && (obj[header] = asStrings && utils$1.isArray(value) ? value.join(", ") : value);
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, value]) => header + ": " + value).join(`
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: () => value,
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(value) {
28073
- return !!(value && value.__CANCEL__);
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, value) {
28269
+ constructor(name2, value2) {
28270
28270
  const { escapeName } = this.constructor;
28271
- const isStringValue = utils$1.isString(value);
28272
- let headers = `Content-Disposition: form-data; name="${escapeName(name2)}"${!isStringValue && value.name ? `; filename="${escapeName(value.name)}"` : ""}${CRLF}`;
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
- value = textEncoder.encode(String(value).replace(/\r?\n|\r\n?/g, CRLF));
28274
+ value2 = textEncoder.encode(String(value2).replace(/\r?\n|\r\n?/g, CRLF));
28275
28275
  } else {
28276
- headers += `Content-Type: ${value.type || "application/octet-stream"}${CRLF}`;
28276
+ headers += `Content-Type: ${value2.type || "application/octet-stream"}${CRLF}`;
28277
28277
  }
28278
28278
  this.headers = textEncoder.encode(headers + CRLF);
28279
- this.contentLength = isStringValue ? value.byteLength : value.size;
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 = 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(value)) {
28288
- yield value;
28286
+ const { value: value2 } = this;
28287
+ if (utils$1.isTypedArray(value2)) {
28288
+ yield value2;
28289
28289
  } else {
28290
- yield* readBlob$1(value);
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, value]) => {
28318
- const part = new FormDataPart(name2, value);
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((value) => {
28363
+ fn.apply(this, args).then((value2) => {
28364
28364
  try {
28365
- reducer ? cb(null, ...reducer(value)) : cb(null, value);
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 = (value, isRejected) => {
28535
+ const done = (value2, isRejected) => {
28536
28536
  if (isDone)
28537
28537
  return;
28538
28538
  isDone = true;
28539
- onDone && onDone(value, isRejected);
28539
+ onDone && onDone(value2, isRejected);
28540
28540
  };
28541
- const _resolve = (value) => {
28542
- done(value);
28543
- resolve(value);
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, (value) => utils$1.isArray(value) ? value : [value]);
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((value, isRejected) => {
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, value, expires, path, domain, secure) {
28928
- const cookie = [name2 + "=" + encodeURIComponent(value)];
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(value) {
29091
- resolve(value);
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 value;
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 = value.byteLength;
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(value));
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, value) => {
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 (value, opt, opts) => {
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(value, opt, opts) : true;
29534
+ return validator2 ? validator2(value2, opt, opts) : true;
29535
29535
  };
29536
29536
  };
29537
29537
  validators$1.spelling = function spelling(correctSpelling) {
29538
- return (value, opt) => {
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 value = options[opt];
29554
- const result = value === undefined || validator2(value, opt, options);
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, value]) => {
29888
- HttpStatusCode[value] = key;
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 value = data[key2];
30635
- const valueType = typeof value;
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(value)) {
30641
- if (valueType === "object" && value !== null) {
30642
- newItem[newKey] = this.beautify(value, knownBeautification[key2]);
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, value);
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 value) {
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(value) {
30748
- return value instanceof P ? value : new P(function(resolve) {
30749
- resolve(value);
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(value) {
30753
+ function fulfilled(value2) {
30754
30754
  try {
30755
- step(generator.next(value));
30755
+ step(generator.next(value2));
30756
30756
  } catch (e2) {
30757
30757
  reject(e2);
30758
30758
  }
30759
30759
  }
30760
- function rejected(value) {
30760
+ function rejected(value2) {
30761
30761
  try {
30762
- step(generator["throw"](value));
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(value) {
30840
- return value instanceof P ? value : new P(function(resolve) {
30841
- resolve(value);
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(value) {
30845
+ function fulfilled(value2) {
30846
30846
  try {
30847
- step(generator.next(value));
30847
+ step(generator.next(value2));
30848
30848
  } catch (e2) {
30849
30849
  reject(e2);
30850
30850
  }
30851
30851
  }
30852
- function rejected(value) {
30852
+ function rejected(value2) {
30853
30853
  try {
30854
- step(generator["throw"](value));
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(value) {
30887
- return value instanceof P ? value : new P(function(resolve) {
30888
- resolve(value);
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(value) {
30892
+ function fulfilled(value2) {
30893
30893
  try {
30894
- step(generator.next(value));
30894
+ step(generator.next(value2));
30895
30895
  } catch (e2) {
30896
30896
  reject(e2);
30897
30897
  }
30898
30898
  }
30899
- function rejected(value) {
30899
+ function rejected(value2) {
30900
30900
  try {
30901
- step(generator["throw"](value));
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 value = params[key];
30948
- if (strict_validation === true && typeof value === "undefined") {
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(value) : value;
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(value) {
31091
- return value instanceof P ? value : new P(function(resolve) {
31092
- resolve(value);
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(value) {
31096
+ function fulfilled(value2) {
31097
31097
  try {
31098
- step(generator.next(value));
31098
+ step(generator.next(value2));
31099
31099
  } catch (e2) {
31100
31100
  reject(e2);
31101
31101
  }
31102
31102
  }
31103
- function rejected(value) {
31103
+ function rejected(value2) {
31104
31104
  try {
31105
- step(generator["throw"](value));
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(value) {
31178
- this.timeOffset = value;
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 value = parseInt(headerValue);
31273
- if (headerValue !== undefined && !isNaN(value)) {
31274
- this.apiLimitTrackers[headerKey] = value;
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: value,
31277
+ valueParsed: value2,
31278
31278
  valueRaw: headerValue
31279
31279
  };
31280
31280
  } else {
31281
31281
  delta[headerKey] = {
31282
31282
  updated: false,
31283
- valueParsed: value,
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(value) {
31325
- return value instanceof P ? value : new P(function(resolve) {
31326
- resolve(value);
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(value) {
31330
+ function fulfilled(value2) {
31331
31331
  try {
31332
- step(generator.next(value));
31332
+ step(generator.next(value2));
31333
31333
  } catch (e2) {
31334
31334
  reject(e2);
31335
31335
  }
31336
31336
  }
31337
- function rejected(value) {
31337
+ function rejected(value2) {
31338
31338
  try {
31339
- step(generator["throw"](value));
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(value) {
31692
- return value instanceof P ? value : new P(function(resolve) {
31693
- resolve(value);
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(value) {
31697
+ function fulfilled(value2) {
31698
31698
  try {
31699
- step(generator.next(value));
31699
+ step(generator.next(value2));
31700
31700
  } catch (e2) {
31701
31701
  reject(e2);
31702
31702
  }
31703
31703
  }
31704
- function rejected(value) {
31704
+ function rejected(value2) {
31705
31705
  try {
31706
- step(generator["throw"](value));
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(value) {
33238
- return value instanceof P ? value : new P(function(resolve) {
33239
- resolve(value);
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(value) {
33243
+ function fulfilled(value2) {
33244
33244
  try {
33245
- step(generator.next(value));
33245
+ step(generator.next(value2));
33246
33246
  } catch (e2) {
33247
33247
  reject(e2);
33248
33248
  }
33249
33249
  }
33250
- function rejected(value) {
33250
+ function rejected(value2) {
33251
33251
  try {
33252
- step(generator["throw"](value));
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(value) {
33712
- return value instanceof P ? value : new P(function(resolve) {
33713
- resolve(value);
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(value) {
33717
+ function fulfilled(value2) {
33718
33718
  try {
33719
- step(generator.next(value));
33719
+ step(generator.next(value2));
33720
33720
  } catch (e2) {
33721
33721
  reject(e2);
33722
33722
  }
33723
33723
  }
33724
- function rejected(value) {
33724
+ function rejected(value2) {
33725
33725
  try {
33726
- step(generator["throw"](value));
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 value = params[key];
34642
- if (value.length > 1) {
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
- value = value[0];
34645
+ value2 = value2[0];
34646
34646
  if (key === "client_max_window_bits") {
34647
- if (value !== true) {
34648
- const num = +value;
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}": ${value}`);
34650
+ throw new TypeError(`Invalid value for parameter "${key}": ${value2}`);
34651
34651
  }
34652
- value = num;
34652
+ value2 = num;
34653
34653
  } else if (!this._isServer) {
34654
- throw new TypeError(`Invalid value for parameter "${key}": ${value}`);
34654
+ throw new TypeError(`Invalid value for parameter "${key}": ${value2}`);
34655
34655
  }
34656
34656
  } else if (key === "server_max_window_bits") {
34657
- const num = +value;
34657
+ const num = +value2;
34658
34658
  if (!Number.isInteger(num) || num < 8 || num > 15) {
34659
- throw new TypeError(`Invalid value for parameter "${key}": ${value}`);
34659
+ throw new TypeError(`Invalid value for parameter "${key}": ${value2}`);
34660
34660
  }
34661
- value = num;
34661
+ value2 = num;
34662
34662
  } else if (key === "client_no_context_takeover" || key === "server_no_context_takeover") {
34663
- if (value !== true) {
34664
- throw new TypeError(`Invalid value for parameter "${key}": ${value}`);
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] = value;
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(value) {
34953
- return hasBlob && typeof value === "object" && typeof value.arrayBuffer === "function" && typeof value.type === "string" && typeof value.stream === "function" && (value[Symbol.toStringTag] === "Blob" || value[Symbol.toStringTag] === "File");
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 value = header.slice(start, end);
35971
+ let value2 = header.slice(start, end);
35972
35972
  if (mustUnescape) {
35973
- value = value.replace(/\\/g, "");
35973
+ value2 = value2.replace(/\\/g, "");
35974
35974
  mustUnescape = false;
35975
35975
  }
35976
- push(params, paramName, value);
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, value] of Object.entries(headers)) {
36500
- options.headers[key2.toLowerCase()] = value;
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 value = extension.format({
37162
+ const value2 = extension.format({
37163
37163
  [PerMessageDeflate.extensionName]: [params]
37164
37164
  });
37165
- headers.push(`Sec-WebSocket-Extensions: ${value}`);
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(value) {
37298
- return value instanceof P ? value : new P(function(resolve) {
37299
- resolve(value);
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(value) {
37303
+ function fulfilled(value2) {
37304
37304
  try {
37305
- step(generator.next(value));
37305
+ step(generator.next(value2));
37306
37306
  } catch (e2) {
37307
37307
  reject(e2);
37308
37308
  }
37309
37309
  }
37310
- function rejected(value) {
37310
+ function rejected(value2) {
37311
37311
  try {
37312
- step(generator["throw"](value));
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, value, requestId) {
37804
+ requestSetProperty(wsKey, property, value2, requestId) {
37805
37805
  const wsMessage = JSON.stringify({
37806
37806
  method: "SET_PROPERTY",
37807
- params: [property, value],
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/exchanges/binance.ts
52078
- var import_binance = __toESM(require_lib2());
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 determine_close_price({
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 position = dollar_value * quantity;
52090
- if (position) {
52091
- const percent = pnl / position;
52092
- const difference = position * percent / quantity;
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 determine_pnl(entry, close_price, quantity, kind = "long", contract_size) {
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 to_f(last, places);
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 to_f(focus_high, places);
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 to_f(focus_high, places);
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(determine_pnl(i2["entry"], i2["risk_sell"], i2["quantity"], kind));
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 = to_f(difference / this.risk_reward, this.price_places);
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) => to_f(margin_range[1] - spread * x, this.price_places));
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) => to_f(margin_range[1] * Math.pow(1 + percent_change, x), this.price_places));
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 value = this.to_f(new_range[1] - spread * x);
52479
- if (value <= current_price) {
52480
- entries2.push(value);
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 value = this.to_f(new_range[1] * Math.pow(1 + percent_change, x));
52484
- if (value >= current_price) {
52485
- entries2.push(value);
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 value = this.to_f(next_focus - spread * x);
52500
- if (value <= this.to_f(current_price)) {
52501
- entries2.push(value);
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 value = this.to_f(next_focus * Math.pow(1 + percent_change, x));
52505
- if (value >= this.to_f(current_price)) {
52506
- entries2.push(value);
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(value, places) {
52518
- return to_f(value, places || this.price_places);
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 = determine_position_size({
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 = determine_position_size({
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 = determine_pnl(entry, stop, quantity, kind);
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 = determine_close_price({ entry, pnl, quantity, kind });
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(determine_pnl(entry, sell_price, quantity, kind));
53031
+ pnl = this.to_df(determine_pnl2(entry, sell_price, quantity, kind));
52779
53032
  pnl = pnl + fee;
52780
- sell_price = determine_close_price({ entry, pnl, quantity, kind });
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 to_f(currentPrice, places);
53051
+ return to_f2(currentPrice, places);
52799
53052
  }
52800
53053
  }
52801
53054
 
52802
- // src/helpers/pnl.ts
52803
- function determine_position_size2(entry, stop, budget) {
52804
- let stop_percent = Math.abs(entry - stop) / entry;
52805
- let size = budget / stop_percent / entry;
52806
- return size;
52807
- }
52808
- function determine_risk(entry, stop, quantity) {
52809
- let stop_percent = Math.abs(entry - stop) / entry;
52810
- let risk = quantity * stop_percent * entry;
52811
- return risk;
52812
- }
52813
- function determine_close_price2(entry, pnl, quantity, kind, single = false, leverage = 1) {
52814
- const dollar_value = entry / leverage;
52815
- const position = dollar_value * quantity;
52816
- if (position) {
52817
- let percent = pnl / position;
52818
- let difference = position * percent / quantity;
52819
- let result;
52820
- if (kind === "long") {
52821
- result = difference + entry;
52822
- } else {
52823
- result = entry - difference;
52824
- }
52825
- if (single) {
52826
- return result;
52827
- }
52828
- return result;
52829
- }
52830
- return 0;
52831
- }
52832
- function determine_amount_to_sell(entry, quantity, sell_price, pnl, kind, places = "%.3f") {
52833
- const _pnl = determine_pnl2(entry, sell_price, quantity, kind);
52834
- const ratio = pnl / to_f2(Math.abs(_pnl), places);
52835
- quantity = quantity * ratio;
52836
- return to_f2(quantity, places);
52837
- }
52838
- function determine_pnl2(entry, close_price, quantity, kind, contract_size, places = "%.2f") {
52839
- if (contract_size) {
52840
- const direction = kind === "long" ? 1 : -1;
52841
- return quantity * contract_size * direction * (1 / entry - 1 / close_price);
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
- let difference = entry - close_price;
52844
- if (kind === "long") {
52845
- difference = close_price - entry;
53100
+ if (!stop) {
53101
+ return [];
52846
53102
  }
52847
- return to_f2(difference * quantity, places);
52848
- }
52849
- function position(entry, quantity, kind, leverage = 1) {
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
- return value;
52859
- }
52860
- var value = {
52861
- determine_risk,
52862
- determine_position_size: determine_position_size2,
52863
- determine_close_price: determine_close_price2,
52864
- determine_pnl: determine_pnl2,
52865
- position,
52866
- determine_amount_to_sell,
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 determine_position_size({
52878
- entry,
52879
- stop,
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 stop_percent = stop ? Math.abs(entry - stop) / entry : percent;
52888
- if (stop_percent && budget) {
52889
- let size = budget / stop_percent;
52890
- let notion_value = size * entry;
52891
- if (notional_value && notional_value > notion_value) {
52892
- size = notional_value / entry;
52893
- }
52894
- if (as_coin) {
52895
- size = size / entry;
52896
- if (min_size && min_size === 1) {
52897
- return to_f(Math.round(size), places);
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 to_f(size, places);
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 determine_average_entry_and_size(orders, places = "%.3f", price_places = "%.1f") {
52905
- const sum_values = orders.reduce((sum, order) => sum + order.price * order.quantity, 0);
52906
- const total_quantity = orders.reduce((sum, order) => sum + order.quantity, 0);
52907
- const avg_price = total_quantity ? to_f(sum_values / total_quantity, price_places) : 0;
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
- entry: avg_price,
52910
- price: avg_price,
52911
- quantity: to_f(total_quantity, places)
53188
+ app_config,
53189
+ max_size,
53190
+ last_value,
53191
+ entries
52912
53192
  };
52913
53193
  }
52914
- var createArray = (start, stop, step) => {
52915
- const result = [];
52916
- let current = start;
52917
- while (current <= stop) {
52918
- result.push(current);
52919
- current += step;
52920
- }
52921
- return result;
52922
- };
52923
- var groupIntoPairsWithSumLessThan = (arr, targetSum, key = "quantity", firstSize = 0) => {
52924
- if (firstSize) {
52925
- const totalSize = arr.reduce((sum, order) => sum + order[key], 0);
52926
- const remainingSize = totalSize - firstSize;
52927
- let newSum = 0;
52928
- let newArray = [];
52929
- let lastIndex = 0;
52930
- for (let i2 = 0;i2 < arr.length; i2++) {
52931
- if (newSum < remainingSize) {
52932
- newSum += arr[i2][key];
52933
- newArray.push(arr[i2]);
52934
- lastIndex = i2;
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 lastGroup = arr.slice(lastIndex + 1);
52938
- const previousPair = groupInPairs(newArray, key, targetSum);
52939
- if (lastGroup.length > 0) {
52940
- previousPair.push(lastGroup);
52941
- }
52942
- return previousPair;
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
- return result;
52960
- }
52961
- var computeTotalAverageForEachTrade = (trades, config2) => {
52962
- let _take_profit = config2.take_profit;
52963
- let kind = config2.kind;
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
- considered = trades.filter((p) => p.entry < _currentEntry);
52973
- }
52974
- const x_pnl = 0;
52975
- const remaining = less.filter((o) => {
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
- return o.entry <= r2.entry;
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 (remaining.length === 0) {
52982
- return { ...r2, pnl: x_pnl };
53298
+ if (result.length === 0) {
53299
+ high_risk = mid_risk;
53300
+ continue;
52983
53301
  }
52984
- const start = kind === "long" ? Math.max(...remaining.map((o) => o.entry)) : Math.min(...remaining.map((o) => o.entry));
52985
- considered = considered.map((o) => ({ ...o, entry: start }));
52986
- considered = considered.concat(remaining);
52987
- let avg_entry = determine_average_entry_and_size([
52988
- ...considered.map((o) => ({
52989
- price: o.entry,
52990
- quantity: o.quantity
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
- ], config2.decimal_places, config2.price_places);
52997
- let _pnl = r2.pnl;
52998
- let sell_price = r2.sell_price;
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
- let tp_close = pnl_default.determine_close_price(r2.entry, Math.abs(entry_loss) * (config2.rr || 1) + x_fee, avg_entry.quantity, kind);
53019
- return {
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
- const result = [];
53042
- const firstElement = arr[0];
53043
- for (let i2 = arr.length - 1;i2 >= 0; i2--) {
53044
- const current = arr[i2];
53045
- const gapIndex = i2 - gap;
53046
- const pairedElement = gapIndex < 0 ? firstElement : arr[gapIndex];
53047
- if (current !== pairedElement) {
53048
- result.push([current, pairedElement]);
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
- if (item) {
53052
- let r2 = result.find((o) => o[0] === item);
53053
- return r2 ? [r2] : [];
53054
- }
53055
- return result;
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
- // src/exchanges/binance.ts
53059
- var CONSTANTS = {
53060
- SPOT_TO_FIAT: "MAIN_C2C",
53061
- SPOT_TO_USDT_FUTURE: "MAIN_UMFUTURE",
53062
- SPOT_TO_COIN_FUTURE: "MAIN_CMFUTURE",
53063
- SPOT_TO_MARGIN_CROSS: "MAIN_MARGIN",
53064
- SPOT_TO_MINING: "MAIN_MINING",
53065
- FIAT_TO_SPOT: "C2C_MAIN",
53066
- FIAT_TO_USDT_FUTURE: "C2C_UMFUTURE",
53067
- FIAT_TO_MINING: "C2C_MINING",
53068
- USDT_FUTURE_TO_SPOT: "UMFUTURE_MAIN",
53069
- USDT_FUTURE_TO_FIAT: "UMFUTURE_C2C",
53070
- USDT_FUTURE_TO_MARGIN_CROSS: "UMFUTURE_MARGIN",
53071
- COIN_FUTURE_TO_SPOT: "CMFUTURE_MAIN",
53072
- MARGIN_CROSS_TO_SPOT: "MARGIN_MAIN",
53073
- MARGIN_CROSS_TO_USDT_FUTURE: "MARGIN_UMFUTURE",
53074
- MINING_TO_SPOT: "MINING_MAIN",
53075
- MINING_TO_USDT_FUTURE: "MINING_UMFUTURE",
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 ? to_f(x.price, priceFormat) : 0,
53306
- quantity: x.quantity ? to_f(x.quantity, quantityFormat) : 0,
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 = to_f(x.stop, priceFormat);
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 { price_places = "%.1f", decimal_places = "%.3f", symbol } = payload;
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 ? to_f(balance, "%.2f") : 0;
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: to_f(x.balance, "%.8f")
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 = to_f(totalQuantity, decimal_places);
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 = to_f(runningTotal, decimal_places);
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 = to_f((minNotional || 0) / support, decimal_places);
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 ? to_f(x.price, priceFormat) : 0).toString(),
54177
- qty: (x.quantity ? to_f(x.quantity, quantityFormat) : 0).toString(),
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 = to_f(x.stop, priceFormat).toString();
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 = to_f(v.triggerPrice, priceFormat).toString();
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 to_f(response.result.list[0].totalWalletBalance, "%.2f");
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: to_f(x.walletBalance, "%.8f")
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 = to_f(totalQuantity, decimal_places);
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 = to_f(runningTotal, decimal_places);
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" ? to_f(long_liquidation, "%.2f") : to_f(short_liquidation, "%.2f");
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(kind, active_account, targetPnl = 100, ratio = 0.9, use_full = false, not_reduce = false) {
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 / position2.quantity : position2.entry - targetPnl / position2.quantity;
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: to_f(takeProfitPrice, active_account.price_places),
54949
- quantity: to_f(position2.quantity || 0, active_account.decimal_places),
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: to_f(stopLossPrice, active_account.price_places),
54954
- quantity: to_f(stopLossQuantity || 0, active_account.decimal_places),
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
- let filteredOrders = withCumulative.filter((order) => (order.cumulative_quantity || 0) > position2?.quantity).map((order) => ({
55513
- ...order,
55514
- price: order.entry,
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
- side: kind.toLowerCase() === "long" ? "buy" : "sell"
55517
- }));
55518
- filteredOrders = filteredOrders.filter((k) => !existingOrders.map((j) => j.price).includes(k.price));
55519
- return filteredOrders;
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 generateOptimumAppConfig(config2, payload, position2) {
55522
- let low_risk = payload.start_risk;
55523
- let high_risk = payload.max_risk || 50000;
55524
- let best_risk = null;
55525
- let best_app_config = null;
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
- const trades = determine_amount_to_buy({
55582
- orders: full_trades,
55583
- kind: position2.kind,
55584
- decimal_places: current_app_config.decimal_places,
55585
- price_places: current_app_config.price_places,
55586
- position: position2,
55587
- existingOrders: []
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 (trades.length === 0) {
55590
- console.log(` -> No trades met quantity requirement after filtering at Risk=${mid_risk.toFixed(2)}. Adjusting low_risk up.`);
55591
- low_risk = mid_risk;
55592
- continue;
55593
- }
55594
- const last_trade = trades[trades.length - 1];
55595
- const last_entry = last_trade.entry;
55596
- console.log(` -> Last Trade Entry (Filtered): ${last_entry.toFixed(4)}`);
55597
- if (position2.kind === "long") {
55598
- if (last_entry > position2.entry) {
55599
- console.log(` -> Constraint VIOLATED (Long): last_entry (${last_entry.toFixed(4)}) > position.entry (${position2.entry.toFixed(4)}). Reducing high_risk.`);
55600
- high_risk = mid_risk;
55601
- } else {
55602
- console.log(` -> Constraint MET (Long): last_entry (${last_entry.toFixed(4)}) <= position.entry (${position2.entry.toFixed(4)}). Storing as best, increasing low_risk.`);
55603
- best_risk = mid_risk;
55604
- best_app_config = current_app_config;
55605
- low_risk = mid_risk;
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
- if (last_entry < position2.entry) {
55609
- console.log(` -> Constraint VIOLATED (Short): last_entry (${last_entry.toFixed(4)}) < position.entry (${position2.entry.toFixed(4)}). Reducing high_risk.`);
55610
- high_risk = mid_risk;
55611
- } else {
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
- if (iterations >= max_iterations) {
55620
- console.warn(`generateAppConfig: Reached max iterations (${max_iterations}) without converging. Returning best found result.`);
55621
- } else if (best_app_config) {
55622
- console.log(`Search finished. Best Risk: ${best_risk?.toFixed(2)}, Final Last Entry: ${best_app_config.last_value?.entry?.toFixed(4)}`);
55623
- } else {
55624
- console.warn(`generateAppConfig: Could not find a valid risk configuration.`);
55625
- }
55626
- if (!best_app_config) {
55627
- return null;
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 = to_f(position2.quantity * _profit_percent * position2.entry / 100);
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 = to_f(totalQuantity, decimal_places);
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 = to_f(runningTotal, decimal_places);
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 = to_f(totalQuantity, decimal_places);
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 = to_f(runningTotal, decimal_places);
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 = to_f(position2.quantity * _profit_percent * position2.entry / 100);
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 = to_f(diff * root_position.quantity);
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 = to_f(long_liquidation, "%.3f");
57877
- short_position.avg_liquidation = to_f(short_liquidation, "%.3f");
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 = to_f(long_ratio, "%.3f") * 100;
57881
- short_position.liquidation_ratio = to_f(short_ratio, "%.3f") * 100;
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
- }