程序库: 虚拟 - 页 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