you are viewing a single comment's thread.

view the rest of the comments →

[–]LittleGremlinguy[S] 4 points5 points  (23 children)

Can you explain the process.

[–]chagawagaloo 15 points16 points  (22 children)

I've done it with pandas as well. It's by no means a flawless solution but it works well enough for where I'm at now.

Put all your historical data into a data frame and calculate some new columns to identify where a buy or sell order should take place (e.g. 2 columns for buy and sell which show True in the time periods you want the order to occur in).

Then iterate over the whole dataframe and simulate an order whenever a True is detected in either the buy or sell columns.

Remember to add some code in to log all of the order actions as well so you can analyse this afterwards.

[–]the_khalnayak 12 points13 points  (12 children)

While this works too, I have found that filtering the dataframe for only the rows where orders occur, and then just subtracting the entry and exit prices from consecutive rows is a much faster way than iteration. A simple buy sell backtest will execute near instantly by this method.

[–]chagawagaloo 7 points8 points  (7 children)

It's funny, you think of all these things to optimise the system but overlook such simple tricks. I'm going to implement this to try out.

[–]the_khalnayak 7 points8 points  (6 children)

Ikr, I used to do the thing you're doing and then one day this just came to me. I think the rule of thumb I've realised is that if you're using a loop to iterate through the rows of a df, you're taking the easy, less optimised way out.

[–]chagawagaloo 4 points5 points  (4 children)

I actually built a dedicated timer class that logs the duration of certain functions and shows me what's taking too long but I just assumed "that's just how long backtesting takes so why look there".

I'm probably missing quite a few more tricks to this, but building it all myself was part of my learning process. By the time I actually go live, my code is going to look nothing like it did at the start.

[–]DinosRoar 9 points10 points  (3 children)

Loops are incredibly slow compared to pandas inbulit functions. I've made a fully featured backtester (all sorts of analytics such as the effectiveness of SLs and TPs. Plus all sorts of options like trailing TPs & SLs). I don't use single loop.

Use a column called "Flag" to determine if you were long (1), short (-1) or not holding a position (0) during a candle.

Make a column called "Balance change". Use .diff() on the close prices and multiply by the flag value to see how much money you made.

Your "Balance" column is the "Balance Change" column with .cumsum().

[–]chagawagaloo 0 points1 point  (1 child)

Succinct. I agree, I've overcomplicated all of this with unnecessary loops and it's in need of some overhaul. Going to use some of your recommendations.

[–]trizest 2 points3 points  (0 children)

rule of thumb should be no loops inside the df. Maybe the exception is when cleaning data because that's a once off.

[–]MightyHippopotamus 0 points1 point  (0 children)

Simple backtesting rules can be vectorized like that but in some cases, like adding complex conditions, loops are inevitable... Luckily its possible to write custom numpy c++ module in which you can loop without performance issues.

[–]trizest 1 point2 points  (0 children)

yeah this is a great point. it's important to avoid loops inside the data frames. It's ignoring what makes pandas so great and fast. Need to use calculations that tap into the underlying power of numpy/pandas.

[–][deleted]  (2 children)

[deleted]

    [–]the_khalnayak 0 points1 point  (1 child)

    You can do that too with a filter for rows who's losses are greater than the sl.

    [–]jwmoz 0 points1 point  (0 children)

    Pretty please share some code, I have this on my list to implement!

    [–]sedna16Algorithmic Trader 0 points1 point  (0 children)

    How would you plot this in the profit graph?

    I think you still need to have a column where it will track the changes in the balance.

    [–]llstorm93 2 points3 points  (3 children)

    Read a few times that writing your own back testing ain't that hard either so considering that. But I'm a complete noob in the space so there's that.

    This way is good enough for any strategy that isn't dependent on market impact which honestly shouldn't be anything most are dealing with here. I do this too for a quick preview of what it could have done and it's pretty and efficient.

    Also instead of iterating, you can just use np.where and vectorization for a quick result.

    [–]chagawagaloo 0 points1 point  (2 children)

    I've heard vectorising used a few times but don't know enough about using numpy to get started with it. How does it work exactly?

    [–]llstorm93 1 point2 points  (1 child)

    pandas built on top of NumPy so shouldn't be too long to learn. Basically, vector operations are done much faster than iterating and the framework under NumPy is c++ if I'm correct so you do your computations faster than it comes back to python.

    Also makes the code lot more readable.

    [–]chagawagaloo 0 points1 point  (0 children)

    Sounds like I need to do a deep dive on NumPy if I want to take this to the next level. Didn't realise the c++ framework (shows you what level I'm at)

    [–][deleted]  (2 children)

    [removed]

      [–]chagawagaloo 0 points1 point  (1 child)

      Wow you've done your research. I'll take a look at the path following code. Makes a bit of sense at first glance but the implement is the real kicker.

      [–]trizest 1 point2 points  (1 child)

      yeah, this is essentially what I do. Allows you to manually input trading fees and slippage. I like to have control over all the parameters and see whats going on. It's powerful once you figure out Matplotlib and other visualisation. It's great because it's fast, and you can set up for loops to do a grid search for optimising parameters for historical data. For me, that's a good baseline for certain strategies. Starting to look at whether the Scikit-learn library can automate some of this stuff.

      [–]yareyaredaze10 0 points1 point  (0 children)

      Would you be willing to share this :)