OLS_Slope_InterceptN
-
Could you please give an example on how to use 'OLS_Slope_InterceptN' class?
Thank you.
-
from datetime import datetime
import backtrader as btclass TestStrategy(bt.Strategy):
params = (
('period', 14),
('sma_atr', 5),
('ols_length',15),
('macd1', 12),
('macd2', 26),
('macdsig', 9),
)def log(self, txt, dt=None): ''' Logging function fot this strategy''' dt = dt or self.datas[0].datetime.date(0) print('%s, %s' % (dt.isoformat(), txt)) def __init__(self): # Keep a reference to the "close" line in the data[0] dataseries self.dataclose = self.datas[0].close # To keep track of pending orders and buy price/commission self.order = None self.buyprice = None self.buycomm = None # Add ATR Indicator self.atr = bt.indicators.ATR( self.datas[0], period=self.params.period) self.sma_atr = bt.indicators.SMA( self.atr, period=self.params.sma_atr) self.my_macd = bt.indicators.MACD( self.datas[0], period_me1=self.p.macd1, period_me2=self.p.macd2, period_signal=self.p.macdsig) self.my_ols1, self.my_ols2 = bt.indicators.OLS_Slope_InterceptN(self.datas[0].close, self.datas[0].close) def notify_order(self, order): if order.status in [order.Submitted, order.Accepted]: # Buy/Sell order submitted/accepted to/by broker - Nothing to do return # Check if an order has been completed # Attention: broker could reject order if not enougth cash if order.status in [order.Completed]: if order.isbuy(): self.log( 'BUY EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' % (order.executed.price, order.executed.value, order.executed.comm)) self.buyprice = order.executed.price self.buycomm = order.executed.comm else: # Sell self.log('SELL EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' % (order.executed.price, order.executed.value, order.executed.comm)) self.bar_executed = len(self) elif order.status in [order.Canceled, order.Margin, order.Rejected]: self.log('Order Canceled/Margin/Rejected') self.order = None def notify_trade(self, trade): if not trade.isclosed: return self.log('OPERATION PROFIT, GROSS %.2f, NET %.2f' % (trade.pnl, trade.pnlcomm)) def next(self): # Simply log the closing price of the series from the reference self.log('Close, %.2f' % self.dataclose[0]) self.log('ATR, %.2f' % self.atr[0]) self.log('SMA_ATR, %.2f' % self.sma_atr[0]) self.log('MACD, %.2f' % self.my_macd.macd[0]) self.log('SIGNAL, %.2f' % self.my_macd.signal[0]) # Check if an order is pending ... if yes, we cannot send a 2nd one if self.order: return # Check if we are in the market if not self.position: # Not yet ... we MIGHT BUY if ... if (self.atr[0] > self.sma_atr[0]) and (self.my_macd.macd[0] > 0) and ((self.my_macd.signal[0] > 0) and (self.my_macd.macd[0] > self.my_macd.signal[0])): # BUY, BUY, BUY!!! (with all possible default parameters) self.log('BUY CREATE, %.2f' % self.dataclose[0]) # Keep track of the created order to avoid a 2nd order self.order = self.order_target_percent(target=0.9) else: if self.atr[0] < self.sma_atr[0]: # SELL, SELL, SELL!!! (with all possible default parameters) self.log('SELL CREATE, %.2f' % self.dataclose[0]) # Keep track of the created order to avoid a 2nd order self.order = self.order_target_percent(target=0)
if name == 'main':
cerebro = bt.Cerebro()
# Add a strategy
cerebro.addstrategy(TestStrategy, period=14, sma_atr=3, ols_length=15)# Basic Setup of the trade cerebro.broker.setcash(1000000.0) # Set the commission - 0.1% ... divide by 100 to remove the % cerebro.broker.setcommission(commission=0.001) # Add a FixedSize sizer according to the stake cerebro.addsizer(bt.sizers.FixedSize, stake=100) #https://community.backtrader.com/topic/279/don-t-understand-buy-amount/6 cerebro.broker.set_coc(True) data = bt.feeds.YahooFinanceData(dataname='IBM', fromdate=datetime(2017, 1, 1), todate=datetime(2017, 11, 27)) cerebro.adddata(data) # Print out the starting conditions print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue()) cerebro.run() # Print out the final result print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue()) cerebro.plot()
-
C:\Users\jirath\Anaconda2\python.exe C:/Users/jirath/PycharmProjects/BackTrader.com/atr_trade.py
Starting Portfolio Value: 1000000.00
C:\Users\jirath\Anaconda2\lib\site-packages\statsmodels\compat\pandas.py:56: FutureWarning: The pandas.core.datetools module is deprecated and will be removed in a future version. Please use the pandas.tseries module instead.
from pandas.core import datetools
Traceback (most recent call last):
File "C:/Users/jirath/PycharmProjects/BackTrader.com/atr_trade.py", line 133, in <module>
cerebro.run()
File "C:\Users\jirath\Anaconda2\lib\site-packages\backtrader\cerebro.py", line 1142, in run
runstrat = self.runstrategies(iterstrat)
File "C:\Users\jirath\Anaconda2\lib\site-packages\backtrader\cerebro.py", line 1229, in runstrategies
strat = stratcls(*sargs, **skwargs)
File "C:\Users\jirath\Anaconda2\lib\site-packages\backtrader\metabase.py", line 88, in call
_obj, args, kwargs = cls.doinit(_obj, *args, **kwargs)
File "C:\Users\jirath\Anaconda2\lib\site-packages\backtrader\metabase.py", line 78, in doinit
_obj.init(*args, **kwargs)
File "C:/Users/jirath/PycharmProjects/BackTrader.com/atr_trade.py", line 36, in init
self.my_ols1, self.my_ols2, self.ols = bt.indicators.OLS_Slope_InterceptN(self.datas[0].close, self.datas[0].close)
ValueError: need more than 0 values to unpackProcess finished with exit code 1
Please any one suggest above error.
-
@jirathh said in OLS_Slope_InterceptN:
self.my_ols1, self.my_ols2, self.ols = bt.indicators.OLS_Slope_InterceptN(self.datas[0].close, self.datas[0].close)
ValueError: need more than 0 values to unpackObviously there is only 1 return value there.
-
I used this one:
self.my_ols = bt.indicators.OLS_Slope_InterceptN(self.datas[0], self.datas[0], period=30)
but still got this error
C:\Users\jirath\Anaconda2\python.exe C:/Users/jirath/PycharmProjects/BackTrader.com/atr_trade.py
Starting Portfolio Value: 1000000.00
C:\Users\jirath\Anaconda2\lib\site-packages\statsmodels\compat\pandas.py:56: FutureWarning: The pandas.core.datetools module is deprecated and will be removed in a future version. Please use the pandas.tseries module instead.
from pandas.core import datetools
Traceback (most recent call last):
File "C:/Users/jirath/PycharmProjects/BackTrader.com/atr_trade.py", line 133, in <module>
cerebro.run()
File "C:\Users\jirath\Anaconda2\lib\site-packages\backtrader\cerebro.py", line 1142, in run
runstrat = self.runstrategies(iterstrat)
File "C:\Users\jirath\Anaconda2\lib\site-packages\backtrader\cerebro.py", line 1305, in runstrategies
self._runonce(runstrats)
File "C:\Users\jirath\Anaconda2\lib\site-packages\backtrader\cerebro.py", line 1663, in _runonce
strat._once()
File "C:\Users\jirath\Anaconda2\lib\site-packages\backtrader\lineiterator.py", line 292, in _once
indicator._once()
File "C:\Users\jirath\Anaconda2\lib\site-packages\backtrader\lineiterator.py", line 313, in _once
self.once(self._minperiod, self.buflen())
File "C:\Users\jirath\Anaconda2\lib\site-packages\backtrader\indicator.py", line 136, in once_via_next
self.next()
File "C:\Users\jirath\Anaconda2\lib\site-packages\backtrader\indicators\ols.py", line 52, in next
slope, intercept = sm.OLS(p0, p1).fit().params
ValueError: need more than 1 value to unpackProcess finished with exit code 1
-
I didn't dig deeply, but looks like by default
bt
script requires 2 data feeds for this indicator. Maybe this is a problem. I would add 2nd data feed and call indicator as follows:self.my_ols = bt.indicators.OLS_Slope_InterceptN(period=whatever_period_you_want)
Default period is 10.
Otherwise you can write your own implementation. -
thank you @ab_trader . I tried but still got this error.
self.my_ols = bt.indicators.OLS_Slope_InterceptN(period=30)
C:\Users\jirath\Anaconda2\python.exe C:/Users/jirath/PycharmProjects/BackTrader.com/atr_trade.py
Starting Portfolio Value: 1000000.00
C:\Users\jirath\Anaconda2\lib\site-packages\statsmodels\compat\pandas.py:56: FutureWarning: The pandas.core.datetools module is deprecated and will be removed in a future version. Please use the pandas.tseries module instead.
from pandas.core import datetools
Traceback (most recent call last):
File "C:/Users/jirath/PycharmProjects/BackTrader.com/atr_trade.py", line 151, in <module>
cerebro.run()
File "C:\Users\jirath\Anaconda2\lib\site-packages\backtrader\cerebro.py", line 1142, in run
runstrat = self.runstrategies(iterstrat)
File "C:\Users\jirath\Anaconda2\lib\site-packages\backtrader\cerebro.py", line 1305, in runstrategies
self._runonce(runstrats)
File "C:\Users\jirath\Anaconda2\lib\site-packages\backtrader\cerebro.py", line 1663, in _runonce
strat._once()
File "C:\Users\jirath\Anaconda2\lib\site-packages\backtrader\lineiterator.py", line 292, in _once
indicator._once()
File "C:\Users\jirath\Anaconda2\lib\site-packages\backtrader\lineiterator.py", line 312, in _once
self.oncestart(self._minperiod - 1, self._minperiod)
File "C:\Users\jirath\Anaconda2\lib\site-packages\backtrader\indicator.py", line 124, in oncestart_via_nextstart
self.nextstart()
File "C:\Users\jirath\Anaconda2\lib\site-packages\backtrader\lineiterator.py", line 342, in nextstart
self.next()
File "C:\Users\jirath\Anaconda2\lib\site-packages\backtrader\indicators\ols.py", line 50, in next
p1 = pd.Series(self.data1.get(size=self.p.period))
File "C:\Users\jirath\Anaconda2\lib\site-packages\backtrader\lineseries.py", line 461, in getattr
return getattr(self.lines, name)
AttributeError: 'Lines_LineSeries_LineIterator_DataAccessor_Indicat' object has no attribute 'data1'Process finished with exit code 1
-
Did you add second data feed in
cerebro
? -
@jirathh said in OLS_Slope_InterceptN:
slope, intercept = sm.OLS(p0, p1).fit().params ValueError: need more than 1 value to unpack
This is a clear indication that the version of
sm.OLS
you are using is not compatible with the code in that indicator. Thestatsmodels
API changes overtime. See this: -
@Paska-Houso , thank you so much for your information.
In this case, I need to modify and run ols algorithm locally.
Could you please suggest how can I run backtrader locally?
I think we need to set something like interpreter or structure the project correctly. I use PyCharm on Windows. Please make suggestions. Thank you.
-
I suggest you look at the many samples ... the blog is full of them. For example:
-
Thank you so much, @Paska-Houso .
I managed to create a new indicator of OLS to be used in my strategy! :)Here is the code:
class TORO_OLS_Slope_InterceptN(bt.Indicator):
packages = (
('pandas', 'pd'),
('sklearn.linear_model', 'lm'),
)
lines = ('slope', 'intercept',)
params = (
('period', 10),
)
def init(self):
self.addminperiod(self.params.period)def next(self): p0 = pd.Series(self.data.close.get(size=self.p.period)) p1 = np.arange(self.p.period).reshape(-1, 1) p1 = sm.add_constant(p1, prepend=True) slope, intercept = sm.OLS(p0, p1).fit().params self.lines.slope[0] = slope self.lines.intercept[0] = intercept