文章 "运用 R-平方 评估策略余额曲线的品质" - 页 2 123456789 新评论 Sergey Pavlov 2017.10.24 16:00 #11 非常感谢作者。 Yury Kirillov 2017.10.24 17:52 #12 感谢您提供的有用文章!转发了!:-) fxsaber 2017.10.24 19:14 #13 图 19:10,000 次随机游走的 LR 相关性分布图 20:10,000 次随机游走的 R^2 分布我不明白 R^2 怎么会出现第二幅图中显示的负值?是的,第一幅图也有问题。如果线性回归 绘制正确,皮尔逊 RQ (LR) 似乎不应该是负值。但在图表中却不是。我错在哪里了?找到了。我哪里都没说错,只是图表中的 R^2 和 LR 是自定义的--如果数值序列的最后一个元素小于第一个元素,就会出现实值乘以-1 的 情况。最好能在图表之前写一下。 fxsaber 2017.10.24 22:47 #14 本文通过 CLinReg::LRLine 考虑了线性回归 的误差。证明#include <Graphics\Graphic.mqh> #include <Math\Stat\Normal.mqh> #include <Math\Alglib\Alglib.mqh> // 返回直线的 Y 值 (y(x)=a*x+b) void GetLine( const double a, const double b, const int Amount, double &Result[] ) { ArrayResize(Result, Amount); for (int i = 0; i < Amount; i++) Result[i] = a * i + b; } // 通过 CLinReg::LRLine 返回线性回归结果 void GetLinearRegression( const double &Array[], double &Result[] ) { const int Total = ArraySize(Array); CMatrixDouble XY(Total, 2); for (int i = 0; i < Total; i++) { XY[i].Set(0, i); XY[i].Set(1, Array[i]); } int retcode; double a, b; CLinReg::LRLine(XY, Total, retcode, a, b); GetLine(a, b, Total, Result); } // 通过 CAlglib::LRBuild + CAlglib::LRUnpack 返回线性回归结果 void GetLinearRegression2( const double &Array[], double &Result[] ) { const int Total = ArraySize(Array); CMatrixDouble XY(Total, 2); for (int i = 0; i < Total; i++) { XY[i].Set(0, i); XY[i].Set(1, Array[i]); } int retcode; CLinearModelShell lm; CLRReportShell ar; //-- 用于存储回归结果的数组 double lr_coeff[]; //--- 线性回归系数的计算 CAlglib::LRBuild(XY, Total, 1, retcode, lm, ar); //--- 获得线性回归系数 CAlglib::LRUnpack(lm, lr_coeff, retcode); GetLine(lr_coeff[0], lr_coeff[1], Total, Result); } void ToChart( const double &Array1[], const double &Array2[], const int X = 0, const int Y = 0, const int Width = 780, const int Height = 380 ) { static const string Name = __FILE__; CGraphic Graphic; if (ObjectFind(0, Name) < 0) Graphic.Create(0, Name, 0, X, Y, Width, Height); else Graphic.Attach(0, Name); Graphic.CurveAdd(Array1, CURVE_LINES); Graphic.CurveAdd(Array2, CURVE_LINES); Graphic.CurvePlotAll(); Graphic.Update(); } void GetRandomArray( double &Array[], const int Amount = 1 e3 ) { double Random[]; MathSrand(GetTickCount()); MathRandomNormal(0, 1, Amount, Random); MathCumulativeSum(Random, Array); } #define TOSTRING(A) #A + " = " + (string)(A) + "\n" void OnStart() { double Array[]; GetRandomArray(Array); double Estimate[]; double Estimate2[]; GetLinearRegression(Array, Estimate); GetLinearRegression2(Array, Estimate2); const double R = CAlglib::PearsonCorr2(Array, Estimate); const double R2 = CAlglib::PearsonCorr2(Array, Estimate2); Print(TOSTRING(R) + TOSTRING((Array[0] > Array[ArraySize(Array) - 1]) ? -R : R) + TOSTRING(R2)); ToChart(Array, Estimate2); }结果R = -0.5864718581193301 (Array[0]>Array[ArraySize(Array)-1])?-R:R = -0.5864718581193301 R2 = 0.58647185811933符号不正确。另一种线性回归实现(CAlglib::LRBuild + CAlglib::LRUnpack)计算正确: fxsaber 2017.10.24 23:38 #15 fxsaber:文章中展示的 10,000 个独立例子的 LR 相关性和 R^2 分布图显示,R^2 != LR^2。 我不明白为什么原始 "凹 "分布的二度分布会使其成为 "平 "分布?事实证明我错就错在这里。对我来说,这种说法一点也不明显令人惊讶的是,通过 一个简单的数学运算(提升到二度) ,我们就完全消除了该分布不需要的边际效应。因此,我决定通过动画来进行实验验证(不要相信我的话)#include <Graphics\Graphic.mqh> #include <Math\Stat\Normal.mqh> #include <Math\Alglib\Alglib.mqh> // 返回直线的 Y 值 (y(x)=a*x+b) void GetLine( const double a, const double b, const int Amount, double &Result[] ) { ArrayResize(Result, Amount); for (int i = 0; i < Amount; i++) Result[i] = a * i + b; } // 通过 CAlglib::LRBuild + CAlglib::LRUnpack 返回线性回归结果 void GetLinearRegression( const double &Array[], double &Result[] ) { const int Total = ArraySize(Array); CMatrixDouble XY(Total, 2); for (int i = 0; i < Total; i++) { XY[i].Set(0, i); XY[i].Set(1, Array[i]); } int retcode; CLinearModelShell lm; CLRReportShell ar; //-- 用于存储回归结果的数组 double lr_coeff[]; //--- 线性回归系数的计算 CAlglib::LRBuild(XY, Total, 1, retcode, lm, ar); //--- 获得线性回归系数 CAlglib::LRUnpack(lm, lr_coeff, retcode); GetLine(lr_coeff[0], lr_coeff[1], Total, Result); } // 计算 R double GetCustomR( const double &Array[] ) { double Estimate[]; GetLinearRegression(Array, Estimate); const double R = CAlglib::PearsonCorr2(Array, Estimate); return((Array[0] > Array[ArraySize(Array) - 1]) ? -R : R); } // 计算 R 随机向量 void GetRandomCustomR( const int Amount, const int VectorSize, double &Result[] ) { double Random[]; double Sum[]; MathSrand(GetTickCount()); ArrayResize(Result, Amount); for (int i = 0; i < Amount; i++) { MathRandomNormal(0, 1, VectorSize, Random); MathCumulativeSum(Random, Sum); Result[i] = GetCustomR(Sum); } } void ToChart( const double &X[], const double &Y[], const string Str = NULL, const int X0 = 0, const int Y0 = 0, const int Width = 780, const int Height = 380 ) { static const string Name = __FILE__; CGraphic Graphic; if (ObjectFind(0, Name)<0) Graphic.Create(0, Name, 0, X0, Y0, Width, Height); else Graphic.Attach(0, Name); Graphic.BackgroundMain(Str); Graphic.BackgroundMainSize(16); Graphic.CurveAdd(X, Y, CURVE_HISTOGRAM).HistogramWidth(6); Graphic.CurvePlotAll(); Graphic.Update(); } void MathPow( double &Result[], const double &Array[], const double Pow ) { const int Size = ArrayResize(Result, ArraySize(Array)); for (int i = 0; i < Size; i++) Result[i] = (Array[i] < 0) ? -MathPow(-Array[i], Pow) : MathPow(Array[i], Pow); } //https://www.mql5.com/zh/docs/standardlibrary/mathematics/stat/normal //+------------------------------------------------------------------+ //| 计算数据集的频率| //+------------------------------------------------------------------+ bool CalculateHistogramArray(const double &data[],double &intervals[],double &frequency[], double &maxv,double &minv,const int cells=10) { if(cells<=1) return (false); int size=ArraySize(data); if(size<cells*10) return (false); minv=data[ArrayMinimum(data)]; maxv=data[ArrayMaximum(data)]; double range=maxv-minv; double width=range/cells; if(width==0) return false; ArrayResize(intervals,cells); ArrayResize(frequency,cells); //--- 设置区间的中心点 for(int i=0; i<cells; i++) { intervals[i]=minv+(i+0.5)*width; frequency[i]=0; } //--- 填入间隔频率 for(int i=0; i<size; i++) { int ind=int((data[i]-minv)/width); if(ind>=cells) ind=cells-1; frequency[ind]++; } return (true); } void DistributionToChart( const double &Array[], const string Str = NULL, const int NCells = 51 ) { double X[]; // 直方图区间中心 double Y[]; // 样本中属于区间的数值个数 double Max, Min; // 样本中的最大值和最小值 CalculateHistogramArray(Array, X, Y, Max, Min, NCells); ToChart(X, Y, Str); } void OnInit() { double R[]; GetRandomCustomR(1 e3, 1 e4, R); double Array[]; const int Max = 50; while (!IsStopped()) for (int i = 1; !IsStopped() && i < (Max << 1); i++) { const double Pow = (i > Max) ? ((Max << 1) - i) * 0.1 : i * 0.1; MathPow(Array, R, Pow); DistributionToChart(Array, "Distribution of R^" + DoubleToString(Pow, 1)); Sleep(100); } }似乎是这样的 fxsaber 2017.10.25 00:04 #16 图 21:作为自定义优化标准的 R^2 值图片中 的 LR Correlation在 MQL 中处于什么位置?或者这个参数和许多其他参数只计算单次运行,所以ENUM_STATISTICS 中没有?如果是这样,建议根据本文中提到的合理考虑来计算该参数:通过不含 MM 和平方的权益计算。ZY 我测量了计算一个百万数值数组(如权益)的 GetCustomR 所需的时间 - 2.5 秒。这是一个很长的时间。所有时间都花在 LR 计算上(CAlglib::LRBuild + CAlglib::LRUnpack)。但有时通过CLinReg::LRLine 计算的 LR 曲线会快上一个数量级。如果将其掺杂在一起,在优化中就可以将其作为优化标准。 Документация по MQL5: Стандартные константы, перечисления и структуры / Состояние окружения / Статистика тестирования www.mql5.com Максимальная просадка баланса в процентах. В процессе торговли баланс может испытать множество просадок, для каждой фиксируется относительное значение просадки в процентах. Возвращается наибольшее значение Максимальная... Discussion of article "R-squared 利用余额图进行策略优化并将结果与 "余额 + 最大锋锐比率" 运用 R-平方 评估策略余额曲线的品质 Vasiliy Sokolov 2017.10.25 09:39 #17 Dennis Kirichenko:我一直以为是100我一直以为是100。谢谢,这篇文章很有意思。是的,这是我在著名的 R 和统计书籍中看到的数字。但抱歉找不到链接,所以很抱歉。丹尼斯-基里琴科: 对回归系数进行显著性检验也很常见。甚至 Alglib 也有 :-)显然,这些检验是针对正态分布的。我们得到的是均匀分布。PearsonCorrelationSignificance(), SpearmanRankCorrelationSignificance().谢谢你的链接,我会记住的。 Vasiliy Sokolov 2017.10.25 09:48 #18 fxsaber:ZY 错误声明R^2 不过是图形与其线性模型之间的相关性而已//-- 求 R^2 及其符号 double r2 = MathPow(corr, 2.0);的确,这是一个严重的用词错误。我竟然写出了这样的东西。我会改正的。当你看到所有其他的 MQL 代码时,你不会明白为什么要给出它们,因为如果没有 CStrategy 知识,它们是完全无法阅读的CStrategy 仅用于收集必要条件。正如有人正确指出的那样,主要代码是 R2 的实际计算。适合 R^2 的 "权益 "计算代码。它是以 MT4 风格编写的,将其翻译为 MT5 并不困难....。让我们来学习一下。 Vasiliy Sokolov 2017.10.25 09:50 #19 Maxim Dmitrievsky: 我同意这一点,所有其他内容都必须从类中删除才能添加到系统中......最好将所有内容都放在单独的 f-iases 或单独的 includnik 中。将您的权益计算(或 fxsaber 提供的代码)作为双数组,并将其插入 R^2 计算函数。您不需要删除任何内容,也不需要使用类和CStrategy。 Vasiliy Sokolov 2017.10.25 09:57 #20 fxsaber:我不明白 R^2 怎么会像第二幅图中显示的那样取负值?第一幅图也有问题。如果线性回归 构造正确,皮尔逊 LR 似乎不应该是负值。但在图中却不是。我错在哪里了?找到了。我哪里都没说错,只是图中的 R^2 和 LR 是自定义的--如果数值序列的最后一个元素小于第一个元素,就会出现实值乘以-1 的 情况。最好在图表之前写明这一点。这一点隐藏在文章中:我们的脚本同时计算 LR 相关性和 R^2。我们稍后会看到它们之间的区别。脚本中还有一个小补充。我们会将计算出的相关系数乘以合成图的最终符号。如果结果小于零,则相关系数为负,如果大于零,则为正。这样做是为了快速、轻松地将负结果与正结果区分开来,而无需借助其他统计方法。这就是 MetaTrader 5 中 LR Correlation 的工作原理,R^2 也将根据同样的原理建立。 也许我应该在其他地方多次写到这一点。 123456789 新评论 您错过了交易机会: 免费交易应用程序 8,000+信号可供复制 探索金融市场的经济新闻 注册 登录 拉丁字符(不带空格) 密码将被发送至该邮箱 发生错误 使用 Google 登录 您同意网站政策和使用条款 如果您没有帐号,请注册 可以使用cookies登录MQL5.com网站。 请在您的浏览器中启用必要的设置,否则您将无法登录。 忘记您的登录名/密码? 使用 Google 登录
图 19:10,000 次随机游走的 LR 相关性分布
图 20:10,000 次随机游走的 R^2 分布
我不明白 R^2 怎么会出现第二幅图中显示的负值?是的,第一幅图也有问题。如果线性回归 绘制正确,皮尔逊 RQ (LR) 似乎不应该是负值。但在图表中却不是。我错在哪里了?
找到了。我哪里都没说错,只是图表中的 R^2 和 LR 是自定义的--如果数值序列的最后一个元素小于第一个元素,就会出现实值乘以-1 的 情况。最好能在图表之前写一下。
本文通过 CLinReg::LRLine 考虑了线性回归 的误差。
证明
结果
符号不正确。另一种线性回归实现(CAlglib::LRBuild + CAlglib::LRUnpack)计算正确:
文章中展示的 10,000 个独立例子的 LR 相关性和 R^2 分布图显示,R^2 != LR^2。
我不明白为什么原始 "凹 "分布的二度分布会使其成为 "平 "分布?事实证明我错就错在这里。对我来说,这种说法一点也不明显
令人惊讶的是,通过 一个简单的数学运算(提升到二度) ,我们就完全消除了该分布不需要的边际效应。
因此,我决定通过动画来进行实验验证(不要相信我的话)
似乎是这样的
图 21:作为自定义优化标准的 R^2 值
图片中 的 LR Correlation在 MQL 中处于什么位置?或者这个参数和许多其他参数只计算单次运行,所以ENUM_STATISTICS 中没有?
如果是这样,建议根据本文中提到的合理考虑来计算该参数:通过不含 MM 和平方的权益计算。
ZY 我测量了计算一个百万数值数组(如权益)的 GetCustomR 所需的时间 - 2.5 秒。这是一个很长的时间。所有时间都花在 LR 计算上(CAlglib::LRBuild + CAlglib::LRUnpack)。但有时通过CLinReg::LRLine 计算的 LR 曲线会快上一个数量级。如果将其掺杂在一起,在优化中就可以将其作为优化标准。
我一直以为是100我一直以为是100。谢谢,这篇文章很有意思。
是的,这是我在著名的 R 和统计书籍中看到的数字。但抱歉找不到链接,所以很抱歉。
对回归系数进行显著性检验也很常见。甚至 Alglib 也有 :-)
显然,这些检验是针对正态分布的。我们得到的是均匀分布。
PearsonCorrelationSignificance(), SpearmanRankCorrelationSignificance().
谢谢你的链接,我会记住的。
ZY 错误声明
R^2 不过是图形与其线性模型之间的相关性而已
的确,这是一个严重的用词错误。我竟然写出了这样的东西。我会改正的。
当你看到所有其他的 MQL 代码时,你不会明白为什么要给出它们,因为如果没有 CStrategy 知识,它们是完全无法阅读的
CStrategy 仅用于收集必要条件。正如有人正确指出的那样,主要代码是 R2 的实际计算。
适合 R^2 的 "权益 "计算代码。它是以 MT4 风格编写的,将其翻译为 MT5 并不困难....。
让我们来学习一下。
我同意这一点,所有其他内容都必须从类中删除才能添加到系统中......最好将所有内容都放在单独的 f-iases 或单独的 includnik 中。
将您的权益计算(或 fxsaber 提供的代码)作为双数组,并将其插入 R^2 计算函数。您不需要删除任何内容,也不需要使用类和CStrategy。
我不明白 R^2 怎么会像第二幅图中显示的那样取负值?第一幅图也有问题。如果线性回归 构造正确,皮尔逊 LR 似乎不应该是负值。但在图中却不是。我错在哪里了?
找到了。我哪里都没说错,只是图中的 R^2 和 LR 是自定义的--如果数值序列的最后一个元素小于第一个元素,就会出现实值乘以-1 的 情况。最好在图表之前写明这一点。
这一点隐藏在文章中:
我们的脚本同时计算 LR 相关性和 R^2。我们稍后会看到它们之间的区别。脚本中还有一个小补充。我们会将计算出的相关系数乘以合成图的最终符号。如果结果小于零,则相关系数为负,如果大于零,则为正。这样做是为了快速、轻松地将负结果与正结果区分开来,而无需借助其他统计方法。这就是 MetaTrader 5 中 LR Correlation 的工作原理,R^2 也将根据同样的原理建立。