Open a limit order in certain time frame
Hello, I am trying to open a long limit order when the time is between 2:55pm and 3pm and only in that timeframe.
In raw python it would look like this, where x is my index column in my dataframe.
def time_in_range(x):
start = time(14, 55)
end = time(15 0)
x = datetime.strptime(x, '%Y-%m-%d %H:%M:%S')
"""Return true if x is in the range [start, end]"""
if start <= end:
return start <= x <= end
else:
return start <= x or x <= end
I am however unsure how I would make it in the backtesting library? How do I open a long limit order when the time is between 2:55pm and 3pm and then close it say 10 minutes later if it hasn't been filled?
Strategy.data.index is an instance of pd.DatetimeIndex and its values are pd.Timestamp. So something like this might work:
time = self.data.index[-1].time()
if start <= time <= end:
self.buy(...)
...
for order in self.orders:
if time >= time(15, 10):
order.cancel()
Strategy.data.indexis an instance ofpd.DatetimeIndexand it's values arepd.Timestamp. So something like this might work:time = self.data.index[-1].time() if start <= time <= end: self.buy(...) ... for order in self.orders: if time >= time(15, 10): order.cancel()
Thanks this seems to work. I've got a another question though. If I place 2 limit orders a long and a short and I want to cancel the opposite order when one of them is filled, how can I do it in backtesting? Say my long order is filled, I then want to cancel my short order.
You can test the order via Order.is_long. The active Trade has a similar property.
You can also just loop over for order in self.orders, because once the order fills and becomes a trade, it is removed from Strategy.orders and put into Strategy.trades.
You can test the order via
Order.is_long. The activeTradehas a similar property.You can also just loop over
for order in self.orders, because once the order fills and becomes a trade, it is removed fromStrategy.ordersand put intoStrategy.trades.
This also cancels the stoploss on the current trade though. Is there a way to disguinish between the stoploss which is attached to the current trade and the order for a limit short (in case the current trade is a long). I only want to cancel the short order, not the stoploss attached to the current active long trade
def next(self):
time = self.data.index[-1].time()
if self.start <= time < self.end:
self.buy(limit=self.highest_high, sl=self.highest_high-self.sl1, tp=self.highest_high+self.tp1)
self.sell(limit=self.lowest_low, sl=self.lowest_low+self.sl1, tp=self.lowest_low-self.tp1)
for order in self.orders:
if time >= self.cancel_order_time:
order.cancel()
for trade in self.trades:
if trade.is_long or trade.is_short:
for order in self.orders:
if order.is_short:
order.cancel()
Is there a way to disguinish between the stoploss which is attached to the current trade and the order for a limit short
Orders have .is_contingent property which is True for SL/TP orders.
@kernc How can I make cancel a order when it exceed certain time ? I tend to close an order if it is not filled in certain time interval , but Order class doesn't contain entry_time .
Whatever is not provided by the library, you can code yourself. Something like:
order = self.buy(...)
self.order_times[order] = self.data.index[-1]
for order in self.orders:
if self.data.index[-1] - self.order_times[order] > pd.Timedelta('3 days'):
order.cancel()
If you think Order needs a new property .placed_time (or somesuch), open a new feature request for it.