Skip to content

Commit 852f084

Browse files
committed
add ISNA, ISINF, ISINFA 指标
1 parent f14fe82 commit 852f084

File tree

14 files changed

+565
-0
lines changed

14 files changed

+565
-0
lines changed

hikyuu_cpp/hikyuu/indicator/build_in.h

+3
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,10 @@
5656
#include "crt/INSUM.h"
5757
#include "crt/IR.h"
5858
#include "crt/INTPART.h"
59+
#include "crt/ISINF.h"
60+
#include "crt/ISINFA.h"
5961
#include "crt/ISLASTBAR.h"
62+
#include "crt/ISNA.h"
6063
#include "crt/LAST.h"
6164
#include "crt/LIUTONGPAN.h"
6265
#include "crt/LLV.h"
+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright (c) 2025 hikyuu.org
3+
*
4+
* Created on: 2025-01-08
5+
* Author: fasiondog
6+
*/
7+
8+
#pragma once
9+
#ifndef INDICATOR_CRT_ISINF_H_
10+
#define INDICATOR_CRT_ISINF_H_
11+
12+
#include "CVAL.h"
13+
14+
namespace hku {
15+
16+
/**
17+
* 是否为正无穷大 (负无穷大使用 ISINFA)
18+
* @ingroup Indicator
19+
*/
20+
Indicator HKU_API ISINF();
21+
22+
inline Indicator ISINF(const Indicator& ind) {
23+
return ISINF()(ind);
24+
}
25+
26+
} // namespace hku
27+
28+
#endif /* INDICATOR_CRT_ISINF_H_ */
+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright (c) 2025 hikyuu.org
3+
*
4+
* Created on: 2025-01-08
5+
* Author: fasiondog
6+
*/
7+
8+
#pragma once
9+
#ifndef INDICATOR_CRT_ISINFA_H_
10+
#define INDICATOR_CRT_ISINFA_H_
11+
12+
#include "CVAL.h"
13+
14+
namespace hku {
15+
16+
/**
17+
* 是否为负无穷大 (正无穷大使用 ISINF)
18+
* @ingroup Indicator
19+
*/
20+
Indicator HKU_API ISINFA();
21+
22+
inline Indicator ISINFA(const Indicator& ind) {
23+
return ISINFA()(ind);
24+
}
25+
26+
} // namespace hku
27+
28+
#endif /* INDICATOR_CRT_ISINFA_H_ */
+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright (c) 2025 hikyuu.org
3+
*
4+
* Created on: 2025-01-08
5+
* Author: fasiondog
6+
*/
7+
8+
#pragma once
9+
#ifndef INDICATOR_CRT_ISNA_H_
10+
#define INDICATOR_CRT_ISNA_H_
11+
12+
#include "CVAL.h"
13+
14+
namespace hku {
15+
16+
/**
17+
* 是否为 NaN 值
18+
* @param ignore_discard 是否忽略discard值,默认为false
19+
* @ingroup Indicator
20+
*/
21+
Indicator HKU_API ISNA(bool ignore_discard = false);
22+
23+
inline Indicator ISNA(const Indicator& ind, bool ignore_discard = false) {
24+
return ISNA(ignore_discard)(ind);
25+
}
26+
27+
} // namespace hku
28+
29+
#endif /* INDICATOR_CRT_ISNA_H_ */
+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright (c) 2025 hikyuu.org
3+
*
4+
* Created on: 2025-01-08
5+
* Author: fasiondog
6+
*/
7+
8+
#include "IIsInf.h"
9+
10+
#if HKU_SUPPORT_SERIALIZATION
11+
BOOST_CLASS_EXPORT(hku::IIsInf)
12+
#endif
13+
14+
namespace hku {
15+
16+
IIsInf::IIsInf() : IndicatorImp("ISINF", 1) {}
17+
18+
IIsInf::~IIsInf() {}
19+
20+
void IIsInf::_calculate(const Indicator &data) {
21+
size_t total = data.size();
22+
m_discard = data.discard();
23+
if (m_discard >= total) {
24+
m_discard = total;
25+
return;
26+
}
27+
28+
auto const *src = data.data();
29+
auto *dst = this->data();
30+
value_t positive_inf = std::numeric_limits<value_t>::infinity();
31+
for (size_t i = m_discard; i < total; ++i) {
32+
dst[i] = (src[i] == positive_inf);
33+
}
34+
}
35+
36+
Indicator HKU_API ISINF() {
37+
return Indicator(make_shared<IIsInf>());
38+
}
39+
40+
} /* namespace hku */
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright (c) 2025 hikyuu.org
3+
*
4+
* Created on: 2025-01-08
5+
* Author: fasiondog
6+
*/
7+
8+
#pragma once
9+
#ifndef INDICATOR_IMP_IISINF_H_
10+
#define INDICATOR_IMP_IISINF_H_
11+
12+
#include "../Indicator.h"
13+
14+
namespace hku {
15+
16+
class IIsInf : public IndicatorImp {
17+
INDICATOR_IMP(IIsInf)
18+
INDICATOR_IMP_NO_PRIVATE_MEMBER_SERIALIZATION
19+
20+
public:
21+
IIsInf();
22+
virtual ~IIsInf();
23+
};
24+
25+
} /* namespace hku */
26+
#endif /* INDICATOR_IMP_IISINF_H_ */
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright (c) 2025 hikyuu.org
3+
*
4+
* Created on: 2025-01-08
5+
* Author: fasiondog
6+
*/
7+
8+
#include "IIsInfa.h"
9+
10+
#if HKU_SUPPORT_SERIALIZATION
11+
BOOST_CLASS_EXPORT(hku::IIsInfa)
12+
#endif
13+
14+
namespace hku {
15+
16+
IIsInfa::IIsInfa() : IndicatorImp("ISINFA", 1) {}
17+
18+
IIsInfa::~IIsInfa() {}
19+
20+
void IIsInfa::_calculate(const Indicator &data) {
21+
size_t total = data.size();
22+
m_discard = data.discard();
23+
if (m_discard >= total) {
24+
m_discard = total;
25+
return;
26+
}
27+
28+
auto const *src = data.data();
29+
auto *dst = this->data();
30+
value_t negative_inf = -std::numeric_limits<value_t>::infinity();
31+
for (size_t i = m_discard; i < total; ++i) {
32+
dst[i] = (src[i] == negative_inf);
33+
}
34+
}
35+
36+
Indicator HKU_API ISINFA() {
37+
return Indicator(make_shared<IIsInfa>());
38+
}
39+
40+
} /* namespace hku */
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright (c) 2025 hikyuu.org
3+
*
4+
* Created on: 2025-01-08
5+
* Author: fasiondog
6+
*/
7+
8+
#pragma once
9+
#ifndef INDICATOR_IMP_IISINFA_H_
10+
#define INDICATOR_IMP_IISINFA_H_
11+
12+
#include "../Indicator.h"
13+
14+
namespace hku {
15+
16+
class IIsInfa : public IndicatorImp {
17+
INDICATOR_IMP(IIsInfa)
18+
INDICATOR_IMP_NO_PRIVATE_MEMBER_SERIALIZATION
19+
20+
public:
21+
IIsInfa();
22+
virtual ~IIsInfa();
23+
};
24+
25+
} /* namespace hku */
26+
#endif /* INDICATOR_IMP_IISINFA_H_ */
+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright (c) 2025 hikyuu.org
3+
*
4+
* Created on: 2025-01-08
5+
* Author: fasiondog
6+
*/
7+
8+
#include "IIsNa.h"
9+
10+
#if HKU_SUPPORT_SERIALIZATION
11+
BOOST_CLASS_EXPORT(hku::IIsNa)
12+
#endif
13+
14+
namespace hku {
15+
16+
IIsNa::IIsNa() : IndicatorImp("ISNA", 1) {
17+
setParam<bool>("ignore_discard", false);
18+
}
19+
20+
IIsNa::~IIsNa() {}
21+
22+
void IIsNa::_calculate(const Indicator &data) {
23+
size_t total = data.size();
24+
m_discard = getParam<bool>("ignore_discard") ? 0 : data.discard();
25+
if (m_discard >= total) {
26+
m_discard = total;
27+
return;
28+
}
29+
30+
auto const *src = data.data();
31+
auto *dst = this->data();
32+
for (size_t i = m_discard; i < total; ++i) {
33+
dst[i] = std::isnan(src[i]);
34+
}
35+
}
36+
37+
Indicator HKU_API ISNA(bool ignore_discard) {
38+
auto p = make_shared<IIsNa>();
39+
p->setParam<bool>("ignore_discard", ignore_discard);
40+
return Indicator(p);
41+
}
42+
43+
} /* namespace hku */
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright (c) 2025 hikyuu.org
3+
*
4+
* Created on: 2025-01-08
5+
* Author: fasiondog
6+
*/
7+
8+
#pragma once
9+
#ifndef INDICATOR_IMP_IISNA_H_
10+
#define INDICATOR_IMP_IISNA_H_
11+
12+
#include "../Indicator.h"
13+
14+
namespace hku {
15+
16+
class IIsNa : public IndicatorImp {
17+
INDICATOR_IMP(IIsNa)
18+
INDICATOR_IMP_NO_PRIVATE_MEMBER_SERIALIZATION
19+
20+
public:
21+
IIsNa();
22+
virtual ~IIsNa();
23+
};
24+
25+
} /* namespace hku */
26+
#endif /* INDICATOR_IMP_IISNA_H_ */
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/*
2+
* Copyright (c) 2025 hikyuu.org
3+
*
4+
* Created on: 2025-01-08
5+
* Author: fasiondog
6+
*/
7+
8+
#include "../test_config.h"
9+
#include <fstream>
10+
#include <hikyuu/StockManager.h>
11+
#include <hikyuu/indicator/crt/ISINF.h>
12+
#include <hikyuu/indicator/crt/KDATA.h>
13+
#include <hikyuu/indicator/crt/PRICELIST.h>
14+
15+
using namespace hku;
16+
17+
/**
18+
* @defgroup test_indicator_ISINF test_indicator_ISINF
19+
* @ingroup test_hikyuu_indicator_suite
20+
* @{
21+
*/
22+
23+
/** @par 检测点 */
24+
TEST_CASE("test_ISINF") {
25+
price_t nan = Null<price_t>();
26+
price_t positive_inf = std::numeric_limits<price_t>::infinity();
27+
price_t negative_inf = -std::numeric_limits<price_t>::infinity();
28+
29+
Indicator data = PRICELIST(PriceList{nan, nan, 1, positive_inf, 3, negative_inf}, 2);
30+
Indicator result = ISINF(data);
31+
CHECK_EQ(result.name(), "ISINF");
32+
CHECK_EQ(result.discard(), 2);
33+
CHECK_EQ(result.size(), data.size());
34+
for (size_t i = 0; i < result.discard(); ++i) {
35+
CHECK_UNARY(std::isnan(result[i]));
36+
}
37+
38+
auto expect = PriceList{nan, nan, 0., 1., 0., 0.};
39+
for (size_t i = result.discard(); i < result.size(); ++i) {
40+
CHECK_EQ(result[i], expect[i]);
41+
}
42+
}
43+
44+
//-----------------------------------------------------------------------------
45+
// test export
46+
//-----------------------------------------------------------------------------
47+
#if HKU_SUPPORT_SERIALIZATION
48+
49+
/** @par 检测点 */
50+
TEST_CASE("test_ISINF_export") {
51+
StockManager& sm = StockManager::instance();
52+
string filename(sm.tmpdir());
53+
filename += "/ISINF.xml";
54+
55+
Stock stock = sm.getStock("sh000001");
56+
KData kdata = stock.getKData(KQuery(-5));
57+
Indicator x1 = ISINF(CLOSE(kdata));
58+
{
59+
std::ofstream ofs(filename);
60+
boost::archive::xml_oarchive oa(ofs);
61+
oa << BOOST_SERIALIZATION_NVP(x1);
62+
}
63+
64+
Indicator x2;
65+
{
66+
std::ifstream ifs(filename);
67+
boost::archive::xml_iarchive ia(ifs);
68+
ia >> BOOST_SERIALIZATION_NVP(x2);
69+
}
70+
71+
CHECK_UNARY(x1.size() == x2.size());
72+
CHECK_UNARY(x1.discard() == x2.discard());
73+
CHECK_UNARY(x1.getResultNumber() == x2.getResultNumber());
74+
for (size_t i = 0; i < x1.size(); ++i) {
75+
CHECK_EQ(x1[i], doctest::Approx(x2[i]).epsilon(0.00001));
76+
}
77+
}
78+
#endif /* #if HKU_SUPPORT_SERIALIZATION */
79+
80+
/** @} */

0 commit comments

Comments
 (0)