Early Christmas Morning
Early Christmas morning, I was able to do something that I had wanted to be able to do for a long time, and that’s to backtest a strategy inside a Pluto.jl notebook. Running trade simulations in the REPL was fun, but what I really needed to do was find a workflow that would allow me to SIT STILL and look at the results of a simulated run, and see where it went right and more importantly see where it went wrong, and then try to improve upon it.
HMAStrategy
function should_open_long(strategy::HMAStrategy)
# if we're neutral and
crossed_up(strategy.rf.hma330, strategy.rf.hma440)
end
function should_close_long(strategy::HMAStrategy)
# if we're long and
crossed_down(strategy.rf.hma330, strategy.rf.hma440)
end
I’m a fan of the Hull Moving Average, so the second strategy I wrote after a Golden Cross strategy was a long-only HMA cross strategy. I let it run from 2023-07-01 to 2024-11-29 which was a bullish period where I thought it would do well.
It did alright and made some imaginary money buying and selling BTCUSD, but towards the end, it made 3 losing trades in a row. They’re trades 4, 5, and 6 in the image above. Trades 4 & 5 had late entries, but they were profitable for a few days before price dipped and the position was closed on a late exit signal. Those two trades looked salvageable to me. Trade 6, on the other hand, was just a bad entry, and I thought I could come up with some criteria to easily avoid it. …so I made some adjustments.
HMA2Strategy
- I added the concept of late entry and early exit to remedy the problem I saw on trades 4 & 5.
- I added an extra check for the slope of the 440 HMA and the position of the close price relative to the 440 HMA. If the slope is negative and the price is under the 440 HMA, skip the trade.
- Then I let it run.
My ideas worked, and I achieved a pretty good performance improvement.
That was the first time I was able to properly iterate on a strategy in Julia.
I knew Pluto was going to be really well suited for this. Pluto was the reason I even started exploring Julia in the first place. Anyone who has had to manually control order-of-execution in Jupyter knows what a pain that can be. I didn’t have to worry about that at all in Pluto, and it made the backtesting workflow feel so much better.
I regret that this notebook may be difficult for others to run, because you’re going to have to download a big dataset using CryptoMarketData.jl to even start. However, I’ve made a static export of the notebook that’ll let you look around and play with the charts. You can also see the implementation of HMA2Strategy which I did not include in this post.
For those who are curious, I also made a static page that tries to explain how my simulation system works. I drew a few diagrams with nomnoml too, because it’s easier to explain some things visually.
There’s a lot that’s unfinished and underdeveloped in my system, but it’s starting to get somewhere. I feel like I have a viable notebook-based workflow for strategy development now. It took me a while to reach this point, and I’m thankful for all the libraries and infrastructure in the Julia community, and the all the human help I received along the way. It’s been a while since I’ve enjoyed learning and using a language this much.