【期权合约排序】由于dataframe多列排序算法bug,可以创建复合键数组实现多列排序
//------------------------------------------------------------------------
// 简称: NAME
// 名称: 
// 类别: 策略应用
// 类型: 用户应用
// 输出: Void
//------------------------------------------------------------------------
Params

Vars
    //此处添加变量

    Global Array<Array<String>> stock_codes;
    Numeric i;
    Numeric j;
    Numeric k;
    Numeric index;
    Numeric cx;
    DataFrame df;
    DataFrame df2;

Events
    //此处实现事件函数
    
    //初始化事件函数,策略运行期间,首先运行且只有一次,应用在订阅数据等操作
    OnInit()
    {
        //与数据源有关
        stock_codes[0] = ["000300.SSE"];
        for i = 0 to GetArraySize(stock_codes[0]) - 1
        {
            SubscribeBar(stock_codes[0][i], "1m", 20251013);
        }

        Array<string> str;
        GetOptSymbolsByCode("510300.SSE", str);
        Array<string> Callcontracts = str;
        CodeProperty props;


        
        // 存储数据的数组
        Array<Numeric> datas1;  // ExpiredDateTime
        Array<Numeric> datas3;  // opType
        Array<Numeric> datas4;  // strikePrice
        Array<Numeric> datas5;  // OpenDateTime
        Array<string> datas6;   // Symbol
        Array<string> datas7;   // SymbolName
        Array<string> datas8;   // symbolType
        
        // 用于DataFrame的map
        map<String, Array<Numeric>> datas2;
        
        for i = 0 to GetArraySize(Callcontracts) - 1
        {
            GetProperty(Callcontracts[i], props);
            datas2["props.ExpiredDateTime"][i] = props.ExpiredDateTime;
            datas1[i] = props.ExpiredDateTime;
            datas3[i] = props.opType;  
            datas4[i] = props.strikePrice;
            datas5[i] = props.OpenDateTime;
            datas6[i] = props.Symbol;
            datas7[i] = props.SymbolName;
            datas8[i] = props.symbolType;
        }
        
        // 初始化并显示原始DataFrame
        df.init(datas2);
        df.setPos("opType", [:], datas3);
        df.setPos("strikePrice", [:], datas4);
        df.setPos("OpenDateTime", [:], datas5);
        df.setPos("SymbolName", [:], datas7);
        df.setPos("symbolType", [:], datas8);
        df.setPos("Symbol", [:], datas6);
        print(df.toString());
        
        // ========== 复合键排序方法 ==========
        Print("\n=== 开始复合键排序 ===");
        
        // 创建复合键数组
        Array<Numeric> compositeKeys;
        Array<Numeric> originalIndices;
        
        for i = 0 to GetArraySize(Callcontracts) - 1
        {
            GetProperty(Callcontracts[i], props);
            
            // 转换为排序用的键值
            // 注意:我们使用负号来实现降序排序
            
            // 1. ExpiredDateTime(最主要权重,降序)
            // 格式:20251224.180000 → 202512241800000
            Numeric expKey = props.ExpiredDateTime*10000000;
            
            // 2. 分红影响(根据symbol长度,升序)12>12000
            Numeric lenKey = -1*Len(props.symbol)*1000;//
            
            // 3. opType(次要权重,降序:2认沽 > 1认购)
            // 放大到100级别,2>200
            Numeric opKey = props.opType * 100; // 10^10
            
            // 4. strikePrice(第三权重,降序)
            Numeric strikeKey = props.strikePrice ; // 
            
            // 构建复合键(用负数实现降序排序)
            compositeKeys[i] = -(expKey + lenKey + opKey + strikeKey );
            
            // 保存原始索引
            originalIndices[i] = i;
            
        }
        
        // 创建索引数组
        Array<Integer> id1;
        Array<Integer> id2;
        for i = 0 to GetArraySize(Callcontracts) - 1
        {
            id1[i] = i;
            id2[i] = i;
        }
        
        // 使用复合键进行一次排序
        // 注意:复合键是负数,所以用升序排序实际上是降序
        SortIds(compositeKeys, id1, id2, 0, GetArraySize(id1) - 1, True);
        

        
        // 根据最终索引重新排列合约
        Array<String> sortedContracts;
        for i = 0 to GetArraySize(id1) - 1
        {
            sortedContracts[i] = Callcontracts[id1[i]];
        }
        

        // ========== 重新整理数据用于df2 ==========
        // 注意:需要重新获取属性,因为sortedContracts的顺序已经改变
        for i = 0 to GetArraySize(sortedContracts) - 1
        {
            GetProperty(sortedContracts[i], props);
            datas2["props.ExpiredDateTime"][i] = props.ExpiredDateTime;
            datas1[i] = props.ExpiredDateTime;
            datas3[i] = props.opType;  
            datas4[i] = props.strikePrice;
            datas5[i] = props.OpenDateTime;
            datas6[i] = props.Symbol;
            datas7[i] = props.SymbolName;
            datas8[i] = props.symbolType;
        }
        
        // 创建并显示排序后的DataFrame
        df2.init(datas2);
        df2.setPos("opType", [:], datas3);
        df2.setPos("strikePrice", [:], datas4);
        df2.setPos("OpenDateTime", [:], datas5);
        df2.setPos("SymbolName", [:], datas7);
        df2.setPos("symbolType", [:], datas8);
        df2.setPos("Symbol", [:], datas6);
        print(df2.toString());
        


    }



最近也在研究期权,dataframe用起来更顺眼,可惜多列排序有bug,绞尽脑汁终于搞定^_^,效果如下:


dataframe多列排序,不支持连续两次排序,反复实验多次认为确实是bug!
关于dataframe的排序问题,每个dataframe第二次排序的时候会出问题。
请给一个二维数组按列排序的例子
二维数组排序的例子
排序
数组排序取分位数
页面标签排序
二维数组排序
〔建议〕,手机版的排序,增加按绝对值排序!
报价面板的排序保存问题