Using pointers to struct members in template functions

 

After encountering a need to implement functional analysis indicators, I’ve encountered a problem: I have two structures which I am actively using to store market data (simplified version is given here):

Candle is used to store the market data for each period of time (for example, every 30 minutes):


struct Candle
{
    double open;
    double close;
    double high;
    double low;
};

 

RangeBar is used to focus only on price fluctuations, it has constant height (therefore we do not need to know the open price and store the height separately: it is usually stored as a system constant)


struct RangeBar
{
    double close;
    bool is_rising;
};

 

What should be done if I want to calculate Simple Moving Average(or simply SMA) value of 20 consequtive candle high or open prices? What if I want to calculate RangeBar close prices? Should I declare 3 functions for every one of them?

One of the possible solutions would be to implement a common class for both RangeBar and Candle, which has virtual Getter methods. However, a colleague of mine has suggested an alternative, much more elgant solution, using C++ templates with pointers to struct members as a template arguments.

Therefore, an SMA function will look like this:


template <typename T, double T::*member> double SMA(T* values, size_t length)
{
    double sum = 0;
    for (size_t i = 0; i < length; i++)
    {
        sum += values[i].*member; //make sure to dereference the member pointer
    }
    return sum / length;
}

 

Then, when I want to calculate the SMA, I just need to call the function with correct parameters. For example:


    double sma_close_range_bars = SMA<RangeBar, &RangeBar::close>(bars, bar_amount);
    double sma_high_candles = SMA<Candle, &Candle::high>(candles, candle_amount);
    double sma_low_candles = SMA<Candle, &Candle::low>(candles, candle_amount);

 

Voila. Now we have a universal solution for this type of problems.

Simple range bar pattern search, C++

To create a working trade algorithms, it is essential to perform the evaluation of gathered forex tick data. One of the way to do that is to transform the data into range bar format

The simplest way to do that would be to check the bar patterns in definite range and look for statistical discrepancies in them which we will be able to abuse: for example, if we have 3 range bars that go up consecutively, the fourth bar also goes up in 75% of the cases.

The minimal range bar representation in C++ would be the following: store only open and close prices.


struct RangeBar
{
    double open;
    double close;
};

Then, for the simplicity of it, you can also define the structure to store the pattern results (we will get to it a bit later):


struct PatternStats
{
    int ups;
    int downs;
};

In my project, for the sake of simplicity, I have made a class (which inherits some stuff from the other parent class) that gathers pattern statistics, but I will only describe the algorithm here:

First step, initialization:



/*
 * First, we decide how many bars will be analyzed for the patterns (bar amount). 
 * My standard options are anywhere from 3 to 7 bars.
 * Then, we initialize the stats array for each possible 
 * pattern and set the current statistics to zero
 * 1 << bar_amount is effectively the same as 2^bar_amount, 
 * so for 2 bars it will be 4 (up-up, up-down, down-up, down-down), 
 * 3 bars it will be 8, for 4 it will be 16, etc.
 * Each pattern will be a set of zeroes and ones, 
 * 1 stands for ascending, and 0 - for descending bar
 * So, for example, to change the pattern up-up stats, 
 * we will be accessing the stats[3] (00000011)
 */

    stats = new PatternStats[1 << bar_amount];
    for (int i = 0; i < pattern_amount; i++)
    {
        stats[i].downs = 0;
        stats[i].ups = 0;
    }

After that, you just go through all range bars you have and process every bar_amount of them:


    /* go through all bars, but no further than
    /* total_bar_amount - bar_amount (this amount you will go forward) - 1 (result)*/
    for (int bar = 0; bar < total_bar_amount - bar_amount - 1; bar++)
    {
        /* go through bar_amount bars to distinguish the current pattern */
        int pattern = 0;
        for (int i = 0; i < bar_param_amount; i++)
        {
            //1 - raising bar, 0 - dropping bar
            /* (if open is lower than close, we have an ascending bar) - true
             * which is evaluated as 1, or false, which is evaluated as zero
             * then we move it by i bits and get the pattern bit
             * so if the first bar was zero, and the second bar was 1,
             * we get 00000010
             */
            pattern += (bars[bar + i].open < bars[bar + i].close) << (i);         
        }
        /* 
         * after the pattern is formed, we check if the next bar is ascending
         * or descending and increase the statistics accordingly          
         */
        if (bars[bar + bar_param_amount].close > bars[bar + bar_param_amount].open)
        {
            stats[pattern].ups++;
        }
        else
        {
            stats[pattern].downs++;
        }
    }

That is all. After you get the statistics, just see if there are any patterns that go up significantly more than down (or vice versa). Of course, it probably won’t be enough to make a successful EA, but it’s a start that can give some clarity.

C++ XML Reader

After stumbling upon a need for multiple configurations for my hobby C++ forex trading bot development, I’ve decided to implement simple xml config files.

As of now, I did not need anything fancy: just the ability to read simple xml format with login and password settings (with the possibility to extend it further with configurable settings for traded currencies):

<config>
  <credentials>
    <login>MyLogin</login>
    <password>MyPassword</password>
  </credentials>
</config>

The pugixml library has really been a pleasant surprise with that: having only three source files (two of which are headers), it can easily be compiled as a static lib or simply included into the project. As for reading the above values, it is really simple:

   
    pugi::xml_parse_result result = doc.load_file(filename);
    if (result)
    {
        is_loaded = true;
        pugi::xml_node root = doc.child("config");

        username = root.child("credentials").child_value("login");
        password = root.child("credentials").child_value("password");
    }
    else
    {
        printf("Error while loading file: %s\n", result.description());
    }

Overall, I’ll continue to use this solution.