How I learned Rust by trading Cryptocurrencies
August 08, 2020
Since around 2015, Iāve been dollar-cost averaging cryptocurrencies over at Coinbase. āStacking Sats,ā itās called these days.
Coinbase makes it very straightforward: link your bank account, pick your currency and frequency of purchase, et voila: your USD becomes cryptocurrency. For a fee, of course.
Anybody who has been around Cryptocurrency for more than a couple minutes knows that prices tend to fluctuate wildly. On the whole, however, prices have been trending up. As of the time of this writing, Bitcoin is:
- Last 6 months, +194.86%
- Last 2 years, +266.49%
- Last 3 years, +290.18%
- Last 5 years, +5,300.92%
With a significant general upward trend like this, monthly cost averaging means youāre leaving a lot of BTC on the table compared with weekly or daily cost average investing. I decided that daily dollar cost averaging was in my best interest, so I set up a recurring purchase for $10 per day, and ate the $1 service charge. Whatās $30/mo when youāve got compounding double-digit gains on $270/mo?
Itās a lot of extra money on the table! Thinking about this in terms of USD is the wrong approach; the amount of USD Iām spending is fixed. The correct way to think about this is: how much more BTC would I have if I were not paying Coinbase a 10% fee?
To be clear, Coinbaseās fee is a much smaller percentage if youāre investing a larger sum of money. Investing a larger sum would mean more time between purchases, which (for reasons described above) I want to avoid.
One solution is to use Coinbase Pro instead of Coinbase. The trading fees on Coinbase Pro are significantly less ā at the volume Iām trading, theyāre 0.5% instead of 10%: a whole 9.5% less.
Switching to Coinbase Pro, in other words, earns me 10.5% more BTC per transaction when compared with Coinbaseās āRecurring Buysā offering. The problem? Coinbase Pro does not offer recurring buys! They do, however, offer an API that we can use to initiate recurring buys on our own.
Enter Rust
Call me paranoid, but I am not about to put API keys that can access my personal Coinbase account on servers that I donāt physically control. This means running servers at home, which means electricity costs and heat.
The electricity and heat problems associated with running servers at home can be mitigated by using hardware like a Raspberry Pi ā a credit-card sized computer that draws around 5W of power, and doesnāt put out enough heat to even require fans. The downsides include limited processing power, and downright atrocious disk IO (if using the built-in SD card reader).
The Piās performance limitations mean that I want software running on it to be small and fast. Furthermore, because Iām dealing with money and network-based APIs, itās also important that the software Iām using is correct.
The Rust Programming Language checks all of these boxes ā with performance on par with C and C++, and a compiler that requires you to account for failure cases and not just happy paths, it becomes difficult to write incorrect code. Furthermore, Rust makes it easy to compile to multiple targets, which means getting it onto an ARM processor (the Pi) is not a significant undertaking.
In fact, thanks to Githubās new pricing strategy around Github Actions (free!), we can just let Github compile all the binaries for us! š
The Strategy
Instead of relying on Coinbase to purchase BTC for us, weāll write a Rust program to do it instead. Nothing fancy needed here ā no price watching or machine learning to optimize purchase times, just a Rust binary that starts instantly, makes a transaction, logs the output, and exits. Stick it on the crontab and call it good!
The program I ended up with, hodl, has been running faithfully for the past two months! Itās my first Rust program, so please be kind and help me learn š.
Since I began āstacking satsā this way, Iāve only run into one issue: after losing power in a storm, we came back online with a new IP address, and the new address was not yet associated with my API key, so hodl
failed to make a couple purchases (this is a security feature that you can elect to disable).
I noticed something was afoot after I stopped receiving my nightly confirmation emails, so I logged onto the Pi, checked the logs, saw the issue, added the new IP address, and we were back in business.
Setting it up
Everyone is going to have different API keys, and Iām not about to check mine into the repository :) In order to use hodl, you need to set some environment variables.
My recommendation would be to create a script, hodl
, that sets these and invokes the hodl binary you download:
#!/bin/bash
export COINBASE_API_KEY=[your key]
export COINBASE_API_SECRET=[your secret]
export COINBASE_API_PASSPHRASE=[your passphrase]
export BANK_ID=[id of your associated bank account]
./hodl-ARMv7 $@
Then, you can set your crontab to run periodic deposit and buy commands. For example,
# m h dom mon dow command
0 0 */3 * * /home/pi/hodl deposit 45 2>&1 | tee -a /home/pi/logs/hodl.log
7 0 * * * /home/pi/hodl buy BTC 10 2>&1 | tee -a /home/pi/logs/hodl.log
8 0 * * * /home/pi/hodl buy ETH 5 2>&1 | tee -a /home/pi/logs/hodl.log
Et voila, cryptocurrency dollar cost averaging at a fraction of the retail cost!
The crontab above will:
- Deposit $45 USD into Coinbase every 3 days (every 72 hours)
- Buy $10 USD worth of BTC every day at 7 minutes past midnight
- Buy $5 USD worth of ETH every day at 8 minutes past midnight
- Send both standard error and standard output to a log file
The times I picked were arbitrary; some time spent with historical data and in a Jupyter notebook revealed that there wasnāt a reliable correlation with time of day and low (relative to a sliding window) prices, so pick a time thatās convenient for you!
Thoughts on Rust
Overall, Iāve walked away with a positive impression of Rust.
I especially like the match
structure, though it took me a while to get comfortable with the difference between Option
and Result
types.
Figuring out how to cryptographically sign API request headers to accommodate the Coinbase Pro API was a fun challenge that forced me to get into the docs of other Crates, and (coming from the dynamically typed world of JavaScript and Clojure) suffer a bit of pain for the type system, though I am grateful that it keeps me honest.
I also like the stance Rust takes towards data organization with Structs, which I feel are a much better alternative to the OO purgatory I found myself in back when worked in Java. When it comes to data, though, I still feel like Clojure has it figured out the best.
For this job, Rust was excellent, and I believe in picking the right tool for the job.
Not that other tools wouldnāt have done the job just as nicely, but I was looking for an excuse to learn something, and this solved a real problem that is making me more money as a result.
Just in time, too: since I started using hodl
instead of Coinbase, the price of BTC has gone up over 30%!
Conclusion
If youāre in the market for some Cryptocurrencies, why not check out hodl, or use it as a starting point for trading against some other API if Coinbase Pro is not your preferred exchange? If youāre a Rust pro, Iād love your feedback on how to improve the program. And Iād like everyone to start buying Bitcoin ā if you havenāt already, now is the time to hop on the bandwagon!