程序库: 虚拟 - 页 8

 

去年语言发生变化后,我的虚拟版本就不能用了。我又换回了你的版本。
但我真的很怀念能考虑到价格变化的佣金。尤其是加密货币,在测试过程中价格会发生多次变化。
我的旧版本很准确,但在进行字符串操作和按工具查询价格时计算速度较慢。可能是因为速度太慢,你不想把它添加到你自己的版本中。

这次,我为欧元兑美元、澳元兑美元...也就是说,如果报价货币== 帐户货币,计算将是正确的。

#define COMMISSION_TO_PRICE 2 // умножить полученную комиссию на цену, например для EURUSD *=1.12345; 1 - комиссия берется только при входе, 2 - комиссия берется 2 раза и при входе и при выходе

佣金只需乘以开仓价或平仓价。对于 USDJPY 等工具,或者如果存款货币不是 USD(T),则可以禁用该选项,因为它不会准确(就像您当前的选项)。

#ifdef  ORDER_COMMISSION
 this.Commission = this.Lots * (ORDER_COMMISSION);
 #ifdef  COMMISSION_TO_PRICE
   this.Commission *= this.OpenPrice + (COMMISSION_TO_PRICE==2 ? this.ClosePrice : 0.0);
 #endif // 佣金比价格
#endif// 订单佣金

以下是我在欧元兑美元上得到的结果:

DC:
虚拟 c * 价格
虚拟无 * 价格

正如您所看到的,在添加选项后,140 笔交易的佣金仅相差 18 美分。而不加选项时则相差 42 美元。当然,您也可以在您的变量中选择平均乘数,例如不是 4,而是 4.305(测试的平均佣金),但必须对每种工具进行手动操作并重新编译。

编辑量不大,我希望您能将此选项添加到库代码中。或者,您可以考虑一些更通用的方法。


附加的文件:
Order.mqh  36 kb
 
Forester 货币== 帐户货币,计算就会正确。

事实上,这个公式总是有效的。

Commission = 0.002%; // 每边。

OrderCommission = (OrderOpenPrice + OrderClosePrice) * Commission * OrderLots * TickValue / TickSize;

当然,您也可以在您的变体中选择平均乘数,例如不是 4,而是 4.305(测试的平均佣金),但必须对每个工具手动操作并重新编译。

另一种变体。

input double inCommission = 0;
// .....
#define  ORDER_COMMISSION inCommission // OrderCommission() = OrderLots() * (ORDER_COMMISSION)),包括动态选项。

编辑量不大,我希望您能将这一变体添加到库代码中。或者,您可能会想到一些更通用的方法。

我完全同意编辑是有用的,应该进行编辑。应该检查部分关闭(OrderClose,而不是全部关闭)和 CloseBy。要检查这一点,只需编写一个脚本,在同一刻度线打开两个不同方向的仓位,同时进行部分平仓和平仓。我自己还没准备好这样做。如果您能提供这样一个结果正确的脚本,我会更快地对您的问题进行修正。

 
fxsaber #:

事实上,这个公式一直在起作用。

这对你来说更容易,你总是在事情的顶端。我没有一直这么做。自七月份以来,我第一次决定再测试一下....。

关于
OrderClosePrice
- 可能有些经纪中心只在开仓时收取佣金 - 对他们来说,最好不考虑佣金。对于点差来说,差别不大,但对于大目标来说,差别就很明显了。
 
fxsaber #:
完全同意编辑是有用的,应该进行编辑。有必要检查部分平仓(OrderClose 而非整批)和平仓。要检查这一点,只需编写一个脚本,在同一刻度线上打开两个不同方向的仓位,并同时进行部分平仓和平仓。我自己还没准备好这样做。如果您给我发来这样一个结果正确的脚本,我会更快地进行修改。
我测试过注释中的内容,并将其作为工作版本。但现在我什么都忘了。CloseBy - 我不用它,我通常有更简单的想法。我也没时间用它。只要有热情,我就会做策略。
 

虚拟系统对不良限额收取佣金:


显然我们需要进行类型检查
 
Forester #:

虚拟会给未执行的限额增加佣金:

显然我们需要进行类型检查
#define ORDER_COMMISSION -5 // OrderCommission() = OrderLots() * (ORDER_COMMISSION)),包括动态选项。
#include <fxsaber\Virtual\Virtual.mqh> //https://www.mql5.com/zh/code/22577

void OnStart()
{
  if (VIRTUAL::SelectByHandle(VIRTUAL::Create()))
  {
    VIRTUAL::NewTick();
    
    OrderDelete(OrderSend(_Symbol, OP_BUYLIMIT, 1, 0.01, 0, 0, 0));
    
    Print(VIRTUAL::ToString(1));
  }
}


结果。

#2 2025.11.25 19:23:11.105 buy limit 1.00 EURGBP.pro 0.01000 0.00000 0.00000 2025.11.25 19:23:11.105 0.87715 0.00 0.00 0.00 0 - 00:00:00


运行正常。显然,这些编辑 需要额外检查。

 
fxsaber #:

运行正常。显然,这些编辑 需要额外的验证。

您说得没错。

在 ToClose() 中,我在 if (this.IsPosition()){ 以外添加了佣金计算。

已修复,附上文件

附加的文件:
Order.mqh  37 kb
 

每次都 从 Virtual 读取资产净值和余额,并绘制图表。直到今天我才注意到,今天他们进行了 -66 的巨额掉期。

图表看起来是这样的。



应该和 MT5 的记录一样。

如您所见,由于佣金(我使用的是实际佣金,而不是点数)和掉期(我仍然不明白 MT 是如何对它们进行四舍五入的--不是通过 round())的四舍五入,最终利润相差几美分。

今天计算的掉期总和为 -5208.97。这只是图表上跳跃的大小。我认为在计算过程中,掉期并没有加到权益和余额中,而是在计算结束时才应用,这就是为什么看起来像这样。

我在 OnTester() 中调用了 VIRTUAL::CalcSwaps(...),这可以在虚拟交易中完成吗?在每个交易日都这样做成本太高。也许应该在每天开始时进行。也许已经编好程序,应该由某个 Defyne 启用?我记得在我的版本中,我为每天都做了交换,因为你有一些不同的东西。如果您过去没有做过,我可以把我的代码发给您,您可以参考一下。

 
Aleksei Kuznetsov #:

也许它已经编程好了,应该由某个 Defyne 启用?我记得在我的版本中,我为每一天都做了交换,而你的版本有所不同。如果你以前没有做过,我可以把我的代码发给你,让你举个例子。

我没有做过。但对于余额/权益曲线的绘制问题,我会在 OnTester 中进行一次 CalcSwaps,然后对余额[]/权益[]进行相应的一次调整。这样做既省钱又准确。

MT5 中的整个掉期操作似乎存在缺陷,因为没有掉期历史记录。如果将掉期计算在内,在大量历史数据中,结果会出现可怕的偏差。可能出现的情况是,您在周末进行了优化,而如果是在工作日进行优化,则选项文件中的最佳运行结果会显示完全不同的值。

不过,MT5-tester 并非基准。