This commit is contained in:
fasiondog 2019-03-18 03:00:42 +08:00
parent 50a619d01c
commit 13a9f63d3c
5 changed files with 350 additions and 0 deletions

View File

@ -233,6 +233,34 @@ Indicator Indicator::operator<=(const Indicator& ind) {
return p->calculate();
}
Indicator Indicator::operator&(const Indicator& ind) {
if (!m_imp) {
return Indicator();
}
if (!ind.getImp()) {
return Indicator(m_imp->clone());
}
IndicatorImpPtr p = make_shared<IndicatorImp>();
p->add(IndicatorImp::AND, m_imp->clone(), ind.getImp()->clone());
return p->calculate();
}
Indicator Indicator::operator|(const Indicator& ind) {
if (!m_imp) {
return Indicator();
}
if (!ind.getImp()) {
return Indicator(m_imp->clone());
}
IndicatorImpPtr p = make_shared<IndicatorImp>();
p->add(IndicatorImp::OR, m_imp->clone(), ind.getImp()->clone());
return p->calculate();
}
/*
HKU_API Indicator operator+(const Indicator& ind, price_t val) {
if (ind.size() == 0) {

View File

@ -59,6 +59,8 @@ public:
Indicator operator<(const Indicator&);
Indicator operator>=(const Indicator&);
Indicator operator<=(const Indicator&);
Indicator operator&(const Indicator&);
Indicator operator|(const Indicator&);
/** 指标名称 */
string name() const;

View File

@ -357,9 +357,11 @@ Indicator IndicatorImp::calculate() {
break;
case AND:
execute_and();
break;
case OR:
execute_or();
break;
default:
@ -720,6 +722,119 @@ void IndicatorImp::execute_ge() {
}
void IndicatorImp::execute_le() {
m_right->calculate();
m_left->calculate();
IndicatorImp *maxp, *minp;
if (m_left->size() > m_right->size()) {
maxp = m_left.get();
minp = m_right.get();
} else {
maxp = m_right.get();
minp = m_left.get();
}
size_t total = maxp->size();
size_t discard = maxp->size() - minp->size() + minp->discard();
if (discard < maxp->discard()) {
discard = maxp->discard();
}
size_t result_number = std::min(minp->getResultNumber(), maxp->getResultNumber());
size_t diff = maxp->size() - minp->size();
_readyBuffer(total, result_number);
setDiscard(discard);
if (m_left->size() > m_right->size()) {
for (size_t i = discard; i < total; ++i) {
for (size_t r = 0; r < result_number; ++r) {
if (m_left->get(i, r) < m_right->get(i-diff, r) + IND_EQ_THRESHOLD) {
_set(1, i, r);
} else {
_set(0, i, r);
}
}
}
} else {
for (size_t i = discard; i < total; ++i) {
for (size_t r = 0; r < result_number; ++r) {
if (m_left->get(i-diff, r) < m_right->get(i, r) + IND_EQ_THRESHOLD) {
_set(1, i, r);
} else {
_set(0, i, r);
}
}
}
}
}
void IndicatorImp::execute_and() {
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();
}
size_t result_number = std::min(minp->getResultNumber(), maxp->getResultNumber());
size_t diff = maxp->size() - minp->size();
_readyBuffer(total, result_number);
setDiscard(discard);
for (size_t i = discard; i < total; ++i) {
for (size_t r = 0; r < result_number; ++r) {
if (maxp->get(i, r) >= IND_EQ_THRESHOLD
&& minp->get(i-diff, r) >= IND_EQ_THRESHOLD) {
_set(1, i, r);
} else {
_set(0, i, r);
}
}
}
}
void IndicatorImp::execute_or() {
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();
}
size_t result_number = std::min(minp->getResultNumber(), maxp->getResultNumber());
size_t diff = maxp->size() - minp->size();
_readyBuffer(total, result_number);
setDiscard(discard);
for (size_t i = discard; i < total; ++i) {
for (size_t r = 0; r < result_number; ++r) {
if (maxp->get(i, r) >= IND_EQ_THRESHOLD
|| minp->get(i-diff, r) >= IND_EQ_THRESHOLD) {
_set(1, i, r);
} else {
_set(0, i, r);
}
}
}
}
} /* namespace hku */

View File

@ -154,6 +154,8 @@ private:
void execute_lt();
void execute_ge();
void execute_le();
void execute_and();
void execute_or();
protected:
string m_name;

View File

@ -451,4 +451,207 @@ BOOST_AUTO_TEST_CASE( test_operator_lt ) {
BOOST_CHECK(result[i] == 0.0);
}
}
/** @par 检测点 */
BOOST_AUTO_TEST_CASE( test_operator_le ) {
PriceList d1, d2, d3;
for (size_t i = 0; i < 10; ++i) {
d1.push_back(i);
d2.push_back(i);
d3.push_back(i+1);
}
Indicator data1 = PRICELIST(d1);
Indicator data2 = PRICELIST(d2);
Indicator data3 = PRICELIST(d3);
/** @arg ind1 > ind2*/
Indicator result = (data3 <= data1);
BOOST_CHECK(result.size() == 10);
BOOST_CHECK(result.getResultNumber() == 1);
BOOST_CHECK(result.discard() == 0);
for (size_t i = 0; i < 10; ++i) {
BOOST_CHECK(result[i] == 0.0);
}
/** @arg ind1 < ind2 */
result = (data1 <= data3);
for (size_t i = 0; i < 10; ++i) {
BOOST_CHECK(result[i] == 1.0);
}
/** @arg ind1 == ind2 */
result = (data1 <= data2);
for (size_t i = 0; i < 10; ++i) {
BOOST_CHECK(result[i] == 1.0);
}
/** @arg 两个ind的size不同 */
Indicator data4;
result = data1 <= data4;
BOOST_CHECK(result.empty());
BOOST_CHECK(result.size() == 0);
/** @arg 两个ind的size相同但result_number不同 */
StockManager& sm = StockManager::instance();
Stock stock = sm.getStock("sh600000");
KQuery query(0, 10);
KData kdata = stock.getKData(query);
Indicator k = KDATA(kdata);
BOOST_CHECK(k.size() == data1.size());
result = (k <= data1);
BOOST_CHECK(result.size() == k.size());
for (size_t i = 0; i < result.size(); ++i) {
BOOST_CHECK(result[i] == 0.0);
}
}
/** @par 检测点 */
BOOST_AUTO_TEST_CASE( test_getResult_getResultAsPriceList ) {
StockManager& sm = StockManager::instance();
Stock stock = sm.getStock("sh600000");
KQuery query;
KData kdata;
Indicator ikdata, result1;
PriceList result2;
/** @arg 源数据为空 */
ikdata = KDATA(kdata);
result1 = ikdata.getResult(0);
result2 = ikdata.getResultAsPriceList(0);
BOOST_CHECK(result1.size() == 0);
BOOST_CHECK(result2.size() == 0);
/** @arg result_num参数非法 */
query = KQuery(0, 10);
kdata = stock.getKData(query);
ikdata = KDATA(kdata);
BOOST_CHECK(ikdata.size() == 10);
result1 = ikdata.getResult(6);
result2 = ikdata.getResultAsPriceList(6);
BOOST_CHECK(result1.size() == 0);
BOOST_CHECK(result2.size() == 0);
/** @arg 正常获取 */
result1 = ikdata.getResult(0);
result2 = ikdata.getResultAsPriceList(1);
BOOST_CHECK(result1.size() == 10);
BOOST_CHECK(result2.size() == 10);
BOOST_CHECK(result1[0] == 29.5);
BOOST_CHECK(std::fabs(result1[1] - 27.58) < 0.0001);
BOOST_CHECK(result1[9] == 26.45);
BOOST_CHECK(result2[0] == 29.8);
BOOST_CHECK(result2[1] == 28.38);
BOOST_CHECK(result2[9] == 26.55);
}
/** @par 检测点 */
BOOST_AUTO_TEST_CASE( test_LOGIC_AND ) {
PriceList d1, d2, d3;
for (size_t i = 0; i < 10; ++i) {
d1.push_back(0);
d2.push_back(1);
d3.push_back(i);
}
Indicator data1 = PRICELIST(d1);
Indicator data2 = PRICELIST(d2);
Indicator data3 = PRICELIST(d3);
/** @arg ind1为全0 ind2为全1 */
Indicator result = data1 & data2;
BOOST_CHECK(result.size() == 10);
BOOST_CHECK(result.getResultNumber() == 1);
BOOST_CHECK(result.discard() == 0);
for (size_t i = 0; i < 10; ++i) {
BOOST_CHECK(result[i] == 0.0);
}
/** @arg ind为全0 val为1 */
/*result = IND_AND(data1, 1.0);
BOOST_CHECK(result.size() == 10);
BOOST_CHECK(result.getResultNumber() == 1);
BOOST_CHECK(result.discard() == 0);
for (size_t i = 0; i < 10; ++i) {
BOOST_CHECK(result[i] == 0.0);
}*/
/** @arg ind1为全0 ind2为从0开始的整数 */
result = data1 & data3;
BOOST_CHECK(result.size() == 10);
BOOST_CHECK(result.getResultNumber() == 1);
BOOST_CHECK(result.discard() == 0);
for (size_t i = 0; i < 10; ++i) {
BOOST_CHECK(result[i] == 0.0);
}
/** @arg ind1为全1 ind2为从0开始的整数 */
result = data2 & data3;
BOOST_CHECK(result.size() == 10);
BOOST_CHECK(result.getResultNumber() == 1);
BOOST_CHECK(result.discard() == 0);
BOOST_CHECK(result[0] == 0.0);
for (size_t i = 1; i < 10; ++i) {
BOOST_CHECK(result[i] == 1.0);
}
/** @arg 两个ind的size不同 */
Indicator data4;
result = data1 & data4;
BOOST_CHECK(result.empty());
BOOST_CHECK(result.size() == 0);
}
/** @par 检测点 */
BOOST_AUTO_TEST_CASE( test_LOGIC_OR ) {
PriceList d1, d2, d3;
for (size_t i = 0; i < 10; ++i) {
d1.push_back(0);
d2.push_back(1);
d3.push_back(i);
}
Indicator data1 = PRICELIST(d1);
Indicator data2 = PRICELIST(d2);
Indicator data3 = PRICELIST(d3);
/** @arg ind1为全0 ind2为全1 */
Indicator result = data1 | data2;
BOOST_CHECK(result.size() == 10);
BOOST_CHECK(result.getResultNumber() == 1);
BOOST_CHECK(result.discard() == 0);
for (size_t i = 0; i < 10; ++i) {
BOOST_CHECK(result[i] == 1.0);
}
/** @arg ind1为全0 ind2为从0开始的整数 */
result = data1 | data3;
BOOST_CHECK(result.size() == 10);
BOOST_CHECK(result.getResultNumber() == 1);
BOOST_CHECK(result.discard() == 0);
BOOST_CHECK(result[0] == 0.0);
for (size_t i = 1; i < 10; ++i) {
BOOST_CHECK(result[i] == 1.0);
}
/** @arg ind1为全1 ind2为从0开始的整数 */
result = data2 | data3;
BOOST_CHECK(result.size() == 10);
BOOST_CHECK(result.getResultNumber() == 1);
BOOST_CHECK(result.discard() == 0);
for (size_t i = 0; i < 10; ++i) {
BOOST_CHECK(result[i] == 1.0);
}
/** @arg 两个ind的size不同 */
Indicator data4;
result = data1 | data4;
BOOST_CHECK(result.empty());
BOOST_CHECK(result.size() == 0);
}
/** @} */