← Back to Documentations

Signature Description Parameters
#include <DataFrame/DataFrameFinancialVisitors.h>

template<typename T, typename I = unsigned long,
         std::size_t A = 0>
struct DonchianChannelsVisitor;

// -------------------------------------

template<typename T, typename I = unsigned long,
         std::size_t A = 0>
using donchian_v = DonchianChannelsVisitor<T, I, A>;
This is a “single action visitor”, meaning it is passed the whole data vector in one call and you must use the single_act_visit() interface.

This visitor calculates Donchian Channels, a band indicator that wraps the price in the range it has recently traded. It requires 2 input columns in the order of low, high.
It produces three bands:
Upper band: the highest high over the last period bars, including the current bar.
Lower band: the lowest low over the last period bars, including the current bar.
Middle band: the average of the upper and lower bands.

get_result() and get_upper_band() return the upper band.
get_lower_band() returns the lower band.
get_middle_band() returns the middle band.
All results are vectors with the same number of items as the given columns. The first period - 1 items of every result are NaN.
explicit
DonchianChannelsVisitor(size_type period = 20);

period: Rolling window over which the highest high and lowest low are found.
        It must be greater than 0 and no larger than the column size.
        
T: Column data type
I: Index type
A: Memory alignment boundary for vectors. Default is system default alignment
static void test_DonchianChannelsVisitor()  {

    std::cout << "\nTesting DonchianChannelsVisitor{ } ..." << std::endl;

    StrDataFrame    df;

    try  {
        df.read("IBM.csv", io_format::csv2);
    }
    catch (const DataFrameError &ex)  {
        std::cout << ex.what() << std::endl;
        ::exit(-1);
    }

    donchian_v<double, std::string> donc;

    df.single_act_visit<double, double>("IBM_Low", "IBM_High", donc);

    // Same as calling get_upper_band()
    //
    assert(donc.get_result().size() == 5031);
    assert(std::isnan(donc.get_result()[0]));
    assert(std::isnan(donc.get_result()[18]));
    assert(std::abs(donc.get_result()[19] - 104.375) < 0.001);
    assert(std::abs(donc.get_result()[30] - 104.75) < 0.001);
    assert(std::abs(donc.get_result()[40] - 104.75) < 0.001);
    assert(std::abs(donc.get_result()[51] - 99.75) < 0.001);
    assert(std::abs(donc.get_result()[101] - 108.4) < 0.001);
    assert(std::abs(donc.get_result()[5022] - 135.5) < 0.001);
    assert(std::abs(donc.get_result()[5029] - 135.5) < 0.001);
    assert(std::abs(donc.get_result()[5030] - 135.5) < 0.001);

    assert(donc.get_lower_band().size() == 5031);
    assert(std::isnan(donc.get_lower_band()[0]));
    assert(std::isnan(donc.get_lower_band()[18]));
    assert(std::abs(donc.get_lower_band()[19] - 91.625) < 0.001);
    assert(std::abs(donc.get_lower_band()[30] - 90.6875) < 0.0001);
    assert(std::abs(donc.get_lower_band()[40] - 80.0625) < 0.0001);
    assert(std::abs(donc.get_lower_band()[51] - 80.0625) < 0.0001);
    assert(std::abs(donc.get_lower_band()[101] - 87.65) < 0.001);
    assert(std::abs(donc.get_lower_band()[5022] - 116.48) < 0.001);
    assert(std::abs(donc.get_lower_band()[5029] - 105.92) < 0.001);
    assert(std::abs(donc.get_lower_band()[5030] - 105.92) < 0.001);

    assert(donc.get_middle_band().size() == 5031);
    assert(std::isnan(donc.get_middle_band()[0]));
    assert(std::isnan(donc.get_middle_band()[18]));
    assert(std::abs(donc.get_middle_band()[19] - 98.0) < 0.001);
    assert(std::abs(donc.get_middle_band()[30] - 97.7188) < 0.0001);
    assert(std::abs(donc.get_middle_band()[40] - 92.4062) < 0.0001);
    assert(std::abs(donc.get_middle_band()[51] - 89.9062) < 0.0001);
    assert(std::abs(donc.get_middle_band()[101] - 98.025) < 0.001);
    assert(std::abs(donc.get_middle_band()[5022] - 125.99) < 0.01);
    assert(std::abs(donc.get_middle_band()[5029] - 120.71) < 0.001);
    assert(std::abs(donc.get_middle_band()[5030] - 120.71) < 0.001);
}

C++ DataFrame