FAQ > 金融建模 > 应用案例 > 回测应用

Q:指数数量类回测的简单实现    

  • 策略:
     中证500指数做多
     当ema20上穿ema60的时候开仓,仓位80%,当已经持有时不再开仓;
     ema20下穿ema60的时候全部平仓;
     初始本金100万人民币,杠杆两倍。
     日线调仓,看最终收益

    分析:
    由调仓策略可看出买入与卖出动作明确,我可以直接用数量类提供交易明细的方式实现该策略的回测。

    具体实现:
    注:下面案例中,更多成员变量的值及说明请查阅:FAQ:2023-09-25-应用专题-回测框架01:策略回测框架TSBackTesting(更新版)

    Function TestBackTestingIndex();
    Begin
      Begt:=20180301T; //策略开始时间
      Endt:=20201012T; //策略截止时间
      obj:=createobject('TestBackTestingSL_Class');//-框架相关变量
       //回测开始时间
      obj.FBegT:=BegT;
       //回测截止时间
      obj.FEndT:=EndT;
       //调仓周期
      obj.FCycle:=cy_day();
       //组合类别(数量类组合)
      obj.FGroupType:=2;
       //基准代码->用于与市场对比,计算超额收益等相关指标
      obj.FIndexId:='SH000300';
       //初始资金
      obj.FIniCash:=10^6;
       //成交价类别(此处为用户自定义价格)
      obj.FPriceType:=2;
       //成交量取整模式
      obj.FVolModType:=-1;
       //是否分红再投资
      obj.FDividendType:=0;
       //是否参与配股
      obj.FAllotmentType:=0;
       //费用类别
      obj.FFeeType:=1;
       //开仓数量类别-剩余资金占比法-在交易明细中提供'剩余资金占比(%)'
      obj.FOpenVolType:=3;
       //平仓数量类别-可平仓数量占比法-在交易明细中提供"平仓数量占比(%)"
      obj.FCloseVolType:=2;
    //--用户变量
      obj.FStockID:='SH000905'; //中证500指数
       //回测
      obj.BackTest();

       //获取返回结果(返回结果可根据需要选择)
      return array(
             //---组合基础
            "交易明细":obj.GetTradeData(BegT,EndT),
            "资产配置":obj.GetAssetData(BegT,EndT),
            "持仓明细":obj.GetHoldData(BegT,EndT),

             //---组合盈亏、交易
            "组合盈亏":obj.GetGainandLoss(BegT,EndT),
            "交易汇总":obj.GetTradingAmount(BegT,EndT),
            "组合盈亏(按证券)":obj.GetGainandLossBySecurity(BegT,EndT),
            "交易汇总(按证券)":obj.GetTradingAmountBySecurity(BegT,EndT),

             //---组合收益
            "区间组合收益率": obj.GetPortfolioReturn(BegT,EndT),
            "组合和基准收益率序列":obj.GetPortfolioReturn2(BegT,EndT),
            "阶段收益":obj.GetTrailingReturn(EndT),
            "滚动收益":obj.GetRollingReturn(BegT,EndT,cy_month()),

            //----组合评价
            "风险回报":obj.GetReturnandRisk(BegT,EndT),
            "相对回报":obj.GetRelativePerformance(BegT,EndT),
            );

    Type TestBackTestingSL_Class=class(TSBackTesting)

      FStockID;//新增用户成员变量
      Function GetTradeOrder(vEndT);override; //必须重写:得到本期调仓日的交易明细
      begin
        oV:=BackUpSystemParameters2();

        SetSysParam(PN_Cycle(),cy_day());
        setsysparam(pn_date(),vEndt);
        setsysparam(pn_stock(),FStockID);
        tP:=GetHoldData(); //获取当前持仓
        jymx:=array();
        if istable(tP) then //有持仓->考虑平仓
        begin
         //ema20下穿ema60的时候平仓
         if cross(ema(close(),20),ema(close(),60))=-1 then
         begin
           jymx:=select vEndt as '截止日',
                ['代码'],
                1 as '方向', //看涨
                1 as '动作', //平仓
                100 as "平仓数量占比(%)",
                50 as '保证金比例(%)', //2倍杠杆
                0.1 as '费率(%)'
                from tP end;
         end
        end
        else begin //-无持仓,考虑开仓,开仓判断: ema20上穿ema60的时候开仓
         if cross(ema(close(),20),ema(close(),60))=1 then
         begin
           jymx:=array(('截止日':vEndt,
             '代码':FStockID,
             '方向':1, //看涨
             '动作':0, //平仓
             "剩余资金占比(%)":80,//防止暴仓
             '保证金比例(%)':50, //2倍杠杆
             '费率(%)':0.1));
         end
        end
        return jymx;
      end;
    end;

    返回结果: