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

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

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

template<typename T, typename I = unsigned long>
using u_osc_v = UltimateOSCIVisitor<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 Ultimate Oscillator. 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 slow_roll items, in the result, will be NAN.

The Ultimate Oscillator is a technical indicator that was developed by Larry Williams in 1976 to measure the price momentum of an asset across multiple timeframes. By using the weighted average of three different timeframes the indicator has less volatility and fewer trade signals compared to other oscillators that rely on a single timeframe. Buy and sell signals are generated following divergences. The Ultimately Oscillator generates fewer divergence signals than other oscillators due to its multi-timeframe construction.
The indicator uses three timeframes in its calculation: 7, 14, and 28 periods.
The shorter timeframe has the most weight in the calculation, while the longer timeframe has the least weight.
Buy signals occur when there is bullish divergence, the divergence low is below 30 on the indicator, and the oscillator then rises above the divergence high.
A sell signal occurs when there is bearish divergence, the divergence high is above 70, and the oscillator then falls below the divergence low.
    explicit
    UltimateOSCIVisitor(std::size_t slow_roll = 28,
                        std::size_t fast_roll = 7,
                        std::size_t medium_roll = 14,
                        T slow_weight = 1.0,
                        T fast_weight = 4.0,
                        T medium_weight = 2.0);
        
T: Column data type
I: Index type
static void test_UltimateOSCIVisitor()  {

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

    typedef StdDataFrame<std::string> StrDataFrame;

    StrDataFrame    df;

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

        UltimateOSCIVisitor<double, std::string> uo_v;

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

        assert(uo_v.get_result().size() == 5031);
        assert(std::isnan(uo_v.get_result()[0]));
        assert(std::isnan(uo_v.get_result()[26]));
        assert(std::abs(uo_v.get_result()[27] - 41.3509) < 0.0001);
        assert(std::abs(uo_v.get_result()[31] - 32.1768) < 0.0001);
        assert(std::abs(uo_v.get_result()[5030] - 45.076) < 0.001);
        assert(std::abs(uo_v.get_result()[5026] - 31.3935) < 0.0001);
    }
    catch (const DataFrameError &ex)  {
        std::cout << ex.what() << std::endl;
    }
}
C++ DataFrame