Position vs Order
-
Good Day all,
I've read through the documentation for Orders and Position and some nuances are still not entirely clear to me. From my current understanding,
Order
objects have a status attribute that contains information on if the order has been submitted, accepted, completed or cancelled/rejected due to margin requirements andPosition
objects have thesize
andprice
attribute containing information on the size and the entry price of the position.My strategy has been firing multiple orders and immediately depleting the available cash in
Broker
which is unintended behavior. What I fail to understand however is:-
I currently store my orders to individual attributes within my strategy. Is this the ideal way to track already opened orders?
-
If an order has been completed, would it still exist as an
Order
object or as aPosition
object? -
For trade management, I'm currently setting completed orders as
None
and tracking the size attribute of thePosition
object. Should I be doing this or should I directly track theOrder
object instead?
-
-
-
if it works for you, than why not?
-
order object and position object are different objects and doesn't mutate to each other. position size changes with the completion of the orders.
-
bt
updates position with each order execution, if it is enough for your needs, than you can use it. otherwise complex order management system can be built on the order status tracking.
you may want to google some real trading explanations for
order
,position
,trades
etc. this may help you to understandbt
better, sincebt
simulates real trading process. -
-
@ab_trader An order is an intention to buy/sell and you wouldn't have a position until the order is filled. If I'm not using
cheat_on_close = True
, the order would only be filled on the open of the next bar and this results in having outstanding orders before the open of the next bar. If I'm setting the orders toNone
in thenotify_order()
method, wouldn't my orders be deleted before they are filled? Hence the questions of:-
Should I be setting my order to
None
after they have been submitted/accepted? -
If I should not, I can still track the existence of positions using orders right?
-
-
@Ron-Aw said in Position vs Order:
If I'm setting the orders to None in the notify_order() method, wouldn't my orders be deleted before they are filled? Hence the questions of:
Should I be setting my order to None after they have been submitted/accepted?
I think you might be getting a bit confused between your container tracking the order(s) and the order itself.
The orders themselves dont' go anywhere. Once created they are there for the duration of the backtest. What does change is their status. When completed they are no longer active, but the order object still exists and you can't delete it.
I think what you are referring to when saying is your tracking of the order
@Ron-Aw said in Position vs Order:
I'm setting the orders to None
This just clears your variable. The most common variables are singular parameter, list, or dictionary. Depends on your needs.
-
@run-out I see. I want to ensure that my strategy does not create new orders are when there are existing unfilled orders present and to be able to do that, my strategy has to be aware of the presence of existing unfilled orders. If what you've mentioned if the case, my questions are now:
-
Unfilled orders would have their status as Submitted/accepted and if the order's status is Completed, that means that the order has been filled right?
-
Is there a way to access the record of issued orders?
-
-
@Ron-Aw said in Position vs Order:
Unfilled orders would have their status as Submitted/accepted and if the order's status is Completed, that means that the order has been filled right?
Right,
@Ron-Aw said in Position vs Order:
Is there a way to access the record of issued orders?
Yes, in your broker object. While in your strategy class, there is a list in your broker object that contains all the order objects.
self.broker.orders
-
Thank you. @run-out @ab_trader
-
I seem to be experiencing something else now. I'm using H1 candles and when I fire orders for my assets, the logs are telling me that my orders only get filled the next day. My
notify_orders()
method is as such:def notify_order(self, Order): if Order.status in [Order.Submitted, Order.Accepted]: return if Order.status in [Order.Completed]: if Order.isbuy(): self.log("BUY EXECUTED, {}".format(Order.executed.price)) elif Order.issell(): self.log("SELL EXECUTED, {}".format(Order.executed.price)) elif Order.status in [Order.Margin, Order.Canceled, Order.Rejected]: self.log("Order Canceled/Margin/Rejected")
Within my
next()
method, the structure is:self.buy(data = self.datas[0], size = self.params.Size, price = self.datas[0].close[0]) self.buy(data = self.datas[0], size = self.params.Size), price = self.datas[0].close[0]) self.log("Creating Long Order")
And in my logs, it frequently prints:
Date: 2019-01-22, Creating Long Order
Followed by:
Date: 2019-01-23, BUY EXECUTED, 118.56 Date: 2019-01-23, BUY EXECUTED, 219.25
Is this happening due to
cheat_on_close = False
? -
Correction* The structure within the
next()
method is:self.buy(data = self.datas[0], size = self.params.Size, price = self.datas[0].close[0]) self.buy(data = self.datas[1], size = self.params.Size), price = self.datas[1].close[0]) self.log("Creating Long Order")
-
Did you set 'timeframe' for your data feed?
-
@ab_trader I don't think so. I'm using the
GenericCSVData()
feed. There doesn't seem to be a parameter for "timeframe". -
@ab_trader Does Backtrader assume that the timeframe is "D" by default? If so, How do I set the timeframe to "H1"? The documentation on the
GenericCSVData()
did not mention the existence of a "timeframe" parameter. -
@Ron-Aw said in Position vs Order:
Does Backtrader assume that the timeframe is "D" by default? If so, How do I set the timeframe to "H1"? The documentation on the GenericCSVData() did not mention the existence of a "timeframe" parameter.
You need to look under common properties: https://www.backtrader.com/docu/datafeed/#data-feeds-common-parameters
-
@run-out I see it now but since it goes by
TimeFrame.Minutes
, how does one configure it for "H1"? There doesn't seem to be an option to set it as something likeTimeFrame.Minutes60
-
You may specify both
timeframe
andcompression
attribute during data feed creation. For H1 use TimeFrame.Minutes and compression 60. -
@vladisld Thank you. What's the interpretation of
compression
though? The documentation states: "Number of actual bars per bar. Informative. Only effective in Data Resampling/Replaying." but thing is, my CSV data is already in the form of H1 bars hence I'm unable to comprehend howcompression
works for my use case -
-
@run-out Yes, it is correct and my backtest seems to be firing orders and entering positions correctly but I still have some confusion and am curious on how
compression
works despite me not using any form of resampling and the fact that my CSV file already containing "H1" candles. -
-
@Ron-Aw to clarify it. backtrader does not know about what data you use. so you need to define it. by setting timeframe: Minutes and compression: 60 you say that you are using 60min data as input which is 1 hour. there is no timeframe equals Hours.
Hope that helps