diff --git a/hikyuu_cpp/hikyuu/StockManager.cpp b/hikyuu_cpp/hikyuu/StockManager.cpp index 51285c4e..381a30cd 100644 --- a/hikyuu_cpp/hikyuu/StockManager.cpp +++ b/hikyuu_cpp/hikyuu/StockManager.cpp @@ -133,9 +133,8 @@ void StockManager::init( void StockManager::setKDataDriver(const KDataDriverPtr& driver) { - string funcname(" [StockManager::setKDataDriver]"); if (!driver) { - HKU_ERROR("kdata driver is null!" << funcname); + HKU_ERROR("kdata driver is null! [StockManager::setKDataDriver]"); return; } @@ -149,7 +148,7 @@ void StockManager::setKDataDriver(const KDataDriverPtr& driver) { try { preload_day = m_preloadParam.get("day"); if (preload_day) - HKU_INFO("Preloading all day kdata to buffer!" << funcname); + HKU_INFO("Preloading all day kdata to buffer!"); } catch(...) { preload_day = false; } @@ -158,7 +157,7 @@ void StockManager::setKDataDriver(const KDataDriverPtr& driver) { try { preload_week = m_preloadParam.get("week"); if (preload_week) - HKU_INFO("Preloading all week kdata to buffer!" << funcname); + HKU_INFO("Preloading all week kdata to buffer!"); } catch(...) { preload_week = false; } @@ -167,7 +166,7 @@ void StockManager::setKDataDriver(const KDataDriverPtr& driver) { try { preload_month = m_preloadParam.get("month"); if (preload_week) - HKU_INFO("Preloading all month kdata to buffer!" << funcname); + HKU_INFO("Preloading all month kdata to buffer!"); } catch(...) { preload_month = false; } @@ -176,7 +175,7 @@ void StockManager::setKDataDriver(const KDataDriverPtr& driver) { try { preload_quarter = m_preloadParam.get("quarter"); if (preload_quarter) - HKU_INFO("Preloading all quarter kdata to buffer!" << funcname); + HKU_INFO("Preloading all quarter kdata to buffer!"); } catch(...) { preload_quarter = false; } @@ -185,7 +184,7 @@ void StockManager::setKDataDriver(const KDataDriverPtr& driver) { try { preload_halfyear = m_preloadParam.get("halfyear"); if (preload_halfyear) - HKU_INFO("Preloading all halfyear kdata to buffer!" << funcname); + HKU_INFO("Preloading all halfyear kdata to buffer!"); } catch(...) { preload_halfyear = false; } @@ -194,7 +193,7 @@ void StockManager::setKDataDriver(const KDataDriverPtr& driver) { try { preload_year = m_preloadParam.get("year"); if (preload_year) - HKU_INFO("Preloading all year kdata to buffer!" << funcname); + HKU_INFO("Preloading all year kdata to buffer!"); } catch(...) { preload_year = false; } @@ -203,7 +202,7 @@ void StockManager::setKDataDriver(const KDataDriverPtr& driver) { try { preload_min = m_preloadParam.get("min"); if (preload_min) - HKU_INFO("Preloading all 1 min kdata to buffer!" << funcname); + HKU_INFO("Preloading all 1 min kdata to buffer!"); } catch(...) { preload_min = false; } @@ -212,7 +211,7 @@ void StockManager::setKDataDriver(const KDataDriverPtr& driver) { try { preload_min5 = m_preloadParam.get("min5"); if (preload_min5) - HKU_INFO("Preloading all 5 min kdata to buffer!" << funcname); + HKU_INFO("Preloading all 5 min kdata to buffer!"); } catch(...) { preload_min5 = false; } @@ -221,7 +220,7 @@ void StockManager::setKDataDriver(const KDataDriverPtr& driver) { try { preload_min15 = m_preloadParam.get("min15"); if (preload_min15) - HKU_INFO("Preloading all 15 min kdata to buffer!" << funcname); + HKU_INFO("Preloading all 15 min kdata to buffer!"); } catch(...) { preload_min15 = false; } @@ -230,7 +229,7 @@ void StockManager::setKDataDriver(const KDataDriverPtr& driver) { try { preload_min30 = m_preloadParam.get("min30"); if (preload_min30) - HKU_INFO("Preloading all 30 min kdata to buffer!" << funcname); + HKU_INFO("Preloading all 30 min kdata to buffer!"); } catch(...) { preload_min30 = false; } @@ -239,7 +238,7 @@ void StockManager::setKDataDriver(const KDataDriverPtr& driver) { try { preload_min60 = m_preloadParam.get("min60"); if (preload_min60) - HKU_INFO("Preloading all 60 min kdata to buffer!" << funcname); + HKU_INFO("Preloading all 60 min kdata to buffer!"); } catch(...) { preload_min60 = false; } diff --git a/hikyuu_cpp/hikyuu/indicator/Indicator.cpp b/hikyuu_cpp/hikyuu/indicator/Indicator.cpp index 1ccbc57f..a36c14c6 100644 --- a/hikyuu_cpp/hikyuu/indicator/Indicator.cpp +++ b/hikyuu_cpp/hikyuu/indicator/Indicator.cpp @@ -84,6 +84,22 @@ Indicator Indicator::clone() const { return m_imp ? Indicator(m_imp->clone()) : Indicator(); } +PriceList Indicator::getResultAsPriceList(size_t num) const { + if (!m_imp) { + HKU_WARN("indicator imptr is null! [Indicator::getResultAsPriceList]"); + return PriceList(); + } + return m_imp->getResultAsPriceList(num); +} + +Indicator Indicator::getResult(size_t num) const { + if (!m_imp) { + HKU_WARN("indicator imptr is null! [Indicator::getResult]"); + return Indicator(); + } + return m_imp->getResult(num); +} + Indicator Indicator::operator()(const Indicator& ind) { if (!m_imp) return Indicator(); @@ -92,7 +108,7 @@ Indicator Indicator::operator()(const Indicator& ind) { return Indicator(m_imp); IndicatorImpPtr p = m_imp->clone(); - p->add(IndicatorImp::OP, IndicatorImpPtr(), ind.getImp()->clone()); + p->add(IndicatorImp::OP, IndicatorImpPtr(), ind.getImp()); return p->calculate(); } @@ -102,7 +118,7 @@ HKU_API Indicator operator+(const Indicator& ind1, const Indicator& ind2) { } IndicatorImpPtr p = make_shared(); - p->add(IndicatorImp::ADD, ind1.getImp()->clone(), ind2.getImp()->clone()); + p->add(IndicatorImp::ADD, ind1.getImp(), ind2.getImp()); return p->calculate(); } @@ -112,7 +128,7 @@ HKU_API Indicator operator-(const Indicator& ind1, const Indicator& ind2) { } IndicatorImpPtr p = make_shared(); - p->add(IndicatorImp::SUB, ind1.getImp()->clone(), ind2.getImp()->clone()); + p->add(IndicatorImp::SUB, ind1.getImp(), ind2.getImp()); return p->calculate(); } @@ -122,7 +138,7 @@ HKU_API Indicator operator*(const Indicator& ind1, const Indicator& ind2) { } IndicatorImpPtr p = make_shared(); - p->add(IndicatorImp::MUL, ind1.getImp()->clone(), ind2.getImp()->clone()); + p->add(IndicatorImp::MUL, ind1.getImp(), ind2.getImp()); return p->calculate(); } @@ -132,7 +148,7 @@ HKU_API Indicator operator/(const Indicator& ind1, const Indicator& ind2) { } IndicatorImpPtr p = make_shared(); - p->add(IndicatorImp::DIV, ind1.getImp()->clone(), ind2.getImp()->clone()); + p->add(IndicatorImp::DIV, ind1.getImp(), ind2.getImp()); return p->calculate(); } @@ -142,7 +158,7 @@ HKU_API Indicator operator==(const Indicator& ind1, const Indicator& ind2) { } IndicatorImpPtr p = make_shared(); - p->add(IndicatorImp::EQ, ind1.getImp()->clone(), ind2.getImp()->clone()); + p->add(IndicatorImp::EQ, ind1.getImp(), ind2.getImp()); return p->calculate(); } @@ -152,7 +168,7 @@ HKU_API Indicator operator!=(const Indicator& ind1, const Indicator& ind2) { } IndicatorImpPtr p = make_shared(); - p->add(IndicatorImp::NE, ind1.getImp()->clone(), ind2.getImp()->clone()); + p->add(IndicatorImp::NE, ind1.getImp(), ind2.getImp()); return p->calculate(); } @@ -162,7 +178,7 @@ HKU_API Indicator operator>(const Indicator& ind1, const Indicator& ind2) { } IndicatorImpPtr p = make_shared(); - p->add(IndicatorImp::GT, ind1.getImp()->clone(), ind2.getImp()->clone()); + p->add(IndicatorImp::GT, ind1.getImp(), ind2.getImp()); return p->calculate(); } @@ -172,7 +188,7 @@ HKU_API Indicator operator<(const Indicator& ind1, const Indicator& ind2) { } IndicatorImpPtr p = make_shared(); - p->add(IndicatorImp::LT, ind1.getImp()->clone(), ind2.getImp()->clone()); + p->add(IndicatorImp::LT, ind1.getImp(), ind2.getImp()); return p->calculate(); } @@ -182,7 +198,7 @@ HKU_API Indicator operator>=(const Indicator& ind1, const Indicator& ind2) { } IndicatorImpPtr p = make_shared(); - p->add(IndicatorImp::GE, ind1.getImp()->clone(), ind2.getImp()->clone()); + p->add(IndicatorImp::GE, ind1.getImp(), ind2.getImp()); return p->calculate(); } @@ -192,7 +208,7 @@ HKU_API Indicator operator<=(const Indicator& ind1, const Indicator& ind2) { } IndicatorImpPtr p = make_shared(); - p->add(IndicatorImp::LE, ind1.getImp()->clone(), ind2.getImp()->clone()); + p->add(IndicatorImp::LE, ind1.getImp(), ind2.getImp()); return p->calculate(); } @@ -202,7 +218,7 @@ HKU_API Indicator operator&(const Indicator& ind1, const Indicator& ind2) { } IndicatorImpPtr p = make_shared(); - p->add(IndicatorImp::AND, ind1.getImp()->clone(), ind2.getImp()->clone()); + p->add(IndicatorImp::AND, ind1.getImp(), ind2.getImp()); return p->calculate(); } @@ -212,7 +228,7 @@ HKU_API Indicator operator|(const Indicator& ind1, const Indicator& ind2) { } IndicatorImpPtr p = make_shared(); - p->add(IndicatorImp::OR, ind1.getImp()->clone(), ind2.getImp()->clone()); + p->add(IndicatorImp::OR, ind1.getImp(), ind2.getImp()); return p->calculate(); } diff --git a/hikyuu_cpp/hikyuu/indicator/Indicator.h b/hikyuu_cpp/hikyuu/indicator/Indicator.h index cff6725d..fb3a189a 100644 --- a/hikyuu_cpp/hikyuu/indicator/Indicator.h +++ b/hikyuu_cpp/hikyuu/indicator/Indicator.h @@ -86,6 +86,13 @@ public: * @note 不做下标越界检查,也不抛出异常 */ price_t operator[](size_t pos) const { +#if CHECK_ACCESS_BOUND + if (!m_imp) { + throw(std::out_of_range( + "Try to access empty indicator! [Indicator::get]")); + return Null(); + } +#endif return m_imp->get(pos, 0); } @@ -96,16 +103,19 @@ public: * @note 不做下标越界检查,不会抛出异常 */ price_t get(size_t pos, size_t num = 0) const { +#if CHECK_ACCESS_BOUND + if (!m_imp) { + throw(std::out_of_range( + "Try to access empty indicator! [Indicator::get]")); + return Null(); + } +#endif return m_imp->get(pos, num); } - Indicator getResult(size_t num) const { - return m_imp->getResult(num); - } + Indicator getResult(size_t num) const; - PriceList getResultAsPriceList(size_t num) const { - return m_imp->getResultAsPriceList(num); - } + PriceList getResultAsPriceList(size_t num) const; template void setParam(const string& name, const ValueType& value) { diff --git a/hikyuu_cpp/hikyuu/indicator/IndicatorImp.cpp b/hikyuu_cpp/hikyuu/indicator/IndicatorImp.cpp index f5f2b8dc..21f625c5 100644 --- a/hikyuu_cpp/hikyuu/indicator/IndicatorImp.cpp +++ b/hikyuu_cpp/hikyuu/indicator/IndicatorImp.cpp @@ -296,8 +296,8 @@ void IndicatorImp::add(OPType op, IndicatorImpPtr left, IndicatorImpPtr right) { } m_optype = op; - m_left = left; - m_right = new_right ? new_right : right; + m_left = left ? left->clone() : left; + m_right = new_right ? new_right : right->clone(); } Indicator IndicatorImp::calculate() { diff --git a/hikyuu_cpp/hikyuu/indicator/IndicatorImp.h b/hikyuu_cpp/hikyuu/indicator/IndicatorImp.h index 70afd776..5e346541 100644 --- a/hikyuu_cpp/hikyuu/indicator/IndicatorImp.h +++ b/hikyuu_cpp/hikyuu/indicator/IndicatorImp.h @@ -8,6 +8,7 @@ #ifndef INDICATORIMP_H_ #define INDICATORIMP_H_ +#include "../config.h" #include "../KData.h" #include "../utilities/Parameter.h" #include "../utilities/util.h" @@ -79,6 +80,13 @@ public: } price_t get(size_t pos, size_t num = 0) { +#if CHECK_ACCESS_BOUND + if ((m_pBuffer[num] == NULL) || pos>= m_pBuffer[num]->size()) { + throw(std::out_of_range("Try to access value out of bounds! " + + name() + " [IndicatorImp::get]")); + return Null(); + } +#endif return (*m_pBuffer[num])[pos]; } @@ -95,11 +103,8 @@ public: void _set(price_t val, size_t pos, size_t num = 0) { #if CHECK_ACCESS_BOUND if ((m_pBuffer[num] == NULL) || pos>= m_pBuffer[num]->size()) { - std::stringstream err_info; - err_info << "Try to access value out of bounds! " - << name() << " [IndicatorImp::_set]"; - HKU_FATAL(err_info.str()); - throw(std::out_of_range(err_info.str())); + throw(std::out_of_range("Try to access value out of bounds! " + + name() + " [IndicatorImp::_set]")); return; } (*m_pBuffer[num])[pos] = val; diff --git a/hikyuu_cpp/hikyuu/indicator/imp/IKData.cpp b/hikyuu_cpp/hikyuu/indicator/imp/IKData.cpp index a6704a60..b9cf0ab0 100644 --- a/hikyuu_cpp/hikyuu/indicator/imp/IKData.cpp +++ b/hikyuu_cpp/hikyuu/indicator/imp/IKData.cpp @@ -42,6 +42,10 @@ bool IKData::check() { void IKData::_calculate(const Indicator& ind) { KData kdata = getCurrentKData(); size_t total = kdata.size(); + if (total == 0) { + return; + } + string part_name = getParam("kpart"); if ("KDATA" == part_name) { diff --git a/hikyuu_cpp/hikyuu/indicator/imp/ILiuTongPan.cpp b/hikyuu_cpp/hikyuu/indicator/imp/ILiuTongPan.cpp index 7f151c1b..bca48e58 100644 --- a/hikyuu_cpp/hikyuu/indicator/imp/ILiuTongPan.cpp +++ b/hikyuu_cpp/hikyuu/indicator/imp/ILiuTongPan.cpp @@ -29,6 +29,10 @@ bool ILiuTongPan::check() { void ILiuTongPan::_calculate(const Indicator& data) { KData k = getCurrentKData(); size_t total = k.size(); + if (total == 0) { + return; + } + _readyBuffer(total, 1); if (total == 0) {