Back to Documentations

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

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

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

template<typename T, typename I = unsigned long,
         std::size_t A = 0>
using qqe_v = QuantQualEstimationVisitor<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.

The Quantitative Qualitative Estimation (QQE) indicator is an offspring from Wilder's famous Relative Strength Index (RSI). The base plot is an RSI smoothed over 5 periods supplemented by a signal line. The signal line is composed of a moving Average True Range (ATR). By smoothing the QQE and signal lines, the QQE becomes less sensitive to short term changes in volatility.
    explicit
    QuantQualEstimationVisitor(size_t avg_period = 14, size_t smooth_period = 5, double width_factor = 4.236);

    avg_period: RSI averaging period
    smooth_period: RSI smoothing period
    width_factor: QQE factor
        
get_result() returns the QQE vector. It has the same length as the input vectors
get_rsi_ma() returns the exponential moving average of RSI basis
get_long_line() returns Long signal when the RSI crosses the signal line to the upside
get_short_line() returns Short signal when the RSI crosses the signal line to the downside
T: Column data type
I: Index type
A: Memory alignment boundary for vectors. Default is system default alignment
static void test_QuantQualEstimationVisitor()  {

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

    typedef StdDataFrame64<std::string> StrDataFrame;

    StrDataFrame    df;

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

        qqe_v<double, std::string, 64>  qqe;

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

        assert(qqe.get_result().size() == 1721);
        assert(std::abs(qqe.get_result()[0] - 0) < 0.0001);
        assert(std::abs(qqe.get_result()[12] - 0) < 0.0001);
        assert(std::abs(qqe.get_result()[14] - 19.73) < 0.0001);
        assert(std::abs(qqe.get_result()[19] - 24.3886) < 0.0001);
        assert(std::abs(qqe.get_result()[20] - 24.7022) < 0.0001);
        assert(std::abs(qqe.get_result()[24] - 24.7022) < 0.0001);
        assert(std::abs(qqe.get_result()[25] - 25.7014) < 0.0001);
        assert(std::abs(qqe.get_result()[1720] - 45.3732) < 0.0001);
        assert(std::abs(qqe.get_result()[1712] - 50.833) < 0.0001);
        assert(std::abs(qqe.get_result()[1707] - 50.5242) < 0.0001);

        assert(qqe.get_rsi_ma().size() == 1721);
        assert(std::abs(qqe.get_rsi_ma()[0] - 0) < 0.0001);
        assert(std::abs(qqe.get_rsi_ma()[12] - 0) < 0.0001);
        assert(std::abs(qqe.get_rsi_ma()[14] - 24.4634) < 0.0001);
        assert(std::abs(qqe.get_rsi_ma()[19] - 36.0438) < 0.0001);
        assert(std::abs(qqe.get_rsi_ma()[20] - 36.8887) < 0.0001);
        assert(std::abs(qqe.get_rsi_ma()[24] - 36.867) < 0.0001);
        assert(std::abs(qqe.get_rsi_ma()[25] - 38.4642) < 0.0001);
        assert(std::abs(qqe.get_rsi_ma()[1720] - 42.5588) < 0.0001);
        assert(std::abs(qqe.get_rsi_ma()[1712] - 50.95) < 0.0001);
        assert(std::abs(qqe.get_rsi_ma()[1707] - 52.7244) < 0.0001);

        assert(qqe.get_long_line().size() == 1721);
        assert(std::abs(qqe.get_long_line()[0] - 0) < 0.0001);
        assert(std::abs(qqe.get_long_line()[12] - 0) < 0.0001);
        assert(std::abs(qqe.get_long_line()[14] - 19.73) < 0.0001);
        assert(std::abs(qqe.get_long_line()[19] - 24.3886) < 0.0001);
        assert(std::abs(qqe.get_long_line()[20] - 24.7022) < 0.0001);
        assert(std::abs(qqe.get_long_line()[24] - 24.7022) < 0.0001);
        assert(std::abs(qqe.get_long_line()[25] - 25.7014) < 0.0001);
        assert(std::abs(qqe.get_long_line()[1720] - 39.9557) < 0.0001);
        assert(std::abs(qqe.get_long_line()[1712] - 50.833) < 0.0001);
        assert(std::abs(qqe.get_long_line()[1707] - 50.5242) < 0.0001);

        assert(qqe.get_short_line().size() == 1721);
        assert(std::abs(qqe.get_short_line()[0] - 0) < 0.0001);
        assert(std::abs(qqe.get_short_line()[12] - 0) < 0.0001);
        assert(std::abs(qqe.get_short_line()[14] - 29.1968) < 0.0001);
        assert(std::abs(qqe.get_short_line()[19] - 37.2629) < 0.0001);
        assert(std::abs(qqe.get_short_line()[20] - 37.2629) < 0.0001);
        assert(std::abs(qqe.get_short_line()[24] - 37.2629) < 0.0001);
        assert(std::abs(qqe.get_short_line()[25] - 51.2269) < 0.0001);
        assert(std::abs(qqe.get_short_line()[1720] - 45.3732) < 0.0001);
        assert(std::abs(qqe.get_short_line()[1712] - 53.3534) < 0.0001);
        assert(std::abs(qqe.get_short_line()[1707] - 54.3629) < 0.0001);
    }
    catch (const DataFrameError &ex)  {
        std::cout << ex.what() << std::endl;
    }
}

C++ DataFrame