Skip to content

Commit

Permalink
优化 HSL 换手率实现
Browse files Browse the repository at this point in the history
  • Loading branch information
fasiondog committed Jan 24, 2025
1 parent 4cabaf8 commit 895838f
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 15 deletions.
2 changes: 1 addition & 1 deletion docs/source/indicator/indicator.rst
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,7 @@

.. py:function:: HSL(kdata)
获取换手率,等于 VOL(k) / CAPITAL(k)
获取换手率(百分比 x%),等于 VOL(k) / CAPITAL(k)

:param KData kdata: k线数据
:rtype: Indicator
Expand Down
2 changes: 1 addition & 1 deletion hikyuu_cpp/hikyuu/indicator/crt/HSL.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
namespace hku {

/**
* 获取换手率,等于 VOL(k) / CAPITAL(k)
* 获取换手率 p%,等于 VOL(k) / CAPITAL(k)
* @param k 关联的K线数据
* @ingroup Indicator
*/
Expand Down
50 changes: 38 additions & 12 deletions hikyuu_cpp/hikyuu/indicator/imp/IHsl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,35 +28,53 @@ void IHsl::_calculate(const Indicator& data) {

KData k = getContext();
size_t total = k.size();
if (total == 0) {
return;
}
HKU_IF_RETURN(total == 0, void());

_readyBuffer(total, 1);

// 先将 discard 设为全部,后续更新
m_discard = total;

Stock stock = k.getStock();
StockWeightList sw_list = stock.getWeight();
if (sw_list.size() == 0) {
return;
auto* kdata = k.data();
Datetime lastdate = kdata[total - 1].datetime.startOfDay();

StockWeightList sw_list = stock.getWeight(Datetime::min(), lastdate + Days(1));
HKU_IF_RETURN(sw_list.empty(), void());

// 寻找第一个流通盘不为0的权息
price_t pre_free_count = 0.0;
Datetime pre_sw_date;
auto sw_iter = sw_list.begin();
for (; sw_iter != sw_list.end(); ++sw_iter) {
if (sw_iter->freeCount() > 0) {
pre_free_count = sw_iter->freeCount();
pre_sw_date = sw_iter->datetime();
break;
}
}

auto* kdata = k.data();
// 没有流通盘相关权息数据, 或者该权息日期大于最后一根K线日期, 直接返回
HKU_IF_RETURN(sw_iter == sw_list.end() || pre_sw_date > lastdate, void());

auto* dst = this->data();
size_t pos = 0;
auto sw_iter = sw_list.begin();
price_t pre_free_count = sw_iter->freeCount();
for (; sw_iter != sw_list.end(); ++sw_iter) {
price_t free_count = sw_iter->freeCount();
if (free_count == 0) {
Datetime cur_sw_date = sw_iter->datetime();
if (free_count <= 0.0) {
continue; // 忽略流通盘为0的权息
}

while (pos < total && k[pos].datetime < sw_iter->datetime()) {
dst[pos] = kdata[pos].transCount / pre_free_count;
while (pos < total && kdata[pos].datetime < cur_sw_date) {
if (kdata[pos].datetime >= pre_sw_date) {
dst[pos] = kdata[pos].transCount / pre_free_count;
}
pos++;
}

pre_free_count = free_count;
pre_sw_date = cur_sw_date;
if (pos >= total) {
break;
}
Expand All @@ -65,6 +83,14 @@ void IHsl::_calculate(const Indicator& data) {
for (; pos < total; pos++) {
dst[pos] = kdata[pos].transCount / pre_free_count;
}

// 更新 discard
for (size_t i = 0; i < total; i++) {
if (!std::isnan(dst[i])) {
m_discard = i;
break;
}
}
}

Indicator HKU_API HSL() {
Expand Down
2 changes: 1 addition & 1 deletion hikyuu_pywrap/indicator/_build_in.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -953,7 +953,7 @@ void export_Indicator_build_in(py::module& m) {
m.def("HSL", HSL_1);
m.def("HSL", HSL_2, R"(HSL(kdata)
获取换手率,等于 VOL(k) / CAPITAL(k)
获取换手率(百分比x%),等于 VOL(k) / CAPITAL(k)
:param KData kdata: k线数据
:rtype: Indicator)");
Expand Down

0 comments on commit 895838f

Please sign in to comment.