只是作为一个介绍。
专家顾问分析了最后一个平仓订单的方向(或利润,...)。最后一个订单是在2天前结束的。
交易员将历史深度设置为1天。
OrdersHistoryTotal()并没有看到该订单。
解决办法是什么?
好的。
只是作为一个介绍。
专家顾问分析了最后一个平仓订单的方向(或利润,...)。最后一个订单是在2天前结束的。
而交易员将历史深度设置为1天。
OrdersHistoryTotal()并没有看到该订单。
解决办法?
对于MT4--在我看来,毫不含糊地,在启动EA时给用户一个警告,让其使用所需的历史深度。
MT5允许加载历史记录到所需的深度。
对于MT4--在我看来,毫不含糊地,在启动EA时给用户一个警告,让其使用所需的历史深度。
依靠用户是一个坏主意。需要有一个检查。
Artem,在MT4中,我没有找到获取设置历史深度值的方法。
真的无法通过编程获得吗?
依靠用户是一个坏主意。你需要一张支票。
Artem,在MT4中,我找不到Get来获取设定的历史深度值。
真的无法通过编程获得吗?
的确如此。
有两种范式来处理交易环境和编写EA。
- 事件输入(OnTick、OnTimer等)相互依赖。在事件之间有必须有的信息(不是为了速度,如缓存,而是为了可用性)。例如,我们需要保存OrderSendAsync的结果并在OnTradeTransaction 中使用它。缓存不是强制性的信息,只用于加快速度。这就是为什么我们不马上考虑他们。
- 事件输入(OnTick、OnTimer等)不是相互依赖的。每个输入都是从零开始。大致上就像一个你自己在每个事件上运行的脚本。
第二种方案比第一种方案的优势
- 你可以在任何地方终止该算法(正常和非正常)。
- 你可以在任何地方开始/继续执行该算法。
- 高度的可靠性。
劣势
- In Tester在性能方面将不如第一个变体。
- 这种 "从头开始 "的逻辑使你写的代码有些 "不合逻辑",这在第一阶段需要一些适应。
我如何比较交易环境的API?引入各种不同的TS。让我们想象一下我们理想的虚拟API,它将允许以最小的努力在可靠的代码中体现出TS。
如果有可能将这种非常理想的虚拟API作为真正的API的包装物来创建,那么原来的API就非常好。尽管甚至需要花费多少精力和时间来创建一个包装器。
按照这个标准,MT4和MT5是优秀的API。只有源API是困难的,但它们允许(没有架构/技术限制)写一个伟大的包装,因此是好的。
因此,当他们说MT5比MT4更复杂--他们的意思是,他们还没有遇到一个MT5包装器(也许还没有写出来),能像他们使用的MT4包装器一样可用的。
一般来说,这两个平台都允许你从低级别的API中创建一个高级别的API(包装器)。因此,他们的交易环境API的复杂性是相等的!
MT4有一个相当高级的API,所以很少有人试图写一个普遍的更方便用户的包装器。但MT5不是这样的--原来的底层API只是要求编写某种包装器。因此,在这个问题上讨论每个包装器的特点没有什么意义。相反,重要的是要表明仍然需要一个包装器。在编写高层API时,确实需要考虑低层API的哪些特征。
В общем, обе платформы позволяют из низкоуровневых API создать единый высокоуровневый API (обертка). Так что сложности API торговых окружений у них равны!
基于这种说法,我们需要学习如何编写MT5代码,在实用性方面不逊于MT4代码。API包装可能不同(语法通常),但从架构上看,MT5不应该比MT4差,否则就失去了强调的意义。因此,更繁琐的MT5代码不应视为批评的理由,而应视为将其缝合到不亚于MT4的用户友好包装中的帮助。
fxsaber, 2018.02.15 23:19
// Шаблон большинства ТС #property strict // обязательно // Сигнал на покупку bool BuySignal( const string Symb ) { return(true); } // Сигнал на продажу bool SellSignal( const string Symb ) { return(false); } // Находит ордер соответствующего типа bool OrdersScan( const string Symb, const int Type ) { for (int i = OrdersTotal() - 1; i >= 0; i--) if (OrderSelect(i, SELECT_BY_POS) && (OrderType() == Type) && (OrderSymbol() == Symb)) return(true); return(false); } // Торговое действие на сигнал bool Action( const string Symb, const int Type, const double Lots = 1 ) { bool Res = true; // Закрыли противоположные сигналу позиции while ((OrdersScan(Symb, 1 - Type)) && (Res = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 100))); // Открыли позицию по сигналу return(Res && !OrdersScan(Symb, Type) && OrderSend(Symb, Type, Lots, SymbolInfoDouble(Symb, Type ? SYMBOL_BID : SYMBOL_ASK), 100, 0, 0)); } // Шаблон торговой стратегии void Strategy( const string Symb ) { if (BuySignal(Symb)) Action(Symb, OP_BUY); else if (SellSignal(Symb)) Action(Symb, OP_SELL); } void OnTick() { Strategy(_Symbol); }
这丝毫没有显示出MT4的便利性,它只是作为一个比较的基准点。这是一个MT5封装器应该能够保持的较低的可用性标准。模板是根据第二个范 式编写的。
看来我们在MT5上写的东西是一样的
fxsaber, 2018.02.15 22:30
// Шаблон большинства ТС #include <Trade/Trade.mqh> // Сигнал на покупку bool BuySignal( const string Symb ) { return(true); } // Сигнал на продажу bool SellSignal( const string Symb ) { return(false); } // Находит позицию соответствующего типа bool PositionsScan( const string Symb, const ENUM_POSITION_TYPE Type ) { for (int i = PositionsTotal() - 1; i >= 0; i--) if ((PositionGetSymbol(i) == Symb) && (PositionGetInteger(POSITION_TYPE) == Type)) return(true); return(false); } // Торговое действие на сигнал bool Action( const string Symb, const ENUM_POSITION_TYPE Type, const double Lots = 1 ) { static CTrade Trade; bool Res = true; // Закрыли противоположные сигналу позиции while ((PositionsScan(Symb, (ENUM_POSITION_TYPE)(1 - Type))) && (Res = Trade.PositionClose(PositionGetInteger(POSITION_TICKET)))); // Открыли позицию по сигналу return(Res && !PositionsScan(Symb, Type) && (Type ? Trade.Sell(Lots, Symb) : Trade.Buy(Lots, Symb))); } // Шаблон торговой стратегии void Strategy( const string Symb ) { if (BuySignal(Symb)) Action(Symb, POSITION_TYPE_BUY); else if (SellSignal(Symb)) Action(Symb, POSITION_TYPE_SELL); } void OnTick() { Strategy(_Symbol); }
由于某些原因,有些人为了同样的TS写了更多的代码。但事实上,这段代码做得同样好。大多数TC只需要写BuySignal和SellSignal。不需要其他任何东西。
该模板的例子是专门用SB写的。因此,向MT5专家提问,该代码是否正确?
显示需要包装器的函数被标为红色。这里 描述了它的问题。有人会想起,这就是古代用睡眠法解决的仓位重开问题,在OrderSend后等待仓位打开。但事实上,这个问题与OrderSend没有关系。你需要知道如何正确阅读交易环境。
你需要能够正确阅读交易环境。
用一个简单的例子来正确地认识它
// Возвращает количество позиций по символу int GetAmountPositions( const string Symb ) { int Res = 0; for (int i = PositionsTotal() - 1; i >= 0; i--) if (PositionGetSymbol(i) == Symb) Res++; for (int i = OrdersTotal() - 1; i >= 0; i--) if (OrderGetTicket(i) && (OrderGetInteger(ORDER_TYPE) <= ORDER_TYPE_SELL) && !OrderGetInteger(ORDER_POSITION_ID) && (OrderGetString(ORDER_SYMBOL) == Symb)) Res++; /* for (int i = OrdersTotal() - 1; i >= 0; i--) if (OrderSelect(i, SELECT_BY_POS) && (OrderType() <= OP_SELL) && (OrderSymbol() == Symb)) Res++; */ return(Res); }
简而言之,重点是:如果有市场订单,也要考虑它是一个 "头寸"。用引号,因为它是一个包裹的位置。突出显示的代码通常不会出现在任何地方。但它避免了重新开 仓。这里最有趣的事情是用红色强调的。这个芯片的必要性并不立即显现。
事情是这样的,有所谓的收盘市场订单。同样的SL/TP。显然,我们不希望将这种市场订单视为 "头寸"。我们也不希望看到我们已经下的那些订单也被关闭。因此,突出显示的条件是适当的过滤器。