@gbozee/ultimate 0.0.2-74 → 0.0.2-75
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 +36 -6
- package/dist/frontend-index.js +55 -15
- package/dist/index.cjs +56 -16
- package/dist/index.d.ts +64 -9
- package/dist/index.js +56 -16
- package/dist/mcp-server.cjs +56 -16
- package/dist/mcp-server.js +56 -16
- package/package.json +1 -1
package/dist/frontend-index.d.ts
CHANGED
|
@@ -402,6 +402,19 @@ export type StrategyPosition = {
|
|
|
402
402
|
entry: number;
|
|
403
403
|
quantity: number;
|
|
404
404
|
};
|
|
405
|
+
export type GapCloserResult = {
|
|
406
|
+
avg_entry: number;
|
|
407
|
+
avg_size: number;
|
|
408
|
+
loss: number;
|
|
409
|
+
stop: number;
|
|
410
|
+
stop_quantity: number;
|
|
411
|
+
re_entry_quantity: number;
|
|
412
|
+
initial_pnl: number;
|
|
413
|
+
tp: number;
|
|
414
|
+
incurred_loss: number;
|
|
415
|
+
pnl: number;
|
|
416
|
+
remaining_quantity: number;
|
|
417
|
+
};
|
|
405
418
|
export type Config = {
|
|
406
419
|
tp_percent: number;
|
|
407
420
|
short_tp_factor: number;
|
|
@@ -442,15 +455,31 @@ export declare class Strategy {
|
|
|
442
455
|
reduce_ratio?: number;
|
|
443
456
|
sell_factor?: number;
|
|
444
457
|
}): {
|
|
445
|
-
[x: string]: any;
|
|
446
|
-
risk: number;
|
|
447
|
-
risk_reward: number;
|
|
448
458
|
last_entry: any;
|
|
449
459
|
first_entry: any;
|
|
450
460
|
threshold: any;
|
|
461
|
+
risk: number;
|
|
462
|
+
risk_reward: number;
|
|
451
463
|
spread: number;
|
|
452
464
|
gap_loss: number;
|
|
453
465
|
net_profit: number;
|
|
466
|
+
long: GapCloserResult;
|
|
467
|
+
short: GapCloserResult;
|
|
468
|
+
};
|
|
469
|
+
gapCloserHelper(payload: {
|
|
470
|
+
risk: number;
|
|
471
|
+
entries?: any[];
|
|
472
|
+
kind: "long" | "short";
|
|
473
|
+
sell_factor?: number;
|
|
474
|
+
reduce_ratio?: number;
|
|
475
|
+
}): {
|
|
476
|
+
risk: number;
|
|
477
|
+
risk_reward: number;
|
|
478
|
+
spread: number;
|
|
479
|
+
gap_loss: number;
|
|
480
|
+
net_profit: number;
|
|
481
|
+
long: GapCloserResult;
|
|
482
|
+
short: GapCloserResult;
|
|
454
483
|
};
|
|
455
484
|
runIterations(payload: {
|
|
456
485
|
kind: "long" | "short";
|
|
@@ -460,15 +489,16 @@ export declare class Strategy {
|
|
|
460
489
|
reduce_ratio?: number;
|
|
461
490
|
sell_factor?: number;
|
|
462
491
|
}): {
|
|
463
|
-
[x: string]: any;
|
|
464
|
-
risk: number;
|
|
465
|
-
risk_reward: number;
|
|
466
492
|
last_entry: any;
|
|
467
493
|
first_entry: any;
|
|
468
494
|
threshold: any;
|
|
495
|
+
risk: number;
|
|
496
|
+
risk_reward: number;
|
|
469
497
|
spread: number;
|
|
470
498
|
gap_loss: number;
|
|
471
499
|
net_profit: number;
|
|
500
|
+
long: GapCloserResult;
|
|
501
|
+
short: GapCloserResult;
|
|
472
502
|
}[];
|
|
473
503
|
getPositionAfterTp(payload: {
|
|
474
504
|
kind: "long" | "short";
|
package/dist/frontend-index.js
CHANGED
|
@@ -1842,9 +1842,6 @@ class Strategy {
|
|
|
1842
1842
|
const reverse_position = this.position[reverse_kind];
|
|
1843
1843
|
let _entry = this.tp(kind);
|
|
1844
1844
|
let _stop = this.tp(reverse_kind);
|
|
1845
|
-
if (!_entry && !_stop) {
|
|
1846
|
-
return null;
|
|
1847
|
-
}
|
|
1848
1845
|
const second_payload = {
|
|
1849
1846
|
entry: _entry,
|
|
1850
1847
|
stop: _stop,
|
|
@@ -1859,14 +1856,60 @@ class Strategy {
|
|
|
1859
1856
|
};
|
|
1860
1857
|
console.log({ second_payload, third_payload });
|
|
1861
1858
|
const app_config = generateOptimumAppConfig(this.config.global_config, second_payload, third_payload);
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
entries =
|
|
1859
|
+
let entries = [];
|
|
1860
|
+
let risk_per_trade = this.config.budget;
|
|
1861
|
+
let last_value = null;
|
|
1862
|
+
if (app_config) {
|
|
1863
|
+
let { entries: _entries, ...rest } = app_config;
|
|
1864
|
+
entries = _entries;
|
|
1865
|
+
risk_per_trade = rest.risk_per_trade;
|
|
1866
|
+
last_value = rest.last_value;
|
|
1867
|
+
if (ignore_entries) {
|
|
1868
|
+
entries = [];
|
|
1869
|
+
}
|
|
1868
1870
|
}
|
|
1869
|
-
const risk = this.to_f(
|
|
1871
|
+
const risk = this.to_f(risk_per_trade);
|
|
1872
|
+
let below_reverse_entries = kind === "long" ? entries.filter((u) => {
|
|
1873
|
+
return u.entry < (reverse_position.entry || focus_position.entry);
|
|
1874
|
+
}) : entries.filter((u) => {
|
|
1875
|
+
return u.entry > (reverse_position.entry || focus_position.entry);
|
|
1876
|
+
});
|
|
1877
|
+
const threshold = below_reverse_entries.at(-1);
|
|
1878
|
+
const result = this.gapCloserHelper({
|
|
1879
|
+
risk,
|
|
1880
|
+
entries,
|
|
1881
|
+
kind,
|
|
1882
|
+
sell_factor,
|
|
1883
|
+
reduce_ratio
|
|
1884
|
+
});
|
|
1885
|
+
return {
|
|
1886
|
+
...result,
|
|
1887
|
+
last_entry: last_value?.entry,
|
|
1888
|
+
first_entry: entries.at(-1)?.entry,
|
|
1889
|
+
threshold
|
|
1890
|
+
};
|
|
1891
|
+
}
|
|
1892
|
+
gapCloserHelper(payload) {
|
|
1893
|
+
const {
|
|
1894
|
+
risk,
|
|
1895
|
+
entries = [],
|
|
1896
|
+
kind,
|
|
1897
|
+
sell_factor = 1,
|
|
1898
|
+
reduce_ratio = 1
|
|
1899
|
+
} = payload;
|
|
1900
|
+
const { entry, quantity } = this.position[kind];
|
|
1901
|
+
const focus_position = this.position[kind];
|
|
1902
|
+
const reverse_kind = kind == "long" ? "short" : "long";
|
|
1903
|
+
const reverse_position = this.position[reverse_kind];
|
|
1904
|
+
let _entry = this.tp(kind);
|
|
1905
|
+
let _stop = this.tp(reverse_kind);
|
|
1906
|
+
const second_payload = {
|
|
1907
|
+
entry: _entry,
|
|
1908
|
+
stop: _stop,
|
|
1909
|
+
risk_reward: this.config.risk_reward,
|
|
1910
|
+
start_risk: this.pnl(reverse_kind),
|
|
1911
|
+
max_risk: this.config.budget
|
|
1912
|
+
};
|
|
1870
1913
|
const adjusted_focus_entries = entries.map((entry2) => {
|
|
1871
1914
|
let adjusted_price = entry2.price;
|
|
1872
1915
|
if (focus_position.quantity > 0) {
|
|
@@ -1886,7 +1929,7 @@ class Strategy {
|
|
|
1886
1929
|
price: entry,
|
|
1887
1930
|
quantity
|
|
1888
1931
|
}
|
|
1889
|
-
]),
|
|
1932
|
+
]), this.config.global_config.decimal_places, this.config.global_config.price_places);
|
|
1890
1933
|
const focus_loss = this.to_f(Math.abs(avg.price - second_payload.stop) * avg.quantity);
|
|
1891
1934
|
let below_reverse_entries = kind === "long" ? entries.filter((u) => {
|
|
1892
1935
|
return u.entry < (reverse_position.entry || focus_position.entry);
|
|
@@ -1913,7 +1956,7 @@ class Strategy {
|
|
|
1913
1956
|
price: reverse_position.entry,
|
|
1914
1957
|
quantity: reverse_position.quantity
|
|
1915
1958
|
}
|
|
1916
|
-
]),
|
|
1959
|
+
]), this.config.global_config.decimal_places, this.config.global_config.price_places);
|
|
1917
1960
|
const sell_quantity = this.to_df(reverse_avg.quantity * sell_factor);
|
|
1918
1961
|
const reverse_pnl = this.to_f(Math.abs(reverse_avg.price - second_payload.stop) * sell_quantity);
|
|
1919
1962
|
const fee_to_pay = this.calculate_fee({
|
|
@@ -1951,9 +1994,6 @@ class Strategy {
|
|
|
1951
1994
|
initial_pnl: this.pnl(reverse_kind),
|
|
1952
1995
|
remaining_quantity: this.to_df(reverse_avg.quantity - sell_quantity)
|
|
1953
1996
|
},
|
|
1954
|
-
last_entry: rest.last_value.entry,
|
|
1955
|
-
first_entry: entries.at(-1)?.entry,
|
|
1956
|
-
threshold,
|
|
1957
1997
|
spread: Math.abs(avg.entry - reverse_avg.entry),
|
|
1958
1998
|
gap_loss: to_f(Math.abs(avg.entry - reverse_avg.entry) * reverse_avg.quantity, "%.2f"),
|
|
1959
1999
|
net_profit: incurred_loss + reverse_pnl
|
package/dist/index.cjs
CHANGED
|
@@ -53902,9 +53902,6 @@ class Strategy {
|
|
|
53902
53902
|
const reverse_position = this.position[reverse_kind];
|
|
53903
53903
|
let _entry = this.tp(kind);
|
|
53904
53904
|
let _stop = this.tp(reverse_kind);
|
|
53905
|
-
if (!_entry && !_stop) {
|
|
53906
|
-
return null;
|
|
53907
|
-
}
|
|
53908
53905
|
const second_payload = {
|
|
53909
53906
|
entry: _entry,
|
|
53910
53907
|
stop: _stop,
|
|
@@ -53919,14 +53916,60 @@ class Strategy {
|
|
|
53919
53916
|
};
|
|
53920
53917
|
console.log({ second_payload, third_payload });
|
|
53921
53918
|
const app_config = generateOptimumAppConfig(this.config.global_config, second_payload, third_payload);
|
|
53922
|
-
|
|
53923
|
-
|
|
53924
|
-
|
|
53925
|
-
|
|
53926
|
-
|
|
53927
|
-
entries =
|
|
53928
|
-
|
|
53929
|
-
|
|
53919
|
+
let entries = [];
|
|
53920
|
+
let risk_per_trade = this.config.budget;
|
|
53921
|
+
let last_value = null;
|
|
53922
|
+
if (app_config) {
|
|
53923
|
+
let { entries: _entries, ...rest } = app_config;
|
|
53924
|
+
entries = _entries;
|
|
53925
|
+
risk_per_trade = rest.risk_per_trade;
|
|
53926
|
+
last_value = rest.last_value;
|
|
53927
|
+
if (ignore_entries) {
|
|
53928
|
+
entries = [];
|
|
53929
|
+
}
|
|
53930
|
+
}
|
|
53931
|
+
const risk = this.to_f(risk_per_trade);
|
|
53932
|
+
let below_reverse_entries = kind === "long" ? entries.filter((u) => {
|
|
53933
|
+
return u.entry < (reverse_position.entry || focus_position.entry);
|
|
53934
|
+
}) : entries.filter((u) => {
|
|
53935
|
+
return u.entry > (reverse_position.entry || focus_position.entry);
|
|
53936
|
+
});
|
|
53937
|
+
const threshold = below_reverse_entries.at(-1);
|
|
53938
|
+
const result = this.gapCloserHelper({
|
|
53939
|
+
risk,
|
|
53940
|
+
entries,
|
|
53941
|
+
kind,
|
|
53942
|
+
sell_factor,
|
|
53943
|
+
reduce_ratio
|
|
53944
|
+
});
|
|
53945
|
+
return {
|
|
53946
|
+
...result,
|
|
53947
|
+
last_entry: last_value?.entry,
|
|
53948
|
+
first_entry: entries.at(-1)?.entry,
|
|
53949
|
+
threshold
|
|
53950
|
+
};
|
|
53951
|
+
}
|
|
53952
|
+
gapCloserHelper(payload) {
|
|
53953
|
+
const {
|
|
53954
|
+
risk,
|
|
53955
|
+
entries = [],
|
|
53956
|
+
kind,
|
|
53957
|
+
sell_factor = 1,
|
|
53958
|
+
reduce_ratio = 1
|
|
53959
|
+
} = payload;
|
|
53960
|
+
const { entry, quantity } = this.position[kind];
|
|
53961
|
+
const focus_position = this.position[kind];
|
|
53962
|
+
const reverse_kind = kind == "long" ? "short" : "long";
|
|
53963
|
+
const reverse_position = this.position[reverse_kind];
|
|
53964
|
+
let _entry = this.tp(kind);
|
|
53965
|
+
let _stop = this.tp(reverse_kind);
|
|
53966
|
+
const second_payload = {
|
|
53967
|
+
entry: _entry,
|
|
53968
|
+
stop: _stop,
|
|
53969
|
+
risk_reward: this.config.risk_reward,
|
|
53970
|
+
start_risk: this.pnl(reverse_kind),
|
|
53971
|
+
max_risk: this.config.budget
|
|
53972
|
+
};
|
|
53930
53973
|
const adjusted_focus_entries = entries.map((entry2) => {
|
|
53931
53974
|
let adjusted_price = entry2.price;
|
|
53932
53975
|
if (focus_position.quantity > 0) {
|
|
@@ -53946,7 +53989,7 @@ class Strategy {
|
|
|
53946
53989
|
price: entry,
|
|
53947
53990
|
quantity
|
|
53948
53991
|
}
|
|
53949
|
-
]),
|
|
53992
|
+
]), this.config.global_config.decimal_places, this.config.global_config.price_places);
|
|
53950
53993
|
const focus_loss = this.to_f(Math.abs(avg.price - second_payload.stop) * avg.quantity);
|
|
53951
53994
|
let below_reverse_entries = kind === "long" ? entries.filter((u) => {
|
|
53952
53995
|
return u.entry < (reverse_position.entry || focus_position.entry);
|
|
@@ -53973,7 +54016,7 @@ class Strategy {
|
|
|
53973
54016
|
price: reverse_position.entry,
|
|
53974
54017
|
quantity: reverse_position.quantity
|
|
53975
54018
|
}
|
|
53976
|
-
]),
|
|
54019
|
+
]), this.config.global_config.decimal_places, this.config.global_config.price_places);
|
|
53977
54020
|
const sell_quantity = this.to_df(reverse_avg.quantity * sell_factor);
|
|
53978
54021
|
const reverse_pnl = this.to_f(Math.abs(reverse_avg.price - second_payload.stop) * sell_quantity);
|
|
53979
54022
|
const fee_to_pay = this.calculate_fee({
|
|
@@ -54011,9 +54054,6 @@ class Strategy {
|
|
|
54011
54054
|
initial_pnl: this.pnl(reverse_kind),
|
|
54012
54055
|
remaining_quantity: this.to_df(reverse_avg.quantity - sell_quantity)
|
|
54013
54056
|
},
|
|
54014
|
-
last_entry: rest.last_value.entry,
|
|
54015
|
-
first_entry: entries.at(-1)?.entry,
|
|
54016
|
-
threshold,
|
|
54017
54057
|
spread: Math.abs(avg.entry - reverse_avg.entry),
|
|
54018
54058
|
gap_loss: to_f2(Math.abs(avg.entry - reverse_avg.entry) * reverse_avg.quantity, "%.2f"),
|
|
54019
54059
|
net_profit: incurred_loss + reverse_pnl
|
package/dist/index.d.ts
CHANGED
|
@@ -528,6 +528,19 @@ export type StrategyPosition = {
|
|
|
528
528
|
entry: number;
|
|
529
529
|
quantity: number;
|
|
530
530
|
};
|
|
531
|
+
export type GapCloserResult = {
|
|
532
|
+
avg_entry: number;
|
|
533
|
+
avg_size: number;
|
|
534
|
+
loss: number;
|
|
535
|
+
stop: number;
|
|
536
|
+
stop_quantity: number;
|
|
537
|
+
re_entry_quantity: number;
|
|
538
|
+
initial_pnl: number;
|
|
539
|
+
tp: number;
|
|
540
|
+
incurred_loss: number;
|
|
541
|
+
pnl: number;
|
|
542
|
+
remaining_quantity: number;
|
|
543
|
+
};
|
|
531
544
|
export type Config = {
|
|
532
545
|
tp_percent: number;
|
|
533
546
|
short_tp_factor: number;
|
|
@@ -568,15 +581,31 @@ export declare class Strategy {
|
|
|
568
581
|
reduce_ratio?: number;
|
|
569
582
|
sell_factor?: number;
|
|
570
583
|
}): {
|
|
571
|
-
[x: string]: any;
|
|
572
|
-
risk: number;
|
|
573
|
-
risk_reward: number;
|
|
574
584
|
last_entry: any;
|
|
575
585
|
first_entry: any;
|
|
576
586
|
threshold: any;
|
|
587
|
+
risk: number;
|
|
588
|
+
risk_reward: number;
|
|
589
|
+
spread: number;
|
|
590
|
+
gap_loss: number;
|
|
591
|
+
net_profit: number;
|
|
592
|
+
long: GapCloserResult;
|
|
593
|
+
short: GapCloserResult;
|
|
594
|
+
};
|
|
595
|
+
gapCloserHelper(payload: {
|
|
596
|
+
risk: number;
|
|
597
|
+
entries?: any[];
|
|
598
|
+
kind: "long" | "short";
|
|
599
|
+
sell_factor?: number;
|
|
600
|
+
reduce_ratio?: number;
|
|
601
|
+
}): {
|
|
602
|
+
risk: number;
|
|
603
|
+
risk_reward: number;
|
|
577
604
|
spread: number;
|
|
578
605
|
gap_loss: number;
|
|
579
606
|
net_profit: number;
|
|
607
|
+
long: GapCloserResult;
|
|
608
|
+
short: GapCloserResult;
|
|
580
609
|
};
|
|
581
610
|
runIterations(payload: {
|
|
582
611
|
kind: "long" | "short";
|
|
@@ -586,15 +615,16 @@ export declare class Strategy {
|
|
|
586
615
|
reduce_ratio?: number;
|
|
587
616
|
sell_factor?: number;
|
|
588
617
|
}): {
|
|
589
|
-
[x: string]: any;
|
|
590
|
-
risk: number;
|
|
591
|
-
risk_reward: number;
|
|
592
618
|
last_entry: any;
|
|
593
619
|
first_entry: any;
|
|
594
620
|
threshold: any;
|
|
621
|
+
risk: number;
|
|
622
|
+
risk_reward: number;
|
|
595
623
|
spread: number;
|
|
596
624
|
gap_loss: number;
|
|
597
625
|
net_profit: number;
|
|
626
|
+
long: GapCloserResult;
|
|
627
|
+
short: GapCloserResult;
|
|
598
628
|
}[];
|
|
599
629
|
getPositionAfterTp(payload: {
|
|
600
630
|
kind: "long" | "short";
|
|
@@ -1469,15 +1499,40 @@ declare class ExchangeAccount$1 {
|
|
|
1469
1499
|
iterations?: number;
|
|
1470
1500
|
raw?: boolean;
|
|
1471
1501
|
}): Promise<Strategy | {
|
|
1472
|
-
[x: string]: any;
|
|
1473
|
-
risk: number;
|
|
1474
|
-
risk_reward: number;
|
|
1475
1502
|
last_entry: any;
|
|
1476
1503
|
first_entry: any;
|
|
1477
1504
|
threshold: any;
|
|
1505
|
+
risk: number;
|
|
1506
|
+
risk_reward: number;
|
|
1478
1507
|
spread: number;
|
|
1479
1508
|
gap_loss: number;
|
|
1480
1509
|
net_profit: number;
|
|
1510
|
+
long: {
|
|
1511
|
+
avg_entry: number;
|
|
1512
|
+
avg_size: number;
|
|
1513
|
+
loss: number;
|
|
1514
|
+
stop: number;
|
|
1515
|
+
stop_quantity: number;
|
|
1516
|
+
re_entry_quantity: number;
|
|
1517
|
+
initial_pnl: number;
|
|
1518
|
+
tp: number;
|
|
1519
|
+
incurred_loss: number;
|
|
1520
|
+
pnl: number;
|
|
1521
|
+
remaining_quantity: number;
|
|
1522
|
+
};
|
|
1523
|
+
short: {
|
|
1524
|
+
avg_entry: number;
|
|
1525
|
+
avg_size: number;
|
|
1526
|
+
loss: number;
|
|
1527
|
+
stop: number;
|
|
1528
|
+
stop_quantity: number;
|
|
1529
|
+
re_entry_quantity: number;
|
|
1530
|
+
initial_pnl: number;
|
|
1531
|
+
tp: number;
|
|
1532
|
+
incurred_loss: number;
|
|
1533
|
+
pnl: number;
|
|
1534
|
+
remaining_quantity: number;
|
|
1535
|
+
};
|
|
1481
1536
|
}[]>;
|
|
1482
1537
|
getCurrentRun(payload: {
|
|
1483
1538
|
symbol: string;
|
package/dist/index.js
CHANGED
|
@@ -53857,9 +53857,6 @@ class Strategy {
|
|
|
53857
53857
|
const reverse_position = this.position[reverse_kind];
|
|
53858
53858
|
let _entry = this.tp(kind);
|
|
53859
53859
|
let _stop = this.tp(reverse_kind);
|
|
53860
|
-
if (!_entry && !_stop) {
|
|
53861
|
-
return null;
|
|
53862
|
-
}
|
|
53863
53860
|
const second_payload = {
|
|
53864
53861
|
entry: _entry,
|
|
53865
53862
|
stop: _stop,
|
|
@@ -53874,14 +53871,60 @@ class Strategy {
|
|
|
53874
53871
|
};
|
|
53875
53872
|
console.log({ second_payload, third_payload });
|
|
53876
53873
|
const app_config = generateOptimumAppConfig(this.config.global_config, second_payload, third_payload);
|
|
53877
|
-
|
|
53878
|
-
|
|
53879
|
-
|
|
53880
|
-
|
|
53881
|
-
|
|
53882
|
-
entries =
|
|
53883
|
-
|
|
53884
|
-
|
|
53874
|
+
let entries = [];
|
|
53875
|
+
let risk_per_trade = this.config.budget;
|
|
53876
|
+
let last_value = null;
|
|
53877
|
+
if (app_config) {
|
|
53878
|
+
let { entries: _entries, ...rest } = app_config;
|
|
53879
|
+
entries = _entries;
|
|
53880
|
+
risk_per_trade = rest.risk_per_trade;
|
|
53881
|
+
last_value = rest.last_value;
|
|
53882
|
+
if (ignore_entries) {
|
|
53883
|
+
entries = [];
|
|
53884
|
+
}
|
|
53885
|
+
}
|
|
53886
|
+
const risk = this.to_f(risk_per_trade);
|
|
53887
|
+
let below_reverse_entries = kind === "long" ? entries.filter((u) => {
|
|
53888
|
+
return u.entry < (reverse_position.entry || focus_position.entry);
|
|
53889
|
+
}) : entries.filter((u) => {
|
|
53890
|
+
return u.entry > (reverse_position.entry || focus_position.entry);
|
|
53891
|
+
});
|
|
53892
|
+
const threshold = below_reverse_entries.at(-1);
|
|
53893
|
+
const result = this.gapCloserHelper({
|
|
53894
|
+
risk,
|
|
53895
|
+
entries,
|
|
53896
|
+
kind,
|
|
53897
|
+
sell_factor,
|
|
53898
|
+
reduce_ratio
|
|
53899
|
+
});
|
|
53900
|
+
return {
|
|
53901
|
+
...result,
|
|
53902
|
+
last_entry: last_value?.entry,
|
|
53903
|
+
first_entry: entries.at(-1)?.entry,
|
|
53904
|
+
threshold
|
|
53905
|
+
};
|
|
53906
|
+
}
|
|
53907
|
+
gapCloserHelper(payload) {
|
|
53908
|
+
const {
|
|
53909
|
+
risk,
|
|
53910
|
+
entries = [],
|
|
53911
|
+
kind,
|
|
53912
|
+
sell_factor = 1,
|
|
53913
|
+
reduce_ratio = 1
|
|
53914
|
+
} = payload;
|
|
53915
|
+
const { entry, quantity } = this.position[kind];
|
|
53916
|
+
const focus_position = this.position[kind];
|
|
53917
|
+
const reverse_kind = kind == "long" ? "short" : "long";
|
|
53918
|
+
const reverse_position = this.position[reverse_kind];
|
|
53919
|
+
let _entry = this.tp(kind);
|
|
53920
|
+
let _stop = this.tp(reverse_kind);
|
|
53921
|
+
const second_payload = {
|
|
53922
|
+
entry: _entry,
|
|
53923
|
+
stop: _stop,
|
|
53924
|
+
risk_reward: this.config.risk_reward,
|
|
53925
|
+
start_risk: this.pnl(reverse_kind),
|
|
53926
|
+
max_risk: this.config.budget
|
|
53927
|
+
};
|
|
53885
53928
|
const adjusted_focus_entries = entries.map((entry2) => {
|
|
53886
53929
|
let adjusted_price = entry2.price;
|
|
53887
53930
|
if (focus_position.quantity > 0) {
|
|
@@ -53901,7 +53944,7 @@ class Strategy {
|
|
|
53901
53944
|
price: entry,
|
|
53902
53945
|
quantity
|
|
53903
53946
|
}
|
|
53904
|
-
]),
|
|
53947
|
+
]), this.config.global_config.decimal_places, this.config.global_config.price_places);
|
|
53905
53948
|
const focus_loss = this.to_f(Math.abs(avg.price - second_payload.stop) * avg.quantity);
|
|
53906
53949
|
let below_reverse_entries = kind === "long" ? entries.filter((u) => {
|
|
53907
53950
|
return u.entry < (reverse_position.entry || focus_position.entry);
|
|
@@ -53928,7 +53971,7 @@ class Strategy {
|
|
|
53928
53971
|
price: reverse_position.entry,
|
|
53929
53972
|
quantity: reverse_position.quantity
|
|
53930
53973
|
}
|
|
53931
|
-
]),
|
|
53974
|
+
]), this.config.global_config.decimal_places, this.config.global_config.price_places);
|
|
53932
53975
|
const sell_quantity = this.to_df(reverse_avg.quantity * sell_factor);
|
|
53933
53976
|
const reverse_pnl = this.to_f(Math.abs(reverse_avg.price - second_payload.stop) * sell_quantity);
|
|
53934
53977
|
const fee_to_pay = this.calculate_fee({
|
|
@@ -53966,9 +54009,6 @@ class Strategy {
|
|
|
53966
54009
|
initial_pnl: this.pnl(reverse_kind),
|
|
53967
54010
|
remaining_quantity: this.to_df(reverse_avg.quantity - sell_quantity)
|
|
53968
54011
|
},
|
|
53969
|
-
last_entry: rest.last_value.entry,
|
|
53970
|
-
first_entry: entries.at(-1)?.entry,
|
|
53971
|
-
threshold,
|
|
53972
54012
|
spread: Math.abs(avg.entry - reverse_avg.entry),
|
|
53973
54013
|
gap_loss: to_f2(Math.abs(avg.entry - reverse_avg.entry) * reverse_avg.quantity, "%.2f"),
|
|
53974
54014
|
net_profit: incurred_loss + reverse_pnl
|
package/dist/mcp-server.cjs
CHANGED
|
@@ -60593,9 +60593,6 @@ class Strategy {
|
|
|
60593
60593
|
const reverse_position = this.position[reverse_kind];
|
|
60594
60594
|
let _entry = this.tp(kind);
|
|
60595
60595
|
let _stop = this.tp(reverse_kind);
|
|
60596
|
-
if (!_entry && !_stop) {
|
|
60597
|
-
return null;
|
|
60598
|
-
}
|
|
60599
60596
|
const second_payload = {
|
|
60600
60597
|
entry: _entry,
|
|
60601
60598
|
stop: _stop,
|
|
@@ -60610,14 +60607,60 @@ class Strategy {
|
|
|
60610
60607
|
};
|
|
60611
60608
|
console.log({ second_payload, third_payload });
|
|
60612
60609
|
const app_config = generateOptimumAppConfig(this.config.global_config, second_payload, third_payload);
|
|
60613
|
-
|
|
60614
|
-
|
|
60615
|
-
|
|
60616
|
-
|
|
60617
|
-
|
|
60618
|
-
entries =
|
|
60619
|
-
|
|
60620
|
-
|
|
60610
|
+
let entries = [];
|
|
60611
|
+
let risk_per_trade = this.config.budget;
|
|
60612
|
+
let last_value = null;
|
|
60613
|
+
if (app_config) {
|
|
60614
|
+
let { entries: _entries, ...rest } = app_config;
|
|
60615
|
+
entries = _entries;
|
|
60616
|
+
risk_per_trade = rest.risk_per_trade;
|
|
60617
|
+
last_value = rest.last_value;
|
|
60618
|
+
if (ignore_entries) {
|
|
60619
|
+
entries = [];
|
|
60620
|
+
}
|
|
60621
|
+
}
|
|
60622
|
+
const risk = this.to_f(risk_per_trade);
|
|
60623
|
+
let below_reverse_entries = kind === "long" ? entries.filter((u) => {
|
|
60624
|
+
return u.entry < (reverse_position.entry || focus_position.entry);
|
|
60625
|
+
}) : entries.filter((u) => {
|
|
60626
|
+
return u.entry > (reverse_position.entry || focus_position.entry);
|
|
60627
|
+
});
|
|
60628
|
+
const threshold = below_reverse_entries.at(-1);
|
|
60629
|
+
const result = this.gapCloserHelper({
|
|
60630
|
+
risk,
|
|
60631
|
+
entries,
|
|
60632
|
+
kind,
|
|
60633
|
+
sell_factor,
|
|
60634
|
+
reduce_ratio
|
|
60635
|
+
});
|
|
60636
|
+
return {
|
|
60637
|
+
...result,
|
|
60638
|
+
last_entry: last_value?.entry,
|
|
60639
|
+
first_entry: entries.at(-1)?.entry,
|
|
60640
|
+
threshold
|
|
60641
|
+
};
|
|
60642
|
+
}
|
|
60643
|
+
gapCloserHelper(payload) {
|
|
60644
|
+
const {
|
|
60645
|
+
risk,
|
|
60646
|
+
entries = [],
|
|
60647
|
+
kind,
|
|
60648
|
+
sell_factor = 1,
|
|
60649
|
+
reduce_ratio = 1
|
|
60650
|
+
} = payload;
|
|
60651
|
+
const { entry, quantity } = this.position[kind];
|
|
60652
|
+
const focus_position = this.position[kind];
|
|
60653
|
+
const reverse_kind = kind == "long" ? "short" : "long";
|
|
60654
|
+
const reverse_position = this.position[reverse_kind];
|
|
60655
|
+
let _entry = this.tp(kind);
|
|
60656
|
+
let _stop = this.tp(reverse_kind);
|
|
60657
|
+
const second_payload = {
|
|
60658
|
+
entry: _entry,
|
|
60659
|
+
stop: _stop,
|
|
60660
|
+
risk_reward: this.config.risk_reward,
|
|
60661
|
+
start_risk: this.pnl(reverse_kind),
|
|
60662
|
+
max_risk: this.config.budget
|
|
60663
|
+
};
|
|
60621
60664
|
const adjusted_focus_entries = entries.map((entry2) => {
|
|
60622
60665
|
let adjusted_price = entry2.price;
|
|
60623
60666
|
if (focus_position.quantity > 0) {
|
|
@@ -60637,7 +60680,7 @@ class Strategy {
|
|
|
60637
60680
|
price: entry,
|
|
60638
60681
|
quantity
|
|
60639
60682
|
}
|
|
60640
|
-
]),
|
|
60683
|
+
]), this.config.global_config.decimal_places, this.config.global_config.price_places);
|
|
60641
60684
|
const focus_loss = this.to_f(Math.abs(avg.price - second_payload.stop) * avg.quantity);
|
|
60642
60685
|
let below_reverse_entries = kind === "long" ? entries.filter((u) => {
|
|
60643
60686
|
return u.entry < (reverse_position.entry || focus_position.entry);
|
|
@@ -60664,7 +60707,7 @@ class Strategy {
|
|
|
60664
60707
|
price: reverse_position.entry,
|
|
60665
60708
|
quantity: reverse_position.quantity
|
|
60666
60709
|
}
|
|
60667
|
-
]),
|
|
60710
|
+
]), this.config.global_config.decimal_places, this.config.global_config.price_places);
|
|
60668
60711
|
const sell_quantity = this.to_df(reverse_avg.quantity * sell_factor);
|
|
60669
60712
|
const reverse_pnl = this.to_f(Math.abs(reverse_avg.price - second_payload.stop) * sell_quantity);
|
|
60670
60713
|
const fee_to_pay = this.calculate_fee({
|
|
@@ -60702,9 +60745,6 @@ class Strategy {
|
|
|
60702
60745
|
initial_pnl: this.pnl(reverse_kind),
|
|
60703
60746
|
remaining_quantity: this.to_df(reverse_avg.quantity - sell_quantity)
|
|
60704
60747
|
},
|
|
60705
|
-
last_entry: rest.last_value.entry,
|
|
60706
|
-
first_entry: entries.at(-1)?.entry,
|
|
60707
|
-
threshold,
|
|
60708
60748
|
spread: Math.abs(avg.entry - reverse_avg.entry),
|
|
60709
60749
|
gap_loss: to_f2(Math.abs(avg.entry - reverse_avg.entry) * reverse_avg.quantity, "%.2f"),
|
|
60710
60750
|
net_profit: incurred_loss + reverse_pnl
|
package/dist/mcp-server.js
CHANGED
|
@@ -60570,9 +60570,6 @@ class Strategy {
|
|
|
60570
60570
|
const reverse_position = this.position[reverse_kind];
|
|
60571
60571
|
let _entry = this.tp(kind);
|
|
60572
60572
|
let _stop = this.tp(reverse_kind);
|
|
60573
|
-
if (!_entry && !_stop) {
|
|
60574
|
-
return null;
|
|
60575
|
-
}
|
|
60576
60573
|
const second_payload = {
|
|
60577
60574
|
entry: _entry,
|
|
60578
60575
|
stop: _stop,
|
|
@@ -60587,14 +60584,60 @@ class Strategy {
|
|
|
60587
60584
|
};
|
|
60588
60585
|
console.log({ second_payload, third_payload });
|
|
60589
60586
|
const app_config = generateOptimumAppConfig(this.config.global_config, second_payload, third_payload);
|
|
60590
|
-
|
|
60591
|
-
|
|
60592
|
-
|
|
60593
|
-
|
|
60594
|
-
|
|
60595
|
-
entries =
|
|
60596
|
-
|
|
60597
|
-
|
|
60587
|
+
let entries = [];
|
|
60588
|
+
let risk_per_trade = this.config.budget;
|
|
60589
|
+
let last_value = null;
|
|
60590
|
+
if (app_config) {
|
|
60591
|
+
let { entries: _entries, ...rest } = app_config;
|
|
60592
|
+
entries = _entries;
|
|
60593
|
+
risk_per_trade = rest.risk_per_trade;
|
|
60594
|
+
last_value = rest.last_value;
|
|
60595
|
+
if (ignore_entries) {
|
|
60596
|
+
entries = [];
|
|
60597
|
+
}
|
|
60598
|
+
}
|
|
60599
|
+
const risk = this.to_f(risk_per_trade);
|
|
60600
|
+
let below_reverse_entries = kind === "long" ? entries.filter((u) => {
|
|
60601
|
+
return u.entry < (reverse_position.entry || focus_position.entry);
|
|
60602
|
+
}) : entries.filter((u) => {
|
|
60603
|
+
return u.entry > (reverse_position.entry || focus_position.entry);
|
|
60604
|
+
});
|
|
60605
|
+
const threshold = below_reverse_entries.at(-1);
|
|
60606
|
+
const result = this.gapCloserHelper({
|
|
60607
|
+
risk,
|
|
60608
|
+
entries,
|
|
60609
|
+
kind,
|
|
60610
|
+
sell_factor,
|
|
60611
|
+
reduce_ratio
|
|
60612
|
+
});
|
|
60613
|
+
return {
|
|
60614
|
+
...result,
|
|
60615
|
+
last_entry: last_value?.entry,
|
|
60616
|
+
first_entry: entries.at(-1)?.entry,
|
|
60617
|
+
threshold
|
|
60618
|
+
};
|
|
60619
|
+
}
|
|
60620
|
+
gapCloserHelper(payload) {
|
|
60621
|
+
const {
|
|
60622
|
+
risk,
|
|
60623
|
+
entries = [],
|
|
60624
|
+
kind,
|
|
60625
|
+
sell_factor = 1,
|
|
60626
|
+
reduce_ratio = 1
|
|
60627
|
+
} = payload;
|
|
60628
|
+
const { entry, quantity } = this.position[kind];
|
|
60629
|
+
const focus_position = this.position[kind];
|
|
60630
|
+
const reverse_kind = kind == "long" ? "short" : "long";
|
|
60631
|
+
const reverse_position = this.position[reverse_kind];
|
|
60632
|
+
let _entry = this.tp(kind);
|
|
60633
|
+
let _stop = this.tp(reverse_kind);
|
|
60634
|
+
const second_payload = {
|
|
60635
|
+
entry: _entry,
|
|
60636
|
+
stop: _stop,
|
|
60637
|
+
risk_reward: this.config.risk_reward,
|
|
60638
|
+
start_risk: this.pnl(reverse_kind),
|
|
60639
|
+
max_risk: this.config.budget
|
|
60640
|
+
};
|
|
60598
60641
|
const adjusted_focus_entries = entries.map((entry2) => {
|
|
60599
60642
|
let adjusted_price = entry2.price;
|
|
60600
60643
|
if (focus_position.quantity > 0) {
|
|
@@ -60614,7 +60657,7 @@ class Strategy {
|
|
|
60614
60657
|
price: entry,
|
|
60615
60658
|
quantity
|
|
60616
60659
|
}
|
|
60617
|
-
]),
|
|
60660
|
+
]), this.config.global_config.decimal_places, this.config.global_config.price_places);
|
|
60618
60661
|
const focus_loss = this.to_f(Math.abs(avg.price - second_payload.stop) * avg.quantity);
|
|
60619
60662
|
let below_reverse_entries = kind === "long" ? entries.filter((u) => {
|
|
60620
60663
|
return u.entry < (reverse_position.entry || focus_position.entry);
|
|
@@ -60641,7 +60684,7 @@ class Strategy {
|
|
|
60641
60684
|
price: reverse_position.entry,
|
|
60642
60685
|
quantity: reverse_position.quantity
|
|
60643
60686
|
}
|
|
60644
|
-
]),
|
|
60687
|
+
]), this.config.global_config.decimal_places, this.config.global_config.price_places);
|
|
60645
60688
|
const sell_quantity = this.to_df(reverse_avg.quantity * sell_factor);
|
|
60646
60689
|
const reverse_pnl = this.to_f(Math.abs(reverse_avg.price - second_payload.stop) * sell_quantity);
|
|
60647
60690
|
const fee_to_pay = this.calculate_fee({
|
|
@@ -60679,9 +60722,6 @@ class Strategy {
|
|
|
60679
60722
|
initial_pnl: this.pnl(reverse_kind),
|
|
60680
60723
|
remaining_quantity: this.to_df(reverse_avg.quantity - sell_quantity)
|
|
60681
60724
|
},
|
|
60682
|
-
last_entry: rest.last_value.entry,
|
|
60683
|
-
first_entry: entries.at(-1)?.entry,
|
|
60684
|
-
threshold,
|
|
60685
60725
|
spread: Math.abs(avg.entry - reverse_avg.entry),
|
|
60686
60726
|
gap_loss: to_f2(Math.abs(avg.entry - reverse_avg.entry) * reverse_avg.quantity, "%.2f"),
|
|
60687
60727
|
net_profit: incurred_loss + reverse_pnl
|