不过这次占据第一名的参赛者是PrizmaL ,其账户存款额值为132 233美元。在一个星期的交易内他的智能交易完成106笔交易,并带来盈利24 128。非常有趣值得注意的是目前他的智能交易整整完成了1000笔交易。这些交易全部在夜间结束交易业务。交易的平均结果为 1.9点。 第三名和第四名的位置被abeiks 和 strelec 占据。与 PrizmaL 的智能交易相同,这两位参赛者的智能交易同样喜欢夜间执行交易,在白天的交易中没有任何积极的动作。 他们在夜间的模式差异非常小,目标几乎相同货币对EURGBP不超过5点。
现在3个家伙倒是真的变成前三了。 我觉得3个人都用这个类似的策略并不偶然,应该他们测试2008.1-2008.9是盈利的,只是参数不知道怎么优化的,他们在细节上还是有点区别。 不过我看留言,多数认为真实帐户基本上是不可能用。
一是MT自己服务器的EG点差比较小是2点,其他的服务器基本上没有2点的,这个对策略最后的盈利有蛮大的影响。另外据说最近有些服务商就对EG的点差做了调整,好像意思是说晚上的点差反而变大了,具体倒是不知道有没有这个情况。 二是各个服务器对EG的最小限价止盈点的设置也不一样,比如说现在比赛的MT服务器最小的是4点: http://championship.mql4.com/2008/cn/rules/specifications/ 其他的服务商不清楚,据说好像没有那么小的; 其实这点蛮有意思的,大家可以试试现用EA测试在MT4服务器上面对EG现在已经没有办法ordersend tp< 6点的单子了,我记得前2个星期是可以的。一个可能是我记错了,还有一种可能的确那个MODE_STOPLEVEL是被他们调整过了。
别过于简单看待这类系统,其中一些思路有很好的借鉴价值的。 这类系统并不简单的是针对EG的,其中enzhi3816 (http://championship.mql4.com/2008/cn/users/enzhi3816/reports) 的就是针对EU的,不要因为enzhi3816的一些缺陷而轻看了,enzhi3816系统也是基本达到90%胜率的。 其中的时间过滤选择就是一个值得考虑和借鉴的。 我还仔细研究他们的交易清单,但从直觉上觉得他们是个利用新高/新低动能的策略,而这类策略又是可以有统计支持的。
我用复盘工具也研究过他的单子,不过一直没有看出来他的开仓条件,直到10.31那次有一个大的资金回撤后就没有再继续,其实那次亏损也不是达到了止损并没有损失特别多,我想他还是有一定的条件来执行。 “新高/新低动能”不是很明白,请教wj2000能否说一下类似的概念?
“新高/新低动能”——一个相对简单的情况, 比如:以小时线为基准,以前一周期的最高/最低价为触发条件设置限价委托策略指令,高于前一周期最高价就买入,低于前一周期最低价就卖出。 一般优化或限制性条件,只在活跃交易时段交易,止损和止盈幅度是可以通过数据统计得到,而且这个如果编写能力强可能还可以作为“反馈”信息来调整限价指令的止损和止盈幅度。另一个优化限制是统计非优化条件下赢利和止损指令执行的“持仓时间”,这个统计数据也可以作为调整止损限价指令的一个优化条件的。 这个类似策略的好处是支持统计分析,也支持资金管理的分析(止盈、止损和胜率的统计值都比较明确、直观)。
另外早上发现一个问题,今天的STOPLEVEL似乎已经开始变成了10点。 我怀疑后面几天那三位大侠可能要原地踏步了,去年那个用EG拨皮的winwin2007同学好像就遭到过这个待遇。 现在前2个比较鬼,判断不行就不开单了,第3个600592同学就比较倒霉了,日志里面一大堆 exp_Night_Watchman_2 EURGBP,M1: Error open BUY. Err Num: 130 - INVALID STOPS 嘿嘿,估计过两天裁判一致投票判断此同学LOG过多直接OUT。 并且如果日元近期产生一个大的涨幅、磅日暴跌,弄不好那个Gorez还会变成第一名。
第3个600592出问题是正常的,因为他是在m1下发出指令的,那样就容易产生大量的处理信息的,而另2个分别是以m5和m15为周期发出指令的。 这个我粗略统计过的,不管盈亏,不加优化,平均胜率在60-70%以上的。
是的,如果编写能力强,是可以在运行间隔一段时间后自动优化参数的。 策略的基本出发点的时候没考虑用ATR值来过滤趋势和震荡的,这个策略是不区分趋势和震荡的,要的只是交易的活跃性。 而这个策略不容易被执行的一个原因是,交易者难以接受在一波趋势交易中只获取很小的一段利润,而这个只获取很小一段利润却是此策略的关键。此策略是高胜率小盈亏比。 论坛里有人就曾经说过的,在高胜率小盈亏和低胜率高盈亏策略之间需要做出选择。
的确是这样,兼顾胜率和盈亏比是很难的,相关的还有一个就是开单数量,我个人比较喜欢和倾向开发高胜率策略系统的。 除了这个外,我能想到另外一个办法就是靠回撤点加仓来增加盈利,这次有个做美日日图的600349有点这个意思。 我把目前放置的EG程序贴在下面,有兴趣的可以看看。目前还是一个雏形,希望有志同道合者的同学能够一起来完善。 (附件似乎好像没有办法上传mq4文件) #define MagicNumber 20080101 extern double Lots = 0.1; extern double Risk = 10; extern int Prd = 5; extern int Rsi = 4; extern int Start1 = 7; extern int Start2 = 20; extern int GMT = 1; extern int MaxVol = 15; extern double Loss = 30; extern double Take = 5; extern double Take0 = 300; extern bool Debug = true; extern string sym ="EURGBP"; double lastbuy = 0; double lastsell = 0; int openorders = 0; double last = 0; double pf=0,lastpf=0; int l1 = 30; int h1 = 70; double CheckForLast(int op) { double tb=10000,ts=0; for(int i=0;i<OrdersTotal();i++) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break; if(OrderSymbol()==sym && OrderMagicNumber()==MagicNumber) { if(OrderType()==op && op ==OP_BUY) { if (OrderOpenPrice()<tb) tb = OrderOpenPrice(); } if(OrderType()==op && op ==OP_SELL) { if (OrderOpenPrice()>ts) ts = OrderOpenPrice(); } } } if (tb==10000) tb =0; if (op==OP_BUY) return (tb); if (op==OP_SELL) return (ts); } bool CheckLastStop() { bool result=false; if(OrderSelect(OrdersHistoryTotal()-1,SELECT_BY_POS,MODE_HISTORY)==true) { Print("profit ",OrderProfit()); if(OrderSymbol()==sym && OrderProfit()<0) { Print("profit ",OrderProfit()); result = true; } } return(result); } //+------------------------------------------------------------------+ //| Calculate open positions | //+------------------------------------------------------------------+ int CalculateCurrentOrders(string symbol) { int buys=0,sells=0; //---- for(int i=0;i<OrdersTotal();i++) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break; if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber) { if(OrderType()==OP_BUY) buys++; if(OrderType()==OP_SELL) sells++; } } return(buys+sells); } double GetLots(int percent) { double openlot = Lots; double req; double p = percent; if (percent !=0) { //Print(percent); //Print(AccountFreeMargin()); //Print(MarketInfo(Symbol(), MODE_MARGINREQUIRED)); req=MarketInfo(sym, MODE_MARGINREQUIRED); if (req!=0) { if (CheckLastStop()) p = p/2; openlot = MathRound (AccountBalance()*p/100/(req)*10)/10; } //Print(openlot); if (openlot < Lots) openlot = Lots; } return (openlot); } int OpenOrder(int cmd , double lts , double op , double sl , double tp) { double mvol = lts; int ticket; int tmpcount =0; if (mvol > MaxVol) mvol = MaxVol; tmpcount = CalculateCurrentOrders(sym); ticket = OrderSend(sym, cmd, mvol, op, 0, sl, tp, DoubleToStr(tmpcount,0), MagicNumber, 0, Red); if (cmd ==OP_SELL) { if(ticket < 0) { Print("OrderSell with error #" + GetLastError() + ":" + DoubleToStr(lastsell,5) ); } } if (cmd ==OP_BUY) { if(ticket < 0) { Print("OrderBuy with error #" + GetLastError() + ":" + DoubleToStr(lastbuy,5) ); } } openorders=CalculateCurrentOrders(sym); //Print(openorders); //Print(CalculateCurrentOrders(Symbol())); /*Print(AccountBalance()); Print(AccountMargin()); Print(AccountFreeMargin()); Print(AccountEquity());*/ return (ticket); } bool CheckTime() { bool result = false; if (TimeHour(TimeCurrent())<GMT+Start1-1 || TimeHour(TimeCurrent())>GMT+Start2-1) result = true; return (result); } //+------------------------------------------------------------------+ //| Check for open order conditions | //+------------------------------------------------------------------+ void CheckForOpen() { double ma ,mahi,malow; int res; int i,j; double tp,sl; lastbuy = CheckForLast(OP_BUY); lastsell = CheckForLast(OP_SELL); if (CalculateCurrentOrders(sym)==0) {lastbuy=0;lastsell=0;} if (iClose(sym,PERIOD_D1,1)==0) return; RefreshRates(); //---- sell conditions if( iRSI(sym,Prd,Rsi,PRICE_CLOSE,0) > h1 && CheckTime() ) { if (CalculateCurrentOrders(sym)!=0) return; //if (TimeDay(TimeCurrent()) == TimeDay(checklasttime())) return; if (TimeMonth(TimeCurrent()) >12 || ( TimeYear(TimeCurrent()) ==2008 && TimeMonth(TimeCurrent()) ==12&& TimeDay(TimeCurrent()) >22) ) return; if (lastsell!=0) return; if (Take !=0) { tp = Bid - (Take)*Point;} sl=Bid + Loss*Point; lastsell = Bid; OpenOrder(OP_SELL, GetLots(Risk),lastsell, sl,tp); return; } //---- buy conditions if( iRSI(sym,Prd,Rsi,PRICE_CLOSE,0) < l1 && CheckTime() ) { if (CalculateCurrentOrders(sym)!=0) return; if (lastbuy!=0) return; if (Take !=0) { tp = Ask + (Take)*Point;} sl= Ask - Loss*Point; lastbuy = Ask; OpenOrder(OP_BUY , GetLots(Risk),lastbuy, sl,tp); return; } //---- } bool CloseALL() { //Print("Close ALL total"); //Print(OrdersTotal()); int ot = OrdersTotal(); for(int i=0;i<ot;i++) { if(OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==false) return(false); if(OrderMagicNumber()!=MagicNumber|| OrderSymbol()!=sym) continue; //---- check order type //Print(i); //Print(OrderOpenPrice()); //Print(OrderProfit()); //Print(OrderSwap()); //Print(OrderTakeProfit()); if(OrderType()==OP_BUY) { if (!OrderClose(OrderTicket(),OrderLots(),Bid,3,White)) { Print("OrderClose with error #" + GetLastError() + OrderTicket()); return(false); } } if(OrderType()==OP_SELL) { if (!OrderClose(OrderTicket(),OrderLots(),Ask,3,White)) { Print("OrderClose with error #" + GetLastError() + OrderTicket()); return(false); } } } openorders=0; return(true); } //+------------------------------------------------------------------+ //| Check for close order conditions | //+------------------------------------------------------------------+ void CheckForClose() { pf = 0; for(int i=0;i<OrdersTotal();i++) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) { Print("error",i); break; } //---- check order type pf = pf + OrderProfit()+OrderSwap(); if(OrderType()==OP_BUY) { if (Bid - OrderOpenPrice()>Take0*Point) { CloseALL(); break; } if (!CheckTime() && OrderProfit()>=0) { CloseALL(); break; } } if(OrderType()==OP_SELL) { if (OrderOpenPrice()-Ask>Take0*Point) { CloseALL(); break; } if (!CheckTime() && OrderProfit()>=0) { CloseALL(); break; } } } //---- } //+------------------------------------------------------------------+ //| Start function | //+------------------------------------------------------------------+ void start() { //---- check for history and trading if(Bars<100 || IsTradeAllowed()==false) return; //---- calculate open orders by current symbol CheckForOpen(); CheckForClose(); //---- } //+------------------------------------------------------------------+
这次比赛的mq4代码,中间的平仓笔误修改过,因为开始对3单5手理解错了,以为只能最多持有5手头寸。 #property copyright "wj2000" #define Time_Frame PERIOD_D1 extern double Lots = 0.1; // 交易单位 extern int slip = 3; extern double MaximumRisk = 0.2; extern bool MoneyManagement = true; extern double MinLots = 1; extern double MaxLots = 50; extern double OpenPrice; extern double TakeProfit = 20; extern double StopPrice = 50; extern double TPS = 2; extern double TPL = 2; extern double SL = 1; extern double OpenSize = 0.4; extern double NSize = 1.5; extern double MinPrice = 30; extern double NewHigh; extern double NewLow; extern int AtrS = 1; extern int AtrL = 14; extern int OpenSwitchSel = 1; extern int CloseSwitchSel = 1; extern int SBuy = 0; extern int SSell = 0; extern int BuySize = 1; extern int SellSize = 1; extern int openhour; extern datetime lasttime; extern datetime lastday; extern datetime opentime; extern datetime opentime2; extern datetime closetime; extern datetime buytime; extern datetime selltime; int init() { lasttime = NULL; lastday = NULL; opentime = NULL; buytime = NULL; selltime = NULL; return(0); } int deinit() { return(0);} int start() { double HighMaNow = iMA(Symbol(),0,10,0,MODE_EMA,PRICE_HIGH,0); double CloseMaNow = iMA(Symbol(),0,20,0,MODE_EMA,PRICE_CLOSE,0); double LowMaNow = iMA(Symbol(),0,8,0,MODE_EMA,PRICE_LOW,0); double PSarNow = iSAR( Symbol(), 0, 0.02, 0.2, 0); double HLPricePro = High[1] - Low[1]; double OHPriceNow = High[0] - Open[0]; double OLPriceNow = Open[0] - Low[0]; // double AtrProS = iATR(Symbol(), 0, AtrS, 1); // double AtrProL = iATR(Symbol(), 0, AtrL, 1); //买入开仓开始 if (Time[0] != buytime && SBuy == 0) { /* switch(TimeHour(CurTime())) { case 8: case 9: case 10: case 11: case 15: case 16: case 17: case 18: */ if(Close[0] > High[1]) // if(Bid > High[1]) { SSell = CloseOrder(SSell, 0); if(MoneyManagement) { BuySize = LotsOptimized(StopPrice * Point); } SBuy = OpenOrder(SBuy, BuySize, 0); buytime = Time[0]; OpenPrice = Close[0]; NewHigh = Close[0]; // StopPrice = NewHigh - SL * AtrProL; } /* break; default: break; } */ } // 买入开仓结束 // 买入平仓开始 if(SBuy == 1) { NewHigh = MathMax(NewHigh, Close[0]); // StopPrice = NewHigh - SL * AtrProL; // StopPrice = NewHigh - StopPrice * Point; if(Close[0] < Low[1]) // if(Bid < Low[1]) { SBuy = CloseOrder(SBuy,1); } if(Close[0] > (OpenPrice + TakeProfit * Point)) // if(Bid > (OpenPrice + TakeProfit * Point)) { SBuy = CloseOrder(SBuy,1); } if(Close[0] < (OpenPrice - StopPrice * Point)) // if(Bid < (OpenPrice - StopPrice * Point)) // if(Close[0] < StopPrice) { SBuy = CloseOrder(SBuy,1); } } //买入平仓结束 //卖出开仓开始 if (Time[0] != selltime && SSell == 0) { /* switch(TimeHour(CurTime())) { case 8: case 9: case 10: case 11: case 15: case 16: case 17: case 18: */ if(Close[0] < Low[1]) // if(Bid < Low[1]) { SBuy = CloseOrder(SBuy, 1); if(MoneyManagement) { SellSize = LotsOptimized(StopPrice * Point); } SSell = OpenOrder(SSell, SellSize, 1); selltime = Time[0]; OpenPrice = Close[0]; NewLow = Close[0]; // StopPrice = NewLow + SL * AtrProL; } /* break; default: break; } */ } //卖出开仓结束 //卖出平仓开始 if(SSell == 1) { NewLow = MathMin(NewLow, Close[0]); // StopPrice = NewLow + SL * AtrProL; // StopPrice = NewLow + StopPrice * Point; if(Close[0] > High[1]) // if(Bid > High[1]) { SSell = CloseOrder(SSell, 0); } if(Close[0] < (OpenPrice - TakeProfit * Point)) // if(Bid < (OpenPrice - TakeProfit * Point)) { SSell = CloseOrder(SSell, 0); } if(Close[0] > (OpenPrice + StopPrice * Point)) // if(Bid > (OpenPrice + StopPrice * Point)) // if(Close[0] > StopPrice) { SSell = CloseOrder(SSell, 0); } } return(0); } void EnterOrder(int size,int mode)//mode=0 多单入场,mode=1,空单入场 { if (mode==0) //if (OrdersTotal( ) >= maxOpen) return ; //如果已持有开仓数达到最大,不做 OrderSend(Symbol(), mode, size*Lots, Ask, 3, 0, 0, 0,0,0); if(mode==1) // if (OrdersTotal( ) >= maxOpen) return ; //如果已持有开仓数达到最大,不做 OrderSend(Symbol(), mode, size*Lots, Bid, 3, 0, 0, 0,0,0); } void EndOrder(int mode)//平仓所有开单,mode=1 平仓多单 mode=0 平仓空单 { for (int i=0;i<OrdersTotal();i++) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break; if(OrderType()==OP_BUY && mode==1) OrderClose(OrderTicket(),OrderLots(),Bid,slip,0); if(OrderType()==OP_SELL && mode==0) OrderClose(OrderTicket(),OrderLots(),Ask,slip,0); } return(0); } int OpenOrder(int SignOpen,int size,int mode) //启动开仓开单,设置信号标示,mode=0 开仓多单 mode=1 开仓空单 { if (SignOpen == 0) { EnterOrder(size, mode); SignOpen = 1; } return(SignOpen); } int CloseOrder(int SignClose,int mode) //关闭平仓所有开单,设置信号标示,mode=1 平仓多单 mode=0 平仓空单 { EndOrder(mode); SignClose = 0; return(SignClose); } double LotsOptimized(double StopLoss) //确定下单量,开仓调用 { double lot=Lots; lot=MathFloor((MaximumRisk * AccountBalance())/(StopLoss / Point)); if(lot < MinLots) lot = MinLots; if(lot > MaxLots) lot = MaxLots; return(lot); }