diff --git a/libs/hikyuu/indicator/Indicator.cpp b/libs/hikyuu/indicator/Indicator.cpp index 374d0c31..6d29ef7a 100644 --- a/libs/hikyuu/indicator/Indicator.cpp +++ b/libs/hikyuu/indicator/Indicator.cpp @@ -80,7 +80,7 @@ size_t Indicator::size() const { } HKU_API Indicator operator+(const Indicator& ind1, const Indicator& ind2) { - if (ind1.size() != ind2.size() || ind1.size() == 0) { + /*if (ind1.size() != ind2.size() || ind1.size() == 0) { return Indicator(); } @@ -96,12 +96,13 @@ HKU_API Indicator operator+(const Indicator& ind1, const Indicator& ind2) { } } - return Indicator(imp); + return Indicator(imp);*/ + return Indicator(ind1.getImp() + ind2.getImp()); } HKU_API Indicator operator-(const Indicator& ind1, const Indicator& ind2) { - if (ind1.size() != ind2.size() || ind1.size() == 0) { + /*if (ind1.size() != ind2.size() || ind1.size() == 0) { return Indicator(); } @@ -117,12 +118,13 @@ HKU_API Indicator operator-(const Indicator& ind1, const Indicator& ind2) { } } - return Indicator(imp); + return Indicator(imp);*/ + return Indicator(ind1.getImp() - ind2.getImp()); } HKU_API Indicator operator*(const Indicator& ind1, const Indicator& ind2) { - if (ind1.size() != ind2.size() || ind1.size() == 0) { + /*if (ind1.size() != ind2.size() || ind1.size() == 0) { return Indicator(); } @@ -139,11 +141,13 @@ HKU_API Indicator operator*(const Indicator& ind1, const Indicator& ind2) { } return Indicator(imp); + */ + return Indicator(ind1.getImp() * ind2.getImp()); } HKU_API Indicator operator/(const Indicator& ind1, const Indicator& ind2) { - if (ind1.size() != ind2.size() || ind1.size() == 0) { + /*if (ind1.size() != ind2.size() || ind1.size() == 0) { return Indicator(); } @@ -163,7 +167,8 @@ HKU_API Indicator operator/(const Indicator& ind1, const Indicator& ind2) { } } - return Indicator(imp); + return Indicator(imp);*/ + return Indicator(ind1.getImp() / ind2.getImp()); } } /* namespace hku */ diff --git a/libs/hikyuu/indicator/Indicator.h b/libs/hikyuu/indicator/Indicator.h index ff2f1646..3878e1b0 100644 --- a/libs/hikyuu/indicator/Indicator.h +++ b/libs/hikyuu/indicator/Indicator.h @@ -110,6 +110,8 @@ public: return m_imp->getParam(name); } + IndicatorImpPtr getImp() const { return m_imp; } + protected: IndicatorImpPtr m_imp; diff --git a/libs/hikyuu/indicator/IndicatorImp.cpp b/libs/hikyuu/indicator/IndicatorImp.cpp index 6e790d84..973c88da 100644 --- a/libs/hikyuu/indicator/IndicatorImp.cpp +++ b/libs/hikyuu/indicator/IndicatorImp.cpp @@ -28,17 +28,17 @@ HKU_API std::ostream & operator<<(std::ostream& os, const IndicatorImpPtr& imp) IndicatorImp::IndicatorImp() -: m_name("IndicatorImp"), m_discard(0), m_result_num(0) { +: m_name("IndicatorImp"), m_discard(0), m_result_num(0), m_optype(LEAF) { memset(m_pBuffer, NULL, sizeof(PriceList*) * MAX_RESULT_NUM); } IndicatorImp::IndicatorImp(const string& name) -: m_name(name), m_discard(0), m_result_num(0) { +: m_name(name), m_discard(0), m_result_num(0), m_optype(LEAF) { memset(m_pBuffer, NULL, sizeof(PriceList*) * MAX_RESULT_NUM); } IndicatorImp::IndicatorImp(const string& name, size_t result_num) -: m_name(name), m_discard(0) { +: m_name(name), m_discard(0), m_optype(LEAF) { memset(m_pBuffer, NULL, sizeof(PriceList*) * MAX_RESULT_NUM); m_result_num = result_num < MAX_RESULT_NUM ? result_num : MAX_RESULT_NUM; for (size_t i = 0; i < m_result_num; ++i) { @@ -155,4 +155,94 @@ void IndicatorImp::calculate(const Indicator& data) { } } + +HKU_API IndicatorImpPtr operator+(const IndicatorImpPtr& ind1, + const IndicatorImpPtr& ind2){ + if (!ind1 || !ind2 || ind1->size() ==0 || ind1->size() != ind2->size()) { + return IndicatorImpPtr(); + } + + size_t result_number = std::min(ind1->getResultNumber(), ind2->getResultNumber()); + size_t total = ind1->size(); + size_t discard = std::max(ind1->discard(), ind2->discard()); + IndicatorImpPtr imp(new IndicatorImp()); + imp->_readyBuffer(total, result_number); + imp->setDiscard(discard); + for (size_t i = discard; i < total; ++i) { + for (size_t r = 0; r < result_number; ++r) { + imp->_set(ind1->get(i, r) + ind2->get(i, r), i, r); + } + } + + return imp; +} + + +HKU_API IndicatorImpPtr operator-(const IndicatorImpPtr& ind1, + const IndicatorImpPtr& ind2) { + if (!ind1 || !ind2 || ind1->size() ==0 || ind1->size() != ind2->size()) { + return IndicatorImpPtr(); + } + + size_t result_number = std::min(ind1->getResultNumber(), ind2->getResultNumber()); + size_t total = ind1->size(); + size_t discard = std::max(ind1->discard(), ind2->discard()); + IndicatorImpPtr imp(new IndicatorImp()); + imp->_readyBuffer(total, result_number); + imp->setDiscard(discard); + for (size_t i = discard; i < total; ++i) { + for (size_t r = 0; r < result_number; ++r) { + imp->_set(ind1->get(i, r) - ind2->get(i, r), i, r); + } + } + + return imp; +} + +HKU_API IndicatorImpPtr operator*(const IndicatorImpPtr& ind1, + const IndicatorImpPtr& ind2) { + if (!ind1 || !ind2 || ind1->size() ==0 || ind1->size() != ind2->size()) { + return IndicatorImpPtr(); + } + + size_t result_number = std::min(ind1->getResultNumber(), ind2->getResultNumber()); + size_t total = ind1->size(); + size_t discard = std::max(ind1->discard(), ind2->discard()); + IndicatorImpPtr imp(new IndicatorImp()); + imp->_readyBuffer(total, result_number); + imp->setDiscard(discard); + for (size_t i = discard; i < total; ++i) { + for (size_t r = 0; r < result_number; ++r) { + imp->_set(ind1->get(i, r) * ind2->get(i, r), i, r); + } + } + + return imp; +} + +HKU_API IndicatorImpPtr operator/(const IndicatorImpPtr& ind1, + const IndicatorImpPtr& ind2) { + if (!ind1 || !ind2 || ind1->size() ==0 || ind1->size() != ind2->size()) { + return IndicatorImpPtr(); + } + + size_t result_number = std::min(ind1->getResultNumber(), ind2->getResultNumber()); + size_t total = ind1->size(); + size_t discard = std::max(ind1->discard(), ind2->discard()); + IndicatorImpPtr imp(new IndicatorImp()); + imp->_readyBuffer(total, result_number); + imp->setDiscard(discard); + for (size_t i = discard; i < total; ++i) { + for (size_t r = 0; r < result_number; ++r) { + if (ind2->get(i, r) == 0.0) { + imp->_set(Null(), i, r); + } else { + imp->_set(ind1->get(i, r) / ind2->get(i, r), i, r); + } + } + } + + return imp; +} + } /* namespace hku */ diff --git a/libs/hikyuu/indicator/IndicatorImp.h b/libs/hikyuu/indicator/IndicatorImp.h index 18c3fb2a..54e41f43 100644 --- a/libs/hikyuu/indicator/IndicatorImp.h +++ b/libs/hikyuu/indicator/IndicatorImp.h @@ -33,6 +33,23 @@ class HKU_API Indicator; class HKU_API IndicatorImp { PARAMETER_SUPPORT +public: + enum OPType { + LEAF, ///<叶子节点 + OP, /// OP(OP1,OP2) OP1->calcalue(OP2->calculate(ind)) + ADD, ///<加 + SUB, ///<减 + MUL, ///<乘 + DIV, ///<除 + EQ, ///<等于 + GT, ///<大于 + LT, ///<小于 + NE, ///<不等于 + GE, ///<大于等于 + LE, ///<小于等于 + INVALID + }; + public: /** 默认构造函数 */ IndicatorImp(); @@ -114,6 +131,10 @@ protected: size_t m_result_num; PriceList *m_pBuffer[MAX_RESULT_NUM]; + OPType m_optype; + IndicatorImpPtr m_left; + IndicatorImpPtr m_right; + #if HKU_SUPPORT_SERIALIZATION private: friend class boost::serialization::access; @@ -182,5 +203,11 @@ typedef shared_ptr IndicatorImpPtr; HKU_API std::ostream & operator<<(std::ostream&, const IndicatorImp&); HKU_API std::ostream & operator<<(std::ostream&, const IndicatorImpPtr&); + +HKU_API IndicatorImpPtr operator+(const IndicatorImpPtr&, const IndicatorImpPtr&); +HKU_API IndicatorImpPtr operator-(const IndicatorImpPtr&, const IndicatorImpPtr&); +HKU_API IndicatorImpPtr operator*(const IndicatorImpPtr&, const IndicatorImpPtr&); +HKU_API IndicatorImpPtr operator/(const IndicatorImpPtr&, const IndicatorImpPtr&); + } /* namespace hku */ #endif /* INDICATORIMP_H_ */