Filtering trading sessions
the strategy, I'm working on is a day trading strategy which would normally run during the EU session. Currently, for backtesting purposes, I have imported 1 minute metaquote (MT4) EURUSD data and reading it in as a dataframe, I downloaded it from here https://www.fxdd.com/mt/en/resources/mt4-one-minute-data. I think it's in GMT time but not sure.
I would need some sort of indicator which indicates the different sessions so I can filter out my trading time for it. I was wondering how to tackle the issue of daylight savings and I'd imagine I'd have to set the timezone or something. I don't really have an idea where to start and eventually I want use IB data to forward test.
Some information on timezones.
@run-out thanks run-out. other question which is related to datetime. for order we have the parameter "valid". if my order is not triggered the next bar(next minute in this case) then I want to cancel it. I can see that datetime.datetime can be used. however, I need to reference the time for the current bar and then I imagine, use a timedelta to get to the next bar in order to cancel the order. how can we reference the datetime of the current bar? I've tried self.datetime.datetime but that doesn't work.
to be more concrete. I want to cancel the order if it doesn't get triggered next bar. however if the high would be equal, and the low would be higher (for a long), I would want to keep my entry the same (above the high) and move the stoploss to the new low.
Try using bar length instead.
just an FYI. I figured out I can use
to reference the current's bar datetime
then if I'd want it to be valid for eg 1 minute I can do
valid=self.data.datetime.datetime(0) + datetime.timedelta(0,0,0,0,1)
I think using
is what I'll need. I am struggling with checking if the order got filled or not.
def next(self): # 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: if entry_condition == True: self.order = self.buy(exectype=bt.Order.StopLimit, price=self.data.high, transmit=False) self.StopLoss = self.sell(price=self.data.low,exectype=bt.Order.Stop, transmit=False, size=self.order.size,parent=self.order ) self.target = self.sell(price=(self.order.price-self.data.low*1.1+self.order.price), exectype=bt.Order.Limit, transmit=True, size=self.order.size, parent=self.order) self.bar_order_submitted = len(self) self.log('BUY CREATE, %.5f' % self.order.price) if self.order not in order.Completed and len(self) == self.bar_order_submitted + 1: # error occurs here if self.data.high == self.data.high[-1]: # current's bar high is equal to the previous bar's high self.order = self.buy(exectype=bt.Order.StopLimit, price=self.data.high, transmit=False) if self.data.low > self.data.low[-1]: # if the current bar's low is higher, we adjust ourstoploss to the current bar's low self.target = self.sell(price=(self.order.price-self.data.low*1.1+self.order.price) ,exectype=bt.Order.Limit,transmit=True, size=self.order.size, parent=self.order)
error I'm getting
--> 102 if self.order not in order.Completed and len(self) == self.bar_order_submitted + 1: 103 if self.data.high == self.data.high[-1]: # current's bar high is equal to the previous bar's high 104 self.order = self.buy(exectype=bt.Order.StopLimit, price=self.data.high, transmit=False) NameError: name 'order' is not defined
just wanted to mention, I have the notify_trade method in the strategy and also self.order = None at init
@Jens-Halsberghe said in Filtering trading sessions:
if self.order not in order.Completed
The offending line is here.
order.Completeis a local variable to the next method, and is not defined in next. It is defined in notify_order. Try using
Or you can just use the number
4to replace order.Complete. The order.Complete attribute returns the number 4. Here is the status list in the order object and the order Status is a list that reflects the number returned.
['Created', 'Submitted', 'Accepted', 'Partial', 'Completed', 'Canceled', 'Expired', 'Margin', 'Rejected'].
And if you debug and look at the attributes you would find
@run-out thanks again Sir. I have actually tried this before and I'm getting
AttributeError: 'NoneType' object has no attribute 'Completed'
and then I'm getting a syntax error so I'm not sure if I'm getting what you're referring to.
btw I know you said "Complete" I tried that too but I think you meant to say "Completed" as that's what we have in notify_order
Couple things here. First of all, I figured out if I add order.status in notify_trade, I'm getting the numbers as you mentioned
if order.status in [order.Submitted, order.Accepted]: # Buy/Sell order submitted/accepted to/by broker - Nothing to do self.log(order.status)
second, I actually noticed that my order is always cancelled for some reason. I split what it says in the log to distinguish between canceled, margin and rejected.
if we have a look at the log:
Starting Portfolio Value: 1000000.00 2020-08-12 08:30, BUY CREATE, 1.17170 2020-08-12 08:31, BUY EXECUTED, Price: 1.17170, Cost: 1.1717, Comm 0.0000 2020-08-12 08:32, SELL EXECUTED, Price: 1.17183, Cost: 1.1717, Comm 0.0000 2020-08-12 08:32, cancelled 2020-08-12 08:32, OPERATION PROFIT, GROSS 0.0001, NET 0.0001 2020-08-12 08:53, BUY CREATE, 1.17228 2020-08-12 08:54, BUY EXECUTED, Price: 1.17228, Cost: 1.1723, Comm 0.0000 2020-08-12 08:55, SELL EXECUTED, Price: 1.17222, Cost: 1.1723, Comm 0.0000 2020-08-12 08:55, cancelled 2020-08-12 08:55, OPERATION PROFIT, GROSS -0.0001, NET -0.0001 2020-08-12 08:55, BUY CREATE, 1.17225 2020-08-12 08:57, BUY EXECUTED, Price: 1.17225, Cost: 1.1723, Comm 0.0000 2020-08-12 08:58, SELL EXECUTED, Price: 1.17208, Cost: 1.1723, Comm 0.0000 2020-08-12 08:58, cancelled
I have not really any idea why that is. I initially create the order, target and stop loss as in my post above. I wanted to log when the stoploss or target gets triggered but I can't really see how to do that either. the execution part is quite tricky for me at the moment!
In next you have assigend your entry order object to the variable
self.order. When in notify_order, you access the current order object using the variable
order. These are both order objects.
In an order object you can access the status of that object which is stores as in next
self.order.statusor in notify_order as
For completed orders this status variable will equal 4.
In your code, in next, you can use:
if self.order.status != self.order.Completed etc.
if self.order.status != 4 etc.
The cancel is normal. It is cancelling the other side of the bracket, so if you fill on the take profit, the stop gets cancelled and vice versa. If you want a bit more information in your log you can show the order reference numbers.
Also as another side note, I notice you are assigning the size using order.size. Size is acutally tracked in order.created.size.