Tuesday, December 12, 2017

Creating your own CandleCode Genes

In the last post, I gave a run-down of the CandleCode format, which is used to express candlestick chart patterns in the Candlestick patterns extension.  A CandleCode is made up of a sequence of "genes" that describe a certain element of the underlying price, for example a long or short candle, or a white or black candle.  These "genes" are all .NET classes that inherit from the CandleGene base class, found in the Candlesticks.dll extension library.  You can build your own class library that contains new CandleCode genes.  As long as your class library DLL resides in the Quantacula Studio folder, the Candlestick Genetic Evolver will use your genes along with the basic set.

Using Volume in CandleCode

Let's build a gene that indicates whether the bar is light, medium, or heavy volume.  We can use a "V" as the gene's prefix, and then simply append a one character suffix to denote (L)ight, (M)edium, or (H)eavy volume.  To determine how heavy volume is, we'll compare the bar's volume to the 10 day average volume, and consider it light if it is half the average volume, and heavy if it is twice the average.

Our web articles describe how to build extensions for Quantacula Studio.  We'll follow the same format, and first create a .NET class library targeting the 4.6.2 .NET framework.  We need to add references to the following libraries:
  • QuantaculaCore
  • Candlesticks
  • QuantaculaIndicators (because we will use the SMA indicator class)
Next create a new class called VolumeStrength, and add the libraries mentioned above to its using section.  Make the VolumeStrength class derive from CandleGene.

Prefix

Override the Prefix property to return the string "V".

Code Property

CandleGenes have a string property called Code.  Use this property to store whatever you need as parameters for your gene.  Our VolumeStrength assigns one of three string values to the Code property.  "L" for light volume, "M" for medium volume, and "H" for heavy volume.

Mutate Method

In this method, mutate your gene by changing one aspect.  Our VolumeStrength gene has only a single parameter, so in our implementation we simply randomize the volume strength.  If your gene uses more than one parameter in its definition, change only one of them in the Mutate method.

RandomGene

Override this method to return a randomized instance of your gene.

IsPositive Method

In this method you test your gene on source data passed as an instance of the BarHistory class.  You're also supplied the index on which to test.  Return a true if the data at that point in the history satisfies your gene's condition.  In our implementation, we use the SMA to obtain the 10 bar average volume, and then compare the current volume with the average.  If the current volume is less than half the average volume, it is considered light, if it is twice the average, it is considered heavy.

Summary

With our new CandleGene in place we can launch the Candlestick Genetic Evolver and see is volume plays a role in identifying profitable patterns in our source data.  The scope of CandleCode genes is really unlimited, and if you come up with any useful genes please share your findings with the Quantacula Community!

Code
 using QuantaculaCore;  
 using QuantaculaIndicators;  
 namespace Candlesticks.CandleGenes  
 {  
   public class VolumeStrength : CandleGene  
   {  
     //Return the prefix of the gene  
     public override string PrefixCode  
     {  
       get  
       {  
         return "V";  
       }  
     }  
     //Return a random gene  
     public override CandleGene RandomGene  
     {  
       get  
       {  
         VolumeStrength vs = new VolumeStrength();  
         vs.RandomizeGeneCode();  
         return vs;  
       }  
     }  
     //Test the gene against source data  
     public override bool IsPositive(BarHistory bars, int idx)  
     {  
       if (idx < 9)  
         return false;  
       double vol = bars.Volume[idx];  
       double avgVol = SMA.Calculate(idx, bars.Volume, 10);  
       switch(Code)  
       {  
         case "L":  
           //light volume  
           return vol < avgVol * 0.5;  
         case "M":  
           //medium volume  
           return vol >= avgVol * 0.5 && vol <= avgVol * 2.0;  
         default:  
           //heavy volume  
           return vol > avgVol * 2.0;  
       }  
     }  
     //mutate the gene (randomize its value)  
     public override void Mutate()  
     {  
       string oldCode = Code;  
       do  
       {  
         RandomizeGeneCode();  
       }  
       while (Code == oldCode);  
     }  
     //private members  
     private void RandomizeGeneCode()  
     {  
       int n = RNG.Next(3);  
       switch (n)  
       {  
         case 0:  
           Code = "L";  
           break;  
         case 1:  
           Code = "M";  
           break;  
         case 2:  
           Code = "H";  
           break;  
       }  
     }  
   }  
 }  




Wednesday, November 29, 2017

Delving into the CandleCode

In this post I'm going to delve into the guts of the most complex (to date) extension for Quantacula, the Candlestick Patterns extension.  Read the linked article first if you're not familiar with the Candlestick extension.  Alright, now that you're an expert, let's delve deeper into the extension to uncover all of the advanced goodies.

CandleCodes

The extension expresses candlestick patterns in the form of text based codes.  The format of a CandleCode is:

CODE:PARAMETER

Patterns that require more than one code to describe them have their CandleCodes separated by periods.  For example, the Bearish Long Black Line is composed of two CandleCodes:

BL:L.BC:B

If a pattern requires more than one bar to describe, each set of CandleCodes is separated by a comma.  For example, here is the two bar code that expresses the Bearish Engulfing pattern:

BL:S.BC:W,BC:B.ENG:1

If you know all of the codes, you can actually compose candlestick patterns by hand, like I did when I populated the pattern library with all of the patterns we're familiar with.  In fact, if you right click on the Pattern Library list in the Candlestick Genetic Evolver tool, you'll see a popup menu item that lets you "Add a new Pattern Manually ..."

Here is a roster of the currently available CandleCodes.

Body Color
BC:W = white body, BC:B = black body

Body Length
BL:L = long body, BL:S = short body

Contained Within
CON:nB = contained within the candle "n" bars ago's body, CON:nR = contained within the candle "n" bars ago's hull range.  

Engulfs
ENG:n = engulfs the bar n bars back.

Gap at Open
GAP:+ = gap up at open, GAP:- = gap down at open.  A gap up at open occurs when the market opens above the previous bar's high.  A gap down at open occurs when it opens below the previous low.

Price Comparison
P:c1?c2
Compares two price components of the candle.  Replace c1 and c2 with one of the following codes:
O = open
H = high
L = low
C = close
T = top of body
B = bottom of body
M = midpoint of body
Replace the ? with one of the following operands:
=
>
<
n = near
f = far

Indexed Price Comparison
P-:nC1?c2
Like above, but compares a price of the current candle with a price from the candle n bars ago.

Range Length
RL:L = long ranged candle, RL:S = short ranged candle

Shadow Length
SL:+L = long upper shadow, SL:+S = short upper shadow, SL:-L = long lower shadow, SL:-S = short lower shadow

You now know how to construct a candlestick pattern by hand and add it to your Candlestick extension pattern library.  In the next part of this article we'll show you how to develop your own CandleCode extensions that can work seamlessly with the extension!  This feature opens up the Genetic Evolver to numerous new possibilities ripe for exploration.

Monday, November 27, 2017

Quandl Extension


The free Quandl extension for Quantacula Studio allows you to consume historical data from the vast array of sources available at Quandl.com. Quandl is a hub of data offered by numerous individual providers, organized into Databases and Datasets. A Database represents a set of data from a specific provider. For example, Quandl offers a Database called WIKI which contains historical end-of-day stock market data curated by its community. Each Database contains Datasets which represent the individual components, analogous to symbols in Quantacula. For example, in the WIKI Database there are Datasets called AAPL and MSFT which represent the individual stocks.

API Key

To access the Quandl data, you first need to create an account at Quandl.com and obtain an API Key. The API Key is required whether you are accessing the free Databases, or the premium Databases.

Creating the Quandl Data Source

After you obtain an API Key, create a New Data Source in Quantacula Studio and select Quandl as the provider. Press the Configure button, and enter your API Key in the field provided.


Quandl Symbology

When specifying symbols in Quantacula Studio, use the convention Database/Dataset. For example, to access data for the stock FB in the free WIKI Database, use the symbol WIKI/FB.

When you configure the Quandl Data Source, you can establish a default Database. If you do not specify the Database in the symbol, the Quandl extension will use the default Database. If you configured the Data Source to use WIKI as the default Database, you could obtain historical data for FB by simply using FB as the symbol.

Quandl Indicator

The extension also includes a Quandl indicator. When you use the indicator, you specify the Database and Dataset as parameters, and the indicator attempts to retrieve the data from Quandl using the "Value" field, if available. You can now use any of Quandl's indicators in your building block models. In the example below, we chart the Natural Rate of Unemployment Short Term (NROUST) from the Federal Reserve Economic Data (FRED) Database, on a monthly chart.



Support

With the sheer array of data available at Quandl, you may run into issues trying to access a particular Database that we have not yet exercised in our extension. Please report any issues to us via email or the Community forums. We will work to enhance the extension to handle the Quandl data that you want to access.

Sunday, November 19, 2017

Using Static Variables

In the last article we talked about the five points where you can hook into the Quantacula backtest process in your C# coded models.  We saw that the backtester first calls BacktestBegin, on the first symbol in your universe, followed by Initialize for every symbol in the universe.  You might be wondering the purpose of BeginBacktest.  Can't we just perform model initialization in the Initialize method?

True, you should perform your model initialization in the Initialize method, including creating the instances of any indicators you will be using in your logic.  The BacktestBegin method is intended to be used for overall initialization, and static variables are a perfect example of when this method will come in handy.

Static Variables

Static variables exist on the .NET class level, rather than the instance level, so they are available to all instances of a class.  You can use static variables in your models to track meta-information during a backtest run.

Consider the model below, which implements a method of determine the "edge" of a technical indicator that I discussed in my Market Glitch YouTube channel.



The model uses static variables to count the number of observations (bars) in the entire universe of data, as well as the sum of the percentage return after 5 bars, and the same for cases where the RSI indicator is oversold.  It uses the BacktestBegin to initialize the static variables to zero.  Then, it uses the Initialize method (which executes once for each symbol in the backtest) to process the history and add values to the static variables.  By the time the Cleanup method hits, the static variables are fully loaded with values for all of the symbols in the universe.

I decided to implement the code that renders the information onto the chart in the Cleanup method rather than the BacktestComplete method.  This is because Cleanup executes for every symbol in the universe, and therefore my plotted text will be visible no matter what symbol I chart.  Had I coded this in the BacktestComplete, the text would only be visible if I chart the last symbol in the universe.  The time to implement BacktestComplete is when you want to do something like save the summary information to a file or other persistent storage.

Summary

We saw here how static variables can be very useful in model processing, to accumulate aggregate information for all of the symbols in the universe.  Judicious use of the BacktestBegin, Initialize, and Cleanup are all you need to implement this kind of meta analysis.


Saturday, November 18, 2017

Backtester Flow

When you create a C# Coded Model in Quantacula, you're creating a new .NET class derived from the UserModelBase base class.  Here we'll delve into how Quantacula interacts with your model during the backtesting process.  The diagram below breaks down the backtesting process into two domains, the Backtester and your UserModelBase.  The items in UserModelBase represent the five virtual methods you can override in your model's code to hook into the different stages of the backtesting process.

Initial Processing

The Quantacula backtester begins the process by calling the BeginBacktest method in your model.  This method is optional, but if you did provide an implementation, you should note that it will only be called once, for the first symbol in your backtest universe.  This method provides you a place to initialize static variables, or perform other operations that you need to undertake one time before the backtest begins.

After calling BeginBacktest, Quantacula calls the Initialize method in your model, once for every symbol in the backtest universe.  As described in the Quantacula help, this is where you should create the instances of any indicators or other objects you declared in your model.  By this point you might begin to realize, Quantacula actually creates a new instance of your model's class for every symbol in the backtest.

Bar by Bar Processing

Quantacula then creates a synchronization object that is responsible for keeping the historical data in the backtest universe aligned during the bar by bar processing.  For each bar of historical data, the synchronizer collects a list of symbols (participants) that have data for the bar currently being processed.

The per-bar processing begins by performing a market open processing.  This executes any simulated orders that were placed on the previous bar, and updating the equity and cash levels.

After processing the market open, the backtester iterates through this bar's participating symbols, and calls the Execute method in your model for each one of them.  It is within your implementation of the Execute method that simulated trades are placed, via calls to the PlaceTrade method.

After executing your model for each participant, the backtester perform a market close processing.  This checks to see if symbols are dropped out of dynamic universes, such as the Wealth-Data Dow 30 or Nasdaq 100, and if so, it closes any open positions in those symbols at market close.  The market close processing also updates the equity curve to reflect the current values of open positions.

Post-Processing

The backtester continues the bar-by-bar processing until there is no more historical data left to process.  After this stage, it calls the Cleanup method in your model, for each of the symbols in the backtest universe.

Finally, Quantacula calls the BacktestComplete method.  If you override this method, note that it will be called only on the last symbol in the backtest universe.  Here you can process any summary information you might have collected during the backtest process.

In a future post we'll see how these pieces come together and implement a model that collects performance statistics on an indicator, over all of the symbols in the backtest universe.

Crypto Rotation Model

In a previous post I published results of an analysis I performed on oversold technical oscillators.  I ran this test on the historical dat...