
非标准自动交易
简介
不进行深入市场分析便使用 MT4 平台成功且舒适地交易——这可能吗?这种交易可以在现实中实施吗?
我想,是的。
特别对于自动交易,更是如此!MQL4 允许进行这种交易。这个深入描述自动交易系统特点在于其良好的可重复性。连刚开始熟悉 Expert Advisor 编写基本知识的菜鸟都可以轻松实施该系统。
系统本身实际上是对外在世界的反映。和谐发展的生活规定自己的规则。孩童时期,我们都见过以下场景:蚂蚁从不同的侧面举起稻草,然后将其拉入蚁穴。每个蚂蚁都按自己的方式来拉动稻草。尽管如此,稻草最后还是运往蚁穴的方向!难道这是自然的奥秘所在?让我们试着在交易平台上仿效这种情况。
非标准自动交易
假设我们拥有某些盈利类型的自动交易系统。系统符合以下要求:
- 入场信号实际上是随机的。
- 系统一直处于市场中,即该系统按计数器导向仓位而非止损点来运行,这点很重要。
- 使用位于入口处的多个静态参数,我们可以优化系统以获得剔除合理亏损的最大利润。
在没有资金管理模块的情况下,实际上该系统将提供 3000 点以上的年利润。随后,我们将以反向模式启用该系统。换言之,该系统可通过以下方式运行:
- 如果我们以直接模式买入,则现在我们将卖出,反之亦然。此后,我们将再次使用静态参数优化系统。在退出反向版本前,我们将获得剔除合理亏损的最大利润。此举应不会造成任何问题,因为我们的自动交易系统最初是建立在随机进场的前提下的。
- 此后,我们将同时开启两个版本——直接和反向。同时运行两个版本非常重要,这是所述交易系统的关键时刻!
来看看我们有什么。
同时开启两个系统——直接和反向,我们将获得双重利润。然而,系统以对抗模式运行,即有意识而非盲目地进行互斥运行!此外,我们已减少了总亏损——目前相对亏损。为什么系统会有意识而非盲目地运行?
原因在于,相比于直接系统,其他在反向系统开始后便存在于四分之三交易中的其他静态参数将按时间和价格上的改变进行交易。但是,反向模式下的入场算法仍一致。
但总利润将持续提高!我认为当两个系统——直接和反向的优化用于利润把持时,这种情况非常明显。此外,一个版本的当前亏损总能由另一版本的当前利润所弥补。最终,我们将获得最大利润和最低亏损。
部分劣势在于这样做会提高保证金要求。但这种情况是否可以称作劣势呢?实际上,这里有两个独立运行的交易系统——直接和反向。自然而然的,保证金要求也是双倍的。如果将风险考虑在内,则该要求将大幅降低!这便是主要思想——不是在于提高利润,而是在于最大限度地降低亏损。但事物之间总是相互影响的。这种交易中的总利润将再次持续提高。最终,我们可以启用资金管理模块了。
MQL4.社区 的网站内有多个 Expert Advisor 可供选择,包括符合上列要求的系统。市场本身迫使我们投入新任务,并寻找不同、非标准的解决方案!我们还可以找到进一步搜索的办法。
为实现这个理念,并进一步进行试验,我们使用了 Yury Reshetov “人工智能”的 Expert Advisor 作为基础,该系统此前曾在相同部分内(参阅 Y. Reshetov 的 “如何找到盈利的交易系统”文章)做过描述。该系统与部分修订和添加一同使用,特别是系统包含了一个选项,可调用另一个基本指标用于运行感知程序。该系统还包含了建仓和进一步跟踪仓位的部分额外条件。
这里是在时间范围 H1 上对 GBPUSD 货币对进行测试期间获得的部分实验结果。初始保证金为 10000 单位。2.5 年的记录——从 2005 年 1 月至 2007 年 5 月。
直接版本包含了此期间内进行的 250 次交易。反向版本则为 360 次交易。交易数量有异,是由于每个版本在优化期间的止损水平不同所致。两个情况下的净利润大约超过 10000。在使用 0.1-手数操作,未启用资金管理模块的情况下,两个版本的盈利和亏损交易比例为 3:2。
这是记录中直接版本和反向版本余额/资产图形的示例:
你可以看到,多数情况下直接版本的亏损交易都由反向版本的盈利交易所弥补。反之亦然——反向版本的亏损由直接版本的盈利所弥补。
此外,一个图表显示为扁平时,另一个则呈现上升趋势!最后,我们以最低风险获得最大利润,即最小亏损。以 Excel 格式收集所有交易记录,绘制将所述观点可视化的结果图表不会造成问题。
接下来便是启用资金管理模块。我们可以预计到,在这种交易期间启用该模块将显著提高在利润、亏损和交易便利性方面的最终结果。在直接和反向版本中,我包括了在 I. Kim 之后调用手数计算 “b-lots”的库。该手数可很容易便纳入源代码中,且操作顺畅:https://www.mql5.com/zh/code/8048
测试期间,我使用了计算手数的合适方法(LotsWayChoice=2),这种方法可带来合理的最小亏损和相对可观的利润(瑞恩·琼斯,“交易游戏:用数字赚取百万收入”)。结果相比其他计算手数方法而言还算不错,其他方法经常显示大额利润和大额亏损。
让我们来看看 2005 年 1 月至 2007 年 5 月的相同记录。带有和之前相同参数的测试结果为:
反向版本:
- 净利润 +79864
- 最大亏损 16969(24%)
- 相对亏损 33%(3511)
直接版本:
- 净利润 +196520
- 最大亏损 25801(12.3%)
- 相对亏损 18.14%(6972)
这些是余额图表:
这些图表同样非常生动地显示当前亏损是如何由反向版本利润所弥补的。我认为,这种交易的便利性非常明显。
具体运用
作为示例并用于进一步主要试验,这里将提供反向版本的代码,该代码与Y. Reshetov 的 Expert Advisor “Ai”的作者直接版本背道而驰。直接版本与其描述在此:https://www.mql5.com/zh/code/10289
此外,随附的文件包含了指标感知器(作者 - 来自乌克兰克列缅丘的无名氏),该感知器可让人从视觉上控制 Expert Advisor 的当前工作(直接和反向),并且事先知道新的仓位建立的方向。在此处将指标感知器 X1-X4 权重系数值设为与对应的 EA 值相同。这是一个反向版本的示例:
对应那些才刚开始使用 MQL4 的人,我尝试对 EA 运行做出最大限度的注释。感知器对该反向版本的运行输出会显示在图表的左上角:
//+------------------------------------------------------------------+ //| ArtificialIntelligenceRevers.mq4 | //| Copyright й 2006, Yury V. Reshetov | //| Modifed by Leonid553 | //| http://www.tradersforum.net.ru/ | //| | //+------------------------------------------------------------------+ #property copyright "Copyright й 2006, Yury V. Reshetov ICQ:282715499" #property link "http://reshetov.xnet.uz/" //---- input parameters extern int x1 = 88; extern int x2 = 172; extern int x3 = 39; extern int x4 = 172; // StopLoss level extern double sl = 50; extern double lots = 0.1; extern int MagicNumber = 808; static int prevtime = 0; static int spread = 3; //+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ int init() { //---- return(0); } //+------------------------------------------------------------------+ //| expert deinitialization function | //+------------------------------------------------------------------+ int deinit() { //---- return(0); } //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() { Comment(perceptron()); // Wait for the formation of a new candlestick // If a new candlestick appears, check for the possibility of a trade if(Time[0] == prevtime) return(0); prevtime = Time[0]; //---- if(IsTradeAllowed()) { spread = MarketInfo(Symbol(), MODE_SPREAD); } else { prevtime = Time[1]; return(0); } int ticket = -1; // check for opened position int total = OrdersTotal(); for(int i = 0; i < total; i++) { OrderSelect(i, SELECT_BY_POS, MODE_TRADES); // check for symbol & magic number if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) { int prevticket = OrderTicket(); // long position is opened if(OrderType() == OP_BUY) // if a long position is opened and ... { // check profit // the current profit is larger than the value of =(stoploss + spread) and ... if(Bid > (OrderStopLoss() + (sl * 2 + spread) * Point)) { if(perceptron() > 0) { // perceptron is more than zero, then turn to Sell // reverse ticket = OrderSend(Symbol(), OP_SELL, lots * 2, Bid, 3, Ask + sl * Point, 0, "AI", MagicNumber, 0, Red); Sleep(30000); if(ticket < 0) { prevtime = Time[1]; } else { OrderCloseBy(ticket, prevticket, Blue); } } else //if perceptron is less than zero, trail the stoploss to the distance =sl //from the current price { // trailing stop if(!OrderModify(OrderTicket(), OrderOpenPrice(), Bid - sl * Point, 0, 0, Blue)) { Sleep(30000); prevtime = Time[1]; } } } // short position is opened } else { // if a short position is opened and ... // check profit if(Ask < (OrderStopLoss() - (sl * 2 + spread) * Point)) { // the current profit is larger than the value of =(stoploss + spread) and ... if(perceptron() < 0) { // perceptron is less than zero, then turn to Buy // reverse ticket = OrderSend(Symbol(), OP_BUY, lots * 2, Ask, 3, Bid - sl * Point, 0, "AI", MagicNumber, 0, Blue); Sleep(30000); if(ticket < 0) { prevtime = Time[1]; } else { OrderCloseBy(ticket, prevticket, Blue); } } else //if perceptron is more than zero, trail the stoploss to the distance =sl //from the current price { // trailing stop if(!OrderModify(OrderTicket(), OrderOpenPrice(), Ask + sl * Point, 0, 0, Blue)) { Sleep(30000); prevtime = Time[1]; } } } } // exit return(0); } } //******************************************************************** // check for long or short position possibility // initial entrance to the market: if(perceptron() < 0) { // if the perceptron is less than zero, open a long position : // long ticket = OrderSend(Symbol(), OP_BUY, lots, Ask, 3, Bid - sl * Point, 0, "AI", MagicNumber, 0, Blue); if(ticket < 0) { Sleep(30000); prevtime = Time[1]; } } else // if the perceptron is more than zero, open a short position: { // short ticket = OrderSend(Symbol(), OP_SELL, lots, Bid, 3, Ask + sl * Point, 0, "AI", MagicNumber, 0, Red); if(ticket < 0) { Sleep(30000); prevtime = Time[1]; } } //--- exit return(0); } //+------------------------------------------------------------------+ //| The PERCEPRRON - a perceiving and recognizing function | //+------------------------------------------------------------------+ double perceptron() { double w1 = x1 - 100.0; double w2 = x2 - 100.0; double w3 = x3 - 100.0; double w4 = x4 - 100.0; double a1 = iAC(Symbol(), 0, 0); double a2 = iAC(Symbol(), 0, 7); double a3 = iAC(Symbol(), 0, 14); double a4 = iAC(Symbol(), 0, 21); return (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4); } //+------------------------------------------------------------------+}
需要注意的是,所述交易技巧的主要意义并不在这个特定的 Expert Advisor 中。相反的是,正如本文开始所阐明的,技巧的意义存在于任何 Expert Advisor 直接和反向版本的合作之中。这里有不同的可能形式:你可以拥有多个反向版本——这些版本基于不同条件,根据直接版本的初始算法进行创建和优化。这里有多种选择。
在这个理念上进一步拓展的话,我会建议绘制支撑和阻力线。或附加 MA 指标或其他任何合适的指标到平衡图上。在此情况下,我们可以基于指标信号,在某种程度上处理每个版本的交易限制。我认为它是可编程的。
但还尚处在设想中。
总结
A 可以预先知晓怀疑论者的反对意见——如果两个版本都在亏损时开始工作呢?
这或许会发生在非常特殊的情况下。但最多不会超过——“世上没有理想的事情”。然而,在实际的意外进场情况下,两个版本都基于一个指标的信号且按相反方向进行工作——即互相对抗!
将两个版本合并到一个 Expert Advisor 中的话,我们将获得进一步管理资产交易,以及用于进一步试验的有效工具。
本文由MetaQuotes Ltd译自俄文
原文地址: https://www.mql5.com/ru/articles/1485
注意: MetaQuotes Ltd.将保留所有关于这些材料的权利。全部或部分复制或者转载这些材料将被禁止。
This article was written by a user of the site and reflects their personal views. MetaQuotes Ltd is not responsible for the accuracy of the information presented, nor for any consequences resulting from the use of the solutions, strategies or recommendations described.


