WtStraDualThrust.h
source: wtcpp/folder98/folder06/folder1/file02.md
CTA策略demo
#pragma once
#include "../Includes/CtaStrategyDefs.h"
class WtStraDualThrust : public CtaStrategy
{
public:
WtStraDualThrust(const char* id);
virtual ~WtStraDualThrust();
public:
// 获取策略工厂名称
virtual const char* getFactName() override;
// 获取策略名称
virtual const char* getName() override;
// 通过配置文件初始化策略
virtual bool init(WTSVariant* cfg) override;
virtual void on_schedule(ICtaStraCtx* ctx, uint32_t curDate, uint32_t curTime) override;
virtual void on_init(ICtaStraCtx* ctx) override;
virtual void on_tick(ICtaStraCtx* ctx, const char* stdCode, WTSTickData* newTick) override;
private:
//指标参数
double _k1;
double _k2;
uint32_t _days;
//数据周期
std::string _period;
//K线条数
uint32_t _count
//合约代码
std::string _code;
bool _isstk;
};
WtStraDualThrust.cpp
extern const char* FACT_NAME;
WtStraDualThrust::WtStraDualThrust(const char* id)
: CtaStrategy(id)
{}
WtStraDualThrust::~WtStraDualThrust()
{}
const char* WtStraDualThrust::getFactName()
{
return FACT_NAME;
}
const char* WtStraDualThrust::getName()
{
return "DualThrust";
}
bool WtStraDualThrust::init(WTSVariant* cfg)
{
if (cfg == NULL)
return false;
_days = cfg->getUInt32("days");
_k1 = cfg->getDouble("k1");
_k2 = cfg->getDouble("k2");
_period = cfg->getCString("period");
_count = cfg->getUInt32("count");
_code = cfg->getCString("code");
_isstk = cfg->getBoolean("stock");
return true;
}
void WtStraDualThrust::on_schedule(ICtaStraCtx* ctx, uint32_t curDate, uint32_t curTime)
{
// 如果是股票, 添加后缀
std::string code = _code;
if (_isstk)
code += "Q";
// 获取K线信息
WTSKlineSlice *kline = ctx->stra_get_bars(code.c_str(), _period.c_str(), _count, true);
if(kline == NULL)
{
// 这里可以输出一些日志
return;
}
if (kline->size() == 0)
{
kline->release();
return;
}
// 设置交易单位
uint32_t trdUnit = 1;
if (_isstk)
trdUnit = 100;
int32_t days = (int32_t)_days;
// 获取价格相关信息
double hh = kline->maxprice(-days, -2);
double ll = kline->minprice(-days, -2);
// 提取某个价格
WTSValueArray* closes = kline->extractData(KFT_CLOSE);
double hc = closes->maxvalue(-days, -2);
double lc = closes->minvalue(-days, -2);
double curPx = closes->at(-1);
closes->release(); ///!!!这个释放一定要做
double openPx = kline->open(-1);
double highPx = kline->high(-1);
double lowPx = kline->low(-1);
// 计算上下轨
double upper_bound = openPx + _k1 * (max(hh - lc, hc - ll));
double lower_bound = openPx - _k2 * max(hh - lc, hc - ll);
// 获取合约信息
WTSCommodityInfo* commInfo = ctx->stra_get_comminfo(_code.c_str());
// 获取当前持仓
double curPos = ctx->stra_get_position(_code.c_str()) / trdUnit;
if(decimal::eq(curPos,0))
{
if(highPx >= upper_bound)
{
ctx->stra_enter_long(_code.c_str(), 2 * trdUnit, "DT_EnterLong");
//向上突破
ctx->stra_log_info("向上突破%.2f>=%.2f,多仓进场", highPx, upper_bound);
}
else if (lowPx <= lower_bound && !_isstk)
{
ctx->stra_enter_short(_code.c_str(), 2 * trdUnit, "DT_EnterShort");
//向下突破
ctx->stra_log_info("向下突破%.2f<=%.2f,空仓进场", lowPx, lower_bound);
}
}
else if (decimal::gt(curPos, 0))
{
if(lowPx <= lower_bound)
{
//多仓出场
ctx->stra_exit_long(_code.c_str(), 2 * trdUnit, "DT_ExitLong");
ctx->stra_log_info("向下突破%.2f<=%.2f,多仓出场", lowPx, lower_bound);
}
}
else if (decimal::lt(curPos, 0))
{
if (highPx >= upper_bound && !_isstk)
{
//空仓出场
ctx->stra_exit_short(_code.c_str(), 2 * trdUnit, "DT_ExitShort");
ctx->stra_log_info("向上突破%.2f>=%.2f,空仓出场", highPx, upper_bound);
}
}
// 保存用户数据
ctx->stra_save_user_data("test", "waht");
// 这个释放一定要做
kline->release();
}
// 策略初始化
void WtStraDualThrust::on_init(ICtaStraCtx* ctx)
{
std::string code = _code;
if (_isstk)
code += "Q";
WTSKlineSlice *kline = ctx->stra_get_bars(code.c_str(), _period.c_str(), _count, true);
if (kline == NULL)
{
//这里可以输出一些日志
return;
}
kline->release();
}
void WtStraDualThrust::on_tick(ICtaStraCtx* ctx, const char* stdCode, WTSTickData* newTick)
{
//没有什么要处理
}