简介
本文描述了开始交易的算法,可以更加方便的进行剥头皮交易。但是,该算法也可以应用于其他交易方法。实际上,本文提供了一种帮助交易者快速交易的方法。
一般来说,剥头皮交易被视为一种激进的交易类型。这里非常重要的一点是每次都需要指明手数、获利和止损位,因此转移了对图表的注意力。
本文是赌博模型作为培养“市场直觉”的方法的续篇。在开始研究本文之前,建议先阅读以上文章。
我想提醒你什么是剥头皮交易。剥头皮交易是快速交易的一种方法。通常这种交易的获利固定在 1-10 个价格利润点(点)。剥头皮交易以其复杂性、激进性和要求高度注意力著称。有人认为它不够严肃,有人则视其为完美操作。对我来说,我不想去评估该交易类型 - 它已被广泛讨论,每人都有自己的看法。
概念
很可能每个交易者都曾尝试过剥头皮交易策略。对某些交易者,剥头皮交易是最便捷的交易类型,而对其他人则相反。有人视剥头皮为最有趣的交易,其他人则视其为浪费时间。但是,所有人都意识到这种交易类型中对市场和已开始交易高度关注的必要性。
很多交易者不愿使用剥头皮交易,仅仅是因为需要太多精力。但是,有一种方法可以帮助剥头皮交易者。
假设交易者打算以固定的手数进行剥头皮交易,并且每次交易都获利。显然,有必要消除每次交易都需要指明这些参数的要求。因为这会占用额外的时间,并且分散交易者对图表的注意力。
这意味着我们需要一个工具,能够根据交易者的命令以固定的手数和获利/止损位开始交易。工具的操作应尽可能简单,此外,应该尽可能少的分散交易者对图表的注意力。
使用 MQL4 可以轻松创建这个工具。
实施
作为基础,我们将采用《赌博模型作为培养“市场直觉”的方法》一文中描述的游戏。我们将创建一个工具,能够在玩该游戏的同时进行交易。
对游戏的简要描述。图表上绘制两个箭头 - 向上和向下。交易者删除不必要的箭头,从而做出表明其意见的选择 - 即证券要上涨还是下跌。在新的蜡烛图的开始处,EA 检查交易者的预测是正确还是错误。预测的正确率影响游戏的分数。此外,交易者可以在限定的时间内做出选择。该时间可以更改(交易者决定是否进行设置)。
为了实现,我们在当前柱后面的一个柱上再画两个箭头。当前柱仍用于赌博。在前一个柱上删除一个箭头将是 EA 在必要的方向上开始交易的信号。另外,选择交易方向的持续时间限制将在交易中禁用。有以下可变参数:获利和止损水平、手数、可接受的滑点和幻数。此外,可以使用外部布尔变量禁用交易,从而使 EA 仅用于赌博。
而且,根据此时开始的交易,在图表上将绘制一个命名为‘买’或‘卖’的箭头。这是为了防止 EA 在该蜡烛图上开始新的交易。该箭头将绘制在距离柱开盘价格 300 点的地方,这样用户很可能根本不会注意到它。
EA 本身将分为两大块 - 游戏和开始交易。这样读者就可以看到代码中添加的内容。
这样,我们有以下程序代码:
//+------------------------------------------------------------------+ //| trener.mq4 | //| Copyright © 2008, FXRaider | //| | //+------------------------------------------------------------------+ #property copyright "Copyright © 2008, FXRaider" extern int gap=2; extern bool Trading=true; extern int TP=2; extern int SL=20; extern double Lots=0.02; extern int slippage=1; extern int MagicNumber=777; extern int time_limit=30; int start() { //---- //################################################################################# //####################################### GAME #################################### //------------------------------ string solution="none"; int point, point_neg, point_pos; //------------------------------ //+---------------------------------------------------------------+ //| "up" choice searching | if( ObjectGet("up", OBJPROP_PRICE1)==Open[1]+gap*Point &&iBarShift(NULL,0,ObjectGet("up",OBJPROP_TIME1))==1 &&ObjectFind("down") != 0 &&ObjectFind("up") == 0 ) { solution="up"; } //| "up" choice searching | //+---------------------------------------------------------------+ //+---------------------------------------------------------------+ //| "down" choice searching | if( ObjectGet("down", OBJPROP_PRICE1)==Open[1]-gap*Point &&iBarShift(NULL,0,ObjectGet("down",OBJPROP_TIME1))==1 &&ObjectFind("up") != 0 &&ObjectFind("down") == 0 ) { solution="down"; } //| "down" choice searching | //+---------------------------------------------------------------+ //+---------------------------------------------------------------+ //| counting points at a positive answer | if((solution=="up"&&Open[1]<Close[1]) ||(solution=="down"&&Open[1]>Close[1])) { point=1; point_pos=1; point_neg=0; } //| counting points at a positive answer | //+---------------------------------------------------------------+ //+---------------------------------------------------------------+ //| counting points at a negative answer | if((solution=="up"&&Open[1]>Close[1]) ||(solution=="down"&&Open[1]<Close[1])) { point=-1; point_pos=0; point_neg=1; } //| counting points at a negative answer | //+---------------------------------------------------------------+ //+----------------------------------------------------------------------------------+ //| working with an external file | int handle; double points, //total score points_pos, //score of positive answers points_neg; //score of negative answers handle=FileOpen("trener_"+Symbol()+"_"+Period()+".csv", FILE_CSV|FILE_WRITE|FILE_READ,";"); if(handle>0) //if there is a file, read it { points=NormalizeDouble(StrToDouble(FileReadString(handle)),Digits); points_pos=NormalizeDouble(StrToDouble(FileReadString(handle)),Digits); points_neg=NormalizeDouble(StrToDouble(FileReadString(handle)),Digits); FileClose(handle); } if(solution!="none") //if a choice has been made made { handle=FileOpen("trener_"+Symbol()+"_"+Period()+".csv", FILE_CSV|FILE_WRITE|FILE_READ,";"); FileWrite(handle ,points+point); //write the total score FileWrite(handle ,points_pos+point_pos); //write the score of positive answers FileWrite(handle ,points_neg+point_neg); //write the score of negative answers FileClose(handle); } //| working with an external file | //+----------------------------------------------------------------------------------+ //+------------------------------------------------------------------------------------+ //| working with 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"); } int sec_lim; if(!time_limit) { sec_lim=0; } else { sec_lim=TimeCurrent()-time_limit; } if(sec_lim>ObjectGet("up",OBJPROP_TIME1) &&sec_lim>ObjectGet("down",OBJPROP_TIME1) &&ObjectFind("down") == 0&&ObjectFind("up") == 0 &&iBarShift(NULL,0,ObjectGet("down",OBJPROP_TIME1))==0 &&iBarShift(NULL,0,ObjectGet("up",OBJPROP_TIME1))==0) { ObjectDelete("up"); ObjectDelete("down"); } if((ObjectFind("down") != 0&&ObjectFind("up") != 0) //if no object &&sec_lim<Time[0]) { 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, SYMBOL_ARROWDOWN); 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, SYMBOL_ARROWUP); ObjectSet("up", OBJPROP_COLOR, Blue); } //| working with objects | //+------------------------------------------------------------------------------------+ //####################################### GAME #################################### //################################################################################# //################################################################################# //#################################### TRADING #################################### //+------------------------------------------------------------------------------------+ //| working with objects I | if(iBarShift(NULL,0,ObjectGet("down_1",OBJPROP_TIME1))>1 ||ObjectGet("down_1",OBJPROP_PRICE1)!=Open[0]-gap*Point ||!Trading) { ObjectDelete("down_1"); } if(iBarShift(NULL,0,ObjectGet("up_1",OBJPROP_TIME1))>1 ||ObjectGet("up_1",OBJPROP_PRICE1)!=Open[0]+gap*Point ||!Trading) { ObjectDelete("up_1"); } if(iBarShift(NULL,0,ObjectGet("sell",OBJPROP_TIME1))>0 ||ObjectGet("sell",OBJPROP_PRICE1)!=Open[0]-300*Point ||!Trading) { ObjectDelete("sell"); } if(iBarShift(NULL,0,ObjectGet("buy",OBJPROP_TIME1))>0 ||ObjectGet("buy",OBJPROP_PRICE1)!=Open[0]+300*Point ||!Trading) { ObjectDelete("buy"); } if(ObjectFind("down_1") != 0&&ObjectFind("up_1") != 0 && Trading) { ObjectCreate("down_1", OBJ_ARROW, 0, Time[1], Open[0]-gap*Point); ObjectSet("down_1", OBJPROP_STYLE, STYLE_DOT); ObjectSet("down_1", OBJPROP_ARROWCODE, SYMBOL_ARROWDOWN); ObjectSet("down_1", OBJPROP_COLOR, Red); ObjectCreate("up_1", OBJ_ARROW, 0, Time[1], Open[0]+gap*Point); ObjectSet("up_1", OBJPROP_STYLE, STYLE_DOT); ObjectSet("up_1", OBJPROP_ARROWCODE, SYMBOL_ARROWUP); ObjectSet("up_1", OBJPROP_COLOR, Blue); } //| working with objects I | //+------------------------------------------------------------------------------------+ if(Trading) { //+----------------------------------------------------------------------------------------------+ //| searching open orders for a security | int pos_sell=0, bar_op_buy, bar_op_sell; 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() &&(OrderType()==OP_SELLSTOP||OrderType()==OP_SELL) &&(OrderMagicNumber()==MagicNumber) &&iBarShift(NULL,0,OrderOpenTime())==0) { 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() &&(OrderType()==OP_BUYSTOP||OrderType()==OP_BUY) &&(OrderMagicNumber()==MagicNumber) &&iBarShift(NULL,0,OrderOpenTime())==0) { pos_buy=1; break; } } //| searching open orders for a security | //+----------------------------------------------------------------------------------------------+ //+------------------------------------------------------------------------------------+ //| working with objects II | if(pos_buy==1) { ObjectCreate("buy", OBJ_ARROW, 0, Time[0], Open[0]+300*Point); ObjectSet("buy", OBJPROP_STYLE, STYLE_DOT); ObjectSet("buy", OBJPROP_ARROWCODE, SYMBOL_ARROWUP); ObjectSet("buy", OBJPROP_COLOR, Red); } if(pos_sell==1) { ObjectCreate("sell", OBJ_ARROW, 0, Time[0], Open[0]-300*Point); ObjectSet("sell", OBJPROP_STYLE, STYLE_DOT); ObjectSet("sell", OBJPROP_ARROWCODE, SYMBOL_ARROWDOWN); ObjectSet("sell", OBJPROP_COLOR, Red); } //| working with objects II | //+------------------------------------------------------------------------------------+ //+------------------------------------------------------------------------------------+ //| 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; } if( ObjectGet("up_1", OBJPROP_PRICE1)==Open[0]+gap*Point &&iBarShift(NULL,0,ObjectGet("up_1",OBJPROP_TIME1))==1 &&ObjectFind("down_1") != 0 &&ObjectFind("up_1") == 0 &&!pos_buy &&ObjectFind("buy") != 0 ) { OrderSend(Symbol(),OP_BUY, Lots,Ask,slippage,sl_buy,Ask+TP*Point,"trener",MagicNumber,0,Blue); } if( ObjectGet("down_1", OBJPROP_PRICE1)==Open[0]-gap*Point &&iBarShift(NULL,0,ObjectGet("down_1",OBJPROP_TIME1))==1 &&ObjectFind("up_1") != 0 &&ObjectFind("down_1") == 0 &&!pos_sell &&ObjectFind("sell") != 0 ) { OrderSend(Symbol(),OP_SELL, Lots,Bid,slippage,sl_sell,Bid-TP*Point,"trener",MagicNumber,0,Red); } //| opening trades | //+------------------------------------------------------------------------------------+ } //#################################### TRADING #################################### //################################################################################# Comment("Score: ", points," (",points_pos,"/",points_neg, //displaying score ") | Time: ", Hour(),":", Minute(),":", Seconds()); //displaying time (for convenience) return(0); } //+------------------------------------------------------------------+
代码包含所有必要的注释。
在 Expert Advisor 添加到图表后,我们得到以下结果:
这里的最后两个箭头用于游戏,其前面的两个箭头用于开始订单。
在上一个蜡烛图上删除一个箭头会导致执行 OrderSend() 函数,开始相应的订单:
以下是更改输入参数的选项卡:
“gap”变量为等于箭头和蜡烛图开盘价格之间距离的点数。“Trading”变量指示交易函数,“TP”- 获利的点数,“SL”- 止损的点数。“Lots”变量为建立头寸的交易量,“slippage”指示我们可以接受的容许滑点。“MagicNumber”指由 EA 为建立头寸指定的幻数(EA 需要能够跟踪其“自己的”订单)。“time_limit”限制变量设置秒数,在该时间内用户须做出选择。如果指示为“0”,说明没有时间限制,即可以在整个蜡烛图形态的时间内做出选择。
总结
这样,我们就可以使用标准参数(TP,SL,Slippage, lot)对证券进行方便的交易。该工具在任何交易中都很有用。但是,在用于短时间内开始大量交易的情况下最为有效。例如,在剥头皮交易中。
利用该程序,交易者不必每次都设置开始订单的参数。这样他的大部分注意力就可以集中在图表上。毫无疑问,这样会提高交易的有效性。