Hello,
I want to know how acts backtrader when a profit order (sell limit) and a stop order (sell stop) have reached in the same bar, which order prevalence?
Hello,
I want to know how acts backtrader when a profit order (sell limit) and a stop order (sell stop) have reached in the same bar, which order prevalence?
There is any way to plot cerebro in a non-blocking way? Nowadays, when I run cerebro.plot() the main thred get blocked until y close the chart manually.
Or maybe, there is any way to save to a file the cerebro.plot() chart without showing it?
Thanks!
When I use the bt.LinePlotterIndicator the Strategy starts executing later than the period defined in params. I think that when we add the bt.LinePlotterIndicator, backtrader multiply by 2 the bars needed to start executing the strategy.
My code is:
class SMACloseSignal(bt.SignalStrategy):
params = (('period', 30),)
def __init__(self):
signal = bt.indicators.CrossOver(self.data, bt.indicators.SMA(period=self.p.period))
self.signal_add(bt.SIGNAL_LONG, signal)
signal_to_plot = self.data - bt.indicators.SMA(period=self.p.period)
bt.LinePlotterIndicator(signal_to_plot, name='SMAsignal')
@backtrader Sorry, I have tried to simplify my example to make easy to understand. It's right that this code raise an exception because lines
is not a tuple. In my real use case I have defined 3 lines, so the code runs. But I added a comma in the declaration of lines
to convert to a tuple, and skip the exception, but I have the same problem described in my post: the strategies doesn't run.
PD: I don't understand so much what you want to say with "That defines 14 lines ..."
Hello, thanks for your answer. Finally what I have done is load my indicator values as a DataBase
(passing first the same main data to my AnalsyisFilter and to Cerebro). Here is the code were I load my indicator values as a DataBase
:
class AnalysisFilterFakeDataLoader(bt.feeds.DataBase):
lines = ('data_indicator',)
def __init__(self, analysis_filter: AnalysisFilter = None):
self.analysis_filter = analysis_filter
self.plotinfo.plot = False
def start(self):
super(AnalysisFilterFakeDataLoader, self).start()
# reset the iterator on each start
self._rows = self.analysis_filter.data.itertuples()
def _load(self):
try:
row = next(self._rows)
except StopIteration:
return False
line_ind = getattr(self.lines, 'data_indicator')
line_ind[0] = self.analysis_filter._check_filter_condition_at_index(row.Index)
return True
And then in my Strategy
I access this data with this lines:
class NearConfHighsBlai5Strategy(bt.Strategy):
params = (('blai5_name', None),
('near_conf_highs_name', None))
def __init__(self):
self.blai5_indicator = self.dnames.get(self.p.blai5_name).data_indicator
self.near_indicator = self.dnames.get(self.p.near_conf_highs_name).data_indicator
def next(self):
if self.blai5_indicator[0] > 0 or self.near_indicator[0]> 0:
self.buy()
else:
self.close()
But I don't know why this code does not works. Because, the next()
method is never executed. The assigment of the indicator values in the __init__()
is working properly, but the next()
is not executing never. Why?
EDIT: Also, when I add my own DataBase, any other strategis not related with this databases stop executing well. It seems, that when I add any data with my own implementation of bt.DataBase, the Strategies don't execute their next() method.
Hello,
I just recently discovered the backtrader library, and I would like to add many of my own indicators (I've called them as AnalysisFilters) that I have already programmed to the backtrader logic. But I would like to add them as if they were bt.Indicator so that they can be easily plotted. (Later you will understand why I focus on saying that I want them to be bt.Indicator. Because I know how to add them as DataFeed (extra columns with my precalculated indicators values), but not as bt.Indicator).
The problem is that all the indicators that I have programmed follow this pattern: they have a method with the following definition:
def _calculate_indicator_at_index(data, index):
"""
:param data: (pd.DataFrame) with all the data and ['open', 'high', 'low', 'close'] columns.
:param index: (int) index of the DataFrame for which we want to calculate the value of the indicator
"""
I've tried something like the following, but it obviously doesn't work because self.data is not a DataFrame.
import backtrader as bt
from src.analysis_filters.blai5_atlas_filter import Blai5AtlasFilter
class AtlasIndicator(bt.Indicator):
lines = ('atlas',)
params = (('boll_avg_value', 20), ('exp_avg_value', 120))
def __init __(self):
atlas_filter = Blai5AtlasFilter(self.p.boll_avg_value, self.p.exp_avg_value)
atlas_precalculated_values = [0]*self.data.buflen()
for i in range(self.data.buflen()):
atlas_precalculated_values[i] = atlas_filter._calculate_indicator_at_index(self.data, i)
self.lines.atlas = atlas_precalculated_values
So my question would be how to convert self.data to a DataFrame or something that my indicator can later access via data['close'], data['open'], etc.
Greetings, and thank you very much in advance for the help.
PS: Congratulations to the creator of the library, because the amount of possibilities it offers is impressive. I would have loved to discover it before.