文章 "运用 R-平方 评估策略余额曲线的品质"

 
新文章 运用 R-平方 评估策略余额曲线的品质已发布:
本文介绍如何构建自定义优化标准 R-平方。这一准则可用来评估一个策略的余额曲线的品质, 并选择增长最平滑和稳定的策略。这项工作讨论其构建原理, 以及用于评估属性和衡量品质的统计方法。

现在我们可以建立一个盈利因子值对交易数量的依赖图表。例如, 在 Excel 中, 可以通过选择相应的列, 并在 "图表" 选项卡中按下绘制散点图的按钮来完成此操作。


图例 8. 盈利因子对交易数量的依赖

 

Именно поэтому количество сделок должно быть достаточно большим. Но что подразумевать под достаточностью? Принято считать, что любая выборка должна содержать как минимум 37 измерений. Это магическое число в статистике, именно оно является нижней границей репрезентативности параметра. Конечно, для оценки торговой системы этого количества сделок недостаточно. Для надежного результата желательно совершить не менее 100 — 150 сделок. Более того, для многих профессиональных трейдеров и этого недостаточно. Они проектируют системы, совершающие не менее 500-1000 сделок, и уже потом, на основании этих результатов, рассматривают возможность запуска системы на реальных торгах...

我一直以为是100我一直以为是100。谢谢,文章很有意思。

因此,可以说 R 平方决定系数是对现有 MetaTrader 5 测试指标的重要补充。它允许您评估策略平衡线曲线的平滑度,这本身就是一个非同小可的指标。R-square 易于使用:其取值范围是固定的,从-1.0 到+1.0,表示 策略平衡的负趋势(取值接近-1.0)、无趋势(取值接近 0.0)和正趋势(取值趋向+1.0)。由于所有这些特性、可靠性和简易性,R-square 可以被推荐用于建立一个有利可图的交易系统。

哇我一直以为Ryx- 确定系数 - 是用来 评估线性回归 的质量的。常数模型确定 系数取值范围为01

对回归系数进行显著性检验也很常见。甚至 Alglib 也有这种测试 :-)

PearsonCorrelationSignificance()、SpearmanRankCorrelationSignificance()。

 
我们将使用现成的智能交易系统 CImpulse 2.0 ,其工作原理在"Universal Trading Expert Advisor: Working with Pending Orders"一文中有所描述。之所以选择它,是因为它简单易用,而且与标准 MetaTrader 5 交付的智能交易系统不同,它可以进行优化,这对我们文章的目的极为重要。

什么意思?

MetaTrader 终端报告中有一个特殊的统计指标。它被称为LR Correlation (线性回归相关性 ),显示平衡线与为该线找到的线性回归之间的相关性。

确定系数 R^2 的计算方法与 LR 相关性的计算方法类似。但最终的数字是额外的平方。

在这里,我们最感兴趣的一个数字是 R 平方或 R 方。这个指标的值为 0.5903。因此,线性回归解释了所有数值的 59.03%,剩下的 41%仍然无法解释。

根据上述引文,可以得出R^2 = LR^2。因此,找到一个名为 "线性回归 "的线性函数的标准是方差的 MNC,或者说是最大化皮尔逊 RQ 的绝对值,也就是MathAbs(LR)。 最大化MathAbs(LR) 与最大化R^2 相同,因为MathAbs(LR) = MathSqrt(R^2)。


总之,我们可以通过最大化准则MathAbs(R)^n( 其中n 为任意正数)找到线性回归。

那么,既然在n = 1 时可以得到 76.8%,在n = 4 时可以得到 34.8%,那么谈论 59.03%的所有数值都是由线性回归解释的又有什么意义呢?


错误的说法

R^2 只是图形与其线性模型之间的相关性

   //-- 求 R^2 及其符号
   double r2 = MathPow(corr, 2.0);
 
Способ расчета коэффициента детерминации R^2 аналогичен способу расчета LR Correlation. Но итоговое число дополнительно возводится в квадрат.

文章中介绍的 10,000 个独立例子的 LR 相关性和 R^2 分布图显示,R^2 != LR^2

令人惊奇的是,通过一个简单的数学运算(二度),我们完全消除了分布的边际效应。

我不明白,为什么原来 "凹 "分布的二度分布会让它变得 "平"?
 
现在,让我们通过 R 平方参数找出最佳运行结果。为此,请将优化运行保存到 XML 文件中。如果电脑上安装了 Microsoft Excel,文件会自动打开。我们将使用排序和筛选器,因此请选中表头并点击同名按钮(主页 -> 排序和筛选器 -> 筛选器),然后就可以灵活显示各列了。Отсортируем прогоны по пользовательскому критерию оптимизации

既然 Tester 本身已经对所有内容进行了排序,为什么还要使用 Excel 呢?

 
НедостаткиРешение
Применим исключительно для оценки линейных процессов, или систем, торгующих фиксированным лотом.Не применять для торговых систем, использующих систему капитализации (мани-менеджемент).

计算 R^2 时的权益不应计入AccountEquity(== AccountBalance + Sum(Profit[i])),而应计入Sum(Profit[i]/Lots[i])(对于单字符 TS)。

 
在文章中的所有 MQL 源中,只有一个是有用的
//+------------------------------------------------------------------+
//} 返回根据策略净值计算得出的 R^2 分数。
//} 权益值以权益数组形式传递。
//+------------------------------------------------------------------+
double CustomR2Equity(double& equity[], ENUM_CORR_TYPE corr_type = CORR_PEARSON)
{
   int total = ArraySize(equity);
   if(total == 0)
      return 0.0;
   //-- 填充矩阵 Y--股票价值,X--价值的序号
   CMatrixDouble xy(total, 2);
   for(int i = 0; i < total; i++)
   {
      xy[i].Set(0, i);
      xy[i].Set(1, equity[i]);
   }
   //-- 找出线性模型 y = a*x + b 的系数 a 和 b;
   int retcode = 0;
   double a, b;
   CLinReg::LRLine(xy, total, retcode, a, b);
   //-- 为每个 X 生成线性回归值;
   double estimate[];
   ArrayResize(estimate, total);
   for(int x = 0; x < total; x++)
      estimate[x] = x*a+b;
   //-- 找出数值与其线性回归的相关系数
   double corr = 0.0;
   if(corr_type == CORR_PEARSON)
      corr = CAlglib::PearsonCorr2(equity, estimate);
   else
      corr = CAlglib::SpearmanCorr2(equity, estimate);
   //-- 求 R^2 及其符号
   double r2 = MathPow(corr, 2.0);
   int sign = 1;
   if(equity[0] > equity[total-1])
      sign = -1;
   r2 *= sign;
   //-- 返回 R^2 的归一化估计值,精度为百分之一
   return NormalizeDouble(r2,2);
}

它是通用的--适用于任何双数组(不仅是 Equity)。

当你查看所有其他 MQL 代码时,你不会明白为什么要给出它们,因为如果不了解CStrategy,根本无法读懂它们。


感谢作者的文章,它让我有所思考。


ZY 源代码中用黄色标出的行是有争议的。

 

非常有趣,谢谢。我从没想过测试人员的指标会因为资本化而被扭曲,因此优化的效率会比固定数量时低。当然,R^2 也非常有用,我想知道与利润因子+ 最大余额相比,它是否会加快优化过程。

 
fxsaber:
在文章中的所有 MQL 源中,只有一个是有用的

我同意这一点,其余的都必须从类中提取出来才能添加到系统中......最好将所有内容都放在单独的 fs 或单独的 includnik 中。

 
fxsaber:

计算 R^2 的权益不应按AccountEquity ( == AccountBalance + Sum(Profit[i])) 计算,而应按Sum(Profit[i] / Lots[i]) 计算(对于单字符 TS)。

适合 R^2 的 "净值 "计算代码。以 MT4 风格编写,翻译成 MT5 并不困难...

// 不含 MM 的权益计算(单字符 TS 的变体)
class EQUITY
{
protected:
  int PrevHistoryTotal;
  double Balance;
  double PrevEquity;
  
  // 在任意数组的末尾添加一个元素
  template <typename T>
  static void AddArrayElement( T &Array[], const T Value, const int Reserve = 0 )
  {
    const int Size = ::ArraySize(Array);
  
    ::ArrayResize(Array, Size + 1, Reserve);
  
    Array[Size] = Value;
  }

  static double GetOrderProfit( void )
  {
    return((OrderProfit()/* + OrderCommission() + OrderSwap()*/) / OrderLots()); // 佣金和交换有时可以忽略
  }
  
  static double GetProfit( void )
  {
    double Res = 0;
    
    for (int i = OrdersTotal() - 1; i >= 0; i--)
      if (OrderSelect(i, SELECT_BY_POS) && (OrderType() <= OP_SELL))
        Res += EQUITY::GetOrderProfit();
    
    return(Res);
  }
  
  double GetBalance( void )
  {
    const int HistoryTotal = OrdersHistoryTotal();
    
    if (HistoryTotal != this.PrevHistoryTotal)
    {
      for (int i = HistoryTotal - 1; i >= PrevHistoryTotal; i--)
        if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY) && (OrderType() <= OP_SELL) && OrderLots()) // OrderLots - CloseBy
          this.Balance += EQUITY::GetOrderProfit();
      
      this.PrevHistoryTotal = HistoryTotal;
    }
    
    return(this.Balance);
  }
  
public:
  double Data[];

  EQUITY( void ) : PrevHistoryTotal(0), Balance(0), PrevEquity(0)
  {
  }
  
  virtual void OnTimer( void )
  {
    const double NewEquity = this.GetBalance() + EQUITY::GetProfit();
    
    if (NewEquity != this.PrevEquity)    
    {
      EQUITY::AddArrayElement(this.Data, NewEquity, 1 e4);
      
      this.PrevEquity = NewEquity;
    }
  }
};


使用方法

EQUITY Equity;

void OnTimer()
{
  Equity.OnTimer();
}

double OnTester()
{
  return(CustomR2Equity(Equity.Data));
}
 
fxsaber:

适合 R^2 的 "权益 "计算代码。以 MT4 风格编写,翻译成 MT5 并不困难....。


使用方法


很酷,您可以在每个新的条形图 上调用它,这样系统就不会加载计时器。适用于具有新栏控制功能的系统。