//+------------------------------------------------------------------+ //| Profit Generator 3.3.2.mq4 | //| | //| No Copyright, created 20 March 2006, Open Source | //| http://www.forex-tsd.com | //| http://www.tradingintl.com | //| | //| Freely receive, Freely give. Please post updated version. | //| Default Settings on EURUSD, GBPUSD, and USDCHF | //+------------------------------------------------------------------+ #property copyright "Created in 2006, Open Source Project" #property link "http://www.forex-tsd.com" #include <stdlib.mqh> #include <WinUser32.mqh> ///////////////////////////////////////////////////Variables////////////////////////////// extern string EAname="Pro-Gen_3"; extern int ID_BASE=100000; // Change this number if running more than one EA on the same pair extern int LongBar=15; // sets the minimum length of the bar extern double BarOpenPercent=0.50;// Set this to determine the percent of the bar which the trade takes place. extern int MaxTrades=1; //maximum number of trades open at a time extern double lots=0.1; // This number will not matter if using Money Management extern int stoploss=20,takeprofit=100; extern bool MM = true; //Use Money Management or not extern double Risk = 10; //percent of available margin to risk. extern int PairsTraded=0; //if set to 0 then std MM. If set to the number of Pairs traded then the risk is divided amongst the number of pairs. extern bool UseClose=false; // This will use the SuperClose(). extern int TSactivation=40,TrailPips=5; // TSactivation will set the point where the TS will start. extern bool UseHourTrade = false; // Time filter extern int FromHourTrade = 7; // start trading on this hour extern int ToHourTrade = 20; // end trading on this hour extern bool UseSimpleTF=false; extern int period=0; // leave this number as zero to use the period from the chart. extern bool OneTradeperPeriod=false; //This will only allow one new trade per period. extern bool Alerts=false,AlertOnlyMode=false;// Alerts will alert when trade signal is present. AOM will not place trades, but will alert to the platform extern bool WeekendMode=true;//True=Will close all trades on and after the hour to close. extern int hour_to_close=21; extern bool EMAconfirm=false; // Uses EMA direction to confirm trades. eg. If Low EMA (lower of two MAperiods)>HighEMA then the market is bearish. extern int LowEMA=10;// lower of EMA TF extern int HighEMA=16;// higher of EMA TF extern int EMAtf=0;// if 0 then it uses the chart TF, otherwise it will use the period based on period settings. extern bool UseStoOpen=false; extern int StoTF=1; extern bool Reverse=true;// reverses orders regardless of ALL signal direction extern bool UseObsoleteMethod=True; extern bool OMwhenLossOnly=false; extern int ObsoleteMinutes=10; extern bool Use50maFilter=true; extern int MApips=10; extern bool UseTE=false; extern int badtrades=2; extern int ReEnter=2; string xname,start; int ID; int bar;//tracks the period where a trade was placed. double Hi, Lo, Op; int tsTicket[21]; double tsPrice[21]; bool tsok[21]; bool lopen,sopen; int TEticket[40]; double TEpips[40]; int TEtype[40]; double TEopen[40]; bool TEclosed[40]; datetime ot; //bool hedged; bool bad; ////////////////////////////////////////////////////////////////////////////////////////////// int init(){ ID=ID_BASE+P(period); start=TimeToStr(CurTime(),TIME_DATE|TIME_SECONDS); xname=EAname+"_"+DoubleToStr(ID,0); // Comment("\n",xname," started @ ",start,"\n","Floating P&L: ",profit(),"\n",presentpos()); ot=CurTime(); } /////////////START FUNCTION///////////////////START FUNCTION//////////////////////START FUNCTION///// int CheckOpen(int f){ if(lopen){ stoopen(1); return; } if(sopen){ stoopen(2); return; } double lwma=iMA(NULL,0,50,0,MODE_LWMA,MODE_CLOSE,0); int x=0; Hi = iHigh(NULL, P(period), x); Lo = iLow (NULL, P(period), x); Op = iOpen(NULL, P(period), x); //Print("CHECKOPEN()"); // Print(Hi, ",", Lo); // This shows how the value of hi and lo changes during the day // Comment("if (",(Hi-Lo)," > ",LongBar*Point," && ",Op," < ",Hi+Lo/2," && ",Ask," < ",Op); if( (Hi-Lo > LongBar*Point && Op < baropen(1) && Ask < Op) && ( !EMAconfirm || EMA(1,P(EMAtf))> EMA(2,P(EMAtf)) )&& (!Use50maFilter || Ask > lwma+MApips*Point) ){ if(f==1){ if(!UseStoOpen){ openorder(1); }else{ lopen=true; stoopen(1); } } else if(f==2){ return(1); } } else if( (Hi-Lo > LongBar*Point && Op > baropen(2)&& Bid > Op) && ( !EMAconfirm || EMA(1,P(EMAtf))< EMA(2,P(EMAtf)) ) && (!Use50maFilter || Bid < lwma-MApips*Point) ){ // Print("shrtOPEN"); if(f==1){ if(!UseStoOpen){ openorder(2); }else{ sopen=true; stoopen(2); } } else if(f==2){ return(2); } } // Comment(Hi-Lo," > ",LongBar*Point," && ",Op," > ",baropen(2)," && ",Bid," > ",Op); return(0); } ////////////////////////////////////////////////////////////////////////////////////////////// double baropen(int t){ double barpr; if(t==1){ barpr= Lo + (Hi-Lo) * BarOpenPercent; // Print("Lo ",Lo," + ",(Hi-Lo) * BarOpenPercent / 100); } else if(t==2){ barpr= Hi - (Hi-Lo) * BarOpenPercent; } return(barpr); } ////////////////////////////////////////////////////////////////////////////////////////////// void stoopen(int t){ double sto1,sto2; sto1=iStochastic(NULL,P(StoTF),5,3,3,MODE_SMA,0,MODE_MAIN,0); sto2=iStochastic(NULL,P(StoTF),5,3,3,MODE_SMA,0,MODE_SIGNAL,0); Print("stoopen() ",sto1, " " , sto2); if( t==1 ){ if(sto1>sto2){ openorder(1); Print("open order on sto"); } } else if( t==2 ){ if(sto1<sto2){ openorder(2); Print("open order on sto"); } } } ///////////////////////////////////////////////////////////////////////////////////////////// int okp(string sym){ int ret; for(int i=0;i<OrdersTotal();i++){ if(OrderSelect(i,SELECT_BY_POS)){ if(OrderMagicNumber()==ID){ if(OrderSymbol()==sym){ if(OrderType()==OP_BUY)ret=1; else if(OrderType()==OP_SELL)ret=2; } } } } return(ret); } bool CMC(string sym,int t){ if(sym=="EURUSD"){ if( okp("GBPUSD") != t && okp("GBPUSD")!=0)return(false); if( okp("USDCHF") ==t && okp("USDCHF")!=0)return(false); } else if(sym=="GBPUSD"){ if( okp("EURUSD") != t && okp("EURUSD")!=0)return(false); if( okp("USDCHF") ==t && okp("USDCHF")!=0)return(false); } else if(sym=="USDCHF"){ if( okp("EURUSD") == t && okp("EURUSD")!=0)return(false); if( okp("GBPUSD") ==t && okp("GPBUSD")!=0)return(false); } return(true); } void openorder(int f){ double sl,tp;int res; //string comm="Pro-Gen_"+DoubleToStr(ID,0); if( !CMC(Symbol(),f) )return; if( MM ) lots = LotSize(); if(Reverse){ if(f==1)f=2; else if(f==2)f=1; } if(f==2){ while(res<=0){ if(stoploss==0){sl=0;}else{sl=Bid+stoploss*Point;} if(takeprofit==0){tp=0;}else{tp=Bid-takeprofit*Point;} if(UseClose)tp=Bid-(takeprofit*2)*Point; if(!AlertOnlyMode){ res=OrderSend(Symbol(),OP_SELL,lots,Bid,2,sl,tp,xname,ID,0,Red); } if(res<=0){ int error=GetLastError(); Print("Error = ",ErrorDescription(error)); if(error==134)break; Sleep(1000); RefreshRates(); } } if(Alerts || AlertOnlyMode){ Alert("PG Short Signal on ",Symbol()); } lopen=false;sopen=false; bar=iBars(NULL,P(period)); } else if(f==1){ while(res<=0){ if(stoploss==0){sl=0;}else{sl=Ask-stoploss*Point;} if(takeprofit==0){tp=0;}else{tp=Ask+takeprofit*Point;} if(UseClose)tp=Ask+(takeprofit*2)*Point; if(!AlertOnlyMode){ res=OrderSend(Symbol(),OP_BUY,lots,Ask,2,sl,tp,xname,ID,0,Blue); } if(res<=0){ error=GetLastError(); Print("Error = ",ErrorDescription(error)); if(error==134)break; Sleep(1000); RefreshRates(); } } if(Alerts || AlertOnlyMode){ Alert("PG Long Signal on ",Symbol()); } lopen=false;sopen=false; bar=iBars(NULL,P(period)); } } ////////////////////////////////////////////////////////////////////////////////////////////// void CloseOrder(int ord){ bool res; if (ord==1){ while(!res){ res = OrderClose(OrderTicket(),OrderLots(),Bid,3,White); // close if(!res){ int error=GetLastError(); Print("Error = ",ErrorDescription(error)); if(error!=135)break; else if(error==135){ Sleep(1000); RefreshRates(); } } } } if (ord==2) { while(!res){ // MA BUY signals res = OrderClose(OrderTicket(),OrderLots(),Ask,3,White); // close if(!res){ error=GetLastError(); Print("Error = ",ErrorDescription(error)); if(error!=135)break; else if(error==135){ Sleep(1000); RefreshRates(); } } } } } ////////////////////////////////////////////////////////////////////////////////////////////// int P(int peri){ //added the ability to control PeriodTF for different functions. if(!UseSimpleTF) { if(peri==0) return(Period()); else return(peri); } if(UseSimpleTF) { if(peri==0) return(Period()); if(peri==1) return(1);//M1 if(peri==2) return(5);//M5 if(peri==3) return(15);//M15 if(peri==4) return(30);//M30 if(peri==5) return(60);//H1 if(peri==6) return(240);//H4 if(peri==7) return(1440);//Daily if(peri==8) return(10080);//weekly if(peri==9) return(43200);//monthly return(Period()); } } ////////////////////////////////////////////////////////////////////////////////////////////// int orderscnt(){ int cnt=0; for(int i =0;i<OrdersTotal();i++){ if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)){ if(OrderSymbol()==Symbol() && ID==OrderMagicNumber()){ cnt++; } } } return(cnt); } ////////////////////////////////////////////////////////////////////////////////////////////// void CloseAllTrades(){ Print("CloseAllTrades()"); for(int i =0;i<OrdersTotal();i++){ if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)){ if(OrderSymbol()==Symbol() && ID==OrderMagicNumber()){ if(OrderType()==OP_BUY){ CloseOrder(1); }else{ CloseOrder(2); } } } } } ////////////////////////////////////////////////////////////////////////////////////////////// double LotSize(){ double lotMM; if(PairsTraded==0){ lotMM = MathCeil(AccountFreeMargin() * Risk / 10000) / 10; } else { lotMM = MathCeil(AccountFreeMargin() * Risk / 10000 /PairsTraded) / 10 ; } if (lotMM < 0.1) lotMM = lots; if (lotMM > 1.0) lotMM = MathCeil(lotMM); if (lotMM > 100) lotMM = 100; return (lotMM); } ////////////////////////////////////////////////////////////////////////////////////////////// void SuperClose(){ for(int i=0;i<OrdersTotal();i++){ if(OrderSelect(i,SELECT_BY_POS)){ if(OrderSymbol()==Symbol() && OrderMagicNumber()==ID){//Pulls in order that meets the criteria for processing int num=0;int pos=0; for(int b=0;b<21;b++){// this (loopB) compares the ticket# of the selected order against the number stored in the ticket array if(tsTicket[b]==OrderTicket() ){ num++; pos=b;// if ticket numbers match, pos is the position in the array where the trailing data is stored //Print("(",pos,") Ticket ",tsTicket[pos]," found. SL is ",tsPrice[pos]); break; } } if(num==0){ // if the loopB did not find a matching ticket number it is time to initialize the data for(int j=0;j<21;j++){ if(tsTicket[j]==0){// this is looking for the earliest instance within the array to store the data pos=j; break; } } tsTicket[pos]=OrderTicket();// setting the ticket number tsok[pos]=false;// this is to determine when trailing kicks in Print("(",pos,") New ticket initialized = ",tsTicket[pos]); } if (OrderType()==OP_SELL) { if (!tsok[pos] && (OrderOpenPrice()-Ask>=TSactivation*Point || TSactivation==0 ) ) {// if the trailing factor is false, but it has hit the activation point continue tsPrice[pos]=Ask+TrailPips*Point;// this is the new trailinf stop price tsok[pos]=true;// it's ok to proceed with trailing stop if(TrailPips>8){// if this distance from the current price to the new stop, then modify the order. ModifyStopLoss(Ask+TrailPips*Point);//modifies order } } if (tsok[pos] && Ask+TrailPips*Point < tsPrice[pos] ){//if the position is gaining in profit tsPrice[pos]=Ask+TrailPips*Point; if(TrailPips>8){ ModifyStopLoss(Ask+TrailPips*Point); } } if (tsok[pos] && Ask >= tsPrice[pos] ){// if the postion hits the stop price CloseOrder(2); Print("Short Order ",tsTicket[pos]," Closed from TS"); } } if (OrderType()==OP_BUY) {// reverse of SELL if(!tsok[pos] && (Bid-OrderOpenPrice() >= TSactivation*Point || TSactivation==0 ) ) { tsPrice[pos]=Bid-TrailPips*Point; tsok[pos]=true; if(TrailPips>8){ ModifyStopLoss(Bid-TrailPips*Point); } } if (tsok[pos] && Bid-TrailPips*Point > tsPrice[pos] ){ tsPrice[pos]=Bid-TrailPips*Point; if(TrailPips > 8){ ModifyStopLoss(Bid-TrailPips*Point); } } if (tsok[pos] && Bid <= tsPrice[pos] ){ CloseOrder(1); Print("Long Order ",tsTicket[pos]," Closed from TS"); } } } } } for(i=0;i<21;i++){// this searches the array for ticket numbers that are now obsolete due to an order that has closed if(tsTicket[i]>0){ bool found=false; for(b=0;b<OrdersTotal();b++){ OrderSelect(b,SELECT_BY_POS); if(tsTicket[i]==OrderTicket()){ found=true; break; } } if(!found){// if there are matching ticket numbers in the trade pool and the array then nothing happens tsTicket[i]=0;tsPrice[i]=0;tsok[i]=false;// if there is an obolete ticket the the data is reset. And the next new ticket data can occupy this space // Print("Array pos ",i," Cleaned"); } } } } ////////////////////////////////////////////////////////////////////////////////////////////// void ModifyStopLoss(double ldStop) { bool fm; double ldOpen=OrderOpenPrice(); double ldTake=OrderTakeProfit(); fm=OrderModify(OrderTicket(), ldOpen, ldStop, ldTake, 0, Pink); } void sada(){ for(int i=0;i<OrdersTotal();i++){ if(OrderSelect(i,SELECT_BY_POS)){ if(OrderSymbol()==Symbol() && OrderMagicNumber()==ID){ if(CurTime()-OrderOpenTime() >= ObsoleteMinutes * 60){ if(!OMwhenLossOnly || OrderProfit()<0){ if(OrderType()==OP_BUY){ if(CheckOpen(2)==2){ CloseOrder(1); openorder(2); Print("Order Swap due to sada"); } } else if(OrderType()==OP_SELL){ if(CheckOpen(2)==1){ CloseOrder(2); openorder(1); Print("Order Swap due to sada"); } } } } } } } } ////////////////////////////////////////////////////////////////////////////////////////////// /* string profit(){ double pro; for(int i =0;i<OrdersTotal();i++){ if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)){ if(ID==OrderMagicNumber()){ pro=pro+OrderProfit(); } } } return(DoubleToStr(pro,2)); }*/ ////////////////////////////////////////////////////////////////////////////////////////////// double EMA(int Length1,int per){ if(Length1==1)int L=LowEMA; else if(Length1==2)L=HighEMA; return(iMA(Symbol(),per,L,0,MODE_EMA,PRICE_CLOSE,1)); } ////////////////////////////////////////////////////////////////////////////////////////////// /* string presentpos(){ string pp;int cnt; static double h[30]; for(int i =0;i<OrdersTotal();i++){ if(OrderSelect(i,SELECT_BY_POS)){ if(ID==OrderMagicNumber()){ cnt++; if(OrderProfit()> h[i]){ string dir=" ( UP ) "; }else if(OrderProfit()< h[i]){ dir=" ( DN ) "; } pp=pp+"\n"+OrderSymbol()+" ("+DoubleToStr(OrderProfit(),2)+")"+dir; h[i]=OrderProfit(); } } } if(cnt>0){ return(pp); }else{ return("\n"+"No Open Trades"); } } */ ////////////////////////////////////////////////////////////////////////////////////////////// bool WE(){ if(orderscnt()>0){ if(DayOfWeek()>=5 && Hour()>=hour_to_close){ CloseAllTrades(); return(true); } }else{ if(DayOfWeek()>=5 && Hour()>=hour_to_close -2){ return(true); } } return(false); } //////////////////////////////////////////////////////////////////////////////////////////////////// // Nicholishen nick@barker.net ///////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////// // // //////////////////////////////////////////////////////////////////////////////////////////////////// //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~TRADE EMULATION~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void TE(){ if(!TE1()){ if( 1==1)TEnew(1); else if( CheckOpen(2)==2) TEnew(2); } } bool TE1(){ bool ok=false;double sl; if(UseClose && TSactivation!=0)sl=TSactivation;else sl=stoploss; for(int i=0;i<200;i++){ if(TEticket[i]!=0 && !TEclosed[i]){ ok=true; if(TEtype[i]==1){ TEpips[i]=Bid-TEopen[i]; if(TEopen[i]-Bid>=sl*Point){TEclosed[i]=true;Print("TE trade closed from SL (",TEpips[i],")");Comment("");} if(Bid-TEopen[i]>=takeprofit*Point){TEclosed[i]=true;Print("TE trade closed from TP (",TEpips[i],")");Comment("");} } if(TEtype[i]==2){ TEpips[i]=TEopen[i]-Ask; if(Ask-TEopen[i]>=sl*Point){TEclosed[i]=true;Print("TE trade closed from SL (",TEpips[i],")");} if(TEopen[i]-Ask>=takeprofit*Point){TEclosed[i]=true;Print("TE trade closed from SL (",TEpips[i],")");} } Comment("\n","TE Open Order: ",TEtype[i]," Tkt ",TEticket[i]," Profit ",TEpips[i]); } } if(ok)return(true); return(false); } void TEnew(int t){ static int cnt;int pos; for(int i=0;i<40;i++){ if(TEticket[i]==0){pos=i;break;} } cnt++; TEticket[pos]=cnt; if(t==1){TEtype[pos]=1;TEopen[pos]=Ask;} else if(t==2){TEtype[pos]=2;TEopen[pos]=Bid;} } int TEprocnt(){ int total; for(int i=39;i>=0;i--){ if(TEticket[i]>0){ if(TEpips[i]>0 && TEclosed[i])total++; if(TEpips[i]<0 && TEclosed[i])total=0; } } return(total); } void TEpurge(){ for(int i=0;i<40;i++){ TEticket[i]=0; TEpips[i]=0; TEtype[i]=0; TEopen[i]=0; TEclosed[i]=false; ot=CurTime(); bad=false; } } int BadTrades(){ for(int i=HistoryTotal();i>=0;i--){ if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)){ if(OrderSymbol()==Symbol() && OrderMagicNumber()==ID){ if(OrderOpenTime()>ot){ if(OrderProfit()>0)int tr=0; if(OrderProfit()<0)tr++; } } } } return(tr); } //////////////START FUNCTION//////////////////START FUNCTION//////////////////START FUNCTION/////// int start(){ int rderscnt=orderscnt(); if( WeekendMode ){ if( WE() )return(0); } if( UseClose ){ if(rderscnt>0)SuperClose(); } if( UseHourTrade ){ if((( FromHourTrade <= ToHourTrade ) && ( Hour() < FromHourTrade || Hour() > ToHourTrade )) || // Allow for Overnight Trading (( FromHourTrade > ToHourTrade ) && ( Hour() < FromHourTrade && Hour() > ToHourTrade )) ) { return(0); } } if(rderscnt==0){ if(UseTE){ if(BadTrades()>=badtrades){ if(TEprocnt()>=ReEnter){TEpurge();return(0);} TE(); bad=true; } } } if(!bad && (rderscnt<MaxTrades) && (!OneTradeperPeriod || bar!=iBars(NULL,P(period))) ){ // openorder(1); CheckOpen(1); } if( UseObsoleteMethod ){ sada(); } } //////////////////////////
Sample
Analysis
Market Information Used:
Series array that contains the highest prices of each bar
Series array that contains open prices of each bar
Indicator Curves created:
Indicators Used:
Moving average indicator
Stochastic oscillator
Custom Indicators Used:
Order Management characteristics:
Checks for the total of open orders
It automatically opens orders when conditions are reached
It Closes Orders by itself
It can change open orders parameters, due to possible stepping strategy
Other Features:
It issuies visual alerts to the screen