update SG for support cycle

This commit is contained in:
fasiondog 2024-04-02 13:33:24 +08:00
parent fa57d64a6c
commit 966c8e6657
22 changed files with 78 additions and 63 deletions

View File

@ -2,20 +2,19 @@
# -*- coding: utf8 -*-
# cp936
#===============================================================================
# ===============================================================================
# Aothor: fasiondog
# History: 20160407, Added by fasiondog
#===============================================================================
# ===============================================================================
from hikyuu import *
def TurtleSG(self):
def TurtleSG(self, k):
n = self.get_param("n")
k = self.to
c = CLOSE(k)
h = REF(HHV(c, n), 1) #n日高点
L = REF(LLV(c, n), 1) #n日低点
h = REF(HHV(c, n), 1) # n日高点
L = REF(LLV(c, n), 1) # n日低点
for i in range(h.discard, len(k)):
if (c[i] >= h[i]):
self._add_buy_signal(k[i].datetime)
@ -30,7 +29,7 @@ if __name__ == "__main__":
s = get_stock("sh000001")
k = s.get_kdata(Query(-500))
#只有设置交易对象时,才会开始实际计算
# 只有设置交易对象时,才会开始实际计算
sg.to = k
dates = k.get_datetime_list()
for d in dates:

View File

@ -2,10 +2,10 @@
# -*- coding: utf8 -*-
# cp936
#===============================================================================
# ===============================================================================
# Aothor: fasiondog
# History: 20160407, Added by fasiondog
#===============================================================================
# ===============================================================================
from hikyuu import *
@ -18,12 +18,11 @@ class TurtleSignal(SignalBase):
def _clone(self):
return TurtleSignal()
def _calculate(self):
def _calculate(self, k):
n = self.get_param("n")
k = self.to
c = CLOSE(k)
h = REF(HHV(c, n), 1) #n日高点
L = REF(LLV(c, n), 1) #n日低点
h = REF(HHV(c, n), 1) # n日高点
L = REF(LLV(c, n), 1) # n日低点
for i in range(h.discard, len(k)):
if (c[i] >= h[i]):
self._add_buy_signal(k[i].datetime)
@ -38,7 +37,7 @@ if __name__ == "__main__":
s = get_stock("sh000001")
k = s.get_kdata(Query(-500))
#只有设置交易对象时,才会开始实际计算
# 只有设置交易对象时,才会开始实际计算
sg.to = k
dates = k.get_datetime_list()
for d in dates:

View File

@ -2,20 +2,20 @@
# -*- coding: utf8 -*-
# cp936
#===============================================================================
# ===============================================================================
# Aothor: fasiondog
# History: 20160407, Added by fasiondog
#===============================================================================
# ===============================================================================
from hikyuu import *
def TurtleSG(self):
def TurtleSG(self, k):
n = self.get_param("n")
k = self.to
c = CLOSE(k)
h = REF(HHV(c, n), 1) #n日高点
L = REF(LLV(c, n), 1) #n日低点
h = REF(HHV(c, n), 1) # n日高点
L = REF(LLV(c, n), 1) # n日低点
for i in range(h.discard, len(k)):
if (c[i] >= h[i]):
self._add_buy_signal(k[i].datetime)
@ -30,7 +30,7 @@ if __name__ == "__main__":
s = get_stock("sh000001")
k = s.get_kdata(Query(-500))
#只有设置交易对象时,才会开始实际计算
# 只有设置交易对象时,才会开始实际计算
sg.to = k
dates = k.get_datetime_list()
for d in dates:

View File

@ -26,7 +26,7 @@ class SignalPython(SignalBase):
p._x = self._x
return p
def _calculate(self):
def _calculate(self, kdata):
self._add_buy_signal(Datetime(201201210000))
self._add_sell_signal(Datetime(201201300000))
@ -91,7 +91,7 @@ class SignalTest(unittest.TestCase):
self.assertEqual(p_clone.get_param("test"), 30)
def testSignal(self):
def testSignal(self, kdata):
self._add_buy_signal(Datetime(201201210000))
self._add_sell_signal(Datetime(201201300000))

View File

@ -72,11 +72,28 @@ SignalPtr SignalBase::clone() {
void SignalBase::setTO(const KData& kdata) {
HKU_IF_RETURN(m_kdata == kdata, void());
m_kdata = kdata;
HKU_IF_RETURN(kdata.empty(), void());
bool cycle = getParam<bool>("cycle");
m_cycle_start = Datetime::min();
m_cycle_end = cycle ? Datetime::min() : Datetime::max();
if (!cycle && !kdata.empty()) {
_calculate();
m_cycle_start = kdata[0].datetime;
const KQuery& query = kdata.getQuery();
if (query.queryType() == KQuery::DATE) {
m_cycle_end = query.endDatetime();
} else {
size_t last_pos = kdata.lastPos();
const Stock& stk = kdata.getStock();
if (last_pos + 1 >= stk.getCount(query.kType())) {
m_cycle_end = Null<Datetime>();
} else {
KRecord krecord = stk.getKRecord(last_pos + 1, query.kType());
m_cycle_end = krecord.datetime;
}
}
KData cycle_kdata = kdata.getKData(m_cycle_start, m_cycle_end);
if (!cycle) {
_calculate(cycle_kdata);
}
}
@ -95,8 +112,9 @@ void SignalBase::startCycle(const Datetime& start, const Datetime& 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();
KData kdata = m_kdata.getKData(start, close);
if (!kdata.empty()) {
_calculate(kdata);
}
}

View File

@ -108,7 +108,7 @@ public:
virtual SignalPtr _clone() = 0;
/** 子类计算接口在setTO中调用 */
virtual void _calculate() = 0;
virtual void _calculate(const KData&) = 0;
private:
void initParam();
@ -196,7 +196,7 @@ public: \
virtual SignalPtr _clone() override { \
return SignalPtr(new classname()); \
} \
virtual void _calculate() override;
virtual void _calculate(const KData&) override;
/**
* 使

View File

@ -24,8 +24,7 @@ void AllwaysBuySignal::_checkParam(const string& name) const {
}
}
void AllwaysBuySignal::_calculate() {
const auto& kdata = getTO();
void AllwaysBuySignal::_calculate(const KData& kdata) {
for (auto iter = kdata.cbegin(); iter != kdata.cend(); ++iter) {
_addBuySignal(iter->datetime);
}

View File

@ -30,13 +30,13 @@ SignalPtr BandSignal::_clone() {
return SignalPtr(p);
}
void BandSignal::_calculate() {
Indicator ind = m_ind(m_kdata);
void BandSignal::_calculate(const KData& kdata) {
Indicator ind = m_ind(kdata);
size_t discard = ind.discard();
size_t total = ind.size();
auto const* inddata = ind.data();
auto const* ks = m_kdata.data();
auto const* ks = kdata.data();
for (size_t i = discard; i < total; ++i) {
if (inddata[i] > m_upper) {
_addBuySignal(ks[i].datetime);

View File

@ -21,7 +21,7 @@ public:
virtual ~BandSignal();
virtual SignalPtr _clone() override;
virtual void _calculate() override;
virtual void _calculate(const KData& kdata) override;
private:
Indicator m_ind;

View File

@ -28,16 +28,16 @@ SignalPtr BoolSignal::_clone() {
return SignalPtr(p);
}
void BoolSignal::_calculate() {
Indicator buy = m_bool_buy(m_kdata);
Indicator sell = m_bool_sell(m_kdata);
void BoolSignal::_calculate(const KData& kdata) {
Indicator buy = m_bool_buy(kdata);
Indicator sell = m_bool_sell(kdata);
HKU_ERROR_IF_RETURN(buy.size() != sell.size(), void(), "buy.size() != sell.size()");
size_t discard = buy.discard() > sell.discard() ? buy.discard() : sell.discard();
size_t total = buy.size();
auto const* buydata = buy.data();
auto const* selldata = sell.data();
auto const* ks = m_kdata.data();
auto const* ks = kdata.data();
for (size_t i = discard; i < total; ++i) {
if (buydata[i] > 0.0)
_addBuySignal(ks[i].datetime);

View File

@ -21,7 +21,7 @@ public:
virtual ~BoolSignal();
virtual SignalPtr _clone() override;
virtual void _calculate() override;
virtual void _calculate(const KData& kdata) override;
private:
Indicator m_bool_buy;

View File

@ -28,16 +28,16 @@ SignalPtr CrossGoldSignal::_clone() {
return SignalPtr(p);
}
void CrossGoldSignal::_calculate() {
Indicator fast = m_fast(m_kdata);
Indicator slow = m_slow(m_kdata);
void CrossGoldSignal::_calculate(const KData& kdata) {
Indicator fast = m_fast(kdata);
Indicator slow = m_slow(kdata);
HKU_ERROR_IF_RETURN(fast.size() != slow.size(), void(), "fast.size() != slow.size()");
size_t discard = fast.discard() > slow.discard() ? fast.discard() : slow.discard();
size_t total = fast.size();
auto const* fastdata = fast.data();
auto const* slowdata = slow.data();
auto const* ks = m_kdata.data();
auto const* ks = kdata.data();
for (size_t i = discard + 1; i < total; ++i) {
if (fastdata[i - 1] < slowdata[i - 1] && fastdata[i] > slowdata[i] &&
fastdata[i - 1] < fastdata[i] && slowdata[i - 1] < slowdata[i]) {

View File

@ -21,7 +21,7 @@ public:
virtual ~CrossGoldSignal();
virtual SignalPtr _clone() override;
virtual void _calculate() override;
virtual void _calculate(const KData& kdata) override;
private:
Indicator m_fast;

View File

@ -28,16 +28,16 @@ SignalPtr CrossSignal::_clone() {
return SignalPtr(p);
}
void CrossSignal::_calculate() {
Indicator fast = m_fast(m_kdata);
Indicator slow = m_slow(m_kdata);
void CrossSignal::_calculate(const KData& kdata) {
Indicator fast = m_fast(kdata);
Indicator slow = m_slow(kdata);
HKU_ERROR_IF_RETURN(fast.size() != slow.size(), void(), "fast.size() != slow.size()");
size_t discard = fast.discard() > slow.discard() ? fast.discard() : slow.discard();
size_t total = fast.size();
auto const* fastdata = fast.data();
auto const* slowdata = slow.data();
auto const* ks = m_kdata.data();
auto const* ks = kdata.data();
for (size_t i = discard + 1; i < total; ++i) {
if (fastdata[i - 1] < slowdata[i - 1] && fastdata[i] > slowdata[i]) {
_addBuySignal(ks[i].datetime);

View File

@ -21,7 +21,7 @@ public:
virtual ~CrossSignal();
virtual SignalPtr _clone() override;
virtual void _calculate() override;
virtual void _calculate(const KData& kdata) override;
private:
Indicator m_fast;

View File

@ -24,7 +24,7 @@ void CycleSignal::_checkParam(const string& name) const {
}
}
void CycleSignal::_calculate() {
void CycleSignal::_calculate(const KData& kdata) {
_addBuySignal(getCycleStart());
}

View File

@ -43,11 +43,11 @@ SignalPtr SingleSignal::_clone() {
return SignalPtr(p);
}
void SingleSignal::_calculate() {
void SingleSignal::_calculate(const KData& kdata) {
int filter_n = getParam<int>("filter_n");
double filter_p = getParam<double>("filter_p");
Indicator ind = m_ind(m_kdata);
Indicator ind = m_ind(kdata);
Indicator dev = STDEV(DIFF(ind), filter_n);
size_t start = dev.discard();
@ -55,7 +55,7 @@ void SingleSignal::_calculate() {
auto const* inddata = ind.data();
auto const* devdata = dev.data();
auto const* ks = m_kdata.data();
auto const* ks = kdata.data();
size_t total = dev.size();
for (size_t i = start; i < total; ++i) {
double dama = inddata[i] - inddata[i - 1];

View File

@ -22,7 +22,7 @@ public:
virtual void _checkParam(const string& name) const override;
virtual SignalPtr _clone() override;
virtual void _calculate() override;
virtual void _calculate(const KData& kdata) override;
private:
Indicator m_ind;

View File

@ -46,11 +46,11 @@ SignalPtr SingleSignal2::_clone() {
return SignalPtr(p);
}
void SingleSignal2::_calculate() {
void SingleSignal2::_calculate(const KData& kdata) {
int filter_n = getParam<int>("filter_n");
double filter_p = getParam<double>("filter_p");
Indicator ind = m_ind(m_kdata);
Indicator ind = m_ind(kdata);
Indicator dev = REF(STDEV(DIFF(ind), filter_n), 1);
size_t start = dev.discard();
@ -62,7 +62,7 @@ void SingleSignal2::_calculate() {
auto const* buydata = buy.data();
auto const* selldata = sell.data();
auto const* devdata = dev.data();
auto const* ks = m_kdata.data();
auto const* ks = kdata.data();
for (size_t i = start; i < total; ++i) {
double filter = filter_p * devdata[i];
if (buydata[i] > filter) {

View File

@ -22,7 +22,7 @@ public:
virtual void _checkParam(const string& name) const override;
virtual SignalPtr _clone() override;
virtual void _calculate() override;
virtual void _calculate(const KData& kdata) override;
private:
Indicator m_ind;

View File

@ -33,7 +33,7 @@ public:
return SignalPtr(p);
}
virtual void _calculate() {}
virtual void _calculate(const KData &) override {}
private:
int m_x;

View File

@ -18,8 +18,8 @@ public:
using SignalBase::SignalBase;
PySignalBase(const SignalBase& base) : SignalBase(base) {}
void _calculate() override {
PYBIND11_OVERLOAD_PURE(void, SignalBase, _calculate, );
void _calculate(const KData& kdata) override {
PYBIND11_OVERLOAD_PURE(void, SignalBase, _calculate, kdata);
}
void _reset() override {