You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

MQL5循环数组越界求助:计算资产收益率时触发数组越界错误

解决MQL5数组越界错误:计算资产收益率的循环问题

首先看你遇到的array out of range错误,根源在Returns函数的循环逻辑和Series模式下的数组索引匹配问题,咱们一步步拆解:

错误原因分析

  1. 循环边界越界
    你设置的循环是for(int i=1;i<=a_size;i++),而rates数组的大小是a_size(比如传入的100)。因为你给rates开启了ArraySetAsSeries(true),数组索引范围是0a_size-1(也就是0到99)。当i=a_size时,访问rt[a_size]就会超出数组的最大索引,触发越界错误。

  2. Series模式下的索引逻辑混淆
    开启Series模式后,数组的0索引对应最新的K线数据,而你原来的计算rt[i].close/rt[i-1].close在i=1时,rt[0]是最新K线,rt[1]是前一根,逻辑是反的;更关键的是,你给rtacao也开启了Series模式,但循环从i=1开始赋值,会直接跳过rtacao[0],同时当i达到a_size-1时,rtacao[i]会超出它的数组范围(因为rtacao的大小是a_size-1,索引范围是0到a_size-2)。

  3. 局部变量的无用性
    额外提一句:rtacaoReturns函数的局部变量,函数执行完就会被销毁,你计算的收益率根本无法在OnStart中使用,这也是一个需要修正的点。

修正后的代码

第一步:修复Returns函数

我们调整循环逻辑,匹配Series模式的索引,同时把rtacao作为参数传入(方便外部获取计算结果):

void Returns(MqlRates &rt[], int a_size, double &rtacao[]) {
    ArraySetAsSeries(rtacao, true);
    // 100根K线对应99个收益率,所以数组大小设为a_size-1
    ArrayResize(rtacao, a_size - 1);
    
    // 循环从0到a_size-2,共a_size-1次迭代
    for(int i = 0; i < a_size - 1; i++) {
        // Series模式下,rt[i]是最新的第i根K线,rt[i+1]是它的前一根(更早的)
        rtacao[i] = MathLog(rt[i].close / rt[i+1].close);
    }
}

第二步:修改OnStart中的调用

OnStart里,需要提前声明rtacao数组,传入Returns函数来获取结果:

void OnStart() {
    int nacoes=144;
    string acao[];
    count_instr("ativos.txt",nacoes);
    ArrayResize(acao,nacoes);
    load_instr("ativos.txt",nacoes,acao,100);
    MqlRates rates[];
    ArraySetAsSeries(rates,true);
    ArrayResize (rates,100);
    
    // 声明收益率数组,用于接收每个资产的计算结果
    double rtacao[];
    
    for (int i=0;i<nacoes;i++) {
        SymbolSelect(acao[i],true);
        if(CopyRates(acao[i],APeriod,0,100,rates)!=100) {
            Print("CopyRates of ",acao[i]," failed, no history");
            //Erase(acao, i);
            //nacoes=nacoes-1;
        } else {
            // 传入rtacao数组获取收益率结果
            Returns(rates, 100, rtacao);
            // 这里可以添加代码使用rtacao,比如打印或存储
            Print("收益率数组大小:", ArraySize(rtacao));
        }
    }
}

关键修改点说明

  • 循环范围改为i从0到a_size-2:确保只访问rates数组的有效索引(0到99),同时给rtacao的每个索引(0到98)都赋值,不会越界。
  • 调整收益率计算的K线索引:在Series模式下,用rt[i].close / rt[i+1].close计算当前K线相对于前一根的对数收益率,逻辑更准确。
  • rtacao作为参数传入:解决局部变量无法传递结果的问题,让你在OnStart中可以使用计算好的收益率数据。

内容的提问来源于stack exchange,提问作者Maverick13

火山引擎 最新活动