pmorissette / bt

bt - flexible backtesting for Python
http://pmorissette.github.io/bt
MIT License
2.13k stars 411 forks source link

New features : Intraday #70

Open arita37 opened 8 years ago

arita37 commented 8 years ago

Hi,

Just wondering if we can 'twist' the existing class to put intraday data ? Think this should be the same, just more timestamp.

Thanks PS: do you have an email where we discuss on this ?

macgyver13 commented 7 years ago

I am interested in the same feature. Feels like this project is dormant

pmorissette commented 7 years ago

Hey @arita37, @macgyver13,

First off, sorry for not responding earlier. I have been extremely busy with work and a young child at home.

I personally don't backtest at the intraday level, but as @arita37 said, it shouldn't be too difficult - most of the heavy lifting is done by pandas. You would just need add some Algos - for example, RunHourly, RunEveryXMinutes, etc. Some of the performance metrics assume daily frequency as well, so that would have to be tweaked.

Also, intraday frequency brings on a whole other set of considerations. What about slippage costs, market impact, timing, etc? This would have to be factored in if you want accurate simulations.

Anyways, I hope this helps and I apologize for the lack of commits on this project - such is life!

Cheers, Phil

macgyver13 commented 7 years ago

I understand how life goes, I have a lot less time to develop than in the past. Thank you for publishing your work to allow others to benefit.

I am trying to determine best way to process reference daily statistics and evaluate 15 minute samples in a DataFrame to make decisions to buy / sell and hold for x points. Based on your response sounds like I should create a RunEveryXMinutes algo and pass the daily stats in the permanent data. How would I go about controlling exit criteria, call strategy.close() in algo?

Any confirmation or advice would be great. Do you know of better backtesting tools you would recommend for Intraday testing?

Thank you Ron

On Wed, Oct 12, 2016 at 9:50 PM, Philippe Morissette < notifications@github.com> wrote:

Hey @arita37 https://github.com/arita37, @macgyver13 https://github.com/macgyver13,

First off, sorry for not responding earlier. I have been extremely busy with work and a young child at home.

I personally don't backtest at the intraday level, but as @arita37 https://github.com/arita37 said, it shouldn't be too difficult - most of the heavy lifting is done by pandas. You would just need add some Algos

  • for example, RunHourly, RunEveryXMinutes, etc. Some of the performance metrics assume daily frequency as well, so that would have to be tweaked.

Also, intraday frequency brings on a whole other set of considerations. What about slippage costs, market impact, timing, etc? This would have to be factored in if you want accurate simulations.

Anyways, I hope this helps and I apologize for the lack of commits on this project - such is life!

Cheers, Phil

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/pmorissette/bt/issues/70#issuecomment-253390255, or mute the thread https://github.com/notifications/unsubscribe-auth/AEfm1ifdLZ9CEerZSbQv_rukcE3OpQCNks5qzY5KgaJpZM4I77Cx .

pmorissette commented 7 years ago

Hey Ron,

Yes basically most of the framework would be fine as is. Look at the RunMonthly algo for an example. It looks to see if the current month is different than the month the last time the algo was called. If so, it returns True, which essentially allows execution to continue. If false, the AlgoStack stops execution at that point. You could apply the same logic at the intraday level. Another interesting algo is Rebalance if you want to see how the actual allocation of capital is done.

I developed bt for longer term portfolio style strategies, where you are essentially rebalancing / shifting weights between different assets. The general pattern is Select -> Weigh -> Rebalance. So, Select figures out which securities should be in the portfolio, Weigh determines their weights (equal weight, min var., etc.) and Rebalance does just that.

You could do the same on a smaller time scale - basically, your algo would determine which securities should have some allocation (x% of your portfolio, or whatever logic you choose to apply).

I haven't really looked at any of the other frameworks in a really long time so I can't give you good advice. The only other Python one I am familiar with would be Zipline, although I haven't used it myself. It powers the website Quantopian, which does support intraday out of the box (I think).

Hope this helps, Phil

Quantmatic commented 7 years ago

+1

intraday would be a great feature, ffn is easy, all you have to do is resample the intraday equity to daily with pandas, like:

    data = equity.resample('1D').last().dropna()
    myffn = PerformanceStats(data, rfr)

bt would be a bit trickier, not sure I could do it without breaking it's natural flow.

JordanPlatts commented 6 years ago

I added an abstract class RunPeriod that can be derived from to handle intraday time frames. Check out the code. If you wanted RunHourly, it would look something like the code below:

class RunHourly(RunPeriod):

"""
Returns True on hour change.

Args:
    * run_on_first_date (bool): determines if it runs the first time the algo is called
    * run_on_end_of_period (bool): determines if it should run at the end of the period
      or the beginning
    * run_on_last_date (bool): determines if it runs on the last time the algo is called

Returns True if the target.now's hour  or day has changed
compared to the last(or next if run_on_end_of_period) date, if not returns False.
Useful for daily rebalancing strategies.

"""
def compare_dates(self, now, date_to_compare):
    if now.date() != date_to_compare.date() or now.date().hour != date_to_compare.date().hour:
        return True
    return False
hcschmitz commented 2 years ago

I added an abstract class RunPeriod that can be derived from to handle intraday time frames. Check out the code. If you wanted RunHourly, it would look something like the code below:

class RunHourly(RunPeriod):

"""
Returns True on hour change.

Args:
    * run_on_first_date (bool): determines if it runs the first time the algo is called
    * run_on_end_of_period (bool): determines if it should run at the end of the period
      or the beginning
    * run_on_last_date (bool): determines if it runs on the last time the algo is called

Returns True if the target.now's hour  or day has changed
compared to the last(or next if run_on_end_of_period) date, if not returns False.
Useful for daily rebalancing strategies.

"""
def compare_dates(self, now, date_to_compare):
    if now.date() != date_to_compare.date() or now.date().hour != date_to_compare.date().hour:
        return True
    return False

Hi @JordanPlatts

Thanks a lot for the hourly intraday code! May I ask you if that code snippet works for you? I would also be interested in running intraday strategies!

Thank you Hans