EA: 交易者的MQL5编程(MQL5 Programming for Traders) - 源代码第六部分 - 页 3

 
hini #property tester_set "FrameTransfer.set" (invalid tester set file extension, '*.set' expected FrameTransfer.mq5)

必须这样修改才能成功编译:#property tester_set "\\Presets\FrameTransfer.set"

甚至 `#property tester_set "/Presets/FrameTransfer.set"` 也会失败。

也许你可以修改算法书中的描述:


已在第 5506 版中修复。
 
Alain Verleyen #:
已在第 5506 版中修复。
谢谢。
 
Stanislav Korotky 优化 标准计算文件 -RSquared.mqh 的更新版本,其中对变量地段的计算进行了更正。

估算质量有了明显改善--从优化结果 表中可以看出,恢复系数和夏普参数的组合已经获得。

使用示例

注意!如果交易的符号不同,为了充分估算交易量,应将其从手数转换为存款货币的价值,例如(简化变量之一):

#include <MQL5Book/DealFilter.mqh>
#include <MQL5Book/RSquared.mqh>

template<typename T>
union Type2Bytes
{
   T d;
   uchar bytes[sizeof(T)];
};

double OnTester()
{
   HistorySelect(0, LONG_MAX);
   
   #define   STAT_PROPS 5
   
   const ENUM_DEAL_PROPERTY_DOUBLE props[STAT_PROPS] =
   {
      DEAL_PROFIT, DEAL_SWAP, DEAL_COMMISSION, DEAL_FEE, DEAL_VOLUME
   };
   double expenses[][STAT_PROPS];
   ulong tickets[]; // 仅用于匹配 "选择 "原型,但对调试很有用
   
   DealFilter filter;
   filter.let(DEAL_TYPE, (1 << DEAL_TYPE_BUY) | (1 << DEAL_TYPE_SELL), IS::OR_BITWISE)
      .let(DEAL_ENTRY, (1 << DEAL_ENTRY_OUT) | (1 << DEAL_ENTRY_INOUT) | (1 << DEAL_ENTRY_OUT_BY), IS::OR_BITWISE)
      .select(props, tickets, expenses);

   const int n = ArraySize(tickets);
   
   double balance[];
   double volumes[]; // 使用 R2 标准时考虑贸易量
   
   ArrayResize(balance, n + 1);
   balance[0] = 0;
   ArrayResize(volumes, n + 1);
   volumes[0] = 0;

   MapArray<ulong,double> sym2value; // 符号哈希值转换为 1 个批次值
   
   for(int i = 0; i < n; ++i)
   {
      const string s = HistoryDealGetString(tickets[i], DEAL_SYMBOL);

      double value = 1;
      Type2Bytes<ulong> sym;
      ArrayInitialize(sym.bytes, 0);
      StringToCharArray(s, sym.bytes);
      int idx = sym2value.find(sym.d);
      if(idx == -1) // 尚未记录每手的符号值
      {
         const double price = SymbolInfoDouble(s, SYMBOL_ASK);
         const double pt = SymbolInfoDouble(s, SYMBOL_POINT);
         double profit = 1;
         ResetLastError();
         if(!OrderCalcProfit(ORDER_TYPE_BUY, s, 1, price, price + pt, profit)) // 注:估计值约为,因为它使用的是记账货币的当前汇率。
         {
            // WARN(StringFormat("OrderCalcProfit Error: %s %d ", s, _LastError));
         }
         value = profit * (price / pt); // 注意:此处不使用杠杆作用
         idx = sym2value.put(sym.d, value);
      }
      else
      {
         value = sym2value.getValue(idx);
      }
   
      double result = 0;
      for(int j = 0; j < STAT_PROPS - 1; ++j) // 循环浏览所有请求的道具,交易量除外
      {
         result += expenses[i][j];
      }
      // 以数量为模型 - 更多投资 - 更多预期回报
      volumes[i + 1] = expenses[i][STAT_PROPS - 1] * value + volumes[i];
      balance[i + 1] = result + balance[i];
   }
   
   const double r2 = RSquaredTest(balance, volumes);
   
   #undef   STAT_PROPS
   
   return r2 * 100;
}

黄色标注的是与交易一个符号的计算结果相比必须增加的部分(来自上一个示例)。

 
Stanislav Korotky #:

修正MQL5/Include/MQL5Book/TradeUtils.mqh.

另一个相关的错误修复(在NormalizeLot 方法中):

const double newLotsRounded = MathFloor(nlot * (1 + DBL_EPSILON) / stepLot) * stepLot;
附加的文件:
TradeUtils.mqh  12 kb