StgyStudio2

一、软件使用

1.建立账号

在"账号列表"窗口点右键,出现菜单,点击"新增",输入账号、密码、期货席位,勾选“自动登录”

2.建策略

在运行窗口,点右键,出现菜单,,点击"新增"


参数说明:

stgyname: 策略名称(唯一,确定后不可修改)

model:   策略模型名称(自开发策略定义的模型名,得开发策略之后才有)

inst_id:交易合约

inst_id2:交易合约 (用于套利方式,另外一个交易合约)

Tds:绑定策略的交易账号名,多账号用逗号隔开(如: 01011,10122)

mode:一般选real(实盘模型)

period:主K线周期(其它辅助周期有的话定义在策略里面)

vol:合约交易手数

vol2:合约2交易手数

status:默认

右边是策略默认参数,等点击保存后才会生成出现

修改好点"save"保存


这样策略执行配置后,就可以自动交易了


二、策略开发

1.打开项目,复制一份策略范例CStgyTest,改名成需要的策略名CStgyXXXXX


2.对策略进行参数和开平逻辑的修改

using DBOper;
using ICtp;
using System;
using System.Collections.Generic;
using System.Linq;
using Util;
using Newtonsoft.Json.Linq;
using DB;
namespace StgyStudio
{
    public class CStgyTest : CStgyBase
    {
        public CStgyTest(T_Strategy setting)
            :base(setting)
        {
            _bSaveSign = true;
            _bUsePo2 = false;
            if (setting.period == "tick")
            {
                setting.period = "1m";
            }
            UpdateSetting(setting);
            _bSaveSign = true;//保存数据
        }
        /*---------------------------------------------------------------- 指标与参数 ----------------------------------------------------------------*/
        //参数数据      
        public int _L0 = 5;//均线周期
        public int _L1 = 40;//均线周期
        public int _SlopO = 0;//实盘开仓滑点
        public int _SlopC = 0;//实盘平仓滑点
        //指标数据
        List<float> _MA0 = new List<float>();
        List<float> _MA1 = new List<float>();
        /*----------------------------------------------------数据--------------------------------------------------------*/
        //参数解析函数
        public override int UpdateParamList(ref string param_list)
        {
            if (string.IsNullOrEmpty(param_list))
            {
                return 0;
            }
            var dictParam = JObject.Parse(param_list);
            if (dictParam == null)
            {
                return -1;
            }
            int ret = 0;
            ret = ParseBasicParam(dictParam);
            if (ret < 0)
            {
                return ret;
            }
            string name = string.Empty, val = string.Empty;
            foreach (var item in dictParam)
            {
                name = item.Key;    
                if (name == "_L0")
                {
                    _L0 = DataUtil.toInt(item.Value, 0);
                }
                else if (name == "_L1")
                {
                    _L1 = DataUtil.toInt(item.Value, 0);
                }
            }
            dictParam["_L0"] = _L0.ToString();
            dictParam["_L1"] = _L1.ToString();
            param_list = dictParam.ToString().Replace("\r\n", string.Empty).Replace("\"", string.Empty).Replace(" ", string.Empty);
            return ret;
        }
        /*----------------------------------------------------实盘--------------------------------------------------------*/
        //数据初始化
        public override void InitData(int barfrom, int signfrom)
        {
            //清除基类数据
            ClearData();
            //清除当前类数据
            _MA0.Clear();
            _MA1.Clear();


            //加载历史数据:K线和信号
            LoadData(barfrom, signfrom, LoadTypeEnum.All, LoadTypeEnum.All);
            //计算历史持仓
            IDeal.ChkPoInfo_LastDC(_Signs, _Po, true);
            //显示持仓
            MsgManager.Instance.SendPoInfo(_stgyid, _Po, null);
        }
        //实盘运行初始
        public override int InitRealRun(bool bLoadData = false, int barfrom = 0, int signfrom = 0)
        {
            InitData((int)LoadTypeEnum.All, (int)LoadTypeEnum.All);
            IDeal.ChkPoInfo_LastDC(_Signs, _Po, true);
            MsgManager.Instance.SendPoInfo(_stgyid, _Po, null);
            ServiceManager.Instance.SetStgyStatus(_stgyid, StrategyStatus.running);
            return 1;
        }
        //计算K线和指标的函数,被主框架调用 
        public override void UpdateBar(MdTick mdTick)
        {
            if (_setting.status != (int)StrategyStatus.running || _setting.chk <= 0)
            {
                return;
            }
            var _TickTime = Ctp.TTime(mdTick.hm);
            if ((_TickTime == TTIME_ENUM.行情中 || _TickTime == TTIME_ENUM.竞价中) == false)
            {
                return;
            }
            double tickL = mdTick.C, tickH = mdTick.C;
            _DBar = UpdateDBar(_DBar, mdTick, 0, ref tickH, ref tickL);//更新日K数据 
            UpdateBar(mdTick.T, mdTick.C, tickH, tickL, mdTick.C, mdTick.SettPrice, mdTick.dV, _Bars, _instid, _period);
            CalcBarIdxs(_Bars, _Bars.Count - 1, BAR_POS.中);
        }
        public override void CalcBarIdxs(List<KBar> bars, int pos, BAR_POS barStatus)
        {
            if (pos < 0 || pos >= bars.Count)
            {
                return;
            }
            CMa.UpdateMA(_MA0, _L0, bars, pos);
            CMa.UpdateMA(_MA1, _L1, bars, pos);
        }
        public int GetSignBarNum(SignEnum signEnum)
        {
            if(_Signs.Count == 0)
            {
                return -1;
            }
            T_Sign sign = null;
            if(signEnum == SignEnum.Buy)
            {
                sign = _Signs.LastOrDefault(x => x.dc == (int)DCEnum.buy && x.kp == (int)KPEnum.open);
            }
            else if(signEnum == SignEnum.SellShort)
            {
                sign = _Signs.LastOrDefault(x => x.dc == (int)DCEnum.sell && x.kp == (int)KPEnum.open);
            }
            else if (signEnum == SignEnum.Sell)
            {
                sign = _Signs.LastOrDefault(x => x.dc == (int)DCEnum.sell && x.kp == (int)KPEnum.close);
            }
            else if (signEnum == SignEnum.BuyToCover)
            {
                sign = _Signs.LastOrDefault(x => x.dc == (int)DCEnum.buy && x.kp == (int)KPEnum.close);
            }
            else
            {
                return -1;
            }
            if (sign.pos > 0)
            {
                return _Bars.Count - 1 - sign.pos;
            }
            KBar bar;
            long T = sign.deal_time.Ticks;
            for (int i = _Bars.Count - 1; i >= 0; i--)
            {
                bar = _Bars[i];
                if (T >= bar.T0 && T <= bar.T2)
                {
                    return _Bars.Count - 1 - i;
                }
            }
            return -1;
        }
        //策略运行的函数,被主框架调用 
        public override void OnTick(MdTick mdTick)
        {
            if (_setting.status != (int)StrategyStatus.running || _setting.chk <= 0)
            {
                return;
            }
            var _TickTime = Ctp.TTime(mdTick.hm);
            if ((_TickTime == TTIME_ENUM.行情中 || _TickTime == TTIME_ENUM.竞价中) == false)
            {
                return;
            }
            _bInProcessing = true;
            OnBarTick(_Bars, _Bars.Count-1,BAR_POS.收);
            _bInProcessing = false;
        }
        public override int OnBarTick(List<KBar> bars, int pos, BAR_POS tickInBar)
        {
            if (_MA0.Count != _MA1.Count || _MA0.Count < 3 || pos >= bars.Count || pos < 0)
            {
                return -1;
            }
            int PO = _Po.po;
            int DC = _setting.dc;//只做某方向的开仓
            CSignData signData = null;
            var ma0_1 = _MA0[pos - 1];
            var ma1_1 = _MA1[pos - 1];
            var bar0 = bars[pos - 1];
            _cParam.SetParm("MA",string.Format("[{0:f1},{1:f1}]", ma0_1, ma1_1));//过程参数显示
            if ( PO == 0)
            {
                if(ma0_1 > ma1_1 && DC>=0 && GetSignBarNum(SignEnum.Buy)!=0)
                {
                    signData = new CSignData(SignEnum.Buy, bar0.C, _Vol, "上", bar0.T, pos);
                }
                else if (ma0_1 < ma1_1 && DC <= 0 && GetSignBarNum(SignEnum.SellShort) != 0)
                {
                    signData = new CSignData(SignEnum.SellShort, bar0.C, _Vol, "下", bar0.T, pos);
                }
            }
            else if ( PO > 0 && GetSignBarNum(SignEnum.Buy) > 0)//GetSignBarNum:不在当跟K线平仓
            {
                if(bar0.C > 0 && Math.Round(bar0.C - _Po.avg, _PTickDotNum ) < -10*_PTick  )
                {
                    signData = new CSignData(SignEnum.Sell, bar0.C, _Vol, "止损", bar0.T, pos);
                }
            }
            else if( PO < 0 && GetSignBarNum(SignEnum.SellShort) > 0)
            {
                if (bar0.C > 0 && Math.Round(bar0.C - _Po.avg, _PTickDotNum) > 10 * _PTick)
                {
                    signData = new CSignData(SignEnum.BuyToCover, bar0.C, _Vol, "止损", bar0.T, pos);
                }
            }


            MsgManager.Instance.SendStgyInData(_stgyid, _cParam.ToView());
            if (signData == null)
            {
                return 0;
            }
            if (PO > 0 && signData.SIGN == SignEnum.Buy)
            {
                return 0;
            }
            else if (PO < 0 && signData.SIGN == SignEnum.SellShort)
            {
                return 0;
            }
            else if (PO >= 0 && signData.SIGN == SignEnum.BuyToCover)
            {
                return 0;
            }
            else if (PO <= 0 && signData.SIGN == SignEnum.Sell)
            {
                return 0;
            }
            var ret = DoSign1(signData, false, true, true, _SlopO, _SlopC);
            IDeal.ChkPoInfo_LastDC(_Signs, _Po, true);  
            MsgManager.Instance.SendPoInfo(_stgyid, _Po, null);
            return 1;
        }
    }
}





浏览:191
编辑: admin

关于我们 联系我们 免责条款 粤ICP备19050133号 版权所有@策略网