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

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

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

template<typename T, typename I = unsigned long>
using ess_v = EhlerSuperSmootherVisitor<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 Ehler's Super Smoother Filter (SSF) indicator.
The result is a vector of values with same number of items as the given column.

The Ehlers' Super Smoother Filter is a smoothing technique developed by John F. Ehlers, based on aerospace analog filters. This filter aims at reducing noise in price data, which appears to be stronger as the high-to-low price swings increase especially when chart is plotted for greater time intervals. In theory, this filter eliminates the noise completely, as opposed to moving averages, e.g., exponential (EMA) which only offers a modest attenuation effect.

    explicit
    EhlerSuperSmootherVisitor(std::size_t poles = 2,  // poles could only be 2 or 3
                              std::size_t bar_period = 10);
        
T: Column data type
I: Index type
static void test_EhlerSuperSmootherVisitor()  {

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

    typedef StdDataFrame<std::string> StrDataFrame;

    StrDataFrame    df;

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

        EhlerSuperSmootherVisitor<double, std::string>  ssf_v2;    // poles = 2
        EhlerSuperSmootherVisitor<double, std::string>  ssf_v3(3); // poles = 3

        df.single_act_visit<double>("IBM_Close", ssf_v2);
        df.single_act_visit<double>("IBM_Close", ssf_v3);

        assert(ssf_v2.get_result().size() == 1721);
        assert(ssf_v3.get_result().size() == 1721);

        assert(std::abs(ssf_v2.get_result()[0] - 185.53) < 0.01);
        assert(std::abs(ssf_v2.get_result()[5] - 188.117) < 0.001);
        assert(std::abs(ssf_v2.get_result()[14] - 185.497) < 0.001);
        assert(std::abs(ssf_v2.get_result()[25] - 174.736) < 0.001);
        assert(std::abs(ssf_v2.get_result()[1720] - 109.294) < 0.001);
        assert(std::abs(ssf_v2.get_result()[1712] - 123.43) < 0.01);
        assert(std::abs(ssf_v2.get_result()[1707] - 127.323) < 0.001);

        assert(std::abs(ssf_v3.get_result()[0] - 185.53) < 0.01);
        assert(std::abs(ssf_v3.get_result()[5] - 186.159) < 0.001);
        assert(std::abs(ssf_v3.get_result()[14] - 186.681) < 0.001);
        assert(std::abs(ssf_v3.get_result()[25] - 174.294) < 0.001);
        assert(std::abs(ssf_v3.get_result()[1720] - 109.187) < 0.001);
        assert(std::abs(ssf_v3.get_result()[1712] - 124.31) < 0.01);
        assert(std::abs(ssf_v3.get_result()[1707] - 127.603) < 0.001);

    }
    catch (const DataFrameError &ex)  {
        std::cout << ex.what() << std::endl;
    }
}
C++ DataFrame