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;  
       }  
     }  
   }  
 }  




No comments:

Post a Comment

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...