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

template<typename T, typename I = unsigned long>
struct CCIVisitor;
        
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 Commodity Channel Index (CCI). It requires 3 input columns in the order of low, high, close.
The result is a vector of values with same number of items as the given columns. The first roll_count items, in the result, will be NAN.

Developed by Donald Lambert and featured in Commodities magazine in 1980, the Commodity Channel Index (CCI) is a versatile indicator that can be used to identify a new trend or warn of extreme conditions. Lambert originally developed CCI to identify cyclical turns in commodities, but the indicator can be successfully applied to indices, ETFs, stocks and other securities. In general, CCI measures the current price level relative to an average price level over a given period of time. CCI is relatively high when prices are far above their average, but is relatively low when prices are far below their average. In this manner, CCI can be used to identify overbought and oversold levels.
    explicit
    CCIVisitor(std::size_t roll_count = 14,
               T lambert_const = 0.015);
        
T: Column data type
I: Index type
static void test_CCIVisitor()  {

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

    typedef StdDataFrame<std::string> StrDataFrame;

    StrDataFrame    df;

    try  {
        df.read("IBM.csv", io_format::csv2);

        CCIVisitor<double, std::string> cci_v;

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

        assert(cci_v.get_result().size() == 5031);
        assert(std::isnan(cci_v.get_result()[0]));
        assert(std::isnan(cci_v.get_result()[12]));
        assert(std::abs(cci_v.get_result()[14] - 30.3681) < 0.0001);
        assert(std::abs(cci_v.get_result()[20] - -178.37) < 0.001);
        assert(std::abs(cci_v.get_result()[5030] - -77.4585) < 0.0001);
        assert(std::abs(cci_v.get_result()[5026] - -127.358) < 0.001);
    }
    catch (const DataFrameError &ex)  {
        std::cout << ex.what() << std::endl;
    }
}