If you want to remain time agnostic and be bar bound (which seems to be your T and T + 1 description)
Record the len of the data
bought_at = len(self.data)
new_len = len(self.data)
if new_len > bought_at + 1:
There are some uses of clone there, but it basically comes down to either of these:
You use GenericCSVData or PandasData. You can tell those feeds in which part of the original data the close and open prices are. Open a 2nd stream and play with the config - See Docs - PandasData Example and Docs - Datafeed Reference
You can clone the existing data (with the method clone)
Add a filter and manipulate the open price to be the close price - See Docs - Filters
@kausality Sorry for lack of response here. Had not been tracking BT for awhile and was just visiting to see about restarting.
The changes look good to me. Clearly not too many people using this functionality it seems. I cannot recall why I used mean and may have just been my lack of familiarity with influxdb.
I would encourage you to submit the PR.
@mar-co said in new users, one error plotting:
This call to matplotlib.use() has no effect because the backend has already
been chosen; matplotlib.use() must be called before pylab, matplotlib.pyplot,
or matplotlib.backends is imported for the first time
It would seem you already made a call to matplotlib or imported something. Or you are running inside an environment which does it for you.
Or read this:
Nevermind, I had taken the idea of using the self._timeframe from the ccxt feed when instead I should have been using self.p.timeframe which doesn't get modified by the replaydata. Works perfectly now.
@jf said in ploting StopLimit, StopTrail observers:
@silverbald I have the same issue,
Since the development of the thread seems to indicate that the originally reported issue wasn't the actual issue, ...
Would you care to let us know which issue are you facing?
backtrader was never meant for bid-ask simulation and it for a very simple reason.
Let's imagine you have an OHLC and you have a limit order with a price that happens to sit in the middle of the HL range (i.e.: limit price = (H + L) / 2)
If the timeframe of the bar is 1-day and we look at recent ES-Mini bars the range can be 120 points between 2891 and 2771 with our limit price right at 2831.
We don't really know when the 2831 price was hit during the day. The question here: Which bid-ask prices have to be considered for matching the desired limit price?.
When we see the bar the only valid bid-ask prices would be that corresponding to the close which in this case was 2772, far far away from our price. And even if we had information for the bid-ask prices for the area 2831, this price could have been crossed several times during the day, so at which time do we execute the trade?
Because backtrader has to work with any timeframe, the bid-ask component as shown cannot be really considered.
That's why people use slippage: Docs - Slippage which simply worsens your matching price.
In any case and for a Limit order, one shouldn't apply slippage because the Limit order will be matched at the requested or at a better price. Use it for Market orders.
I wonder if I would have come to such a simple an elegant solution so quickly. The only contribution I could think of is to use the simplification in the comparison that Python offers
timenow = self.data0.datetime.time(0)
if datetime.time(11, 31) <= timenow <= datetime.time(12, 59):
... your logic here ...
Storing the time instances would be wise to avoid creation and recreation of the instances.
@forrestchi said in How to refer some specific indicator value?:
How can I define a variable to store the very first sma value(at maperiod price)?
maybe something like: self.inds[d]['firstma'] = .....?
It's a possibility. But the value has to be filled manually by you when the SMA starts producing values. Your options
You check all SMAs during prenext and nextstart (because they will first produce a value at different times) and record the values the first time they aren't NaN
You subclass the moving average of your choice and specifically store the first value in an attribute when nextstart is called
See Docs - Operating the Platform to understand when next, prenext and nextstart are called.
The design chose for backtrader is to not make assumptions. If you connect to an account and a position is open, you know what you are doing. The platform doesn't have to know it.
Use a separate account (as suggested by @bishbashbosh )
Subclass your live broker to skip the first position update
Here you will still have a problem: you may, for example, still manually change the position in your account while the algorithm is running. Which means you have to ignore not only the initial position update, but also others.
I would use a separate account.
You have to check the length of the data feed. It changes when a new bar is delivered. This can happen for both data feeds at the same time, but with different timeframes, it will obviously happend a lot more often for the smaller timeframe
@андрей-музыкин This is absolutely amazing!!! I spent a whole week just reviewing the work you did... and I feel like I'm just scratching the surface.
mind blowing!!! thanks a lot for this contribution.
as this is very technical stuff, is there a place maybe to ask questions or exchange ideas?
love this project :)
@mttax said in Extend CSV feeder with string column:
So is there an easy way to use string column in backtrader, or any advice on doing so?
No. This is not pandas. your best option is to load the data using pandas into a Dataframe and then using the current data index, fetch the string from the dataframe.
I bumped into similar situation. Looks like by default, backtrader is not touching DELAYED data and therefore inherits whatever "rightedge" convention from the original data feed, and in case of ibstore, it is "rightedge=False"; while for LIVE data part it will use the default convention of "rightedge=True", which causes the discrepancy.
Many thanks for the tip from @dasch, now the bars match backteset/live trading.