← Back to Documentations

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

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

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

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

Ichimoku Cloud (Ichimoku Kinko Hyo) is a multi-component indicator that shows trend direction, momentum and support/resistance together. It has five lines. Two of them form a shaded area, the “cloud” (kumo), projected ahead of price. It requires 3 input columns, in the order low, high, close. This is a “single action visitor”: use single_act_visit().

The five components:
Each of the first three is the midpoint of the highest high and lowest low over a window.
Tenkan-sen (conversion line): window of tenkan_period bars (default 9). It is fast and reacts quickly.
Kijun-sen (base line): window of kijun_period bars (default 26). It is slower and acts as a medium-term equilibrium level.
Senkou span B: window of senkou_b_period bars (default 52), plotted displacement bars ahead.
Senkou span A: the average of tenkan-sen and kijun-sen, plotted displacement bars ahead (default 26).
Chikou span (lagging span): the close, plotted displacement bars behind.

The area between span A and span B is the cloud.

When to use it:
Trend. Price above the cloud is a bullish regime, price below is bearish, and price inside the cloud is neutral or transitioning.
Support and resistance. The cloud’s edges and the kijun-sen act as levels. A thicker cloud means stronger support or resistance, and a thin cloud means weak.
Signals. Tenkan-sen crossing kijun-sen is the classic momentum signal. It is stronger when it happens on the trend’s side of the cloud. Span A crossing span B marks a cloud color change.
Confirmation. The chikou span being above (below) the price from displacement bars earlier confirms a bullish (bearish) move.
Suitable data. It is meant for trending markets and daily or higher bar frequencies. In sideways markets the lines intertwine and the cloud goes flat.
Parameters. The defaults are the traditional values, historically tied to the Japanese trading week. Many practitioners adjust them for other markets or bar frequencies.

get_result() and get_tenkan_sen(): Return the conversion line.
get_kijun_sen(): Returns the base line.
get_senkou_span_a() and get_senkou_span_b(): Return the cloud edges, aligned to the bar they are plotted under. The value at bar i was computed from bars up to i - displacement, so it is known at bar i and has no look-ahead. Bullish cloud: span_a[i] > span_b[i]. Price above the cloud: close[i] > max(span_a[i], span_b[i]). The cloud’s projection beyond the last input bar is not returned.
get_chikou_span(): chikou[i] = close[i + displacement].
explicit
IchimokuVisitor(size_type tenkan_period = 9,
                size_type kijun_period = 26,
                size_type senkou_b_period = 52,
                size_type displacement = 26);
        
T: Column data type
I: Index type
A: Memory alignment boundary for vectors. Default is system default alignment
static void test_IchimokuVisitor()  {

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

    StrDataFrame    df;

    try  {
        df.read("IBM.csv", io_format::csv2);
    }
    catch (const DataFrameError &ex)  {
        std::cout << ex.what() << std::endl;
        ::exit(-1);
    }

    ichimoku_v<double, std::string> ich;

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

    // Same as calling get_tenkan_sen()
    //
    assert(ich.get_result().size() == 5031);
    assert(std::isnan(ich.get_result()[0]));
    assert(std::isnan(ich.get_result()[7]));
    assert(std::abs(ich.get_result()[8] - 97.6875) < 0.0001);
    assert(std::abs(ich.get_result()[25] - 98.5) < 0.001);
    assert(std::abs(ich.get_result()[51] - 95.375) < 0.001);
    assert(std::abs(ich.get_result()[52] - 100.5) < 0.001);
    assert(std::abs(ich.get_result()[101] - 93.825) < 0.001);
    assert(std::abs(ich.get_result()[5022] - 126.17) < 0.001);
    assert(std::abs(ich.get_result()[5030] - 113.035) < 0.001);

    assert(ich.get_kijun_sen().size() == 5031);
    assert(std::isnan(ich.get_kijun_sen()[0]));
    assert(std::isnan(ich.get_kijun_sen()[24]));
    assert(std::abs(ich.get_kijun_sen()[25] - 98.1875) < 0.0001);
    assert(std::abs(ich.get_kijun_sen()[51] - 89.9062) < 0.0001);
    assert(std::abs(ich.get_kijun_sen()[52] - 95.0312) < 0.0001);
    assert(std::abs(ich.get_kijun_sen()[101] - 99.275) < 0.001);
    assert(std::abs(ich.get_kijun_sen()[5022] - 125.99) < 0.01);
    assert(std::abs(ich.get_kijun_sen()[5030] - 120.71) < 0.001);

    assert(ich.get_senkou_span_a().size() == 5031);
    assert(std::isnan(ich.get_senkou_span_a()[0]));
    assert(std::isnan(ich.get_senkou_span_a()[50]));
    assert(std::abs(ich.get_senkou_span_a()[51] - 98.3438) < 0.0001);
    assert(std::abs(ich.get_senkou_span_a()[52] - 98.3438) < 0.0001);
    assert(std::abs(ich.get_senkou_span_a()[77] - 92.6406) < 0.0001);
    assert(std::abs(ich.get_senkou_span_a()[101] - 109.096) < 0.001);
    assert(std::abs(ich.get_senkou_span_a()[5022] - 125.225) < 0.001);
    assert(std::abs(ich.get_senkou_span_a()[5030] - 122.183) < 0.001);

    assert(ich.get_senkou_span_b().size() == 5031);
    assert(std::isnan(ich.get_senkou_span_b()[0]));
    assert(std::isnan(ich.get_senkou_span_b()[76]));
    assert(std::abs(ich.get_senkou_span_b()[77] - 92.4062) < 0.0001);
    assert(std::abs(ich.get_senkou_span_b()[101] - 99.3512) < 0.0001);
    assert(std::abs(ich.get_senkou_span_b()[5022] - 123.685) < 0.001);
    assert(std::abs(ich.get_senkou_span_b()[5030] - 124.325) < 0.001);

    assert(ich.get_chikou_span().size() == 5031);
    assert(std::abs(ich.get_chikou_span()[0] - 97.0) < 0.001);
    assert(std::abs(ich.get_chikou_span()[9] - 81.5625) < 0.0001);
    assert(std::abs(ich.get_chikou_span()[25] - 96.6875) < 0.0001);
    assert(std::abs(ich.get_chikou_span()[101] - 115.9) < 0.001);
    assert(! std::isnan(ich.get_chikou_span()[5004]));
    assert(std::isnan(ich.get_chikou_span()[5005]));
    assert(std::isnan(ich.get_chikou_span()[5030]));
}

C++ DataFrame