mirror of
https://gitee.com/fasiondog/hikyuu.git
synced 2024-11-30 02:48:57 +08:00
commit
7d6c0886f0
@ -300,4 +300,14 @@ Indicator HKU_API IF(const Indicator& x, price_t a, price_t b) {
|
||||
return IF(x, CVAL(x, a), CVAL(x, b));
|
||||
}
|
||||
|
||||
Indicator HKU_API CORR(const Indicator& ind1, const Indicator& ind2, int n) {
|
||||
HKU_ERROR_IF_RETURN(!ind1.getImp() || !ind2.getImp(), Indicator(),
|
||||
"ind1 or ind2 is Null Indicator!");
|
||||
HKU_ERROR_IF_RETURN(n < 2, Indicator(), "Invalid param n: {} (need >= 2)", n);
|
||||
IndicatorImpPtr p = make_shared<IndicatorImp>("CORR");
|
||||
p->setParam<int>("n", n);
|
||||
p->add(IndicatorImp::CORR, ind1.getImp(), ind2.getImp());
|
||||
return p->calculate();
|
||||
}
|
||||
|
||||
} /* namespace hku */
|
||||
|
@ -365,6 +365,14 @@ Indicator HKU_API IF(const Indicator& x, price_t a, const Indicator& b);
|
||||
Indicator HKU_API IF(const Indicator& x, const Indicator& a, price_t b);
|
||||
Indicator HKU_API IF(const Indicator& x, price_t a, price_t b);
|
||||
|
||||
/**
|
||||
* 计算相关系数
|
||||
* @param ind1 指标1
|
||||
* @param ind2 指标2
|
||||
* @ingroup Indicator
|
||||
*/
|
||||
Indicator HKU_API CORR(const Indicator& ind1, const Indicator& ind2, int n);
|
||||
|
||||
} /* namespace hku */
|
||||
|
||||
#if FMT_VERSION >= 90000
|
||||
|
@ -400,6 +400,10 @@ string IndicatorImp::formula() const {
|
||||
<< m_right->formula() << ")";
|
||||
break;
|
||||
|
||||
case CORR:
|
||||
buf << m_name << "(" << m_left->formula() << ", " << m_right->formula() << ")";
|
||||
break;
|
||||
|
||||
default:
|
||||
HKU_ERROR("Wrong optype! {}", int(m_optype));
|
||||
break;
|
||||
@ -623,6 +627,10 @@ Indicator IndicatorImp::calculate() {
|
||||
execute_if();
|
||||
break;
|
||||
|
||||
case CORR:
|
||||
execute_corr();
|
||||
break;
|
||||
|
||||
default:
|
||||
HKU_ERROR("Unkown Indicator::OPType! {}", int(m_optype));
|
||||
break;
|
||||
@ -1251,6 +1259,98 @@ void IndicatorImp::execute_if() {
|
||||
}
|
||||
}
|
||||
|
||||
void IndicatorImp::execute_corr() {
|
||||
m_right->calculate();
|
||||
m_left->calculate();
|
||||
|
||||
IndicatorImp *maxp, *minp;
|
||||
if (m_right->size() > m_left->size()) {
|
||||
maxp = m_right.get();
|
||||
minp = m_left.get();
|
||||
} else {
|
||||
maxp = m_left.get();
|
||||
minp = m_right.get();
|
||||
}
|
||||
|
||||
size_t total = maxp->size();
|
||||
size_t discard = maxp->size() - minp->size() + minp->discard();
|
||||
if (discard < maxp->discard()) {
|
||||
discard = maxp->discard();
|
||||
}
|
||||
|
||||
// 结果 0 存放相关系数结果
|
||||
// 结果 1 存放协方差(COV)结果
|
||||
_readyBuffer(total, 2);
|
||||
|
||||
int n = getParam<int>("n");
|
||||
if (n < 2 || discard + 2 > total) {
|
||||
setDiscard(total);
|
||||
return;
|
||||
}
|
||||
|
||||
price_t null_price = Null<price_t>();
|
||||
vector<price_t> prebufx(total, null_price);
|
||||
vector<price_t> prebufy(total, null_price);
|
||||
vector<price_t> prepowx(total, null_price);
|
||||
vector<price_t> prepowy(total, null_price);
|
||||
vector<price_t> prepowxy(total, null_price);
|
||||
price_t kx = maxp->get(discard);
|
||||
price_t ky = minp->get(discard);
|
||||
price_t ex = 0.0, ey = 0.0, exy = 0.0, varx = 0.0, vary = 0.0, cov = 0.0;
|
||||
price_t ex2 = 0.0, ey2 = 0.0, exy2 = 0.0;
|
||||
prebufx[discard] = 0.0;
|
||||
prebufy[discard] = 0.0;
|
||||
prepowx[discard] = 0.0;
|
||||
prepowy[discard] = 0.0;
|
||||
prepowxy[discard] = 0.0;
|
||||
|
||||
for (size_t i = discard, nobs = 0; i < total; ++i) {
|
||||
price_t ix = maxp->get(i) - kx;
|
||||
price_t iy = minp->get(i) - ky;
|
||||
price_t preix = prebufx[i - nobs];
|
||||
price_t preiy = prebufy[i - nobs];
|
||||
price_t prepowix = prepowx[i - nobs];
|
||||
price_t prepowiy = prepowy[i - nobs];
|
||||
price_t prepowixy = prepowxy[i - nobs];
|
||||
HKU_INFO_IF(i % 100 == 0, "{}: ix: {}, iy: {}, preix: {}, preiy: {}", i, ix, iy, preix,
|
||||
preiy);
|
||||
if (!std::isnan(preix) && !std::isnan(preiy) && !std::isnan(ix) && !std::isnan(iy)) {
|
||||
if (nobs < n) {
|
||||
nobs++;
|
||||
ex += ix;
|
||||
ey += iy;
|
||||
exy += ix * iy;
|
||||
ex2 += std::pow(ix, 2);
|
||||
ey2 += std::pow(iy, 2);
|
||||
varx = nobs == 1 ? 0. : (ex2 - std::pow(ex, 2) / nobs) / (nobs - 1);
|
||||
vary = nobs == 1 ? 0. : (ey2 - std::pow(ey, 2) / nobs) / (nobs - 1);
|
||||
cov = nobs == 1 ? 0. : (exy - ex * ey / nobs) / (nobs - 1);
|
||||
_set(cov / std::sqrt(varx * vary), i, 0);
|
||||
_set(cov, i, 1);
|
||||
} else {
|
||||
ex += ix - preix;
|
||||
ey += iy - preiy;
|
||||
ex2 = ex2 - prepowix + std::pow(ix, 2);
|
||||
ey2 = ey2 - prepowiy + std::pow(iy, 2);
|
||||
exy = exy + ix * iy - prepowixy;
|
||||
varx = (ex2 - std::pow(ex, 2) / n) / (n - 1);
|
||||
vary = (ey2 - std::pow(ey, 2) / n) / (n - 1);
|
||||
cov = (exy - ex * ey / n) / (n - 1);
|
||||
_set(cov / std::sqrt(varx * vary), i, 0);
|
||||
_set(cov, i, 1);
|
||||
}
|
||||
prebufx[i] = ix;
|
||||
prebufy[i] = iy;
|
||||
prepowx[i] = ex2;
|
||||
prepowy[i] = ey2;
|
||||
prepowxy[i] = exy2;
|
||||
}
|
||||
}
|
||||
|
||||
// 修正 discard
|
||||
setDiscard(++discard);
|
||||
}
|
||||
|
||||
void IndicatorImp::_dyn_calculate(const Indicator &ind) {
|
||||
// SPEND_TIME(IndicatorImp__dyn_calculate);
|
||||
const auto &ind_param = getIndParamImp("n");
|
||||
|
@ -77,6 +77,7 @@ public:
|
||||
OR, ///< 或
|
||||
WEAVE, ///< 特殊的,需要两个指标作为参数的指标
|
||||
OP_IF, /// if操作
|
||||
CORR, ///< 相关系数,需要两个指标作为参数
|
||||
INVALID
|
||||
};
|
||||
|
||||
@ -211,6 +212,7 @@ private:
|
||||
void execute_or();
|
||||
void execute_weave();
|
||||
void execute_if();
|
||||
void execute_corr();
|
||||
|
||||
protected:
|
||||
static size_t _get_step_start(size_t pos, size_t step, size_t discard);
|
||||
|
@ -728,6 +728,15 @@ void export_Indicator_build_in() {
|
||||
:param Indicator ind2: 指标2
|
||||
:rtype: Indicator)");
|
||||
|
||||
def("CORR", CORR, R"(CORR(ind1, ind2, n)
|
||||
|
||||
计算 ind1 和 ind2 的相关系数
|
||||
|
||||
:param Indicator ind1: 指标1
|
||||
:param Indicator ind2: 指标2
|
||||
:param int n: 按指定 n 的长度计算两个 ind 直接数据相关系数
|
||||
:rtype: Indicator)");
|
||||
|
||||
def("IF", IF_1);
|
||||
def("IF", IF_2);
|
||||
def("IF", IF_3);
|
||||
|
@ -42,6 +42,7 @@ local boost_version = "1.81.0"
|
||||
local hdf5_version = "1.12.2"
|
||||
local mysql_version = "8.0.31"
|
||||
local fmt_version = "10.0.0"
|
||||
local flatbuffers_version = "2.0.0"
|
||||
if is_plat("windows") or (is_plat("linux", "cross") and is_arch("aarch64", "arm64.*")) then mysql_version = "8.0.21" end
|
||||
|
||||
add_repositories("project-repo hikyuu_extern_libs")
|
||||
@ -81,7 +82,7 @@ end
|
||||
add_requires("spdlog", {system = false, configs = {header_only = true, fmt_external = true, vs_runtime = "MD"}})
|
||||
add_requireconfs("spdlog.fmt", {override = true, version = fmt_version, configs = {header_only = true}})
|
||||
add_requires("sqlite3", {system = false, configs = {shared = true, vs_runtime = "MD", cxflags = "-fPIC"}})
|
||||
add_requires("flatbuffers 2.0.0", {system = false, configs = {vs_runtime = "MD"}})
|
||||
add_requires("flatbuffers v" .. flatbuffers_version, {system = false, configs = {vs_runtime = "MD"}})
|
||||
add_requires("nng", {system = false, configs = {vs_runtime = "MD", cxflags = "-fPIC"}})
|
||||
add_requires("nlohmann_json", {system = false})
|
||||
add_requires("cpp-httplib", {system = false})
|
||||
|
Loading…
Reference in New Issue
Block a user