ETH/USD Missed Opportunities

William Hill
6 min readMar 23, 2023

My last post showed a lot of promise for using ADX to trade ETH/USD. In this post I am going to add a few more popular tokens and start a bit of parameter tuning. My goal is to maximize ROI. To recap, I wrote a bit of code to grab the latest data (sans current day) for ETH/USD from Alpaca. Then I did some backtesting on ADX with a threshold of 40 and the resulting ROI was 11.56%. Here is a plot showing the trades along with the ROI and ADX & DI values.

ETH/USD Trading Bot v0.0.1-Alpha

Missed Opportunities

If I zoom in the above plot in a few places, I find a few spots that show some missed opportunities. The plot below shows this particular trade was opened 6 minutes too late. The Plus_DI signal spiked 2 minutes too late, but we aren’t really using that Plus_DI quantitatively, anyways.

Missed Opportunity #1–6 Minutes Late

The following plot shows we opened a trade but did not sell at the right time. The ADX & DI data shows an interesting crossover between Plus_DI and Minus_DI near the ETH/USD during the trade. The ADX value was too low to trigger a sell signal.

Missed Opportunity #2

ADX & DI Correlation

My first attempt to root out some useful data is to re-run my ADX-DI system using a few more tokens and a few more ADX parameter ranges. To run more of these experiments I re-organize my code and create a couple new functions. All code images are from carbon. But first are the boring imports

from datetime import timedelta, datetime as dt
from alpaca.data.timeframe import TimeFrameUnit
from pandas import DataFrame
from pytz import timezone
from talib import abstract
from os import getenv
from functools import lru_cache
from alpaca.data import CryptoHistoricalDataClient
from alpaca.data.requests import CryptoBarsRequest
from alpaca.data.timeframe import TimeFrame

1 of 5 — Crypto Token Data from Alpaca

I used lru_cache to speed up the process of grabbing Crypto candles. I explain this code in-depth in this post.

Grab Crypto Data from Alpaca

2 of 5 — Calculate ADX Values

The following function takes your pandas DataFrame with Crypto candles, along with parameters for TA-Lib’s implementation of ADX and DI as parameters to calculate ADX and DI values. Using the ADX and DI values, columns for buy and sell flags are created. These buy and sell flags are then used to simulate trading. A trade is executed by shifting the trading flags to the next row. This shifting of flags simulates a live Trading Bot where the signal indicates a trade but the trade happens in the next tick (or row). The opening price of the simulated next tick would be the purchase or sales price. Using these trades, gains for each sales are calculated. And from the gains, cumulative gains are added to a cumulative column.

ADX & DI Code

3 of 5 — Calculate ROI

Once we have our trading flags and gains, we can now simulate a Trading Bot that starts with a set amount of capital and creates returns. I struggled with doing this without a loop. Please reply in the comments if you have a suggestion on how to vectorize this loop. I will have to figure this out at some point if I plan to accelerate this code on a GPU.

ROI

4 of 5 — Objective Function

Here is where we call all the previous functions. This function grabs the data, perform calculations, and simply returns a single ROI. I call this the Objective Function because I want to tune its parameters to give me the best ROI. To find the optimal parameters for maximizing ROI, we use Machine Learning in my next post.

Calling All Functions

5 of 5 — Tokens and ADX Trials

Finally, the Objective Function needs all sorts of parameters for testing. For now we will do a Grid Search. In my next post we will use Machine Learning, specifically AutoML or Bayesian Optimization and its cousins like Tree Parzen Estimator to choose the optimal parameters.

Trials for Testing and Analyzing

Enough Talk, Run Trials

Not horribly slow!

Now that we have run all the various ADX parameters with the various Crypto tokens, using multiple time windows, I was eager to see which parameter provides the highest ROI.

The Best 5 Trials

It is the trusty, ole Bitcoin that wins the ROI prize. It has been on the up-and-up lately. So it seems BTC/USD with a 10 day history and a low ADX threshold optimizes ROI.

Bitcoin for the Win

To be fair, it is hard to lose money when your Token is up and to the right. Or, everyone is genius in a Bull Market.

BTC/USD March 13–23, 2023

The Worst 5 Trials

Solana Losses

The worst scenario is Solana over 14 days and a ADX threshold of 40. Let’s dig into all the trials.

Correlation Analysis

Correlation Analysis ROI~ADX

The ADX threshold is negatively correlated and history is positively correlated. So it seems a smaller ADX threshold and a longer history is better for ROI. This makes sense because lowering the ADX threshold would trigger more trades over a period of time. And lengthening the history also provides more trade opportunities. This makes sense but a bit more analysis makes me think worry that this only works when your asset is increasing over time. To test this hypothesis, I break out the correlation analysis and closing price plots for both Bitcoin and Solana.

Bitcoin vs Solana Price Trends

From the price plots, it is not difficult to understand why Solana has the worst performing ADX Trials. Bitcoin and a nice, mostly smooth increase over time. Solana has some downward trending days and some volatile jumps, relative to its price. Trying to jump in and out at a profit would be difficult more difficult than Bitcoin.

BTC/USD Closing Price Plot
SOL/USD Closing Price Plot

Bitcoin vs Solana ADX~ROI Correlation

There really is not a huge difference between these two heatmaps. The correlation strengths are in the same ballpark and in the same order of importance.

BTC/USD Correlation — ADX Parameters ~ ROI
SOL/USD Correlation — ADX Parameters ~ ROI

Bitcoin vs Solana — Best and Worst

The tables below reveal the most import information so far. It is possible to profit using ADX on both tokens, but the parameters need to be optimized independently. If our eventual Trading Bot is to make a profit, it needs to use a separate AutoML process for each Token.

Bitcoin

Bitcoin — Best & Worst ROIs

Solana

Solana — Best & Worst ROIs

Next Steps

In my next post, I will take all of the above work and use Optuna, an open source AutoML platform to find the best parameters for ADX. I think I need to adjust my objective function to optimize for average trade ROI, instead of ROI over time. I believe this will be a better metric since the correlation maps above strongly correlated history to ROI, which doesn’t help for a live Trading Bot. More to come.

--

--

William Hill

AI Engineer, Google: Finance, Crypto, ML, Coding, Fantasy Football