Qubx 0.2.4__tar.gz → 0.2.5__tar.gz
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.
Potentially problematic release.
This version of Qubx might be problematic. Click here for more details.
- {qubx-0.2.4 → qubx-0.2.5}/PKG-INFO +1 -1
- {qubx-0.2.4 → qubx-0.2.5}/pyproject.toml +1 -1
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/backtester/queue.py +2 -2
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/core/helpers.py +2 -1
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/core/metrics.py +26 -19
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/core/series.pyi +12 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/data/readers.py +1 -1
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/pandaz/ta.py +1 -1
- qubx-0.2.5/src/qubx/ta/indicators.pxd +138 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/ta/indicators.pyi +7 -1
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/ta/indicators.pyx +7 -81
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/trackers/sizers.py +9 -1
- {qubx-0.2.4 → qubx-0.2.5}/README.md +0 -0
- {qubx-0.2.4 → qubx-0.2.5}/build.py +0 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/__init__.py +0 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/_nb_magic.py +0 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/backtester/__init__.py +0 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/backtester/ome.py +0 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/backtester/optimization.py +0 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/backtester/simulator.py +0 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/core/__init__.py +0 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/core/account.py +0 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/core/basics.py +0 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/core/context.py +0 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/core/exceptions.py +0 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/core/loggers.py +0 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/core/lookups.py +0 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/core/series.pxd +0 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/core/series.pyx +0 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/core/strategy.py +0 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/core/utils.pyi +0 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/core/utils.pyx +0 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/data/helpers.py +0 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/gathering/simplest.py +0 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/impl/ccxt_connector.py +0 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/impl/ccxt_customizations.py +0 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/impl/ccxt_trading.py +0 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/impl/ccxt_utils.py +0 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/math/__init__.py +0 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/math/stats.py +0 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/pandaz/__init__.py +0 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/pandaz/utils.py +0 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/ta/__init__.py +0 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/trackers/__init__.py +0 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/trackers/composite.py +0 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/trackers/rebalancers.py +0 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/trackers/riskctrl.py +0 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/utils/__init__.py +0 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/utils/_pyxreloader.py +0 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/utils/charting/lookinglass.py +0 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/utils/charting/mpl_helpers.py +0 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/utils/marketdata/binance.py +0 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/utils/misc.py +0 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/utils/ntp.py +0 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/utils/runner.py +0 -0
- {qubx-0.2.4 → qubx-0.2.5}/src/qubx/utils/time.py +0 -0
|
@@ -137,7 +137,7 @@ class SimulatedDataQueue:
|
|
|
137
137
|
def __iter__(self) -> Iterator:
|
|
138
138
|
logger.debug("Initializing chunks for each loader")
|
|
139
139
|
assert self._start is not None
|
|
140
|
-
self._current_time = int(pd.Timestamp(self._start).timestamp() *
|
|
140
|
+
self._current_time = int(pd.Timestamp(self._start).timestamp() * 1e9)
|
|
141
141
|
self._index_to_chunk_size = {}
|
|
142
142
|
self._index_to_iterator = {}
|
|
143
143
|
self._event_heap = []
|
|
@@ -185,7 +185,7 @@ class SimulatedDataQueue:
|
|
|
185
185
|
@_SW.watch("DataQueue")
|
|
186
186
|
def _next_chunk(self, index: int) -> list[Any]:
|
|
187
187
|
if index not in self._index_to_iterator:
|
|
188
|
-
self._index_to_iterator[index] = self._index_to_loader[index].load(self._current_time, self._stop) # type: ignore
|
|
188
|
+
self._index_to_iterator[index] = self._index_to_loader[index].load(pd.Timestamp(self._current_time, unit="ns"), self._stop) # type: ignore
|
|
189
189
|
iterator = self._index_to_iterator[index]
|
|
190
190
|
try:
|
|
191
191
|
return next(iterator)
|
|
@@ -353,7 +353,8 @@ def set_parameters_to_object(strategy: Any, **kwargs):
|
|
|
353
353
|
raise ValueError("Internal variable can't be set from external parameter !")
|
|
354
354
|
if hasattr(strategy, k):
|
|
355
355
|
strategy.__dict__[k] = v
|
|
356
|
-
|
|
356
|
+
v_str = str(v).replace(">", "").replace("<", "")
|
|
357
|
+
_log_info += f"\n\tset <green>{k}</green> <- <red>{v_str}</red>"
|
|
357
358
|
|
|
358
359
|
if _log_info:
|
|
359
360
|
logger.info(f"<yellow>{strategy.__class__.__name__}</yellow> new parameters:" + _log_info)
|
|
@@ -661,19 +661,23 @@ def portfolio_metrics(
|
|
|
661
661
|
returns_on_init_bp = returns_on_init_bp[:end]
|
|
662
662
|
|
|
663
663
|
# aggregate them to daily (if we have intraday portfolio)
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
664
|
+
try:
|
|
665
|
+
if infer_series_frequency(returns) < pd.Timedelta("1D").to_timedelta64():
|
|
666
|
+
returns_daily = aggregate_returns(returns, "daily")
|
|
667
|
+
returns_on_init_bp = aggregate_returns(returns_on_init_bp, "daily")
|
|
668
|
+
except:
|
|
669
|
+
returns_daily = returns
|
|
667
670
|
|
|
668
671
|
# todo: add transaction_cost calculations
|
|
669
672
|
equity = init_cash + pft_total["Total_PnL"]
|
|
670
673
|
mdd, ddstart, ddpeak, ddrecover, dd_data = absmaxdd(equity)
|
|
671
|
-
|
|
674
|
+
execs = len(executions_log)
|
|
675
|
+
mdd_pct = 100 * dd_data / equity.cummax() if execs > 0 else pd.Series(0, index=equity.index)
|
|
672
676
|
sheet["equity"] = equity
|
|
673
677
|
sheet["gain"] = sheet["equity"].iloc[-1] - sheet["equity"].iloc[0]
|
|
674
678
|
sheet["cagr"] = cagr(returns_daily, performance_statistics_period)
|
|
675
679
|
sheet["sharpe"] = sharpe_ratio(returns_daily, risk_free, performance_statistics_period)
|
|
676
|
-
sheet["qr"] = qr(equity)
|
|
680
|
+
sheet["qr"] = qr(equity) if execs > 0 else 0
|
|
677
681
|
sheet["drawdown_usd"] = dd_data
|
|
678
682
|
sheet["drawdown_pct"] = mdd_pct
|
|
679
683
|
# 25-May-2019: MDE fixed Max DD pct calculations
|
|
@@ -709,7 +713,7 @@ def portfolio_metrics(
|
|
|
709
713
|
sheet["fees"] = pft_total["Total_Commissions"].iloc[-1]
|
|
710
714
|
|
|
711
715
|
# executions metrics
|
|
712
|
-
sheet["execs"] =
|
|
716
|
+
sheet["execs"] = execs
|
|
713
717
|
|
|
714
718
|
return sheet
|
|
715
719
|
|
|
@@ -722,6 +726,7 @@ def tearsheet(
|
|
|
722
726
|
timeframe: str | pd.Timedelta | None = None,
|
|
723
727
|
sort_by: str | None = "Sharpe",
|
|
724
728
|
sort_ascending: bool = False,
|
|
729
|
+
plot_equities: bool = True,
|
|
725
730
|
):
|
|
726
731
|
if timeframe is None:
|
|
727
732
|
timeframe = _estimate_timeframe(session)
|
|
@@ -739,19 +744,21 @@ def tearsheet(
|
|
|
739
744
|
for s in session:
|
|
740
745
|
report, mtrx = _pfl_metrics_prepare(s, account_transactions, performance_statistics_period)
|
|
741
746
|
_rs.append(report)
|
|
742
|
-
if
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
747
|
+
if plot_equities:
|
|
748
|
+
if compound:
|
|
749
|
+
# _eq.append(pd.Series(100 * mtrx["compound_returns"], name=s.trading_id))
|
|
750
|
+
compound_returns = mtrx["compound_returns"].resample(timeframe).ffill()
|
|
751
|
+
plt.plot(100 * compound_returns, label=s.name)
|
|
752
|
+
else:
|
|
753
|
+
# _eq.append(pd.Series(mtrx["equity"], name=s.trading_id))
|
|
754
|
+
equity = mtrx["equity"].resample(timeframe).ffill()
|
|
755
|
+
plt.plot(equity, label=s.name)
|
|
756
|
+
|
|
757
|
+
if plot_equities:
|
|
758
|
+
if len(session) <= 15:
|
|
759
|
+
plt.legend(ncol=max(1, len(session) // 5))
|
|
760
|
+
plt.title("Comparison of Equity Curves")
|
|
761
|
+
|
|
755
762
|
report = pd.concat(_rs, axis=1).T
|
|
756
763
|
report["id"] = [s.id for s in session]
|
|
757
764
|
report = report.set_index("id", append=True).swaplevel()
|
|
@@ -4,6 +4,11 @@ from typing import Any, Tuple
|
|
|
4
4
|
import pandas as pd
|
|
5
5
|
|
|
6
6
|
class Bar:
|
|
7
|
+
open: float
|
|
8
|
+
high: float
|
|
9
|
+
low: float
|
|
10
|
+
close: float
|
|
11
|
+
volume: float
|
|
7
12
|
def __init__(self, time, open, high, low, close, volume, bought_volume=0): ...
|
|
8
13
|
|
|
9
14
|
class Quote:
|
|
@@ -28,8 +33,15 @@ class Locator:
|
|
|
28
33
|
def __getitem__(self, idx): ...
|
|
29
34
|
def find(self, t: str) -> Tuple[np.datetime64, Any]: ...
|
|
30
35
|
|
|
36
|
+
class Indexed:
|
|
37
|
+
def __getitem__(self, idx): ...
|
|
38
|
+
|
|
31
39
|
class TimeSeries:
|
|
32
40
|
loc: Locator
|
|
41
|
+
timeframe: str
|
|
42
|
+
max_series_length: int
|
|
43
|
+
times: Indexed
|
|
44
|
+
values: Indexed
|
|
33
45
|
def __init__(self, name, timeframe, max_series_length, process_every_update=True) -> None: ...
|
|
34
46
|
def __getitem__(self, idx): ...
|
|
35
47
|
def update(self, time: int, value: float) -> bool: ...
|
|
@@ -789,7 +789,7 @@ class QuestDBSqlCandlesBuilder(QuestDBSqlBuilder):
|
|
|
789
789
|
|
|
790
790
|
where = f"where symbol = '{symb}'"
|
|
791
791
|
w0 = f"timestamp >= '{start}'" if start else ""
|
|
792
|
-
w1 = f"timestamp
|
|
792
|
+
w1 = f"timestamp < '{end}'" if end else ""
|
|
793
793
|
|
|
794
794
|
# - fix: when no data ranges are provided we must skip empy where keyword
|
|
795
795
|
if w0 or w1:
|
|
@@ -695,7 +695,7 @@ def macd(x: pd.Series, fast=12, slow=26, signal=9, method="ema", signal_method="
|
|
|
695
695
|
return smooth(x_diff, signal_method, signal).rename("macd")
|
|
696
696
|
|
|
697
697
|
|
|
698
|
-
def atr(x: pd.
|
|
698
|
+
def atr(x: pd.DataFrame, window=14, smoother="sma", percentage=False) -> pd.Series:
|
|
699
699
|
"""
|
|
700
700
|
Average True Range indicator
|
|
701
701
|
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
cimport numpy as np
|
|
2
|
+
from qubx.core.series cimport Indicator, IndicatorOHLC, RollingSum, TimeSeries, OHLCV, Bar
|
|
3
|
+
|
|
4
|
+
cdef class Sma(Indicator):
|
|
5
|
+
cdef unsigned int period
|
|
6
|
+
cdef RollingSum summator
|
|
7
|
+
|
|
8
|
+
cpdef double calculate(self, long long time, double value, short new_item_started)
|
|
9
|
+
|
|
10
|
+
cdef class Ema(Indicator):
|
|
11
|
+
cdef int period
|
|
12
|
+
cdef np.ndarray __s
|
|
13
|
+
cdef int __i
|
|
14
|
+
cdef double alpha
|
|
15
|
+
cdef double alpha_1
|
|
16
|
+
cdef unsigned short init_mean
|
|
17
|
+
cdef unsigned short _init_stage
|
|
18
|
+
|
|
19
|
+
cpdef double calculate(self, long long time, double value, short new_item_started)
|
|
20
|
+
|
|
21
|
+
cdef class Tema(Indicator):
|
|
22
|
+
cdef int period
|
|
23
|
+
cdef unsigned short init_mean
|
|
24
|
+
cdef TimeSeries ser0
|
|
25
|
+
cdef Ema ema1
|
|
26
|
+
cdef Ema ema2
|
|
27
|
+
cdef Ema ema3
|
|
28
|
+
cpdef double calculate(self, long long time, double value, short new_item_started)
|
|
29
|
+
|
|
30
|
+
cdef class Dema(Indicator):
|
|
31
|
+
cdef int period
|
|
32
|
+
cdef unsigned short init_mean
|
|
33
|
+
cdef TimeSeries ser0
|
|
34
|
+
cdef Ema ema1
|
|
35
|
+
cdef Ema ema2
|
|
36
|
+
|
|
37
|
+
cpdef double calculate(self, long long time, double value, short new_item_started)
|
|
38
|
+
|
|
39
|
+
cdef class Kama(Indicator):
|
|
40
|
+
cdef int period
|
|
41
|
+
cdef int fast_span
|
|
42
|
+
cdef int slow_span
|
|
43
|
+
cdef double _S1
|
|
44
|
+
cdef double _K1
|
|
45
|
+
cdef _x_past
|
|
46
|
+
cdef RollingSum summator
|
|
47
|
+
|
|
48
|
+
cpdef double calculate(self, long long time, double value, short new_item_started)
|
|
49
|
+
|
|
50
|
+
cdef class Highest(Indicator):
|
|
51
|
+
cdef int period
|
|
52
|
+
cdef object queue
|
|
53
|
+
cpdef double calculate(self, long long time, double value, short new_item_started)
|
|
54
|
+
|
|
55
|
+
cdef class Lowest(Indicator):
|
|
56
|
+
cdef int period
|
|
57
|
+
cdef object queue
|
|
58
|
+
cpdef double calculate(self, long long time, double value, short new_item_started)
|
|
59
|
+
|
|
60
|
+
cdef class Std(Indicator):
|
|
61
|
+
cdef int period
|
|
62
|
+
cpdef double calculate(self, long long time, double value, short new_item_started)
|
|
63
|
+
|
|
64
|
+
cdef class Pewma(Indicator):
|
|
65
|
+
cdef public TimeSeries std
|
|
66
|
+
cdef double alpha, beta
|
|
67
|
+
cdef int T
|
|
68
|
+
|
|
69
|
+
cdef double _mean, _vstd, _var
|
|
70
|
+
cdef double mean, vstd, var
|
|
71
|
+
cdef long _i
|
|
72
|
+
|
|
73
|
+
cpdef double calculate(self, long long time, double value, short new_item_started)
|
|
74
|
+
|
|
75
|
+
cdef class PewmaOutliersDetector(Indicator):
|
|
76
|
+
cdef public TimeSeries upper, lower, outliers, std
|
|
77
|
+
cdef double alpha, beta, threshold
|
|
78
|
+
cdef int T
|
|
79
|
+
cdef str dist
|
|
80
|
+
|
|
81
|
+
cdef double student_t_df
|
|
82
|
+
cdef long _i
|
|
83
|
+
cdef double mean, vstd, variance
|
|
84
|
+
cdef double _mean, _vstd, _variance, _z_thr
|
|
85
|
+
|
|
86
|
+
cpdef double calculate(self, long long time, double x, short new_item_started)
|
|
87
|
+
|
|
88
|
+
cdef double _get_z_thr(self)
|
|
89
|
+
cdef double _get_alpha(self, double p_t)
|
|
90
|
+
cdef double _get_mean(self, double x, double alpha_t)
|
|
91
|
+
cdef double _get_variance(self, double x, double alpha_t)
|
|
92
|
+
cdef double _get_std(self, double variance, double mean)
|
|
93
|
+
cdef double _get_p(self, double x)
|
|
94
|
+
|
|
95
|
+
cdef class Psar(IndicatorOHLC):
|
|
96
|
+
cdef int _bull
|
|
97
|
+
cdef double _af
|
|
98
|
+
cdef double _psar
|
|
99
|
+
cdef double _lp
|
|
100
|
+
cdef double _hp
|
|
101
|
+
|
|
102
|
+
cdef int bull
|
|
103
|
+
cdef double af
|
|
104
|
+
cdef double psar
|
|
105
|
+
cdef double lp
|
|
106
|
+
cdef double hp
|
|
107
|
+
|
|
108
|
+
cdef public TimeSeries upper
|
|
109
|
+
cdef public TimeSeries lower
|
|
110
|
+
|
|
111
|
+
cdef double iaf
|
|
112
|
+
cdef double maxaf
|
|
113
|
+
|
|
114
|
+
cdef _store(self)
|
|
115
|
+
cdef _restore(self)
|
|
116
|
+
|
|
117
|
+
cpdef double calculate(self, long long time, Bar bar, short new_item_started)
|
|
118
|
+
|
|
119
|
+
cdef class Atr(IndicatorOHLC):
|
|
120
|
+
cdef short percentage
|
|
121
|
+
cdef TimeSeries tr
|
|
122
|
+
cdef Indicator ma
|
|
123
|
+
|
|
124
|
+
cpdef double calculate(self, long long time, Bar bar, short new_item_started)
|
|
125
|
+
|
|
126
|
+
cdef class Swings(IndicatorOHLC):
|
|
127
|
+
cdef double _min_l
|
|
128
|
+
cdef long long _min_t
|
|
129
|
+
cdef double _max_h
|
|
130
|
+
cdef long long _max_t
|
|
131
|
+
cdef OHLCV base
|
|
132
|
+
cdef Indicator trend
|
|
133
|
+
# tops contain upper pivot point prices
|
|
134
|
+
# tops_detection_lag contain time lag when top was actually spotted
|
|
135
|
+
cdef public TimeSeries tops, tops_detection_lag
|
|
136
|
+
cdef public TimeSeries bottoms, bottoms_detection_lag
|
|
137
|
+
|
|
138
|
+
cpdef double calculate(self, long long time, Bar bar, short new_item_started)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from qubx.core.series import OHLCV, Indicator, TimeSeries
|
|
1
|
+
from qubx.core.series import OHLCV, Indicator, TimeSeries, IndicatorOHLC
|
|
2
2
|
|
|
3
3
|
def sma(series: TimeSeries, period: int): ...
|
|
4
4
|
def ema(series: TimeSeries, period: int, init_mean: bool = True): ...
|
|
@@ -14,3 +14,9 @@ def psar(series: OHLCV, iaf: float = 0.02, maxaf: float = 0.2): ...
|
|
|
14
14
|
def smooth(series: TimeSeries, smoother: str, *args, **kwargs) -> Indicator: ...
|
|
15
15
|
def atr(series: OHLCV, period: int = 14, smoother="sma", percentage: bool = False): ...
|
|
16
16
|
def swings(series: OHLCV, trend_indicator, **indicator_args): ...
|
|
17
|
+
|
|
18
|
+
class Kama(Indicator):
|
|
19
|
+
def __init__(self, name: str, series: TimeSeries, period: int, fast_span: int = 2, slow_span: int = 30): ...
|
|
20
|
+
|
|
21
|
+
class Atr(IndicatorOHLC):
|
|
22
|
+
def __init__(self, name: str, series: OHLCV, period: int, smoother: str, percentage: bool): ...
|
|
@@ -16,12 +16,7 @@ cdef class Sma(Indicator):
|
|
|
16
16
|
"""
|
|
17
17
|
Simple Moving Average indicator
|
|
18
18
|
"""
|
|
19
|
-
cdef unsigned int period
|
|
20
|
-
cdef RollingSum summator
|
|
21
19
|
|
|
22
|
-
"""
|
|
23
|
-
Simple moving average
|
|
24
|
-
"""
|
|
25
20
|
def __init__(self, str name, TimeSeries series, int period):
|
|
26
21
|
self.period = period
|
|
27
22
|
self.summator = RollingSum(period)
|
|
@@ -40,13 +35,6 @@ cdef class Ema(Indicator):
|
|
|
40
35
|
"""
|
|
41
36
|
Exponential moving average
|
|
42
37
|
"""
|
|
43
|
-
cdef int period
|
|
44
|
-
cdef np.ndarray __s
|
|
45
|
-
cdef int __i
|
|
46
|
-
cdef double alpha
|
|
47
|
-
cdef double alpha_1
|
|
48
|
-
cdef unsigned short init_mean
|
|
49
|
-
cdef unsigned short _init_stage
|
|
50
38
|
|
|
51
39
|
def __init__(self, str name, TimeSeries series, int period, init_mean=True):
|
|
52
40
|
self.period = period
|
|
@@ -92,12 +80,6 @@ def ema(series:TimeSeries, period: int, init_mean: bool = True):
|
|
|
92
80
|
|
|
93
81
|
|
|
94
82
|
cdef class Tema(Indicator):
|
|
95
|
-
cdef int period
|
|
96
|
-
cdef unsigned short init_mean
|
|
97
|
-
cdef TimeSeries ser0
|
|
98
|
-
cdef Ema ema1
|
|
99
|
-
cdef Ema ema2
|
|
100
|
-
cdef Ema ema3
|
|
101
83
|
|
|
102
84
|
def __init__(self, str name, TimeSeries series, int period, init_mean=True):
|
|
103
85
|
self.period = period
|
|
@@ -118,11 +100,6 @@ def tema(series:TimeSeries, period: int, init_mean: bool = True):
|
|
|
118
100
|
|
|
119
101
|
|
|
120
102
|
cdef class Dema(Indicator):
|
|
121
|
-
cdef int period
|
|
122
|
-
cdef unsigned short init_mean
|
|
123
|
-
cdef TimeSeries ser0
|
|
124
|
-
cdef Ema ema1
|
|
125
|
-
cdef Ema ema2
|
|
126
103
|
|
|
127
104
|
def __init__(self, str name, TimeSeries series, int period, init_mean=True):
|
|
128
105
|
self.period = period
|
|
@@ -142,13 +119,13 @@ def dema(series:TimeSeries, period: int, init_mean: bool = True):
|
|
|
142
119
|
|
|
143
120
|
|
|
144
121
|
cdef class Kama(Indicator):
|
|
145
|
-
cdef int period
|
|
146
|
-
cdef int fast_span
|
|
147
|
-
cdef int slow_span
|
|
148
|
-
cdef double _S1
|
|
149
|
-
cdef double _K1
|
|
150
|
-
cdef _x_past
|
|
151
|
-
cdef RollingSum summator
|
|
122
|
+
# cdef int period
|
|
123
|
+
# cdef int fast_span
|
|
124
|
+
# cdef int slow_span
|
|
125
|
+
# cdef double _S1
|
|
126
|
+
# cdef double _K1
|
|
127
|
+
# cdef _x_past
|
|
128
|
+
# cdef RollingSum summator
|
|
152
129
|
|
|
153
130
|
def __init__(self, str name, TimeSeries series, int period, int fast_span=2, int slow_span=30):
|
|
154
131
|
self.period = period
|
|
@@ -183,8 +160,6 @@ def kama(series:TimeSeries, period: int, fast_span:int=2, slow_span:int=30):
|
|
|
183
160
|
|
|
184
161
|
|
|
185
162
|
cdef class Highest(Indicator):
|
|
186
|
-
cdef int period
|
|
187
|
-
cdef queue
|
|
188
163
|
|
|
189
164
|
def __init__(self, str name, TimeSeries series, int period):
|
|
190
165
|
self.period = period
|
|
@@ -214,8 +189,6 @@ def highest(series:TimeSeries, period:int):
|
|
|
214
189
|
|
|
215
190
|
|
|
216
191
|
cdef class Lowest(Indicator):
|
|
217
|
-
cdef int period
|
|
218
|
-
cdef queue
|
|
219
192
|
|
|
220
193
|
def __init__(self, str name, TimeSeries series, int period):
|
|
221
194
|
self.period = period
|
|
@@ -246,7 +219,6 @@ def lowest(series:TimeSeries, period:int):
|
|
|
246
219
|
|
|
247
220
|
# - - - - TODO !!!!!!!
|
|
248
221
|
cdef class Std(Indicator):
|
|
249
|
-
cdef int period
|
|
250
222
|
|
|
251
223
|
def __init__(self, str name, TimeSeries series, int period):
|
|
252
224
|
self.period = period
|
|
@@ -285,13 +257,6 @@ cdef double student_t_pdf(double x, double df):
|
|
|
285
257
|
|
|
286
258
|
|
|
287
259
|
cdef class Pewma(Indicator):
|
|
288
|
-
cdef public TimeSeries std
|
|
289
|
-
cdef double alpha, beta
|
|
290
|
-
cdef int T
|
|
291
|
-
|
|
292
|
-
cdef double _mean, _vstd, _var
|
|
293
|
-
cdef double mean, vstd, var
|
|
294
|
-
cdef long _i
|
|
295
260
|
|
|
296
261
|
def __init__(self, str name, TimeSeries series, double alpha, double beta, int T):
|
|
297
262
|
self.alpha = alpha
|
|
@@ -359,15 +324,6 @@ def pewma(series:TimeSeries, alpha: float, beta: float, T:int=30):
|
|
|
359
324
|
|
|
360
325
|
|
|
361
326
|
cdef class PewmaOutliersDetector(Indicator):
|
|
362
|
-
cdef public TimeSeries upper, lower, outliers, std
|
|
363
|
-
cdef double alpha, beta, threshold
|
|
364
|
-
cdef int T
|
|
365
|
-
cdef str dist
|
|
366
|
-
|
|
367
|
-
cdef double student_t_df
|
|
368
|
-
cdef long _i
|
|
369
|
-
cdef double mean, vstd, variance
|
|
370
|
-
cdef double _mean, _vstd, _variance, _z_thr
|
|
371
327
|
|
|
372
328
|
def __init__(
|
|
373
329
|
self,
|
|
@@ -498,23 +454,6 @@ def pewma_outliers_detector(
|
|
|
498
454
|
|
|
499
455
|
|
|
500
456
|
cdef class Psar(IndicatorOHLC):
|
|
501
|
-
cdef int _bull
|
|
502
|
-
cdef double _af
|
|
503
|
-
cdef double _psar
|
|
504
|
-
cdef double _lp
|
|
505
|
-
cdef double _hp
|
|
506
|
-
|
|
507
|
-
cdef int bull
|
|
508
|
-
cdef double af
|
|
509
|
-
cdef double psar
|
|
510
|
-
cdef double lp
|
|
511
|
-
cdef double hp
|
|
512
|
-
|
|
513
|
-
cdef public TimeSeries upper
|
|
514
|
-
cdef public TimeSeries lower
|
|
515
|
-
|
|
516
|
-
cdef double iaf
|
|
517
|
-
cdef double maxaf
|
|
518
457
|
|
|
519
458
|
def __init__(self, name, series, iaf, maxaf):
|
|
520
459
|
self.iaf = iaf
|
|
@@ -636,9 +575,6 @@ def smooth(TimeSeries series, str smoother, *args, **kwargs) -> Indicator:
|
|
|
636
575
|
|
|
637
576
|
|
|
638
577
|
cdef class Atr(IndicatorOHLC):
|
|
639
|
-
cdef short percentage
|
|
640
|
-
cdef TimeSeries tr
|
|
641
|
-
cdef Indicator ma
|
|
642
578
|
|
|
643
579
|
def __init__(self, str name, OHLCV series, int period, str smoother, short percentage):
|
|
644
580
|
self.percentage = percentage
|
|
@@ -665,16 +601,6 @@ def atr(series: OHLCV, period: int = 14, smoother="sma", percentage: bool = Fals
|
|
|
665
601
|
|
|
666
602
|
|
|
667
603
|
cdef class Swings(IndicatorOHLC):
|
|
668
|
-
cdef double _min_l
|
|
669
|
-
cdef long long _min_t
|
|
670
|
-
cdef double _max_h
|
|
671
|
-
cdef long long _max_t
|
|
672
|
-
cdef OHLCV base
|
|
673
|
-
cdef Indicator trend
|
|
674
|
-
# tops contain upper pivot point prices
|
|
675
|
-
# tops_detection_lag contain time lag when top was actually spotted
|
|
676
|
-
cdef public TimeSeries tops, tops_detection_lag
|
|
677
|
-
cdef public TimeSeries bottoms, bottoms_detection_lag
|
|
678
604
|
|
|
679
605
|
def __init__(self, str name, OHLCV series, trend_indicator, **indicator_args):
|
|
680
606
|
self.base = OHLCV("base", series.timeframe, series.max_series_length)
|
|
@@ -63,7 +63,13 @@ class FixedLeverageSizer(IPositionSizer):
|
|
|
63
63
|
|
|
64
64
|
|
|
65
65
|
class FixedRiskSizer(IPositionSizer):
|
|
66
|
-
def __init__(
|
|
66
|
+
def __init__(
|
|
67
|
+
self,
|
|
68
|
+
max_cap_in_risk: float,
|
|
69
|
+
max_allowed_position=np.inf,
|
|
70
|
+
reinvest_profit: bool = True,
|
|
71
|
+
divide_by_symbols: bool = True,
|
|
72
|
+
):
|
|
67
73
|
"""
|
|
68
74
|
Create fixed risk sizer calculator instance.
|
|
69
75
|
:param max_cap_in_risk: maximal risked capital (in percentage)
|
|
@@ -73,6 +79,7 @@ class FixedRiskSizer(IPositionSizer):
|
|
|
73
79
|
self.max_cap_in_risk = max_cap_in_risk / 100
|
|
74
80
|
self.max_allowed_position_quoted = max_allowed_position
|
|
75
81
|
self.reinvest_profit = reinvest_profit
|
|
82
|
+
self.divide_by_symbols = divide_by_symbols
|
|
76
83
|
|
|
77
84
|
def calculate_target_positions(self, ctx: StrategyContext, signals: List[Signal]) -> List[TargetPosition]:
|
|
78
85
|
t_pos = []
|
|
@@ -91,6 +98,7 @@ class FixedRiskSizer(IPositionSizer):
|
|
|
91
98
|
target_position_size = (
|
|
92
99
|
_direction
|
|
93
100
|
*min((_cap * self.max_cap_in_risk) / abs(signal.stop / _entry - 1), self.max_allowed_position_quoted) / _entry
|
|
101
|
+
/ len(ctx.instruments) if self.divide_by_symbols else 1
|
|
94
102
|
)
|
|
95
103
|
# fmt: on
|
|
96
104
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|