mirror of
https://gitee.com/fasiondog/hikyuu.git
synced 2024-12-02 11:58:21 +08:00
Signal add Cycle
This commit is contained in:
parent
8d28ef9dd6
commit
2db4bf7692
@ -173,15 +173,18 @@ void Portfolio::run(const KQuery& query, int adjust_cycle, bool force) {
|
||||
HKU_IF_RETURN(datelist.empty(), void());
|
||||
|
||||
size_t cur_adjust_ix = 0;
|
||||
Datetime cur_cycle_end;
|
||||
for (size_t i = 0, total = datelist.size(); i < total; i++) {
|
||||
bool adjust = false;
|
||||
if (i == cur_adjust_ix) {
|
||||
adjust = true;
|
||||
cur_adjust_ix += adjust_cycle;
|
||||
cur_cycle_end =
|
||||
cur_adjust_ix < total ? datelist[cur_adjust_ix] : datelist.back() + Seconds(1);
|
||||
}
|
||||
|
||||
const auto& date = datelist[i];
|
||||
_runMoment(date, adjust);
|
||||
_runMoment(date, cur_cycle_end, adjust);
|
||||
}
|
||||
|
||||
m_need_calculate = false;
|
||||
@ -191,7 +194,7 @@ void Portfolio::run(const KQuery& query, int adjust_cycle, bool force) {
|
||||
m_tmp_will_remove_sys = SystemWeightList();
|
||||
}
|
||||
|
||||
void Portfolio::_runMoment(const Datetime& date, bool adjust) {
|
||||
void Portfolio::_runMoment(const Datetime& date, const Datetime& nextCycle, bool adjust) {
|
||||
// 当前日期小于账户建立日期,直接忽略
|
||||
HKU_IF_RETURN(date < m_cash_tm->initDatetime(), void());
|
||||
|
||||
@ -295,44 +298,6 @@ void Portfolio::_runMoment(const Datetime& date, bool adjust) {
|
||||
|
||||
m_delay_adjust_sys_list.swap(tmp_continue_adjust_sys_list);
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// 遍历当前运行中的子系统,如果已没有分配资金和持仓,则回收
|
||||
//---------------------------------------------------------------
|
||||
#if 0
|
||||
m_tmp_will_remove_sys.clear();
|
||||
for (auto& running_sys : m_running_sys_set) {
|
||||
Stock stock = running_sys->getStock();
|
||||
TMPtr sub_tm = running_sys->getTM();
|
||||
PositionRecord position = sub_tm->getPosition(date, stock);
|
||||
price_t cash = sub_tm->currentCash();
|
||||
|
||||
price_t min_cash = 1.0;
|
||||
KRecord krecord = stock.getKRecord(date);
|
||||
if (krecord.isValid()) {
|
||||
min_cash = krecord.openPrice * stock.minTradeNumber();
|
||||
}
|
||||
|
||||
// 如果系统的剩余资金小于交易一手的资金,则回收资金??? TODO 放到 AF 中进行处理不足一手的
|
||||
if (cash != 0 && cash <= min_cash) {
|
||||
sub_tm->checkout(date, cash);
|
||||
m_cash_tm->checkin(date, cash);
|
||||
HKU_INFO_IF(trace, "Recycle cash ({:<.2f}) from {}, current cash: {}", cash,
|
||||
running_sys->name(), m_cash_tm->currentCash());
|
||||
// 如果已经没有持仓,则回收
|
||||
if (position.number <= 0.0) {
|
||||
m_tmp_will_remove_sys.emplace_back(running_sys, 0.);
|
||||
HKU_INFO_IF(trace, "[PF] Recycle running sys: {}", running_sys->name());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 依据待移除列表将系统从运行中系统列表里删除
|
||||
for (auto& sub_sys : m_tmp_will_remove_sys) {
|
||||
HKU_INFO_IF(trace, "Recycling system {}", sub_sys.sys->name());
|
||||
m_running_sys_set.erase(sub_sys.sys);
|
||||
}
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------
|
||||
// 调仓日,进行资金分配调整
|
||||
//---------------------------------------------------
|
||||
@ -395,6 +360,11 @@ void Portfolio::_runMoment(const Datetime& date, bool adjust) {
|
||||
//----------------------------------------------------------------------------
|
||||
for (auto& sub_sys : m_running_sys_set) {
|
||||
HKU_TRACE_IF(trace, "run: {}", sub_sys->name());
|
||||
if (adjust) {
|
||||
auto sg = sub_sys->getSG();
|
||||
sg->startCycle(date, nextCycle);
|
||||
}
|
||||
|
||||
auto tr = sub_sys->runMoment(date);
|
||||
if (!tr.isNull()) {
|
||||
HKU_INFO_IF(trace, "[PF] {}", tr);
|
||||
@ -449,9 +419,13 @@ void Portfolio::_runMoment(const Datetime& date, bool adjust) {
|
||||
#endif
|
||||
// clang-format off
|
||||
HKU_INFO("+------------+------------+------------+--------------+--------------+-------------+-------------+");
|
||||
if (++count >= getParam<int>("trace_max_num")) {
|
||||
HKU_INFO("+ ... ... more +");
|
||||
HKU_INFO("+------------+------------+------------+--------------+--------------+-------------+-------------+");
|
||||
count++;
|
||||
int trace_max_num = getParam<int>("trace_max_num");
|
||||
if (count >= trace_max_num) {
|
||||
if (count > trace_max_num) {
|
||||
HKU_INFO("+ ... ... more +");
|
||||
HKU_INFO("+------------+------------+------------+--------------+--------------+-------------+-------------+");
|
||||
}
|
||||
break;
|
||||
}
|
||||
// clang-format on
|
||||
|
@ -101,7 +101,7 @@ private:
|
||||
/** 运行前准备 */
|
||||
void _readyForRun();
|
||||
|
||||
void _runMoment(const Datetime& date, bool adjust);
|
||||
void _runMoment(const Datetime& date, const Datetime& nextCycle, bool adjust);
|
||||
|
||||
protected:
|
||||
string m_name;
|
||||
|
@ -25,17 +25,21 @@ HKU_API std::ostream& operator<<(std::ostream& os, const SignalPtr& sg) {
|
||||
}
|
||||
|
||||
SignalBase::SignalBase() : m_name("SignalBase"), m_hold_long(false), m_hold_short(false) {
|
||||
setParam<bool>("alternate", true); // 买入卖出信号交替出现
|
||||
setParam<bool>("support_borrow_stock", false); // 支持发出空头信号
|
||||
initParam();
|
||||
}
|
||||
|
||||
SignalBase::SignalBase(const string& name) : m_name(name), m_hold_long(false), m_hold_short(false) {
|
||||
setParam<bool>("alternate", true);
|
||||
setParam<bool>("support_borrow_stock", false);
|
||||
initParam();
|
||||
}
|
||||
|
||||
SignalBase::~SignalBase() {}
|
||||
|
||||
void SignalBase::initParam() {
|
||||
setParam<bool>("cycle", false); // 仅在指定周期范围内计算
|
||||
setParam<bool>("alternate", true); // 买入卖出信号交替出现
|
||||
setParam<bool>("support_borrow_stock", false); // 支持发出空头信号
|
||||
}
|
||||
|
||||
void SignalBase::baseCheckParam(const string& name) const {}
|
||||
void SignalBase::paramChanged() {}
|
||||
|
||||
@ -66,7 +70,12 @@ SignalPtr SignalBase::clone() {
|
||||
void SignalBase::setTO(const KData& kdata) {
|
||||
HKU_IF_RETURN(m_kdata == kdata, void());
|
||||
m_kdata = kdata;
|
||||
if (!kdata.empty()) {
|
||||
bool cycle = getParam<bool>("cycle");
|
||||
if (!cycle) {
|
||||
m_cycle_start = Datetime::min();
|
||||
m_cycle_end = Datetime::max();
|
||||
}
|
||||
if (!cycle && !kdata.empty()) {
|
||||
_calculate();
|
||||
}
|
||||
}
|
||||
@ -80,6 +89,17 @@ void SignalBase::reset() {
|
||||
_reset();
|
||||
}
|
||||
|
||||
void SignalBase::startCycle(const Datetime& start, const Datetime& close) {
|
||||
HKU_IF_RETURN(!getParam<bool>("cycle"), void());
|
||||
HKU_ASSERT(start != Null<Datetime>() && close != Null<Datetime>() && start < close);
|
||||
HKU_CHECK(start >= m_cycle_end, "curretn start: {}, pre cycle end: {}", start, m_cycle_end);
|
||||
m_cycle_start = start;
|
||||
m_cycle_end = close;
|
||||
if (!m_kdata.empty()) {
|
||||
_calculate();
|
||||
}
|
||||
}
|
||||
|
||||
DatetimeList SignalBase::getBuySignal() const {
|
||||
DatetimeList result(m_buySig.size());
|
||||
std::copy(m_buySig.begin(), m_buySig.end(), result.begin());
|
||||
|
@ -84,6 +84,10 @@ public:
|
||||
*/
|
||||
const KData& getTO() const;
|
||||
|
||||
void startCycle(const Datetime& start, const Datetime& end);
|
||||
const Datetime& getCycleStart() const;
|
||||
const Datetime& getCycleEnd() const;
|
||||
|
||||
/** 复位操作 */
|
||||
void reset();
|
||||
|
||||
@ -106,6 +110,9 @@ public:
|
||||
/** 子类计算接口,在setTO中调用 */
|
||||
virtual void _calculate() = 0;
|
||||
|
||||
private:
|
||||
void initParam();
|
||||
|
||||
protected:
|
||||
string m_name;
|
||||
KData m_kdata;
|
||||
@ -118,6 +125,9 @@ protected:
|
||||
std::set<Datetime> m_buySig;
|
||||
std::set<Datetime> m_sellSig;
|
||||
|
||||
Datetime m_cycle_start{Datetime::min()};
|
||||
Datetime m_cycle_end{Datetime::min()};
|
||||
|
||||
//============================================
|
||||
// 序列化支持
|
||||
//============================================
|
||||
@ -218,6 +228,14 @@ inline bool SignalBase::shouldSell(const Datetime& datetime) const {
|
||||
return m_sellSig.count(datetime) ? true : false;
|
||||
}
|
||||
|
||||
inline const Datetime& SignalBase::getCycleStart() const {
|
||||
return m_cycle_start;
|
||||
}
|
||||
|
||||
inline const Datetime& SignalBase::getCycleEnd() const {
|
||||
return m_cycle_end;
|
||||
}
|
||||
|
||||
} /* namespace hku */
|
||||
|
||||
#if FMT_VERSION >= 90000
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "crt/SG_AllwaysBuy.h"
|
||||
#include "crt/SG_Cross.h"
|
||||
#include "crt/SG_CrossGold.h"
|
||||
#include "crt/SG_Cycle.h"
|
||||
#include "crt/SG_Flex.h"
|
||||
#include "crt/SG_Single.h"
|
||||
#include "crt/SG_Bool.h"
|
||||
|
16
hikyuu_cpp/hikyuu/trade_sys/signal/crt/SG_Cycle.h
Normal file
16
hikyuu_cpp/hikyuu/trade_sys/signal/crt/SG_Cycle.h
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (c) 2024 hikyuu.org
|
||||
*
|
||||
* Created on: 2024-04-01
|
||||
* Author: fasiondog
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../SignalBase.h"
|
||||
|
||||
namespace hku {
|
||||
|
||||
SignalPtr HKU_API SG_Cycle();
|
||||
|
||||
}
|
35
hikyuu_cpp/hikyuu/trade_sys/signal/imp/CycleSignal.cpp
Normal file
35
hikyuu_cpp/hikyuu/trade_sys/signal/imp/CycleSignal.cpp
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2024 hikyuu.org
|
||||
*
|
||||
* Created on: 2024-03-30
|
||||
* Author: fasiondog
|
||||
*/
|
||||
|
||||
#include "CycleSignal.h"
|
||||
|
||||
#if HKU_SUPPORT_SERIALIZATION
|
||||
BOOST_CLASS_EXPORT(hku::CycleSignal)
|
||||
#endif
|
||||
|
||||
namespace hku {
|
||||
|
||||
CycleSignal::CycleSignal() : SignalBase("SG_AllwaysBuy") {
|
||||
setParam<bool>("cycle", true);
|
||||
}
|
||||
|
||||
void CycleSignal::_checkParam(const string& name) const {
|
||||
if ("cycle" == name) {
|
||||
bool cycle = getParam<bool>(name);
|
||||
HKU_CHECK(cycle, "param cycle must be true!");
|
||||
}
|
||||
}
|
||||
|
||||
void CycleSignal::_calculate() {
|
||||
_addBuySignal(getCycleStart());
|
||||
}
|
||||
|
||||
SignalPtr HKU_API SG_Cycle() {
|
||||
return make_shared<CycleSignal>();
|
||||
}
|
||||
|
||||
} // namespace hku
|
25
hikyuu_cpp/hikyuu/trade_sys/signal/imp/CycleSignal.h
Normal file
25
hikyuu_cpp/hikyuu/trade_sys/signal/imp/CycleSignal.h
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2024 hikyuu.org
|
||||
*
|
||||
* Created on: 2024-04-01
|
||||
* Author: fasiondog
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../SignalBase.h"
|
||||
|
||||
namespace hku {
|
||||
|
||||
class CycleSignal : public SignalBase {
|
||||
SIGNAL_IMP(CycleSignal)
|
||||
SIGNAL_NO_PRIVATE_MEMBER_SERIALIZATION
|
||||
|
||||
public:
|
||||
CycleSignal();
|
||||
virtual ~CycleSignal() = default;
|
||||
|
||||
virtual void _checkParam(const string& name) const override;
|
||||
};
|
||||
|
||||
}
|
@ -209,4 +209,5 @@ void export_Signal(py::module& m) {
|
||||
)");
|
||||
|
||||
m.def("SG_AllwaysBuy", SG_AllwaysBuy);
|
||||
m.def("SG_Cycle", SG_Cycle);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user