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

Q:如何跟踪指数成份股进行比例类回测    

  • A:在回测中获取调仓数据时可以指定指数成分股作为选股样本,再通过选股策略选出目标股票作为调仓数据即可。

    回测说明:FAQ:2023-09-25-应用专题-回测框架01:策略回测框架TSBackTesting(更新版)
    回测示例
    回测区间:20211001-20240930
    回测周期:月线
    资金配比方式:总股本加权
    跟踪指数:SH000852
    策略:每次调仓时获取跟踪指数成份股通过P/E策略选出来的前300个股票作为调仓数据进行回测
    回测代码:
      begt:=20211001t;
      endt:=20240930t;
      obj := createobject('TSFL_BackTestingIndex');
      //********************回测基本设置***************************//
       //回测开始时间
      obj.FBegT:=BegT;
       //回测截止时间
      obj.FEndT:=EndT;
       //调仓周期(以月线为例)
      obj.FCycle:=cy_month();
       //组合类别(比例类组合)
      obj.FGroupType:=1;
       //基准代码
      obj.FIndexId:="SH000300";
       //初始资金
      obj.FIniCash:=10^6;
       //资金配比方式:总股本加权
      obj.FRateType:=0;
       //成交价类别 :收盘价
      obj.FPriceType:=2;
       //成交量取整模式:自适应取整
      obj.FVolModType:=-1;
       //是否分红再投资:分红不再投资
      obj.FDividendType:=0;
       //是否参与配股:不参与配股
      obj.FAllotmentType:=0;

      //********************自定义参数***************************//
       //指数代码 :中证1000
      obj.Index :="SH000852" ;
       //每期样本个数
      obj.FTopN := 300;

       //交易费率
      obj.FFeeRate:=0.03;
       //回测
      obj.BackTest();

       //获取返回结果(返回结果可根据需要选择)
      return array(
             //---组合基础
            '配置明细':obj.GetPortfolioPercent(BegT,EndT),
            '交易明细':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 TSFL_BackTestingIndex=class(TSBackTesting)
      Index; //获取成份股的指数
      FTopN;  //样本个数

      FFeeRate; //费率
      //重写GetTradeOrder,获取T日选股结果(TSFL_CL_PE_EndT即T日根据PE选股结果)
      function GetTradeOrder(vEndT);override;
      begin
       echo datetostr(vEndT); //打印调仓日期
       //t日选股
       t := TSFL_CL_PE_EndT_Index(Index,vEndT,FTopN);
       Update t set ['开仓费率(%)']=FFeeRate,['平仓费率(%)']=FFeeRate end;
       return t;
      end
    End;

    //t日选股-P/E策略
    Function TSFL_CL_PE_EndT_Index(Index,EndT,TopN);
    Begin
      oV:=BackUpSystemParameters();
      StockArr:=GetBKByDate(Index,EndT);
      r:=array();
      n:=0;
      for nI:=0 to length(StockArr)-1 do
      begin
       StockId:=StockArr[nI];
       SetSysParam(PN_Stock(),StockId);
         //截止日没有上市
       if not IsStockGoMarket(EndT) then continue;
         //截止日非交易日
       if not istradeday(EndT) then continue;
       r[n]['代码']:=StockId;
       r[n]['名称']:=StockName(StockId);
       r[n]['P/E']:=StockPE_VI(EndT);
       r[n]['日期']:=EndT;
       n++;
      end;
       //选中前N个股票
      if TopN>0 then
       r:=Select drange(0 to TopN-1) * from r where ['P/E']>0 order by ['P/E'] end
      else
       r:=select * from r order by ['P/E'] end;
      RestoreSystemParameters(oV);
      return r;
    End;

    回测结果: