Merge branch 'master' of https://github.com/fasiondog/hikyuu into feature/se

This commit is contained in:
fasiondog 2024-06-06 19:01:16 +08:00
commit 4182296aca
4 changed files with 57 additions and 17 deletions

View File

@ -305,6 +305,17 @@ void Portfolio::_runMoment(const Datetime& date, const Datetime& nextCycle, bool
m_delay_adjust_sys_list.swap(tmp_continue_adjust_sys_list);
//---------------------------------------------------
// 检测当前运行中的系统是否存在延迟卖出信号,并在开盘时有效处理
//---------------------------------------------------
for (auto& sys : m_running_sys_set) {
auto tr = sys->pfProcessDelaySellRequest(date);
if (!tr.isNull()) {
HKU_INFO_IF(trace, "[PF] sell delay {}", tr);
m_tm->addTradeRecord(tr);
}
}
//---------------------------------------------------
// 调仓日,进行资金分配调整
//---------------------------------------------------
@ -312,10 +323,10 @@ void Portfolio::_runMoment(const Datetime& date, const Datetime& nextCycle, bool
// 从选股策略获取选中的系统列表
m_tmp_selected_list = m_se->getSelected(date);
// 如果选中的系统不在已有列表中, 则先清除其延迟操作,防止在调仓日出现未来信号
// 如果选中的系统不在已有列表中, 则先清除其延迟买入操作,防止在调仓日出现未来信号
for (auto& sys : m_tmp_selected_list) {
if (m_running_sys_set.find(sys.sys) == m_running_sys_set.end()) {
sys.sys->clearDelayRequest();
sys.sys->clearDelayBuyRequest();
}
}

View File

@ -406,11 +406,12 @@ void System::run(const KData& kdata, bool reset, bool resetAll) {
m_calculated = true;
}
void System::clearDelayRequest() {
void System::clearDelayBuyRequest() {
m_buyRequest.clear();
m_sellRequest.clear();
m_sellShortRequest.clear();
m_buyShortRequest.clear();
}
bool System::haveDelaySellRequest() const {
return m_sellRequest.valid;
}
TradeRecord System::runMoment(const Datetime& datetime) {
@ -767,12 +768,16 @@ TradeRecord System::_sellForce(const Datetime& date, double num, Part from, bool
}
TradeRecord System::_sell(const KRecord& today, const KRecord& src_today, Part from) {
bool trace = getParam<bool>("trace");
TradeRecord result;
if (getParam<bool>("sell_delay")) {
_submitSellRequest(today, src_today, from);
HKU_INFO_IF(trace, "[{}] will be delay to sell", name());
return result;
} else {
return _sellNow(today, src_today, from);
result = _sellNow(today, src_today, from);
HKU_INFO_IF(trace, "[{}] sell now: {}", name(), result);
return result;
}
}
@ -817,6 +822,9 @@ TradeRecord System::_sellNow(const KRecord& today, const KRecord& src_today, Par
}
TradeRecord System::_sellDelay(const KRecord& today, const KRecord& src_today) {
bool trace = getParam<bool>("trace");
HKU_INFO_IF(trace, "[{}] process _sellDelay request", name());
TradeRecord result;
if (today.highPrice == today.lowPrice && !getParam<bool>("can_trade_when_high_eq_low")) {
// 无法执行,保留卖出请求,继续延迟至下一时刻
@ -1175,6 +1183,15 @@ TradeRecord System::_processRequest(const KRecord& today, const KRecord& src_tod
return TradeRecord();
}
TradeRecord System::pfProcessDelaySellRequest(const Datetime& date) {
HKU_IF_RETURN(!m_sellRequest.valid, TradeRecord());
size_t pos = m_kdata.getPos(date);
HKU_IF_RETURN(pos == Null<size_t>(), TradeRecord());
KRecord today = m_kdata.getKRecord(pos);
KRecord src_today = m_src_kdata.getKRecord(pos);
return _sellDelay(today, src_today);
}
price_t System::_getStoplossPrice(const KRecord& today, const KRecord& src_today, price_t price) {
HKU_IF_RETURN(!m_st, 0.0);
HKU_IF_RETURN(today.highPrice == today.lowPrice, src_today.lowPrice);

View File

@ -25,12 +25,17 @@
namespace hku {
class HKU_API Portfolio;
class HKU_API AllocateFundsBase;
/**
*
* @ingroup System
*/
class HKU_API System {
PARAMETER_SUPPORT_WITH_CHECK
friend class HKU_API Portfolio;
friend class HKU_API AllocateFundsBase;
public:
/** 默认构造函数 */
@ -200,12 +205,6 @@ public:
*/
TradeRecord runMoment(const Datetime& datetime);
// 清除已有的交易请求供Portfolio使用
void clearDelayRequest();
// 当前是否存在延迟的操作请求供Portfolio
bool haveDelayRequest() const;
// 运行前准备工作, 失败将抛出异常
void readyForRun();
@ -213,6 +212,12 @@ public:
return _sell(today, src_today, from);
}
// 由各个相关组件调用,用于组件参数变化时通知 sys以便重算
void partChangedNotify() {
m_calculated = false;
}
private:
// 强制以开盘价卖出,仅供 PF/AF 内部调用
TradeRecord sellForceOnOpen(const Datetime& date, double num, Part from) {
HKU_ASSERT(from == PART_ALLOCATEFUNDS || from == PART_PORTFOLIO);
@ -225,10 +230,14 @@ public:
return _sellForce(date, num, from, false);
}
// 由各个相关组件调用,用于组件参数变化时通知 sys以便重算
void partChangedNotify() {
m_calculated = false;
}
// 清除已有的交易请求供Portfolio使用
void clearDelayBuyRequest();
// 当前是否存在延迟的操作请求供Portfolio
bool haveDelaySellRequest() const;
// 处理延迟买入请求,仅供 PF 调用
TradeRecord pfProcessDelaySellRequest(const Datetime& date);
private:
bool _environmentIsValid(const Datetime& datetime);

View File

@ -30,6 +30,8 @@ string HKU_API getSystemPartName(int part) {
return "SP";
case PART_ALLOCATEFUNDS:
return "AF";
case PART_PORTFOLIO:
return "PF";
default:
return "--";
}
@ -47,6 +49,7 @@ SystemPart HKU_API getSystemPartEnum(const string& arg) {
HKU_IF_RETURN("SP" == name, PART_SLIPPAGE);
HKU_IF_RETURN("MM" == name, PART_MONEYMANAGER);
HKU_IF_RETURN("AF" == name, PART_ALLOCATEFUNDS);
HKU_IF_RETURN("PF" == name, PART_PORTFOLIO);
return PART_INVALID;
}