Skip to content

Commit

Permalink
Merge pull request #213 from fasiondog/feature/factor
Browse files Browse the repository at this point in the history
add AF_MultiFactor/SE_MultiFactor//SG_Allways_buy
  • Loading branch information
fasiondog committed Mar 30, 2024
2 parents 7d482d9 + eb76ff9 commit 81b7c43
Show file tree
Hide file tree
Showing 38 changed files with 456 additions and 50 deletions.
13 changes: 0 additions & 13 deletions hikyuu/trade_sys/trade_sys.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,19 +133,6 @@ def crtSG(func, params={}, name='crtSG'):
# ------------------------------------------------------------------
# Selector
# ------------------------------------------------------------------
def se_add_stock_list(self, stk_list, proto_sys):
result = True
for stk in stk_list:
success = self.add_stock(stk, proto_sys)
if not success:
result = False
break
return result
SelectorBase.add_stock_list = se_add_stock_list
def crtSE(calculate, get_selected, is_match_af=None, params={}, name='crtSE'):
"""
快速创建交易对象选择算法
Expand Down
2 changes: 1 addition & 1 deletion hikyuu_cpp/hikyuu/trade_sys/all.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@
#include "system/build_in.h"
#include "allocatefunds/build_in.h"
#include "selector/build_in.h"
#include "factor/build_in.h"
#include "multifactor/build_in.h"

#endif /* ALL_TRADE_SYS_H_ */
1 change: 1 addition & 0 deletions hikyuu_cpp/hikyuu/trade_sys/allocatefunds/build_in.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@

#include "crt/AF_EqualWeight.h"
#include "crt/AF_FixedWeight.h"
#include "crt/AF_MultiFactor.h"

#endif /* TRADE_SYS_ALLOCATEFUNDS_BUILD_IN_H_ */
21 changes: 21 additions & 0 deletions hikyuu_cpp/hikyuu/trade_sys/allocatefunds/crt/AF_MultiFactor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright (c) 2024 hikyuu.org
*
* Created on: 2024-03-30
* Author: fasiondog
*/

#pragma once

#include "../AllocateFundsBase.h"

namespace hku {

/**
* 创建 MultiFactor 评分权重的资产分配算法实例
* @return AFPtr
* @ingroup AllocateFunds
*/
AFPtr HKU_API AF_MultiFactor();

} // namespace hku
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright (c) 2024 hikyuu.org
*
* Created on: 2024-03-30
* Author: fasiondog
*/

#include "MultiFactorAllocaterFunds.h"

namespace hku {

MultiFactorAllocaterFunds::MultiFactorAllocaterFunds() : AllocateFundsBase("AF_Multi_factor") {}

MultiFactorAllocaterFunds::~MultiFactorAllocaterFunds() {}

SystemWeightList MultiFactorAllocaterFunds::_allocateWeight(const Datetime& date,
const SystemWeightList& se_list) {
return se_list;
}

AFPtr HKU_API AF_MultiFactor() {
return make_shared<MultiFactorAllocaterFunds>();
}

} // namespace hku
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright (c) 2024 hikyuu.org
*
* Created on: 2024-03-30
* Author: fasiondog
*/

#pragma once

#include "../AllocateFundsBase.h"

namespace hku {

class MultiFactorAllocaterFunds : public AllocateFundsBase {
ALLOCATEFUNDS_IMP(MultiFactorAllocaterFunds)
ALLOCATEFUNDS_NO_PRIVATE_MEMBER_SERIALIZATION

public:
MultiFactorAllocaterFunds();
virtual ~MultiFactorAllocaterFunds();
};

} // namespace hku
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,14 @@ void MultiFactorBase::paramChanged() {
m_calculated = false;
}

void MultiFactorBase::reset() {
std::lock_guard<std::mutex> lock(m_mutex);
_reset();

// 仅重置 m_calculated,其他缓存不重置,否则线程不安全
m_calculated = false;
}

MultiFactorPtr MultiFactorBase::clone() {
std::lock_guard<std::mutex> lock(m_mutex);
MultiFactorPtr p;
Expand All @@ -142,23 +150,23 @@ MultiFactorPtr MultiFactorBase::clone() {
p->m_stks = m_stks;
p->m_ref_stk = m_ref_stk;
p->m_query = m_query;
p->m_stk_map = m_stk_map;
p->m_all_factors = m_all_factors;
p->m_date_index = m_date_index;
p->m_stk_factor_by_date = m_stk_factor_by_date;
p->m_ref_dates = m_ref_dates;
p->m_ic = m_ic.clone();
p->m_calculated = m_calculated;

p->m_inds.reserve(m_inds.size());
for (const auto& ind : m_inds) {
p->m_inds.emplace_back(ind.clone());
}

p->m_all_factors.reserve(m_all_factors.size());
for (const auto& ind : m_all_factors) {
p->m_all_factors.emplace_back(ind.clone());
}
p->m_calculated = false;
// 强制重算,不克隆以下缓存,避免非线程安全
// p->m_stk_map = m_stk_map;
// p->m_date_index = m_date_index;
// p->m_stk_factor_by_date = m_stk_factor_by_date;
// p->m_ic = m_ic.clone();
// p->m_all_factors.reserve(m_all_factors.size());
// for (const auto& ind : m_all_factors) {
// p->m_all_factors.emplace_back(ind.clone());
// }
return p;
}

Expand All @@ -181,6 +189,22 @@ const ScoreRecordList& MultiFactorBase::getScore(const Datetime& d) {
return m_stk_factor_by_date[iter->second];
}

ScoreRecordList MultiFactorBase::getScores(const Datetime& date, size_t start, size_t end) {
ScoreRecordList ret;
HKU_IF_RETURN(start >= end, ret);

const auto& cross = getScore(date);
if (end == Null<size_t>() || end > cross.size()) {
end = cross.size();
}

for (size_t i = start; i < end; i++) {
ret.emplace_back(cross[i]);
}

return ret;
}

ScoreRecordList MultiFactorBase::getScores(const Datetime& date, size_t start, size_t end,
std::function<bool(const ScoreRecord&)>&& filter) {
ScoreRecordList ret;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,20 +82,20 @@ class HKU_API MultiFactorBase : public enable_shared_from_this<MultiFactorBase>
/** 获取指定日期截面的所有因子值,已经降序排列 */
const ScoreRecordList& getScore(const Datetime&);

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

/**
* 获取指定日期截面 [start, end] 范围内的因子值(评分), 并通过filer进行过滤
* @param date 指定日期
* @param start 排序起始点
* @param end 排序起始点(不含该点)
* @param filter 过滤函数
*/
ScoreRecordList getScores(
const Datetime& date, size_t start, size_t end = Null<size_t>(),
std::function<bool(const ScoreRecord&)>&& filter = std::function<bool(const ScoreRecord&)>());
ScoreRecordList getScores(const Datetime& date, size_t start, size_t end,
std::function<bool(const ScoreRecord&)>&& filter);

ScoreRecordList getScores(const Datetime& date, size_t start, size_t end = Null<size_t>(),
std::function<bool(const Datetime&, const ScoreRecord&)>&& filter =
std::function<bool(const Datetime&, const ScoreRecord&)>());
ScoreRecordList getScores(const Datetime& date, size_t start, size_t end,
std::function<bool(const Datetime&, const ScoreRecord&)>&& filter);

/** 获取所有截面数据,已按降序排列 */
const vector<ScoreRecordList>& getAllScores();
Expand Down Expand Up @@ -123,9 +123,12 @@ class HKU_API MultiFactorBase : public enable_shared_from_this<MultiFactorBase>
*/
vector<IndicatorList> getAllSrcFactors();

void reset();

typedef std::shared_ptr<MultiFactorBase> MultiFactorPtr;
MultiFactorPtr clone();

virtual void _reset() {}
virtual MultiFactorPtr _clone() = 0;
virtual IndicatorList _calculate(const vector<IndicatorList>&) = 0;

Expand Down
21 changes: 12 additions & 9 deletions hikyuu_cpp/hikyuu/trade_sys/portfolio/Portfolio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -370,18 +370,21 @@ void Portfolio::_runMoment(const Datetime& date, bool adjust) {
// 跟踪打印持仓情况
//----------------------------------------------------------------------
if (trace && !m_running_sys_set.empty()) {
// clang-format off
HKU_INFO(
"+------------+------------+------------+--------------+--------------+-------------+");
"+------------+------------+------------+--------------+--------------+-------------+-------------+");
HKU_INFO(
"| code | name | position | market value | remain cash | close price |");
"| code | name | position | market value | remain cash | open price | close price |");
HKU_INFO(
"+------------+------------+------------+--------------+--------------+-------------+");
"+------------+------------+------------+--------------+--------------+-------------+-------------+");
// clang-format on

size_t count = 0;
for (const auto& sys : m_running_sys_set) {
Stock stk = sys->getStock();
auto funds = sys->getTM()->getFunds(date, m_query.kType());
size_t position = sys->getTM()->getHoldNumber(date, stk);
KRecord krecord = stk.getKRecord(date, m_query.kType());
#if HKU_OS_WINDOWS
auto stk_name =
runningInPython() && pythonInJupyter() ? stk.name() : UTF8ToGB(stk.name());
Expand All @@ -390,18 +393,18 @@ void Portfolio::_runMoment(const Datetime& date, bool adjust) {
stk_name.push_back(' ');
}
}
HKU_INFO("| {:<11}| {}| {:<11}| {:<13.2f}| {:<13.2f}| {:<12.2f}|", stk.market_code(),
stk_name, position, funds.market_value, funds.cash,
stk.getKRecord(date, m_query.kType()).closePrice);
HKU_INFO("| {:<11}| {}| {:<11}| {:<13.2f}| {:<13.2f}| {:<12.2f}| {:<12.2f}|",
stk.market_code(), stk_name, position, funds.market_value, funds.cash,
krecord.openPrice, krecord.closePrice);
#else
auto stk_name = stk.name();
HKU_INFO("| {:<11}| {:<11}| {:<11}| {:<13.2f}| {:<13.2f}| {:<12.2f}|",
HKU_INFO("| {:<11}| {:<11}| {:<11}| {:<13.2f}| {:<13.2f}| {:<12.2f}| {:<12.2f}|",
stk.market_code(), stk_name, position, funds.market_value, funds.cash,
stk.getKRecord(date, m_query.kType()).closePrice);
krecord.openPrice, krecord.closePrice);
#endif
HKU_INFO(
"+------------+------------+------------+--------------+--------------+-------------"
"+");
"+-------------+");
if (++count >= 10) {
break;
}
Expand Down
1 change: 1 addition & 0 deletions hikyuu_cpp/hikyuu/trade_sys/selector/build_in.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#define TRADE_SYS_SELECTOR_BUILD_IN_H_

#include "crt/SE_Fixed.h"
#include "crt/SE_MultiFactor.h"
#include "crt/SE_Signal.h"

#endif /* TRADE_SYS_SELECTOR_BUILD_IN_H_ */
42 changes: 42 additions & 0 deletions hikyuu_cpp/hikyuu/trade_sys/selector/crt/SE_MultiFactor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2024 hikyuu.org
*
* Created on: 2024-03-30
* Author: fasiondog
*/

#pragma once

#include "hikyuu/trade_sys/multifactor/MultiFactorBase.h"
#include "../SelectorBase.h"

namespace hku {

/**
* 基于 MultiFactor 选股算法
* @param mf MultiFactor 实例
* @param topn 只选取时间截面中前 topn 个系统
* @return SelectorPtr
* @ingroup Selector
*/
SelectorPtr HKU_API SE_MultiFactor(const MFPtr& mf, int topn = 10);

/**
* 基于 MultiFactor 选股算法
* @param src_inds 原始因子公式
* @param stks 证券列表
* @param query 查询条件
* @param topn 只选取时间截面中前 topn 个系统
* @param ic_n ic 对应的 ic_n 日收益率
* @param ic_rolling_n 计算滚动 IC (即 IC 的 n 日移动平均)周期
* @param ref_stk 参照对比证券,未指定时,默认使用 sh000300 沪深300指数
* @param mode "MF_ICIRWeight" | "MF_ICWeight" | "MF_EqualWeight" 因子合成算法名称
* @return SelectorPtr
* @ingroup Selector
*/
SelectorPtr HKU_API SE_MultiFactor(const IndicatorList& src_inds, const StockList& stks,
const KQuery& query, int topn = 10, int ic_n = 5,
int ic_rolling_n = 120, const Stock& ref_stk = Stock(),
const string& mode = "MF_ICIRWeight");

} // namespace hku

0 comments on commit 81b7c43

Please sign in to comment.