API Docs

Manual, tutorials and complete function reference

Comparison of High and Low
Frequency Trading Strategies


This tutorial demonstrates how one could compare high and low frequency intraday trading strategies in terms of their intraday risk and performance. Both strategies would employ a price moving average with a window of different length as a single trading signal generator, so that we could simulate position entry and exit with different holding perdiod durations. Our trading portfolio would consist of a single stock (GOOG) to keep matters simple.

R Code Matlab Code
Constructing Trading Portfolios

The high frequency trading strategy has a window length of 20 seconds, while the low frequency strategy uses 1000 seconds to compute an average price. When the stock price exceeds the N-second moving average, strategy would buy 100 shares of the stock. If moving average goes above the current price while we are still in position, the strategy would issue a sell signal.

Now that we defined our intraday holding intervals, we can construct our trading portfolio for further analysis. Note that we set portfolioMetricsMode to "portfolio" to account for changing stock volumes.

require(PortfolioEffectHFT)

symbol = "GOOG"
dateStart = "2014-10-13 09:30:00"
dateEnd = "2014-10-14 16:00:00"

# Create function of moving average
MA=function(x,order){
  result=x
  x1=c(0,x)
  result[(order):NROW(x)]=(cumsum(x1)[-(1:(order))]-cumsum(x1)[-((NROW(x1)-order+1):NROW(x1))])/order
  result[1:(order-1)]=cumsum(x[1:(order-1)])/(1:(order-1))
  return(result-0.0000000001)
}

highFrequencyPortfolio=portfolio_create(fromTime=dateStart,toTime=dateEnd)
lowFrequencyportfolio=portfolio_create(fromTime=dateStart,toTime=dateEnd)

position=position_add(highFrequencyPortfolio,symbol,1)
price=compute(price(position))[[1]]
printTime=price[,1]

highFrequencyStrategy=array(0,dim=NROW(price))
highFrequencyStrategy[price[,"value"]>MA(price[,"value"],150)]=100
lowFrequencyStrategy=array(0,dim=NROW(price))
lowFrequencyStrategy[price[,"value"]>MA(price[,"value"],800)]=100

# Add position GOOG to portfolios
positionHF=position_add(portfolio=highFrequencyPortfolio,symbol=symbol,quantity=highFrequencyStrategy,time=printTime)
positionLF=position_add(lowFrequencyportfolio,symbol=symbol,quantity=lowFrequencyStrategy,time=printTime)

# Display general information about the portfolio at the end of a dataset
print(highFrequencyPortfolio)
print(lowFrequencyportfolio)
plot(lowFrequencyportfolio)


Trading Portfolio Summary
symbol = 'GOOG';
dateStart = '2014-10-13 09:30:00';
dateEnd = '2014-10-14 16:00:00';
highFrequencyPortfolio=portfolio_create('fromTime',dateStart,'toTime',dateEnd);
lowFrequencyportfolio=portfolio_create('fromTime',dateStart,'toTime',dateEnd);

portfolio_addPosition(highFrequencyPortfolio,symbol,1);

goog=position_price(highFrequencyPortfolio,symbol);
printTime=goog(:,1);
googPrice=goog(:,2);

MA=150;
googHFMA=tsmovavg(googPrice','S',MA);
googHFMA(1:(MA-1))=rdivide(cumsum(googPrice(1:(MA-1)))',1:(MA-1));
MA=800;
googLFMA=tsmovavg(googPrice','S',MA);
googLFMA(1:(MA-1))=rdivide(cumsum(googPrice(1:(MA-1)))',1:(MA-1));
 
highFrequencyStrategy=zeros(length(googPrice),1);
highFrequencyStrategy(googPrice>=googHFMA')=100;
lowFrequencyStrategy=zeros(length(googPrice),1);
lowFrequencyStrategy(googPrice>=googLFMA')=100;

portfolio_addPosition(highFrequencyPortfolio,symbol,highFrequencyStrategy,'time',printTime);
portfolio_addPosition(lowFrequencyportfolio,symbol,lowFrequencyStrategy,'time',printTime);

highFrequencyPortfolio
lowFrequencyportfolio
plot(lowFrequencyportfolio)
Trading Portfolio Summary

Strategy Holding Periods

Let's plot corresponding holding periods for each intraday strategy.

plot1=util_ggplot(plot(quantity(positionHF),title="High Frequency Portfolio Strategy",line_size=0.6))
plot2=util_ggplot(plot(quantity(positionLF),title="Low Frequency Portfolio Strategy",line_size=0.6))
util_multiplot(plot1,plot2,cols=1)
Strategy Holding Periods
close
figure('position',[800 200 1000 700])
subplot(2,1,1);
util_plot2d([printTime,highFrequencyStrategy],'HF Quantity','Title','High Frequency Portfolio Strategy')
subplot(2,1,2);
util_plot2d([printTime,lowFrequencyStrategy],'LF Quantity','Title','Low Frequency Portfolio Strategy')
Strategy Holding Periods

Strategy Variance

As you can see, our low frequency trading portfolio has on average a higher return variance that its high frequency counterpart and therefore turns to be a more risky investment. PortfolioEffect Platform handles market microstructure noise effects and other HF anomalies, which could cause severe biases in traditional intraday variance estimates. The intraday bias could have particularly severe for the high frequency strategy that trades at intervals closer to the distances between actual stock market transactions.

plot(variance(highFrequencyPortfolio),variance(lowFrequencyportfolio),title="Variance, daily",legend=c("HF Portfolio","LF Portfolio"))
Strategy Return Variance (daily)
close
figure('position',[800 200 1000 700])
util_plot2d(portfolio_variance(highFrequencyPortfolio),'HF Portfolio','Title','Variance, daily')+...
util_line2d(portfolio_variance(lowFrequencyportfolio),'LF Portfolio')
Strategy Return Variance (daily)

Strategy Value-at-Risk

Strategy Value-at-Risk displays similar behavior as does the return variance. The 95% VaR is a more balanced measure of overall risk than return variance, as it acounts for tail events using high order moments (skewness, kurtosis) of return distribution.

plot(value_at_risk(highFrequencyPortfolio,0.95),value_at_risk(lowFrequencyportfolio,0.95),title="Value at Risk in %, daily (95% c.i.)",legend=c("HF Portfolio","LF Portfolio"))
Strategy Value-at-Risk (daily, @95% c.i.)
util_plot2d(portfolio_VaR(highFrequencyPortfolio,0.05),'HF Portfolio','Title','Value at Risk in %, daily (95% c.i.)')+...
util_line2d(portfolio_VaR(lowFrequencyportfolio,0.05),'LF Portfolio')
Strategy Value-at-Risk (daily, @95% c.i.)

Strategy Sharpe Ratio

We selected a classic Sharpe Ratio metric among many popular performance measures that are offered by the platform. Our high frequency trading strategy displays slightly higher Sharpe Ratio values during longer part of the day, though the difference is not very significant given a substantial overlap of holding periods in our example. However, you may easily extend this simple example to compare your own trading rules and portflios that cover multiple assets.

plot(sharpe_ratio(highFrequencyPortfolio),sharpe_ratio(lowFrequencyportfolio),title="Sharpe Ratio, daily",legend=c("HF Portfolio","LF Portfolio"))
Strategy Sharpe Ratio (daily)
util_plot2d(portfolio_sharpeRatio(highFrequencyPortfolio),'HF Portfolio','Title','Sharpe Ratio, daily')+...
util_line2d(portfolio_sharpeRatio(lowFrequencyportfolio),'LF Portfolio')
Strategy Sharpe Ratio (daily)