搞MT4一年了,发个我在使用的EA,改写了一下,没有策略部的,当然,有些代码是在网上“山寨”过来的,改成这样的工具,如默认的止损,止盈,时间止损等,移动止损,帐户余额保护等等,作为辅助交易的工具,可以在手工交易时就非常非常有用了 这个EA代码已经实战了很长时间,能够正常使用的,只是策略部分自己的思路还不够好。自己也一直在完善细节的部分,也一直有测试自己的策略,挂机测试,希望与各位共同学习提高。 以下是基本的功能介绍: 1)4位报价,5位报价都适用。所说的点,都是按第4位小数的值,在5位报价平台也是如此。 2)帐户余保护,可以设置最大亏损百分比后就关仓。 3)开仓单最大亏损百分比关仓。 4)BEP,即设置到达一定的利润点后,就保护多少点值。 5)移动止损。 6)利润保护,可设置不同的利润保护等级,最多5个等级 7)日期及时间的设置,指定日期及时间段开平仓。本来有EA中使用的,但现在将策略部分删除了,意义不大 8)时间止损,可以设定一定时间内,单子不盈利就关掉 Code: #include <stdlib.mqh> #include <stderror.mqh> #include <WinUser32.mqh> extern bool Debug = false; extern string UserComment = ""; extern int MagicNum = 0; extern bool EADisabled = false; extern bool EmergencyCloseAll = false; extern int Portion = 1; extern bool UseAccountProtect = false; extern double StopTradePercent = 50; // percent of account balance lost before trading stops extern double MaxDDPercent = 60; // Percent of portion for max drawdown level. extern bool MoveToBEP = true; extern int MoveStopWhenPoint = 48; extern int LockProfit = 3; extern string mm8 = "OrderProfitProtect Settings"; extern bool UseOrderProfitProtect = true; extern int BeginProtectPositions = 2; extern double ProfitProtectLevel_0_Pips = 50; extern double ProfitProtectLevel_0_Percen = 10; extern double ProfitProtectLevel_1_Pips = 120; extern double ProfitProtectLevel_1_Percen = 20; extern double ProfitProtectLevel_2_Pips = 220; extern double ProfitProtectLevel_2_Percen = 40; extern double ProfitProtectLevel_3_Pips = 280; extern double ProfitProtectLevel_3_Percen = 50; extern double ProfitProtectLevel_4_Pips = 380; extern double ProfitProtectLevel_4_Percen = 60; extern double ProfitProtectLevel_5_Pips = 450; extern double ProfitProtectLevel_5_Percen = 70; //----------------------------------------------------- extern string s08 = "--TRADING TIME MANAGEMENT--"; extern string TTM1 = "Set time frames when new trades can open."; extern string TTM2 = "If Starthour = Stophour, then trade 24/5."; extern string TTM3 = "If TTMGoFlat=true, close all open trades"; extern string TTM4 = "when outside trading hours or days."; extern bool EnableTradeTimeManage = false; extern int ManualGMToffset = 3; // Set your broker's GMT Offset extern int GMTStartHour = 0; // Start trading at 0:00/GMT extern int GMTStopHour = 0; // Stop trading at 23:59/GMT extern bool TradeOnFriday = true; extern int FridayGMTStopHour = -1; // If set to 0 or higher, will prevent new trades from opening on Friday starting at that hour GMT. extern bool TTMGoFlat = false; extern string s12 = "-- Use this section to exclude trading days"; extern bool EnableBlackout = false; extern int StartBlackoutDay = 20; extern int StartBlackoutMonth = 12; extern int StopBlackoutDay = 15; extern int StopBlackoutMonth = 01; int StartBlackout = 0; int StopBlackout = 0; //----------------------------------------------------- extern bool UsingTakeProfit = true; extern int TakeProfit = 300; extern bool UsingStopLoss = true; extern double StopLoss = 39; // piont extern bool UsingTrailingStop = false; extern double TrailingStop = 55;//piont extern bool UsingHiLoTrailingStop = true; extern bool UsingTimeStopLoss = true; extern int TimeStopLossMin = 125; //Minute string myType = "ALL"; int Magic; string Type; double myPoint; datetime BarTime; double Lot; double StopTradeBalance; double InitialAB; double MaxDDPer; double MaxDD; double OrdersBuyLots; double OrdersSellLots; double MaxTradeLots; int OrderCount; int BuyOrderCount; int SellOrderCount; double OrderProfitPips = 0; double OrderProfits = 0; double MaxOrderProfitPips = 0; double LastOrderOpenPrice; //---signal variable int BaseEntrySignal; int AddPositionSignal; int CloseSignal; int SignalFilter; double uplevel; double dnlevel; // Comment variable string txt; //+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ int init() { //---- myPoint = SetmyPoint(); Magic = 0; Type = "ALL"; while (!IsConnected()) { Comment("Waiting for connection..."); Sleep(10000); } StartBlackout = DayNumber(StartBlackoutMonth, StartBlackoutDay); StopBlackout = DayNumber(StopBlackoutMonth, StopBlackoutDay); InitialAB=AccountBalance(); StopTradeBalance=InitialAB - InitialAB*(StopTradePercent/100); //---- return(0); } //+------------------------------------------------------------------+ //| expert deinitialization function | //+------------------------------------------------------------------+ int deinit() { //---- //---- return(0); } //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() { if (EADisabled == true) { if (IsTesting()) Comment("EA Disabled! Check Journal Log for details.\n"); else Comment("EA Disabled! Check Experts Log for details.\n"); return(0); } Comment(txt); TraceOrderDetail(Type); if(EmergencyCloseAll == true) { CloseOrders(OP_SELL,"ALL"); CloseOrders(OP_BUY,"ALL"); EADisabled = true; Comment("Close All Position and Halt"); Print("Close All Position and Halt"); return(0); } if(UseAccountProtect == true) { if(AccountProtection()== true) { Comment("Account Balance dropped below stop trade percent"); Comment( "Reset EA, account balance dropped below stop trade percent"); Print("Account Balance dropped below stop trade percent"); return(0); } } if(UseOrderProfitProtect == true) { if(PositionsProtection(Type)== true) { BarTime = Time[0]; //don't open order in the current Bar return(0); } } if (!IsTradingTime() && TTMGoFlat && OrderProfitTotalPips("ALL") >0) { Comment("Closing orders because outside of trading window."); Print("Closing orders because outside of trading window."); CloseOrders(OP_SELL,"ALL"); CloseOrders(OP_BUY,"ALL"); } if(!IsTradingTime()) { Comment("Closing orders because outside of trading window."); Print("Closing orders because outside of trading window."); return(0); } ModifyDefaultStopLoss(); if(MoveToBEP == true) BEP(Type); if(UsingTrailingStop == true) TrailStop(Type,TrailingStop); if(UsingTimeStopLoss == true) TimeStopLoss (Type); //------------------------------------------------------------- //---- return(0); } //+------------------------------------------------------------------+ //1 long -1 short 0 no signal //-------------------------------------------------------------------------------- double SetmyPoint() { double res; if (Digits < 4) res = 0.01; else res = 0.0001; return (res); } double StopLong(double Price, int Pips) { if (Price == 0) return (0); else return (NormalizeDouble(Price - Pips * myPoint,Digits)); } double StopShort(double Price, int Pips) { if (Price == 0) return (0); else return (NormalizeDouble(Price + Pips * myPoint,Digits)); } double TakeLong(double Price, int Pips) { if (Price == 0) return (0); else return (NormalizeDouble(Price + Pips * myPoint,Digits)); } double TakeShort(double Price, int Pips) { if (Price == 0) return (0); else return (NormalizeDouble(Price - Pips * myPoint,Digits)); } double ValidStopLoss(int myOrderType, double Price, double StopPrice) { double Spread = MarketInfo(Symbol(), MODE_STOPLEVEL); if (Digits == 3 || Digits == 5) Spread /= 10.0; if (myOrderType == OP_BUY) if (Price - StopPrice < Spread * myPoint) StopPrice = NormalizeDouble(Price + Spread * myPoint,Digits); if (myOrderType == OP_SELL) if (StopPrice - Price < Spread * myPoint) StopPrice = NormalizeDouble(Price - Spread * myPoint,Digits); return (StopPrice); } double ValidTakeProfit(int myOrderType, double Price, double myTakeProfit) { double Spread = MarketInfo(Symbol(), MODE_STOPLEVEL); if (Digits == 3 || Digits == 5) Spread /= 10.0; if (myOrderType == OP_SELL) if (Price - myTakeProfit < Spread * myPoint) myTakeProfit = Price - Spread * myPoint; if (myOrderType == OP_BUY) if (myTakeProfit - Price < Spread * myPoint) myTakeProfit = Price + Spread * myPoint; return (myTakeProfit); } int CalculateBuyOrders(string myType) { int cnt = 0; int total = OrdersTotal(); for(int i = 0;i<total;i++) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) ==false) continue; if( isOrder(OrderSymbol(), OrderMagicNumber(), OrderComment(), myType) && (OrderType()==OP_BUY) ) cnt++; } return(cnt); } int CalculateSellOrders(string myType) { int cnt = 0; int total = OrdersTotal(); for(int i = 0;i<total;i++) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) ==false) continue; if( isOrder(OrderSymbol(), OrderMagicNumber(), OrderComment(), myType) && (OrderType()==OP_SELL) ) cnt++; } return(cnt); } //------------------------------------------------------------------------------------ double CalculateBuyLots(string myType) { double sum = 0; int total = OrdersTotal(); for(int i = 0;i<total;i++) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) ==false) continue; if( isOrder(OrderSymbol(), OrderMagicNumber(), OrderComment(), myType) && (OrderType()==OP_BUY) ) sum+=OrderLots(); } return(sum); } double CalculateSellLots(string myType) { double sum = 0; int total = OrdersTotal(); for(int i = 0;i<total;i++) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) ==false) continue; if( isOrder(OrderSymbol(), OrderMagicNumber(), OrderComment(), myType) && (OrderType()==OP_SELL) ) sum+=OrderLots(); } return(sum); } bool isOrder(string mySymbol,int myMagicNumber,string myOrderComment,string myType) { if(Debug) { Print(mySymbol," ",myMagicNumber," ",myOrderComment," ",myType); } if(myType =="ALL" || myType =="" ) { if(StringFind(myOrderComment,UserComment)>=0 && mySymbol == Symbol() && myMagicNumber == Magic ) return(true); else return(false); } } //END FUN void TraceOrderDetail(string myType) { static int LastOrderCount = -1; BuyOrderCount = CalculateBuyOrders ("ALL"); SellOrderCount = CalculateSellOrders("ALL"); OrderCount = BuyOrderCount + SellOrderCount; if(OrderCount < 1 || LastOrderCount != OrderCount) { MaxOrderProfitPips = 0; LastOrderOpenPrice = 99999999999; LastOrderCount = OrderCount; } else { OrderProfitPips = OrderProfitTotalPips(myType); //order profit pips OrderProfits = OrderProfitPips * MarketInfo(Symbol(),MODE_TICKVALUE) * (myPoint /Point); OrdersBuyLots = CalculateBuyLots(myType); OrdersSellLots = CalculateSellLots(myType); if(MaxOrderProfitPips < OrderProfitPips) MaxOrderProfitPips = OrderProfitPips; } } //+------------------------------------------------------------------+ //--------------------------------------------------------- double OrderProfitTotalPips(string myType) { int cnt, total = 0; double tickvalue = MarketInfo(Symbol(),MODE_TICKVALUE); double TotalProfitPips = 0; for(cnt=0;cnt<OrdersTotal();cnt++) { if(OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES) ==false) continue; if((OrderType()==OP_SELL||OrderType()==OP_BUY) && isOrder(OrderSymbol(), OrderMagicNumber(), OrderComment(), myType)) { double PipProfitPips = (OrderProfit()/OrderLots()/ (tickvalue * (myPoint / Point))); TotalProfitPips = TotalProfitPips+PipProfitPips; } } return(TotalProfitPips); } //--------------------------------------------------------- void StopMoveToCost (string myType,int OffsetPips) { bool res = false; int total = OrdersTotal(); for(int i = 0;i<total;i++) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) ==false) continue; if( isOrder(OrderSymbol(), OrderMagicNumber(), OrderComment(), myType)) { if( OrderType()==OP_BUY && OrderOpenPrice() - OffsetPips * myPoint > OrderStopLoss()) ModiFyOrder(OrderTicket(),OrderOpenPrice(), OrderOpenPrice() - OffsetPips * myPoint, OrderTakeProfit()); if( OrderType()==OP_SELL && OrderOpenPrice() + OffsetPips * myPoint < OrderStopLoss()) ModiFyOrder(OrderTicket(),OrderOpenPrice(), OrderOpenPrice() + OffsetPips * myPoint, OrderTakeProfit()); } } //for } //--------------------------------------------------------- bool AccountProtection () { double PortionBalance = NormalizeDouble(AccountBalance() / Portion, 2); if ( -OrderProfits >= (PortionBalance * MaxDDPercent / 100) ) { CloseOrders(OP_SELL,"ALL"); CloseOrders(OP_BUY,"ALL"); Print("AccountProtection Close"); } if ( -OrderProfits > MaxDD) MaxDD = -OrderProfits; MaxDDPer = MathMax(MaxDDPer, MaxDD / PortionBalance * 100); double StepAB = InitialAB + InitialAB * (StopTradePercent / 100); double StepSTB = AccountBalance() - AccountBalance()*(StopTradePercent / 100); double NextISTB = StepAB - StepAB*(StopTradePercent / 100); if (StepSTB > NextISTB){ InitialAB = StepAB; StopTradeBalance = StepSTB; } double InitialAccountMultiPortion = StopTradeBalance/Portion; if (PortionBalance < InitialAccountMultiPortion){ return (true); } return(false); } bool PositionsProtection(string myType) { if(OrderCount < BeginProtectPositions) return(false); // profit protect level 5 if(MaxOrderProfitPips >= ProfitProtectLevel_5_Pips) { if(OrderProfitPips < NormalizeDouble(MaxOrderProfitPips * (ProfitProtectLevel_5_Percen /100),0)) { CloseOrders(OP_SELL,myType); CloseOrders(OP_BUY,myType); Print("Order protected ",ProfitProtectLevel_5_Percen," MaxOrderProfitPips ",MaxOrderProfitPips," now " ,OrderProfitPips); return(true); } else return(false); } else // profit protect level 4 if(MaxOrderProfitPips >= ProfitProtectLevel_4_Pips) { if(OrderProfitPips < NormalizeDouble(MaxOrderProfitPips * (ProfitProtectLevel_4_Percen /100),0)) { CloseOrders(OP_SELL,myType); CloseOrders(OP_BUY,myType); Print("Order protected ",ProfitProtectLevel_4_Percen," MaxOrderProfitPips ",MaxOrderProfitPips," now " ,OrderProfitPips); return(true); } else return(false); } else // profit protect level 3 if(MaxOrderProfitPips >= ProfitProtectLevel_3_Pips) { if(OrderProfitPips < NormalizeDouble(MaxOrderProfitPips * (ProfitProtectLevel_3_Percen /100),0)) { CloseOrders(OP_SELL,myType); CloseOrders(OP_BUY,myType); Print("Order protected ",ProfitProtectLevel_3_Percen," MaxOrderProfitPips ",MaxOrderProfitPips," now " ,OrderProfitPips); return(true); } else return(false); } else // profit protect level 2 if(MaxOrderProfitPips >= ProfitProtectLevel_2_Pips) { if(OrderProfitPips < NormalizeDouble(MaxOrderProfitPips * (ProfitProtectLevel_2_Percen /100),0)) { CloseOrders(OP_SELL,myType); CloseOrders(OP_BUY,myType); Print("Order protected ",ProfitProtectLevel_2_Percen," MaxOrderProfitPips ",MaxOrderProfitPips," now " ,OrderProfitPips); return(true); } else return(false); } else // profit protect level 1 if(MaxOrderProfitPips >= ProfitProtectLevel_1_Pips) { if(OrderProfitPips < NormalizeDouble(MaxOrderProfitPips * (ProfitProtectLevel_1_Percen /100),0)) { CloseOrders(OP_SELL,myType); CloseOrders(OP_BUY,myType); Print("Order protected ",ProfitProtectLevel_1_Percen," MaxOrderProfitPips ",MaxOrderProfitPips," now " ,OrderProfitPips); return(true); } } else // profit protect level 0 if(MaxOrderProfitPips >= ProfitProtectLevel_0_Pips) { if(OrderProfitPips < NormalizeDouble(MaxOrderProfitPips * (ProfitProtectLevel_0_Percen /100),0)) { CloseOrders(OP_SELL,myType); CloseOrders(OP_BUY,myType); Print("Order protected ",ProfitProtectLevel_0_Percen," MaxOrderProfitPips ",MaxOrderProfitPips," now " ,OrderProfitPips); return(true); } else return(false); } return(false); } // end PositionsProtection //--------------------------------------------------------- bool GetTradeContext() { bool hadToWait=false; while(!IsTradeAllowed()) { Sleep(5000); hadToWait=true; } while(IsTradeContextBusy()) { Sleep(200); hadToWait=true; } return(hadToWait); } //------------------ModifyStop function------------------------------------- bool ModiFyOrder(int Ticket,double myOrderPrice,double myStopPrice,double myTakeProfit) { bool res = true; int retryTimes = 5,cnt = 0; if(myStopPrice ==0.0 && myTakeProfit == 0.0) return(true); while(cnt < retryTimes) { res = OrderModify(Ticket,myOrderPrice,myStopPrice,myTakeProfit,0,Blue); if(res==false) { cnt += 1; } else { cnt = retryTimes; } } if(res==false) { Print("ModiFyOrder error:" ,ErrorDescription(GetLastError())); Print("Ticket",Ticket,"OrderPrice ",myOrderPrice," StopPrice ",myStopPrice," TakeProfit ",myTakeProfit); } return(res); } //------------------------------------------------------------------------------------- bool CloseOrder(int Ticket, double Lots, int myOrderType) { bool res; int ErrorCode; double Price; bool Status = false; if(myOrderType == OP_BUYLIMIT || myOrderType == OP_BUYSTOP || myOrderType == OP_SELLLIMIT || myOrderType == OP_SELLSTOP) { OrderDelete(OrderTicket()); return(true); } if (myOrderType == OP_BUY) Price = Bid; if (myOrderType == OP_SELL) Price = Ask; if (Digits > 0) Price = NormalizeDouble(Price, Digits); int cnt = 0; while (!Status) { if (IsTradeAllowed() == true) { res = OrderClose(Ticket, Lots, Price, MarketInfo(Symbol(),MODE_SPREAD), Violet); ErrorCode = GetLastError(); } else cnt++; if (res == true) Status = true; ErrorCode = GetLastError(); switch (ErrorCode) { case 0/* NO_ERROR */: Status = true; break; case 4/* SERVER_BUSY */: case 6/* NO_CONNECTION */: case 129/* INVALID_PRICE */: case 136/* OFF_QUOTES */: case 137/* BROKER_BUSY */: case 146/* TRADE_CONTEXT_BUSY */: case 128/* TRADE_TIMEOUT */: RefreshRates(); cnt++; break; case 135/* PRICE_CHANGED */: case 138/* REQUOTE */: RefreshRates(); continue; default: Status = TRUE; } if (cnt > 20) Status = TRUE; //10 time try if (!Status) { Sleep(500); RefreshRates(); } } if (res == true || ErrorCode == 0/* NO_ERROR */) return (true); Print(" Error closing order : (", ErrorCode, ") " + ErrorDescription(ErrorCode)); return (false); } bool CloseOrders(int orderMode,string myType) { int OrderCount=0, gle=0; int cnt,mode; int TicketArray[100]; double ClosePrice=0; string stringOrderMode; if (orderMode==OP_BUY) stringOrderMode="BUY"; if (orderMode==OP_SELL) stringOrderMode="SELL"; // first, we retrieve all ticket IDs for existing orders to close out for(cnt=OrdersTotal()-1;cnt>=0;cnt--) { if (OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES)) { mode=OrderType(); if (isOrder(OrderSymbol(), OrderMagicNumber(), OrderComment(), myType)) { if (mode==orderMode) { TicketArray[OrderCount]=OrderTicket(); Print("OrderCount: ",OrderCount,", Ticket: ",TicketArray[OrderCount]," Selected for closure."); OrderCount++; } } } else { gle=GetLastError(); Print("Error selecting an order in CloseAllOrders!!! Error #",gle,": ",ErrorDescription(gle)); return(false); //Since returning false, the caller will retry this function again } } // second, we close out all applicable orders in the array. this two step method prevents problems closing out all orders successfully at once. int retries=0; while(retries<20) { for(cnt=0;cnt<OrderCount;cnt++) { if (TicketArray[cnt]>0) { if (OrderSelect(TicketArray[cnt], SELECT_BY_TICKET, MODE_TRADES)) { mode=OrderType(); GetTradeContext(); RefreshRates(); if (mode==OP_BUY) ClosePrice=NormalizeDouble(Bid,Digits); if (mode==OP_SELL) ClosePrice=NormalizeDouble(Ask,Digits); if (mode == (orderMode+2) || mode == (orderMode+4)) { if (OrderDelete(OrderTicket())) { TicketArray[cnt]=0; } else { gle=GetLastError(); Print("Error closing pending order #",TicketArray[cnt],": Error #",gle,": ",ErrorDescription(gle)); } } else { if (CloseOrder(OrderTicket(), OrderLots(), OrderType())) { TicketArray[cnt]=0; } else { gle=GetLastError(); Print("Error closing order #",TicketArray[cnt],": Error #",gle,": ",ErrorDescription(gle)); } } } else { gle=GetLastError(); Print("Error selecting order #",TicketArray[cnt],": Error #",gle,": ",ErrorDescription(gle)); } } } retries++; } bool CloseAllSuccess=true; for(cnt=0;cnt<OrderCount;cnt++) { if (TicketArray[cnt]>0) { CloseAllSuccess=false; Alert("Could not close ticket #",TicketArray[cnt],"! Will keep retrying."); } } if(CloseAllSuccess) { return(true); } else { Print("There was a critical error closing one or more ",stringOrderMode," orders when trying to CLOSE ALL!"); return(false); //Since returning false, the caller will retry this function again } } //------------------------------------------------------------------------------------- bool ModifyDefaultStopLoss() { double StopPrice; double TakeProfitPrice; double myPrice; int retryTimes = 5,cnt = 0; bool res = false; int total = OrdersTotal(); for(int i = 0;i<total;i++) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) ==false) continue; if(!isOrder(OrderSymbol(), OrderMagicNumber(), OrderComment(), myType)) continue; while(cnt < retryTimes) { RefreshRates(); if(OrderType() == OP_BUY) { myPrice = Ask; StopPrice =StopLong (Ask,StopLoss); StopPrice = ValidStopLoss(OP_BUY,Ask,StopPrice); TakeProfitPrice=TakeLong(Ask,TakeProfit); TakeProfitPrice=ValidTakeProfit(OP_BUY,Ask,TakeProfitPrice); } if(OrderType() == OP_SELL) { myPrice = Bid; StopPrice =StopShort(Bid,StopLoss); StopPrice = ValidStopLoss(OP_SELL,Bid,StopPrice); TakeProfitPrice=TakeShort(Bid,TakeProfit); TakeProfitPrice=ValidTakeProfit(OP_SELL,Bid,TakeProfitPrice); } if(UsingStopLoss == false) StopPrice = 0; if(UsingTakeProfit == false) TakeProfitPrice = 0; if(ModiFyOrder(OrderTicket(),OrderOpenPrice(),StopPrice,TakeProfitPrice)== true) { cnt = retryTimes; res = true; } else cnt++; } //while } //for return(res); } //--------------------------------------------------------------------------- void TrailStop(string myType,int triling_i) { if (triling_i > 0) for (int k=0;k<OrdersTotal();k++) { if(OrderSelect(k,SELECT_BY_POS)!= true) continue; if(isOrder(OrderSymbol(), OrderMagicNumber(), OrderComment(), myType)) { if (OrderType()==OP_BUY && NormalizeDouble(Ask-OrderOpenPrice(),Digits)>=triling_i*myPoint && (OrderStopLoss()< NormalizeDouble(Ask-triling_i*myPoint,Digits) || OrderStopLoss()==0)) { if (!ModiFyOrder(OrderTicket(),OrderOpenPrice(),NormalizeDouble(Ask-triling_i*myPoint,Digits),OrderTakeProfit()) ) { Print("Trailing stop error Buy :" +ErrorDescription(GetLastError())); } } if (OrderType()==OP_SELL && NormalizeDouble(Bid+triling_i*myPoint,Digits)<=OrderOpenPrice() && (OrderStopLoss()>NormalizeDouble(Bid+triling_i*myPoint,Digits) || OrderStopLoss()==0)) { if (!ModiFyOrder(OrderTicket(),OrderOpenPrice(),NormalizeDouble(Bid+triling_i*myPoint,Digits),OrderTakeProfit()) ) { Print("Trailing stop error Sell :"+ErrorDescription(GetLastError())); } } } } } //---------------------------------------------------------- void BEP(string myType) { for (int i = 0; i < OrdersTotal(); i++) { OrderSelect(i,SELECT_BY_POS,MODE_TRADES); if(isOrder(OrderSymbol(), OrderMagicNumber(), OrderComment(), myType)) { if(OrderType()==OP_BUY) { if(Bid-OrderOpenPrice() >= myPoint * MoveStopWhenPoint) { if(OrderStopLoss()<OrderOpenPrice()) { ModiFyOrder(OrderTicket(),OrderOpenPrice(),NormalizeDouble(OrderOpenPrice()+myPoint*LockProfit,Digits),OrderTakeProfit()); return(0); } } } if(OrderType()==OP_SELL) { if(OrderOpenPrice()-Ask >= myPoint * MoveStopWhenPoint) { if(OrderStopLoss()>OrderOpenPrice()) { ModiFyOrder(OrderTicket(),OrderOpenPrice(),NormalizeDouble(OrderOpenPrice()-myPoint*LockProfit,Digits),OrderTakeProfit()); return(0); } } } } } } //--------------------------------------------------- void TimeStopLoss(string myType) { for (int i = 0; i < OrdersTotal(); i++) { OrderSelect(i,SELECT_BY_POS,MODE_TRADES); if(isOrder(OrderSymbol(), OrderMagicNumber(), OrderComment(), myType)) { if(TimeCurrent()-OrderOpenTime() > TimeStopLossMin * 60) { if(OrderType()==OP_BUY) { if(Bid-OrderOpenPrice() < 3 * myPoint ) { CloseOrder(OrderTicket(), OrderLots(), OrderType()); Print("Time stopLoss,Close"); } } if(OrderType()==OP_SELL) { if(OrderOpenPrice()-Ask < 3 * myPoint ) { CloseOrder(OrderTicket(), OrderLots(), OrderType()); Print("Time stopLoss,Close"); } } } } } } //--------------------------------------------------- bool IsTradingTime() { if (EnableTradeTimeManage == false) return(true); if (BlackoutTime()) return(false); // Added for blackout dates int currentDay = TimeDayOfWeek(TimeCurrent() - 3600 * ManualGMToffset); int currentHour = TimeHour(TimeCurrent() - 3600 * ManualGMToffset); if (!TradeOnFriday && currentDay >= 5) return(false); // GMT Adjusted Day of Week if (currentDay >= 5 && currentHour >= FridayGMTStopHour && FridayGMTStopHour >= 0) return(false); if (GMTStartHour == GMTStopHour) return(true); return(IsTradingTimeSub(GMTStartHour, GMTStopHour)); } bool IsTradingTimeSub(int myStartHour, int myEndHour) { int currentHour = TimeHour(TimeCurrent() - 3600 * ManualGMToffset); int adjustedEndHour = NormalizedHourParam(myEndHour - 1); if (myStartHour == adjustedEndHour) if (currentHour != myStartHour) return(false); if (myStartHour > adjustedEndHour) if (currentHour < myStartHour && currentHour > adjustedEndHour) return(false); if (myStartHour < adjustedEndHour) if (currentHour < myStartHour || currentHour > adjustedEndHour) return(false); return(true); } bool BlackoutTime() //DM: Kept variables global in scope { if (EnableBlackout) { StartBlackout = DayNumber(StartBlackoutMonth, StartBlackoutDay); StopBlackout = DayNumber(StopBlackoutMonth, StopBlackoutDay); if (StartBlackout <= StopBlackout && DayOfYear() >= StartBlackout && DayOfYear() < StopBlackout) { return (true); } if ((StartBlackout > StopBlackout && DayOfYear() >= StartBlackout) || (StartBlackout > StopBlackout && DayOfYear() < StopBlackout)) { return (true); } else return (false); } return (false); } int DayNumber(int month, int day) { int days = 0; switch(month) { case 1 : days = 0; break; case 2 : days = 31; break; case 3 : days = 59; break; case 4 : days = 90; break; case 5 : days = 120; break; case 6 : days = 151; break; case 7 : days = 181; break; case 8 : days = 212; break; case 9 : days = 243; break; case 10: days = 273; break; case 11: days = 304; break; case 12: days = 334; break; } days = days + day; bool leapYear = false; if (MathMod(Year(), 4) == 0) { leapYear = true; } else if (MathMod(Year(), 400) == 0) { leapYear = true; } else if (MathMod(Year(), 100) == 0) { leapYear = false; } if (leapYear == true && month > 2) days++; return (days); } int NormalizedHourParam(int myParam) { while (true) { if (myParam >= 24) { myParam -= 24; continue; } if (myParam >= 0) break; myParam += 24; } return(myParam); } //+------------------------------------------------------------------+ //| return error description | //+------------------------------------------------------------------+ string ErrorDescription(int error_code) { string error_string; //---- switch(error_code) { //---- codes returned from trade server case 0: case 1: error_string="no error"; break; case 2: error_string="common error"; break; case 3: error_string="invalid trade parameters"; break; case 4: error_string="trade server is busy"; break; case 5: error_string="old version of the client terminal"; break; case 6: error_string="no connection with trade server"; break; case 7: error_string="not enough rights"; break; case 8: error_string="too frequent requests"; break; case 9: error_string="malfunctional trade operation"; break; case 64: error_string="account disabled"; break; case 65: error_string="invalid account"; break; case 128: error_string="trade timeout"; break; case 129: error_string="invalid price"; break; case 130: error_string="invalid stops"; break; case 131: error_string="invalid trade volume"; break; case 132: error_string="market is closed"; break; case 133: error_string="trade is disabled"; break; case 134: error_string="not enough money"; break; case 135: error_string="price changed"; break; case 136: error_string="off quotes"; break; case 137: error_string="broker is busy"; break; case 138: error_string="requote"; break; case 139: error_string="order is locked"; break; case 140: error_string="long positions only allowed"; break; case 141: error_string="too many requests"; break; case 145: error_string="modification denied because order too close to market"; break; case 146: error_string="trade context is busy"; break; //---- mql4 errors case 4000: error_string="no error"; break; case 4001: error_string="wrong function myPointer"; break; case 4002: error_string="array index is out of range"; break; case 4003: error_string="no memory for function call stack"; break; case 4004: error_string="recursive stack overflow"; break; case 4005: error_string="not enough stack for parameter"; break; case 4006: error_string="no memory for parameter string"; break; case 4007: error_string="no memory for temp string"; break; case 4008: error_string="not initialized string"; break; case 4009: error_string="not initialized string in array"; break; case 4010: error_string="no memory for array\' string"; break; case 4011: error_string="too long string"; break; case 4012: error_string="remainder from zero divide"; break; case 4013: error_string="zero divide"; break; case 4014: error_string="unknown command"; break; case 4015: error_string="wrong jump (never generated error)"; break; case 4016: error_string="not initialized array"; break; case 4017: error_string="dll calls are not allowed"; break; case 4018: error_string="cannot load library"; break; case 4019: error_string="cannot call function"; break; case 4020: error_string="expert function calls are not allowed"; break; case 4021: error_string="not enough memory for temp string returned from function"; break; case 4022: error_string="system is busy (never generated error)"; break; case 4050: error_string="invalid function parameters count"; break; case 4051: error_string="invalid function parameter value"; break; case 4052: error_string="string function internal error"; break; case 4053: error_string="some array error"; break; case 4054: error_string="incorrect series array using"; break; case 4055: error_string="custom indicator error"; break; case 4056: error_string="arrays are incompatible"; break; case 4057: error_string="global variables processing error"; break; case 4058: error_string="global variable not found"; break; case 4059: error_string="function is not allowed in testing mode"; break; case 4060: error_string="function is not confirmed"; break; case 4061: error_string="send mail error"; break; case 4062: error_string="string parameter expected"; break; case 4063: error_string="integer parameter expected"; break; case 4064: error_string="double parameter expected"; break; case 4065: error_string="array as parameter expected"; break; case 4066: error_string="requested history data in update state"; break; case 4099: error_string="end of file"; break; case 4100: error_string="some file error"; break; case 4101: error_string="wrong file name"; break; case 4102: error_string="too many opened files"; break; case 4103: error_string="cannot open file"; break; case 4104: error_string="incompatible access to a file"; break; case 4105: error_string="no order selected"; break; case 4106: error_string="unknown symbol"; break; case 4107: error_string="invalid price parameter for trade function"; break; case 4108: error_string="invalid ticket"; break; case 4109: error_string="trade is not allowed"; break; case 4110: error_string="longs are not allowed"; break; case 4111: error_string="shorts are not allowed"; break; case 4200: error_string="object is already exist"; break; case 4201: error_string="unknown object property"; break; case 4202: error_string="object is not exist"; break; case 4203: error_string="unknown object type"; break; case 4204: error_string="no object name"; break; case 4205: error_string="object coordinates error"; break; case 4206: error_string="no specified subwindow"; break; default: error_string="unknown error"; } //---- return(error_string); }
日系货币也能适用,2位3位报价均可,还有是紧急情况下关闭多个仓位的,都是较方便的。 另外, 如果是作为手工辅助交易工具的,还需要在 ModifyDefaultStopLoss函数中 for(int i = 0;i<total;i++) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) ==false) continue; if(!isOrder(OrderSymbol(), OrderMagicNumber(), OrderComment(), myType)) continue; 的下方,加入 if(!(OrderStopLoss() == 0 || OrderTakeProfit() == 0)) continue; 本来,这个EA不是作为辅助工具而开发的,所以考虑不太周全,如果朋友能用上,或者可以提点意见去完善一下
很强! 7)日期及时间的设置,指定日期及时间段开平仓。本来有EA中使用的,但现在将策略部分删除了,意义不大——指定日期及时间段开、平仓,这个意义还是很大的,另外指定时间全撤单也有意义。 另外大部分MT4的经纪公司都限制单笔委托的最大手数的,所以常常需要将计算得到的总委托手数分解成多笔委托(每笔委托手数限制在经纪公司允许的最大手数内或自定义的手数内)。