add RESULT 指标

This commit is contained in:
fasiondog 2024-04-12 02:23:01 +08:00
parent 9bd8e58f46
commit d91874e0d1
8 changed files with 191 additions and 0 deletions

View File

@ -796,6 +796,15 @@
:rtype: Indicator
.. py:function:: RESULT(data, result_ix)
以公式指标的方式返回指定指标中的指定结果集
:param Indicator data: 指定的指标
:param int result_ix: 指定的结果集
:rtype: Indicator
.. py:function:: REVERSE([data])
求相反数REVERSE(X)返回-X

View File

@ -10,6 +10,7 @@
* :py:func:`CVAL` - 创建指定长度的固定数值指标
* :py:func:`DROPNA` - 删除 nan 值
* :py:func:`PRICELIST` - 将PriceList或Indicator的结果集包装为Indicator同名 VALUE
* :py:func:`RESULT` - 以指标公式的方式返回指定指标中相应的结果集
* :py:func:`WEAVE` - 将两个ind的结果合并到一个ind中
* :py:func:`ZSCORE` - ZScore 标准化

View File

@ -73,6 +73,7 @@
#include "crt/PRICELIST.h"
#include "crt/RECOVER.h"
#include "crt/REF.h"
#include "crt/RESULT.h"
#include "crt/REVERSE.h"
#include "crt/ROC.h"
#include "crt/ROCP.h"

View File

@ -0,0 +1,20 @@
/*
* Copyright (c) 2024 hikyuu.org
*
* Created on: 2024-04-12
* Author: fasiondog
*/
#pragma once
#include "../Indicator.h"
namespace hku {
Indicator HKU_API RESULT(int result_ix);
inline Indicator HKU_API RESULT(const Indicator& ind, int result_ix) {
return RESULT(result_ix)(ind);
}
}

View File

@ -0,0 +1,49 @@
/*
* Copyright (c) 2024 hikyuu.org
*
* Created on: 2024-04-12
* Author: fasiondog
*/
#include "IResult.h"
#if HKU_SUPPORT_SERIALIZATION
BOOST_CLASS_EXPORT(hku::IResult)
#endif
namespace hku {
IResult::IResult() : IndicatorImp("RESULT", 1) {
setParam<int>("result_ix", 0);
}
IResult::IResult(int result_ix) : IndicatorImp("RESULT", 1) {
setParam<int>("result_ix", result_ix);
checkParam("result_ix");
}
void IResult::_checkParam(const string& name) const {
if ("result_ix" == name) {
int result_ix = getParam<int>("result_ix");
HKU_ASSERT(result_ix >= 0 && result_ix < MAX_RESULT_NUM);
}
}
void IResult::_calculate(const Indicator& ind) {
int result_ix = getParam<int>("result_ix");
HKU_CHECK(result_ix < ind.getResultNumber(),
"The input indicator has only {} results, but result_ix({}) is out_of range!",
ind.getResultNumber(), result_ix);
m_discard = ind.discard();
HKU_IF_RETURN(m_discard >= ind.size(), void());
const auto* src = ind.data(result_ix);
auto* dst = this->data();
memcpy(dst + m_discard, src + m_discard, sizeof(value_t) * (ind.size() - m_discard));
}
Indicator HKU_API RESULT(int result_ix) {
return make_shared<IResult>(result_ix);
}
} // namespace hku

View File

@ -0,0 +1,26 @@
/*
* Copyright (c) 2024 hikyuu.org
*
* Created on: 2024-04-12
* Author: fasiondog
*/
#pragma once
#include "../Indicator.h"
namespace hku {
class IResult : public IndicatorImp {
INDICATOR_IMP(IResult)
INDICATOR_IMP_NO_PRIVATE_MEMBER_SERIALIZATION
public:
IResult();
explicit IResult(int reuslt_ix);
virtual ~IResult() = default;
virtual void _checkParam(const string& name) const override;
};
} // namespace hku

View File

@ -0,0 +1,76 @@
/*
* Copyright (c) 2024 hikyuu.org
*
* Created on: 2024-04-12
* Author: fasiondog
*/
#include "../test_config.h"
#include <hikyuu/StockManager.h>
#include <hikyuu/indicator/crt/KDATA.h>
#include <hikyuu/indicator/crt/MACD.h>
#include <hikyuu/indicator/crt/RESULT.h>
using namespace hku;
/**
* @defgroup test_indicator_RESULT test_indicator_RESULT
* @ingroup test_hikyuu_indicator_suite
* @{
*/
/** @par 检测点 */
TEST_CASE("test_RESULT") {
/** @arg 无效参数 */
CHECK_THROWS_AS(RESULT(-1), std::exception);
CHECK_THROWS_AS(RESULT(6), std::exception);
/** @arg 输入空指标 */
auto ret = RESULT(Indicator(), 0);
CHECK_EQ(ret.empty(), true);
/** @arg 正常获取 */
auto k = getStock("SH000001").getKData(KQuery(-100));
auto macd = MACD(CLOSE(), 0);
auto bar = RESULT(macd, 0);
auto diff = RESULT(macd, 1);
auto dea = RESULT(macd, 2);
auto expect = MACD(k.close(), 0);
CHECK_UNARY(bar(k).equal(expect.getResult(0)));
CHECK_UNARY(diff(k).equal(expect.getResult(1)));
CHECK_UNARY(dea(k).equal(expect.getResult(2)));
}
//-----------------------------------------------------------------------------
// test export
//-----------------------------------------------------------------------------
#if HKU_SUPPORT_SERIALIZATION
/** @par 检测点 */
TEST_CASE("test_RESULT_export") {
StockManager& sm = StockManager::instance();
string filename(sm.tmpdir());
filename += "/RESULT.xml";
Stock stock = sm.getStock("sh000001");
KData kdata = stock.getKData(KQuery(-20));
Indicator ma1 = RESULT(MACD(CLOSE(kdata)), 0);
{
std::ofstream ofs(filename);
boost::archive::xml_oarchive oa(ofs);
oa << BOOST_SERIALIZATION_NVP(ma1);
}
Indicator ma2;
{
std::ifstream ifs(filename);
boost::archive::xml_iarchive ia(ifs);
ia >> BOOST_SERIALIZATION_NVP(ma2);
}
CHECK_EQ(ma1.size(), ma2.size());
CHECK_UNARY(ma1.equal(ma2));
}
#endif /* #if HKU_SUPPORT_SERIALIZATION */
/** @} */

View File

@ -1815,4 +1815,13 @@ void export_Indicator_build_in(py::module& m) {
=/×100%
:param int n: )");
m.def("RESULT", py::overload_cast<int>(RESULT));
m.def("RESULT", py::overload_cast<const Indicator&, int>(RESULT), py::arg("data"),
py::arg("result_ix"), R"(RESULT(data, result_ix)
:param Indicator data:
:param int result_ix: )");
}