Machine learning + backtrader
From the Quantopian Lecture on Kalman.
KalmanMovingAverageshould be something like this. The actual calculation can yield values already with the 2nd data tick, but to make it similar to other moving averages and avoid the actual very steep ramp-up phase (seen in the Quantopian chart), the
periodparameter is used to decide when to start delivering values, skipping the initial warm-up.
import pykalman class KMA(bt.indicators.MovingAverageBase): alias = ('KalmanMovingAverage',) lines = ('kma',) params = ( ('initial_state_covariance', 1.0), ('observation_covariance', 1.0), ('transition_covariance', 0.05), ) def __init__(self): self.addminperiod(self.p.period) # when to deliver values self._dlast = self.data(-1) # get previous day value def nextstart(self): self._k1 = self._dlast self._c1 = self.p.initial_state_covariance self._kf = pykalman.KalmanFilter( transition_matrices=, observation_matrices=, observation_covariance=self.p.observation_covariance, transition_covariance=self.p.transition_covariance, initial_state_mean=self._k1, initial_state_covariance=self._c1, ) self.next() def next(self): k1, self._c1 = self._kf.filter_update(self._k1, self._c1, self.data) self.lines.kma = self._k1 = k1
An example getting it compared to the
RandyT last edited by
@junajo10 Do you have any suggestions for the Half Life algorithm? I have run across a couple of them which give vastly different results.
Here is what I have with the alternate calculation commented out.
lag = series.shift(1) lag.ix = lag.ix s_ret = series - lag s_ret.ix = s_ret.ix lag2 = sm.add_constant(lag) model = sm.OLS(s_ret, lag2) res = model.fit() # halflife = round(-np.log(2) / res.params, 0) halflife = np.log(0.5) / np.log(np.abs(res.params))
Some additional reference would be needed.
RandyT last edited by
I've found this link which offers other links to relevant info and the resulting two algorithms I have attempted. Values of the two formulas are very different with one of the formulas returning negative values. As I understand Half-Life of a time series, it indicates some time value for complete cycle of the reversion to mean process. However, given the results, I'm not quite grasping the measurement value and how it applies to the concept of "time".
chuka last edited by chuka
Initialize counter in the
__init()__, add 1 to the counter every
next()call. If it equals to 30 call your function and zero counter. You may want to call your function also at the very beginning of the cycle in the
chuka last edited by
ok, many thanks @ab_trader