//+------------------------------------------------------------------+ //| | //| LSMA_EA | //| | //| Written by Robert Hill aka MrPip for StrategyBuilder FX group | //| | //+------------------------------------------------------------------+ #property copyright "Robert Hill" #property link "None" #include <stdlib.mqh> extern string Expert_Name = "LSMA_EA"; extern int MagicNumberBase = 200000; extern string UserComment = "LSMA_EA"; extern string in="---Indicator settings---"; extern string p = "--Applied Price Types--"; extern string p0 = " 0 = close"; extern string p1 = " 1 = open"; extern string p2 = " 2 = high"; extern string p3 = " 3 = low"; extern string p4 = " 4 = median(high+low)/2"; extern string p5 = " 5 = typical(high+low+close)/3"; extern string p6 = " 6 = weighted(high+low+close+close)/4"; extern int LSMA_Period=7; extern int LSMA_AppliedPrice = 0; extern double EntryDif_Threshold=10; // What size angle to trigger a trade extern double ExitDif_Threshold=2; extern int PrevMAShift=3; extern int CurMAShift=1; //+---------------------------------------------------+ //|Money Management | //+---------------------------------------------------+ extern string mm = "---Money Management---"; extern double Lots=1.0; extern double MaxLots = 100; extern bool UseMoneyManagement = true; // Change to false to shutdown money management controls. extern bool BrokerIsIBFX = false; extern string m1="Set mini and micro to false for standard account"; extern bool AccountIsMini = false; extern bool AccountIsMicro = false; extern string fm="UseFreeMargin = false to use Account Balance"; extern bool UseFreeMargin = false; extern double TradeSizePercent = 10; // Change to whatever percent of equity you wish to risk. extern bool BrokerPermitsFractionalLots = true; //+---------------------------------------------------+ //|Profit controls | //+---------------------------------------------------+ extern string st6 = "--Profit Controls--"; extern double StopLoss=0; extern double TakeProfit=0; extern int Slippage=3; extern string db0="---Flag to run start once per bar---"; extern string db1=" Set to false when using stoploss"; extern string db2=" takeprofit or trailing stop"; extern bool UseOncePerBar = true; //+---------------------------------------------------+ //|General controls | //+---------------------------------------------------+ int MagicNumber=0; string setup; int TradesInThisSymbol = 0; double mLots=0; datetime timeprev = 0; //+---------------------------------------------------+ //| Indicator values for signals and filters | //| Add or Change to test your system | //+---------------------------------------------------+ //+------------------------------------------------------------------+ //| Calculate MagicNumber, setup comment and assign RSI Period | //| | //+------------------------------------------------------------------+ int init() { MagicNumber = MagicNumberBase + func_Symbol2Val(Symbol())*100 + func_TimeFrame_Const2Val(Period()); setup=Expert_Name + Symbol() + "_" + func_TimeFrame_Val2String(func_TimeFrame_Const2Val(Period())); setup = UserComment; return(0); } int deinit() { return(0); } //+------------------------------------------------------------------------+ //| LSMA - Least Squares Moving Average function calculation | //| LSMA_In_Color Indicator plots the end of the linear regression line | //+------------------------------------------------------------------------+ double LSMA(int Rperiod, int prMode, int shift) { int i, myShift; double sum, pr; int length; double lengthvar; double tmp; double wt; length = Rperiod; sum = 0; for(i = length; i >= 1 ; i--) { lengthvar = length + 1; lengthvar /= 3; tmp = 0; myShift = length - i + shift; switch (prMode) { case 0: pr = iClose(NULL,0,myShift);break; case 1: pr = iOpen(NULL,0,myShift);break; case 2: pr = iHigh(NULL,0,myShift);break; case 3: pr = iLow(NULL,0,myShift);break; case 4: pr = (iHigh(NULL,0,myShift) + iLow(NULL,0,myShift))/2;break; case 5: pr = (iHigh(NULL,0,myShift) + iLow(NULL,0,myShift) + iClose(NULL,0,myShift))/3;break; case 6: pr = (iHigh(NULL,0,myShift) + iLow(NULL,0,myShift) + iClose(NULL,0,myShift) + iClose(NULL,0,myShift))/4;break; } tmp = ( i - lengthvar)*pr; sum+=tmp; } wt = sum*6/(length*(length+1)); wt = MathFloor(wt/Point)*Point; return(wt); } double MA_Dif( int PrevShift, int CurShift) { double fDif, mFactor; double fCurMA, fPrevMA; string Sym; int ShiftDif; mFactor = 100000.0; Sym = StringSubstr(Symbol(),3,3); if (Sym == "JPY") mFactor = 1000.0; ShiftDif = PrevShift-CurShift; mFactor /= ShiftDif; fCurMA=LSMA(LSMA_Period,LSMA_AppliedPrice,CurShift); fPrevMA=LSMA(LSMA_Period,LSMA_AppliedPrice,PrevShift); fDif = mFactor * (fCurMA - fPrevMA)/2.0; return(fDif); } //+------------------------------------------------------------------+ //| CheckExitCondition | //| Check if AngleSep cross 0 line | //+------------------------------------------------------------------+ bool CheckExitCondition(int cmd) { double maDif; maDif = MA_Dif(PrevMAShift, CurMAShift); switch (cmd) { case OP_BUY : if (maDif < ExitDif_Threshold) return(true); break; case OP_SELL : if (maDif > -ExitDif_Threshold) return(true); } return(false); } //+------------------------------------------------------------------+ //| CheckEntryCondition | //| Check if separation on LSMA pair | //+------------------------------------------------------------------+ bool CheckEntryCondition(int cmd) { double maDif; maDif = MA_Dif(PrevMAShift, CurMAShift); switch (cmd) { case OP_BUY : if (maDif > EntryDif_Threshold) return(true); break; case OP_SELL : if (maDif < -EntryDif_Threshold) return(true); } return(false); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Start | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ int start() { // Only run once per completed bar if (UseOncePerBar == true) { if(timeprev==Time[0]) return(0); timeprev = Time[0]; } //+------------------------------------------------------------------+ //| Check for Open Position | //+------------------------------------------------------------------+ HandleOpenPositions(); // Check if any open positions were not closed TradesInThisSymbol = CheckOpenPositions(); // Only allow 1 trade per Symbol if(TradesInThisSymbol > 0) { return(0);} mLots = GetLots(); if(CheckEntryCondition(OP_BUY) == true) { OpenBuyOrder(mLots, StopLoss,TakeProfit, Slippage, setup, MagicNumber, Green); return(0); } if(CheckEntryCondition(OP_SELL) == true) { OpenSellOrder(mLots, StopLoss,TakeProfit, Slippage, setup, MagicNumber, Red); } return(0); } //+------------------------------------------------------------------+ //| Get number of lots for this trade | //+------------------------------------------------------------------+ double GetLots() { double lot; if(UseMoneyManagement == true) { lot = LotsOptimized(); } else { lot = Lots; } // Use at least 1 micro lot if (AccountIsMicro == true) { if (lot < 0.01) lot = 0.01; if (lot > MaxLots) lot = MaxLots * 100; if (BrokerIsIBFX == true) lot = lot * 10; return(lot); } // Use at least 1 mini lot if(AccountIsMini == true) { if (lot < 0.1) lot = 0.1; if (lot > MaxLots) lot = MaxLots; if (BrokerIsIBFX == true) lot = lot * 10; return(lot); } // Standard account if( BrokerPermitsFractionalLots == false) { if (lot >= 1.0) lot = MathFloor(lot); else lot = 1.0; } if (lot > MaxLots) lot = MaxLots; return(lot); } //+------------------------------------------------------------------+ //| Calculate optimal lot size | //+------------------------------------------------------------------+ double LotsOptimized() { double lot=Lots; //---- select lot size if (UseFreeMargin == true) lot=NormalizeDouble(MathFloor(AccountFreeMargin()*TradeSizePercent/10000)/10,1); else lot=NormalizeDouble(MathFloor(AccountBalance()*TradeSizePercent/10000)/10,1); // Check if mini or standard Account if(AccountIsMini == true) { lot = MathFloor(lot*10)/10; } return(lot); } //+------------------------------------------------------------------+ //| OpenBuyOrder | //| If Stop Loss or TakeProfit are used the values are calculated | //| for each trade | //+------------------------------------------------------------------+ int OpenBuyOrder(double mLots, double mStopLoss, double mTakeProfit, int mSlippage, string mComment, int mMagic, color mColor) { int err,ticket; double myPrice, myStopLoss = 0, myTakeProfit = 0; RefreshRates(); myStopLoss = StopLong(Bid,mStopLoss); myTakeProfit = TakeLong(Bid,mTakeProfit); // Normalize all price / stoploss / takeprofit to the proper # of digits. if (Digits > 0) { myPrice = NormalizeDouble( Ask, Digits); myStopLoss = NormalizeDouble( myStopLoss, Digits); myTakeProfit = NormalizeDouble( myTakeProfit, Digits); } ticket=OrderSend(Symbol(),OP_BUY,mLots,myPrice,mSlippage,myStopLoss,myTakeProfit,mComment,mMagic,0,mColor); if (ticket > 0) { if (OrderSelect( ticket,SELECT_BY_TICKET, MODE_TRADES) ) { Print("BUY order opened : ", OrderOpenPrice( )); // ModifyOrder(ticket,OrderOpenPrice( ), OrderStopLoss(), myTakeProfit); } } else { err = GetLastError(); if(err==0) { return(ticket); } else { if(err==4 || err==137 ||err==146 || err==136) //Busy errors { Sleep(5000); } else //normal error { Print("Error opening BUY order [" + setup + "]: (" + err + ") " + ErrorDescription(err)); } } } return(ticket); } //+------------------------------------------------------------------+ //| OpenSellOrder | //| If Stop Loss or TakeProfit are used the values are calculated | //| for each trade | //+------------------------------------------------------------------+ void OpenSellOrder(double mLots, double mStopLoss, double mTakeProfit, int mSlippage, string mComment, int mMagic, color mColor) { int err, ticket; double myPrice, myStopLoss = 0, myTakeProfit = 0; RefreshRates(); myStopLoss = StopShort(Ask,mStopLoss); myTakeProfit = TakeShort(Ask,mTakeProfit); // Normalize all price / stoploss / takeprofit to the proper # of digits. if (Digits > 0) { myPrice = NormalizeDouble( Bid, Digits); myStopLoss = NormalizeDouble( myStopLoss, Digits); myTakeProfit = NormalizeDouble( myTakeProfit, Digits); } ticket=OrderSend(Symbol(),OP_SELL,mLots,myPrice,mSlippage,myStopLoss,myTakeProfit,mComment,mMagic,0,mColor); if (ticket > 0) { if (OrderSelect( ticket,SELECT_BY_TICKET, MODE_TRADES) ) { Print("Sell order opened : ", OrderOpenPrice()); // ModifyOrder(ticket,OrderOpenPrice( ), OrderStopLoss(), myTakeProfit); } } else { err = GetLastError(); if(err==0) { return(ticket); } else { if(err==4 || err==137 ||err==146 || err==136) //Busy errors { Sleep(5000); } else //normal error { Print("Error opening Sell order [" + mComment + "]: (" + err + ") " + ErrorDescription(err)); } } } return(ticket); } double StopLong(double price,int stop) { if(stop==0) return(0); else return(price-(stop*Point)); } double StopShort(double price,int stop) { if(stop==0) return(0); else return(price+(stop*Point)); } double TakeLong(double price,int take) { if(take==0) return(0); else return(price+(take*Point)); } double TakeShort(double price,int take) { if(take==0) return(0); else return(price-(take*Point)); } //+------------------------------------------------------------------+ //| Handle Open Positions | //| Check if any open positions need to be closed or modified | //+------------------------------------------------------------------+ int HandleOpenPositions() { int cnt; for(cnt=OrdersTotal()-1;cnt>=0;cnt--) { OrderSelect (cnt, SELECT_BY_POS, MODE_TRADES); if ( OrderSymbol() != Symbol()) continue; if ( OrderMagicNumber() != MagicNumber) continue; if(OrderType() == OP_BUY) { if (CheckExitCondition(OP_BUY) == true) { CloseOrder(OrderTicket(),OrderOpenPrice(),OrderLots(),OP_BUY); } } if(OrderType() == OP_SELL) { if (CheckExitCondition(OP_SELL) == true) { CloseOrder(OrderTicket(),OrderOpenPrice(), OrderLots(),OP_SELL); } } } } //+------------------------------------------------------------------+ //| Check Open Position Controls | //+------------------------------------------------------------------+ int CheckOpenPositions() { int cnt, total; int NumTrades; NumTrades = 0; total=OrdersTotal(); for(cnt=OrdersTotal()-1;cnt>=0;cnt--) { OrderSelect (cnt, SELECT_BY_POS, MODE_TRADES); if ( OrderSymbol() != Symbol()) continue; if ( OrderMagicNumber() != MagicNumber) continue; if(OrderType() == OP_BUY ) NumTrades++; if(OrderType() == OP_SELL ) NumTrades++; } return (NumTrades); } int CloseOrder(int ticket, double op, double numLots,int cmd) { int CloseCnt, err, digits; double myPrice; string olStr, bidStr, askStr; RefreshRates(); if (cmd == OP_BUY) myPrice = Bid; if (cmd == OP_SELL) myPrice = Ask; if (Digits > 0) myPrice = NormalizeDouble( myPrice, Digits); olStr = DoubleToStr(numLots,2); bidStr = DoubleToStr(Bid, Digits); askStr = DoubleToStr(Ask, Digits); // try to close 3 Times CloseCnt = 0; while (CloseCnt < 3) { if (OrderClose(ticket,numLots,myPrice,Slippage,Violet) == false) { err=GetLastError(); Print(CloseCnt," Error closing order : (", err , ") " + ErrorDescription(err)); if (err > 0) CloseCnt++; } else { CloseCnt = 3; } } } int func_Symbol2Val(string symbol) { string mySymbol = StringSubstr(symbol,0,6); if(mySymbol=="AUDCAD") return(1); if(mySymbol=="AUDJPY") return(2); if(mySymbol=="AUDNZD") return(3); if(mySymbol=="AUDUSD") return(4); if(mySymbol=="CHFJPY") return(5); if(mySymbol=="EURAUD") return(6); if(mySymbol=="EURCAD") return(7); if(mySymbol=="EURCHF") return(8); if(mySymbol=="EURGBP") return(9); if(mySymbol=="EURJPY") return(10); if(mySymbol=="EURUSD") return(11); if(mySymbol=="GBPCHF") return(12); if(mySymbol=="GBPJPY") return(13); if(mySymbol=="GBPUSD") return(14); if(mySymbol=="NZDJPY") return(15); if(mySymbol=="NZDUSD") return(16); if(mySymbol=="USDCAD") return(17); if(mySymbol=="USDCHF") return(18); if(mySymbol=="USDJPY") return(19); Comment("unexpected Symbol"); return(999); } //+------------------------------------------------------------------+ //| Time frame interval appropriation function | //+------------------------------------------------------------------+ int func_TimeFrame_Const2Val(int Constant ) { switch(Constant) { case 1: // M1 return(1); case 5: // M5 return(2); case 15: return(3); case 30: return(4); case 60: return(5); case 240: return(6); case 1440: return(7); case 10080: return(8); case 43200: return(9); } } //+------------------------------------------------------------------+ //| Time frame string appropriation function | //+------------------------------------------------------------------+ string func_TimeFrame_Val2String(int Value ) { switch(Value) { case 1: // M1 return("PERIOD_M1"); case 2: // M1 return("PERIOD_M5"); case 3: return("PERIOD_M15"); case 4: return("PERIOD_M30"); case 5: return("PERIOD_H1"); case 6: return("PERIOD_H4"); case 7: return("PERIOD_D1"); case 8: return("PERIOD_W1"); case 9: return("PERIOD_MN1"); default: return("undefined " + Value); } } //+------------------------------------------------------------------+
Sample
Analysis
Market Information Used:
Series array that contains close prices for each bar
Series array that contains open prices of each bar
Series array that contains the highest prices of each bar
Series array that contains the lowest prices of each bar
Series array that contains open time of each bar
Indicator Curves created:
Indicators Used:
Custom Indicators Used:
Order Management characteristics:
It automatically opens orders when conditions are reached
Checks for the total of open orders
It Closes Orders by itself
Other Features: