Indicator that checks if the current candle high (as soon as a condition is met) breaks the previous days high (over a specific period ) or not
-
I am making an Indicator that calculates how many previous days (period is dynamic i.e. 3, 4, 5, 10 and 20) high is taken out as soon as we met a condition on a bar. I used Highest (MaxN) to find the High in those specified periods (i.e. 3, 4, 5, 10 and 20) in next of my Indicator and stored the results in Lines. Then, I compared them in next of my Strategy with the bar's high (the one which satisfies the condition). But I am not getting the desired results even though on charts I can point out such data points. Please help !!
@run-out @dasch @backtrader @vladisld -
Please refer to this example
The 12th Feb bar has met the condition and now I need to check that it's has taken out high of some defined period, which in this case is from 15th Jan to 11th Feb. So, I need to count how many such bars are there in this.
-
@ayush-somani please don't spam. It was clear that you unable to code something from your very first post. Other posts don't add any value, just pollutes the community.
-
It would be great if you provide the code you tried, to see where you stuck. Also please don't open that many posts with the same question.
-
@dasch This is my Code -
from datetime import datetime
import os.path
import sys
import backtrader as bt
import pandas as pd
import mathticker_list = ['SBIN']
class DynamicHighest(bt.Indicator):
lines = ('periodline',)
params = dict(minperiod=3)def __init__(self): self.addminperiod(self.p.minperiod) def next(self): pass
class MyStrategy(bt.Strategy):
params = dict(bearish=-100, bullish=100)def log(self, txt, dt=None): dt = dt or self.datas[0].datetime.date(0) print('{0}, {1}'.format(dt.isoformat(), txt)) def __init__(self): self.dataopen = self.datas[0].open self.datahigh = self.datas[0].high self.datalow = self.datas[0].low self.dataclose = self.datas[0].close self.CDLENGULFING = bt.talib.CDLENGULFING(self.datas[0].open, self.datas[0].high, self.datas[0].low, self.datas[0].close) self.CDLDARKCLOUDCOVER = bt.talib.CDLDARKCLOUDCOVER(self.datas[0].open, self.datas[0].high, self.datas[0].low, self.datas[0].close) self.dyn_highest = DynamicHighest(self.data.high) def next(self): if math.isclose(self.dataopen[0], self.datahigh[0], abs_tol=0.2): #Minimum Criteria to be Considered if self.datahigh[0] > self.datahigh[-1]: """print('DATE: '+str(self.date(0))+' CDLENGULFING: '+str(self.CDLENGULFING[0])+' CDLDARKCLOUDCOVER: '+str(self.CDLDARKCLOUDCOVER[0]))""" if (self.CDLENGULFING[0] == self.p.bearish or self.CDLDARKCLOUDCOVER[0] == self.p.bearish): self.log(' SELL CREATED AT PRICE: , %.2f' % self.dataclose[0])
if name == 'main':
for ticker in ticker_list:
print('Ticker: %s' % ticker)
cerebro = bt.Cerebro()
cerebro.broker.set_cash(10000)filename = '%s.csv' % ticker #modpath = os.path.dirname('/Users/ayushsomani/Desktop/BANKNIFTY/') datapath = os.path.join('/Users/ayushsomani/Desktop/BANKNIFTY/', filename) if not os.path.isfile(datapath): print('File: %s not found' % filename) sys.exit() dateparse = lambda date: datetime.strptime(date, '%Y-%m-%d') data = pd.read_csv(datapath, index_col='Date', parse_dates=True, date_parser=dateparse) datafeed = bt.feeds.PandasData(dataname=data) cerebro.adddata(datafeed) print('Starting Portfolio Value: %.2f' % cerebro.broker.get_value()) cerebro.addstrategy(MyStrategy) cerebro.run() print('Final Portfolio Value: %.2f' % cerebro.broker.get_value())
I am unable to write the logic in my Created Indicator (DynamicHighest). I tried various approaches but couldn't get the success. Moreover, some of the rows are skipped when I run my Cerebro. My CSV starts on Date - 17/09/18 but when I debugged it is processing from Date - 04/10/18. Why so?
-
@dasch
What does exactly FindFirstIndexHighest does (if I use it calculating count of those bars)? -
@ayush-somani said in Indicator that checks if the current candle high (as soon as a condition is met) breaks the previous days high (over a specific period ) or not:
What does exactly FindFirstIndexHighest does (if I use it calculating count of those bars)?
This will return the index location of the first highest value looking back. See docs.
-
@run-out
I am not getting the desired output.Code Snippet -
from future import (absolute_import, division, print_function,
unicode_literals)
from datetime import datetime
import os.path
import sys
import backtrader as bt
import pandas as pd
import mathticker_list = ['SBIN']
class DynamicHighest(bt.Indicator):
lines = ('firsthighindex','periodline',)
params = dict(minperiod=3, maxperiod=20)def __init__(self): self.addminperiod(self.p.minperiod) self.l.firsthighindex = bt.ind.FindFirstIndexHighest(self.datas[0].high, period=self.p.maxperiod) def next(self): if self.datas[0].high[0] < self.datas[0].high[-int(self.l.firsthighindex[0])]: self.l.periodline[0] = self.l.firsthighindex[0]
class MyStrategy(bt.Strategy):
params = dict(bearish=-100, bullish=100)def log(self, txt, dt=None): dt = dt or self.datas[0].datetime.date(0) print('{0}, {1}'.format(dt.isoformat(), txt)) def __init__(self): self.dataopen = self.datas[0].open self.datahigh = self.datas[0].high self.datalow = self.datas[0].low self.dataclose = self.datas[0].close self.CDLENGULFING = bt.talib.CDLENGULFING(self.datas[0].open, self.datas[0].high, self.datas[0].low, self.datas[0].close) self.CDLDARKCLOUDCOVER = bt.talib.CDLDARKCLOUDCOVER(self.datas[0].open, self.datas[0].high, self.datas[0].low, self.datas[0].close) self.dyn_highest = DynamicHighest(self.datas[0]) def next(self): if math.isclose(self.dataopen[0], self.datahigh[0], abs_tol=0.2): #Minimum Criteria to be Considered if self.datahigh[0] > self.datahigh[-1]: if (self.CDLENGULFING[0] == self.p.bearish or self.CDLDARKCLOUDCOVER[0] == self.p.bearish): if self.dyn_highest.l.periodline[0] >= 3: self.log(' SELL CREATED AT PRICE: , %.2f with %.2f number of days taken out.' % (self.dataclose[0],abs(self.dyn_highest.l.periodline[0])))
if name == 'main':
for ticker in ticker_list:
print('Ticker: %s' % ticker)
cerebro = bt.Cerebro()
cerebro.broker.set_cash(10000)filename = '%s.csv' % ticker #modpath = os.path.dirname('/Users/ayushsomani/Desktop/BANKNIFTY/') datapath = os.path.join('/Users/ayushsomani/Desktop/BANKNIFTY/', filename) if not os.path.isfile(datapath): print('File: %s not found' % filename) sys.exit() dateparse = lambda date: datetime.strptime(date, '%Y-%m-%d') data = pd.read_csv(datapath, index_col='Date', parse_dates=True, date_parser=dateparse) datafeed = bt.feeds.PandasData(dataname=data) cerebro.adddata(datafeed) print('Starting Portfolio Value: %.2f' % cerebro.broker.get_value()) cerebro.addstrategy(MyStrategy) cerebro.run() print('Final Portfolio Value: %.2f' % cerebro.broker.get_value())
Output -
Ticker: SBIN
Starting Portfolio Value: 10000.00
2018-11-19, SELL CREATED AT PRICE: , 288.15 with 9.00 number of days taken out.
2018-12-04, SELL CREATED AT PRICE: , 282.55 with 19.00 number of days taken out.
2020-06-24, SELL CREATED AT PRICE: , 184.60 with 12.00 number of days taken out.
Final Portfolio Value: 10000.00On Chart (https://in.tradingview.com/chart/K307Cbrw/), we can clearly see that 04/12/2018 High is broken on 30/11/2018 but the Output is showing that it took 19 bars to break this high. Hope, you understood my query what I am trying to achieve.
-
-
@ayush-somani said in Indicator that checks if the current candle high (as soon as a condition is met) breaks the previous days high (over a specific period ) or not:
if self.datas[0].high[0] < self.datas[0].high[-int(self.l.firsthighindex[0])]:
Using MaxN might be more straight forward.