mirror of
https://gitee.com/fasiondog/hikyuu.git
synced 2024-12-04 04:48:17 +08:00
SAFTYLOSS 支持动态参数
This commit is contained in:
parent
e115dc98e0
commit
9290a84571
@ -24,13 +24,14 @@ namespace hku {
|
|||||||
* 上移,在上述结果的基础上再取起N日(一般为3天)内的最高值
|
* 上移,在上述结果的基础上再取起N日(一般为3天)内的最高值
|
||||||
* </pre>
|
* </pre>
|
||||||
* @note:返回结果中前(回溯周期宽度+去最高值的宽度)个点是无效的
|
* @note:返回结果中前(回溯周期宽度+去最高值的宽度)个点是无效的
|
||||||
* @param data 输入数据,单一输入
|
|
||||||
* @param n1 计算平均噪音的回溯时间窗口,默认为10天
|
* @param n1 计算平均噪音的回溯时间窗口,默认为10天
|
||||||
* @param n2 对初步止损线去n2日内的最高值,默认为3
|
* @param n2 对初步止损线去n2日内的最高值,默认为3
|
||||||
* @param p 噪音系数,默认为2
|
* @param p 噪音系数,默认为2
|
||||||
* @ingroup Indicator
|
* @ingroup Indicator
|
||||||
*/
|
*/
|
||||||
Indicator HKU_API SAFTYLOSS(const Indicator& data, int n1 = 10, int n2 = 3, double p = 2.0);
|
Indicator HKU_API SAFTYLOSS(int n1 = 10, int n2 = 3, double p = 2.0);
|
||||||
|
Indicator HKU_API SAFTYLOSS(const IndParam& n1, const IndParam& n2, double p = 2.0);
|
||||||
|
Indicator HKU_API SAFTYLOSS(const IndParam& n1, const IndParam& n2, const IndParam& p);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 亚历山大 艾尔德安全地带止损
|
* 亚历山大 艾尔德安全地带止损
|
||||||
@ -43,12 +44,35 @@ Indicator HKU_API SAFTYLOSS(const Indicator& data, int n1 = 10, int n2 = 3, doub
|
|||||||
* 上移,在上述结果的基础上再取起N日(一般为3天)内的最高值
|
* 上移,在上述结果的基础上再取起N日(一般为3天)内的最高值
|
||||||
* </pre>
|
* </pre>
|
||||||
* @note:返回结果中前(回溯周期宽度+去最高值的宽度)个点是无效的
|
* @note:返回结果中前(回溯周期宽度+去最高值的宽度)个点是无效的
|
||||||
|
* @param data 输入数据,单一输入
|
||||||
* @param n1 计算平均噪音的回溯时间窗口,默认为10天
|
* @param n1 计算平均噪音的回溯时间窗口,默认为10天
|
||||||
* @param n2 对初步止损线去n2日内的最高值,默认为3
|
* @param n2 对初步止损线去n2日内的最高值,默认为3
|
||||||
* @param p 噪音系数,默认为2
|
* @param p 噪音系数,默认为2
|
||||||
* @ingroup Indicator
|
* @ingroup Indicator
|
||||||
*/
|
*/
|
||||||
Indicator HKU_API SAFTYLOSS(int n1 = 10, int n2 = 3, double p = 2.0);
|
inline Indicator SAFTYLOSS(const Indicator& data, int n1 = 10, int n2 = 3, double p = 2.0) {
|
||||||
|
return SAFTYLOSS(n1, n2, p)(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Indicator SAFTYLOSS(const Indicator& data, const IndParam& n1, const IndParam& n2,
|
||||||
|
double p = 2.0) {
|
||||||
|
return SAFTYLOSS(n1, n2, p)(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Indicator SAFTYLOSS(const Indicator& data, const IndParam& n1, const IndParam& n2,
|
||||||
|
const IndParam& p) {
|
||||||
|
return SAFTYLOSS(n1, n2, p)(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Indicator SAFTYLOSS(const Indicator& data, const Indicator& n1, const Indicator& n2,
|
||||||
|
double p = 2.0) {
|
||||||
|
return SAFTYLOSS(IndParam(n1), IndParam(n2), p)(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Indicator SAFTYLOSS(const Indicator& data, const Indicator& n1, const Indicator& n2,
|
||||||
|
const Indicator& p) {
|
||||||
|
return SAFTYLOSS(IndParam(n1), IndParam(n2), IndParam(p))(data);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace hku
|
} // namespace hku
|
||||||
|
|
||||||
|
@ -5,6 +5,9 @@
|
|||||||
* Author: fasiondog
|
* Author: fasiondog
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "../crt/SLICE.h"
|
||||||
|
#include "../crt/CVAL.h"
|
||||||
|
#include "../crt/SAFTYLOSS.h"
|
||||||
#include "ISaftyLoss.h"
|
#include "ISaftyLoss.h"
|
||||||
|
|
||||||
#if HKU_SUPPORT_SERIALIZATION
|
#if HKU_SUPPORT_SERIALIZATION
|
||||||
@ -71,6 +74,80 @@ void ISaftyLoss::_calculate(const Indicator& data) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ISaftyLoss::_dyn_one_circle(const Indicator& ind, size_t curPos, int n1, int n2, double p) {
|
||||||
|
HKU_IF_RETURN(n1 < 2 || n2 < 2, void());
|
||||||
|
Indicator slice = SLICE(ind, 0, curPos + 1);
|
||||||
|
Indicator st = SAFTYLOSS(slice, n1, n2, p);
|
||||||
|
if (st.size() > 0) {
|
||||||
|
_set(st[st.size() - 1], curPos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ISaftyLoss::_dyn_calculate(const Indicator& ind) {
|
||||||
|
auto iter = m_ind_params.find("n1");
|
||||||
|
Indicator n1 =
|
||||||
|
iter != m_ind_params.end() ? Indicator(iter->second) : CVAL(ind, getParam<int>("n1"));
|
||||||
|
iter = m_ind_params.find("n2");
|
||||||
|
Indicator n2 =
|
||||||
|
iter != m_ind_params.end() ? Indicator(iter->second) : CVAL(ind, getParam<int>("n2"));
|
||||||
|
iter = m_ind_params.find("p");
|
||||||
|
Indicator p =
|
||||||
|
iter != m_ind_params.end() ? Indicator(iter->second) : CVAL(ind, getParam<int>("p"));
|
||||||
|
|
||||||
|
HKU_CHECK(n1.size() == ind.size(), "ind_param(n1).size()={}, ind.size()={}!", n1.size(),
|
||||||
|
ind.size());
|
||||||
|
HKU_CHECK(n2.size() == ind.size(), "ind_param(n2).size()={}, ind.size()={}!", n2.size(),
|
||||||
|
ind.size());
|
||||||
|
HKU_CHECK(p.size() == ind.size(), "ind_param(p).size()={}, ind.size()={}!", p.size(),
|
||||||
|
ind.size());
|
||||||
|
|
||||||
|
m_discard = std::max(ind.discard(), n1.discard());
|
||||||
|
m_discard = std::max(m_discard, n2.discard());
|
||||||
|
m_discard = std::max(m_discard, p.discard());
|
||||||
|
size_t total = ind.size();
|
||||||
|
HKU_IF_RETURN(0 == total || m_discard >= total, void());
|
||||||
|
|
||||||
|
static const size_t minCircleLength = 400;
|
||||||
|
size_t workerNum = ms_tg->worker_num();
|
||||||
|
if (total < minCircleLength || workerNum == 1) {
|
||||||
|
for (size_t i = ind.discard(); i < total; i++) {
|
||||||
|
_dyn_one_circle(ind, i, n1[i], n2[i], p[i]);
|
||||||
|
}
|
||||||
|
_update_discard();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t circleLength = minCircleLength;
|
||||||
|
if (minCircleLength * workerNum >= total) {
|
||||||
|
circleLength = minCircleLength;
|
||||||
|
} else {
|
||||||
|
size_t tailCount = total % workerNum;
|
||||||
|
circleLength = tailCount == 0 ? total / workerNum : total / workerNum + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::future<void>> tasks;
|
||||||
|
for (size_t group = 0; group < workerNum; group++) {
|
||||||
|
size_t first = circleLength * group;
|
||||||
|
if (first >= total) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
tasks.push_back(ms_tg->submit([=, &ind, &n1, &n2, &p]() {
|
||||||
|
size_t endPos = first + circleLength;
|
||||||
|
if (endPos > total) {
|
||||||
|
endPos = total;
|
||||||
|
}
|
||||||
|
for (size_t i = circleLength * group; i < endPos; i++) {
|
||||||
|
_dyn_one_circle(ind, i, n1[i], n2[i], p[i]);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& task : tasks) {
|
||||||
|
task.get();
|
||||||
|
}
|
||||||
|
_update_discard();
|
||||||
|
}
|
||||||
|
|
||||||
Indicator HKU_API SAFTYLOSS(int n1, int n2, double p) {
|
Indicator HKU_API SAFTYLOSS(int n1, int n2, double p) {
|
||||||
IndicatorImpPtr result = make_shared<ISaftyLoss>();
|
IndicatorImpPtr result = make_shared<ISaftyLoss>();
|
||||||
result->setParam<int>("n1", n1);
|
result->setParam<int>("n1", n1);
|
||||||
@ -79,8 +156,20 @@ Indicator HKU_API SAFTYLOSS(int n1, int n2, double p) {
|
|||||||
return Indicator(result);
|
return Indicator(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
Indicator HKU_API SAFTYLOSS(const Indicator& data, int n1, int n2, double p) {
|
Indicator HKU_API SAFTYLOSS(const IndParam& n1, const IndParam& n2, double p) {
|
||||||
return SAFTYLOSS(n1, n2, p)(data);
|
IndicatorImpPtr result = make_shared<ISaftyLoss>();
|
||||||
|
result->setIndParam("n1", n1);
|
||||||
|
result->setIndParam("n2", n2);
|
||||||
|
result->setParam<double>("p", p);
|
||||||
|
return Indicator(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
Indicator HKU_API SAFTYLOSS(const IndParam& n1, const IndParam& n2, const IndParam& p) {
|
||||||
|
IndicatorImpPtr result = make_shared<ISaftyLoss>();
|
||||||
|
result->setIndParam("n1", n1);
|
||||||
|
result->setIndParam("n2", n2);
|
||||||
|
result->setIndParam("p", p);
|
||||||
|
return Indicator(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* namespace hku */
|
} /* namespace hku */
|
||||||
|
@ -32,6 +32,11 @@ class ISaftyLoss : public hku::IndicatorImp {
|
|||||||
public:
|
public:
|
||||||
ISaftyLoss();
|
ISaftyLoss();
|
||||||
virtual ~ISaftyLoss();
|
virtual ~ISaftyLoss();
|
||||||
|
|
||||||
|
virtual void _dyn_calculate(const Indicator&) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void _dyn_one_circle(const Indicator& ind, size_t curPos, int n1, int n2, double p);
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace hku */
|
} /* namespace hku */
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <hikyuu/StockManager.h>
|
#include <hikyuu/StockManager.h>
|
||||||
#include <hikyuu/indicator/crt/SAFTYLOSS.h>
|
#include <hikyuu/indicator/crt/SAFTYLOSS.h>
|
||||||
|
#include <hikyuu/indicator/crt/CVAL.h>
|
||||||
#include <hikyuu/indicator/crt/KDATA.h>
|
#include <hikyuu/indicator/crt/KDATA.h>
|
||||||
|
|
||||||
using namespace hku;
|
using namespace hku;
|
||||||
@ -128,6 +129,32 @@ TEST_CASE("test_SAFTYLOSS") {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @par 检测点 */
|
||||||
|
TEST_CASE("test_SAFTYLOSS_dyn") {
|
||||||
|
Stock stock = StockManager::instance().getStock("sh000001");
|
||||||
|
KData kdata = stock.getKData(KQuery(-50));
|
||||||
|
// KData kdata = stock.getKData(KQuery(0, Null<size_t>(), KQuery::MIN));
|
||||||
|
Indicator c = CLOSE(kdata);
|
||||||
|
Indicator expect = SAFTYLOSS(c, 10, 3, 2.0);
|
||||||
|
Indicator result = SAFTYLOSS(c, CVAL(c, 10), CVAL(c, 3), CVAL(c, 2.0));
|
||||||
|
CHECK_EQ(expect.size(), result.size());
|
||||||
|
for (size_t i = 0; i < result.discard(); i++) {
|
||||||
|
CHECK_UNARY(std::isnan(result[i]));
|
||||||
|
}
|
||||||
|
for (size_t i = result.discard(); i < result.size(); i++) {
|
||||||
|
CHECK_EQ(expect.get(i, 0), doctest::Approx(result.get(i, 0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
result = SAFTYLOSS(c, IndParam(CVAL(c, 10)), IndParam(CVAL(c, 3)), IndParam(CVAL(c, 2.0)));
|
||||||
|
CHECK_EQ(expect.size(), result.size());
|
||||||
|
for (size_t i = 0; i < result.discard(); i++) {
|
||||||
|
CHECK_UNARY(std::isnan(result[i]));
|
||||||
|
}
|
||||||
|
for (size_t i = result.discard(); i < result.size(); i++) {
|
||||||
|
CHECK_EQ(expect.get(i, 0), doctest::Approx(result.get(i, 0)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// test export
|
// test export
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -83,9 +83,17 @@ Indicator (*REF_4)(const Indicator&, const Indicator&) = REF;
|
|||||||
Indicator (*REF_5)(const Indicator&, int) = REF;
|
Indicator (*REF_5)(const Indicator&, int) = REF;
|
||||||
|
|
||||||
Indicator (*SAFTYLOSS_1)(int n1, int n2, double p) = SAFTYLOSS;
|
Indicator (*SAFTYLOSS_1)(int n1, int n2, double p) = SAFTYLOSS;
|
||||||
Indicator (*SAFTYLOSS_2)(const Indicator&, int n1, int n2, double p) = SAFTYLOSS;
|
Indicator (*SAFTYLOSS_2)(const IndParam& n1, const IndParam& n2, double p) = SAFTYLOSS;
|
||||||
// BOOST_PYTHON_FUNCTION_OVERLOADS(SAFTYLOSS_1_overload, SAFTYLOSS, 0, 3);
|
Indicator (*SAFTYLOSS_3)(const IndParam& n1, const IndParam& n2, const IndParam& p) = SAFTYLOSS;
|
||||||
// BOOST_PYTHON_FUNCTION_OVERLOADS(SAFTYLOSS_2_overload, SAFTYLOSS, 1, 4);
|
Indicator (*SAFTYLOSS_4)(const Indicator&, int n1, int n2, double p) = SAFTYLOSS;
|
||||||
|
Indicator (*SAFTYLOSS_5)(const Indicator&, const IndParam& n1, const IndParam& n2,
|
||||||
|
double p) = SAFTYLOSS;
|
||||||
|
Indicator (*SAFTYLOSS_6)(const Indicator&, const IndParam& n1, const IndParam& n2,
|
||||||
|
const IndParam& p) = SAFTYLOSS;
|
||||||
|
Indicator (*SAFTYLOSS_7)(const Indicator&, const Indicator& n1, const Indicator& n2,
|
||||||
|
double p) = SAFTYLOSS;
|
||||||
|
Indicator (*SAFTYLOSS_8)(const Indicator&, const Indicator& n1, const Indicator& n2,
|
||||||
|
const Indicator& p) = SAFTYLOSS;
|
||||||
|
|
||||||
Indicator (*STDEV_1)(int) = STDEV;
|
Indicator (*STDEV_1)(int) = STDEV;
|
||||||
Indicator (*STDEV_2)(const IndParam&) = STDEV;
|
Indicator (*STDEV_2)(const IndParam&) = STDEV;
|
||||||
@ -576,7 +584,13 @@ void export_Indicator_build_in() {
|
|||||||
:rtype: Indicator)");
|
:rtype: Indicator)");
|
||||||
|
|
||||||
def("SAFTYLOSS", SAFTYLOSS_1, (arg("n1") = 10, arg("n2") = 3, arg("p") = 2.0));
|
def("SAFTYLOSS", SAFTYLOSS_1, (arg("n1") = 10, arg("n2") = 3, arg("p") = 2.0));
|
||||||
def("SAFTYLOSS", SAFTYLOSS_2, (arg("data"), arg("n1") = 10, arg("n2") = 3, arg("p") = 2.0),
|
def("SAFTYLOSS", SAFTYLOSS_2, (arg("n1"), arg("n2"), arg("p") = 2.0));
|
||||||
|
def("SAFTYLOSS", SAFTYLOSS_3, (arg("n1"), arg("n2"), arg("p")));
|
||||||
|
def("SAFTYLOSS", SAFTYLOSS_4, (arg("data"), arg("n1") = 10, arg("n2") = 3, arg("p") = 2.0));
|
||||||
|
def("SAFTYLOSS", SAFTYLOSS_5, (arg("data"), arg("n1"), arg("n2"), arg("p") = 2.0));
|
||||||
|
def("SAFTYLOSS", SAFTYLOSS_6, (arg("data"), arg("n1"), arg("n2"), arg("p")));
|
||||||
|
def("SAFTYLOSS", SAFTYLOSS_7, (arg("data"), arg("n1"), arg("n2"), arg("p") = 2.0));
|
||||||
|
def("SAFTYLOSS", SAFTYLOSS_8, (arg("data"), arg("n1"), arg("n2"), arg("p")),
|
||||||
R"(SAFTYLOSS([data, n1=10, n2=3, p=2.0])
|
R"(SAFTYLOSS([data, n1=10, n2=3, p=2.0])
|
||||||
|
|
||||||
亚历山大 艾尔德安全地带止损线,参见 [BOOK2]_
|
亚历山大 艾尔德安全地带止损线,参见 [BOOK2]_
|
||||||
@ -584,9 +598,9 @@ void export_Indicator_build_in() {
|
|||||||
计算说明:在回溯周期内(一般为10到20天),将所有向下穿越的长度相加除以向下穿越的次数,得到噪音均值(即回溯期内所有最低价低于前一日最低价的长度除以次数),并用今日最低价减去(前日噪音均值乘以一个倍数)得到该止损线。为了抵消波动并且保证止损线的上移,在上述结果的基础上再取起N日(一般为3天)内的最高值
|
计算说明:在回溯周期内(一般为10到20天),将所有向下穿越的长度相加除以向下穿越的次数,得到噪音均值(即回溯期内所有最低价低于前一日最低价的长度除以次数),并用今日最低价减去(前日噪音均值乘以一个倍数)得到该止损线。为了抵消波动并且保证止损线的上移,在上述结果的基础上再取起N日(一般为3天)内的最高值
|
||||||
|
|
||||||
:param Indicator data: 输入数据
|
:param Indicator data: 输入数据
|
||||||
:param int n1: 计算平均噪音的回溯时间窗口
|
:param int|Indicator|IndParam n1: 计算平均噪音的回溯时间窗口
|
||||||
:param int n2: 对初步止损线去n2日内的最高值
|
:param int|Indicator|IndParam n2: 对初步止损线去n2日内的最高值
|
||||||
:param float p: 噪音系数
|
:param float|Indicator|IndParam p: 噪音系数
|
||||||
:rtype: Indicator)");
|
:rtype: Indicator)");
|
||||||
|
|
||||||
def("DIFF", DIFF_1);
|
def("DIFF", DIFF_1);
|
||||||
|
Loading…
Reference in New Issue
Block a user