应对交易环境时的典型错误和如何处理这些错误 - 页 2

 

fxsaber:

表示需要包扎的功能用红色标记。这里 描述了它的问题。有些人可能还记得,这是一个古老的仓位重开问题,在古代是通过睡眠来解决的,在OrderSend之后等待仓位打开。但事实上,这个问题与OrderSend没有关系。你必须能够正确阅读交易环境。

右边的是一个简单的例子。

订单列表和仓位列表一样,不是即时更新的。我认为我们不能没有 "睡眠-离合器"。

可能更正确的是 OnTradeTransaction

 
Aleksey Lebedev:

订单列表,像头寸列表一样,不是即时更新的。我认为,我们不能没有 "睡眠"。

也许,使用 OnTradeTransaction会更好。

如果有一个问题等待环境更新,睡眠如何帮助?它要么有帮助,要么没有。

因此,应该从另一个方面着手:在发送开仓指令或设置挂单后,我们应该等待结果,不要再发送任何开仓或设置指令。那么我们就需要一个我们自己管理的标志,而不是相信 "睡眠",因为 "睡眠 "只提供程序执行的延迟,却不检查程序本身发送的交易请求的结果,而程序本身必须知道之后要做什么--设置一个标志并根据等待结果的逻辑来工作。在等待结果后,该标志被移除。

 
Artyom Trishkin:

问题:如果在发送交易订单后,直到下一个tick,服务器没有下市场订单,会发生什么?

这将与MT4上的情况完全一样--如果没有,就不会被计算在内。


这样的交易指令可能有几个原因

  1. 第三方OrderSend或OrderSendAsync - 不是来自我们读取交易环境的程序。它甚至可能不是来自程序运行的终端。在这种情况下,什么也做不了。在这种情况下,一切都与MT4相同。
  2. OrderSend或OrderSendAsync - 是从读取交易环境的程序中启动。在OrderSend的情况下,一切都很清楚,因为OrderSend将以一个明确的结果完成其执行。在OrderSendAsync的情况下,我们可以做两件事--根据第一个范例 将数据传递给下一个事件,或者做OrdersAsyncWait()(我没有代码),因为在MT4(多线程实现)的常规异步数据传输模拟中是这样的。
我也许应该对MT4的OrderSendAsync说几句。在程序执行的任何阶段,都可以看到相应的交易线程有多忙,以及它到底在做什么。从这个意义上说,MT4的自定义异步给我们提供了比MT5多得多的可能性。但在MT4中,它是通过在每个图表上运行 "客户端 "来实现的,也就是说,价格昂贵。在MT5中,可以编写同样的功能,甚至没有大量的图表--在OBJ_CHART对象上运行脚本,但仍会有轻微的延迟。也就是说,OrderSendAsyncCustom会比OrderSendAsync稍慢,但它仍然会比OrderSend快得多,并具有自定义实现的所有优势。
 
Aleksey Lebedev:

订单列表,像头寸列表一样,不是即时更新的。我认为,我们不能没有 "睡眠"。

也许,使用 OnTradeTransaction会更正确。

只有在使用OrderSendAsync时选择适当的范式,才可能需要MqlTradeTransaction。在其他情况下,OnTradeTransaction == OnTrade在意义上并不比OnTick或OnTimer发挥更多作用。


关于交易、自动交易系统和策略测试的论坛

在交易环境中工作时的典型错误以及如何解决这些错误

fxsaber, 2018.02.19 22:36

在交易环境中,有两种工作范式,编写EA。

  1. 事件输入(OnTick、OnTimer等)相互依赖。在事件之间有必须有的信息(不是为了速度,如缓存,而是为了可用性)。例如,我们需要保存OrderSendAsync的结果并在OnTradeTransaction 中使用它。缓存不是强制性的信息,只用于加快速度。这就是为什么我们不马上考虑他们。
  2. 事件输入(OnTick、OnTimer等)不是相互依赖的。每个输入都是从零开始。大致上就像一个你自己在每个事件上运行的脚本

突出显示的表示在每个On-function中运行相同的交易代码。相应的非交易代码完成了其他一切。

 
fxsaber:

这将与MT4上的情况完全一样--如果没有,就不会被计算在内。

也就是说--在下一次打勾时,程序会发送一个新的打开请求。结果是,我们有同样的问题--多个开口。

专家顾问应具有以下逻辑。

  1. 我们得到一个信号,可以开仓或设置一个挂单
  2. 检查订单/仓位的数量,如果没有建立新仓位的信号--退出(到第1点)。
  3. 检查服务器响应等待标志。
    1. 旗帜升起 - 退出(到步骤1)。
    2. 标志省略 - 继续
  4. 标志被省略 - 发送交易指令(尝试次数有限)并检查返回代码
    1. 订单已被执行 - 设置等待标志
    2. 订单失败--调用交易订单修正功能并转到第4点
  5. 等待标志被升起--检查交易环境的变化
    1. 贸易环境没有改变 - 退出(到步骤1)。
    2. 环境发生了变化--挂单被放置或开仓--移除等待标志并退出(到步骤1)。
 
Artyom Trishkin:

也就是说,在下一次打勾时,软件会发送一个新的开盘请求。结果是,我们有同样的问题--多个开口。

如果能读完整个帖子就好了。

该EA应该有以下逻辑。

  1. 我们收到了一个开仓或设置挂单的 信号
  2. 检查订单/仓位的数量,如果没有建立新仓位的信号--退出(到第1点)。
  3. 检查服务器响应等待标志
    1. 旗帜升起 - 退出(到步骤1)。
    2. 标志省略 - 继续
  4. 标志被省略 - 发送交易指令(尝试次数有限)并检查返回代码
    1. 订单已被执行 - 设置等待标志
    2. 订单未执行 - 调用功能纠正交易订单并转到第4点
  5. 等待标志被升起--检查交易环境的变化
    1. 贸易环境没有改变--退出(转到步骤1)。
    2. 环境发生了变化--挂单被放置或开仓--移除等待标志并退出(到步骤1)。

等待标志只适用于第二种情况 和OrderSendAsync。对于OrderSend,根本不需要等待标志。没有等待标志的OrderSendAsync是OrdersAsyncWait()。

你可以在实践中检验任何理论。

以实际成果为指导。
 
fxsaber:

完整地阅读该帖子是一个好主意。

等待标志只适用于第二种情况 和OrderSendAsync。对于OrderSend,根本不需要等待标志。没有等待标志的OrderSendAsync是OrdersAsyncWait()。

任何理论都可以在实践中得到检验

我以实际结果为指导。

嗯,我是为异步模式写的。使用同步时,你不需要等待--结果已经在查询响应中出现了。

 
Artyom Trishkin:

好吧,我是为异步模式写的。

从一开始就给出了一个详细的答案

 
fxsaber:

从一开始就给出了一个扩展的答案

我一定是看错了 :)

没有看到里面有任何步骤可以绕过多重发现的错误。只有一般的 "范式";)

这就是为什么我概述了近似的逻辑,这是多余的--标志是在一个开仓/设置挂单的函数(包装器)中检查。或者也可能是在信号跟踪功能中。

你必须考虑到最好的方式。

 
Artyom Trishkin:

该标志在开仓/放置挂单的功能(包装)中被检查。或者也可能是在信号跟踪功能中。

我更喜欢通过OrdersAsyncWait()的解决方案,当从On-function退出时,总是不会出现挂起状态。那么下一次以干净的方式对交易环境进行解读,就会尽可能的有针对性。

使用OrderSendAsync 应该始终是合适的。唯一可能发生的情况是在同一信号上发送多个(>1个)交易订单,彼此独立。因此,OrderSendAsync的事情在所有其他情况下都没有意义。


SZZY 有一个单独的话题,OrderSendAsync非常相关--多顾问:一个专家顾问中的几个独立TS。OrderSend在这里很少适用,甚至OrderAsyncWait(const string Symb)也不好,因为原则上不允许睡眠。