KDJ指数——C++函数式元编程实现

KDJ指数是基于RSV指数的。RSV指数是以N天内最低值为底,当前值与最高值之间的比值。其具体意义为当天相对于N天最高值的比例(取值范围0-1),其值越大说明当天标的价格约高。其中1表示当天就是最高的,0表示当天就是最低的。从计算方法可以看出RSV指数只跟最高值最低值相关,属于支持向量相关的参数。KDJ指数分为K/D/J三个指数。其中K指数表示RSV的惯性累积值、D为K的惯性累积值、J为3K-2D。K为RSV惯性加权值,D为K惯性加权值,J为K与D的差值修正后的K值。K惯性修正与K差值的意义为K在自己的变化趋势上增加了部分。如果把标的价格运动比作线性运动,那么J值应该为K线性运动的预判值。

一下用C++函数式元编程实现了这些值的计算:

 
#include <vector>
#include <functional>
#include <exception>
#include <algorithm>
 
template<typename val_t>
using param_t = std::vector<val_t>;
 
template<typename val_t>
using func_t = std::function<param_t<val_t>(const param_t<val_t>&)>;
 
/* 计算N天的RSV值 */
template<int N, typename val_t>
func_t<val_t> rsv_gen() 
{
	return [](const param_t<val_t>& vec_input)
	{
		size_t szt_num = vec_input.size() - N;
		param_t<val_t> vec_out(szt_num, 0.0);
		for (size_t i = 0; i < szt_num; ++i) 
		{
			auto pr = std::minmax_element(vec_input.begin() + i, vec_input.begin() + i + N);
			auto Ln = *pr.first;
			auto Hn = *pr.second;
			if (Hn != Ln)
				vec_out[i] = (vec_input[i] - Ln) / (Hn - Ln) * 100.;
			else
				vec_out[i] = 0.;
		}
		return vec_out;
	};
}
 
 //* 计算N天的惯性加权值
template<int N, typename val_t>
inline val_t inert_weight(const param_t<val_t>& vec_rsv, const int& i_cur) 
{
    if constexpr (N == 1)
    {
        if (i_cur >= vec_rsv.size())
        {
            return vec_rsv.back();
        }
        return vec_rsv[i_cur];
    }
    if constexpr (N > 1)
    {
        if (i_cur >= vec_rsv.size() - 1)
        {
            return vec_rsv.back();
        }
        return 2 * vec_rsv[i_cur] / 3. + inert_weight<N - 1, val_t>(vec_rsv, i_cur + 1) / 3.;
    }
}
 
template<int N, int KN, typename val_t>
inline param_t<val_t> deep_inert_weight(const param_t<val_t>& vec_input) 
{
	if constexpr (N == 0) return vec_input;
	if constexpr (N != 0)
	{
        // * 自己先用K的计算方法惯性加权一次
		param_t<val_t> vec_out(vec_input.size() - 1, 0.0);
		for (size_t i = 0; i < vec_out.size(); ++i)
		{
			vec_out[i] = inert_weight<KN, val_t>(vec_input, i);
		}
		return deep_inert_weight<N - 1, KN, val_t>(vec_out);     // * 计算剩下的K算法惯性加权
	}
}
 
template<int N, int RSV_N, int K_N, typename val_t>
func_t<val_t> kdj_gen() 
{
	return [](const param_t<val_t>& vec) 
	{
		auto rsv = rsv_gen<RSV_N, val_t>();
		auto vec_rsv = rsv(vec);
 
		return deep_inert_weight<N, K_N, val_t>(vec_rsv);
	};
}
 
template<int RSV_N, int K_N, typename val_t>
func_t<val_t> k_gen() 
{
	return kdj_gen<1, RSV_N, K_N, val_t>();          // * k参数只需要用惯性加权算法算一次就行
}
 
template<int RSV_N, int K_N, typename val_t>
func_t<val_t> d_gen()
{
	return kdj_gen<2, RSV_N, K_N, val_t>();          // * d参数需要用惯性加权算法,将结果再次使用惯性加权算法算一次
}
 
template<int RSV_N, int K_N, typename val_t>
func_t<val_t> j_gen()
{
	return [](const param_t<val_t>& vec) 
	{
		auto k = k_gen<RSV_N, K_N, double>();
		auto vec_k = k(vec);
		auto d = d_gen<RSV_N, K_N, double>();
		auto vec_d = d(vec);
		size_t szt_short = vec_k.size() < vec_d.size() ? vec_k.size() : vec_d.size();
		param_t<val_t> vec_out(szt_short, 0.0);
		for (size_t i = 0; i < szt_short; ++i)
		{
			vec_out[i] = 3. * vec_k[i] - 2. * vec_d[i];
		}
		return vec_out;
	};
}

#include <vector>
#include <algorithm>
#include <random>

// * 价格生成函数
double price_generate()
{
    static std::default_random_engine ge;
    static std::uniform_real_distribution <double> ud(0., 5.);
    return ud(ge);
} 

int main() 
{
	/* 测试数据产生,模拟一个以恒定速度增长的价格 */
	std::vector<double> vec;
	vec.resize(50, 0.0);
	std::generate(vec.begin(), vec.end(), price_generate);
	std::reverse(vec.begin(), vec.end());				// * 数据是反向的,第一个是最近的数据
 
    printf("origin:\n");
    for(auto v: vec)
    {
        printf("%3.4lf ", v);
    }
    printf("\n");
    auto kfun = k_gen<9, 3, double>();
    auto dfun = d_gen<9, 3, double>();
    auto jfun = j_gen<9, 3, double>();

    auto veck = kfun(vec);
    printf("K:\n");
    for(auto v: veck)
    {
        printf("%3.4lf ", v);
    }
    printf("\n");

    auto vecd = dfun(vec);
    printf("D:\n");
    for(auto v: vecd)
    {
        printf("%3.4lf ", v);
    }
    printf("\n");

    auto vecj = jfun(vec);
    printf("J:\n");
    for(auto v: vecj)
    {
        printf("%3.4lf ", v);
    }
    printf("\n");
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

腾昵猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值