//+------------------------------------------------------------------+ //| CorrelationMatrix.mq5 | //| 多品种相关性分析矩阵 v1.0 | //+------------------------------------------------------------------+ #property copyright "Copyright 2026" #property version "1.00" #property script_show_inputs // --- 输入参数(可自行调整)--- input int iBars_P = 30; // 使用的K线数量 input ENUM_TIMEFRAMES iTimeframe = PERIOD_H4; // 时间周期(日线/4H/1H) string Symbols[4] = {"XAUUSDm","EURUSDm","GBPUSDm","GBPJPYm"}; //+------------------------------------------------------------------+ //| 脚本主入口 | //+------------------------------------------------------------------+ void OnStart() { // --- 1. 获取原始价格数据(收盘价)--- Print("========== 开始计算多品种相关性矩阵 =========="); Print("品种列表:", Symbols[0], ", ", Symbols[1], ", ", Symbols[2], ", ", Symbols[3]); Print("K线数量:", iBars_P, " 根,周期:", EnumToString(iTimeframe)); int nSymbols = 4; // 四个品种 double close_prices[]; ArrayResize(close_prices, iBars_P); // 创建矩阵:iBars行 × nSymbols列(每列存储一个品种的收盘价) matrix priceMatrix(iBars_P, nSymbols); SymbolSelect(Symbols[0],true); SymbolSelect(Symbols[1],true); SymbolSelect(Symbols[2],true); SymbolSelect(Symbols[3],true); // 为每个品种获取历史收盘价 for(int s = 0; s < nSymbols; s++) { // 调用CopyRates将收盘价直接复制到向量(使用Mql5矩阵方法) vector close_vector; // 创建一个向量来存储收盘价 // 从历史中复制iBars根K线的收盘价 // COPY_RATES_CLOSE 是一个标志,表示只复制收盘价 // 参数:品种名称,时间周期,要复制的内容,起始索引,数量 // SymbolSelect(Symbols[s],true); bool success = close_vector.CopyRates(Symbols[s], iTimeframe, COPY_RATES_CLOSE, 0, iBars_P); if(!success) { Print("错误:无法获取 ", Symbols[s], " 的历史数据!"); return; } // 将收盘价向量赋值到矩阵的列中 for(int i = 0; i < iBars_P; i++) { priceMatrix[i][s] = close_vector[i]; } Print(Symbols[s], " 数据已获取,大小:", close_vector.Size()); } // --- 2. 计算对数收益率矩阵 --- // 对数收益率公式:r = ln(P_t / P_{t-1}) // 这将创建(iBars_P-1)行的收益率矩阵 matrix retMatrix(iBars_P-1, nSymbols); for(int s = 0; s < nSymbols; s++) { for(int i = 0; i < iBars_P-1; i++) { // 收盘价严格大于0 if(priceMatrix[i+1][s] > 0 && priceMatrix[i][s] > 0) { retMatrix[i][s] = MathLog(priceMatrix[i+1][s] / priceMatrix[i][s]); } else { retMatrix[i][s] = 0.0; // 如果数据无效,设为0 } } } Print("对数收益率矩阵已创建,大小:", retMatrix.Rows(), " 行 × ", retMatrix.Cols(), " 列"); // --- 3. 计算相关性矩阵 --- // 使用矩阵的CorrCoef方法:计算各行(观察值)之间的相关系数 // 参数:true表示按行计算(每一行是一个观察点,每一列是一个变量) // 由于我们的矩阵布局是:行=时间,列=品种,所以应该使用 rowvar=true matrix corrMatrix = retMatrix.CorrCoef(true); // 这会生成一个 4x4 的对称矩阵 // --- 4. 输出相关性矩阵结果 --- Print("\n===== 相关性矩阵(Pearson相关系数) ====="); Print("矩阵对角线都是1.0(每个品种与自身的相关性)"); Print("矩阵对称,右上角和左下角的值相同"); Print(""); // 设置打印格式,精确到小数点后4位 string header = " "; for(int s = 0; s < nSymbols; s++) header += StringFormat("%10s", Symbols[s]); Print(header); for(int i = 0; i < nSymbols; i++) { string row = StringFormat("%10s", Symbols[i]); for(int j = 0; j < nSymbols; j++) { double corr = corrMatrix[i][j]; string corrStr; if(MathAbs(corr) >= 0.7) corrStr = StringFormat("%10.2f*", corr); // 强相关用*标记 else if(MathAbs(corr) >= 0.3) corrStr = StringFormat("%10.2f", corr); else corrStr = StringFormat("%10.2f", corr); row += corrStr; } Print(row); } // --- 5. 详细解读两两相关性 --- Print("\n===== 两两相关性详细解读 ====="); for(int i = 0; i < nSymbols; i++) { for(int j = i+1; j < nSymbols; j++) { double corr = corrMatrix[i][j]; string relationship; if(corr >= 0.7) relationship = "强正相关(通常同涨同跌)"; else if(corr >= 0.3) relationship = "弱正相关(有一定同向性)"; else if(corr > -0.3) relationship = "无明显相关性(可分散风险)"; else if(corr > -0.7) relationship = "弱负相关(有一定反向性)"; else relationship = "强负相关(反向对冲)"; PrintFormat("%s 与 %s:相关性 = %.4f (%s)", Symbols[i], Symbols[j], corr, relationship); } } // --- 6. 基于相关性的实用建议 --- Print("\n===== 基于相关性的组合风险提示 ====="); // 检查EURUSD与GBPUSD的相关性(同受美元影响) double usd_pair_corr = corrMatrix[1][2]; // EURUSD vs GBPUSD PrintFormat("⚠️ EURUSD与GBPUSD相关性:%.4f", usd_pair_corr); if(usd_pair_corr > 0.7) Print(" → 同时持有这两个货币对的多头仓位,实际上是把对美元的赌注翻倍了!"); else if(usd_pair_corr > 0.5) Print(" → 这两个货币对走势高度相关,同时开单会放大风险敞口,建议只选一个。"); // 检查黄金与美元货币对的关系(黄金通常与美元负相关) double gold_eur_corr = corrMatrix[0][1]; // XAUUSD vs EURUSD PrintFormat("💰 XAUUSD与EURUSD相关性:%.4f", gold_eur_corr); if(gold_eur_corr < -0.3) Print(" → 黄金与欧元兑美元呈负相关,可作为组合中的分散化工具。"); else if(gold_eur_corr > 0.3) Print(" → 黄金与欧元走势同向,可能在美元波动时产生叠加效应。"); // 检查GBPJPY的独立性(日元避险属性) double gbpjpy_eur_corr = corrMatrix[3][1]; // GBPJPY vs EURUSD double gbpjpy_gold_corr = corrMatrix[3][0]; // GBPJPY vs XAUUSD PrintFormat("🇬🇧🇯🇵 GBPJPY与EURUSD相关性:%.4f", gbpjpy_eur_corr); PrintFormat("🇬🇧🇯🇵 GBPJPY与XAUUSD相关性:%.4f", gbpjpy_gold_corr); if(MathAbs(gbpjpy_eur_corr) < 0.3 && MathAbs(gbpjpy_gold_corr) < 0.3) Print(" → GBPJPY与其他品种相关性较低,是很好的组合分散化选择。"); Print("\n========== 相关性分析完成 =========="); } // 辅助函数:将周期枚举转换为字符串 string EnumToString(ENUM_TIMEFRAMES tf) { switch(tf) { case PERIOD_M1: return "M1"; case PERIOD_M5: return "M5"; case PERIOD_M15: return "M15"; case PERIOD_M30: return "M30"; case PERIOD_H1: return "H1"; case PERIOD_H4: return "H4"; case PERIOD_D1: return "D1"; case PERIOD_W1: return "W1"; case PERIOD_MN1: return "MN1"; default: return "Unknown"; } } //+------------------------------------------------------------------+