@backtrader said in Multi timeframe indicator plotted twice and in wrong timeframe:
Use coupling: Docs - Mixing Timeframes in Indicators
This functionality allows to calculate an indicator on a timeframe an automatically apply the indicator to another lower timeframe.
I tried coupling the D1 indicator with the following code as suggested by the guide, but I still get the same error: ValueError: x and y must have same first dimension, but have shapes (54,) and (6,)
params = dict(period=30)
# self.data1 = D1 Timeframe
levels = Levels(self.data1, period=self.p.period)
self.levels = levels()
self.levels.plotinfo.subplot = False
self.levels.plotinfo.plotmaster = self.data0
I do not see any other places in the Strategy where I could couple.
The guide says
See how the () is executed with no arguments (in the background a None is being supplied). The following is happening:
pivotpoint.s1() is returning an internal LinesCoupler object which follows the rhythm of the larger scope. This coupler fills itself with the latest delivered value from the real s1 (starting with a default value of NaN)
How does the Cerebro know which timeframe is the "the larger scope"? Does it analyze all the added data?
BTW the Mixing Timeframes guide is where I started and it does not mention plotmaster at all. Maybe it could be useful for newbies if it was somehow mentioned. Just a suggestion.
Thanks that worked .... I had an issue with kicking off the calc at the right time as this was an indicator on another indicator which is an average of another average, so had to find a way to delay the start. but the below is not very pretty but it worked. I think it might be better in a new indicator class but I kept getting a variety of errors with that and my python isn't good enough. Thanks for the help.
#keep a reference to the close
self.dataclose = self.datas.close
self.dataopen = self.datas.open
self.datahi = self.datas.high
self.datalo = self.datas.low
self.datadate = self.datas.datetime
self.dmi = btind.DirectionalMovement(period = self.params.fastdays)
self.dyn_adx_hi = [0,]
self.dyn_adx_lo = [0,]
if len(self.dmi.adx) > (self.params.fastdays)*3+1 and len(self.dmi.adx) <=(self.params.fastdays)*3+2:
self.dyn_adx_hi = self.dmi.adx[-1]
self.dyn_adx_lo = self.dmi.adx[-1]
if len(self.dmi.adx) > (self.params.fastdays)*3+2:
if self.dmi.adx > self.dyn_adx_hi[-1] or self.dmi.adx >= self.dmi.adx[-1]:
self.dyn_adx_hi = self.dmi.adx
self.dyn_adx_lo = self.dyn_adx_lo[-1]
elif self.dmi.adx < self.dyn_adx_lo[-1] or self.dmi.adx < self.dmi.adx[-1]:
self.dyn_adx_lo = self.dmi.adx
self.dyn_adx_hi = self.dyn_adx_hi[-1]
If you post code, you should have a look at what's right above the title of the post
For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/
Because if you don't, code is basically non-readable.
You say 2x orders are rejected, but how leverage is configured is not known. What you exactly do is unclear, but you probably want to see this discussion (there are some others you can quickly google).
You can also use the MA_CrossOver strategy class in the bt. Strategy parent. Just change the init attributes to accommodate for the EMA function. https://github.com/backtrader/backtrader/blob/master/backtrader/strategies/sma_crossover.py
@backtrader I tried executing the trade with what you mentioned above, but I got the best execution using the bracket orders with a risk method controlling the sizes.
Really appreciate the timely response, Thank you.
You can always separate them. Use
stdstats=False in cerebro Docs - Cerebro
And add the observers your like. There are separate observers for Broker and Value.
Docs - Observers and Statistics
Docs - Observer Reference
Hi, yes, among many other items I've created a rolling VWAP for backtrader which I've found useful. And as a challenge to myself I did it in four actual lines of code. If you use this you need to pay me by shipping me a box of your local delicacies (although not dried fish or lutefisk).
Investopedia has some good entries on VWAP and MVWAP as I recall.
Author: B. Bradford
Copyright (c) B. Bradford
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
That they contact me for shipping information for the purpose of sending a
local delicacy of their choice native to whatever region they are domiciled.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
plotinfo = dict(subplot=False)
params = (('period', 30), )
alias = ('VWAP', 'VolumeWeightedAveragePrice',)
lines = ('VWAP',)
plotlines = dict(VWAP=dict(alpha=0.50, linestyle='-.', linewidth=2.0))
# Before super to ensure mixins (right-hand side in subclassing)
# can see the assignment operation and operate on the line
cumvol = bt.ind.SumN(self.data.volume, period = self.p.period)
typprice = ((self.data.close + self.data.high + self.data.low)/3) * self.data.volume
cumtypprice = bt.ind.SumN(typprice, period=self.p.period)
self.lines = cumtypprice / cumvol
@momentum said in indicator with dynamically changing data:
Do you mean instead of changing the data of the indicator, change the data feed itself?
No, I said that you create a data feed which dynamically changes the data it serves.
You fail to understand that the self.datas array in each object is a different one. This is obvious if you consider that you can do this
ma_on_ma = bt.ind.SMA(bt.ind.SMA(self.data, period=5), period=5)
The outer SMA has, obviously, only 1 data feed which happens to be another SMA (the inner one)
Futhermore, you expect things to use the array self.datas and you manipulate it with that expectation. As noted above, this is not supported, given that other notations and references are used in the internals.
@sylvain said in Question on PyFolio:
Is there any way I could format the trading result and feed to Pyfolio and make it works?
Your use case is not covered by the PyFolioAnalyzer which is the analyzer wrapping the calls to PyFolio.
You would have to use the existing code as basis for a new analyzer which decides which data feeds to consider.
Thank you for pointing that out.
So if I want to compare the current volume to the average volume at the same time historically. I need to store the rolling avg for 480points (8hours*60mins), then filter by dt.time() to get the right point and do the comparison?
Docs - Live Trading - Interactive Brokers
If the user wishes to modify this, extra **kwargs can be supplied to buy and sell following the IB documentation.
For example inside the next method of a strategy: