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

template<typename T, typename I = unsigned long>
struct ChandeKrollStopVisitor;

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

template<typename T, typename I = unsigned long>
using cksp_v = ChandeKrollStopVisitor<T, I>;
        
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 the rolling values of Chande/Kroll trading indicator. It requires 3 input columns in the order of low, high, close.
The result() method returns the long stop indicator. The first q_period elements of all results are NaN.

The Chande Kroll Stop indicator is a stop for either a short or long position. It presents itself as a red and green (sometimes blue) line that is overlaid on the price chart. The red line represents the stop level for a short position, whereas the green line represents the stop level for a long position. The Chande Kroll Stop is calculated on the true range and therefore is labeled as independent from the volatility of the instruments involved.

There are 3 other methods:
    get_result()      // It returns the long stop
    get_long_stop()   // It returns the long stop
    get_short_stop()  // It returns the short stop
        
    explicit
    ChandeKrollStopVisitor(size_t p_period = 10,
                           size_t q_period = 20,
                           T multiplier = 3);

    p_period: Rolling period to apply to min/max of lows/highs
    q_period: Rolling period to apply to short/long stops
    multiplier: Multiplier of average true range
        
T: Column data type
I: Index type
static void test_ChandeKrollStopVisitor()  {

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

    typedef StdDataFrame<std::string> StrDataFrame;

    StrDataFrame    df;

    try  {
        df.read("data/SHORT_IBM.csv", io_format::csv2);

        cksp_v<double, std::string>  cksp;

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

        assert(cksp.get_result().size() == 1721);
        assert(std::isnan(cksp.get_long_stop()[0]));
        assert(std::isnan(cksp.get_long_stop()[18]));
        assert(std::abs(cksp.get_long_stop()[20] - 182.5875) < 0.0001);
        assert(std::abs(cksp.get_long_stop()[25] - 182.5875) < 0.0001);
        assert(std::abs(cksp.get_long_stop()[35] - 182.5875) < 0.0001);
        assert(std::abs(cksp.get_long_stop()[1720] - 127.2591) < 0.0001);
        assert(std::abs(cksp.get_long_stop()[1712] - 127.2591) < 0.0001);
        assert(std::abs(cksp.get_long_stop()[1707] - 124.5657) < 0.0001);

        assert(cksp.get_short_stop().size() == 1721);
        assert(std::isnan(cksp.get_short_stop()[0]));
        assert(std::isnan(cksp.get_short_stop()[18]));
        assert(std::abs(cksp.get_short_stop()[20] - 192.6438) < 0.0001);
        assert(std::abs(cksp.get_short_stop()[25] - 192.6438) < 0.0001);
        assert(std::abs(cksp.get_short_stop()[35] - 187.8592) < 0.0001);
        assert(std::abs(cksp.get_short_stop()[1720] - 131.7065) < 0.0001);
        assert(std::abs(cksp.get_short_stop()[1712] - 131.7065) < 0.0001);
        assert(std::abs(cksp.get_short_stop()[1707] - 131.7065) < 0.0001);
    }
    catch (const DataFrameError &ex)  {
        std::cout << ex.what() << std::endl;
    }
}
C++ DataFrame