Custom indicator creation help.
-
Hey I'm working on my mean reversion strategy but in order for me to fully start I need to finish my indicator. So what I want is a Linear regression slope from TALib which ive created then I want standard 8 standard deviations with different distances from the slope (4 above and 4 below). This is what I've got so far;
class LregressionSlope(bt.indicators): params = ( ('period', 17), ) def __init__(self): self.slope = bt.talib.LINEARREG_SLOPE(timeperiod=self.params.period) class Cstdev(bt.indicators.StandardDeviation, LregressionSlope): lines = ( ('upper_dev1', 1), ('upper_dev2', 2), ('upper_dev3', 3), ('upper_dev4', 4), ('lower_dev1', -1), ('lower_dev2', -2), ('lower_dev3', -3), ('lower_dev4', -4) ) params = ( ('period', 14), ('movav', 'LregressionSlope') ) def __init__(self): self.upper_dev1 = bt.indicators.StandardDeviation(self.lines.data, self) self.upper_dev2 = bt.indicators.StandardDeviation() self.upper_dev3 = bt.indicators.StandardDeviation() self.upper_dev4 = bt.indicators.StandardDeviation() self.lower_dev1 = bt.indicators.StandardDeviation() self.lower_dev2 = bt.indicators.StandardDeviation() self.lower_dev3 = bt.indicators.StandardDeviation() self.lower_dev4 = bt.indicators.StandardDeviation()
I want the stdev to inherit the 'LregressionSlope' as its movav and then build the deviations around that. Any way I can plot it individually as I have a trading background and im still a novice (if that) coder. Thanks for any help!
Regards,
cept0r
-
Reading trough all the docs again and going trough the 'parttimelarry' videos again will post updated code later.
-
Okay I'm working on just getting the LINEARREG_SLOPE to plot to begin with.
I'm getting this output error:self.lines[i].array = array.array(str('d'), o) TypeError: 'numpy.float64' object is not iterable
When running this code:
# Imports import backtrader as bt from backtrader.talib import LINEARREG_SLOPE class LregressionSlope(bt.talib.LINEARREG_SLOPE): lines = ('slope',) params = ( ('timeperiod', 17), ) def __init__(self): self.slope = bt.talib.LINEARREG_SLOPE(self.data, timeperiod=self.params.timeperiod) def __next__(self): pass```
-
Here is my backtester setup:
# Imports from __future__ import (absolute_import, division, print_function, unicode_literals) import backtrader as bt import pandas as pd import datetime from strat.examplestrat_04 import LregressionSlope class CommInfoFractional(bt.CommissionInfo): def getsize(self, price, cash): """Returns fractional size for cash operation @price""" return self.p.leverage * (cash / price) startcash = 1000000 cerebro = bt.Cerebro() cerebro.addindicator(LregressionSlope) # Datafeed btc = pd.read_csv('/home/dev/PycharmProjects/Backtesting/csvdata/BTCUSDT-1m-data.csv', index_col='timestamp', parse_dates=True ) feed = bt.feeds.PandasData( dataname=btc, fromdate=datetime.datetime(2020, 1, 1), todate=datetime.datetime(2020, 1, 2), timeframe=bt.TimeFrame.Minutes, ) cerebro.adddata(feed) cerebro.broker.setcash(startcash) cerebro.addsizer(bt.sizers.PercentSizer, percents=0.05) cerebro.broker.addcommissioninfo(CommInfoFractional()) cerebro.broker.setcommission(commission=0.0025, leverage=50) cerebro.run() portvalue = cerebro.broker.getvalue() pnl = portvalue - startcash print('Final Portfolio Value: ${}'.format(round(portvalue, 2))) print('P/L: ${}'.format(round(pnl, 2))) cerebro.plot(style='candlestick')
-
Using btalib instead and going trough the docs there..
-
Let us know how you get on and if you still need help after you work through the docs. Good luck.
-
@run-out
All right I managed to solve it using 4 of these indicators:# Imports import backtrader as bt class MeanReversionLong(bt.Strategy): lines = ('kama', 'mean' 'top1', 'emamean' 'bot1', 'emamean' 'top2', 'emadev1' 'bot2', 'emadev1' 'top3', 'emadev2' 'bot3', 'emadev2' 'top4', 'emadev3' 'bot4', 'emadev3') params = dict(period=30, fast=2, slow=30, perc=2.5) def __init__(self): emamean = bt.indicators.AdaptiveMovingAverageEnvelope(period=9, fast=1, slow=7, perc=0.2, plotname='mean') emadev1 = bt.indicators.AdaptiveMovingAverageEnvelope(period=9, fast=1, slow=7, perc=0.4, plotname='dev1') emadev2 = bt.indicators.AdaptiveMovingAverageEnvelope(period=9, fast=1, slow=7, perc=0.8, plotname='dev2') emadev3 = bt.indicators.AdaptiveMovingAverageEnvelope(period=9, fast=1, slow=7, perc=1.2, plotname='dev3')
But now I need to identify each "band" like I do it in my lines section, because when I plot it it only identifies the moving average which is the same for all indicators.
-
@run-out
AdaptiveMovingAverageEnvelopeAlias:
KAMAEnvelope, MovingAverageAdaptiveEnvelope
AdaptiveMovingAverage and envelope bands separated “perc” from it
Formula:
kama (from AdaptiveMovingAverage) top = kama * (1 + perc) bot = kama * (1 - perc)
See also:
http://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:moving_average_envelopes
Lines:
kama top bot
Params:
period (30) fast (2) slow (30) perc (2.5)
def __init__(self): emamean = bt.indicators.AdaptiveMovingAverageEnvelope(period=30, fast=1, slow=8, perc=0.2, plotname='mean') emadev1 = bt.indicators.AdaptiveMovingAverageEnvelope(period=30, fast=1.2, slow=8.2, perc=0.4, plotname='dev1') emadev2 = bt.indicators.AdaptiveMovingAverageEnvelope(period=30, fast=1.4, slow=8.5, perc=0.8, plotname='dev2') emadev3 = bt.indicators.AdaptiveMovingAverageEnvelope(period=30, fast=1.8, slow=8.9, perc=1.2, plotname='dev3') top1 = emamean()
How do I create a unique identifier on each respective band ? or what is the calculation I need to provide inside "top1" for example.
And also;
Should I create an indicator or just develop within the strategy what is the best or rather easiest approach? -
Maybe I should calculate inside the lines or parameters.. hmm
-
@run-out
All right I'm kind of stuck on this calculation.. I changed my code but I can't seem to get the "top" code done right. No output errors but it won't plot.
here is the code;from backtrader.indicators import AdaptiveMovingAverageEnvelope amae = AdaptiveMovingAverageEnvelope class Adaptive_ma1(amae): lines = ('kama', 'top', 'bot') params = dict(period=27, fast=1.0, slow=8, perc=0.2) def __init__(self): self.l.kama = amae(period=self.p.period) self.l.top = self.l.kama * (1 + amae(perc=self.p.perc)) # self.l.bot = self.l.kama * (1 - ama(self.data, self.p.perc)) def __next__(self): pass
here is the plot:
link textThis is what I need to calculate:
top = kama * (1 + perc)Thanks in advance!