Your interactive trading laboratory!
 • 
7 users online

Quantacula Help

How-To
C# API Reference
Extensions
Development Blog
API-Extensions

QCommunity Extensions
The open-source GitHub repository of source code for the QCommunity Extensions library. Contains indicators and other extensions submitted by the Quantacula Community. Look for QCommunity indicators when you create a Building Block model, mark the "QCommunity" library check box to expose them.

TASC-Extensions
The open-source GitHub repository of source code for the TASCExtensions Quantacula extension. Contains indicators and other extensions adapted from the Traders' Tips articles in Technical Analysis of Stocks & Commodities magazine.
How to use MarketClose Orders
Published by Q Glitch on 1/6/2019

As of Quantacula Studio Q167, released 12/28/2018, we added a new simulated order type to the backtester: MarketClose. While we can now simulate models that close their positions at market close, there are a few considerations to keep in mind, and a few things to understand, before using the new order type.

How Quantacula Simulates Trades

The Quantacula framework is based an a .NET class called UserModelBase which provides numerous properties and methods related to backtesting. Even if you're using the Building Block Model Builder, Quantacula converts your building blocks into .NET code so it's still valuable to understand the following concept. Trades are placed by calling the PlaceTrade method, which looks something like this:

Transaction t = PlaceTrade(bars, TransactionType.Sell, OrderType.Market);

The above example illustrates a market sell order. You might have this code execute on some condition(s) based on technical indicators or chart patterns. Whatever the criteria, Quantacula assume you are placing the trade after the completion of the current bar of data being processed. At this point, technical indicators can be properly calculated and analyzed. Quantacula will then queue the transaction for simulated "fill" on the following bar at market open.

The MarketClose Wrinkle

Trying to simulate a trade at market close poses a problem, because it goes against the assumption of the backtester, which is: analyze the data for the completed bar, and queue the transaction for the following bar. In order to get models using MarketClose to work the way we want, we need to change the code in our model to peek into the future one bar, and then submit the MarketClose order based on the next bar's data.

Let's take a classic 4x2 system, adapted from James Altucher's book Trade Like a Hedge Fund. The system buys after 4 consecutive down days, and sells after 2 consecutive up days. The following code uses Market orders to enter and exit the next bar at market open the day after the signal.

using QuantaculaBacktest;
using QuantaculaCore;
using QuantaculaIndicators;

namespace Quantacula
{
    public class MyModel : UserModelBase
    {
        //create indicators and other objects here, this is executed prior to the main trading loop
        public override void Initialize(BarHistory bars)
        {
		cd = new ConsecDown(bars.Close, 1);
		cu = new ConsecUp(bars.Close, 1);
		PlotIndicator(cd);
		PlotIndicator(cu);
        }

        //execute the strategy rules here, this is executed once for each bar in the backtest history
        public override void Execute(BarHistory bars, int idx)
        {
		if (!HasOpenPosition(bars, PositionType.Long))
		{
			//4 consecutive down days
			if (cd[idx] == 4)
				PlaceTrade(bars, TransactionType.Buy, OrderType.Market);
		}
		else
		{
			//2 consecutive up days
			if (cu[idx] == 2)
				PlaceTrade(bars, TransactionType.Sell, OrderType.Market);
		}
        }

	//declare private variables below
	ConsecDown cd;
	ConsecUp cu;
    }
}

Backtesting the model on the Nasdaq 100 stocks using the QPremium Universe (which eliminates the risk of survivorship bias) with a 10% of equity position size resulted in a net profit of 150% and an APR of 9.62%.

4x2 Market

Let's try modeling the system to execute at market close of the signal bar. In order to do this we need to change a few things in the Execute method:

  1. Use an OrderType of MarketClose instead of Market
  2. Examine the consecutive up and down bars 1 day "into the future" by changing the index to idx + 1
  3. Don't process the last bar of data, since there is no future bar after it to examine

The result will be that the backtester still queues the transaction for a simulated fill on the following bar, but since we're actually analyzing the data for the following bar, we can simulate tracking the prices throughout the day and placing the order at market close as conditions dictate.

Here's the code for the modified Execute method.

        //execute the strategy rules here, this is executed once for each bar in the backtest history
        public override void Execute(BarHistory bars, int idx)
        {
		//we can't examine a future bar if it's the last bar
	        if (idx == bars.Count - 1)
			return;
	        
		if (!HasOpenPosition(bars, PositionType.Long))
            	{
                	if (cd[idx + 1] == 4)
				PlaceTrade(bars, TransactionType.Buy, OrderType.MarketClose);
            	}
            	else
            	{
                	if (cu[idx + 1] == 2)
				PlaceTrade(bars, TransactionType.Sell, OrderType.MarketClose);
            	}
        }

Interestingly, running the same backtest resulted in a more profitable result, net profit of 198% with an APR of 11.55%. This is only one backtest, but the results are encouraging and make me feel that more MarketClose analysis is warranted.

4x2 MarketClose

Use with Caution

There are a few considerations when trading at MarketClose. Obviously, you'll somehow need to run the model based on a partial bar of data, probably a few minutes prior to market close, in order to determine what trades need to be acted upon. The further back you push this analysis from actual market close, the more likely you are to run into distortions as the market prices change within the last few minutes of action.

Additionally, Quantacula won't produce signals for models using this type of coding, since we are not processing the last bar of data. The results we see above are theoretical, but will be a challenge to put into action in a trading plan.

A possible solution would be a new component that could, on-demand, download the day's partial bar of data, and construct a new BarHistory of the current data, with the partial bar appended to the end. During the model's last bar processing, it could invoke this component to generate any required indicators, and issue PlaceTrade as needed. This would result in actual signals that could be acted upon in Quantacula Studio. Since they would be MarketClose signals, the Signal Hub would hold them until 1 minute before market close for execution.

This "missing link" component would make it possible to trade MarketClose orders relatively easily, and we could develop this if there's sufficient demand.