@gbozee/ultimate 0.0.2-next.23 → 0.0.2-next.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +616 -1612
- package/dist/index.js +616 -1612
- package/dist/mcp-server.cjs +616 -1612
- package/dist/mcp-server.js +616 -1612
- package/package.json +1 -2
package/dist/index.cjs
CHANGED
|
@@ -50646,19 +50646,92 @@ class AppDatabase {
|
|
|
50646
50646
|
}
|
|
50647
50647
|
async deleteAndBulCreateAllOrders(payload) {
|
|
50648
50648
|
const { account, symbol, all_orders } = payload;
|
|
50649
|
-
console.log(`Fetching existing DB orders for ${account.owner}/${account.exchange} - ${symbol}
|
|
50650
|
-
let
|
|
50649
|
+
console.log(`Fetching existing DB orders for ${account.owner}/${account.exchange} - ${symbol} for deduplication...`);
|
|
50650
|
+
let existing_orders = [];
|
|
50651
50651
|
try {
|
|
50652
|
-
|
|
50652
|
+
existing_orders = await this.pb.collection("orders").getFullList({
|
|
50653
50653
|
filter: `symbol:lower="${symbol.toLowerCase()}" && account.owner:lower="${account.owner.toLowerCase()}" && account.exchange:lower="${account.exchange.toLowerCase()}"`
|
|
50654
50654
|
});
|
|
50655
|
-
|
|
50656
|
-
console.log(`Found ${pocketbase_ids_to_delete.length} existing DB orders to delete.`);
|
|
50655
|
+
console.log(`Found ${existing_orders.length} existing DB orders.`);
|
|
50657
50656
|
} catch (error) {
|
|
50658
|
-
console.error("Error fetching DB orders
|
|
50657
|
+
console.error("Error fetching existing DB orders:", error);
|
|
50658
|
+
existing_orders = [];
|
|
50659
|
+
}
|
|
50660
|
+
const existing_signatures = new Set;
|
|
50661
|
+
const existing_ids_to_delete = new Set;
|
|
50662
|
+
for (const existing_order of existing_orders) {
|
|
50663
|
+
const signature = [
|
|
50664
|
+
existing_order.symbol?.toLowerCase() || "",
|
|
50665
|
+
existing_order.kind || "",
|
|
50666
|
+
existing_order.price?.toString() || "",
|
|
50667
|
+
existing_order.quantity?.toString() || "",
|
|
50668
|
+
existing_order.side?.toLowerCase() || "",
|
|
50669
|
+
existing_order.stop?.toString() || "0",
|
|
50670
|
+
existing_order.order_id?.toString() || "",
|
|
50671
|
+
existing_order.client_order_id?.toString() || "",
|
|
50672
|
+
account.id
|
|
50673
|
+
].join("|");
|
|
50674
|
+
existing_signatures.add(signature);
|
|
50675
|
+
existing_ids_to_delete.add(existing_order.id);
|
|
50676
|
+
}
|
|
50677
|
+
const unique_orders = [];
|
|
50678
|
+
const new_signatures = new Set;
|
|
50679
|
+
for (const order of all_orders) {
|
|
50680
|
+
const signature = [
|
|
50681
|
+
symbol.toLowerCase(),
|
|
50682
|
+
order.kind || "",
|
|
50683
|
+
order.price?.toString() || "",
|
|
50684
|
+
order.quantity?.toString() || "",
|
|
50685
|
+
order.side?.toLowerCase() || "",
|
|
50686
|
+
(order.stop || order.triggerPrice || 0).toString(),
|
|
50687
|
+
order.order_id?.toString() || "",
|
|
50688
|
+
(order.clientOrderId || "").toString(),
|
|
50689
|
+
account.id
|
|
50690
|
+
].join("|");
|
|
50691
|
+
if (!existing_signatures.has(signature) && !new_signatures.has(signature)) {
|
|
50692
|
+
unique_orders.push(order);
|
|
50693
|
+
new_signatures.add(signature);
|
|
50694
|
+
} else {
|
|
50695
|
+
console.log(`Skipping duplicate order: ${order.order_id} for ${symbol}`);
|
|
50696
|
+
}
|
|
50697
|
+
}
|
|
50698
|
+
console.log(`After deduplication: ${unique_orders.length} unique orders out of ${all_orders.length} total orders`);
|
|
50699
|
+
const orders_to_keep = new Set;
|
|
50700
|
+
for (const order of all_orders) {
|
|
50701
|
+
const signature = [
|
|
50702
|
+
symbol.toLowerCase(),
|
|
50703
|
+
order.kind || "",
|
|
50704
|
+
order.price?.toString() || "",
|
|
50705
|
+
order.quantity?.toString() || "",
|
|
50706
|
+
order.side?.toLowerCase() || "",
|
|
50707
|
+
(order.stop || order.triggerPrice || 0).toString(),
|
|
50708
|
+
order.order_id?.toString() || "",
|
|
50709
|
+
(order.clientOrderId || "").toString(),
|
|
50710
|
+
account.id
|
|
50711
|
+
].join("|");
|
|
50712
|
+
if (existing_signatures.has(signature)) {
|
|
50713
|
+
orders_to_keep.add(signature);
|
|
50714
|
+
}
|
|
50715
|
+
}
|
|
50716
|
+
const pocketbase_ids_to_delete = [];
|
|
50717
|
+
for (const existing_order of existing_orders) {
|
|
50718
|
+
const signature = [
|
|
50719
|
+
existing_order.symbol?.toLowerCase() || "",
|
|
50720
|
+
existing_order.kind || "",
|
|
50721
|
+
existing_order.price?.toString() || "",
|
|
50722
|
+
existing_order.quantity?.toString() || "",
|
|
50723
|
+
existing_order.side?.toLowerCase() || "",
|
|
50724
|
+
existing_order.stop?.toString() || "0",
|
|
50725
|
+
existing_order.order_id?.toString() || "",
|
|
50726
|
+
existing_order.client_order_id?.toString() || "",
|
|
50727
|
+
account.id
|
|
50728
|
+
].join("|");
|
|
50729
|
+
if (!orders_to_keep.has(signature)) {
|
|
50730
|
+
pocketbase_ids_to_delete.push(existing_order.id);
|
|
50731
|
+
}
|
|
50659
50732
|
}
|
|
50660
50733
|
if (pocketbase_ids_to_delete.length > 0) {
|
|
50661
|
-
console.log(`Deleting ${pocketbase_ids_to_delete.length}
|
|
50734
|
+
console.log(`Deleting ${pocketbase_ids_to_delete.length} obsolete orders from PocketBase...`);
|
|
50662
50735
|
for (let i2 = 0;i2 < pocketbase_ids_to_delete.length; i2 += 5) {
|
|
50663
50736
|
const batch_to_delete = pocketbase_ids_to_delete.slice(i2, i2 + 5);
|
|
50664
50737
|
try {
|
|
@@ -50667,13 +50740,12 @@ class AppDatabase {
|
|
|
50667
50740
|
console.error(`Error deleting batch starting at index ${i2}:`, error, "Batch IDs:", batch_to_delete);
|
|
50668
50741
|
}
|
|
50669
50742
|
}
|
|
50670
|
-
console.log("Finished deleting
|
|
50743
|
+
console.log("Finished deleting obsolete DB orders.");
|
|
50671
50744
|
}
|
|
50672
|
-
|
|
50673
|
-
|
|
50674
|
-
|
|
50675
|
-
|
|
50676
|
-
const orderChunk = all_orders.slice(i2, i2 + 100);
|
|
50745
|
+
if (unique_orders.length > 0) {
|
|
50746
|
+
console.log(`Creating ${unique_orders.length} new orders in PocketBase...`);
|
|
50747
|
+
for (let i2 = 0;i2 < unique_orders.length; i2 += 100) {
|
|
50748
|
+
const orderChunk = unique_orders.slice(i2, i2 + 100);
|
|
50677
50749
|
const batch2 = this.pb.createBatch();
|
|
50678
50750
|
for (const order of orderChunk) {
|
|
50679
50751
|
const order_data = {
|
|
@@ -50695,8 +50767,9 @@ class AppDatabase {
|
|
|
50695
50767
|
console.error(`Error creating batch starting at index ${i2}:`, error);
|
|
50696
50768
|
}
|
|
50697
50769
|
}
|
|
50698
|
-
console.log("Finished
|
|
50770
|
+
console.log("Finished creating new orders in PocketBase.");
|
|
50699
50771
|
}
|
|
50772
|
+
console.log(`Order synchronization complete. Created ${unique_orders.length} new orders, deleted ${pocketbase_ids_to_delete.length} obsolete orders.`);
|
|
50700
50773
|
}
|
|
50701
50774
|
async cancelLimitOrders(payload) {
|
|
50702
50775
|
const { symbol, kind, account, cancelExchangeOrders, raw } = payload;
|
|
@@ -59004,1582 +59077,350 @@ function convert_to_exchange_order(order) {
|
|
|
59004
59077
|
var import_https_proxy_agent3 = __toESM(require_dist2());
|
|
59005
59078
|
var import_socks_proxy_agent3 = __toESM(require_dist3());
|
|
59006
59079
|
|
|
59007
|
-
//
|
|
59008
|
-
|
|
59009
|
-
|
|
59010
|
-
|
|
59011
|
-
|
|
59012
|
-
|
|
59013
|
-
|
|
59014
|
-
}
|
|
59015
|
-
function isFunction(obj) {
|
|
59016
|
-
return typeof obj === "function";
|
|
59017
|
-
}
|
|
59018
|
-
function isPrimitive2(arg) {
|
|
59019
|
-
const type = typeof arg;
|
|
59020
|
-
return arg !== undefined && (isDate2(arg) || type !== "object" && type !== "function");
|
|
59021
|
-
}
|
|
59022
|
-
function isDate2(obj) {
|
|
59023
|
-
return obj instanceof Date;
|
|
59024
|
-
}
|
|
59025
|
-
function isBoolean2(obj) {
|
|
59026
|
-
return typeof obj === "boolean";
|
|
59027
|
-
}
|
|
59028
|
-
function isPromise(obj) {
|
|
59029
|
-
return obj instanceof Promise;
|
|
59030
|
-
}
|
|
59031
|
-
function isEmpty(obj) {
|
|
59032
|
-
if (!obj)
|
|
59033
|
-
return false;
|
|
59034
|
-
if (isArray3(obj))
|
|
59035
|
-
return obj.length === 0;
|
|
59036
|
-
for (const key in obj) {
|
|
59037
|
-
if (hasOwnProperty.call(obj, key)) {
|
|
59038
|
-
return false;
|
|
59039
|
-
}
|
|
59040
|
-
}
|
|
59041
|
-
return true;
|
|
59042
|
-
}
|
|
59043
|
-
var setPrimitives = new Set(["boolean", "string", "number"]);
|
|
59044
|
-
function isActualPrimitive(arg) {
|
|
59045
|
-
return setPrimitives.has(typeof arg);
|
|
59046
|
-
}
|
|
59047
|
-
function isChildNodeValue(node) {
|
|
59048
|
-
return !!node.parent;
|
|
59049
|
-
}
|
|
59050
|
-
var symbolToPrimitive = Symbol.toPrimitive;
|
|
59051
|
-
var symbolGetNode = Symbol("getNode");
|
|
59052
|
-
var symbolDelete = /* @__PURE__ */ Symbol("delete");
|
|
59053
|
-
var symbolOpaque = Symbol("opaque");
|
|
59054
|
-
var optimized = Symbol("optimized");
|
|
59055
|
-
var extraPrimitiveActivators = new Map;
|
|
59056
|
-
var extraPrimitiveProps = new Map;
|
|
59057
|
-
var globalState = {
|
|
59058
|
-
isLoadingLocal: false,
|
|
59059
|
-
isLoadingRemote: false,
|
|
59060
|
-
isMerging: false
|
|
59061
|
-
};
|
|
59062
|
-
function checkActivate(node) {
|
|
59063
|
-
var _a;
|
|
59064
|
-
const root = node.root;
|
|
59065
|
-
(_a = root.activate) === null || _a === undefined || _a.call(root);
|
|
59066
|
-
if (root.toActivate) {
|
|
59067
|
-
root.toActivate.forEach(checkActivate);
|
|
59068
|
-
delete root.toActivate;
|
|
59080
|
+
// src/exchanges/paper/engine-class.ts
|
|
59081
|
+
function generateSummary2({
|
|
59082
|
+
trades = [],
|
|
59083
|
+
fee_percent = 0.05,
|
|
59084
|
+
anchor
|
|
59085
|
+
}) {
|
|
59086
|
+
if (trades.length === 0) {
|
|
59087
|
+
return {};
|
|
59069
59088
|
}
|
|
59089
|
+
const avg_entry = trades[0].avg_entry;
|
|
59090
|
+
const avg_size = trades[0].avg_size;
|
|
59091
|
+
const expected_fee = avg_entry * avg_size * fee_percent / 100;
|
|
59092
|
+
return {
|
|
59093
|
+
first_entry: trades.at(-1).entry,
|
|
59094
|
+
last_entry: trades[0].entry,
|
|
59095
|
+
quantity: avg_size,
|
|
59096
|
+
entry: avg_entry,
|
|
59097
|
+
loss: trades[0].neg_pnl,
|
|
59098
|
+
number_of_trades: trades.length,
|
|
59099
|
+
fee: to_f(expected_fee, "%.2f"),
|
|
59100
|
+
anchor_pnl: anchor?.target_pnl
|
|
59101
|
+
};
|
|
59070
59102
|
}
|
|
59071
|
-
function
|
|
59072
|
-
|
|
59103
|
+
function cumulativeHelper({
|
|
59104
|
+
tradesList,
|
|
59105
|
+
pos = {
|
|
59106
|
+
quantity: 0,
|
|
59107
|
+
entry: 0
|
|
59108
|
+
},
|
|
59109
|
+
decimal_places = "%.3f"
|
|
59110
|
+
}) {
|
|
59111
|
+
let cumulativeQty = pos.quantity || 0;
|
|
59112
|
+
const reversedTrades = [...tradesList].reverse();
|
|
59113
|
+
const processedTrades = reversedTrades.map((trade) => {
|
|
59114
|
+
cumulativeQty += trade.quantity;
|
|
59115
|
+
const avg_size = to_f(cumulativeQty, decimal_places);
|
|
59116
|
+
return {
|
|
59117
|
+
...trade,
|
|
59118
|
+
cumulative_size: avg_size
|
|
59119
|
+
};
|
|
59120
|
+
});
|
|
59121
|
+
return processedTrades.reverse();
|
|
59073
59122
|
}
|
|
59074
|
-
|
|
59075
|
-
|
|
59076
|
-
|
|
59077
|
-
|
|
59078
|
-
|
|
59079
|
-
|
|
59080
|
-
|
|
59081
|
-
|
|
59082
|
-
|
|
59083
|
-
|
|
59084
|
-
|
|
59085
|
-
|
|
59086
|
-
|
|
59087
|
-
|
|
59088
|
-
|
|
59089
|
-
|
|
59090
|
-
|
|
59123
|
+
|
|
59124
|
+
class PositionState {
|
|
59125
|
+
position;
|
|
59126
|
+
trades;
|
|
59127
|
+
take_profit = null;
|
|
59128
|
+
stop_loss = null;
|
|
59129
|
+
entry_fees;
|
|
59130
|
+
fee_percent;
|
|
59131
|
+
global_config;
|
|
59132
|
+
constructor({
|
|
59133
|
+
position: position2,
|
|
59134
|
+
trades,
|
|
59135
|
+
fee_percent = 0,
|
|
59136
|
+
entry_fees = 0,
|
|
59137
|
+
global_config
|
|
59138
|
+
}) {
|
|
59139
|
+
this.position = position2;
|
|
59140
|
+
this.trades = trades ?? [];
|
|
59141
|
+
this.entry_fees = entry_fees ?? 0;
|
|
59142
|
+
this.fee_percent = fee_percent ?? 0;
|
|
59143
|
+
this.global_config = global_config;
|
|
59144
|
+
}
|
|
59145
|
+
get newTrades() {
|
|
59146
|
+
const tradesList = this.trades;
|
|
59147
|
+
const pos = this.position;
|
|
59148
|
+
if (!tradesList || tradesList.length === 0) {
|
|
59149
|
+
return [];
|
|
59091
59150
|
}
|
|
59092
|
-
|
|
59093
|
-
|
|
59094
|
-
|
|
59095
|
-
|
|
59096
|
-
|
|
59097
|
-
|
|
59098
|
-
|
|
59099
|
-
|
|
59100
|
-
|
|
59101
|
-
|
|
59102
|
-
|
|
59103
|
-
|
|
59104
|
-
|
|
59105
|
-
|
|
59106
|
-
|
|
59107
|
-
|
|
59108
|
-
|
|
59109
|
-
|
|
59110
|
-
const key = arrNodeKeys[i2];
|
|
59111
|
-
child = key !== "size" && (child instanceof Map || child instanceof WeakMap) ? child.get(key) : child[key];
|
|
59151
|
+
let cumulativeQty = pos.quantity || 0;
|
|
59152
|
+
let cumulativeValue = cumulativeQty * (pos.entry || 0);
|
|
59153
|
+
const reversedTrades = [...tradesList].reverse();
|
|
59154
|
+
const processedTrades = reversedTrades.map((trade) => {
|
|
59155
|
+
cumulativeQty += trade.quantity;
|
|
59156
|
+
cumulativeValue += trade.quantity * trade.entry;
|
|
59157
|
+
const avg_entry = cumulativeQty > 0 ? to_f(cumulativeValue / cumulativeQty, this.global_config.price_places) : 0;
|
|
59158
|
+
const avg_size = to_f(cumulativeQty, this.global_config.decimal_places);
|
|
59159
|
+
const stop = trade.stop || pos.kind === "long" ? Math.min(...tradesList.map((o) => o.entry)) : Math.max(...tradesList.map((o) => o.entry));
|
|
59160
|
+
const neg_pnl = to_f(Math.abs(avg_entry - stop) * avg_size, this.global_config.price_places);
|
|
59161
|
+
return {
|
|
59162
|
+
...trade,
|
|
59163
|
+
avg_entry,
|
|
59164
|
+
avg_size,
|
|
59165
|
+
neg_pnl
|
|
59166
|
+
};
|
|
59167
|
+
});
|
|
59168
|
+
return processedTrades.reverse();
|
|
59112
59169
|
}
|
|
59113
|
-
|
|
59114
|
-
|
|
59115
|
-
|
|
59116
|
-
|
|
59117
|
-
|
|
59118
|
-
|
|
59119
|
-
|
|
59120
|
-
|
|
59121
|
-
|
|
59122
|
-
key,
|
|
59123
|
-
lazy: true
|
|
59170
|
+
generateSummary(fee_percentOverride) {
|
|
59171
|
+
const trades = this.newTrades;
|
|
59172
|
+
const fee_percent = fee_percentOverride ?? this.fee_percent;
|
|
59173
|
+
return {
|
|
59174
|
+
...generateSummary2({
|
|
59175
|
+
trades,
|
|
59176
|
+
fee_percent
|
|
59177
|
+
}),
|
|
59178
|
+
entry_fees: to_f(this.entry_fees, "%.2f")
|
|
59124
59179
|
};
|
|
59125
|
-
if (!node.children) {
|
|
59126
|
-
node.children = new Map;
|
|
59127
|
-
}
|
|
59128
|
-
node.children.set(key, child);
|
|
59129
|
-
}
|
|
59130
|
-
return child;
|
|
59131
|
-
}
|
|
59132
|
-
function ensureNodeValue(node) {
|
|
59133
|
-
let value2 = getNodeValue(node);
|
|
59134
|
-
if (!value2) {
|
|
59135
|
-
if (isChildNodeValue(node)) {
|
|
59136
|
-
const parent = ensureNodeValue(node.parent);
|
|
59137
|
-
value2 = parent[node.key] = {};
|
|
59138
|
-
} else {
|
|
59139
|
-
value2 = node.root._ = {};
|
|
59140
|
-
}
|
|
59141
59180
|
}
|
|
59142
|
-
|
|
59143
|
-
|
|
59144
|
-
function findIDKey(obj, node) {
|
|
59145
|
-
let idKey = isObject2(obj) ? "id" in obj ? "id" : ("key" in obj) ? "key" : ("_id" in obj) ? "_id" : ("__id" in obj) ? "__id" : undefined : undefined;
|
|
59146
|
-
if (!idKey && node.parent) {
|
|
59147
|
-
const keyExtractor = getNodeValue(node.parent)[node.key + "_keyExtractor"];
|
|
59148
|
-
if (keyExtractor && isFunction(keyExtractor)) {
|
|
59149
|
-
idKey = keyExtractor;
|
|
59150
|
-
}
|
|
59181
|
+
get summary() {
|
|
59182
|
+
return this.generateSummary();
|
|
59151
59183
|
}
|
|
59152
|
-
|
|
59153
|
-
|
|
59154
|
-
|
|
59155
|
-
|
|
59156
|
-
|
|
59184
|
+
positionAt(price) {
|
|
59185
|
+
const trades = this.newTrades;
|
|
59186
|
+
const kind = this.position.kind;
|
|
59187
|
+
const filtered = trades.filter((trade) => {
|
|
59188
|
+
if (kind === "long") {
|
|
59189
|
+
return trade.entry >= price;
|
|
59190
|
+
}
|
|
59191
|
+
return trade.entry <= price;
|
|
59192
|
+
});
|
|
59193
|
+
return filtered[0];
|
|
59157
59194
|
}
|
|
59158
|
-
|
|
59159
|
-
|
|
59160
|
-
|
|
59161
|
-
|
|
59162
|
-
|
|
59195
|
+
newPositionState(price) {
|
|
59196
|
+
const position2 = this.position;
|
|
59197
|
+
const trades = this.newTrades;
|
|
59198
|
+
const instance = this.positionAt(price);
|
|
59199
|
+
if (!instance) {
|
|
59200
|
+
return new PositionState({
|
|
59201
|
+
position: { ...position2 },
|
|
59202
|
+
trades,
|
|
59203
|
+
fee_percent: this.fee_percent,
|
|
59204
|
+
entry_fees: this.entry_fees,
|
|
59205
|
+
global_config: this.global_config
|
|
59206
|
+
});
|
|
59163
59207
|
}
|
|
59164
|
-
|
|
59165
|
-
|
|
59166
|
-
|
|
59167
|
-
|
|
59168
|
-
|
|
59169
|
-
}
|
|
59170
|
-
|
|
59171
|
-
|
|
59172
|
-
|
|
59173
|
-
|
|
59174
|
-
|
|
59175
|
-
let c = selector;
|
|
59176
|
-
if (isFunction(c)) {
|
|
59177
|
-
c = e2 ? c(e2) : c();
|
|
59208
|
+
return new PositionState({
|
|
59209
|
+
position: {
|
|
59210
|
+
...position2,
|
|
59211
|
+
entry: instance.avg_entry,
|
|
59212
|
+
quantity: instance.avg_size
|
|
59213
|
+
},
|
|
59214
|
+
trades,
|
|
59215
|
+
fee_percent: this.fee_percent,
|
|
59216
|
+
entry_fees: this.entry_fees,
|
|
59217
|
+
global_config: this.global_config
|
|
59218
|
+
});
|
|
59178
59219
|
}
|
|
59179
|
-
|
|
59180
|
-
|
|
59181
|
-
|
|
59182
|
-
|
|
59183
|
-
|
|
59184
|
-
if (root) {
|
|
59185
|
-
root.locked = value2;
|
|
59220
|
+
updateTakeProfit({ entry, quantity }) {
|
|
59221
|
+
this.take_profit = {
|
|
59222
|
+
price: entry,
|
|
59223
|
+
quantity: quantity ?? this.position.quantity
|
|
59224
|
+
};
|
|
59186
59225
|
}
|
|
59187
|
-
|
|
59188
|
-
|
|
59189
|
-
|
|
59190
|
-
|
|
59191
|
-
function replacer(_, value2) {
|
|
59192
|
-
if (value2 instanceof Map) {
|
|
59193
|
-
return {
|
|
59194
|
-
__LSType: "Map",
|
|
59195
|
-
value: Array.from(value2.entries())
|
|
59226
|
+
updateStopLoss(payload) {
|
|
59227
|
+
const { stop, quantity } = payload ?? {
|
|
59228
|
+
stop: this.newTrades[0].entry,
|
|
59229
|
+
quantity: this.summary.quantity
|
|
59196
59230
|
};
|
|
59197
|
-
|
|
59198
|
-
|
|
59199
|
-
|
|
59200
|
-
value: Array.from(value2)
|
|
59231
|
+
this.stop_loss = {
|
|
59232
|
+
price: stop,
|
|
59233
|
+
quantity
|
|
59201
59234
|
};
|
|
59202
|
-
} else {
|
|
59203
|
-
return value2;
|
|
59204
|
-
}
|
|
59205
|
-
}
|
|
59206
|
-
function reviver(_, value2) {
|
|
59207
|
-
if (typeof value2 === "object" && value2) {
|
|
59208
|
-
if (value2.__LSType === "Map") {
|
|
59209
|
-
return new Map(value2.value);
|
|
59210
|
-
} else if (value2.__LSType === "Set") {
|
|
59211
|
-
return new Set(value2.value);
|
|
59212
|
-
}
|
|
59213
|
-
}
|
|
59214
|
-
return value2;
|
|
59215
|
-
}
|
|
59216
|
-
function safeStringify(value2) {
|
|
59217
|
-
return JSON.stringify(value2, replacer);
|
|
59218
|
-
}
|
|
59219
|
-
function safeParse(value2) {
|
|
59220
|
-
return JSON.parse(value2, reviver);
|
|
59221
|
-
}
|
|
59222
|
-
function clone2(value2) {
|
|
59223
|
-
return safeParse(safeStringify(value2));
|
|
59224
|
-
}
|
|
59225
|
-
var timeout4;
|
|
59226
|
-
var numInBatch = 0;
|
|
59227
|
-
var isRunningBatch = false;
|
|
59228
|
-
var didDelayEndBatch = false;
|
|
59229
|
-
var _afterBatch = [];
|
|
59230
|
-
var _queuedBatches = [];
|
|
59231
|
-
var _batchMap = new Map;
|
|
59232
|
-
function onActionTimeout() {
|
|
59233
|
-
if (_batchMap.size > 0) {
|
|
59234
|
-
if (true) {
|
|
59235
|
-
console.error("Forcibly completing observableBatcher because end() was never called. This may be due to an uncaught error between begin() and end().");
|
|
59236
|
-
}
|
|
59237
|
-
endBatch(true);
|
|
59238
59235
|
}
|
|
59239
59236
|
}
|
|
59240
|
-
function
|
|
59241
|
-
|
|
59242
|
-
|
|
59243
|
-
|
|
59237
|
+
function determineNewPosition({
|
|
59238
|
+
position: position2,
|
|
59239
|
+
price,
|
|
59240
|
+
trades,
|
|
59241
|
+
global_config
|
|
59242
|
+
}) {
|
|
59243
|
+
const kind = position2.kind;
|
|
59244
|
+
const placed = trades.filter((t2) => {
|
|
59245
|
+
if (kind === "long") {
|
|
59246
|
+
return t2.entry >= price;
|
|
59244
59247
|
}
|
|
59245
|
-
|
|
59246
|
-
|
|
59247
|
-
|
|
59248
|
-
|
|
59249
|
-
|
|
59250
|
-
|
|
59251
|
-
|
|
59252
|
-
let o = cloned;
|
|
59253
|
-
if (path.length > 0) {
|
|
59254
|
-
let i3;
|
|
59255
|
-
for (i3 = 0;i3 < path.length - 1; i3++) {
|
|
59256
|
-
o = o[path[i3]];
|
|
59257
|
-
}
|
|
59258
|
-
const key = path[i3];
|
|
59259
|
-
if (o instanceof Map) {
|
|
59260
|
-
o.set(key, prevAtPath);
|
|
59261
|
-
} else {
|
|
59262
|
-
o[key] = prevAtPath;
|
|
59248
|
+
return t2.entry <= price;
|
|
59249
|
+
});
|
|
59250
|
+
const placeQty = placed.reduce((acc, trade) => acc + trade.quantity, 0);
|
|
59251
|
+
if (position2.quantity > 0) {
|
|
59252
|
+
const placed_less_than_entry = placed.filter((t2) => {
|
|
59253
|
+
if (kind === "long") {
|
|
59254
|
+
return t2.entry < position2.entry;
|
|
59263
59255
|
}
|
|
59264
|
-
|
|
59265
|
-
|
|
59266
|
-
|
|
59256
|
+
return t2.entry > position2.entry;
|
|
59257
|
+
});
|
|
59258
|
+
const avg = determine_average_entry_and_size(placed_less_than_entry.map((o) => ({
|
|
59259
|
+
price: o.entry,
|
|
59260
|
+
quantity: o.quantity
|
|
59261
|
+
})).concat([{ price: position2.entry, quantity: position2.quantity }]), global_config.decimal_places, global_config.price_places);
|
|
59262
|
+
position2.entry = avg.price;
|
|
59263
|
+
position2.quantity = avg.quantity;
|
|
59264
|
+
return position2;
|
|
59267
59265
|
}
|
|
59268
|
-
return
|
|
59269
|
-
|
|
59270
|
-
|
|
59271
|
-
|
|
59272
|
-
return createPreviousHandlerInner(value2, changes);
|
|
59266
|
+
return {
|
|
59267
|
+
...position2,
|
|
59268
|
+
entry: price,
|
|
59269
|
+
quantity: placeQty
|
|
59273
59270
|
};
|
|
59274
59271
|
}
|
|
59275
|
-
function
|
|
59276
|
-
|
|
59277
|
-
|
|
59278
|
-
|
|
59279
|
-
|
|
59280
|
-
|
|
59281
|
-
|
|
59282
|
-
|
|
59283
|
-
|
|
59284
|
-
|
|
59285
|
-
|
|
59286
|
-
|
|
59287
|
-
|
|
59288
|
-
|
|
59289
|
-
|
|
59290
|
-
if (immediate ? node.listenersImmediate : node.listeners) {
|
|
59291
|
-
const change = {
|
|
59292
|
-
path,
|
|
59293
|
-
pathTypes,
|
|
59294
|
-
valueAtPath,
|
|
59295
|
-
prevAtPath
|
|
59296
|
-
};
|
|
59297
|
-
const changeInBatch = changesInBatch.get(node);
|
|
59298
|
-
if (changeInBatch && path.length > 0) {
|
|
59299
|
-
const { changes } = changeInBatch;
|
|
59300
|
-
if (!isArraySubset(changes[0].path, change.path)) {
|
|
59301
|
-
changes.push(change);
|
|
59302
|
-
}
|
|
59303
|
-
} else {
|
|
59304
|
-
changesInBatch.set(node, {
|
|
59305
|
-
level,
|
|
59306
|
-
value: value2,
|
|
59307
|
-
whenOptimizedOnlyIf,
|
|
59308
|
-
changes: [change]
|
|
59309
|
-
});
|
|
59310
|
-
}
|
|
59311
|
-
}
|
|
59312
|
-
}
|
|
59313
|
-
function computeChangesRecursive(changesInBatch, node, value2, path, pathTypes, valueAtPath, prevAtPath, immediate, level, whenOptimizedOnlyIf) {
|
|
59314
|
-
computeChangesAtNode(changesInBatch, node, value2, path, pathTypes, valueAtPath, prevAtPath, immediate, level, whenOptimizedOnlyIf);
|
|
59315
|
-
if (node.linkedFromNodes) {
|
|
59316
|
-
for (const linkedFromNode of node.linkedFromNodes) {
|
|
59317
|
-
computeChangesAtNode(changesInBatch, linkedFromNode, value2, path, pathTypes, valueAtPath, prevAtPath, immediate, level, whenOptimizedOnlyIf);
|
|
59318
|
-
}
|
|
59319
|
-
}
|
|
59320
|
-
if (node.parent) {
|
|
59321
|
-
const parent = node.parent;
|
|
59322
|
-
if (parent) {
|
|
59323
|
-
const parentValue = getNodeValue(parent);
|
|
59324
|
-
computeChangesRecursive(changesInBatch, parent, parentValue, [node.key].concat(path), [getPathType(value2)].concat(pathTypes), valueAtPath, prevAtPath, immediate, level + 1, whenOptimizedOnlyIf);
|
|
59325
|
-
}
|
|
59326
|
-
}
|
|
59327
|
-
}
|
|
59328
|
-
function batchNotifyChanges(changesInBatch, immediate) {
|
|
59329
|
-
const listenersNotified = new Set;
|
|
59330
|
-
changesInBatch.forEach(({ changes, level, value: value2, whenOptimizedOnlyIf }, node) => {
|
|
59331
|
-
const listeners = immediate ? node.listenersImmediate : node.listeners;
|
|
59332
|
-
if (listeners) {
|
|
59333
|
-
let listenerParams;
|
|
59334
|
-
const arr = Array.from(listeners);
|
|
59335
|
-
for (let i2 = 0;i2 < arr.length; i2++) {
|
|
59336
|
-
const listenerFn = arr[i2];
|
|
59337
|
-
const { track, noArgs, listener } = listenerFn;
|
|
59338
|
-
if (!listenersNotified.has(listener)) {
|
|
59339
|
-
const ok = track === true ? level <= 0 : track === optimized ? whenOptimizedOnlyIf && level <= 0 : true;
|
|
59340
|
-
if (ok) {
|
|
59341
|
-
if (!noArgs && !listenerParams) {
|
|
59342
|
-
listenerParams = {
|
|
59343
|
-
value: value2,
|
|
59344
|
-
getPrevious: createPreviousHandler(value2, changes),
|
|
59345
|
-
changes
|
|
59346
|
-
};
|
|
59347
|
-
}
|
|
59348
|
-
if (!track) {
|
|
59349
|
-
listenersNotified.add(listener);
|
|
59350
|
-
}
|
|
59351
|
-
listener(listenerParams);
|
|
59352
|
-
}
|
|
59353
|
-
}
|
|
59354
|
-
}
|
|
59272
|
+
function positionAt({
|
|
59273
|
+
price,
|
|
59274
|
+
position: position2,
|
|
59275
|
+
trades = [],
|
|
59276
|
+
as_state = true,
|
|
59277
|
+
global_config
|
|
59278
|
+
}) {
|
|
59279
|
+
const kind = position2.kind;
|
|
59280
|
+
const fee_rate = {
|
|
59281
|
+
maker: 0.02,
|
|
59282
|
+
taker: 0.05
|
|
59283
|
+
};
|
|
59284
|
+
const placed = trades.filter((t2) => {
|
|
59285
|
+
if (kind === "long") {
|
|
59286
|
+
return t2.entry >= price;
|
|
59355
59287
|
}
|
|
59288
|
+
return t2.entry <= price;
|
|
59356
59289
|
});
|
|
59357
|
-
|
|
59358
|
-
|
|
59359
|
-
|
|
59360
|
-
_batchMap = new Map;
|
|
59361
|
-
const changesInBatch = new Map;
|
|
59362
|
-
map.forEach(({ value: value2, prev, level, whenOptimizedOnlyIf }, node) => {
|
|
59363
|
-
computeChangesRecursive(changesInBatch, node, value2, [], [], value2, prev, false, level, whenOptimizedOnlyIf);
|
|
59364
|
-
});
|
|
59365
|
-
batchNotifyChanges(changesInBatch, false);
|
|
59366
|
-
}
|
|
59367
|
-
function batch2(fn, onComplete) {
|
|
59368
|
-
if (onComplete) {
|
|
59369
|
-
if (isRunningBatch) {
|
|
59370
|
-
_queuedBatches.push([fn, onComplete]);
|
|
59371
|
-
return;
|
|
59372
|
-
} else {
|
|
59373
|
-
_afterBatch.push(onComplete);
|
|
59374
|
-
}
|
|
59375
|
-
}
|
|
59376
|
-
beginBatch();
|
|
59377
|
-
try {
|
|
59378
|
-
fn();
|
|
59379
|
-
} finally {
|
|
59380
|
-
endBatch();
|
|
59381
|
-
}
|
|
59382
|
-
}
|
|
59383
|
-
function beginBatch() {
|
|
59384
|
-
numInBatch++;
|
|
59385
|
-
if (!timeout4) {
|
|
59386
|
-
timeout4 = setTimeout(onActionTimeout, 0);
|
|
59387
|
-
}
|
|
59388
|
-
}
|
|
59389
|
-
function endBatch(force) {
|
|
59390
|
-
numInBatch--;
|
|
59391
|
-
if (numInBatch <= 0 || force) {
|
|
59392
|
-
if (isRunningBatch) {
|
|
59393
|
-
didDelayEndBatch = true;
|
|
59394
|
-
} else {
|
|
59395
|
-
if (timeout4) {
|
|
59396
|
-
clearTimeout(timeout4);
|
|
59397
|
-
timeout4 = undefined;
|
|
59398
|
-
}
|
|
59399
|
-
numInBatch = 0;
|
|
59400
|
-
const after = _afterBatch;
|
|
59401
|
-
if (after.length) {
|
|
59402
|
-
_afterBatch = [];
|
|
59403
|
-
}
|
|
59404
|
-
isRunningBatch = true;
|
|
59405
|
-
runBatch();
|
|
59406
|
-
isRunningBatch = false;
|
|
59407
|
-
for (let i2 = 0;i2 < after.length; i2++) {
|
|
59408
|
-
after[i2]();
|
|
59409
|
-
}
|
|
59410
|
-
if (didDelayEndBatch) {
|
|
59411
|
-
didDelayEndBatch = false;
|
|
59412
|
-
endBatch(true);
|
|
59413
|
-
}
|
|
59414
|
-
const queued = _queuedBatches;
|
|
59415
|
-
if (queued.length) {
|
|
59416
|
-
_queuedBatches = [];
|
|
59417
|
-
for (let i2 = 0;i2 < queued.length; i2++) {
|
|
59418
|
-
const [fn, onComplete] = queued[i2];
|
|
59419
|
-
batch2(fn, onComplete);
|
|
59420
|
-
}
|
|
59421
|
-
}
|
|
59422
|
-
}
|
|
59423
|
-
}
|
|
59424
|
-
}
|
|
59425
|
-
function createObservable(value2, makePrimitive, createObject, createPrimitive) {
|
|
59426
|
-
const valueIsPromise = isPromise(value2);
|
|
59427
|
-
const root = {
|
|
59428
|
-
_: value2
|
|
59429
|
-
};
|
|
59430
|
-
const node = {
|
|
59431
|
-
root,
|
|
59432
|
-
lazy: true
|
|
59433
|
-
};
|
|
59434
|
-
const prim = makePrimitive || isActualPrimitive(value2);
|
|
59435
|
-
const obs = prim ? new createPrimitive(node) : createObject(node);
|
|
59436
|
-
if (valueIsPromise) {
|
|
59437
|
-
extractPromise(node, value2);
|
|
59438
|
-
}
|
|
59439
|
-
return obs;
|
|
59440
|
-
}
|
|
59441
|
-
function onChange(node, callback, options = {}) {
|
|
59442
|
-
const { initial, immediate, noArgs } = options;
|
|
59443
|
-
const { trackingType } = options;
|
|
59444
|
-
let listeners = immediate ? node.listenersImmediate : node.listeners;
|
|
59445
|
-
if (!listeners) {
|
|
59446
|
-
listeners = new Set;
|
|
59447
|
-
if (immediate) {
|
|
59448
|
-
node.listenersImmediate = listeners;
|
|
59449
|
-
} else {
|
|
59450
|
-
node.listeners = listeners;
|
|
59290
|
+
const not_placed = trades.filter((t2) => {
|
|
59291
|
+
if (kind === "long") {
|
|
59292
|
+
return t2.entry < price;
|
|
59451
59293
|
}
|
|
59452
|
-
|
|
59453
|
-
|
|
59454
|
-
const
|
|
59455
|
-
|
|
59456
|
-
|
|
59457
|
-
|
|
59294
|
+
return t2.entry > price;
|
|
59295
|
+
});
|
|
59296
|
+
const placeQty = placed.reduce((acc, trade) => acc + trade.quantity, 0);
|
|
59297
|
+
const takerFee = price * placeQty * fee_rate.taker / 100;
|
|
59298
|
+
const makerFee = not_placed.reduce((acc, trade) => acc + trade.entry * trade.quantity * fee_rate.maker / 100, 0);
|
|
59299
|
+
const fee = to_f(takerFee + makerFee, "%.2f");
|
|
59300
|
+
const result = {
|
|
59301
|
+
trades: not_placed,
|
|
59302
|
+
position: determineNewPosition({
|
|
59303
|
+
global_config,
|
|
59304
|
+
position: { ...position2, kind },
|
|
59305
|
+
price,
|
|
59306
|
+
trades
|
|
59307
|
+
}),
|
|
59308
|
+
entry_fees: fee,
|
|
59309
|
+
fee_percent: fee_rate.maker,
|
|
59310
|
+
global_config
|
|
59458
59311
|
};
|
|
59459
|
-
|
|
59460
|
-
|
|
59461
|
-
|
|
59462
|
-
|
|
59463
|
-
|
|
59464
|
-
|
|
59465
|
-
|
|
59466
|
-
path: [],
|
|
59467
|
-
pathTypes: [],
|
|
59468
|
-
prevAtPath: value2,
|
|
59469
|
-
valueAtPath: value2
|
|
59470
|
-
}
|
|
59471
|
-
],
|
|
59472
|
-
getPrevious: () => {
|
|
59473
|
-
return;
|
|
59474
|
-
}
|
|
59312
|
+
if (as_state) {
|
|
59313
|
+
const derivedState = new PositionState({
|
|
59314
|
+
position: result.position,
|
|
59315
|
+
trades: result.trades,
|
|
59316
|
+
fee_percent: result.fee_percent,
|
|
59317
|
+
entry_fees: parseFloat(result.entry_fees) || 0,
|
|
59318
|
+
global_config
|
|
59475
59319
|
});
|
|
59320
|
+
return derivedState;
|
|
59476
59321
|
}
|
|
59477
|
-
return
|
|
59478
|
-
}
|
|
59479
|
-
var trackCount = 0;
|
|
59480
|
-
var trackingQueue = [];
|
|
59481
|
-
var tracking = {
|
|
59482
|
-
current: undefined
|
|
59483
|
-
};
|
|
59484
|
-
function beginTracking() {
|
|
59485
|
-
trackingQueue.push(tracking.current);
|
|
59486
|
-
trackCount++;
|
|
59487
|
-
tracking.current = {};
|
|
59488
|
-
}
|
|
59489
|
-
function endTracking() {
|
|
59490
|
-
trackCount--;
|
|
59491
|
-
if (trackCount < 0) {
|
|
59492
|
-
trackCount = 0;
|
|
59493
|
-
}
|
|
59494
|
-
tracking.current = trackingQueue.pop();
|
|
59495
|
-
}
|
|
59496
|
-
function updateTracking(node, track) {
|
|
59497
|
-
if (trackCount) {
|
|
59498
|
-
const tracker = tracking.current;
|
|
59499
|
-
if (tracker) {
|
|
59500
|
-
if (!tracker.nodes) {
|
|
59501
|
-
tracker.nodes = new Map;
|
|
59502
|
-
}
|
|
59503
|
-
const existing = tracker.nodes.get(node);
|
|
59504
|
-
if (existing) {
|
|
59505
|
-
existing.track = existing.track || track;
|
|
59506
|
-
existing.num++;
|
|
59507
|
-
} else {
|
|
59508
|
-
tracker.nodes.set(node, { node, track, num: 1 });
|
|
59509
|
-
}
|
|
59510
|
-
}
|
|
59511
|
-
}
|
|
59512
|
-
}
|
|
59513
|
-
var ArrayModifiers = new Set([
|
|
59514
|
-
"copyWithin",
|
|
59515
|
-
"fill",
|
|
59516
|
-
"from",
|
|
59517
|
-
"pop",
|
|
59518
|
-
"push",
|
|
59519
|
-
"reverse",
|
|
59520
|
-
"shift",
|
|
59521
|
-
"sort",
|
|
59522
|
-
"splice",
|
|
59523
|
-
"unshift"
|
|
59524
|
-
]);
|
|
59525
|
-
var ArrayLoopers = new Set([
|
|
59526
|
-
"every",
|
|
59527
|
-
"filter",
|
|
59528
|
-
"find",
|
|
59529
|
-
"findIndex",
|
|
59530
|
-
"forEach",
|
|
59531
|
-
"join",
|
|
59532
|
-
"map",
|
|
59533
|
-
"some"
|
|
59534
|
-
]);
|
|
59535
|
-
var ArrayLoopersReturn = new Set(["filter", "find"]);
|
|
59536
|
-
var observableProperties = new Map;
|
|
59537
|
-
var observableFns = new Map([
|
|
59538
|
-
["get", get3],
|
|
59539
|
-
["set", set],
|
|
59540
|
-
["peek", peek],
|
|
59541
|
-
["onChange", onChange],
|
|
59542
|
-
["assign", assign],
|
|
59543
|
-
["delete", deleteFn],
|
|
59544
|
-
["toggle", toggle]
|
|
59545
|
-
]);
|
|
59546
|
-
if (true) {
|
|
59547
|
-
__devUpdateNodes = new Set;
|
|
59548
|
-
}
|
|
59549
|
-
var __devUpdateNodes;
|
|
59550
|
-
function collectionSetter(node, target, prop, ...args) {
|
|
59551
|
-
var _a;
|
|
59552
|
-
const prevValue = isArray3(target) && target.slice() || target;
|
|
59553
|
-
const ret = target[prop].apply(target, args);
|
|
59554
|
-
if (node) {
|
|
59555
|
-
const hasParent = isChildNodeValue(node);
|
|
59556
|
-
const key = hasParent ? node.key : "_";
|
|
59557
|
-
const parentValue = hasParent ? getNodeValue(node.parent) : node.root;
|
|
59558
|
-
parentValue[key] = prevValue;
|
|
59559
|
-
setKey((_a = node.parent) !== null && _a !== undefined ? _a : node, key, target);
|
|
59560
|
-
}
|
|
59561
|
-
return ret;
|
|
59562
|
-
}
|
|
59563
|
-
function getKeys(obj, isArr, isMap2) {
|
|
59564
|
-
return isArr ? undefined : obj ? isMap2 ? Array.from(obj.keys()) : Object.keys(obj) : [];
|
|
59565
|
-
}
|
|
59566
|
-
function updateNodes(parent, obj, prevValue) {
|
|
59567
|
-
var _a, _b;
|
|
59568
|
-
if (typeof __devUpdateNodes !== "undefined" && isObject2(obj)) {
|
|
59569
|
-
if (__devUpdateNodes.has(obj)) {
|
|
59570
|
-
console.error("[legend-state] Circular reference detected in object. You may want to use opaqueObject to stop traversing child nodes.", obj);
|
|
59571
|
-
return false;
|
|
59572
|
-
}
|
|
59573
|
-
__devUpdateNodes.add(obj);
|
|
59574
|
-
}
|
|
59575
|
-
if (isObject2(obj) && obj[symbolOpaque] || isObject2(prevValue) && prevValue[symbolOpaque]) {
|
|
59576
|
-
const isDiff = obj !== prevValue;
|
|
59577
|
-
if (isDiff) {
|
|
59578
|
-
if (parent.listeners || parent.listenersImmediate) {
|
|
59579
|
-
notify(parent, obj, prevValue, 0);
|
|
59580
|
-
}
|
|
59581
|
-
}
|
|
59582
|
-
if (typeof __devUpdateNodes !== "undefined" && obj !== undefined) {
|
|
59583
|
-
__devUpdateNodes.delete(obj);
|
|
59584
|
-
}
|
|
59585
|
-
return isDiff;
|
|
59586
|
-
}
|
|
59587
|
-
const isArr = isArray3(obj);
|
|
59588
|
-
let prevChildrenById;
|
|
59589
|
-
let moved;
|
|
59590
|
-
const isMap2 = obj instanceof Map;
|
|
59591
|
-
const keys = getKeys(obj, isArr, isMap2);
|
|
59592
|
-
const keysPrev = getKeys(prevValue, isArr, isMap2);
|
|
59593
|
-
const length = ((_a = keys || obj) === null || _a === undefined ? undefined : _a.length) || 0;
|
|
59594
|
-
const lengthPrev = ((_b = keysPrev || prevValue) === null || _b === undefined ? undefined : _b.length) || 0;
|
|
59595
|
-
let idField;
|
|
59596
|
-
let isIdFieldFunction;
|
|
59597
|
-
let hasADiff = false;
|
|
59598
|
-
let retValue;
|
|
59599
|
-
if (isArr && isArray3(prevValue)) {
|
|
59600
|
-
if (prevValue.length > 0) {
|
|
59601
|
-
const firstPrevValue = prevValue[0];
|
|
59602
|
-
if (firstPrevValue !== undefined) {
|
|
59603
|
-
idField = findIDKey(firstPrevValue, parent);
|
|
59604
|
-
if (idField) {
|
|
59605
|
-
isIdFieldFunction = isFunction(idField);
|
|
59606
|
-
prevChildrenById = new Map;
|
|
59607
|
-
moved = [];
|
|
59608
|
-
const keysSeen = new Set;
|
|
59609
|
-
if (parent.children) {
|
|
59610
|
-
for (let i2 = 0;i2 < prevValue.length; i2++) {
|
|
59611
|
-
const p = prevValue[i2];
|
|
59612
|
-
if (p) {
|
|
59613
|
-
const child = parent.children.get(i2 + "");
|
|
59614
|
-
if (child) {
|
|
59615
|
-
const key = isIdFieldFunction ? idField(p) : p[idField];
|
|
59616
|
-
if (true) {
|
|
59617
|
-
if (keysSeen.has(key)) {
|
|
59618
|
-
console.warn(`[legend-state] Warning: Multiple elements in array have the same ID. Key field: ${idField}, Array:`, prevValue);
|
|
59619
|
-
}
|
|
59620
|
-
keysSeen.add(key);
|
|
59621
|
-
}
|
|
59622
|
-
prevChildrenById.set(key, child);
|
|
59623
|
-
}
|
|
59624
|
-
}
|
|
59625
|
-
}
|
|
59626
|
-
}
|
|
59627
|
-
}
|
|
59628
|
-
}
|
|
59629
|
-
}
|
|
59630
|
-
} else if (prevValue && (!obj || isObject2(obj))) {
|
|
59631
|
-
const lengthPrev2 = keysPrev.length;
|
|
59632
|
-
for (let i2 = 0;i2 < lengthPrev2; i2++) {
|
|
59633
|
-
const key = keysPrev[i2];
|
|
59634
|
-
if (!keys.includes(key)) {
|
|
59635
|
-
hasADiff = true;
|
|
59636
|
-
const child = getChildNode(parent, key);
|
|
59637
|
-
const prev = isMap2 ? prevValue.get(key) : prevValue[key];
|
|
59638
|
-
if (prev !== undefined) {
|
|
59639
|
-
if (!isPrimitive2(prev)) {
|
|
59640
|
-
updateNodes(child, undefined, prev);
|
|
59641
|
-
}
|
|
59642
|
-
if (child.listeners || child.listenersImmediate) {
|
|
59643
|
-
notify(child, undefined, prev, 0);
|
|
59644
|
-
}
|
|
59645
|
-
}
|
|
59646
|
-
}
|
|
59647
|
-
}
|
|
59648
|
-
}
|
|
59649
|
-
if (obj && !isPrimitive2(obj)) {
|
|
59650
|
-
hasADiff = hasADiff || length !== lengthPrev;
|
|
59651
|
-
const isArrDiff = hasADiff;
|
|
59652
|
-
let didMove = false;
|
|
59653
|
-
for (let i2 = 0;i2 < length; i2++) {
|
|
59654
|
-
const key = isArr ? i2 + "" : keys[i2];
|
|
59655
|
-
const value2 = isMap2 ? obj.get(key) : obj[key];
|
|
59656
|
-
const prev = isMap2 ? prevValue === null || prevValue === undefined ? undefined : prevValue.get(key) : prevValue === null || prevValue === undefined ? undefined : prevValue[key];
|
|
59657
|
-
let isDiff = value2 !== prev;
|
|
59658
|
-
if (isDiff) {
|
|
59659
|
-
const id = idField && value2 ? isIdFieldFunction ? idField(value2) : value2[idField] : undefined;
|
|
59660
|
-
let child = getChildNode(parent, key);
|
|
59661
|
-
if (isArr && id !== undefined) {
|
|
59662
|
-
const prevChild = id !== undefined ? prevChildrenById === null || prevChildrenById === undefined ? undefined : prevChildrenById.get(id) : undefined;
|
|
59663
|
-
if (!prevChild) {
|
|
59664
|
-
isDiff = false;
|
|
59665
|
-
hasADiff = true;
|
|
59666
|
-
} else if (prevChild !== undefined && prevChild.key !== key) {
|
|
59667
|
-
const valuePrevChild = prevValue[prevChild.key];
|
|
59668
|
-
if (isArrDiff) {
|
|
59669
|
-
child = prevChild;
|
|
59670
|
-
parent.children.delete(child.key);
|
|
59671
|
-
child.key = key;
|
|
59672
|
-
moved.push([key, child]);
|
|
59673
|
-
}
|
|
59674
|
-
didMove = true;
|
|
59675
|
-
isDiff = valuePrevChild !== value2;
|
|
59676
|
-
}
|
|
59677
|
-
}
|
|
59678
|
-
if (isDiff) {
|
|
59679
|
-
if (isPrimitive2(value2)) {
|
|
59680
|
-
hasADiff = true;
|
|
59681
|
-
} else {
|
|
59682
|
-
const updatedNodes = updateNodes(child, value2, prev);
|
|
59683
|
-
hasADiff = hasADiff || updatedNodes;
|
|
59684
|
-
}
|
|
59685
|
-
}
|
|
59686
|
-
if (isDiff || !isArrDiff) {
|
|
59687
|
-
if (child.listeners || child.listenersImmediate) {
|
|
59688
|
-
notify(child, value2, prev, 0, !isArrDiff);
|
|
59689
|
-
}
|
|
59690
|
-
}
|
|
59691
|
-
}
|
|
59692
|
-
}
|
|
59693
|
-
if (moved) {
|
|
59694
|
-
for (let i2 = 0;i2 < moved.length; i2++) {
|
|
59695
|
-
const [key, child] = moved[i2];
|
|
59696
|
-
parent.children.set(key, child);
|
|
59697
|
-
}
|
|
59698
|
-
}
|
|
59699
|
-
retValue = hasADiff || didMove;
|
|
59700
|
-
} else if (prevValue !== undefined) {
|
|
59701
|
-
retValue = true;
|
|
59702
|
-
}
|
|
59703
|
-
if (typeof __devUpdateNodes !== "undefined" && obj !== undefined) {
|
|
59704
|
-
__devUpdateNodes.delete(obj);
|
|
59705
|
-
}
|
|
59706
|
-
return retValue !== null && retValue !== undefined ? retValue : false;
|
|
59707
|
-
}
|
|
59708
|
-
function getProxy(node, p) {
|
|
59709
|
-
if (p !== undefined)
|
|
59710
|
-
node = getChildNode(node, p);
|
|
59711
|
-
return node.proxy || (node.proxy = new Proxy(node, proxyHandler));
|
|
59712
|
-
}
|
|
59713
|
-
var proxyHandler = {
|
|
59714
|
-
get(node, p, receiver) {
|
|
59715
|
-
var _a;
|
|
59716
|
-
if (p === symbolToPrimitive) {
|
|
59717
|
-
throw new Error("[legend-state] observable should not be used as a primitive. You may have forgotten to use .get() or .peek() to get the value of the observable.");
|
|
59718
|
-
}
|
|
59719
|
-
if (p === symbolGetNode) {
|
|
59720
|
-
return node;
|
|
59721
|
-
}
|
|
59722
|
-
const value2 = peek(node);
|
|
59723
|
-
if (node.linkedToNode && p !== "onChange") {
|
|
59724
|
-
return proxyHandler.get(node.linkedToNode, p, receiver);
|
|
59725
|
-
}
|
|
59726
|
-
if (value2 instanceof Map || value2 instanceof WeakMap || value2 instanceof Set || value2 instanceof WeakSet) {
|
|
59727
|
-
const ret = handlerMapSet(node, p, value2);
|
|
59728
|
-
if (ret !== undefined) {
|
|
59729
|
-
return ret;
|
|
59730
|
-
}
|
|
59731
|
-
}
|
|
59732
|
-
const fn = observableFns.get(p);
|
|
59733
|
-
if (fn) {
|
|
59734
|
-
return function(a, b, c) {
|
|
59735
|
-
const l = arguments.length;
|
|
59736
|
-
switch (l) {
|
|
59737
|
-
case 0:
|
|
59738
|
-
return fn(node);
|
|
59739
|
-
case 1:
|
|
59740
|
-
return fn(node, a);
|
|
59741
|
-
case 2:
|
|
59742
|
-
return fn(node, a, b);
|
|
59743
|
-
default:
|
|
59744
|
-
return fn(node, a, b, c);
|
|
59745
|
-
}
|
|
59746
|
-
};
|
|
59747
|
-
}
|
|
59748
|
-
if (node.isComputed) {
|
|
59749
|
-
if (node.proxyFn && !fn) {
|
|
59750
|
-
return node.proxyFn(p);
|
|
59751
|
-
} else {
|
|
59752
|
-
checkActivate(node);
|
|
59753
|
-
}
|
|
59754
|
-
}
|
|
59755
|
-
const property = observableProperties.get(p);
|
|
59756
|
-
if (property) {
|
|
59757
|
-
return property.get(node);
|
|
59758
|
-
}
|
|
59759
|
-
const isValuePrimitive = isPrimitive2(value2);
|
|
59760
|
-
if (value2 === undefined || value2 === null || isValuePrimitive) {
|
|
59761
|
-
if (extraPrimitiveProps.size && (node.isActivatedPrimitive || extraPrimitiveActivators.has(p))) {
|
|
59762
|
-
node.isActivatedPrimitive = true;
|
|
59763
|
-
const vPrim = extraPrimitiveProps.get(p);
|
|
59764
|
-
if (vPrim !== undefined) {
|
|
59765
|
-
return isFunction(vPrim) ? vPrim(getProxy(node)) : vPrim;
|
|
59766
|
-
}
|
|
59767
|
-
}
|
|
59768
|
-
}
|
|
59769
|
-
const vProp = value2 === null || value2 === undefined ? undefined : value2[p];
|
|
59770
|
-
if (isObject2(value2) && value2[symbolOpaque]) {
|
|
59771
|
-
return vProp;
|
|
59772
|
-
}
|
|
59773
|
-
if (isFunction(vProp)) {
|
|
59774
|
-
if (isArray3(value2)) {
|
|
59775
|
-
if (ArrayModifiers.has(p)) {
|
|
59776
|
-
return (...args) => collectionSetter(node, value2, p, ...args);
|
|
59777
|
-
} else if (ArrayLoopers.has(p)) {
|
|
59778
|
-
updateTracking(node);
|
|
59779
|
-
return function(cbOrig, thisArg) {
|
|
59780
|
-
function cbWrapped(_, index, array) {
|
|
59781
|
-
return cbOrig(getProxy(node, index + ""), index, array);
|
|
59782
|
-
}
|
|
59783
|
-
if (ArrayLoopersReturn.has(p)) {
|
|
59784
|
-
const isFind = p === "find";
|
|
59785
|
-
const out = [];
|
|
59786
|
-
for (let i2 = 0;i2 < value2.length; i2++) {
|
|
59787
|
-
if (cbWrapped(value2[i2], i2, value2)) {
|
|
59788
|
-
const proxy = getProxy(node, i2 + "");
|
|
59789
|
-
if (isFind) {
|
|
59790
|
-
return proxy;
|
|
59791
|
-
} else {
|
|
59792
|
-
out.push(proxy);
|
|
59793
|
-
}
|
|
59794
|
-
}
|
|
59795
|
-
}
|
|
59796
|
-
return isFind ? undefined : out;
|
|
59797
|
-
} else {
|
|
59798
|
-
return value2[p](cbWrapped, thisArg);
|
|
59799
|
-
}
|
|
59800
|
-
};
|
|
59801
|
-
}
|
|
59802
|
-
}
|
|
59803
|
-
return vProp.bind(value2);
|
|
59804
|
-
}
|
|
59805
|
-
if (isPrimitive2(vProp)) {
|
|
59806
|
-
if (isArray3(value2) && p === "length") {
|
|
59807
|
-
updateTracking(node, true);
|
|
59808
|
-
return vProp;
|
|
59809
|
-
}
|
|
59810
|
-
}
|
|
59811
|
-
const fnOrComputed = (_a = node.functions) === null || _a === undefined ? undefined : _a.get(p);
|
|
59812
|
-
if (fnOrComputed) {
|
|
59813
|
-
return fnOrComputed;
|
|
59814
|
-
}
|
|
59815
|
-
if (vProp === undefined && (p === "state" || p === "_state") && node.state) {
|
|
59816
|
-
return node.state;
|
|
59817
|
-
}
|
|
59818
|
-
return getProxy(node, p);
|
|
59819
|
-
},
|
|
59820
|
-
getPrototypeOf(node) {
|
|
59821
|
-
const value2 = getNodeValue(node);
|
|
59822
|
-
return value2 !== null && typeof value2 === "object" ? Reflect.getPrototypeOf(value2) : null;
|
|
59823
|
-
},
|
|
59824
|
-
ownKeys(node) {
|
|
59825
|
-
const value2 = getNodeValue(node);
|
|
59826
|
-
if (isPrimitive2(value2))
|
|
59827
|
-
return [];
|
|
59828
|
-
const keys = value2 ? Reflect.ownKeys(value2) : [];
|
|
59829
|
-
updateTracking(node, true);
|
|
59830
|
-
if (isArray3(value2) && keys[keys.length - 1] === "length") {
|
|
59831
|
-
keys.splice(keys.length - 1, 1);
|
|
59832
|
-
}
|
|
59833
|
-
return keys;
|
|
59834
|
-
},
|
|
59835
|
-
getOwnPropertyDescriptor(node, prop) {
|
|
59836
|
-
const value2 = getNodeValue(node);
|
|
59837
|
-
return !isPrimitive2(value2) ? Reflect.getOwnPropertyDescriptor(value2, prop) : undefined;
|
|
59838
|
-
},
|
|
59839
|
-
set(node, prop, value2) {
|
|
59840
|
-
if (node.isSetting) {
|
|
59841
|
-
return Reflect.set(node, prop, value2);
|
|
59842
|
-
}
|
|
59843
|
-
if (node.isAssigning) {
|
|
59844
|
-
setKey(node, prop, value2);
|
|
59845
|
-
return true;
|
|
59846
|
-
}
|
|
59847
|
-
const property = observableProperties.get(prop);
|
|
59848
|
-
if (property) {
|
|
59849
|
-
property.set(node, value2);
|
|
59850
|
-
return true;
|
|
59851
|
-
}
|
|
59852
|
-
if (true) {
|
|
59853
|
-
console.warn("[legend-state]: Error: Cannot set a value directly:", prop, value2);
|
|
59854
|
-
}
|
|
59855
|
-
return false;
|
|
59856
|
-
},
|
|
59857
|
-
deleteProperty(node, prop) {
|
|
59858
|
-
if (node.isSetting) {
|
|
59859
|
-
return Reflect.deleteProperty(node, prop);
|
|
59860
|
-
} else {
|
|
59861
|
-
if (true) {
|
|
59862
|
-
console.warn("[legend-state]: Error: Cannot delete a value directly:", prop);
|
|
59863
|
-
}
|
|
59864
|
-
return false;
|
|
59865
|
-
}
|
|
59866
|
-
},
|
|
59867
|
-
has(node, prop) {
|
|
59868
|
-
const value2 = getNodeValue(node);
|
|
59869
|
-
return Reflect.has(value2, prop);
|
|
59870
|
-
}
|
|
59871
|
-
};
|
|
59872
|
-
function set(node, newValue) {
|
|
59873
|
-
if (node.parent) {
|
|
59874
|
-
return setKey(node.parent, node.key, newValue);
|
|
59875
|
-
} else {
|
|
59876
|
-
return setKey(node, "_", newValue);
|
|
59877
|
-
}
|
|
59878
|
-
}
|
|
59879
|
-
function toggle(node) {
|
|
59880
|
-
const value2 = getNodeValue(node);
|
|
59881
|
-
if (value2 === undefined || isBoolean2(value2)) {
|
|
59882
|
-
set(node, !value2);
|
|
59883
|
-
return !value2;
|
|
59884
|
-
} else if (true) {
|
|
59885
|
-
throw new Error("[legend-state] Cannot toggle a non-boolean value");
|
|
59886
|
-
}
|
|
59887
|
-
}
|
|
59888
|
-
function setKey(node, key, newValue, level) {
|
|
59889
|
-
if (true) {
|
|
59890
|
-
if (typeof HTMLElement !== "undefined" && newValue instanceof HTMLElement) {
|
|
59891
|
-
console.warn(`[legend-state] Set an HTMLElement into state. You probably don't want to do that.`);
|
|
59892
|
-
}
|
|
59893
|
-
}
|
|
59894
|
-
if (node.root.locked && !node.root.set) {
|
|
59895
|
-
if (globalState.isMerging) {
|
|
59896
|
-
return;
|
|
59897
|
-
} else {
|
|
59898
|
-
throw new Error("[legend-state] Cannot modify an observable while it is locked. Please make sure that you unlock the observable before making changes.");
|
|
59899
|
-
}
|
|
59900
|
-
}
|
|
59901
|
-
const isRoot = !node.parent && key === "_";
|
|
59902
|
-
const childNode = isRoot ? node : getChildNode(node, key);
|
|
59903
|
-
const { newValue: savedValue, prevValue, parentValue } = setNodeValue(childNode, newValue);
|
|
59904
|
-
const isFunc = isFunction(savedValue);
|
|
59905
|
-
const isPrim = isPrimitive2(savedValue) || savedValue instanceof Date;
|
|
59906
|
-
if (savedValue !== prevValue) {
|
|
59907
|
-
updateNodesAndNotify(node, savedValue, prevValue, childNode, isPrim, isRoot, level);
|
|
59908
|
-
}
|
|
59909
|
-
extractFunctionOrComputed(node, parentValue, key, savedValue);
|
|
59910
|
-
return isFunc ? savedValue : isRoot ? getProxy(node) : getProxy(node, key);
|
|
59911
|
-
}
|
|
59912
|
-
function assign(node, value2) {
|
|
59913
|
-
const proxy = getProxy(node);
|
|
59914
|
-
beginBatch();
|
|
59915
|
-
if (isPrimitive2(node.root._)) {
|
|
59916
|
-
node.root._ = {};
|
|
59917
|
-
}
|
|
59918
|
-
node.isAssigning = (node.isAssigning || 0) + 1;
|
|
59919
|
-
try {
|
|
59920
|
-
Object.assign(proxy, value2);
|
|
59921
|
-
} finally {
|
|
59922
|
-
node.isAssigning--;
|
|
59923
|
-
}
|
|
59924
|
-
endBatch();
|
|
59925
|
-
return proxy;
|
|
59926
|
-
}
|
|
59927
|
-
function deleteFn(node, key) {
|
|
59928
|
-
if (key === undefined && isChildNodeValue(node)) {
|
|
59929
|
-
key = node.key;
|
|
59930
|
-
node = node.parent;
|
|
59931
|
-
}
|
|
59932
|
-
setKey(node, key !== null && key !== undefined ? key : "_", symbolDelete, -1);
|
|
59933
|
-
}
|
|
59934
|
-
function handlerMapSet(node, p, value2) {
|
|
59935
|
-
const vProp = value2 === null || value2 === undefined ? undefined : value2[p];
|
|
59936
|
-
if (p === "size") {
|
|
59937
|
-
return getProxy(node, p);
|
|
59938
|
-
} else if (isFunction(vProp)) {
|
|
59939
|
-
return function(a, b, c) {
|
|
59940
|
-
const l = arguments.length;
|
|
59941
|
-
const valueMap = value2;
|
|
59942
|
-
if (p === "get") {
|
|
59943
|
-
if (l > 0 && typeof a !== "boolean" && a !== optimized) {
|
|
59944
|
-
return getProxy(node, a);
|
|
59945
|
-
}
|
|
59946
|
-
} else if (p === "set") {
|
|
59947
|
-
if (l === 2) {
|
|
59948
|
-
const prev = valueMap.get(a);
|
|
59949
|
-
const ret = valueMap.set(a, b);
|
|
59950
|
-
if (prev !== b) {
|
|
59951
|
-
updateNodesAndNotify(getChildNode(node, a), b, prev);
|
|
59952
|
-
}
|
|
59953
|
-
return ret;
|
|
59954
|
-
}
|
|
59955
|
-
} else if (p === "delete") {
|
|
59956
|
-
if (l > 0) {
|
|
59957
|
-
const prev = value2.get ? valueMap.get(a) : a;
|
|
59958
|
-
const ret = value2.delete(a);
|
|
59959
|
-
if (ret) {
|
|
59960
|
-
updateNodesAndNotify(getChildNode(node, a), undefined, prev);
|
|
59961
|
-
}
|
|
59962
|
-
return ret;
|
|
59963
|
-
}
|
|
59964
|
-
} else if (p === "clear") {
|
|
59965
|
-
const prev = new Map(valueMap);
|
|
59966
|
-
const size = valueMap.size;
|
|
59967
|
-
valueMap.clear();
|
|
59968
|
-
if (size) {
|
|
59969
|
-
updateNodesAndNotify(node, value2, prev);
|
|
59970
|
-
}
|
|
59971
|
-
return;
|
|
59972
|
-
} else if (p === "add") {
|
|
59973
|
-
const prev = new Set(value2);
|
|
59974
|
-
const ret = value2.add(a);
|
|
59975
|
-
if (!value2.has(p)) {
|
|
59976
|
-
notify(node, ret, prev, 0);
|
|
59977
|
-
}
|
|
59978
|
-
return ret;
|
|
59979
|
-
}
|
|
59980
|
-
const fn = observableFns.get(p);
|
|
59981
|
-
if (fn) {
|
|
59982
|
-
switch (l) {
|
|
59983
|
-
case 0:
|
|
59984
|
-
return fn(node);
|
|
59985
|
-
case 1:
|
|
59986
|
-
return fn(node, a);
|
|
59987
|
-
case 2:
|
|
59988
|
-
return fn(node, a, b);
|
|
59989
|
-
default:
|
|
59990
|
-
return fn(node, a, b, c);
|
|
59991
|
-
}
|
|
59992
|
-
} else {
|
|
59993
|
-
return value2[p](a, b);
|
|
59994
|
-
}
|
|
59995
|
-
};
|
|
59996
|
-
}
|
|
59997
|
-
}
|
|
59998
|
-
function updateNodesAndNotify(node, newValue, prevValue, childNode, isPrim, isRoot, level) {
|
|
59999
|
-
if (!childNode)
|
|
60000
|
-
childNode = node;
|
|
60001
|
-
beginBatch();
|
|
60002
|
-
if (isPrim === undefined) {
|
|
60003
|
-
isPrim = isPrimitive2(newValue);
|
|
60004
|
-
}
|
|
60005
|
-
let hasADiff = isPrim;
|
|
60006
|
-
let whenOptimizedOnlyIf = false;
|
|
60007
|
-
if (!isPrim || prevValue && !isPrimitive2(prevValue)) {
|
|
60008
|
-
if (typeof __devUpdateNodes !== "undefined") {
|
|
60009
|
-
__devUpdateNodes.clear();
|
|
60010
|
-
}
|
|
60011
|
-
hasADiff = updateNodes(childNode, newValue, prevValue);
|
|
60012
|
-
if (isArray3(newValue)) {
|
|
60013
|
-
whenOptimizedOnlyIf = (newValue === null || newValue === undefined ? undefined : newValue.length) !== (prevValue === null || prevValue === undefined ? undefined : prevValue.length);
|
|
60014
|
-
}
|
|
60015
|
-
}
|
|
60016
|
-
if (isPrim || !newValue || isEmpty(newValue) && !isEmpty(prevValue) ? newValue !== prevValue : hasADiff) {
|
|
60017
|
-
notify(isPrim && isRoot ? node : childNode, newValue, prevValue, (level !== null && level !== undefined ? level : prevValue === undefined) ? -1 : hasADiff ? 0 : 1, whenOptimizedOnlyIf);
|
|
60018
|
-
}
|
|
60019
|
-
endBatch();
|
|
60020
|
-
}
|
|
60021
|
-
function extractPromise(node, value2) {
|
|
60022
|
-
if (!node.state) {
|
|
60023
|
-
node.state = createObservable({
|
|
60024
|
-
isLoaded: false
|
|
60025
|
-
}, false, getProxy);
|
|
60026
|
-
}
|
|
60027
|
-
value2.then((value3) => {
|
|
60028
|
-
set(node, value3);
|
|
60029
|
-
node.state.isLoaded.set(true);
|
|
60030
|
-
}).catch((error) => {
|
|
60031
|
-
node.state.error.set(error);
|
|
60032
|
-
});
|
|
60033
|
-
}
|
|
60034
|
-
function extractFunctionOrComputed(node, obj, k, v) {
|
|
60035
|
-
if (isPromise(v)) {
|
|
60036
|
-
extractPromise(getChildNode(node, k), v);
|
|
60037
|
-
} else if (typeof v === "function") {
|
|
60038
|
-
extractFunction(node, k, v);
|
|
60039
|
-
} else if (typeof v == "object" && v !== null && v !== undefined) {
|
|
60040
|
-
const childNode = getNode(v);
|
|
60041
|
-
if (childNode === null || childNode === undefined ? undefined : childNode.isComputed) {
|
|
60042
|
-
extractFunction(node, k, v, childNode);
|
|
60043
|
-
delete obj[k];
|
|
60044
|
-
} else {
|
|
60045
|
-
return true;
|
|
60046
|
-
}
|
|
60047
|
-
}
|
|
60048
|
-
}
|
|
60049
|
-
function get3(node, options) {
|
|
60050
|
-
const track = options ? isObject2(options) ? options.shallow : options : undefined;
|
|
60051
|
-
updateTracking(node, track);
|
|
60052
|
-
return peek(node);
|
|
60053
|
-
}
|
|
60054
|
-
function peek(node) {
|
|
60055
|
-
const value2 = getNodeValue(node);
|
|
60056
|
-
if (node.lazy) {
|
|
60057
|
-
delete node.lazy;
|
|
60058
|
-
for (const key in value2) {
|
|
60059
|
-
if (hasOwnProperty.call(value2, key)) {
|
|
60060
|
-
extractFunctionOrComputed(node, value2, key, value2[key]);
|
|
60061
|
-
}
|
|
60062
|
-
}
|
|
60063
|
-
}
|
|
60064
|
-
checkActivate(node);
|
|
60065
|
-
return value2;
|
|
60066
|
-
}
|
|
60067
|
-
var fns = ["get", "set", "peek", "onChange", "toggle"];
|
|
60068
|
-
function ObservablePrimitiveClass(node) {
|
|
60069
|
-
this._node = node;
|
|
60070
|
-
for (let i2 = 0;i2 < fns.length; i2++) {
|
|
60071
|
-
const key = fns[i2];
|
|
60072
|
-
this[key] = this[key].bind(this);
|
|
60073
|
-
}
|
|
60074
|
-
}
|
|
60075
|
-
function proto(key, fn) {
|
|
60076
|
-
ObservablePrimitiveClass.prototype[key] = function(...args) {
|
|
60077
|
-
return fn.call(this, this._node, ...args);
|
|
60078
|
-
};
|
|
60079
|
-
}
|
|
60080
|
-
proto("peek", peek);
|
|
60081
|
-
proto("get", get3);
|
|
60082
|
-
proto("set", set);
|
|
60083
|
-
proto("onChange", onChange);
|
|
60084
|
-
Object.defineProperty(ObservablePrimitiveClass.prototype, symbolGetNode, {
|
|
60085
|
-
configurable: true,
|
|
60086
|
-
get() {
|
|
60087
|
-
return this._node;
|
|
60088
|
-
}
|
|
60089
|
-
});
|
|
60090
|
-
ObservablePrimitiveClass.prototype.toggle = function() {
|
|
60091
|
-
const value2 = this.peek();
|
|
60092
|
-
if (value2 === undefined || isBoolean2(value2)) {
|
|
60093
|
-
this.set(!value2);
|
|
60094
|
-
} else if (true) {
|
|
60095
|
-
throw new Error("[legend-state] Cannot toggle a non-boolean value");
|
|
60096
|
-
}
|
|
60097
|
-
return !value2;
|
|
60098
|
-
};
|
|
60099
|
-
ObservablePrimitiveClass.prototype.delete = function() {
|
|
60100
|
-
this.set(undefined);
|
|
60101
|
-
return this;
|
|
60102
|
-
};
|
|
60103
|
-
function observable(value2) {
|
|
60104
|
-
return createObservable(value2, false, getProxy, ObservablePrimitiveClass);
|
|
60105
|
-
}
|
|
60106
|
-
function setupTracking(nodes, update, noArgs, immediate) {
|
|
60107
|
-
let listeners = [];
|
|
60108
|
-
nodes === null || nodes === undefined || nodes.forEach((tracked) => {
|
|
60109
|
-
const { node, track } = tracked;
|
|
60110
|
-
listeners.push(onChange(node, update, { trackingType: track, immediate, noArgs }));
|
|
60111
|
-
});
|
|
60112
|
-
return () => {
|
|
60113
|
-
if (listeners) {
|
|
60114
|
-
for (let i2 = 0;i2 < listeners.length; i2++) {
|
|
60115
|
-
listeners[i2]();
|
|
60116
|
-
}
|
|
60117
|
-
listeners = undefined;
|
|
60118
|
-
}
|
|
60119
|
-
};
|
|
60120
|
-
}
|
|
60121
|
-
function trackSelector(selector, update, observeEvent, observeOptions, createResubscribe) {
|
|
60122
|
-
var _a;
|
|
60123
|
-
let dispose;
|
|
60124
|
-
let resubscribe;
|
|
60125
|
-
let updateFn = update;
|
|
60126
|
-
beginTracking();
|
|
60127
|
-
const value2 = selector ? computeSelector(selector, observeEvent, observeOptions === null || observeOptions === undefined ? undefined : observeOptions.fromComputed) : selector;
|
|
60128
|
-
const tracker = tracking.current;
|
|
60129
|
-
const nodes = tracker.nodes;
|
|
60130
|
-
endTracking();
|
|
60131
|
-
if (tracker && nodes) {
|
|
60132
|
-
(_a = tracker.traceListeners) === null || _a === undefined || _a.call(tracker, nodes);
|
|
60133
|
-
if (tracker.traceUpdates) {
|
|
60134
|
-
updateFn = tracker.traceUpdates(update);
|
|
60135
|
-
}
|
|
60136
|
-
tracker.traceListeners = undefined;
|
|
60137
|
-
tracker.traceUpdates = undefined;
|
|
60138
|
-
}
|
|
60139
|
-
if (!(observeEvent === null || observeEvent === undefined ? undefined : observeEvent.cancel)) {
|
|
60140
|
-
dispose = setupTracking(nodes, updateFn, false, observeOptions === null || observeOptions === undefined ? undefined : observeOptions.immediate);
|
|
60141
|
-
if (true) {
|
|
60142
|
-
resubscribe = createResubscribe ? () => {
|
|
60143
|
-
dispose === null || dispose === undefined || dispose();
|
|
60144
|
-
dispose = setupTracking(nodes, updateFn);
|
|
60145
|
-
return dispose;
|
|
60146
|
-
} : undefined;
|
|
60147
|
-
}
|
|
60148
|
-
}
|
|
60149
|
-
return { value: value2, dispose, resubscribe };
|
|
60150
|
-
}
|
|
60151
|
-
function observe(selectorOrRun, reactionOrOptions, options) {
|
|
60152
|
-
let reaction;
|
|
60153
|
-
if (isFunction(reactionOrOptions)) {
|
|
60154
|
-
reaction = reactionOrOptions;
|
|
60155
|
-
} else {
|
|
60156
|
-
options = reactionOrOptions;
|
|
60157
|
-
}
|
|
60158
|
-
let dispose;
|
|
60159
|
-
const e2 = { num: 0 };
|
|
60160
|
-
const update = function() {
|
|
60161
|
-
if (e2.onCleanup) {
|
|
60162
|
-
e2.onCleanup();
|
|
60163
|
-
e2.onCleanup = undefined;
|
|
60164
|
-
}
|
|
60165
|
-
beginBatch();
|
|
60166
|
-
delete e2.value;
|
|
60167
|
-
dispose === null || dispose === undefined || dispose();
|
|
60168
|
-
const { dispose: _dispose, value: value2 } = trackSelector(selectorOrRun, update, e2, options);
|
|
60169
|
-
dispose = _dispose;
|
|
60170
|
-
e2.value = value2;
|
|
60171
|
-
if (e2.onCleanupReaction) {
|
|
60172
|
-
e2.onCleanupReaction();
|
|
60173
|
-
e2.onCleanupReaction = undefined;
|
|
60174
|
-
}
|
|
60175
|
-
endBatch();
|
|
60176
|
-
if (reaction && (e2.num > 0 || !isEvent(selectorOrRun)) && (e2.previous !== e2.value || (options === null || options === undefined ? undefined : options.fromComputed) || typeof e2.value === "object")) {
|
|
60177
|
-
reaction(e2);
|
|
60178
|
-
}
|
|
60179
|
-
e2.previous = e2.value;
|
|
60180
|
-
e2.num++;
|
|
60181
|
-
};
|
|
60182
|
-
update();
|
|
60183
|
-
return () => {
|
|
60184
|
-
var _a, _b;
|
|
60185
|
-
(_a = e2.onCleanup) === null || _a === undefined || _a.call(e2);
|
|
60186
|
-
e2.onCleanup = undefined;
|
|
60187
|
-
(_b = e2.onCleanupReaction) === null || _b === undefined || _b.call(e2);
|
|
60188
|
-
e2.onCleanupReaction = undefined;
|
|
60189
|
-
dispose === null || dispose === undefined || dispose();
|
|
60190
|
-
};
|
|
60191
|
-
}
|
|
60192
|
-
function computed(compute, set$1) {
|
|
60193
|
-
const obs = observable();
|
|
60194
|
-
lockObservable(obs, true);
|
|
60195
|
-
const node = getNode(obs);
|
|
60196
|
-
node.isComputed = true;
|
|
60197
|
-
let isSetAfterActivated = false;
|
|
60198
|
-
const setInner = function(val) {
|
|
60199
|
-
const prevNode = node.linkedToNode;
|
|
60200
|
-
if (prevNode) {
|
|
60201
|
-
prevNode.linkedFromNodes.delete(node);
|
|
60202
|
-
node.linkedToNode = undefined;
|
|
60203
|
-
}
|
|
60204
|
-
const { parentOther } = node;
|
|
60205
|
-
if (isObservable(val)) {
|
|
60206
|
-
const linkedNode = getNode(val);
|
|
60207
|
-
node.linkedToNode = linkedNode;
|
|
60208
|
-
if (!linkedNode.linkedFromNodes) {
|
|
60209
|
-
linkedNode.linkedFromNodes = new Set;
|
|
60210
|
-
}
|
|
60211
|
-
linkedNode.linkedFromNodes.add(node);
|
|
60212
|
-
if (node.parentOther) {
|
|
60213
|
-
onChange(linkedNode, ({ value: value2 }) => {
|
|
60214
|
-
setNodeValue(node.parentOther, value2);
|
|
60215
|
-
}, { initial: true });
|
|
60216
|
-
}
|
|
60217
|
-
if (prevNode) {
|
|
60218
|
-
const value2 = getNodeValue(linkedNode);
|
|
60219
|
-
const prevValue = getNodeValue(prevNode);
|
|
60220
|
-
notify(node, value2, prevValue, 0);
|
|
60221
|
-
}
|
|
60222
|
-
} else if (val !== obs.peek()) {
|
|
60223
|
-
lockObservable(obs, false);
|
|
60224
|
-
const setter = isSetAfterActivated ? set : setNodeValue;
|
|
60225
|
-
setter(node, val);
|
|
60226
|
-
if (parentOther) {
|
|
60227
|
-
let didUnlock = false;
|
|
60228
|
-
if (parentOther.root.locked) {
|
|
60229
|
-
parentOther.root.locked = false;
|
|
60230
|
-
didUnlock = true;
|
|
60231
|
-
}
|
|
60232
|
-
setter(parentOther, val);
|
|
60233
|
-
if (didUnlock) {
|
|
60234
|
-
parentOther.root.locked = true;
|
|
60235
|
-
}
|
|
60236
|
-
}
|
|
60237
|
-
lockObservable(obs, true);
|
|
60238
|
-
} else if (parentOther) {
|
|
60239
|
-
setNodeValue(parentOther, val);
|
|
60240
|
-
}
|
|
60241
|
-
isSetAfterActivated = true;
|
|
60242
|
-
};
|
|
60243
|
-
node.root.activate = () => {
|
|
60244
|
-
node.root.activate = undefined;
|
|
60245
|
-
observe(compute, ({ value: value2 }) => {
|
|
60246
|
-
if (isPromise(value2)) {
|
|
60247
|
-
value2.then((v) => setInner(v));
|
|
60248
|
-
} else {
|
|
60249
|
-
setInner(value2);
|
|
60250
|
-
}
|
|
60251
|
-
}, { immediate: true, fromComputed: true });
|
|
60252
|
-
};
|
|
60253
|
-
if (set$1) {
|
|
60254
|
-
node.root.set = (value2) => {
|
|
60255
|
-
batch2(() => set$1(value2));
|
|
60256
|
-
};
|
|
60257
|
-
}
|
|
60258
|
-
return obs;
|
|
59322
|
+
return result;
|
|
60259
59323
|
}
|
|
60260
59324
|
|
|
60261
|
-
|
|
60262
|
-
|
|
60263
|
-
|
|
60264
|
-
|
|
60265
|
-
|
|
60266
|
-
|
|
60267
|
-
|
|
60268
|
-
|
|
59325
|
+
class TradeEngine {
|
|
59326
|
+
trade_details = null;
|
|
59327
|
+
position;
|
|
59328
|
+
global_config;
|
|
59329
|
+
constructor({
|
|
59330
|
+
global_config,
|
|
59331
|
+
position: position2 = { entry: 0, quantity: 0, kind: "long" }
|
|
59332
|
+
}) {
|
|
59333
|
+
this.global_config = global_config;
|
|
59334
|
+
this.position = position2;
|
|
60269
59335
|
}
|
|
60270
|
-
|
|
60271
|
-
|
|
60272
|
-
|
|
60273
|
-
|
|
60274
|
-
|
|
60275
|
-
|
|
60276
|
-
|
|
60277
|
-
|
|
60278
|
-
|
|
60279
|
-
|
|
60280
|
-
|
|
60281
|
-
|
|
60282
|
-
|
|
60283
|
-
}
|
|
60284
|
-
|
|
60285
|
-
|
|
60286
|
-
|
|
60287
|
-
|
|
60288
|
-
entry: 0
|
|
60289
|
-
},
|
|
60290
|
-
decimal_places = "%.3f"
|
|
60291
|
-
}) {
|
|
60292
|
-
let cumulativeQty = pos.quantity || 0;
|
|
60293
|
-
const reversedTrades = [...tradesList].reverse();
|
|
60294
|
-
const processedTrades = reversedTrades.map((trade) => {
|
|
60295
|
-
cumulativeQty += trade.quantity;
|
|
60296
|
-
const avg_size = to_f(cumulativeQty, decimal_places);
|
|
60297
|
-
return {
|
|
60298
|
-
...trade,
|
|
60299
|
-
cumulative_size: avg_size
|
|
60300
|
-
};
|
|
60301
|
-
});
|
|
60302
|
-
return processedTrades.reverse();
|
|
60303
|
-
}
|
|
60304
|
-
function preComputePositionState({
|
|
60305
|
-
position: position2,
|
|
60306
|
-
trades,
|
|
60307
|
-
fee_percent = 0,
|
|
60308
|
-
entry_fees = 0,
|
|
60309
|
-
global_config: symbol_config
|
|
60310
|
-
}) {
|
|
60311
|
-
const state = observable({
|
|
60312
|
-
position: position2,
|
|
60313
|
-
trades,
|
|
60314
|
-
take_profit: null,
|
|
60315
|
-
stop_loss: null,
|
|
60316
|
-
newTrades: () => {
|
|
60317
|
-
const tradesList = state.trades.get();
|
|
60318
|
-
const pos = state.position.get();
|
|
60319
|
-
if (!tradesList || tradesList.length === 0) {
|
|
60320
|
-
return [];
|
|
60321
|
-
}
|
|
60322
|
-
let cumulativeQty = pos.quantity || 0;
|
|
60323
|
-
let cumulativeValue = cumulativeQty * (pos.entry || 0);
|
|
60324
|
-
const reversedTrades = [...tradesList].reverse();
|
|
60325
|
-
const processedTrades = reversedTrades.map((trade) => {
|
|
60326
|
-
cumulativeQty += trade.quantity;
|
|
60327
|
-
cumulativeValue += trade.quantity * trade.entry;
|
|
60328
|
-
const avg_entry = cumulativeQty > 0 ? to_f(cumulativeValue / cumulativeQty, symbol_config.price_places) : 0;
|
|
60329
|
-
const avg_size = to_f(cumulativeQty, symbol_config.decimal_places);
|
|
60330
|
-
const stop = trade.stop || pos.kind === "long" ? Math.min(...tradesList.map((o) => o.entry)) : Math.max(...tradesList.map((o) => o.entry));
|
|
60331
|
-
const neg_pnl = to_f(Math.abs(avg_entry - stop) * avg_size, symbol_config.price_places);
|
|
60332
|
-
return {
|
|
60333
|
-
...trade,
|
|
60334
|
-
avg_entry,
|
|
60335
|
-
avg_size,
|
|
60336
|
-
neg_pnl
|
|
60337
|
-
};
|
|
60338
|
-
});
|
|
60339
|
-
return processedTrades.reverse();
|
|
60340
|
-
},
|
|
60341
|
-
generateSummary() {
|
|
60342
|
-
const trades2 = state.newTrades();
|
|
60343
|
-
return {
|
|
60344
|
-
...generateSummary2({
|
|
60345
|
-
trades: trades2,
|
|
60346
|
-
fee_percent
|
|
60347
|
-
}),
|
|
60348
|
-
entry_fees: to_f(entry_fees, "%.2f")
|
|
60349
|
-
};
|
|
60350
|
-
},
|
|
60351
|
-
summary: computed(() => {
|
|
60352
|
-
const trades2 = state.newTrades();
|
|
60353
|
-
return {
|
|
60354
|
-
...generateSummary2({
|
|
60355
|
-
trades: trades2,
|
|
60356
|
-
fee_percent
|
|
60357
|
-
}),
|
|
60358
|
-
entry_fees: to_f(entry_fees, "%.2f")
|
|
60359
|
-
};
|
|
60360
|
-
}),
|
|
60361
|
-
positionAt(price) {
|
|
60362
|
-
const trades2 = state.newTrades();
|
|
60363
|
-
const kind = state.position.get().kind;
|
|
60364
|
-
const filtered = trades2.filter((trade) => {
|
|
60365
|
-
if (kind === "long") {
|
|
60366
|
-
return trade.entry >= price;
|
|
60367
|
-
}
|
|
60368
|
-
return trade.entry <= price;
|
|
60369
|
-
});
|
|
60370
|
-
return filtered[0];
|
|
60371
|
-
},
|
|
60372
|
-
newPositionState(price) {
|
|
60373
|
-
const position3 = state.position.get();
|
|
60374
|
-
const trades2 = state.newTrades();
|
|
60375
|
-
const instance = state.positionAt(price);
|
|
60376
|
-
return positionAt({
|
|
59336
|
+
generateShortTrades(config2) {
|
|
59337
|
+
const result = compoundAPI.buildWithOptimumReward({
|
|
59338
|
+
global_config: this.global_config,
|
|
59339
|
+
config: config2,
|
|
59340
|
+
settings: config2,
|
|
59341
|
+
use_default: true
|
|
59342
|
+
});
|
|
59343
|
+
this.trade_details = result;
|
|
59344
|
+
}
|
|
59345
|
+
positionAt({
|
|
59346
|
+
price,
|
|
59347
|
+
dangerous,
|
|
59348
|
+
trades: existingTrades
|
|
59349
|
+
}) {
|
|
59350
|
+
const trades = existingTrades || this.trade_details?.trades || [];
|
|
59351
|
+
if (dangerous) {
|
|
59352
|
+
const kind = this.position.kind;
|
|
59353
|
+
const naive_assumptions = positionAt({
|
|
60377
59354
|
price,
|
|
60378
59355
|
position: {
|
|
60379
|
-
|
|
60380
|
-
entry:
|
|
60381
|
-
quantity:
|
|
59356
|
+
kind,
|
|
59357
|
+
entry: 0,
|
|
59358
|
+
quantity: 0
|
|
60382
59359
|
},
|
|
60383
|
-
|
|
60384
|
-
|
|
60385
|
-
|
|
60386
|
-
},
|
|
60387
|
-
updateTakeProfit({
|
|
60388
|
-
entry,
|
|
60389
|
-
quantity
|
|
60390
|
-
}) {
|
|
60391
|
-
state.take_profit.set({
|
|
60392
|
-
price: entry,
|
|
60393
|
-
quantity: quantity || state.position.get().quantity
|
|
60394
|
-
});
|
|
60395
|
-
},
|
|
60396
|
-
updateStopLoss(payload) {
|
|
60397
|
-
const { stop, quantity } = payload || {
|
|
60398
|
-
stop: state.newTrades()[0].entry,
|
|
60399
|
-
quantity: state.summary.get().quantity
|
|
60400
|
-
};
|
|
60401
|
-
state.stop_loss.set({
|
|
60402
|
-
price: stop,
|
|
60403
|
-
quantity
|
|
59360
|
+
global_config: this.global_config,
|
|
59361
|
+
trades,
|
|
59362
|
+
as_state: false
|
|
60404
59363
|
});
|
|
60405
|
-
|
|
60406
|
-
|
|
60407
|
-
|
|
60408
|
-
|
|
60409
|
-
|
|
60410
|
-
|
|
60411
|
-
|
|
60412
|
-
|
|
60413
|
-
|
|
60414
|
-
|
|
60415
|
-
|
|
60416
|
-
|
|
60417
|
-
|
|
60418
|
-
|
|
60419
|
-
|
|
60420
|
-
|
|
60421
|
-
|
|
60422
|
-
|
|
60423
|
-
|
|
60424
|
-
|
|
60425
|
-
|
|
60426
|
-
|
|
60427
|
-
|
|
60428
|
-
|
|
59364
|
+
const avg_position = determine_average_entry_and_size([
|
|
59365
|
+
{
|
|
59366
|
+
price: this.position.entry,
|
|
59367
|
+
quantity: this.position.quantity
|
|
59368
|
+
},
|
|
59369
|
+
{
|
|
59370
|
+
price: naive_assumptions.position.entry,
|
|
59371
|
+
quantity: naive_assumptions.position.quantity
|
|
59372
|
+
}
|
|
59373
|
+
], this.global_config.decimal_places, this.global_config.price_places);
|
|
59374
|
+
const new_position = dangerous ? {
|
|
59375
|
+
...this.position,
|
|
59376
|
+
entry: avg_position.entry,
|
|
59377
|
+
quantity: avg_position.quantity
|
|
59378
|
+
} : this.position;
|
|
59379
|
+
return new PositionState({
|
|
59380
|
+
...naive_assumptions,
|
|
59381
|
+
trades: naive_assumptions.trades,
|
|
59382
|
+
position: new_position,
|
|
59383
|
+
global_config: this.global_config
|
|
59384
|
+
});
|
|
59385
|
+
}
|
|
59386
|
+
const _trades = cumulativeHelper({
|
|
59387
|
+
tradesList: [...trades].concat({
|
|
59388
|
+
entry: this.position.entry,
|
|
59389
|
+
quantity: this.position.quantity
|
|
59390
|
+
}),
|
|
59391
|
+
decimal_places: this.global_config.decimal_places
|
|
59392
|
+
}).filter((o) => {
|
|
59393
|
+
const numeric = Number(o.cumulative_size);
|
|
59394
|
+
return numeric > this.position.quantity;
|
|
59395
|
+
});
|
|
59396
|
+
return positionAt({
|
|
59397
|
+
price,
|
|
59398
|
+
position: this.position,
|
|
59399
|
+
trades: _trades,
|
|
59400
|
+
global_config: this.global_config
|
|
60429
59401
|
});
|
|
60430
|
-
const avg = determine_average_entry_and_size(placed_less_than_entry.map((o) => ({
|
|
60431
|
-
price: o.entry,
|
|
60432
|
-
quantity: o.quantity
|
|
60433
|
-
})).concat([{ price: position2.entry, quantity: position2.quantity }]), global_config.decimal_places, global_config.price_places);
|
|
60434
|
-
position2.entry = avg.price;
|
|
60435
|
-
position2.quantity = avg.quantity;
|
|
60436
|
-
return position2;
|
|
60437
59402
|
}
|
|
60438
|
-
|
|
60439
|
-
|
|
60440
|
-
|
|
60441
|
-
|
|
60442
|
-
|
|
60443
|
-
}
|
|
60444
|
-
|
|
60445
|
-
|
|
60446
|
-
position: position2,
|
|
60447
|
-
trades = [],
|
|
60448
|
-
as_state = true,
|
|
60449
|
-
global_config
|
|
60450
|
-
}) {
|
|
60451
|
-
const kind = position2.kind;
|
|
60452
|
-
const fee_rate = {
|
|
60453
|
-
maker: 0.02,
|
|
60454
|
-
taker: 0.05
|
|
60455
|
-
};
|
|
60456
|
-
const placed = trades.filter((t2) => {
|
|
60457
|
-
if (kind === "long") {
|
|
60458
|
-
return t2.entry >= price;
|
|
60459
|
-
}
|
|
60460
|
-
return t2.entry <= price;
|
|
60461
|
-
});
|
|
60462
|
-
const not_placed = trades.filter((t2) => {
|
|
60463
|
-
if (kind === "long") {
|
|
60464
|
-
return t2.entry < price;
|
|
59403
|
+
initializeEngine({
|
|
59404
|
+
price,
|
|
59405
|
+
dangerous,
|
|
59406
|
+
trades,
|
|
59407
|
+
config: config2
|
|
59408
|
+
}) {
|
|
59409
|
+
if (config2) {
|
|
59410
|
+
this.generateShortTrades(config2);
|
|
60465
59411
|
}
|
|
60466
|
-
return
|
|
60467
|
-
});
|
|
60468
|
-
const placeQty = placed.reduce((acc, trade) => acc + trade.quantity, 0);
|
|
60469
|
-
const takerFee = price * placeQty * fee_rate.taker / 100;
|
|
60470
|
-
const makerFee = not_placed.reduce((acc, trade) => acc + trade.entry * trade.quantity * fee_rate.maker / 100, 0);
|
|
60471
|
-
const fee = to_f(takerFee + makerFee, "%.2f");
|
|
60472
|
-
const result = {
|
|
60473
|
-
trades: not_placed,
|
|
60474
|
-
position: determineNewPosition({
|
|
60475
|
-
global_config,
|
|
60476
|
-
position: { ...position2, kind },
|
|
59412
|
+
return this.positionAt({
|
|
60477
59413
|
price,
|
|
59414
|
+
dangerous,
|
|
60478
59415
|
trades
|
|
60479
|
-
})
|
|
60480
|
-
entry_fees: fee,
|
|
60481
|
-
fee_percent: fee_rate.maker,
|
|
60482
|
-
global_config
|
|
60483
|
-
};
|
|
60484
|
-
if (as_state) {
|
|
60485
|
-
const derivedState = preComputePositionState(result);
|
|
60486
|
-
return derivedState;
|
|
59416
|
+
});
|
|
60487
59417
|
}
|
|
60488
|
-
return result;
|
|
60489
|
-
}
|
|
60490
|
-
function primitiveTradeGenerator({
|
|
60491
|
-
global_config,
|
|
60492
|
-
position: position2 = { entry: 0, quantity: 0, kind: "long" }
|
|
60493
|
-
}) {
|
|
60494
|
-
const state = observable({
|
|
60495
|
-
trade_details: null,
|
|
60496
|
-
async generateShortTrades(config2) {
|
|
60497
|
-
const result = compoundAPI.buildWithOptimumReward({
|
|
60498
|
-
global_config,
|
|
60499
|
-
config: config2,
|
|
60500
|
-
settings: config2,
|
|
60501
|
-
use_default: true
|
|
60502
|
-
});
|
|
60503
|
-
state.trade_details.set(result);
|
|
60504
|
-
},
|
|
60505
|
-
async generateAllTrades(config2) {
|
|
60506
|
-
await Promise.allSettled([state.generateShortTrades(config2)]);
|
|
60507
|
-
},
|
|
60508
|
-
positionAt({
|
|
60509
|
-
price,
|
|
60510
|
-
dangerous,
|
|
60511
|
-
trades: existingTrades
|
|
60512
|
-
}) {
|
|
60513
|
-
const trades = existingTrades || state.trade_details.get()?.trades || [];
|
|
60514
|
-
if (dangerous) {
|
|
60515
|
-
const kind = position2.kind;
|
|
60516
|
-
const naive_assumptions = positionAt({
|
|
60517
|
-
price,
|
|
60518
|
-
position: {
|
|
60519
|
-
kind,
|
|
60520
|
-
entry: 0,
|
|
60521
|
-
quantity: 0
|
|
60522
|
-
},
|
|
60523
|
-
global_config,
|
|
60524
|
-
trades,
|
|
60525
|
-
as_state: false
|
|
60526
|
-
});
|
|
60527
|
-
const avg_position = determine_average_entry_and_size([
|
|
60528
|
-
{
|
|
60529
|
-
price: position2.entry,
|
|
60530
|
-
quantity: position2.quantity
|
|
60531
|
-
},
|
|
60532
|
-
{
|
|
60533
|
-
price: naive_assumptions.position.entry,
|
|
60534
|
-
quantity: naive_assumptions.position.quantity
|
|
60535
|
-
}
|
|
60536
|
-
], global_config.decimal_places, global_config.price_places);
|
|
60537
|
-
const new_position = dangerous ? {
|
|
60538
|
-
...position2,
|
|
60539
|
-
entry: avg_position.entry,
|
|
60540
|
-
quantity: avg_position.quantity
|
|
60541
|
-
} : position2;
|
|
60542
|
-
return preComputePositionState({
|
|
60543
|
-
...naive_assumptions,
|
|
60544
|
-
trades: naive_assumptions.trades,
|
|
60545
|
-
position: new_position,
|
|
60546
|
-
global_config
|
|
60547
|
-
});
|
|
60548
|
-
}
|
|
60549
|
-
const _trades = existingTrades || cumulativeHelper({
|
|
60550
|
-
tradesList: trades,
|
|
60551
|
-
decimal_places: global_config.decimal_places
|
|
60552
|
-
}).filter((o) => o.cumulative_size > position2.quantity);
|
|
60553
|
-
return positionAt({
|
|
60554
|
-
price,
|
|
60555
|
-
position: position2,
|
|
60556
|
-
trades: _trades,
|
|
60557
|
-
global_config
|
|
60558
|
-
});
|
|
60559
|
-
},
|
|
60560
|
-
async initializeEngine({
|
|
60561
|
-
price,
|
|
60562
|
-
dangerous,
|
|
60563
|
-
trades,
|
|
60564
|
-
config: config2
|
|
60565
|
-
}) {
|
|
60566
|
-
if (config2) {
|
|
60567
|
-
await state.generateAllTrades(config2);
|
|
60568
|
-
}
|
|
60569
|
-
return state.positionAt({
|
|
60570
|
-
price,
|
|
60571
|
-
dangerous,
|
|
60572
|
-
trades
|
|
60573
|
-
});
|
|
60574
|
-
}
|
|
60575
|
-
});
|
|
60576
|
-
return state;
|
|
60577
59418
|
}
|
|
60578
59419
|
function transformTradesToExchangeType({
|
|
60579
59420
|
trades,
|
|
60580
|
-
kind,
|
|
60581
59421
|
take_profit,
|
|
60582
|
-
stop_loss
|
|
59422
|
+
stop_loss,
|
|
59423
|
+
kind
|
|
60583
59424
|
}) {
|
|
60584
59425
|
const currentTime = Date.now();
|
|
60585
59426
|
const result = [];
|
|
@@ -60623,7 +59464,7 @@ function transformTradesToExchangeType({
|
|
|
60623
59464
|
});
|
|
60624
59465
|
});
|
|
60625
59466
|
let nextOrderId = trades.length;
|
|
60626
|
-
if (take_profit) {
|
|
59467
|
+
if (take_profit && take_profit.quantity > 0) {
|
|
60627
59468
|
const tpSide = kind === "long" ? "sell" : "buy";
|
|
60628
59469
|
const tpPositionSide = kind.toUpperCase();
|
|
60629
59470
|
result.push({
|
|
@@ -60663,7 +59504,7 @@ function transformTradesToExchangeType({
|
|
|
60663
59504
|
});
|
|
60664
59505
|
nextOrderId++;
|
|
60665
59506
|
}
|
|
60666
|
-
if (stop_loss) {
|
|
59507
|
+
if (stop_loss && stop_loss.quantity > 0) {
|
|
60667
59508
|
const slSide = kind === "long" ? "sell" : "buy";
|
|
60668
59509
|
const slPositionSide = kind.toUpperCase();
|
|
60669
59510
|
result.push({
|
|
@@ -60712,8 +59553,8 @@ function isTakeProfitOrder(order) {
|
|
|
60712
59553
|
}
|
|
60713
59554
|
function transformExchangeOrderToTradeWithValidation(orders, options) {
|
|
60714
59555
|
const {
|
|
60715
|
-
validateQuantity = true,
|
|
60716
59556
|
validatePrice = true,
|
|
59557
|
+
validateQuantity = true,
|
|
60717
59558
|
defaultStop = 0
|
|
60718
59559
|
} = options || {};
|
|
60719
59560
|
const trades = [];
|
|
@@ -60762,6 +59603,72 @@ function transformExchangeOrderToTradeWithValidation(orders, options) {
|
|
|
60762
59603
|
stop_loss
|
|
60763
59604
|
};
|
|
60764
59605
|
}
|
|
59606
|
+
function updatePositionBasedOffTpOrSl({
|
|
59607
|
+
kind,
|
|
59608
|
+
orders,
|
|
59609
|
+
positions,
|
|
59610
|
+
current_price
|
|
59611
|
+
}) {
|
|
59612
|
+
const position2 = positions[kind];
|
|
59613
|
+
const side_orders = orders.filter((o) => o.positionSide.toLowerCase() === kind);
|
|
59614
|
+
const { trades, take_profit, stop_loss } = transformExchangeOrderToTradeWithValidation(side_orders, {
|
|
59615
|
+
validatePrice: false,
|
|
59616
|
+
validateQuantity: false,
|
|
59617
|
+
defaultStop: 0
|
|
59618
|
+
});
|
|
59619
|
+
if (position2.quantity === 0) {
|
|
59620
|
+
return {
|
|
59621
|
+
trades,
|
|
59622
|
+
position: position2,
|
|
59623
|
+
orders: side_orders,
|
|
59624
|
+
changed: null
|
|
59625
|
+
};
|
|
59626
|
+
}
|
|
59627
|
+
if (take_profit && take_profit.quantity) {
|
|
59628
|
+
const should_close = kind === "long" ? current_price >= take_profit.price : current_price <= take_profit.price;
|
|
59629
|
+
if (should_close) {
|
|
59630
|
+
position2.quantity = Math.max(0, position2.quantity - take_profit.quantity);
|
|
59631
|
+
if (position2.quantity === 0) {
|
|
59632
|
+
position2.entry = 0;
|
|
59633
|
+
}
|
|
59634
|
+
return {
|
|
59635
|
+
trades,
|
|
59636
|
+
position: position2,
|
|
59637
|
+
orders: transformTradesToExchangeType({
|
|
59638
|
+
trades,
|
|
59639
|
+
kind,
|
|
59640
|
+
stop_loss
|
|
59641
|
+
}),
|
|
59642
|
+
changed: "tp"
|
|
59643
|
+
};
|
|
59644
|
+
}
|
|
59645
|
+
}
|
|
59646
|
+
if (stop_loss && stop_loss.quantity) {
|
|
59647
|
+
const should_close = kind === "long" ? current_price <= stop_loss.price : current_price >= stop_loss.price;
|
|
59648
|
+
if (should_close) {
|
|
59649
|
+
position2.quantity = Math.max(0, position2.quantity - stop_loss.quantity);
|
|
59650
|
+
if (position2.quantity === 0) {
|
|
59651
|
+
position2.entry = 0;
|
|
59652
|
+
}
|
|
59653
|
+
return {
|
|
59654
|
+
position: position2,
|
|
59655
|
+
orders: transformTradesToExchangeType({
|
|
59656
|
+
trades: trades.filter((t2) => kind === "long" ? t2.entry < stop_loss.price : t2.entry > stop_loss.price),
|
|
59657
|
+
kind,
|
|
59658
|
+
take_profit
|
|
59659
|
+
}),
|
|
59660
|
+
changed: "sl",
|
|
59661
|
+
trades
|
|
59662
|
+
};
|
|
59663
|
+
}
|
|
59664
|
+
}
|
|
59665
|
+
return {
|
|
59666
|
+
trades,
|
|
59667
|
+
position: position2,
|
|
59668
|
+
orders: side_orders,
|
|
59669
|
+
changed: null
|
|
59670
|
+
};
|
|
59671
|
+
}
|
|
60765
59672
|
|
|
60766
59673
|
// src/exchanges/paper/index.ts
|
|
60767
59674
|
async function initClient3(credentials, options) {
|
|
@@ -60998,6 +59905,7 @@ async function savePaperDetails(client, payload, new_payload) {
|
|
|
60998
59905
|
async function fetchDBExchangeData(client, symbol) {
|
|
60999
59906
|
const current_price = await getCurrentPrice3(client.client, symbol);
|
|
61000
59907
|
let orders = [];
|
|
59908
|
+
let trades = { long: [], short: [] };
|
|
61001
59909
|
let positions = {
|
|
61002
59910
|
long: null,
|
|
61003
59911
|
short: null
|
|
@@ -61040,6 +59948,30 @@ async function fetchDBExchangeData(client, symbol) {
|
|
|
61040
59948
|
const raw_data = live_exchange_details.data;
|
|
61041
59949
|
orders = raw_data.config.trades.exchange_info.open_orders || [];
|
|
61042
59950
|
positions = raw_data.config.trades.exchange_info.positions;
|
|
59951
|
+
const long_result = updatePositionBasedOffTpOrSl({
|
|
59952
|
+
current_price,
|
|
59953
|
+
orders,
|
|
59954
|
+
positions,
|
|
59955
|
+
kind: "long"
|
|
59956
|
+
});
|
|
59957
|
+
const short_result = updatePositionBasedOffTpOrSl({
|
|
59958
|
+
current_price,
|
|
59959
|
+
orders,
|
|
59960
|
+
positions,
|
|
59961
|
+
kind: "short"
|
|
59962
|
+
});
|
|
59963
|
+
orders = long_result.orders.concat(short_result.orders);
|
|
59964
|
+
positions.long = long_result.position;
|
|
59965
|
+
positions.short = short_result.position;
|
|
59966
|
+
if (["tp", "sl"].includes(long_result.changed)) {
|
|
59967
|
+
config2.long = null;
|
|
59968
|
+
}
|
|
59969
|
+
live_exchange_details.data.config.trades.exchange_info.open_orders = orders;
|
|
59970
|
+
live_exchange_details.data.config.trades.exchange_info.positions = positions;
|
|
59971
|
+
trades = {
|
|
59972
|
+
long: long_result.trades,
|
|
59973
|
+
short: short_result.trades
|
|
59974
|
+
};
|
|
61043
59975
|
}
|
|
61044
59976
|
return {
|
|
61045
59977
|
orders,
|
|
@@ -61047,12 +59979,13 @@ async function fetchDBExchangeData(client, symbol) {
|
|
|
61047
59979
|
positions,
|
|
61048
59980
|
current_price,
|
|
61049
59981
|
config: config2,
|
|
59982
|
+
trades,
|
|
61050
59983
|
raw_data: live_exchange_details?.data
|
|
61051
59984
|
};
|
|
61052
59985
|
}
|
|
61053
59986
|
async function getPositionInfo3(client, symbol) {
|
|
61054
|
-
const { positions, symbol_config, current_price,
|
|
61055
|
-
const long_generator =
|
|
59987
|
+
const { positions, symbol_config, current_price, raw_data, trades } = await fetchDBExchangeData(client, symbol);
|
|
59988
|
+
const long_generator = new TradeEngine({
|
|
61056
59989
|
position: {
|
|
61057
59990
|
kind: "long",
|
|
61058
59991
|
entry: positions.long?.entry || 0,
|
|
@@ -61060,7 +59993,7 @@ async function getPositionInfo3(client, symbol) {
|
|
|
61060
59993
|
},
|
|
61061
59994
|
global_config: symbol_config
|
|
61062
59995
|
});
|
|
61063
|
-
const short_generator =
|
|
59996
|
+
const short_generator = new TradeEngine({
|
|
61064
59997
|
position: {
|
|
61065
59998
|
kind: "short",
|
|
61066
59999
|
entry: positions.short?.entry || 0,
|
|
@@ -61068,36 +60001,75 @@ async function getPositionInfo3(client, symbol) {
|
|
|
61068
60001
|
},
|
|
61069
60002
|
global_config: symbol_config
|
|
61070
60003
|
});
|
|
61071
|
-
const
|
|
61072
|
-
|
|
61073
|
-
const long_state = await long_generator.initializeEngine({
|
|
61074
|
-
trades: config2.long ? undefined : long_trades.trades,
|
|
61075
|
-
config: config2.long,
|
|
60004
|
+
const long_state = long_generator.initializeEngine({
|
|
60005
|
+
trades: trades.long,
|
|
61076
60006
|
price: current_price
|
|
61077
60007
|
});
|
|
61078
|
-
const short_state =
|
|
61079
|
-
trades:
|
|
61080
|
-
config: config2.short,
|
|
60008
|
+
const short_state = short_generator.initializeEngine({
|
|
60009
|
+
trades: trades.short,
|
|
61081
60010
|
price: current_price
|
|
61082
60011
|
});
|
|
61083
60012
|
if (raw_data) {
|
|
61084
|
-
|
|
61085
|
-
|
|
61086
|
-
|
|
61087
|
-
|
|
61088
|
-
|
|
61089
|
-
|
|
61090
|
-
|
|
61091
|
-
|
|
61092
|
-
|
|
61093
|
-
|
|
61094
|
-
|
|
61095
|
-
|
|
61096
|
-
|
|
61097
|
-
|
|
60013
|
+
const long_state_trades = long_state.newTrades;
|
|
60014
|
+
const short_state_trades = short_state.newTrades;
|
|
60015
|
+
if (trades.long.length !== long_state_trades.length && positions.long.quantity !== long_state.position.quantity) {
|
|
60016
|
+
console.log({
|
|
60017
|
+
old: trades.long.length,
|
|
60018
|
+
new: long_state_trades.length,
|
|
60019
|
+
position: long_state.position
|
|
60020
|
+
});
|
|
60021
|
+
let _position = {
|
|
60022
|
+
entry: long_state.position.entry,
|
|
60023
|
+
quantity: long_state.position.quantity
|
|
60024
|
+
};
|
|
60025
|
+
let tp = undefined;
|
|
60026
|
+
if (long_state_trades.length === 0 && positions.long.quantity === 0) {
|
|
60027
|
+
_position.entry = 0;
|
|
60028
|
+
_position.quantity = 0;
|
|
60029
|
+
long_state.position.entry = 0;
|
|
60030
|
+
long_state.position.quantity = 0;
|
|
60031
|
+
tp = {
|
|
60032
|
+
price: 0,
|
|
60033
|
+
quantity: 0
|
|
60034
|
+
};
|
|
60035
|
+
}
|
|
60036
|
+
await updateDbDetails(client, {
|
|
60037
|
+
kind: "long",
|
|
60038
|
+
symbol
|
|
60039
|
+
}, raw_data, {
|
|
60040
|
+
take_profit: tp,
|
|
60041
|
+
position: _position,
|
|
60042
|
+
orders: long_state_trades
|
|
60043
|
+
});
|
|
60044
|
+
}
|
|
60045
|
+
if (trades.short.length !== short_state_trades.length && positions.short.quantity !== short_state.position.quantity) {
|
|
60046
|
+
let _position = {
|
|
60047
|
+
entry: short_state.position.entry,
|
|
60048
|
+
quantity: short_state.position.quantity
|
|
60049
|
+
};
|
|
60050
|
+
let tp = undefined;
|
|
60051
|
+
if (short_state_trades.length === 0 && positions.short.quantity === 0) {
|
|
60052
|
+
_position.entry = 0;
|
|
60053
|
+
_position.quantity = 0;
|
|
60054
|
+
short_state.position.entry = 0;
|
|
60055
|
+
short_state.position.quantity = 0;
|
|
60056
|
+
tp = {
|
|
60057
|
+
price: 0,
|
|
60058
|
+
quantity: 0
|
|
60059
|
+
};
|
|
60060
|
+
}
|
|
60061
|
+
await updateDbDetails(client, {
|
|
60062
|
+
kind: "short",
|
|
60063
|
+
symbol
|
|
60064
|
+
}, raw_data, {
|
|
60065
|
+
position: _position,
|
|
60066
|
+
orders: short_state_trades,
|
|
60067
|
+
take_profit: tp
|
|
60068
|
+
});
|
|
60069
|
+
}
|
|
61098
60070
|
}
|
|
61099
|
-
const long_position = long_state.position
|
|
61100
|
-
const short_position = short_state.position
|
|
60071
|
+
const long_position = long_state.position;
|
|
60072
|
+
const short_position = short_state.position;
|
|
61101
60073
|
const long_quantity = long_position.quantity;
|
|
61102
60074
|
const short_quantity = short_position.quantity;
|
|
61103
60075
|
const long = {
|
|
@@ -61320,7 +60292,11 @@ async function placeTpOrder3(client, payload) {
|
|
|
61320
60292
|
}
|
|
61321
60293
|
async function cancelAllOrders3(client, symbol, payload) {
|
|
61322
60294
|
const { type, side, kind } = payload;
|
|
61323
|
-
const {
|
|
60295
|
+
const {
|
|
60296
|
+
orders: fullOrders,
|
|
60297
|
+
symbol_config,
|
|
60298
|
+
positions
|
|
60299
|
+
} = await fetchDBExchangeData(client, symbol);
|
|
61324
60300
|
const allOrders = await getOpenOrders3(client, symbol, type);
|
|
61325
60301
|
const sameKindOrders = fullOrders.filter((o) => o.positionSide.toLowerCase() === kind);
|
|
61326
60302
|
const ordersToCancel = allOrders.filter((x) => side ? x.side === side : true).filter((x) => kind ? x.kind === kind : true);
|
|
@@ -61331,9 +60307,13 @@ async function cancelAllOrders3(client, symbol, payload) {
|
|
|
61331
60307
|
decimal_places: symbol_config.decimal_places,
|
|
61332
60308
|
price_places: symbol_config.price_places
|
|
61333
60309
|
}, {
|
|
61334
|
-
position: {},
|
|
60310
|
+
position: positions[kind] || {},
|
|
61335
60311
|
orders: excludeFromSameKind,
|
|
61336
|
-
raw: true
|
|
60312
|
+
raw: true,
|
|
60313
|
+
stop_loss: {
|
|
60314
|
+
price: 0,
|
|
60315
|
+
quantity: 0
|
|
60316
|
+
}
|
|
61337
60317
|
});
|
|
61338
60318
|
}
|
|
61339
60319
|
async function cancelOrdersParallel2(payload) {
|
|
@@ -61370,6 +60350,49 @@ async function cancelOrders3(payload) {
|
|
|
61370
60350
|
custom_client: payload.custom_client
|
|
61371
60351
|
});
|
|
61372
60352
|
}
|
|
60353
|
+
async function createLimitPurchaseOrders2(client, payload) {
|
|
60354
|
+
const { positions, symbol_config, current_price, raw_data } = await fetchDBExchangeData(client, payload.symbol);
|
|
60355
|
+
const kind = payload.orders[0].kind || payload.kind;
|
|
60356
|
+
const params = {
|
|
60357
|
+
position: {
|
|
60358
|
+
kind,
|
|
60359
|
+
entry: positions[kind]?.entry || 0,
|
|
60360
|
+
quantity: positions[kind]?.quantity || 0
|
|
60361
|
+
},
|
|
60362
|
+
global_config: symbol_config
|
|
60363
|
+
};
|
|
60364
|
+
const generator = new TradeEngine(params);
|
|
60365
|
+
const state = generator.initializeEngine({
|
|
60366
|
+
trades: payload.orders,
|
|
60367
|
+
price: current_price
|
|
60368
|
+
});
|
|
60369
|
+
const current_position_state = {
|
|
60370
|
+
entry: state.position.entry,
|
|
60371
|
+
quantity: state.position.quantity
|
|
60372
|
+
};
|
|
60373
|
+
const remaining_orders = state.newTrades;
|
|
60374
|
+
console.log({
|
|
60375
|
+
length: remaining_orders.length,
|
|
60376
|
+
position: current_position_state,
|
|
60377
|
+
last: remaining_orders[remaining_orders.length - 1]
|
|
60378
|
+
});
|
|
60379
|
+
return await updateDbDetails(client, {
|
|
60380
|
+
kind,
|
|
60381
|
+
symbol: payload.symbol
|
|
60382
|
+
}, raw_data, {
|
|
60383
|
+
position: current_position_state,
|
|
60384
|
+
orders: remaining_orders
|
|
60385
|
+
});
|
|
60386
|
+
return await savePaperDetails(client, {
|
|
60387
|
+
kind,
|
|
60388
|
+
symbol: payload.symbol,
|
|
60389
|
+
price_places: payload.price_places,
|
|
60390
|
+
decimal_places: payload.decimal_places
|
|
60391
|
+
}, {
|
|
60392
|
+
position: current_position_state,
|
|
60393
|
+
orders: remaining_orders
|
|
60394
|
+
});
|
|
60395
|
+
}
|
|
61373
60396
|
|
|
61374
60397
|
class PaperBinanceExchange extends BaseExchange {
|
|
61375
60398
|
constructor(client) {
|
|
@@ -61387,36 +60410,7 @@ class PaperBinanceExchange extends BaseExchange {
|
|
|
61387
60410
|
return await cancelAllOrders3(this.client, symbol, payload);
|
|
61388
60411
|
}
|
|
61389
60412
|
async _createLimitPurchaseOrders(payload) {
|
|
61390
|
-
|
|
61391
|
-
const kind = payload.orders[0].kind;
|
|
61392
|
-
const params = {
|
|
61393
|
-
position: {
|
|
61394
|
-
kind,
|
|
61395
|
-
entry: positions[kind]?.entry || 0,
|
|
61396
|
-
quantity: positions[kind]?.quantity || 0
|
|
61397
|
-
},
|
|
61398
|
-
global_config: symbol_config
|
|
61399
|
-
};
|
|
61400
|
-
const generator = primitiveTradeGenerator(params);
|
|
61401
|
-
const state = await generator.initializeEngine({
|
|
61402
|
-
config: config2[kind],
|
|
61403
|
-
trades: payload.orders,
|
|
61404
|
-
price: current_price
|
|
61405
|
-
});
|
|
61406
|
-
const current_position_state = {
|
|
61407
|
-
entry: state.position.get().entry,
|
|
61408
|
-
quantity: state.position.get().quantity
|
|
61409
|
-
};
|
|
61410
|
-
const remaining_orders = state.newTrades();
|
|
61411
|
-
return await savePaperDetails(this.client, {
|
|
61412
|
-
kind,
|
|
61413
|
-
symbol: payload.symbol,
|
|
61414
|
-
price_places: payload.price_places,
|
|
61415
|
-
decimal_places: payload.decimal_places
|
|
61416
|
-
}, {
|
|
61417
|
-
position: current_position_state,
|
|
61418
|
-
orders: remaining_orders
|
|
61419
|
-
});
|
|
60413
|
+
return await createLimitPurchaseOrders2(this.client, payload);
|
|
61420
60414
|
}
|
|
61421
60415
|
async analyzeCharts(_payload) {}
|
|
61422
60416
|
async getExchangeInfo(options) {
|
|
@@ -61496,9 +60490,10 @@ class PaperBinanceExchange extends BaseExchange {
|
|
|
61496
60490
|
symbol_config,
|
|
61497
60491
|
current_price,
|
|
61498
60492
|
orders: _orders,
|
|
60493
|
+
trades,
|
|
61499
60494
|
config: config2
|
|
61500
60495
|
} = await fetchDBExchangeData(this.client, _payload.symbol);
|
|
61501
|
-
const generator =
|
|
60496
|
+
const generator = new TradeEngine({
|
|
61502
60497
|
position: {
|
|
61503
60498
|
kind,
|
|
61504
60499
|
entry: positions[kind]?.entry || 0,
|
|
@@ -61506,9 +60501,10 @@ class PaperBinanceExchange extends BaseExchange {
|
|
|
61506
60501
|
},
|
|
61507
60502
|
global_config: symbol_config
|
|
61508
60503
|
});
|
|
61509
|
-
const long_state =
|
|
60504
|
+
const long_state = generator.initializeEngine({
|
|
61510
60505
|
config: config2[kind],
|
|
61511
|
-
price: current_price
|
|
60506
|
+
price: current_price,
|
|
60507
|
+
trades: trades.long
|
|
61512
60508
|
});
|
|
61513
60509
|
return long_state;
|
|
61514
60510
|
}
|
|
@@ -61534,6 +60530,14 @@ async function forceClosePosition2(client, symbol, options) {
|
|
|
61534
60530
|
entry: 0,
|
|
61535
60531
|
quantity: 0
|
|
61536
60532
|
},
|
|
60533
|
+
take_profit: {
|
|
60534
|
+
price: 0,
|
|
60535
|
+
quantity: 0
|
|
60536
|
+
},
|
|
60537
|
+
stop_loss: {
|
|
60538
|
+
price: 0,
|
|
60539
|
+
quantity: 0
|
|
60540
|
+
},
|
|
61537
60541
|
orders: []
|
|
61538
60542
|
});
|
|
61539
60543
|
}
|