Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open a limit order in certain time frame #502

Closed
sword134 opened this issue Oct 10, 2021 · 7 comments
Closed

Open a limit order in certain time frame #502

sword134 opened this issue Oct 10, 2021 · 7 comments
Labels
question Not a bug, but a FAQ entry

Comments

@sword134
Copy link

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?

@kernc
Copy link
Owner

kernc commented Oct 10, 2021

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()

@kernc kernc added the question Not a bug, but a FAQ entry label Oct 10, 2021
@sword134
Copy link
Author

Strategy.data.index is an instance of pd.DatetimeIndex and it's 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()

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.

@kernc
Copy link
Owner

kernc commented Oct 11, 2021

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.

@sword134
Copy link
Author

sword134 commented Nov 14, 2021

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.

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()

@kernc
Copy link
Owner

kernc commented Nov 14, 2021

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.

@eromoe
Copy link

eromoe commented Jan 8, 2023

@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 .

@kernc
Copy link
Owner

kernc commented Jan 8, 2023

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.

@kernc kernc closed this as completed Jan 8, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Not a bug, but a FAQ entry
Projects
None yet
Development

No branches or pull requests

3 participants