Developing a Trading Strategy using Volume Data
Traders and market analysts use volume data, which is the amount of buying and selling of an instrument over a given time period, to gauge the strength of an existing trend or identify a reversal. The back-and-forth movement between buyers and sellers for the best available price allows us to analyze volume to confirm trends and predict reversals. Generally, volume tends to increase as a trend continues, and will begin to decrease when a trend starts to slow down and reverse. Traders may use volume as both a predictor of price action and a confirmation signal in conjunction with other forms of analysis.
What’s in Volume Data?
Traders know that information can provide an edge in trading, and this is what makes FXCM’s volume data so valuable. This volume data goes beyond what is typically available by providing 32 unique volume data points for each minute, each illustrating a different aspect of trading volume during that minute. See below for a description of each data point:
Live and historical volume data subscriptions are available, and a free 1-month sample of historical volume data can be downloaded from FXCM’s Github. In this article, we will use some of this data to create a trading strategy.
Using Volume to Create a Trading Strategy
To see how this volume data can be used for trading purposes, we will create a trading strategy that buys when buy open amount (BOA) is greater than the sell open amount (SOA) 5-period rolling mean, and test the strategy over the 6-month period 07/01/2017-12/31/2017. BOA can be interpreted as the total volume of opening buy transactions for EUR/USD for each day and SOA is the total volume of opening sell transactions for EUR/USD for each day.
By considering only opening volume, we seek to filter out buy trades that are to cover a short position and sell trades that are to cover a long position. By signaling only when the BOA is greater than the 5-period rolling mean of the SOA we look to trade only when there has been a pattern of stronger buying activity than selling activity over the past 5 days. The strategy will also have a filter for the closing ask price to ensure we are trading with the trend as price is increasing.
The strategy will buy when both of the following conditions are true:
- Yesterday’s closing ask price is greater than the rolling mean of the previous 5 days closing ask price; and
- Yesterday’s buy open amount (BOA) was greater than the rolling mean of the previous 5 days sell open amount (SOA).
Testing the Trading Strategy
We will use the logic explained above to create a backtest of a sample trading strategy using volume data. FXCM’s volume data comes in 1-minute intervals. For this example, I have aggregated historical volume data from m1 to D1 and imported it along with D1 price data into a DataFrame
The difference (pips) column is each day’s return in pips. We multiply by 10,000 here because FXCM prices to the fractional pip (the ten-thousandths place). The pip value for EUR/USD is $0.10 and we will assume a lot size of one standard lot for this example.
pip_cost = .1 lot_size = 100 df['difference (pips)'] = ((df['askclose'] - df['askopen']) * 10000)
Now the trading logic explained above is set: when cond_1 and cond_2 are both true, the signal column reads ‘True’ indicating a trade should be signaled. Since we want to buy today if both conditions were true yesterday, the position column considers the previous period’s signal and will read ‘True’ if a trading signal was issued.
cond_1 = np.where(df['askclose'] > (df['askclose'].rolling(window=5).mean()),1,0) cond_2 = np.where(df['BOA'] > (df['SOA'].rolling(window=5).mean()),1,0) df['signal'] = np.logical_and(cond_1==1, cond_2==1) df['position'] = df['signal'].shift(1)
The function below checks if the position column reads ‘True’, indicating a trade should be taken. If True, the returns for that day are added to the running total.
returns = 0 CountPL=False for i, row in df.iterrows(): if CountPL==True: returns += (row['difference (pips)']*pip_cost *lot_size) df.loc[i,'total'] = returns else: df.loc[i,'total'] = returns if row['position'] == True: CountPL=True else: CountPL=False
We can visualize the returns of this strategy by plotting returns and price over the testing period.
fig = plt.figure(figsize=(12,8)) ax1 = fig.add_subplot(111, ylabel='EURUSD Price') df['askclose'].plot(ax=ax1, color='b', lw=2) ax2 = ax1.twinx() ax2.set_ylabel('Returns in $') ax2.plot(df['total'], color = 'g', lw=2) ax1.set_xlabel('Date') ax1.legend(loc='upper left') ax2.legend(loc='upper right') plt.style.use(['ggplot'])
The green line shows the strategy returns and the blue line shows the EUR/USD price over the same period. Compared to a buy-and-hold strategy over the same period, the backtest indicates the volume strategy has a higher return and avoids some of the drawdown a buy-and-hold strategy would have experienced.
Clearly this was a very general example of how a trading strategy could be developed based on FXCM’s volume data, and we know past performance cannot guarantee future results. However, hopefully now it is clear how this data can be used to create a trading strategy. For more on downloading and analyzing FXCM’s sample data sets, see my article on exploring sentiment data with Python and Pandas.
Try your own analysis
Risk Warning: The FXCM Group does not guarantee accuracy and will not accept liability for any loss or damage which arise directly or indirectly from use of or reliance on information contained within the webinars. The FXCM Group may provide general commentary which is not intended as investment advice and must not be construed as such. FX/CFD trading carries a risk of losses in excess of your deposited funds and may not be suitable for all investors. Please ensure that you fully understand the risks involved.