This commit is contained in:
fasiondog 2016-05-16 01:45:01 +08:00
parent 65d30fe852
commit c92c4f4575
21 changed files with 131 additions and 93 deletions

View File

@ -85,21 +85,21 @@ public:
/**
* Null<hku_int64>()
*/
const hku_int64 start() const {
hku_int64 start() const {
return m_queryType != INDEX ? Null<hku_int64>() : m_start;
}
/**
* Null<hku_int64>()
*/
const hku_int64 end() const {
hku_int64 end() const {
return m_queryType != INDEX ? Null<hku_int64>() : m_end;
}
/**
* Null<Datetime>()
*/
const Datetime startDatetime() const {
Datetime startDatetime() const {
return m_queryType != DATE
? Null<Datetime>()
: Datetime((hku_uint64)m_start);
@ -108,20 +108,20 @@ public:
/**
* Null<Datetime>()
*/
const Datetime endDatetime() const {
Datetime endDatetime() const {
return m_queryType != DATE
? Null<Datetime>()
: Datetime((hku_uint64)m_end);
}
/** 获取查询条件类型 */
const QueryType queryType() const { return m_queryType; }
QueryType queryType() const { return m_queryType; }
/** 获取K线数据类型 */
const KType kType() const { return m_dataType; }
KType kType() const { return m_dataType; }
/** 获取复权类型 */
const RecoverType recoverType() const { return m_recoverType; }
RecoverType recoverType() const { return m_recoverType; }
/** 获取queryType名称用于显示输出 */
static string getQueryTypeName(QueryType);

View File

@ -38,7 +38,6 @@ ConditionBase::~ConditionBase() {
void ConditionBase::reset() {
m_valid.clear();
m_invalid.clear();
_reset();
}
@ -48,7 +47,6 @@ ConditionPtr ConditionBase::clone() {
p->m_name = m_name;
p->m_kdata = m_kdata;
p->m_valid = m_valid;
p->m_invalid = m_invalid;
return p;
}
@ -56,6 +54,10 @@ ConditionPtr ConditionBase::clone() {
void ConditionBase::setTO(const KData& kdata) {
reset();
m_kdata = kdata;
if (!m_sg) {
HKU_WARN("m_sg is NULL! [ConditionBase::setTO]");
return;
}
if (!kdata.empty()) {
_calculate();
}
@ -65,8 +67,11 @@ void ConditionBase::_addValid(const Datetime& datetime) {
m_valid.insert(datetime);
}
void ConditionBase::_addInvalid(const Datetime& datetime) {
m_invalid.insert(datetime);
bool ConditionBase::isValid(const Datetime& datetime) {
if (m_valid.count(datetime) != 0) {
return true;
}
return false;
}
} /* namespace hku */

View File

@ -13,6 +13,7 @@
#include "../../utilities/util.h"
#include "../../KData.h"
#include "../../trade_manage/TradeManager.h"
#include "../signal/SignalBase.h"
#if HKU_SUPPORT_SERIALIZATION
#include <boost/serialization/shared_ptr.hpp>
@ -57,18 +58,18 @@ public:
/** 获取交易管理实例 */
TradeManagerPtr getTM() const;
/** 设置系统信号指示器 */
void setSG(const SGPtr& sg);
/** 获取系统信号指示器 */
SGPtr getSG() const;
/**
* _calculate中调用
* @param datetime
*/
void _addValid(const Datetime& datetime);
/**
* _calculate中调用
* @param datetime
*/
void _addInvalid(const Datetime& datetime);
typedef shared_ptr<ConditionBase> ConditionPtr;
/** 克隆操作 */
ConditionPtr clone();
@ -78,7 +79,7 @@ public:
* @param datetime
* @return true | false
*/
virtual bool isValid(const Datetime& datetime) = 0;
bool isValid(const Datetime& datetime);
virtual void _calculate() = 0;
@ -91,9 +92,10 @@ public:
protected:
string m_name;
KData m_kdata;
TradeManagerPtr m_tm;
TMPtr m_tm;
SGPtr m_sg;
std::set<Datetime> m_valid;
std::set<Datetime> m_invalid;
//============================================
// 序列化支持
@ -107,7 +109,6 @@ private:
ar & boost::serialization::make_nvp("m_name", name);
ar & BOOST_SERIALIZATION_NVP(m_params);
ar & BOOST_SERIALIZATION_NVP(m_valid);
ar & BOOST_SERIALIZATION_NVP(m_invalid);
// m_kdata是系统运行时临时设置不需要序列化
//ar & BOOST_SERIALIZATION_NVP(m_ktype);
}
@ -119,7 +120,6 @@ private:
m_name = UTF8ToGB(name);
ar & BOOST_SERIALIZATION_NVP(m_params);
ar & BOOST_SERIALIZATION_NVP(m_valid);
ar & BOOST_SERIALIZATION_NVP(m_invalid);
// m_kdata是系统运行时临时设置不需要序列化
//ar & BOOST_SERIALIZATION_NVP(m_ktype);
}
@ -170,7 +170,6 @@ typedef shared_ptr<ConditionBase> CNPtr;
virtual ConditionPtr _clone() {\
return ConditionPtr(new classname());\
}\
virtual bool isValid(const Datetime& datetime); \
virtual void _calculate();
@ -195,6 +194,14 @@ inline void ConditionBase::setTM(const TradeManagerPtr& tm) {
m_tm = tm;
}
inline SGPtr ConditionBase::getSG() const {
return m_sg;
}
inline void ConditionBase::setSG(const SGPtr& sg) {
m_sg = sg;
}
inline TradeManagerPtr ConditionBase::getTM() const {
return m_tm;
}

View File

@ -14,6 +14,11 @@
namespace hku {
/**
* 使线op值线op时
* @param op
* @return
*/
CNPtr HKU_API CN_OPLine(const Operand& op);
} /* namespace hku */

View File

@ -5,10 +5,12 @@
* Author: Administrator
*/
#include <hikyuu/trade_sys/condition/imp/OPLineCondition.h>
#include "OPLineCondition.h"
#include "../../../trade_manage/crt/crtTM.h"
#include "../../../trade_manage/crt/TC_Zero.h"
#include "../../../indicator/crt/PRICELIST.h"
#include "../../system/crt/SYS_Simple.h"
#include "../../moneymanager/crt/MM_FixedCount.h"
namespace hku {
@ -39,44 +41,32 @@ void OPLineCondition::_calculate() {
if (m_kdata.size() == 0)
return;
TradeManagerPtr tm = crtTM(m_kdata[0].datetime, 0.0, TC_Zero());
KQuery::KType ktype = m_kdata.getQuery().kType();
Stock stock = m_kdata.getStock();
KQuery query = m_kdata.getQuery();
SYSPtr sys = SYS_Simple();
TMPtr tm = crtTM(m_kdata[0].datetime, 0.0, TC_Zero());
MMPtr mm = MM_FixedCount(stock.minTradeNumber());
mm->setParam<bool>("auto-checkin", true);
sys->setTM(tm);
sys->setMM(mm);
sys->setSG(m_sg);
sys->run(m_kdata.getStock(), m_kdata.getQuery());
KQuery::KType ktype = query.kType();
DatetimeList dates = m_kdata.getDatetimeList();
Indicator profit = PRICELIST(tm->getProfitCurve(dates, ktype));
Indicator op = m_op(profit);
size_t discard = profit.discard() > op.discard()
? profit.discard() : op.discard();
for (size_t i = 0; i < discard; i++) {
_addInvalid(dates[i]);
}
size_t total = dates.size();
bool hold = false;
for (size_t i = discard + 1; i < total; i++) {
if (profit[i-1] < op[i-1] && profit[i] >= op[i]) {
hold = true;
} else if (profit[i-1] > op[i-1] && profit[i] >= op[i]) {
hold = false;
}
if (hold) {
Indicator x = profit - op;
for (size_t i = 0; i < x.size(); i++) {
if (x[i] > 0) {
_addValid(dates[i]);
} else {
_addInvalid(dates[i]);
}
}
}
bool OPLineCondition::isValid(const Datetime& datetime) {
if (m_valid.count(datetime) != 0) {
return true;
} else if (m_invalid.count(datetime) != 0) {
return false;
}
return false;
}
CNPtr HKU_API CN_OPLine(const Operand& op) {
return CNPtr(new OPLineCondition(op));

View File

@ -19,7 +19,6 @@ public:
OPLineCondition(const Operand&);
virtual ~OPLineCondition();
virtual bool isValid(const Datetime& datetime);
virtual void _calculate();
virtual void _reset();
virtual ConditionPtr _clone();

View File

@ -23,6 +23,11 @@ HKU_API std::ostream& operator <<(std::ostream &os, const EnvironmentPtr& en) {
return os;
}
EnvironmentBase::EnvironmentBase()
: m_name("EnvironmentBase"), m_ktype(KQuery::DAY) {
}
EnvironmentBase::EnvironmentBase(const string& name)
: m_name(name), m_ktype(KQuery::DAY) {

View File

@ -29,11 +29,15 @@ class HKU_API EnvironmentBase {
PARAMETER_SUPPORT
public:
EnvironmentBase();
EnvironmentBase(const string& name);
virtual ~EnvironmentBase();
/** 获取名称 */
const string& name() const;
string name() const;
/** 设置名称 */
void name(const string& name);
/** 复位 */
void reset();
@ -123,6 +127,7 @@ BOOST_SERIALIZATION_ASSUME_ABSTRACT(EnvironmentBase)
* @ingroup Environment
*/
typedef shared_ptr<EnvironmentBase> EnvironmentPtr;
typedef shared_ptr<EnvironmentBase> EVPtr;
/**
@ -133,10 +138,14 @@ HKU_API std::ostream& operator <<(std::ostream &os, const EnvironmentPtr&);
HKU_API std::ostream& operator <<(std::ostream &os, const EnvironmentBase&);
inline const string& EnvironmentBase::name() const {
inline string EnvironmentBase::name() const {
return m_name;
}
inline void EnvironmentBase::name(const string& name) {
m_name = name;
}
inline void EnvironmentBase::reset() {
m_ktype = KQuery::DAY;
_reset();

View File

@ -113,6 +113,11 @@ size_t MoneyManagerBase
//转换为最小交易量的整数倍
n = (n / stock.minTradeNumber()) * stock.minTradeNumber();
if (n > stock.maxTradeNumber()) {
n = stock.maxTradeNumber();
HKU_INFO("Over stock.maxTradeNumber! MoneyManagerBase::getBuyNumber]");
}
//在现金不足时,自动补充存入现金
if (getParam<bool>("auto-checkin")) {
price_t cash = m_tm->currentCash();

View File

@ -195,6 +195,7 @@ BOOST_SERIALIZATION_ASSUME_ABSTRACT(MoneyManagerBase)
* @ingroup MoneyManager
*/
typedef shared_ptr<MoneyManagerBase> MoneyManagerPtr;
typedef shared_ptr<MoneyManagerBase> MMPtr;
#define MONEY_MANAGER_IMP(classname) public:\

View File

@ -154,6 +154,7 @@ BOOST_SERIALIZATION_ASSUME_ABSTRACT(ProfitGoalBase)
* @ingroup ProfitGoal
*/
typedef shared_ptr<ProfitGoalBase> ProfitGoalPtr;
typedef shared_ptr<ProfitGoalBase> PGPtr;
HKU_API std::ostream & operator<<(std::ostream& os, const ProfitGoalBase& pg);
HKU_API std::ostream & operator<<(std::ostream& os, const ProfitGoalPtr& pg);

View File

@ -183,6 +183,7 @@ BOOST_SERIALIZATION_ASSUME_ABSTRACT(SignalBase)
* @ingroup Signal
*/
typedef shared_ptr<SignalBase> SignalPtr;
typedef shared_ptr<SignalBase> SGPtr;
HKU_API std::ostream & operator<<(std::ostream&, const SignalBase&);
HKU_API std::ostream & operator<<(std::ostream&, const SignalPtr&);

View File

@ -151,6 +151,7 @@ BOOST_SERIALIZATION_ASSUME_ABSTRACT(SlippageBase)
* @ingroup Slippage
*/
typedef shared_ptr<SlippageBase> SlippagePtr;
typedef shared_ptr<SlippageBase> SPPtr;
HKU_API std::ostream & operator<<(std::ostream&, const SlippageBase&);
HKU_API std::ostream & operator<<(std::ostream&, const SlippagePtr&);

View File

@ -165,6 +165,9 @@ BOOST_SERIALIZATION_ASSUME_ABSTRACT(StoplossBase)
* @ingroup StopLoss
*/
typedef boost::shared_ptr<StoplossBase> StoplossPtr;
typedef boost::shared_ptr<StoplossBase> SLPtr;
typedef boost::shared_ptr<StoplossBase> TakeProfitPtr;
typedef boost::shared_ptr<StoplossBase> TPPtr;
HKU_API std::ostream& operator <<(std::ostream& os, const StoplossBase&);
HKU_API std::ostream& operator <<(std::ostream& os, const StoplossPtr&);

View File

@ -134,13 +134,23 @@ void System::setKType(KQuery::KType ktype) {
}
void System::setTO(const KData& kdata) {
if (kdata.empty()) {
return;
}
m_kdata = kdata;
if (m_cn) m_cn->setTO(kdata);
//sg->setTO必须在cn->setTO之前cn会使用到sg防止sg被计算两次
if (m_sg) m_sg->setTO(kdata);
if (m_cn) m_cn->setTO(kdata);
if (m_st) m_st->setTO(kdata);
if (m_tp) m_tp->setTO(kdata);
if (m_pg) m_pg->setTO(kdata);
if (m_sp) m_sp->setTO(kdata);
KQuery::KType ktype = kdata.getQuery().kType();
if (m_ev) m_ev->setKType(ktype);
if (m_mm) m_mm->setKType(ktype);
}
@ -216,7 +226,10 @@ void System::run(const Stock& stock, const KQuery& query) {
return;
}
if (m_cn) m_cn->setTM(m_tm);
if (m_cn) {
m_cn->setTM(m_tm);
m_cn->setSG(m_sg);
}
if (m_mm) m_mm->setTM(m_tm);
if (m_pg) m_pg->setTM(m_tm);
if (m_st) m_st->setTM(m_tm);

View File

@ -261,6 +261,7 @@ private:
* @ingroup System
*/
typedef shared_ptr<System> SystemPtr;
typedef shared_ptr<System> SYSPtr;
typedef vector<SystemPtr> SystemList;
HKU_API std::ostream& operator <<(std::ostream &os, const System& sys);

View File

@ -30,10 +30,6 @@ public:
this->ConditionBase::_reset();
}
bool isValid(const Datetime& datetime) {
return this->get_override("isValid")(datetime);
}
void _calculate() {
this->get_override("_calculate")();
}
@ -55,11 +51,13 @@ void export_Condition() {
.add_property("name", get_name, set_name)
.def("getParam", &ConditionBase::getParam<boost::any>)
.def("setParam", &ConditionBase::setParam<object>)
.def("isValid", pure_virtual(&ConditionBase::isValid))
.def("isValid", &ConditionBase::isValid)
.def("setTO", &ConditionBase::setTO)
.def("getTO", &ConditionBase::getTO)
.def("setTM", &ConditionBase::setTM)
.def("getTM", &ConditionBase::getTM)
.def("setSG", &ConditionBase::setSG)
.def("getSG", &ConditionBase::getSG)
.def("reset", &ConditionBase::reset)
.def("clone", &ConditionBase::clone)
.def("_calculate", pure_virtual(&ConditionBase::_calculate))

View File

@ -36,15 +36,15 @@ public:
};
string (EnvironmentBase::*get_name)() const = &EnvironmentBase::name;
void (EnvironmentBase::*set_name)(const string&) = &EnvironmentBase::name;
void export_Environment() {
class_<EnvironmentWrap, boost::noncopyable>("EnvironmentBase", init<const string&>())
.def(self_ns::str(self))
.add_property("name",
make_function(&EnvironmentBase::name,
return_value_policy<copy_const_reference>()))
.add_property("params",
make_function(&EnvironmentBase::getParameter,
return_internal_reference<>()))
.add_property("name", get_name, set_name)
.def("getParam", &EnvironmentBase::getParam<boost::any>)
.def("setParam", &EnvironmentBase::setParam<object>)
.def("reset", &EnvironmentBase::reset)
.def("clone", &EnvironmentBase::clone)
.def("isValid", pure_virtual(&EnvironmentBase::isValid))

View File

@ -30,10 +30,6 @@ public:
return m_kdata;
}
virtual bool isValid(const Datetime& datetime) {
return m_flag;
}
virtual void _calculate() {}
virtual void _reset() {
if (m_flag) {
@ -80,7 +76,7 @@ BOOST_AUTO_TEST_CASE( test_Condition ) {
BOOST_CHECK(p->getParam<int>("n") == 10);
BOOST_CHECK(p->isValid(Datetime(200001010000)) == false);
p->reset();
BOOST_CHECK(p->isValid(Datetime(200001010000)) == true);
//BOOST_CHECK(p->isValid(Datetime(200001010000)) == true);
/** @arg 克隆操作 */
p->setParam<int>("n", 20);
@ -96,7 +92,7 @@ BOOST_AUTO_TEST_CASE( test_Condition ) {
BOOST_CHECK(p_clone->name() == "TEST");
BOOST_CHECK(p_clone->getParam<int>("n") == 20);
BOOST_CHECK(p_clone->isValid(Datetime(200001010000)) == true);
//BOOST_CHECK(p_clone->isValid(Datetime(200001010000)) == true);
p_clone->reset();
BOOST_CHECK(p_clone->isValid(Datetime(200001010000)) == false);
}

View File

@ -4,10 +4,15 @@
系统有效条件
============
系统有效条件
系统有效条件
----------------
.. py:function:: CN_OPLine(op)
固定使用股票最小交易量进行交易计算权益曲线的op值当权益曲线高于op时系统有效否则无效。
:param Operand op:
:return: 系统有效条件实例
自定义系统有效条件
@ -15,7 +20,6 @@
自定义系统有效条件接口:
* :py:meth:`ConditionBase.isValid` - 【必须】获取目标价格
* :py:meth:`ConditionBase._calculate` - 【必须】子类计算接口
* :py:meth:`ConditionBase._clone` - 【必须】克隆接口
* :py:meth:`ConditionBase._reset` - 【可选】重载私有变量
@ -79,12 +83,6 @@
:param Datetime datetime: 有效时间
.. py:method:: _addInvald(datetime)
加入无效时间在_calculate中调用
:param Datetime datetime: 无效时间
.. py:method:: reset()
复位操作

View File

@ -15,7 +15,7 @@ from hikyuu.trade_sys.environment import *
class EnvironmentPython(EnvironmentBase):
def __init__(self):
super(EnvironmentPython, self).__init__("EnvironmentPython")
self.params.set("n", 10)
self.setParam("n", 10)
self._m_flag = False
def isValid(self, market, datetime):
@ -36,22 +36,22 @@ class EnvironmentTest(unittest.TestCase):
def test_EnvironmentBase(self):
p = EnvironmentPython()
self.assertEqual(p.name, "EnvironmentPython")
self.assertEqual(p.params.get("n"), 10)
p.params.set("n",20)
self.assertEqual(p.params.get("n"), 20)
self.assertEqual(p.getParam("n"), 10)
p.setParam("n",20)
self.assertEqual(p.getParam("n"), 20)
self.assertEqual(p.isValid("SH", Datetime(200101010000)), False)
p.reset()
self.assertEqual(p.isValid("SH", Datetime(200101010000)), True)
p_clone = p.clone()
self.assertEqual(p_clone.name, "EnvironmentPython")
self.assertEqual(p_clone.params.get("n"), 20)
self.assertEqual(p_clone.getParam("n"), 20)
self.assertEqual(p_clone.isValid("SH", Datetime(200101010000)), True)
p.params.set("n", 1)
p_clone.params.set("n", 3)
self.assertEqual(p.params.get("n"), 1)
self.assertEqual(p_clone.params.get("n"), 3)
p.setParam("n", 1)
p_clone.setParam("n", 3)
self.assertEqual(p.getParam("n"), 1)
self.assertEqual(p_clone.getParam("n"), 3)
def suite():