I just realized that I only created an indicator, but no strategy and they are two totally different things lol. All clear
Best posts made by marsario
-
RE: AttributeError: 'Lines_LineSeries_LineIterator_DataAccessor_Indicat' object has no attribute '_addobserver'
-
RE: Custom indicator, how datas work in init
@run-out Amazing! Thanks a lot! All clear!
Latest posts made by marsario
-
RE: Custom indicator, how datas work in init
@run-out Amazing! Thanks a lot! All clear!
-
RE: Custom indicator, how datas work in init
Wow, it's really difficult for me to understand...
I tried a different test. This is the indicator's code:
class hasGrown(bt.Indicator): lines = ('hasgrown',) # output line (array) def __init__(self): self.lines.hasgrown = self.data(0) > self.data(-1)
and this is the strategy:
class buyifgrewStrategy(bt.Strategy): def __init__(self): print("Starting strategy") self.hasgrown = hasGrown() def next(self): if self.hasgrown: if not self.position: calculateSize(self) self.buy(self.data,size=self.size) print("Buying") else: if self.position: self.close(self.data) print("Selling") log(self,f"Today: {self.data.close[0]}. Yesterday: {self.data.close[-1]}")
So, in the indicator I'm checking whether the stock has price has grown yesterday (and if so I buy). If it has decreased I sell.
The code apperently works, but I don't understand why.
What am I comparing here? (open prices? close prices? all of them?)
self.lines.hasgrown = self.data(0) > self.data(-1)
The print output:
... 2021-02-16, Today: 133.19. Yesterday: 135.37 2021-02-17, Today: 130.84. Yesterday: 133.19 2021-02-18, Today: 129.71. Yesterday: 130.84 Buying 2021-02-19, Today: 129.87. Yesterday: 129.71 Selling 2021-02-22, Today: 126.0. Yesterday: 129.87 2021-02-23, Today: 125.86. Yesterday: 126.0 2021-02-24, Today: 125.35. Yesterday: 125.86 2021-02-25, Today: 120.99. Yesterday: 125.35 Buying 2021-02-26, Today: 121.26. Yesterday: 120.99 2021-03-01, Today: 127.79. Yesterday: 121.26 Selling 2021-03-02, Today: 125.12. Yesterday: 127.79 2021-03-03, Today: 122.06. Yesterday: 125.12 2021-03-04, Today: 120.13. Yesterday: 122.06 Buying 2021-03-05, Today: 121.42. Yesterday: 120.13 Strategy is over, final cash: 122076.85999999993
-
Custom indicator, how datas work in init
Hi,
I'm trying to understand how to build a custom indicator. Let's see this one:
import backtrader as bt class DummyDifferenceDivider(bt.Indicator): lines = ('diffdiv',) # output line (array) params = ( ('period', 1), # distance to previous data point ('divfactor', 2.0), # factor to use for the division ) def __init__(self): diff = self.data(0) - self.data(-self.p.period) diffdiv = diff / self.p.divfactor self.lines.diffdiv = diffdiv
(source: https://medium.com/@danjrod/custom-indicator-development-in-python-with-backtrader-bc775552dc3e by Daniel Rodriguez)
What does this line do?
diff = self.data(0) - self.data(-self.p.period)
Daniel writes it should be self-explanatory, but i don't understand it.
It seems to me that he's subtracting two datafeeds (but this is impossible as I tried to run the code with only one datafeed and it runs). At first, I thought that it was subtracting the closing value of today and today-period, but I don't understand why it's not written as:
diff = self.datas[0].close[0] - self.datas[0].close[-self.p.period]
Thanks for any insights...
-
RE: AttributeError: 'Lines_LineSeries_LineIterator_DataAccessor_Indicat' object has no attribute '_addobserver'
I just realized that I only created an indicator, but no strategy and they are two totally different things lol. All clear
-
AttributeError: 'Lines_LineSeries_LineIterator_DataAccessor_Indicat' object has no attribute '_addobserver'
Hi, I'm learning to make a new indicator.
I've been following these two pages:
When I paste the code, I get the same error message:
AttributeError: 'Lines_LineSeries_LineIterator_DataAccessor_Indicat' object has no attribute '_addobserver'What is the problem?
This is my full code:
import datafeeds.yf as yf import backtrader as bt import datetime enddate=datetime.date.today() startdate = enddate - datetime.timedelta(days=(365*10)) cerebro = bt.Cerebro() #Adding apple datafeed to cerebro: cerebro = yf.apple(cerebro,startdate,enddate) cerebro.broker.setcash(100000.0) print("Launching the strategy") cerebro.addstrategy(DummyDifferenceDivider) cerebro.run() print("Strategy is over, final cash:",cerebro.broker.getvalue()) cerebro.plot() class DummyDifferenceDivider(bt.Indicator): lines = ('diffdiv',) # output line (array) params = ( ('period', 1), # distance to previous data point ('divfactor', 2.0), # factor to use for the division ) def __init__(self): diff = self.data(0) - self.data(-self.p.period) diffdiv = diff / self.p.divfactor self.lines.diffdiv = diffdiv
-
Multiple datafeeds with different start dates
This is a topic that has been widely discussed but I haven't seen a straightforward answer on how to work with multiple that have different start dates.
The major challenges are:
- How to pass an indicator to multiple data
- How to start a strategy even if some of the datafeeds haven't started yet (for instance, in the case of IPOs)
- How to handle the datafeeds that have the right timeframe
This is the code I came up with. It's really unclear, but I hope it can be useful for others as I struggled with this a lot. If anyone has recommendations on how to improve it, you are more than welcome!
from __future__ import (absolute_import, division, print_function, unicode_literals) import math import argparse import datetime import backtrader as bt import backtrader.feeds as btfeeds import backtrader.indicators as btind from backtrader import ResamplerDaily, ResamplerWeekly, ResamplerMonthly from backtrader import ReplayerDaily, ReplayerWeekly, ReplayerMonthly from backtrader.utils import flushfile def log(self, txt, dt=None): """ Logging function fot this strategy""" dt = dt or self.data.datetime[0] if isinstance(dt, float): dt = bt.num2date(dt) print("%s, %s" % (dt.date(), txt)) class multitimeframeStrategy(bt.Strategy): period = 60 wait = 0 def __init__(self): self.mo = dict() #1) Passing the indicator to all the datas here for d in self.datas: self.mo[d] = bt.ind.momentum(d.close, period=self.period) #2) starting a strategy even if some of the datafeeds haven't started yet her (for instance, in the case of IPOs) def prenext(self): self.next() #3) Handling the datafeeds that have the right timeframe here def next(self): self.wait = self.wait + 1 if (self.period < self.wait): best_mo_val = None best_mo_data = None for dmo, mom in self.mo.items(): #3) Handling the datafeeds that have the right timeframe also here if len(dmo) > self.period: # log(self,f"{dmo._name} is being analysed. it's length is {len(dmo)}",dmo.datetime[0]) if not best_mo_val or mom[0] > best_mo_val: best_mo_val = mom[0] best_mo_data = dmo # self.log(f"{best_mo_data._name}, {best_mo_val:5.2f}") for data in self.datas: if data!= best_mo_data: self.close(data) amount_to_invest = 0.95 * self.broker.cash self.size = math.floor(amount_to_invest/best_mo_data.close) # self.buy(best_mo_data,percent=100) self.buy(best_mo_data,size=self.size) log(self,f"Buying {best_mo_data._name}") if __name__ == '__main__': cerebro = bt.Cerebro() startdate =datetime.date(2010, 7, 1) enddate=datetime.date(2021, 2, 1) """ NEW DATA PARAMETERS """ for ticker in [ "AAPL", "ADBE", "ADSK", "AMZN", "ANSS", "AQB", "ARCT", "AVAV", "AY", "BEEM", "BIDU", "CDNA", "CDXS", "CERS", "CGEN", "CLLS", "CRSP", "ARKW", "CHIK", "TAN", "VGT", "VOO" ]: data = bt.feeds.YahooFinanceData( dataname=ticker, timeframe=bt.TimeFrame.Days, fromdate=startdate, todate=enddate, reverse=False, ) cerebro.adddata(data) cerebro.addobserver(bt.observers.Broker) # cerebro.broker.setcommission(commission=0.005) print('Initial Portfolio Value: %.2f' % cerebro.broker.getvalue()) cerebro.addstrategy(multitimeframeStrategy) cerebro.run() print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue()) cerebro.plot()[0][0]
-
RE: Similar to Exponential Moving Average
Hi!
Could you check this link:
https://docs.google.com/spreadsheets/d/1WRUfJC3VWcxCKAlXdaYAjszViJkFx__q36GKveJjEAU/edit?usp=sharingI'm looking for an indicator for what I called "Geometric average daily increase" (probably it's not the right name).
I wrote a formula that creates weights so that the most recent weight is 1 and they are halved every X days (in this case every 30 days). The last weight comes after Y days (in this case 493)
Also I take the prices of the last 494 days and do the following (basically I multiply together 493 weighted daily increases):
product((price today/price yesterday)^today's weight)Finally, the 493 weights are summed all together and they root the total product above.
Any idea, whether there exists anything similar?
-
Similar to Exponential Moving Average
Hi,
I'm looking for the name of an indicator but I don't know whether it exists.
It should be similar to Exponential Moving Average but it divides the price at each day by the stock's cost on that day. In this way, it's possible to compare the average of different stocks and see which one has grown most in the recent past.
-
RE: Changing tickets orders leads to different results
I appreciate that you are taking the time to reply each time, but I feel you are underestimating how much effort I'm putting in to try to make this code run. It's been a week that I have been going through the documentation and if I wrote to this forum it's because I have no idea of how to make it run. Yes, I understand it doesn't close orders. And how to make them close? I've been trying both with sell and close orders, changing the piece of code, nothing helps.
-
RE: Changing tickets orders leads to different results
These are some trials.
I tried to print the value of the stocks in my portfolio:
import datetime import backtrader as bt class Strategy(bt.Strategy): def log(self, txt, dt=None): """ Logging function fot this strategy""" dt = dt or self.data.datetime[0] if isinstance(dt, float): dt = bt.num2date(dt) print("%s, %s" % (dt.date(), txt)) def __init__(self): self.mo = dict() for d in self.datas: self.mo[d] = bt.ind.Momentum(d.close, period=10) def next(self): best_mo_val = None best_mo_data = None for dmo, mom in self.mo.items(): print("The portfolio contains",self.broker.getposition(dmo).size*dmo.close[0],"of",dmo._name) if not best_mo_val or mom[0] > best_mo_val: self.close(best_mo_data) best_mo_val = mom[0] best_mo_data = dmo self.log(f"{best_mo_data._name}, {best_mo_val:5.2f}") try: self.buy(best_mo_data,self.cerebro.broker.get_cash()/best_mo_data.open[1]) except: pass if __name__ == "__main__": cerebro = bt.Cerebro() """ NEW DATA PARAMETERS """ for ticker in [ "TSLA", "XOM", "v", "AAPL", "AMZN", "BAC", "BUD", "FB", "GOOG", "JNJ", "MSFT", "PG", "T" ]: data = bt.feeds.YahooFinanceData( dataname=ticker, timeframe=bt.TimeFrame.Days, fromdate=datetime.date(2020, 1, 1), todate=datetime.date(2020, 12, 31), reverse=False, ) cerebro.adddata(data) cerebro.addstrategy(Strategy) # Execute print('Initial Portfolio Value: %.2f' % cerebro.broker.getvalue()) cerebro.run() print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
The result shows that it buys Google at first (which is the best), and then it keeps it till the end.
Initial Portfolio Value: 10000.00 The portfolio contains 0.0 of TSLA The portfolio contains 0.0 of XOM The portfolio contains 0.0 of v The portfolio contains 0.0 of AAPL The portfolio contains 0.0 of AMZN The portfolio contains 0.0 of BAC The portfolio contains 0.0 of BUD The portfolio contains 0.0 of FB The portfolio contains 0.0 of GOOG The portfolio contains 0.0 of JNJ The portfolio contains 0.0 of MSFT The portfolio contains 0.0 of PG The portfolio contains 0.0 of T 2020-01-16, GOOG, 84.33 The portfolio contains 0.0 of TSLA The portfolio contains 0.0 of XOM The portfolio contains 0.0 of v The portfolio contains 0.0 of AAPL The portfolio contains 0.0 of AMZN The portfolio contains 0.0 of BAC The portfolio contains 0.0 of BUD The portfolio contains 0.0 of FB The portfolio contains 10119.487870067194 of GOOG The portfolio contains 0.0 of JNJ The portfolio contains 0.0 of MSFT The portfolio contains 0.0 of PG The portfolio contains 0.0 of T 2020-01-17, GOOG, 119.73 The portfolio contains 0.0 of TSLA The portfolio contains 0.0 of XOM The portfolio contains 0.0 of v The portfolio contains 0.0 of AAPL The portfolio contains 0.0 of AMZN The portfolio contains 0.0 of BAC The portfolio contains 0.0 of BUD The portfolio contains 0.0 of FB The portfolio contains 10146.898989001375 of GOOG The portfolio contains 0.0 of JNJ The portfolio contains 0.0 of MSFT The portfolio contains 0.0 of PG The portfolio contains 0.0 of T 2020-01-21, GOOG, 90.19 The portfolio contains 0.0 of TSLA The portfolio contains 0.0 of XOM The portfolio contains 0.0 of v The portfolio contains 0.0 of AAPL The portfolio contains 0.0 of AMZN The portfolio contains 0.0 of BAC The portfolio contains 0.0 of BUD The portfolio contains 0.0 of FB The portfolio contains 10157.494309287653 of GOOG The portfolio contains 0.0 of JNJ The portfolio contains 0.0 of MSFT The portfolio contains 0.0 of PG The portfolio contains 0.0 of T 2020-01-22, GOOG, 92.61 The portfolio contains 0.0 of TSLA The portfolio contains 0.0 of XOM The portfolio contains 0.0 of v The portfolio contains 0.0 of AAPL The portfolio contains 0.0 of AMZN The portfolio contains 0.0 of BAC The portfolio contains 0.0 of BUD The portfolio contains 0.0 of FB The portfolio contains 10162.279292642746 of GOOG The portfolio contains 0.0 of JNJ The portfolio contains 0.0 of MSFT The portfolio contains 0.0 of PG The portfolio contains 0.0 of T 2020-01-23, GOOG, 82.33 The portfolio contains 0.0 of TSLA The portfolio contains 0.0 of XOM The portfolio contains 0.0 of v The portfolio contains 0.0 of AAPL The portfolio contains 0.0 of AMZN The portfolio contains 0.0 of BAC The portfolio contains 0.0 of BUD The portfolio contains 0.0 of FB The portfolio contains 10025.97562392765 of GOOG The portfolio contains 0.0 of JNJ The portfolio contains 0.0 of MSFT The portfolio contains 0.0 of PG The portfolio contains 0.0 of T 2020-01-24, GOOG, 46.88 The portfolio contains 0.0 of TSLA The portfolio contains 0.0 of XOM The portfolio contains 0.0 of v The portfolio contains 0.0 of AAPL The portfolio contains 0.0 of AMZN The portfolio contains 0.0 of BAC The portfolio contains 0.0 of BUD The portfolio contains 0.0 of FB The portfolio contains 9801.696618383905 of GOOG The portfolio contains 0.0 of JNJ The portfolio contains 0.0 of MSFT The portfolio contains 0.0 of PG The portfolio contains 0.0 of T 2020-01-27, TSLA, 15.97 The portfolio contains 0.0 of TSLA The portfolio contains 0.0 of XOM The portfolio contains 0.0 of v The portfolio contains 0.0 of AAPL The portfolio contains 0.0 of AMZN The portfolio contains 0.0 of BAC The portfolio contains 0.0 of BUD The portfolio contains 0.0 of FB The portfolio contains 9929.250603249686 of GOOG The portfolio contains 0.0 of JNJ The portfolio contains 0.0 of MSFT The portfolio contains 0.0 of PG The portfolio contains 0.0 of T ... The portfolio contains 0.0 of TSLA The portfolio contains 0.0 of XOM The portfolio contains 0.0 of v The portfolio contains 0.0 of AAPL The portfolio contains 0.0 of AMZN The portfolio contains 0.0 of BAC The portfolio contains 0.0 of BUD The portfolio contains 0.0 of FB The portfolio contains 12022.065608957488 of GOOG The portfolio contains 0.0 of JNJ The portfolio contains 0.0 of MSFT The portfolio contains 0.0 of PG The portfolio contains 0.0 of T 2020-12-29, AMZN, 165.03 The portfolio contains 0.0 of TSLA The portfolio contains 0.0 of XOM The portfolio contains 0.0 of v The portfolio contains 0.0 of AAPL The portfolio contains 0.0 of AMZN The portfolio contains 0.0 of BAC The portfolio contains 0.0 of BUD The portfolio contains 0.0 of FB The portfolio contains 11890.820351217777 of GOOG The portfolio contains 0.0 of JNJ The portfolio contains 0.0 of MSFT The portfolio contains 0.0 of PG The portfolio contains 0.0 of T 2020-12-30, AMZN, 120.73 Final Portfolio Value: 11890.82
After that, I tried to put the close orders at different places and change the close order with a sell order. But none of the results made any sense..