@gbozee/ultimate 0.0.2-107 → 0.0.2-109
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/frontend-index.d.ts +2 -1
- package/dist/frontend-index.js +3 -12
- package/dist/index.cjs +67 -18
- package/dist/index.d.ts +20 -1
- package/dist/index.js +67 -18
- package/dist/mcp-server.cjs +67 -18
- package/dist/mcp-server.js +67 -18
- package/package.json +1 -1
package/dist/frontend-index.d.ts
CHANGED
|
@@ -82,7 +82,7 @@ export type RawPosition = {
|
|
|
82
82
|
entry: number;
|
|
83
83
|
quantity: number;
|
|
84
84
|
price_places: string;
|
|
85
|
-
decimal_places
|
|
85
|
+
decimal_places?: string;
|
|
86
86
|
};
|
|
87
87
|
export type ConfigOptionType = {
|
|
88
88
|
reduce_ratio: number | string;
|
|
@@ -451,6 +451,7 @@ export declare function computeProfitDetail(payload: {
|
|
|
451
451
|
max_reward_factor: number;
|
|
452
452
|
risk: number;
|
|
453
453
|
};
|
|
454
|
+
pnl: number;
|
|
454
455
|
reduce_position?: {
|
|
455
456
|
kind: "long" | "short";
|
|
456
457
|
entry: number;
|
package/dist/frontend-index.js
CHANGED
|
@@ -1807,24 +1807,14 @@ function computeProfitDetail(payload) {
|
|
|
1807
1807
|
const {
|
|
1808
1808
|
focus_position,
|
|
1809
1809
|
strategy,
|
|
1810
|
+
pnl,
|
|
1810
1811
|
price_places = "%.1f",
|
|
1811
1812
|
reduce_position,
|
|
1812
1813
|
decimal_places,
|
|
1813
1814
|
reverse_position
|
|
1814
1815
|
} = payload;
|
|
1815
1816
|
let reward_factor = strategy.reward_factor;
|
|
1816
|
-
|
|
1817
|
-
if (strategy.max_reward_factor === 0) {
|
|
1818
|
-
reward_factor = strategy.reward_factor;
|
|
1819
|
-
}
|
|
1820
|
-
if (focus_position.avg_qty >= focus_position.quantity && strategy.max_reward_factor) {
|
|
1821
|
-
reward_factor = to_f(focus_position.quantity * strategy.max_reward_factor / focus_position.avg_qty, "%.4f");
|
|
1822
|
-
} else {
|
|
1823
|
-
reward_factor = strategy.reward_factor;
|
|
1824
|
-
}
|
|
1825
|
-
const full_pnl = reward_factor * risk;
|
|
1826
|
-
const profit_percent = to_f(full_pnl * 100 / (focus_position.avg_price * focus_position.avg_qty), "%.4f");
|
|
1827
|
-
const pnl = to_f(focus_position.entry * focus_position.quantity * profit_percent / 100, "%.2f");
|
|
1817
|
+
const profit_percent = to_f(pnl * 100 / (focus_position.avg_price * focus_position.avg_qty), "%.4f");
|
|
1828
1818
|
const diff = pnl / focus_position.quantity;
|
|
1829
1819
|
const sell_price = to_f(focus_position.kind === "long" ? focus_position.entry + diff : focus_position.entry - diff, price_places);
|
|
1830
1820
|
let loss = 0;
|
|
@@ -2381,6 +2371,7 @@ class Strategy {
|
|
|
2381
2371
|
avg_price: focus_position.avg_price,
|
|
2382
2372
|
avg_qty: focus_position.avg_qty
|
|
2383
2373
|
},
|
|
2374
|
+
pnl: this.pnl(kind),
|
|
2384
2375
|
strategy: {
|
|
2385
2376
|
reward_factor,
|
|
2386
2377
|
max_reward_factor,
|
package/dist/index.cjs
CHANGED
|
@@ -54027,24 +54027,14 @@ function computeProfitDetail(payload) {
|
|
|
54027
54027
|
const {
|
|
54028
54028
|
focus_position,
|
|
54029
54029
|
strategy,
|
|
54030
|
+
pnl,
|
|
54030
54031
|
price_places = "%.1f",
|
|
54031
54032
|
reduce_position,
|
|
54032
54033
|
decimal_places,
|
|
54033
54034
|
reverse_position
|
|
54034
54035
|
} = payload;
|
|
54035
54036
|
let reward_factor = strategy.reward_factor;
|
|
54036
|
-
|
|
54037
|
-
if (strategy.max_reward_factor === 0) {
|
|
54038
|
-
reward_factor = strategy.reward_factor;
|
|
54039
|
-
}
|
|
54040
|
-
if (focus_position.avg_qty >= focus_position.quantity && strategy.max_reward_factor) {
|
|
54041
|
-
reward_factor = to_f2(focus_position.quantity * strategy.max_reward_factor / focus_position.avg_qty, "%.4f");
|
|
54042
|
-
} else {
|
|
54043
|
-
reward_factor = strategy.reward_factor;
|
|
54044
|
-
}
|
|
54045
|
-
const full_pnl = reward_factor * risk;
|
|
54046
|
-
const profit_percent = to_f2(full_pnl * 100 / (focus_position.avg_price * focus_position.avg_qty), "%.4f");
|
|
54047
|
-
const pnl = to_f2(focus_position.entry * focus_position.quantity * profit_percent / 100, "%.2f");
|
|
54037
|
+
const profit_percent = to_f2(pnl * 100 / (focus_position.avg_price * focus_position.avg_qty), "%.4f");
|
|
54048
54038
|
const diff = pnl / focus_position.quantity;
|
|
54049
54039
|
const sell_price = to_f2(focus_position.kind === "long" ? focus_position.entry + diff : focus_position.entry - diff, price_places);
|
|
54050
54040
|
let loss = 0;
|
|
@@ -54602,6 +54592,7 @@ class Strategy {
|
|
|
54602
54592
|
avg_price: focus_position.avg_price,
|
|
54603
54593
|
avg_qty: focus_position.avg_qty
|
|
54604
54594
|
},
|
|
54595
|
+
pnl: this.pnl(kind),
|
|
54605
54596
|
strategy: {
|
|
54606
54597
|
reward_factor,
|
|
54607
54598
|
max_reward_factor,
|
|
@@ -54723,6 +54714,56 @@ class BaseExchange {
|
|
|
54723
54714
|
decimal_places
|
|
54724
54715
|
});
|
|
54725
54716
|
}
|
|
54717
|
+
async analyzeCandlesticks(payload) {
|
|
54718
|
+
const { symbol } = payload;
|
|
54719
|
+
const arr = [
|
|
54720
|
+
"weekly",
|
|
54721
|
+
"days_3",
|
|
54722
|
+
"daily",
|
|
54723
|
+
"hours_12",
|
|
54724
|
+
"hours_8",
|
|
54725
|
+
"hours_6",
|
|
54726
|
+
"hours_4",
|
|
54727
|
+
"hours_2"
|
|
54728
|
+
];
|
|
54729
|
+
const results = await Promise.all(arr.map((x) => this.analyzeCharts({ chartType: x, raw: true, limit: 99, symbol })));
|
|
54730
|
+
const currentPrice = await this.get_current_price(symbol);
|
|
54731
|
+
const resistance = {};
|
|
54732
|
+
const support = {};
|
|
54733
|
+
for (let i2 = 0;i2 < arr.length; i2++) {
|
|
54734
|
+
const interval = arr[i2];
|
|
54735
|
+
const data = results[i2];
|
|
54736
|
+
for (const value2 of data.slice(1)) {
|
|
54737
|
+
const high = value2[2];
|
|
54738
|
+
const low = value2[3];
|
|
54739
|
+
console.log("slice", { high, low, interval });
|
|
54740
|
+
if (high in resistance) {
|
|
54741
|
+
resistance[high] += 1;
|
|
54742
|
+
} else {
|
|
54743
|
+
resistance[high] = 1;
|
|
54744
|
+
}
|
|
54745
|
+
if (low in support) {
|
|
54746
|
+
support[low] += 1;
|
|
54747
|
+
} else {
|
|
54748
|
+
support[low] = 1;
|
|
54749
|
+
}
|
|
54750
|
+
}
|
|
54751
|
+
}
|
|
54752
|
+
const filteredResistance = Object.fromEntries(Object.entries(resistance).filter(([k, v]) => parseFloat(k) > currentPrice));
|
|
54753
|
+
const filteredSupport = Object.fromEntries(Object.entries(support).filter(([k, v]) => parseFloat(k) < currentPrice));
|
|
54754
|
+
const candlesticks = arr.reduce((acc, interval, index) => {
|
|
54755
|
+
acc[interval] = results[index].slice(1);
|
|
54756
|
+
return acc;
|
|
54757
|
+
}, {});
|
|
54758
|
+
const minimumWeekly = Math.min(...candlesticks["weekly"].map((x) => parseFloat(x[3])));
|
|
54759
|
+
return {
|
|
54760
|
+
candlesticks,
|
|
54761
|
+
resistance: filteredResistance,
|
|
54762
|
+
support: filteredSupport,
|
|
54763
|
+
current_price: currentPrice,
|
|
54764
|
+
minimum_weekly: minimumWeekly
|
|
54765
|
+
};
|
|
54766
|
+
}
|
|
54726
54767
|
}
|
|
54727
54768
|
|
|
54728
54769
|
// src/exchanges/binance.ts
|
|
@@ -55597,8 +55638,8 @@ class BinanceExchange extends BaseExchange {
|
|
|
55597
55638
|
client: this.client,
|
|
55598
55639
|
symbol: payload.symbol,
|
|
55599
55640
|
chartType: payload.chartType,
|
|
55600
|
-
|
|
55601
|
-
raw: payload.raw
|
|
55641
|
+
limit: payload.limit,
|
|
55642
|
+
raw: payload.raw
|
|
55602
55643
|
});
|
|
55603
55644
|
}
|
|
55604
55645
|
async getExchangeAccountInfo(options) {
|
|
@@ -56418,7 +56459,7 @@ class BybitExchange extends BaseExchange {
|
|
|
56418
56459
|
client: this.client,
|
|
56419
56460
|
symbol: payload.symbol,
|
|
56420
56461
|
chartType: payload.chartType,
|
|
56421
|
-
|
|
56462
|
+
limit: payload.limit,
|
|
56422
56463
|
raw: payload.raw || false
|
|
56423
56464
|
});
|
|
56424
56465
|
}
|
|
@@ -59565,7 +59606,7 @@ class ExchangeAccount {
|
|
|
59565
59606
|
});
|
|
59566
59607
|
}
|
|
59567
59608
|
async getSellPriceFromStrategy(payload) {
|
|
59568
|
-
const { symbol, reduce_position } = payload;
|
|
59609
|
+
const { symbol, reduce_position, kind } = payload;
|
|
59569
59610
|
const symbol_config = await this.recomputeSymbolConfig({
|
|
59570
59611
|
symbol
|
|
59571
59612
|
});
|
|
@@ -59573,7 +59614,13 @@ class ExchangeAccount {
|
|
|
59573
59614
|
symbol,
|
|
59574
59615
|
as_view: true
|
|
59575
59616
|
});
|
|
59576
|
-
const focus_position = positions.find((k) =>
|
|
59617
|
+
const focus_position = positions.find((k) => {
|
|
59618
|
+
let condition = Boolean(k.expand?.account_strategy);
|
|
59619
|
+
if (kind) {
|
|
59620
|
+
condition = condition && k.kind === kind;
|
|
59621
|
+
}
|
|
59622
|
+
return condition;
|
|
59623
|
+
});
|
|
59577
59624
|
if (!focus_position) {
|
|
59578
59625
|
return;
|
|
59579
59626
|
}
|
|
@@ -59591,6 +59638,7 @@ class ExchangeAccount {
|
|
|
59591
59638
|
avg_price: focus_position.avg_price,
|
|
59592
59639
|
avg_qty: focus_position.avg_qty
|
|
59593
59640
|
},
|
|
59641
|
+
pnl: focus_position.target_pnl,
|
|
59594
59642
|
strategy: {
|
|
59595
59643
|
reward_factor: strategy.reward_factor,
|
|
59596
59644
|
risk: strategy.risk,
|
|
@@ -59956,7 +60004,8 @@ class App {
|
|
|
59956
60004
|
});
|
|
59957
60005
|
const result = await main_exchange_account.getSellPriceFromStrategy({
|
|
59958
60006
|
symbol: main_account.symbol,
|
|
59959
|
-
reduce_position
|
|
60007
|
+
reduce_position,
|
|
60008
|
+
kind: main_account.kind
|
|
59960
60009
|
});
|
|
59961
60010
|
if (place) {
|
|
59962
60011
|
await reduce_exchange_account.cancelOrders({
|
package/dist/index.d.ts
CHANGED
|
@@ -287,6 +287,19 @@ interface Order$1 {
|
|
|
287
287
|
stop: number;
|
|
288
288
|
triggerPrice?: number;
|
|
289
289
|
}
|
|
290
|
+
export interface CandlestickAnalysisResult {
|
|
291
|
+
candlesticks: {
|
|
292
|
+
[key: string]: any[];
|
|
293
|
+
};
|
|
294
|
+
resistance: {
|
|
295
|
+
[key: string]: number;
|
|
296
|
+
};
|
|
297
|
+
support: {
|
|
298
|
+
[key: string]: number;
|
|
299
|
+
};
|
|
300
|
+
current_price: number;
|
|
301
|
+
minimum_weekly: number;
|
|
302
|
+
}
|
|
290
303
|
declare abstract class BaseExchange {
|
|
291
304
|
client: any;
|
|
292
305
|
constructor(client: any);
|
|
@@ -317,7 +330,7 @@ declare abstract class BaseExchange {
|
|
|
317
330
|
abstract analyzeCharts(payload: {
|
|
318
331
|
symbol: string;
|
|
319
332
|
chartType: any;
|
|
320
|
-
|
|
333
|
+
limit: number;
|
|
321
334
|
raw?: boolean;
|
|
322
335
|
}): Promise<any>;
|
|
323
336
|
abstract getExchangeAccountInfo(options: {
|
|
@@ -424,6 +437,9 @@ declare abstract class BaseExchange {
|
|
|
424
437
|
price_places?: string;
|
|
425
438
|
decimal_places?: string;
|
|
426
439
|
}): Promise<any>;
|
|
440
|
+
analyzeCandlesticks(payload: {
|
|
441
|
+
symbol: string;
|
|
442
|
+
}): Promise<CandlestickAnalysisResult>;
|
|
427
443
|
}
|
|
428
444
|
declare function initPocketBaseClient(proxy_credentials: {
|
|
429
445
|
host: string;
|
|
@@ -1273,6 +1289,7 @@ export declare function computeProfitDetail(payload: {
|
|
|
1273
1289
|
max_reward_factor: number;
|
|
1274
1290
|
risk: number;
|
|
1275
1291
|
};
|
|
1292
|
+
pnl: number;
|
|
1276
1293
|
reduce_position?: {
|
|
1277
1294
|
kind: "long" | "short";
|
|
1278
1295
|
entry: number;
|
|
@@ -2151,6 +2168,7 @@ declare class ExchangeAccount$1 {
|
|
|
2151
2168
|
getSellPriceFromStrategy(payload: {
|
|
2152
2169
|
symbol: string;
|
|
2153
2170
|
reduce_position: PositionsView;
|
|
2171
|
+
kind?: "long" | "short";
|
|
2154
2172
|
}): Promise<{
|
|
2155
2173
|
pnl: number;
|
|
2156
2174
|
loss: number;
|
|
@@ -2388,6 +2406,7 @@ declare class App {
|
|
|
2388
2406
|
reduceExistingPosition(payload: {
|
|
2389
2407
|
main_account: ExchangeType & {
|
|
2390
2408
|
symbol: string;
|
|
2409
|
+
kind?: "long" | "short";
|
|
2391
2410
|
};
|
|
2392
2411
|
reduce_account: ExchangeType & {
|
|
2393
2412
|
symbol: string;
|
package/dist/index.js
CHANGED
|
@@ -53979,24 +53979,14 @@ function computeProfitDetail(payload) {
|
|
|
53979
53979
|
const {
|
|
53980
53980
|
focus_position,
|
|
53981
53981
|
strategy,
|
|
53982
|
+
pnl,
|
|
53982
53983
|
price_places = "%.1f",
|
|
53983
53984
|
reduce_position,
|
|
53984
53985
|
decimal_places,
|
|
53985
53986
|
reverse_position
|
|
53986
53987
|
} = payload;
|
|
53987
53988
|
let reward_factor = strategy.reward_factor;
|
|
53988
|
-
|
|
53989
|
-
if (strategy.max_reward_factor === 0) {
|
|
53990
|
-
reward_factor = strategy.reward_factor;
|
|
53991
|
-
}
|
|
53992
|
-
if (focus_position.avg_qty >= focus_position.quantity && strategy.max_reward_factor) {
|
|
53993
|
-
reward_factor = to_f2(focus_position.quantity * strategy.max_reward_factor / focus_position.avg_qty, "%.4f");
|
|
53994
|
-
} else {
|
|
53995
|
-
reward_factor = strategy.reward_factor;
|
|
53996
|
-
}
|
|
53997
|
-
const full_pnl = reward_factor * risk;
|
|
53998
|
-
const profit_percent = to_f2(full_pnl * 100 / (focus_position.avg_price * focus_position.avg_qty), "%.4f");
|
|
53999
|
-
const pnl = to_f2(focus_position.entry * focus_position.quantity * profit_percent / 100, "%.2f");
|
|
53989
|
+
const profit_percent = to_f2(pnl * 100 / (focus_position.avg_price * focus_position.avg_qty), "%.4f");
|
|
54000
53990
|
const diff = pnl / focus_position.quantity;
|
|
54001
53991
|
const sell_price = to_f2(focus_position.kind === "long" ? focus_position.entry + diff : focus_position.entry - diff, price_places);
|
|
54002
53992
|
let loss = 0;
|
|
@@ -54554,6 +54544,7 @@ class Strategy {
|
|
|
54554
54544
|
avg_price: focus_position.avg_price,
|
|
54555
54545
|
avg_qty: focus_position.avg_qty
|
|
54556
54546
|
},
|
|
54547
|
+
pnl: this.pnl(kind),
|
|
54557
54548
|
strategy: {
|
|
54558
54549
|
reward_factor,
|
|
54559
54550
|
max_reward_factor,
|
|
@@ -54675,6 +54666,56 @@ class BaseExchange {
|
|
|
54675
54666
|
decimal_places
|
|
54676
54667
|
});
|
|
54677
54668
|
}
|
|
54669
|
+
async analyzeCandlesticks(payload) {
|
|
54670
|
+
const { symbol } = payload;
|
|
54671
|
+
const arr = [
|
|
54672
|
+
"weekly",
|
|
54673
|
+
"days_3",
|
|
54674
|
+
"daily",
|
|
54675
|
+
"hours_12",
|
|
54676
|
+
"hours_8",
|
|
54677
|
+
"hours_6",
|
|
54678
|
+
"hours_4",
|
|
54679
|
+
"hours_2"
|
|
54680
|
+
];
|
|
54681
|
+
const results = await Promise.all(arr.map((x) => this.analyzeCharts({ chartType: x, raw: true, limit: 99, symbol })));
|
|
54682
|
+
const currentPrice = await this.get_current_price(symbol);
|
|
54683
|
+
const resistance = {};
|
|
54684
|
+
const support = {};
|
|
54685
|
+
for (let i2 = 0;i2 < arr.length; i2++) {
|
|
54686
|
+
const interval = arr[i2];
|
|
54687
|
+
const data = results[i2];
|
|
54688
|
+
for (const value2 of data.slice(1)) {
|
|
54689
|
+
const high = value2[2];
|
|
54690
|
+
const low = value2[3];
|
|
54691
|
+
console.log("slice", { high, low, interval });
|
|
54692
|
+
if (high in resistance) {
|
|
54693
|
+
resistance[high] += 1;
|
|
54694
|
+
} else {
|
|
54695
|
+
resistance[high] = 1;
|
|
54696
|
+
}
|
|
54697
|
+
if (low in support) {
|
|
54698
|
+
support[low] += 1;
|
|
54699
|
+
} else {
|
|
54700
|
+
support[low] = 1;
|
|
54701
|
+
}
|
|
54702
|
+
}
|
|
54703
|
+
}
|
|
54704
|
+
const filteredResistance = Object.fromEntries(Object.entries(resistance).filter(([k, v]) => parseFloat(k) > currentPrice));
|
|
54705
|
+
const filteredSupport = Object.fromEntries(Object.entries(support).filter(([k, v]) => parseFloat(k) < currentPrice));
|
|
54706
|
+
const candlesticks = arr.reduce((acc, interval, index) => {
|
|
54707
|
+
acc[interval] = results[index].slice(1);
|
|
54708
|
+
return acc;
|
|
54709
|
+
}, {});
|
|
54710
|
+
const minimumWeekly = Math.min(...candlesticks["weekly"].map((x) => parseFloat(x[3])));
|
|
54711
|
+
return {
|
|
54712
|
+
candlesticks,
|
|
54713
|
+
resistance: filteredResistance,
|
|
54714
|
+
support: filteredSupport,
|
|
54715
|
+
current_price: currentPrice,
|
|
54716
|
+
minimum_weekly: minimumWeekly
|
|
54717
|
+
};
|
|
54718
|
+
}
|
|
54678
54719
|
}
|
|
54679
54720
|
|
|
54680
54721
|
// src/exchanges/binance.ts
|
|
@@ -55549,8 +55590,8 @@ class BinanceExchange extends BaseExchange {
|
|
|
55549
55590
|
client: this.client,
|
|
55550
55591
|
symbol: payload.symbol,
|
|
55551
55592
|
chartType: payload.chartType,
|
|
55552
|
-
|
|
55553
|
-
raw: payload.raw
|
|
55593
|
+
limit: payload.limit,
|
|
55594
|
+
raw: payload.raw
|
|
55554
55595
|
});
|
|
55555
55596
|
}
|
|
55556
55597
|
async getExchangeAccountInfo(options) {
|
|
@@ -56370,7 +56411,7 @@ class BybitExchange extends BaseExchange {
|
|
|
56370
56411
|
client: this.client,
|
|
56371
56412
|
symbol: payload.symbol,
|
|
56372
56413
|
chartType: payload.chartType,
|
|
56373
|
-
|
|
56414
|
+
limit: payload.limit,
|
|
56374
56415
|
raw: payload.raw || false
|
|
56375
56416
|
});
|
|
56376
56417
|
}
|
|
@@ -59517,7 +59558,7 @@ class ExchangeAccount {
|
|
|
59517
59558
|
});
|
|
59518
59559
|
}
|
|
59519
59560
|
async getSellPriceFromStrategy(payload) {
|
|
59520
|
-
const { symbol, reduce_position } = payload;
|
|
59561
|
+
const { symbol, reduce_position, kind } = payload;
|
|
59521
59562
|
const symbol_config = await this.recomputeSymbolConfig({
|
|
59522
59563
|
symbol
|
|
59523
59564
|
});
|
|
@@ -59525,7 +59566,13 @@ class ExchangeAccount {
|
|
|
59525
59566
|
symbol,
|
|
59526
59567
|
as_view: true
|
|
59527
59568
|
});
|
|
59528
|
-
const focus_position = positions.find((k) =>
|
|
59569
|
+
const focus_position = positions.find((k) => {
|
|
59570
|
+
let condition = Boolean(k.expand?.account_strategy);
|
|
59571
|
+
if (kind) {
|
|
59572
|
+
condition = condition && k.kind === kind;
|
|
59573
|
+
}
|
|
59574
|
+
return condition;
|
|
59575
|
+
});
|
|
59529
59576
|
if (!focus_position) {
|
|
59530
59577
|
return;
|
|
59531
59578
|
}
|
|
@@ -59543,6 +59590,7 @@ class ExchangeAccount {
|
|
|
59543
59590
|
avg_price: focus_position.avg_price,
|
|
59544
59591
|
avg_qty: focus_position.avg_qty
|
|
59545
59592
|
},
|
|
59593
|
+
pnl: focus_position.target_pnl,
|
|
59546
59594
|
strategy: {
|
|
59547
59595
|
reward_factor: strategy.reward_factor,
|
|
59548
59596
|
risk: strategy.risk,
|
|
@@ -59908,7 +59956,8 @@ class App {
|
|
|
59908
59956
|
});
|
|
59909
59957
|
const result = await main_exchange_account.getSellPriceFromStrategy({
|
|
59910
59958
|
symbol: main_account.symbol,
|
|
59911
|
-
reduce_position
|
|
59959
|
+
reduce_position,
|
|
59960
|
+
kind: main_account.kind
|
|
59912
59961
|
});
|
|
59913
59962
|
if (place) {
|
|
59914
59963
|
await reduce_exchange_account.cancelOrders({
|
package/dist/mcp-server.cjs
CHANGED
|
@@ -60715,24 +60715,14 @@ function computeProfitDetail(payload) {
|
|
|
60715
60715
|
const {
|
|
60716
60716
|
focus_position,
|
|
60717
60717
|
strategy,
|
|
60718
|
+
pnl,
|
|
60718
60719
|
price_places = "%.1f",
|
|
60719
60720
|
reduce_position,
|
|
60720
60721
|
decimal_places,
|
|
60721
60722
|
reverse_position
|
|
60722
60723
|
} = payload;
|
|
60723
60724
|
let reward_factor = strategy.reward_factor;
|
|
60724
|
-
|
|
60725
|
-
if (strategy.max_reward_factor === 0) {
|
|
60726
|
-
reward_factor = strategy.reward_factor;
|
|
60727
|
-
}
|
|
60728
|
-
if (focus_position.avg_qty >= focus_position.quantity && strategy.max_reward_factor) {
|
|
60729
|
-
reward_factor = to_f2(focus_position.quantity * strategy.max_reward_factor / focus_position.avg_qty, "%.4f");
|
|
60730
|
-
} else {
|
|
60731
|
-
reward_factor = strategy.reward_factor;
|
|
60732
|
-
}
|
|
60733
|
-
const full_pnl = reward_factor * risk;
|
|
60734
|
-
const profit_percent = to_f2(full_pnl * 100 / (focus_position.avg_price * focus_position.avg_qty), "%.4f");
|
|
60735
|
-
const pnl = to_f2(focus_position.entry * focus_position.quantity * profit_percent / 100, "%.2f");
|
|
60725
|
+
const profit_percent = to_f2(pnl * 100 / (focus_position.avg_price * focus_position.avg_qty), "%.4f");
|
|
60736
60726
|
const diff = pnl / focus_position.quantity;
|
|
60737
60727
|
const sell_price = to_f2(focus_position.kind === "long" ? focus_position.entry + diff : focus_position.entry - diff, price_places);
|
|
60738
60728
|
let loss = 0;
|
|
@@ -61284,6 +61274,7 @@ class Strategy {
|
|
|
61284
61274
|
avg_price: focus_position.avg_price,
|
|
61285
61275
|
avg_qty: focus_position.avg_qty
|
|
61286
61276
|
},
|
|
61277
|
+
pnl: this.pnl(kind),
|
|
61287
61278
|
strategy: {
|
|
61288
61279
|
reward_factor,
|
|
61289
61280
|
max_reward_factor,
|
|
@@ -61405,6 +61396,56 @@ class BaseExchange {
|
|
|
61405
61396
|
decimal_places
|
|
61406
61397
|
});
|
|
61407
61398
|
}
|
|
61399
|
+
async analyzeCandlesticks(payload) {
|
|
61400
|
+
const { symbol } = payload;
|
|
61401
|
+
const arr = [
|
|
61402
|
+
"weekly",
|
|
61403
|
+
"days_3",
|
|
61404
|
+
"daily",
|
|
61405
|
+
"hours_12",
|
|
61406
|
+
"hours_8",
|
|
61407
|
+
"hours_6",
|
|
61408
|
+
"hours_4",
|
|
61409
|
+
"hours_2"
|
|
61410
|
+
];
|
|
61411
|
+
const results = await Promise.all(arr.map((x) => this.analyzeCharts({ chartType: x, raw: true, limit: 99, symbol })));
|
|
61412
|
+
const currentPrice = await this.get_current_price(symbol);
|
|
61413
|
+
const resistance = {};
|
|
61414
|
+
const support = {};
|
|
61415
|
+
for (let i2 = 0;i2 < arr.length; i2++) {
|
|
61416
|
+
const interval = arr[i2];
|
|
61417
|
+
const data = results[i2];
|
|
61418
|
+
for (const value2 of data.slice(1)) {
|
|
61419
|
+
const high = value2[2];
|
|
61420
|
+
const low = value2[3];
|
|
61421
|
+
console.log("slice", { high, low, interval });
|
|
61422
|
+
if (high in resistance) {
|
|
61423
|
+
resistance[high] += 1;
|
|
61424
|
+
} else {
|
|
61425
|
+
resistance[high] = 1;
|
|
61426
|
+
}
|
|
61427
|
+
if (low in support) {
|
|
61428
|
+
support[low] += 1;
|
|
61429
|
+
} else {
|
|
61430
|
+
support[low] = 1;
|
|
61431
|
+
}
|
|
61432
|
+
}
|
|
61433
|
+
}
|
|
61434
|
+
const filteredResistance = Object.fromEntries(Object.entries(resistance).filter(([k, v]) => parseFloat(k) > currentPrice));
|
|
61435
|
+
const filteredSupport = Object.fromEntries(Object.entries(support).filter(([k, v]) => parseFloat(k) < currentPrice));
|
|
61436
|
+
const candlesticks = arr.reduce((acc, interval, index) => {
|
|
61437
|
+
acc[interval] = results[index].slice(1);
|
|
61438
|
+
return acc;
|
|
61439
|
+
}, {});
|
|
61440
|
+
const minimumWeekly = Math.min(...candlesticks["weekly"].map((x) => parseFloat(x[3])));
|
|
61441
|
+
return {
|
|
61442
|
+
candlesticks,
|
|
61443
|
+
resistance: filteredResistance,
|
|
61444
|
+
support: filteredSupport,
|
|
61445
|
+
current_price: currentPrice,
|
|
61446
|
+
minimum_weekly: minimumWeekly
|
|
61447
|
+
};
|
|
61448
|
+
}
|
|
61408
61449
|
}
|
|
61409
61450
|
|
|
61410
61451
|
// src/exchanges/binance.ts
|
|
@@ -62279,8 +62320,8 @@ class BinanceExchange extends BaseExchange {
|
|
|
62279
62320
|
client: this.client,
|
|
62280
62321
|
symbol: payload.symbol,
|
|
62281
62322
|
chartType: payload.chartType,
|
|
62282
|
-
|
|
62283
|
-
raw: payload.raw
|
|
62323
|
+
limit: payload.limit,
|
|
62324
|
+
raw: payload.raw
|
|
62284
62325
|
});
|
|
62285
62326
|
}
|
|
62286
62327
|
async getExchangeAccountInfo(options) {
|
|
@@ -63100,7 +63141,7 @@ class BybitExchange extends BaseExchange {
|
|
|
63100
63141
|
client: this.client,
|
|
63101
63142
|
symbol: payload.symbol,
|
|
63102
63143
|
chartType: payload.chartType,
|
|
63103
|
-
|
|
63144
|
+
limit: payload.limit,
|
|
63104
63145
|
raw: payload.raw || false
|
|
63105
63146
|
});
|
|
63106
63147
|
}
|
|
@@ -66247,7 +66288,7 @@ class ExchangeAccount {
|
|
|
66247
66288
|
});
|
|
66248
66289
|
}
|
|
66249
66290
|
async getSellPriceFromStrategy(payload) {
|
|
66250
|
-
const { symbol, reduce_position } = payload;
|
|
66291
|
+
const { symbol, reduce_position, kind } = payload;
|
|
66251
66292
|
const symbol_config = await this.recomputeSymbolConfig({
|
|
66252
66293
|
symbol
|
|
66253
66294
|
});
|
|
@@ -66255,7 +66296,13 @@ class ExchangeAccount {
|
|
|
66255
66296
|
symbol,
|
|
66256
66297
|
as_view: true
|
|
66257
66298
|
});
|
|
66258
|
-
const focus_position = positions.find((k) =>
|
|
66299
|
+
const focus_position = positions.find((k) => {
|
|
66300
|
+
let condition = Boolean(k.expand?.account_strategy);
|
|
66301
|
+
if (kind) {
|
|
66302
|
+
condition = condition && k.kind === kind;
|
|
66303
|
+
}
|
|
66304
|
+
return condition;
|
|
66305
|
+
});
|
|
66259
66306
|
if (!focus_position) {
|
|
66260
66307
|
return;
|
|
66261
66308
|
}
|
|
@@ -66273,6 +66320,7 @@ class ExchangeAccount {
|
|
|
66273
66320
|
avg_price: focus_position.avg_price,
|
|
66274
66321
|
avg_qty: focus_position.avg_qty
|
|
66275
66322
|
},
|
|
66323
|
+
pnl: focus_position.target_pnl,
|
|
66276
66324
|
strategy: {
|
|
66277
66325
|
reward_factor: strategy.reward_factor,
|
|
66278
66326
|
risk: strategy.risk,
|
|
@@ -66638,7 +66686,8 @@ class App {
|
|
|
66638
66686
|
});
|
|
66639
66687
|
const result = await main_exchange_account.getSellPriceFromStrategy({
|
|
66640
66688
|
symbol: main_account.symbol,
|
|
66641
|
-
reduce_position
|
|
66689
|
+
reduce_position,
|
|
66690
|
+
kind: main_account.kind
|
|
66642
66691
|
});
|
|
66643
66692
|
if (place) {
|
|
66644
66693
|
await reduce_exchange_account.cancelOrders({
|
package/dist/mcp-server.js
CHANGED
|
@@ -60692,24 +60692,14 @@ function computeProfitDetail(payload) {
|
|
|
60692
60692
|
const {
|
|
60693
60693
|
focus_position,
|
|
60694
60694
|
strategy,
|
|
60695
|
+
pnl,
|
|
60695
60696
|
price_places = "%.1f",
|
|
60696
60697
|
reduce_position,
|
|
60697
60698
|
decimal_places,
|
|
60698
60699
|
reverse_position
|
|
60699
60700
|
} = payload;
|
|
60700
60701
|
let reward_factor = strategy.reward_factor;
|
|
60701
|
-
|
|
60702
|
-
if (strategy.max_reward_factor === 0) {
|
|
60703
|
-
reward_factor = strategy.reward_factor;
|
|
60704
|
-
}
|
|
60705
|
-
if (focus_position.avg_qty >= focus_position.quantity && strategy.max_reward_factor) {
|
|
60706
|
-
reward_factor = to_f2(focus_position.quantity * strategy.max_reward_factor / focus_position.avg_qty, "%.4f");
|
|
60707
|
-
} else {
|
|
60708
|
-
reward_factor = strategy.reward_factor;
|
|
60709
|
-
}
|
|
60710
|
-
const full_pnl = reward_factor * risk;
|
|
60711
|
-
const profit_percent = to_f2(full_pnl * 100 / (focus_position.avg_price * focus_position.avg_qty), "%.4f");
|
|
60712
|
-
const pnl = to_f2(focus_position.entry * focus_position.quantity * profit_percent / 100, "%.2f");
|
|
60702
|
+
const profit_percent = to_f2(pnl * 100 / (focus_position.avg_price * focus_position.avg_qty), "%.4f");
|
|
60713
60703
|
const diff = pnl / focus_position.quantity;
|
|
60714
60704
|
const sell_price = to_f2(focus_position.kind === "long" ? focus_position.entry + diff : focus_position.entry - diff, price_places);
|
|
60715
60705
|
let loss = 0;
|
|
@@ -61261,6 +61251,7 @@ class Strategy {
|
|
|
61261
61251
|
avg_price: focus_position.avg_price,
|
|
61262
61252
|
avg_qty: focus_position.avg_qty
|
|
61263
61253
|
},
|
|
61254
|
+
pnl: this.pnl(kind),
|
|
61264
61255
|
strategy: {
|
|
61265
61256
|
reward_factor,
|
|
61266
61257
|
max_reward_factor,
|
|
@@ -61382,6 +61373,56 @@ class BaseExchange {
|
|
|
61382
61373
|
decimal_places
|
|
61383
61374
|
});
|
|
61384
61375
|
}
|
|
61376
|
+
async analyzeCandlesticks(payload) {
|
|
61377
|
+
const { symbol } = payload;
|
|
61378
|
+
const arr = [
|
|
61379
|
+
"weekly",
|
|
61380
|
+
"days_3",
|
|
61381
|
+
"daily",
|
|
61382
|
+
"hours_12",
|
|
61383
|
+
"hours_8",
|
|
61384
|
+
"hours_6",
|
|
61385
|
+
"hours_4",
|
|
61386
|
+
"hours_2"
|
|
61387
|
+
];
|
|
61388
|
+
const results = await Promise.all(arr.map((x) => this.analyzeCharts({ chartType: x, raw: true, limit: 99, symbol })));
|
|
61389
|
+
const currentPrice = await this.get_current_price(symbol);
|
|
61390
|
+
const resistance = {};
|
|
61391
|
+
const support = {};
|
|
61392
|
+
for (let i2 = 0;i2 < arr.length; i2++) {
|
|
61393
|
+
const interval = arr[i2];
|
|
61394
|
+
const data = results[i2];
|
|
61395
|
+
for (const value2 of data.slice(1)) {
|
|
61396
|
+
const high = value2[2];
|
|
61397
|
+
const low = value2[3];
|
|
61398
|
+
console.log("slice", { high, low, interval });
|
|
61399
|
+
if (high in resistance) {
|
|
61400
|
+
resistance[high] += 1;
|
|
61401
|
+
} else {
|
|
61402
|
+
resistance[high] = 1;
|
|
61403
|
+
}
|
|
61404
|
+
if (low in support) {
|
|
61405
|
+
support[low] += 1;
|
|
61406
|
+
} else {
|
|
61407
|
+
support[low] = 1;
|
|
61408
|
+
}
|
|
61409
|
+
}
|
|
61410
|
+
}
|
|
61411
|
+
const filteredResistance = Object.fromEntries(Object.entries(resistance).filter(([k, v]) => parseFloat(k) > currentPrice));
|
|
61412
|
+
const filteredSupport = Object.fromEntries(Object.entries(support).filter(([k, v]) => parseFloat(k) < currentPrice));
|
|
61413
|
+
const candlesticks = arr.reduce((acc, interval, index) => {
|
|
61414
|
+
acc[interval] = results[index].slice(1);
|
|
61415
|
+
return acc;
|
|
61416
|
+
}, {});
|
|
61417
|
+
const minimumWeekly = Math.min(...candlesticks["weekly"].map((x) => parseFloat(x[3])));
|
|
61418
|
+
return {
|
|
61419
|
+
candlesticks,
|
|
61420
|
+
resistance: filteredResistance,
|
|
61421
|
+
support: filteredSupport,
|
|
61422
|
+
current_price: currentPrice,
|
|
61423
|
+
minimum_weekly: minimumWeekly
|
|
61424
|
+
};
|
|
61425
|
+
}
|
|
61385
61426
|
}
|
|
61386
61427
|
|
|
61387
61428
|
// src/exchanges/binance.ts
|
|
@@ -62256,8 +62297,8 @@ class BinanceExchange extends BaseExchange {
|
|
|
62256
62297
|
client: this.client,
|
|
62257
62298
|
symbol: payload.symbol,
|
|
62258
62299
|
chartType: payload.chartType,
|
|
62259
|
-
|
|
62260
|
-
raw: payload.raw
|
|
62300
|
+
limit: payload.limit,
|
|
62301
|
+
raw: payload.raw
|
|
62261
62302
|
});
|
|
62262
62303
|
}
|
|
62263
62304
|
async getExchangeAccountInfo(options) {
|
|
@@ -63077,7 +63118,7 @@ class BybitExchange extends BaseExchange {
|
|
|
63077
63118
|
client: this.client,
|
|
63078
63119
|
symbol: payload.symbol,
|
|
63079
63120
|
chartType: payload.chartType,
|
|
63080
|
-
|
|
63121
|
+
limit: payload.limit,
|
|
63081
63122
|
raw: payload.raw || false
|
|
63082
63123
|
});
|
|
63083
63124
|
}
|
|
@@ -66224,7 +66265,7 @@ class ExchangeAccount {
|
|
|
66224
66265
|
});
|
|
66225
66266
|
}
|
|
66226
66267
|
async getSellPriceFromStrategy(payload) {
|
|
66227
|
-
const { symbol, reduce_position } = payload;
|
|
66268
|
+
const { symbol, reduce_position, kind } = payload;
|
|
66228
66269
|
const symbol_config = await this.recomputeSymbolConfig({
|
|
66229
66270
|
symbol
|
|
66230
66271
|
});
|
|
@@ -66232,7 +66273,13 @@ class ExchangeAccount {
|
|
|
66232
66273
|
symbol,
|
|
66233
66274
|
as_view: true
|
|
66234
66275
|
});
|
|
66235
|
-
const focus_position = positions.find((k) =>
|
|
66276
|
+
const focus_position = positions.find((k) => {
|
|
66277
|
+
let condition = Boolean(k.expand?.account_strategy);
|
|
66278
|
+
if (kind) {
|
|
66279
|
+
condition = condition && k.kind === kind;
|
|
66280
|
+
}
|
|
66281
|
+
return condition;
|
|
66282
|
+
});
|
|
66236
66283
|
if (!focus_position) {
|
|
66237
66284
|
return;
|
|
66238
66285
|
}
|
|
@@ -66250,6 +66297,7 @@ class ExchangeAccount {
|
|
|
66250
66297
|
avg_price: focus_position.avg_price,
|
|
66251
66298
|
avg_qty: focus_position.avg_qty
|
|
66252
66299
|
},
|
|
66300
|
+
pnl: focus_position.target_pnl,
|
|
66253
66301
|
strategy: {
|
|
66254
66302
|
reward_factor: strategy.reward_factor,
|
|
66255
66303
|
risk: strategy.risk,
|
|
@@ -66615,7 +66663,8 @@ class App {
|
|
|
66615
66663
|
});
|
|
66616
66664
|
const result = await main_exchange_account.getSellPriceFromStrategy({
|
|
66617
66665
|
symbol: main_account.symbol,
|
|
66618
|
-
reduce_position
|
|
66666
|
+
reduce_position,
|
|
66667
|
+
kind: main_account.kind
|
|
66619
66668
|
});
|
|
66620
66669
|
if (place) {
|
|
66621
66670
|
await reduce_exchange_account.cancelOrders({
|