void SingleSignal::_calculate() { int filter_n = getParam<int>("filter_n"); double filter_p = getParam<double>("filter_p"); string kpart(getParam<string>("kpart")); Indicator ind = m_ind(KDATA_PART(m_kdata, kpart)); Indicator dev = STDEV(DIFF(ind), filter_n); size_t start = dev.discard(); if (start < 3) { return; } size_t total = dev.size(); for (size_t i = start; i < total; ++i) { double dama = ind[i] - ind[i-1]; double dama2 = ind[i] - ind[i-2]; double dama3 = ind[i] - ind[i-3]; double sdama = dev[i] * filter_p; if (dama > 0 && (dama > sdama || dama2 > sdama || dama3 > sdama)) { _addBuySignal(m_kdata[i].datetime); } else if (dama < 0 && (dama < sdama || dama2 < sdama || dama3 < sdama)) { _addSellSignal(m_kdata[i].datetime); } } }
void LowLine::_calculate(const Indicator& data) { size_t total = data.size(); int n = getParam<int>("n"); m_discard = data.discard() + n - 1; size_t pos = m_discard + 1 - n; price_t min = 0; for (size_t i = m_discard; i < total; ++i) { size_t j = i + 1 - n; if (pos > j) { j = pos; } else { min = data[j]; } for (; j <= i; ++j) { if (data[j] < min) { min = data[j]; pos = j; } } _set(min, i); } }
void Weave::_calculate(const Indicator& ind) { size_t total = ind.size(); if (m_result_num != 0 && total != size()) { HKU_ERROR("ind's size must be equal weave's size! [Weave::_calculate]"); return; } if (total == 0) { return; } size_t old_m_result_num = m_result_num; m_result_num = ind.getResultNumber() + m_result_num; if (m_result_num > MAX_RESULT_NUM) { HKU_WARN("Weave only can contains " << MAX_RESULT_NUM << "reult_num! [Weave::_calculate]"); m_result_num = MAX_RESULT_NUM; } if (m_discard < ind.discard()) { m_discard = ind.discard(); } price_t null_price = Null<price_t>(); for (size_t i = old_m_result_num; i < m_result_num; ++i) { m_pBuffer[i] = new PriceList(total, null_price); for (size_t j = m_discard; j < total; ++j) { (*m_pBuffer[i])[j] = ind.get(j, i-old_m_result_num); } } }
void RightShift::_calculate(const Indicator& data) { size_t total = data.size(); int n = getParam<int>("n"); m_discard = data.discard() + n; for (size_t i = m_discard; i < total; ++i) { _set(data[i-n], i); } }
void ConstantValue::_calculate(const Indicator& data) { size_t total = data.size(); double value = getParam<double>("value"); m_discard = data.discard(); for (size_t i = m_discard; i < total; ++i) { _set(value, i, 0); } }
void Diff::_calculate(const Indicator& data) { size_t total = data.size(); m_discard = data.discard() + 1; if (total <= m_discard) { return; } for (size_t i = discard(); i < total; ++i) { _set(data[i] - data[i-1], i); } }
void ISqrt::_calculate(const Indicator& data) { size_t total = data.size(); m_discard = data.discard(); if (m_discard >= total) { m_discard = total; return; } for (size_t i = m_discard; i < total; ++i) { _set(std::sqrt(data[i]), i); } }
void IRound::_calculate(const Indicator& data) { size_t total = data.size(); m_discard = data.discard(); if (m_discard >= total) { m_discard = total; return; } int n = getParam<int>("ndigits"); for (size_t i = m_discard; i < total; ++i) { _set(roundEx(data[i], n), i); } }
void IReverse::_calculate(const Indicator& data) { size_t total = data.size(); m_discard = data.discard(); if (m_discard >= total) { m_discard = total; return; } for (size_t i = m_discard; i < total; ++i) { _set(-data[i], i); } }
void ConstantValue::_calculate(const Indicator& data) { double value = getParam<double>("value"); int discard = getParam<int>("discard"); size_t total = 0; if (isLeaf()) { //叶子节点 KData k = getContext(); if (k.getStock().isNull()) { _readyBuffer(1, 1); if (discard < 1) { m_discard = 0; _set(value, 0, 0); } else { m_discard = 1; } return; } total = k.size(); if (0 == total) { return; } _readyBuffer(total, 1); } else { //非叶子节点 total = data.size(); discard = data.discard() > discard ? data.discard() : discard; } m_discard = discard > total ? total : discard; for (size_t i = m_discard; i < total; ++i) { _set(value, i, 0); } }
void SaftyLoss::_calculate(const Indicator& data) { size_t total = data.size(); if (total == 0) { return; } _readyBuffer(total, 1); int n1 = getParam<int>("n1"); int n2 = getParam<int>("n2"); double p = getParam<double>("p"); m_discard = data.discard() + n1 + n2 - 2; if (m_discard >= total) { m_discard = total; return; } price_t sum = 0.0; size_t num = 0; price_t result = 0.0; size_t start = discard(); for (size_t i = start; i < total; ++i) { result = 0.0; for (size_t j = i + 1 - n2; j <= i; ++j) { sum = 0.0; num = 0; for (size_t k = j + 2 -n1; k <=j; ++k) { price_t pre = data[k-1]; price_t cur = data[k]; if (pre > cur) { sum += pre - cur; ++num; } } price_t temp = data[j]; if (num != 0) { temp = temp - (p * sum / num); } if (temp > result) { result = temp; } } _set(result, i); } }
void IPriceList::_calculate(const Indicator& data) { //如果在叶子节点,直接取自身的data参数 if (isLeaf()) { PriceList x = getParam<PriceList>("data"); int discard = getParam<int>("discard"); size_t total = x.size(); _readyBuffer(total, 1); //更新抛弃数量 m_discard = discard > total ? total : discard; for (size_t i = m_discard; i < total; ++i) { _set(x[i], i); } return; } //不在叶子节点上,则忽略本身的data参数,认为其输入实际为函数入参中的data int result_index = getParam<int>("result_index"); if (result_index < 0 || result_index >= data.getResultNumber()) { HKU_ERROR("result_index out of range! [IPriceList::IPriceList]"); return; } size_t total = data.size(); _readyBuffer(total, 1); for (size_t i = data.discard(); i < total; ++i) { _set(data.get(i, result_index), i); } //更新抛弃数量 m_discard = data.discard(); }
void INot::_calculate(const Indicator& data) { size_t total = data.size(); m_discard = data.discard(); if (m_discard >= total) { m_discard = total; return; } for (size_t i = m_discard; i < total; ++i) { if (data[i] == 0.0) { _set(1.0, i); } else { _set(0.0, i); } } }
void IVarp::_calculate(const Indicator& data) { size_t total = data.size(); int n = getParam<int>("n"); m_discard = data.discard() + n - 1; if (m_discard >= total) { m_discard = total; return; } Indicator ma = MA(data, n); for (size_t i = discard(); i < total; ++i) { price_t mean = ma[i]; price_t sum = 0.0; for (size_t j = i + 1 - n; j <= i; ++j) { sum += std::pow(data[j] - mean, 2); } _set(sum/n, i); } }
void Macd::_calculate(const Indicator& data) { size_t total = data.size(); if (total == 0) { return; } _readyBuffer(total, 3); int n1 = getParam<int>("n1"); int n2 = getParam<int>("n2"); int n3 = getParam<int>("n3"); m_discard = data.discard(); if (total <= m_discard) { m_discard = total; return; } price_t m1 = 2.0 / (n1 + 1); price_t m2 = 2.0 / (n2 + 1); price_t m3 = 2.0 / (n3 + 1); price_t ema1 = data[0]; price_t ema2 = data[0]; price_t diff = 0.0; price_t dea = 0.0; price_t bar = 0.0; _set(bar, 0, 0); _set(diff, 0, 1); _set(dea, 0, 2); for (size_t i = 1; i < total; ++i) { ema1 = (data[i] - ema1) * m1 + ema1; ema2 = (data[i] - ema2) * m2 + ema2; diff = ema1 - ema2; dea = diff * m3 + dea - dea * m3; bar = diff - dea; _set(bar, i, 0); _set(diff, i, 1); _set(dea, i, 2); } }
Indicator HKU_API AmaSpecial(const Block& block, KQuery query, Indicator ama) { Indicator result; StockManager& sm = StockManager::instance(); //计算每日股票总数 DatetimeList dateList = sm.getTradingCalendar(query, "SH"); size_t dayTotal = dateList.size(); if (dayTotal == 0) { result = PRICELIST(PriceList()); result.name("POS"); return result; } vector<size_t> numberPerDay(dayTotal); for (size_t i = 0; i < dayTotal; ++i) { numberPerDay[i] = 0; for (auto stk_iter = block.begin(); stk_iter != block.end(); ++stk_iter) { if (stk_iter->startDatetime() <= dateList[i] && dateList[i] <= stk_iter->lastDatetime()) { numberPerDay[i]++; } } } vector<size_t> position(dayTotal); size_t discard = ama.discard(); for (auto stk_iter = block.begin(); stk_iter != block.end(); ++stk_iter) { KData kdata = stk_iter->getKData(query); if (kdata.empty()) continue; SignalPtr sg(SG_Single(ama)); sg->setTO(kdata); bool isHold = false; size_t n_dis = 0; for (size_t i = 0; i < dayTotal; ++i) { if (isHold) { if (sg->shouldSell(dateList[i])) { isHold = false; } else { position[i]++; } } else { if (sg->shouldBuy(dateList[i])) { position[i]++; isHold = true; } } if (dateList[i] >= kdata[0].datetime) { if (n_dis < discard) { n_dis++; numberPerDay[i]--; } } } } PriceList tmp_result(dayTotal, Null<price_t>()); for (auto i = discard; i < dayTotal; ++i) { tmp_result[i] = numberPerDay[i] ? (double)position[i]/(double)numberPerDay[i] : 1.0; } result = PRICELIST(tmp_result); result.name("POS"); return PRICELIST(result); }
void ILowLineBars::_calculate(const Indicator& ind) { size_t total = ind.size(); if (0 == total) { m_discard = 0; return; } if (ind.discard() >= total) { m_discard = total; return; } m_discard = ind.discard(); if (1 == total) { if (0 == m_discard) { _set(0, 0); } return; } int n = getParam<int>("n"); if (0 == n) { n = total - m_discard; } else if (n > total) { n = total; } price_t min = ind[m_discard]; size_t pre_pos = m_discard; size_t start_pos = m_discard + n < total ? m_discard + n : total; for (size_t i = m_discard; i < start_pos; i++) { if (ind[i] <= min) { min = ind[i]; pre_pos = i; } _set(i - pre_pos, i); } for (size_t i = start_pos; i < total-1; i++) { size_t j = i + 1 - n; if (pre_pos < j) { pre_pos = j; min = ind[j]; } if (ind[i] <= min) { min = ind[i]; pre_pos = i; } _set(i - pre_pos, i); } start_pos = total - n; min = ind[start_pos]; pre_pos = start_pos; for (size_t i = start_pos; i < total; i++) { if (ind[i] <= min) { pre_pos = i; min = ind[i]; } } _set(total-pre_pos-1, total-1); }