Skip to content

Commit

Permalink
Merge pull request #211 from fasiondog/feature/factor
Browse files Browse the repository at this point in the history
StockManager/Block/MF 增加过滤函数;其他
  • Loading branch information
fasiondog committed Mar 29, 2024
2 parents 82eb014 + 2f46872 commit fe69d5c
Show file tree
Hide file tree
Showing 16 changed files with 115 additions and 13 deletions.
16 changes: 12 additions & 4 deletions hikyuu_cpp/hikyuu/Block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,20 @@ Stock Block::get(const string& market_code) const {
return result;
}

vector<Stock> Block::getAllStocks() const {
vector<Stock> ret;
StockList Block::getStockList(std::function<bool(const Stock&)>&& filter) const {
StockList ret;
ret.reserve(size());
auto iter = m_data->m_stockDict.begin();
for (; iter != m_data->m_stockDict.end(); ++iter) {
ret.emplace_back(iter->second);
if (filter) {
for (; iter != m_data->m_stockDict.end(); ++iter) {
if (filter(iter->second)) {
ret.emplace_back(iter->second);
}
}
} else {
for (; iter != m_data->m_stockDict.end(); ++iter) {
ret.emplace_back(iter->second);
}
}
return ret;
}
Expand Down
3 changes: 2 additions & 1 deletion hikyuu_cpp/hikyuu/Block.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ class HKU_API Block {
}

/** 获取板块下所有证券 */
vector<Stock> getAllStocks() const;
StockList getStockList(
std::function<bool(const Stock&)>&& filter = std::function<bool(const Stock&)>()) const;

/** 加入指定证券 */
bool add(const Stock& stock);
Expand Down
19 changes: 19 additions & 0 deletions hikyuu_cpp/hikyuu/StockManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,25 @@ Stock StockManager::getStock(const string& querystr) const {
return (iter != m_stockDict.end()) ? iter->second : result;
}

StockList StockManager::getStockList(std::function<bool(const Stock&)>&& filter) const {
StockList ret;
ret.reserve(m_stockDict.size());
std::lock_guard<std::mutex> lock(*m_stockDict_mutex);
auto iter = m_stockDict.begin();
if (filter) {
for (; iter != m_stockDict.end(); ++iter) {
if (filter(iter->second)) {
ret.emplace_back(iter->second);
}
}
} else {
for (; iter != m_stockDict.end(); ++iter) {
ret.emplace_back(iter->second);
}
}
return ret;
}

MarketInfo StockManager::getMarketInfo(const string& market) const {
MarketInfo result;
string market_tmp = market;
Expand Down
3 changes: 3 additions & 0 deletions hikyuu_cpp/hikyuu/StockManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ class HKU_API StockManager {
/** 同 getStock @see getStock */
Stock operator[](const string&) const;

StockList getStockList(
std::function<bool(const Stock&)>&& filter = std::function<bool(const Stock&)>()) const;

/**
* 获取相应的市场信息
* @param market 指定的市场标识
Expand Down
2 changes: 1 addition & 1 deletion hikyuu_cpp/hikyuu/analysis/combinate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ vector<CombinateAnalysisOutput> HKU_API combinateIndicatorAnalysisWithBlock(
}

vector<CombinateAnalysisOutput> result;
auto stocks = blk.getAllStocks();
auto stocks = blk.getStockList();
size_t total = stocks.size();
HKU_IF_RETURN(total == 0, result);

Expand Down
2 changes: 1 addition & 1 deletion hikyuu_cpp/hikyuu/indicator/crt/POS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Indicator HKU_API POS(const Block& block, KQuery query, SignalPtr sg) {
}
}

auto stks = block.getAllStocks();
auto stks = block.getStockList();
vector<SGPtr> sgs = parallel_for_index(0, stks.size(), [&](size_t i) {
auto tmpsg = sg->clone();
auto kdata = stks[i].getKData(query);
Expand Down
2 changes: 1 addition & 1 deletion hikyuu_cpp/hikyuu/indicator/imp/IIc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ Indicator HKU_API IC(const StockList& stks, const KQuery& query, const Stock& re
}

Indicator HKU_API IC(const Block& blk, const KQuery& query, const Stock& ref_stk, int n) {
StockList stks = blk.getAllStocks();
StockList stks = blk.getStockList();
return IC(stks, query, ref_stk, n);
}

Expand Down
12 changes: 12 additions & 0 deletions hikyuu_cpp/hikyuu/trade_sys/factor/MultiFactorBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,18 @@ ScoreRecordList MultiFactorBase::getScore(const Datetime& date, size_t start, si
return ret;
}

ScoreRecordList MultiFactorBase::getScore(const Datetime& date,
std::function<bool(const ScoreRecord&)> filter) {
ScoreRecordList ret;
const auto& all_scores = getScore(date);
for (const auto& score : all_scores) {
if (filter(score)) {
ret.emplace_back(score);
}
}
return ret;
}

const vector<ScoreRecordList>& MultiFactorBase::getAllScores() {
calculate();
return m_stk_factor_by_date;
Expand Down
5 changes: 4 additions & 1 deletion hikyuu_cpp/hikyuu/trade_sys/factor/MultiFactorBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
namespace hku {

/**
* 合成多因子
* 合成多因子,当只有一个因子时相当于简易的评分板
* @ingroup MultiFactor
*/
class HKU_API MultiFactorBase : public enable_shared_from_this<MultiFactorBase> {
Expand Down Expand Up @@ -84,6 +84,9 @@ class HKU_API MultiFactorBase : public enable_shared_from_this<MultiFactorBase>

ScoreRecordList getScore(const Datetime& date, size_t start, size_t end = Null<size_t>());

/** 获取指定日期截面的所有因子值, 并通过指定的filer进行过滤 */
ScoreRecordList getScore(const Datetime& date, std::function<bool(const ScoreRecord&)> filter);

/** 获取所有截面数据,已按降序排列 */
const vector<ScoreRecordList>& getAllScores();

Expand Down
1 change: 1 addition & 0 deletions hikyuu_cpp/hikyuu/trade_sys/factor/ScoreRecord.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ struct HKU_API ScoreRecord {
};

typedef vector<ScoreRecord> ScoreRecordList;
typedef vector<ScoreRecord> ScoreList;

HKU_API std::ostream& operator<<(std::ostream& out, const ScoreRecord& td);

Expand Down
4 changes: 3 additions & 1 deletion hikyuu_cpp/hikyuu/trade_sys/system/System.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -696,11 +696,13 @@ TradeRecord System::_sellForce(const Datetime& date, double num, Part from, bool
"Failed to sellForce {}, the day {} could'nt sell!", m_stock.market_code(),
date);

PositionRecord position = m_tm->getPosition(date, m_stock);
HKU_IF_RETURN(position.number <= 0.0, record);

const auto& krecord = m_kdata.getKRecord(pos);
const auto& src_krecord =
m_stock.getKRecord(m_kdata.startPos() + pos, m_kdata.getQuery().kType());

PositionRecord position = m_tm->getPosition(date, m_stock);
price_t realPrice =
_getRealSellPrice(krecord.datetime, on_open ? src_krecord.openPrice : src_krecord.closePrice);

Expand Down
8 changes: 6 additions & 2 deletions hikyuu_cpp/hikyuu/utilities/SpendTimer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,10 @@ SpendTimer::~SpendTimer() {
#endif

#else
printf("%5zu keep: %7.3f %s - %s\n", i, duration, unit.c_str(), m_keep_desc[i].c_str());
// printf("%5zu keep: %7.3f %s - %s\n", i, duration, unit.c_str(),
// m_keep_desc[i].c_str());
std::cout << std::setw(5) << " keep: " << i << std::setw(7) << std::setprecision(3)
<< duration << " " << unit << " - " << m_keep_desc[i] << std::endl;
#endif /* __ANDROID__ */
}
}
Expand Down Expand Up @@ -113,7 +116,8 @@ void SpendTimer::show() const {
#endif

#else
printf("%s", outmsg);
// printf("%s", outmsg);
std::cout << outmsg;
#endif /* __ANDROID__ */
}

Expand Down
20 changes: 20 additions & 0 deletions hikyuu_pywrap/_Block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,5 +92,25 @@ void export_Block(py::module& m) {
},
py::keep_alive<0, 1>())

.def(
"get_stock_list",
[](const Block& self, py::object filter) {
StockList ret;
if (filter.is_none()) {
ret = self.getStockList();
} else {
HKU_CHECK(py::hasattr(filter, "__call__"), "filter not callable!");
py::object filter_func = filter.attr("__call__");
ret = self.getStockList(
[&](const Stock& stk) { return filter_func(stk).cast<bool>(); });
}
return ret;
},
py::arg("filter") = py::none(), R"(get_stock_list(self[, filter=None])
获取证券列表
:param func filter: 输入参数为 stock, 返回 True | False 的过滤函数)")

DEF_PICKLE(Block);
}
20 changes: 20 additions & 0 deletions hikyuu_pywrap/_StockManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,26 @@ void export_StockManager(py::module& m) {
:return: 对应的证券实例,如果实例不存在,则Null<Stock>(),不抛出异常
:rtype: Stock)")

.def(
"get_stock_list",
[](const StockManager& self, py::object filter) {
StockList ret;
if (filter.is_none()) {
ret = self.getStockList();
} else {
HKU_CHECK(py::hasattr(filter, "__call__"), "filter not callable!");
py::object filter_func = filter.attr("__call__");
ret = self.getStockList(
[&](const Stock& stk) { return filter_func(stk).cast<bool>(); });
}
return ret;
},
py::arg("filter") = py::none(), R"(get_stock_list(self[, filter=None])
获取证券列表
:param func filter: 输入参数为 stock, 返回 True | False 的过滤函数)")

.def("get_block", &StockManager::getBlock, R"(get_block(self, category, name)
获取预定义的板块
Expand Down
8 changes: 8 additions & 0 deletions hikyuu_pywrap/trade_sys/_MultiFactor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,14 @@ void export_MultiFactor(py::module& m) {
:param int end: 取当日排名结束(不包含本身)
:rtype: ScoreRecordList)")

.def("get_score",
[](MultiFactorBase& self, const Datetime& date, py::object filter) {
HKU_CHECK(py::hasattr(filter, "__call__"), "filter not callable!");
py::object filter_func = filter.attr("__call__");
return self.getScore(
date, [&](const ScoreRecord& score) { return filter_func(score).cast<bool>(); });
})

.def("get_all_scores", &MultiFactorBase::getAllScores, py::return_value_policy::copy,
R"(get_all_scores(self)
Expand Down
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ flatbuffers>=23.5.6
pynng
akshare
pyecharts
pipdeptree
pipdeptree
h5py

0 comments on commit fe69d5c

Please sign in to comment.