FAQ > 金融建模 > 应用案例 > 数据处理

Q:数组中如何按某列的值设置权重,并限制权重阈值?    

  • A:实现过程如下:
    1.计算指定列的和sumv;
    2.按指定列更新每行权重为w=v/sumv?v/sumv:阈值;
    3.计算总权重sumw;
    4.将100%-sumw的权重按列的大小重新分配给各行(为满足阈值约束需迭代实现);
    5.返回结果。
    实现范例
    获取20251203日上证50上一年的股息率数据后,根据股息率加权设置权重,同时限制个股的权重上限不超过5%
      endt:=20251203t;
      rdate:=20241231;
      yz:=5;//阈值
      field:="权重(%)";
      arr:=select thisrow as "代码",spec(DividendYield6(rdate,endt),thisrow) as "股息率(%)" from GetbkbyDate("SH000016",endt) end;
      sumgxl:=sum(arr[:,"股息率(%)"]);
      
      arr:=select *,w:=["股息率(%)"]/sumgxl*100 as nil,
             w<=yz?w:yz as field
         from arr end;
      sumw:=sum(arr[:,field]);
      
      rt:=array();
      //将多余的权重重新分配
      if CompareValue(sumw-100,0,0.001) then
      begin
        rt&=select * from arr where [field]=yz end;
        arr_:=select * from arr where [field]<yz end;
        w_:=100-sumw;
        tsdn_getdataweigh(arr_,w_,yz,field,rt);
      end
      else
        rt:=arr;
      return rt;
      return sum(rt[:,field]);//100
      
    function tsdn_getdataweigh(arr,w,yz,field,rt);
    begin
    {
      迭代分配权重
    }
      sumw:=sum(arr[:,field]);
      update arr set [field]=([field]+w*[field]/sumw)<yz?([field]+w*[field]/sumw):yz end;
      allw:=sum(arr[:,field]);
      if CompareValue(allw,sumw+w,0.001)=0 then
      begin
        rt&=select * from arr where [field]<=yz end;
        return ;
      end
      else
      begin
        rt&=select * from arr where [field]=yz end;
        w_:=sumw+w-allw;
        arr_:=select * from arr where [field]<yz end;
        tsdn_getdataweigh(arr_,w_,yz,field,rt);
      end
    end

    部分结果: