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