@gbozee/ultimate 0.0.2-56 → 0.0.2-58
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 +37 -1
- package/dist/frontend-index.js +67 -7
- package/dist/index.cjs +1584 -1452
- package/dist/index.d.ts +133 -69
- package/dist/index.js +1584 -1452
- package/package.json +1 -1
package/dist/frontend-index.d.ts
CHANGED
|
@@ -372,6 +372,7 @@ export type Config = {
|
|
|
372
372
|
fee_percent?: number;
|
|
373
373
|
budget: number;
|
|
374
374
|
risk_reward: number;
|
|
375
|
+
reduce_ratio: number;
|
|
375
376
|
global_config: GlobalConfig;
|
|
376
377
|
};
|
|
377
378
|
export declare class Strategy {
|
|
@@ -389,7 +390,7 @@ export declare class Strategy {
|
|
|
389
390
|
get decimal_places(): string;
|
|
390
391
|
to_f(price: number): number;
|
|
391
392
|
to_df(quantity: number): number;
|
|
392
|
-
pnl(kind: "long" | "short"): number;
|
|
393
|
+
pnl(kind: "long" | "short", _position?: StrategyPosition): number;
|
|
393
394
|
tp(kind: "long" | "short"): number;
|
|
394
395
|
calculate_fee(position: {
|
|
395
396
|
price: number;
|
|
@@ -419,6 +420,41 @@ export declare class Strategy {
|
|
|
419
420
|
first_entry: any;
|
|
420
421
|
threshold: any;
|
|
421
422
|
}[];
|
|
423
|
+
getPositionAfterTp(payload: {
|
|
424
|
+
kind: "long" | "short";
|
|
425
|
+
include_fees?: boolean;
|
|
426
|
+
}): {
|
|
427
|
+
[x: string]: number | {
|
|
428
|
+
entry: number;
|
|
429
|
+
quantity: number;
|
|
430
|
+
} | {
|
|
431
|
+
[x: string]: number;
|
|
432
|
+
entry?: undefined;
|
|
433
|
+
quantity?: undefined;
|
|
434
|
+
};
|
|
435
|
+
pnl: {
|
|
436
|
+
[x: string]: number;
|
|
437
|
+
};
|
|
438
|
+
spread: number;
|
|
439
|
+
};
|
|
440
|
+
getPositionAfterIteration(payload: {
|
|
441
|
+
kind: "long" | "short";
|
|
442
|
+
iterations: number;
|
|
443
|
+
with_fees?: boolean;
|
|
444
|
+
}): {
|
|
445
|
+
[x: string]: number | {
|
|
446
|
+
entry: number;
|
|
447
|
+
quantity: number;
|
|
448
|
+
} | {
|
|
449
|
+
[x: string]: number;
|
|
450
|
+
entry?: undefined;
|
|
451
|
+
quantity?: undefined;
|
|
452
|
+
};
|
|
453
|
+
pnl: {
|
|
454
|
+
[x: string]: number;
|
|
455
|
+
};
|
|
456
|
+
spread: number;
|
|
457
|
+
}[];
|
|
422
458
|
}
|
|
423
459
|
|
|
424
460
|
export {};
|
package/dist/frontend-index.js
CHANGED
|
@@ -1663,8 +1663,8 @@ class Strategy {
|
|
|
1663
1663
|
to_df(quantity) {
|
|
1664
1664
|
return to_f(quantity, this.decimal_places);
|
|
1665
1665
|
}
|
|
1666
|
-
pnl(kind) {
|
|
1667
|
-
const position2 = this.position[kind];
|
|
1666
|
+
pnl(kind, _position) {
|
|
1667
|
+
const position2 = _position || this.position[kind];
|
|
1668
1668
|
const { entry, quantity } = position2;
|
|
1669
1669
|
const notional = entry * quantity;
|
|
1670
1670
|
let tp_percent = this.config.tp_percent;
|
|
@@ -1675,10 +1675,14 @@ class Strategy {
|
|
|
1675
1675
|
return this.to_f(profit);
|
|
1676
1676
|
}
|
|
1677
1677
|
tp(kind) {
|
|
1678
|
-
|
|
1678
|
+
let position2 = this.position[kind];
|
|
1679
|
+
if (position2.quantity == 0) {
|
|
1680
|
+
const reverse_kind = kind == "long" ? "short" : "long";
|
|
1681
|
+
position2 = this.position[reverse_kind];
|
|
1682
|
+
}
|
|
1679
1683
|
const { entry, quantity } = position2;
|
|
1680
|
-
const profit = this.pnl(kind);
|
|
1681
|
-
const diff = profit / quantity;
|
|
1684
|
+
const profit = this.pnl(kind, position2);
|
|
1685
|
+
const diff = profit / (quantity || 1);
|
|
1682
1686
|
return this.to_f(kind == "long" ? entry + diff : entry - diff);
|
|
1683
1687
|
}
|
|
1684
1688
|
calculate_fee(position2) {
|
|
@@ -1744,9 +1748,9 @@ class Strategy {
|
|
|
1744
1748
|
]), rest.decimal_places, rest.price_places);
|
|
1745
1749
|
const focus_loss = this.to_f((avg.price - second_payload.stop) * avg.quantity);
|
|
1746
1750
|
let below_reverse_entries = kind === "long" ? entries.filter((u) => {
|
|
1747
|
-
return u.entry < reverse_position.entry;
|
|
1751
|
+
return u.entry < (reverse_position.entry || focus_position.entry);
|
|
1748
1752
|
}) : entries.filter((u) => {
|
|
1749
|
-
return u.entry > reverse_position.entry;
|
|
1753
|
+
return u.entry > (reverse_position.entry || focus_position.entry);
|
|
1750
1754
|
});
|
|
1751
1755
|
const threshold = below_reverse_entries.at(-1);
|
|
1752
1756
|
let adjusted_reverse_entries = entries.map((entry2) => {
|
|
@@ -1844,6 +1848,62 @@ class Strategy {
|
|
|
1844
1848
|
}
|
|
1845
1849
|
return result;
|
|
1846
1850
|
}
|
|
1851
|
+
getPositionAfterTp(payload) {
|
|
1852
|
+
const { kind, include_fees = false } = payload;
|
|
1853
|
+
const focus_position = this.position[kind];
|
|
1854
|
+
const reverse_kind = kind == "long" ? "short" : "long";
|
|
1855
|
+
const reverse_position = this.position[reverse_kind];
|
|
1856
|
+
const focus_tp = this.tp(kind);
|
|
1857
|
+
const focus_pnl = this.pnl(kind);
|
|
1858
|
+
const fees = include_fees ? this.calculate_fee({
|
|
1859
|
+
price: focus_tp,
|
|
1860
|
+
quantity: focus_position.quantity
|
|
1861
|
+
}) * 2 : 0;
|
|
1862
|
+
const expected_loss = (focus_pnl - fees) * this.config.reduce_ratio;
|
|
1863
|
+
const actual_loss = Math.abs(focus_tp - reverse_position.entry) * reverse_position.quantity;
|
|
1864
|
+
const ratio = expected_loss / actual_loss;
|
|
1865
|
+
const loss_quantity = this.to_df(ratio * reverse_position.quantity);
|
|
1866
|
+
const remaining_quantity = this.to_df(reverse_position.quantity - loss_quantity);
|
|
1867
|
+
return {
|
|
1868
|
+
[kind]: {
|
|
1869
|
+
entry: focus_tp,
|
|
1870
|
+
quantity: remaining_quantity
|
|
1871
|
+
},
|
|
1872
|
+
[reverse_kind]: {
|
|
1873
|
+
entry: reverse_position.entry,
|
|
1874
|
+
quantity: remaining_quantity
|
|
1875
|
+
},
|
|
1876
|
+
pnl: {
|
|
1877
|
+
[kind]: focus_pnl,
|
|
1878
|
+
[reverse_kind]: -expected_loss
|
|
1879
|
+
},
|
|
1880
|
+
spread: this.to_f(Math.abs(focus_tp - reverse_position.entry) * remaining_quantity)
|
|
1881
|
+
};
|
|
1882
|
+
}
|
|
1883
|
+
getPositionAfterIteration(payload) {
|
|
1884
|
+
const { kind, iterations, with_fees = false } = payload;
|
|
1885
|
+
let _result = this.getPositionAfterTp({
|
|
1886
|
+
kind,
|
|
1887
|
+
include_fees: with_fees
|
|
1888
|
+
});
|
|
1889
|
+
const result = [_result];
|
|
1890
|
+
for (let i = 0;i < iterations - 1; i++) {
|
|
1891
|
+
const instance = new Strategy({
|
|
1892
|
+
long: _result.long,
|
|
1893
|
+
short: _result.short,
|
|
1894
|
+
config: {
|
|
1895
|
+
...this.config,
|
|
1896
|
+
tp_percent: this.config.tp_percent + (i + 1) * 0.3
|
|
1897
|
+
}
|
|
1898
|
+
});
|
|
1899
|
+
_result = instance.getPositionAfterTp({
|
|
1900
|
+
kind,
|
|
1901
|
+
include_fees: with_fees
|
|
1902
|
+
});
|
|
1903
|
+
result.push(_result);
|
|
1904
|
+
}
|
|
1905
|
+
return result;
|
|
1906
|
+
}
|
|
1847
1907
|
}
|
|
1848
1908
|
export {
|
|
1849
1909
|
to_f,
|