警告
本文中包含的信息仅为我的个人见解。作为作者,我不想诱导你使用本文描述的算法进行交易。此外,我必须警告,使用该信息可能导致损失。
简介
本文包含对交易方法的描述 - 即获利交易的成交量积累。我认为只有获利交易才能够积累。文章解释了实施的最佳方式,并包含了帮助正确进行交易的 EA 代码。
算法的概念
获利交易的成交量积累可以让我们从市场变动中最大化获利。但成交量积累必须避免导致风险的增加。本文描述了这种成交量积累的算法之一。
首先,我们需要一个参考点 - 第一个主交易。主交易的交易量应大于每个辅交易的交易量。假设主交易的量为 0.2 手,辅交易的量则为 0.1 手。跟踪止损用于所有的交易,例如,50 个点。当主交易的获利达到 +100 点,止损为 +50。此时,在止损 -50 点的相同方向上打开 0.1 手的交易。如果价格回落,两个交易将被止损订单关闭。获得的利润等于 0.2 手的 50 点和 0.1 手的 - 50 点。总共获利等于 0.1 手的 50 点。这样就在交易量增加时实现了止损保护。
如果交易继续沿着必要的方向移动,当辅交易的获利达到 +50 点时,跟踪止损激活。当主交易的获利达到 200 点,辅交易的获利达到 100 点,将打开另一个辅交易。止损还是等于 -50。诸如此类。
这是一个非常简单的从手数积累良好获利的方法。同时使风险最小化。实际上,这里的风险不过是亏损了主交易的一部分,即第一个辅交易亏损的风险。但这并不是亏损风险,而是没有获得全部利润的风险。
标准的跟踪 止 损在只有获利时才跟踪交易。但如果在获得必要的利润之前对辅交易实施,则可以提高这种手数积累方法的获利性。你可以利用 MQL4 在优化辅订单的打开时如此操作。
实施
为此而编写的 Expert Advisor 基于“方便的剥头皮交易”一文中描述的 EA。本文中,EA 具有复合功能:即作为训练游戏,又是打开交易的工具。在该交易中,删除了游戏的功能。这样 Expert Advisor 在图表上绘制两个箭头 - 向上和向下。删除其中之一是在必要的方向打开交易的信号。例如,删除向下的箭头,则向上的箭头保留在图表上。对于 EA,这是一个买入信号,下一定量的买入止损挂单。
这里,市场订单是主订单。挂单具有辅订单的功能,辅订单比主订单的手数小。为了计算辅交易打开的“频率”及其数量,使用了两个概念。第一个是终极目标,即获利。这对所有订单都一样(主订单和辅订单)。第二个概念是打开挂单的步长。根据终极目标,EA 计算按照从当前价格到获利水平的间隔下单的数量。
例如,如果使获利等于 400 点,打开订单的步长为 100 点(默认),则买入时要打开 4 个订单。第一个是以沽盘价买入的主订单。第二个是以沽盘价+100 点买入的止损辅订单。第三个是以沽盘价+200 点买入的止损辅订单。第四个是以沽盘价+300 点买入的止损辅订单。所有订单的获利等于沽盘价+400 点,即对第一个订单为 400 点,第二个为 300 点,第三个为 200 点,第四个为 100 点。
跟踪 止 损 只有在获得必要的利润时才作用于主交易(默认为 50 点)。对于辅交易,则从打开订单的时刻开始(即可以跟踪止损的亏损区域)。跟踪止损水平对所有交易都相等。此外,跟踪止损水平是对辅交易的止损水平。
如果主订单关闭,会删除剩余的挂单。之后,图表上再次绘制两个箭头。这意味着 EA 准备好再次打开交易。
这一切看起来很冗长,但在实践中很容易实施。我们来分析 EA 代码。
//+------------------------------------------------------------------+ //| take_trend.mq4 | //| Copyright © 2008, FXRaider | //| | //+------------------------------------------------------------------+ #property copyright "Copyright © 2008, FXRaider" extern int gap=20; //level at which arrows are placed extern int TP=400; //Take Profit level extern int SL=0; //Stop Loss level extern double Lots1=0.2; //lot of a main trade extern double Lots2=0.1; //lot of auxiliary trades extern int slippage=2; //level of acceptable requote extern int MagicNumber1=5345; //magic number of the main trade extern int MagicNumber2=4365; //magic number of auxiliary trades extern int Open_Step=100; //step for opening auxiliary trades extern bool UseTrailing = true; //enabling/disabling T-SL extern int TrailingStop = 50; //Trailing Stop Loss level extern int TrailingStep = 1; //Trailing Stop Loss step int start() { //------------------------------ //+----------------------------------------------------------------------------------------------+ //| searching open orders for a pair | int pos_sell=0; for (int i_op_sell=OrdersTotal()-1; i_op_sell>=0; i_op_sell--) { if (!OrderSelect(i_op_sell,SELECT_BY_POS,MODE_TRADES)) break; if (Symbol()==OrderSymbol() &&OrderMagicNumber()==MagicNumber1 &&(OrderType()==OP_SELL)) { pos_sell=1; break; } } int pos_buy=0; for (int i_op_buy=OrdersTotal()-1; i_op_buy>=0; i_op_buy--) { if (!OrderSelect(i_op_buy,SELECT_BY_POS,MODE_TRADES)) break; if (Symbol()==OrderSymbol() &&OrderMagicNumber()==MagicNumber1 &&(OrderType()==OP_BUY)) { pos_buy=1; break; } } //| searching open orders for a pair | //+----------------------------------------------------------------------------------------------+ //+------------------------------------------------------------------------------------+ //| working with objects | //+----------------------------------------------------------+ //| deleting objects | if(iBarShift(NULL,0,ObjectGet("down",OBJPROP_TIME1))>0 ||ObjectGet("down",OBJPROP_PRICE1)!=Open[0]-gap*Point) { ObjectDelete("down"); } if(iBarShift(NULL,0,ObjectGet("up",OBJPROP_TIME1))>0 ||ObjectGet("up",OBJPROP_PRICE1)!=Open[0]+gap*Point) { ObjectDelete("up"); } //| deleting objects | //+----------------------------------------------------------+ //+----------------------------------------------------------+ //| drawing objects | if((ObjectFind("down") != 0&&ObjectFind("up") != 0) //if no objects &&!pos_sell&&!pos_buy) //if no open orders { ObjectCreate("down", OBJ_ARROW, 0, Time[0], Open[0]-gap*Point); //draw a down arrow ObjectSet("down", OBJPROP_STYLE, STYLE_DOT); ObjectSet("down", OBJPROP_ARROWCODE, 234); ObjectSet("down", OBJPROP_COLOR, Red); ObjectCreate("up", OBJ_ARROW, 0, Time[0], Open[0]+gap*Point); //draw an up arrow ObjectSet("up", OBJPROP_STYLE, STYLE_DOT); ObjectSet("up", OBJPROP_ARROWCODE, 233); ObjectSet("up", OBJPROP_COLOR, Blue); } //| drawing objects | //+----------------------------------------------------------+ //| working with objects | //+------------------------------------------------------------------------------------+ //+----------------------------------------------------------------------------------------------+ //| deleting unnecessary orders | int cnt_del; if(pos_buy==0) { for (cnt_del=0; cnt_del<OrdersTotal(); cnt_del++) { if (!(OrderSelect(cnt_del, SELECT_BY_POS, MODE_TRADES))) continue; if(OrderSymbol()==Symbol()) { if (OrderType()==OP_BUYSTOP && OrderMagicNumber()==MagicNumber2) OrderDelete(OrderTicket()); } } } if(pos_sell==0) { for (cnt_del=0; cnt_del<OrdersTotal(); cnt_del++) { if (!(OrderSelect(cnt_del, SELECT_BY_POS, MODE_TRADES))) continue; if(OrderSymbol()==Symbol()) { if (OrderType()==OP_SELLSTOP && OrderMagicNumber()==MagicNumber2) OrderDelete(OrderTicket()); } } } //| deleting unnecessary orders | //+----------------------------------------------------------------------------------------------+ //+------------------------------------------------------------------------------------+ //| opening trades | double sl_buy, sl_sell; if(!SL) { sl_buy=0; sl_sell=0; } else { sl_buy=Ask-SL*Point; sl_sell=Bid+SL*Point; } int stop_positions=MathFloor(TP/Open_Step-1); int i, open_step_2; if( ObjectGet("up", OBJPROP_PRICE1)==Open[0]+gap*Point &&iBarShift(NULL,0,ObjectGet("up",OBJPROP_TIME1))==0 &&ObjectFind("down") != 0 &&ObjectFind("up") == 0 &&!pos_buy ) { OrderSend(Symbol(),OP_BUY, Lots1,Ask,slippage,sl_buy,Ask+TP*Point,"take_trend",MagicNumber1,0,Blue); for(i=stop_positions;i>=0; i--) { open_step_2=open_step_2+Open_Step; OrderSend(Symbol(),OP_BUYSTOP, Lots2, Ask+open_step_2*Point,slippage, 0,Ask+TP*Point,"take_trend",MagicNumber2,0,Blue); } } if( ObjectGet("down", OBJPROP_PRICE1)==Open[0]-gap*Point &&iBarShift(NULL,0,ObjectGet("down",OBJPROP_TIME1))==0 &&ObjectFind("up") != 0 &&ObjectFind("down") == 0 &&!pos_sell ) { OrderSend(Symbol(),OP_SELL, Lots1,Bid,slippage,sl_sell,Bid-TP*Point,"take_trend",MagicNumber1,0,Red); for(i=stop_positions;i>=0; i--) { open_step_2=open_step_2+Open_Step; OrderSend(Symbol(),OP_SELLSTOP, Lots2, Bid-open_step_2*Point,slippage, 0,Bid-TP*Point,"take_trend",MagicNumber2,0,Red); } } //| opening trades | //+------------------------------------------------------------------------------------+ //+-------------------------------------------------------------------------------------------------+ //| trail of open orders | if (UseTrailing) { for (int trall=0; trall<OrdersTotal(); trall++) { if (!(OrderSelect(trall, SELECT_BY_POS, MODE_TRADES))) continue; if (OrderSymbol() != Symbol()) continue; if (OrderType() == OP_BUY ) { if (Bid-OrderOpenPrice() > TrailingStop*Point || OrderMagicNumber()==MagicNumber2) { if (OrderStopLoss() < Bid-(TrailingStop+TrailingStep-1)*Point || OrderStopLoss() == 0) { OrderModify(OrderTicket(), OrderOpenPrice(), Bid-TrailingStop*Point, OrderTakeProfit(), 0, Blue); } } } if (OrderType() == OP_SELL) { if (OrderOpenPrice()-Ask > TrailingStop*Point || OrderMagicNumber()==MagicNumber2) { if (OrderStopLoss() > Ask+(TrailingStop+TrailingStep-1)*Point || OrderStopLoss() == 0) { OrderModify(OrderTicket(), OrderOpenPrice(), Ask+TrailingStop*Point, OrderTakeProfit(), 0, Blue); } } } } } //| trail of open orders | //+-------------------------------------------------------------------------------------------------+ return(0); } //+------------------------------------------------------------------+
代码包含所有必要的注释。
变量:
gap – level, on which arrows are placed; TP – Take Profit level; SL – Stop Loss level; Lots1 – lot of a main trade; Lots2 – lot of auxiliary trades; slippage – level of acceptable requote; MagicNumber1 – magic number of the main trade; MagicNumber2 – magic number of auxiliary trades; Open_Step – step for opening auxiliary trades; UseTrailing – enabling/disabling T-SL; TrailingStop – Trailing Stop Loss level; TrailingStep – Trailing Stop Loss step.
在添加 Expert Advisor 到图表后,绘制了两个箭头:
直到下一个蜡烛图出现前,剩下的箭头会保留在图表上。
在删除一个箭头后,EA 立即打开交易。
可以看到,剩下的箭头未显示在截屏上 - 之前已经说过,在下一个蜡烛图出现时它会被删除,直到所有交易关闭后才出现箭头。只要第一个交易的利润达到必要水平,T-SL 开始工作(它始终作用于辅交易)。在本例中,只有第一个交易在回落时关闭。同时,所有其他订单被删除。
总结
最后,我想说的是,应该为每一个货币对单独选择跟踪止损水平、获利和打开辅交易的水平。另需要注意的是,为了有效使用,辅交易的打开水平必须大于 T-SL 水平。在主交易中,建议使用大于辅交易的手数。