//+------------------------------------------------------------------+ //| Moving Averages LC.mq5 | //| Copyright 2009-2013, MetaQuotes Software Corp. | //| http://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2009-2013, MetaQuotes Software Corp." #property link "http://www.mql5.com" #property version "1.00" #include input double MaximumRisk = 0.1; // Maximum Risk in percentage input double DecreaseFactor = 3; // Descrease factor input int MovingPeriod = 12; // Moving Average period input int MovingShift = 6; // Moving Average shift //--- input ENUM_TIMEFRAMES BaseTF = PERIOD_M1; // LC Base Period input bool LC_on = true; // LC mode ON input int LC_shift = 0; // LC shift //--- include the file with the data conversion function #include //+------------------------------------------------------------------+ //| Calculate optimal lot size | //+------------------------------------------------------------------+ double TradeSizeOptimized(void) { double price=0.0; double margin=0.0; //--- select lot size if(!SymbolInfoDouble(_Symbol,SYMBOL_ASK,price)) return(0.0); if(!OrderCalcMargin(ORDER_TYPE_BUY,_Symbol,1.0,price,margin)) return(0.0); if(margin<=0.0) return(0.0); double lot=NormalizeDouble(AccountInfoDouble(ACCOUNT_FREEMARGIN)*MaximumRisk/margin,2); //--- calculate number of losses orders without a break if(DecreaseFactor>0) { //--- select history for access HistorySelect(0,TimeCurrent()); //--- int orders=HistoryDealsTotal(); // total history deals int losses=0; // number of losses orders without a break for(int i=orders-1;i>=0;i--) { ulong ticket=HistoryDealGetTicket(i); if(ticket==0) { Print("HistoryDealGetTicket failed, no trade history"); break; } //--- check symbol if(HistoryDealGetString(ticket,DEAL_SYMBOL)!=_Symbol) continue; //--- check profit double profit=HistoryDealGetDouble(ticket,DEAL_PROFIT); if(profit>0.0) break; if(profit<0.0) losses++; } //--- if(losses>1) lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,1); } //--- normalize and check limits double stepvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP); lot=stepvol*NormalizeDouble(lot/stepvol,0); double minvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN); if(lotmaxvol) lot=maxvol; //--- return trading volume return(lot); } //+------------------------------------------------------------------+ //| Detecting new bar | //+------------------------------------------------------------------+ bool newbar(datetime t) { static datetime t_prev=0; if(t!=t_prev) { t_prev=t; return(true); } return(false); } //+------------------------------------------------------------------+ //| Check for open position conditions | //+------------------------------------------------------------------+ void CheckForOpen(void) { MqlRates rt[2]; //--- go trading only for first ticks of new bar int copied; if(LC_on==true) { int shift=LC_shift; copied=GetRatesLC(0,2,rt,BaseTF,shift); } else copied=CopyRates(_Symbol,_Period,0,2,rt); if(copied!=2) { Print("CopyRates of ",_Symbol," failed, no history"); return; } if(newbar(rt[1].time)==false) return; //--- get current Moving Average double ma[1]; if(CopyMABuffer(1,ma)!=1) { Print("CopyBuffer from iMA failed, no data"); return; } //--- check signals ENUM_ORDER_TYPE signal=WRONG_VALUE; if(rt[0].open>ma[0] && rt[0].closema[0]) signal=ORDER_TYPE_BUY; // buy conditions } //--- additional checking if(signal!=WRONG_VALUE) if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)) if(Bars(_Symbol,_Period)>100) { CTrade trade; trade.PositionOpen(_Symbol,signal,TradeSizeOptimized(), SymbolInfoDouble(_Symbol,signal==ORDER_TYPE_SELL ? SYMBOL_BID:SYMBOL_ASK),0,0); } //--- } //+------------------------------------------------------------------+ //| Check for close position conditions | //+------------------------------------------------------------------+ void CheckForClose(void) { MqlRates rt[2]; //--- go trading only for first ticks of new bar int copied; if(LC_on==true) { int shift=LC_shift; copied=GetRatesLC(0,2,rt,BaseTF,shift); } else copied=CopyRates(_Symbol,_Period,0,2,rt); if(copied!=2) { Print("CopyRates of ",_Symbol," failed, no history"); return; } if(newbar(rt[1].time)==false) return; //--- get current Moving Average double ma[1]; if(CopyMABuffer(1,ma)!=1) { Print("CopyBuffer from iMA failed, no data"); return; } //--- positions already selected before bool signal=false; long type=PositionGetInteger(POSITION_TYPE); if(type==(long)POSITION_TYPE_BUY && rt[0].open>ma[0] && rt[0].closema[0]) signal=true; //--- additional checking if(signal) if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)) if(Bars(_Symbol,_Period)>100) { CTrade trade; trade.PositionClose(_Symbol,3); } //--- } //+------------------------------------------------------------------+ //| Copying of the Moving Average buffer | //+------------------------------------------------------------------+ int CopyMABuffer(int len,double &ma[]) { if(len<=0) return(0); MqlRates rates[]; int l=len-1+MovingPeriod; int copied; if(LC_on==true) { int shift=LC_shift; ArrayResize(rates,l); copied=GetRatesLC(MovingShift,l,rates,BaseTF,shift); } else copied=CopyRates(_Symbol,_Period,MovingShift,l,rates); //--- insufficient historical data if(copied=k) { Comment("Shift specified incorrectly"); return(INIT_PARAMETERS_INCORRECT); } //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick(void) { //--- if(PositionSelect(_Symbol)) CheckForClose(); else CheckForOpen(); //--- } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { } //+------------------------------------------------------------------+