//Phoenix 6 License information: //Not Commercial use defined by QPL Open Source License. //Contact PhoenixFund for Commercial License. Derivative works must also be QPL. //Unless alternatively licensed by copyright holder, no commercial derivative works may exist. //+------------------------------------------------------------------+ #property copyright "Copyright PhoenixFund under QPL License. www.bestforextools.com/pf/" // Constants used in the Signals section #define Buy +1 #define Sell -1 #define None 0 // Constant used in T2_SendTrade for ordersend. #define Failed -1 //************* User Variables ******************// extern string C_TradeManage = "===== Trade Management Settings ====="; int U_maxtrades = 1; extern int P_ConsecSignals = 10; bool U_SignalResetOnBlank = false; extern string U_Trade_CURRENCY = "USDCHF"; //Currency pair to be traded extern string U_Trade_Per = "M15"; //TimeFrame, use the labels from the MT4 buttons #define AcceptSlip 2 extern int StaticTP = 40; //Take Profit extern int StaticSL = 40; //Stop Loss extern string C_Function_Y = "====== Lotsize Money Management ====="; extern double U_Lots = 1; //Money management will override setting double U_MinLot = 0.01; //Set to be micro safe by default extern double U_MaxLot = 90.0; //Set to previous max value by default bool U_ConfirmSignal1On = false; //Will double lotsize if S&R lines near. extern bool U_MoneyManage = true; //Money management for lot sizing extern double U_MaxRisk = 0.1; //Percentage of FreeMargin for trade int U_DecreaseFactor = 0; //6 digit number, 2 digits per subsequent loss 805010= 80% 50% 10% extern string C_Function_X1 = "====== Exit Management ====="; extern bool E_ExitStaticTSOn = true; //Enable static trailing stops extern bool E_ExitParaTSOn = false; //Enable Parabolic SAR exit - in progress still extern int StaticTS = 5; //If staticTS is enabled, use this pip value for TS int E_MoveTPonTS =1; //increase Trailing stop by this value in pips each time TS is adjusted. Allows good trades to rise higher bool TSConstrictOn = false; //code currently broken extern int E_DelayTS = 35; //pips to wait before activating trailing stop extern int E_BE_SL = 16; //Pips in profit to enable a Break Even SL extern int E_BE_Profit = 8; //If 0, this sets trade to BE. If a number, this sets the number of pips in profit to lock in int E_RecrossMax =0; //Not multitrade safe :/ 0 disables setting. Multitrade safe needs an array of ticket numbers? int recrosscount, bcRecross; int minStop; //Pulled from broker in init(), minimal TS value string C_Function_X = "====== Exit Grace Functionality ======"; int E_GraceHours = 0; //Setting of 0 disables, 24 = 24 hours Daraknor 5.6.6 int E_ForceHours = 0; //Setting of 0 disables, 48 = 48 hours Darankor 5.6.6 int E_GraceTS = 5; //Trailing stop in pips to use during Grace Exit: should be small extern string C_SignalA = "====== Signals Enabled ================="; int P_signalsRequired = 3; //Now calculated on init extern bool P_EntrySignal1On = true; //These settings turn on/off different signals. extern bool P_EntrySignal2On = true; // Editing these settings is not necessary or recommended extern bool P_EntrySignal3On = true; // when Phoenix is being optimized. New strategies require extern bool P_EntrySignal4On = true; // changes to the signals that are executed. extern bool P_EntrySignal5On = false; extern bool P_EntrySignal6On = false; extern bool P_EntryFilter1On = true; //Enabling these settings reduces the number of trades extern bool P_EntryFilter2On = true; extern bool P_EntryFilter3On = true; extern bool P_EntryFilter4On = true; //extern bool P_EntryFilter5On = false; extern string C_Signal1 = "====== Signal 1 Envelope ================="; extern double P_EnvPerc = 0.008; //Percent extern int P_EnvPer = 6; //Period extern string C_Signal2 = "====== Signal 2 SMA Difference ==========="; extern int P_SMAPer = 5; extern int P_SMA2Bars = 6; extern string C_Signal3 = "====== Signal 3 OSMA Cross ==============="; extern int P_OSMAFast = 4; extern int P_OSMASlow = 16; extern double P_OSMASignal = 8; extern string C_Signal4 = "====== Signal 4: Price Divergence ========"; extern int P_Fast_Per = 4; int P_Fast_Price = PRICE_OPEN; extern int P_Slow_Per = 16; int P_Slow_Price = PRICE_OPEN; extern double P_DVBuySell = 1; //only needs 1 decimal at most extern double P_DVStayOut = 8; //only needs 1 decimal at most double W_DVBuySell; double W_DVStayOut; extern string C_Signal5_6 = "===== Signal 5 RSI Direction & 6 RSI ====="; extern int P_RSI_High = 80; extern int P_RSI_Low = 20; extern int P_RSI_Per = 2; double W_RSI1, W_RSI2, W_RSI3; //3 globals saves 6 indicator calls. int W_RSIBar, W_ES4_SRBar; double W_ES4_SR[4]; extern string C_Filter1 = "====== Filter 1: BBands Channel Detect ====="; extern int F_ATRShort = 5; //Short term period for consolidation //int F_ATRLong = 35; //Long term reference data vs consolidation //changed so Long = 7*short extern double F_ATR = 0.6; //Minimum value to allow trades //Code contributed by Wackena extern string C_Filter2 = "====== Filter 2: Allowed Time =========="; extern double F_AllAt1 = 1; //Defaults will trader 24 hours Mon-Thu extern double F_AllTo1 = 21; //TODO Support double and min instead of hour int. extern double F_AllAt2 = 24; extern double F_AllTo2 = 24; extern double F_SunAt = 0; //Sunday trading is disabled extern double F_SunTo = 0; extern double F_FriAt = 0; //Friday trading ends early extern double F_FriTo = 16; extern double F_MonAt = 4; //Monday without Japanese Open extern double F_MonTo = 24; int currentHour; //One global variable saves thousands of CPU cycles. extern string C_Filter3_4 = "====== Filter 3&4 Trend ==============="; extern int U_TrendPer = 30; extern int U_TrendShift = 5; extern double P_TrendStr = 30; //Difference in pips between price and MA. extern string C_SystemChange = "====== System Changes ================="; extern bool U_WriteLog = false; extern bool U_WriteDebug = false; extern string U_EAComment = ""; //******************* Global Variables ***************// #define MagicNumSet1 101010 int maxMagic = 0; //Set size of magic numbers used bool Chain2EntryOn = false; bool W_GreenLight = true; string W_Trade_Per; int nDaysSince1970 = 0; int LogHandle = -1; int BuySignalCount; int SellSignalCount; //---------------------- INIT -------------------- void init() { //Startup Functions, only called once. if((Symbol() != U_Trade_CURRENCY) && (Symbol() != U_Trade_CURRENCY+"m")) { Alert("These settings are designed for "+U_Trade_CURRENCY+ " only! Change chart or update U_Trade_CURRENCY" ); W_GreenLight=false; } if(U_MaxLot >MarketInfo(Symbol(),MODE_MAXLOT)) U_MaxLot=MarketInfo(Symbol(),MODE_MAXLOT); if(U_MinLot >MarketInfo(Symbol(),MODE_MINLOT)) U_MaxLot=MarketInfo(Symbol(),MODE_MINLOT); switch(Period()) { case 1: W_Trade_Per="M1"; break; case 5: W_Trade_Per="M5"; break; case 15: W_Trade_Per="M15"; break; case 30: W_Trade_Per="M30"; break; case 60: W_Trade_Per="H1"; break; case 240: W_Trade_Per="H4"; break; case 1440: W_Trade_Per="D1"; break; case 10080: W_Trade_Per="W1"; break; case 43200: W_Trade_Per="MN"; break; default: Alert("Your timeframe "+Period()+" was not detected."); W_Trade_Per=""; } if(U_Trade_Per != W_Trade_Per) { Alert("These settings are designed for "+U_Trade_Per+ " only! Change chart or update U_Trade_Per"); W_GreenLight=false; } //Initial Settings: // W_DVBuySell = P_DVBuySell*Point; // W_DVStayOut = P_DVStayOut*Point; W_DVBuySell = P_DVBuySell; W_DVStayOut = P_DVStayOut; //TODO starting balance for complex money management. P_signalsRequired=P_EntrySignal1On+P_EntrySignal2On+P_EntrySignal3On+P_EntrySignal4On+P_EntrySignal5On+P_EntrySignal6On; minStop=MarketInfo(Symbol(),MODE_STOPLEVEL); if(E_BE_SL<E_BE_Profit+minStop) E_BE_Profit=E_BE_SL-minStop; if(F_AllAt1>F_AllTo1) { Alert("F_AllAt1>F_AllTo1"); W_GreenLight = false; } if(F_AllAt2>F_AllTo2) { Alert("F_AllAt2>F_AllTo2"); W_GreenLight = false; } if(F_AllTo1>F_AllAt2) { Alert("F_AllTo1>=F_AllAt2"); W_GreenLight = false; } if(F_SunAt>F_SunTo) { Alert("F_SunAt>F_SunTo"); W_GreenLight = false; } if(F_FriAt>F_FriTo) { Alert("F_FriAt>F_FriTo"); W_GreenLight = false; } if(F_MonAt>F_MonTo) { Alert("F_MonAt>F_MonTo"); W_GreenLight = false; } //F_ATRLong=7*F_ATRShort; //Filter 1, autoconfigure } //---------------------- START -------------------- void start() { if(W_GreenLight == false) return(0); L1_OpenLogFile("MyLog.txt"); int ordercount; //*************** Detect open trades *********************// for (int cticket = 0; cticket < OrdersTotal(); cticket++) { if (OrderSelect(cticket, SELECT_BY_POS) == false) continue; if (OrderSymbol() != Symbol()) continue; if (OrderMagicNumber() >= MagicNumSet1 && OrderMagicNumber() <= MagicNumSet1 + maxMagic) { X1_ManageExit(OrderTicket()); ordercount++; // PContour - removed the following lines in favour of condensed order management. // if (OrderType() == OP_BUY) X1_ManageExit(OrderTicket()); //Buy // else if (OrderType() == OP_SELL) X1_ManageExit(OrderTicket()); //Sell } } if ( ordercount < U_maxtrades) A1_OpenTrade_If_Signal(); L9_FlushLog(); } //End Start() //********************* Check for New Trade *******************// void A1_OpenTrade_If_Signal() { //Check singals and conditions to enter new trade int signalCount; bool enableBuy= true; bool enableSell=true; //EntryFilters enable or disable trading, while EntrySignals generate "buy" or "sell" //EntryFilter should return "false" if trading is still enabled. if (P_EntryFilter1On) //Changed filters to quit ASAP. if (Z_F1_BlockTradingFilter1()) return; if (P_EntryFilter2On) if (Z_F2_BlockTradingFilter2()) return; if (P_EntryFilter3On) if (Z_F3_BlockTradingFilter3()) { enableBuy=false; BuySignalCount=0; } if (P_EntryFilter4On) if (Z_F4_BlockTradingFilter4()) { enableSell=false; SellSignalCount=0; } // if (P_EntryFilter5On) // if (Z_F5_BlockTradingFilter5()) return; //Check all the EntrySignals for Buy=1 or Sell=-1 values. See constants at top of file. if (P_EntrySignal1On) { signalCount += Z_S1_EntrySignal1(); if(U_WriteDebug) L3_WriteDebug("Signal1 sum: "+signalCount); } if (P_EntrySignal2On) { signalCount += Z_S2_EntrySignal2(); if(U_WriteDebug) L3_WriteDebug("Signal2 sum: "+signalCount); } if (P_EntrySignal3On) { signalCount += Z_S3_EntrySignal3(); if(U_WriteDebug) L3_WriteDebug("Signal3 sum: "+signalCount); } if (P_EntrySignal4On) { signalCount += Z_S4_EntrySignal4(); if(U_WriteDebug) L3_WriteDebug("Signal4 sum: "+signalCount); } if (P_EntrySignal5On) { signalCount += Z_S5_EntrySignal5(); if(U_WriteDebug) L3_WriteDebug("Signal5 sum: "+signalCount); } if (P_EntrySignal6On) { signalCount += Z_S6_EntrySignal6(); if(U_WriteDebug) L3_WriteDebug("Signal5 sum: "+signalCount); } // Counting up the number of buy or sell signals that happen consecutively. if(enableBuy) if(signalCount >= P_signalsRequired) { //Check for Buy BuySignalCount++; SellSignalCount=0; } if(enableSell) if(signalCount <= (-1)*P_signalsRequired) { BuySignalCount=0; SellSignalCount++; } if(U_SignalResetOnBlank) if( (signalCount <= (-1)*P_signalsRequired) && (signalCount >= P_signalsRequired)) {//If neither buy nor sell signal is received BuySignalCount =0; SellSignalCount=0; } if(U_WriteLog) L2_WriteLog("signal#:"+signalCount+" P_ConsecSignals:" +P_ConsecSignals+" BuySignalCount:" +BuySignalCount+" SellSignalCount:"+ SellSignalCount); // If the BuySignalCount or SellSignalCount exceeds the P_ConsecSignals required // then the Buy order or Sell order will be submitted. if(P_ConsecSignals <= BuySignalCount) { A1_1_OrderNewBuy(M1_MM_OptimizeLotSize()*A1_3_EntryConfirmation(OP_BUY)); BuySignalCount =0; recrosscount=0; //reset recross count for new trade. } else if(P_ConsecSignals <= SellSignalCount) { A1_2_OrderNewSell(M1_MM_OptimizeLotSize()*A1_3_EntryConfirmation(OP_SELL)); SellSignalCount =0; recrosscount=0; //reset recross count for new trade. } } void A1_1_OrderNewBuy(double lots) //Trade TP+SL Signals { T2_SendTrade(StaticTP, StaticSL, lots, OP_BUY); } void A1_2_OrderNewSell(double lots) //Trade TP+SL Signals { T2_SendTrade(StaticTP, StaticSL, lots, OP_SELL); } double A1_3_EntryConfirmation(int direction) { //Gann Style Support and Resist Lines. if(!U_ConfirmSignal1On) return (1.0); double value=1; if(W_ES4_SRBar>iBars(Symbol(),PERIOD_H4)) { W_ES4_SRBar=iBars(Symbol(),PERIOD_H4); W_ES4_SR[4]=iHigh(Symbol(),PERIOD_H4,1); W_ES4_SR[0]=iLow(Symbol(),PERIOD_H4,1); if(W_ES4_SR[4]-W_ES4_SR[0]<(StaticTP+StaticSL)*Point) { W_ES4_SR[4]=iHigh(Symbol(),PERIOD_D1,1); W_ES4_SR[0]=iLow(Symbol(),PERIOD_D1,1); } W_ES4_SR[3]=(W_ES4_SR[0]+W_ES4_SR[4])*0.75; W_ES4_SR[2]=(W_ES4_SR[0]+W_ES4_SR[4])*0.5; W_ES4_SR[1]=(W_ES4_SR[0]+W_ES4_SR[4])*0.25; } int next=ArrayBsearch(W_ES4_SR,Bid); if(direction==OP_SELL) { if(Bid+StaticSL*Point>W_ES4_SR[next]) value=2; } if(direction==OP_BUY) { if(next !=0)//safe array { if(Bid-StaticSL*Point<W_ES4_SR[next-1]) value=2; } else value=1; } return (value); } /*double EntryConfirmation2() { //TODO Speed Angle Check return(1.0); } */ /*double EntryConfirmation3() { //TODO 4-7 Rule return(1.0); } */ //********************* Money Management *****************// double M1_MM_OptimizeLotSize() { if(!U_MoneyManage) return(U_Lots); double lots =U_Lots; int orders =HistoryTotal(); int i =orders-1; int trades =0; int wins =0; int losses =0; double lotStep=MarketInfo(Symbol(),MODE_LOTSTEP); //if(U_WriteLog) L2_WriteLog("ALERT lotstep from broker is "+lotStep); //if(lotStep==0) lotStep =.0001; //TODO Safety feature... need to debug this better. lots=AccountFreeMargin()*U_MaxRisk/1000.0; if(U_DecreaseFactor > 256) //need to check for a real value { while (trades< 3 && i > 0) { if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false) { if(U_WriteLog) L2_WriteLog("Error in history!"); break; } if(OrderSymbol()==Symbol() && OrderType()<=OP_SELL) { trades++; if(OrderProfit()<0) losses++; if(OrderProfit()>0) wins++; } i--; } if (U_DecreaseFactor > 999999) { if(U_WriteLog) L2_WriteLog("U_DecreaseFactor too large. Changed to 902005"); U_DecreaseFactor = 902005; } int Loss1_Percentage = U_DecreaseFactor * 0.0001; int Loss2_Percentage = (U_DecreaseFactor - 10000 * Loss1_Percentage) * 0.01; int Loss3_Percentage = (U_DecreaseFactor - 10000 * Loss1_Percentage - 100 * Loss2_Percentage); if(U_WriteLog) L2_WriteLog("Decrease Factors "+Loss1_Percentage+" "+Loss2_Percentage+" "+Loss3_Percentage) ; // if (losses==0){ lots=lots*100 *0.01; } //This line is just documentation if (losses==1){ lots=lots*Loss1_Percentage*0.01; } if (losses==2){ lots=lots*Loss2_Percentage*0.01; } if (losses>=3){ lots=lots*Loss3_Percentage*0.01; } if(U_WriteLog) L2_WriteLog(" losses "+losses+" lots "+lots); } if(lots<U_MinLot) { lots=U_MinLot; if(U_WriteLog) L2_WriteLog("lots switched to min "+lots); } if(lots>U_MaxLot) { lots=U_MaxLot; if(U_WriteLog) L2_WriteLog("lots switched to max "+lots); } lots /=lotStep; lots = NormalizeDouble(lots,0); lots *= lotStep; return(lots); } int T2_SendTrade(int TP, int SL, double lot, int order, int incMagic = 0) //Execute Trades { double price; color arrow; int ticket; string tradecomment= U_EAComment + " P6B T"+ incMagic; if (order %2==OP_BUY) { //if number is even price = Ask; arrow = Blue; } if (order %2==OP_SELL) { //if number is odd price = Bid; SL = -SL; TP = -TP; arrow = Red; } //ticket = OrderSend(Symbol(),OP_BUY,1,Ask,3,Ask-25*Point,Ask+25*Point,"My order #2",16384,0,Green); ticket = OrderSend( Symbol(), order, lot, price, AcceptSlip, price-SL*Point, price+TP*Point, tradecomment, MagicNumSet1 + incMagic, 0, arrow ); if (ticket != Failed) { if(U_WriteLog) L2_WriteLog("Success:"+ticket+" "+Symbol()+" order:"+order+" lot:"+lot+" price:"+price+" SL:"+(price-SL*Point)+" TP:"+(price+TP*Point)); return (ticket); //TODO use ticket number somehow } else { int error=GetLastError(); if(U_WriteLog) L2_WriteLog("Error:"+error+" "+Symbol()+" order:"+order+" lot:"+lot+" price:"+price+" SL:"+(price-SL*Point)+" TP:"+(price+TP*Point)); if(error==129 || error==130 || error==135 || error==138) { //Handle a few errors we know about, usually price movement. TODO make this configurable. RefreshRates(); ticket = OrderSend( Symbol(), order, lot, price, AcceptSlip, price - SL * Point, price + TP * Point, tradecomment, MagicNumSet1 + incMagic, 0, arrow ); if (ticket != Failed) return (ticket); //TODO use ticket number somehow else if(U_WriteLog) L2_WriteLog("Error: Order send failed twice. Quitting."+ GetLastError()); } if(error==4 || error==136 || error==137 ||error==146) { //Busy Errors, sleep a little then retry Sleep(2000); RefreshRates(); ticket = OrderSend( Symbol(), order, lot, price, AcceptSlip, price - SL * Point, price + TP * Point, tradecomment, MagicNumSet1 + incMagic, 0, arrow ); if (ticket != Failed) return (ticket); //TODO use ticket number somehow else if(U_WriteLog) L2_WriteLog("Error: Order send failed twice. Quitting."+ GetLastError()); } } } //********** Exit Strategies & Trailing Stops **********************************// void X1_ManageExit(int myticket) { //Contains all of the exit strategies and trade management routines. Listed in priority. minStop=MarketInfo(Symbol(),MODE_STOPLEVEL); //updated every tick in case of news SL movement if(E_GraceHours !=0 ||E_ForceHours !=0) X1_ForceClose_or_GraceModify(myticket); if(E_RecrossMax!=0) { double price; if (OrderType() == OP_BUY) price=Bid; if (OrderType() == OP_SELL) price=Ask; if(Bars>bcRecross) { //Bar hasn't been counted yet if(OrderOpenPrice()>price-1 && OrderOpenPrice()<price+1) { recrosscount++; bcRecross=Bars; if (recrosscount>=E_RecrossMax) if(!OrderClose(myticket,OrderLots(),price,AcceptSlip,Red)) L4_WriteError(); } } } //TODO StealthExit if(E_BE_SL!=0) { // BreakEven SL @target if(E_BE_SL<E_BE_Profit+minStop) E_BE_Profit=E_BE_SL-minStop; //keeps trade safe all of the time if(Bid-OrderOpenPrice()>Point*E_BE_Profit && (OrderStopLoss()< OrderOpenPrice()+E_BE_Profit*Point)) { if (OrderType() == OP_BUY) X9_ModifySL(OrderOpenPrice()+E_BE_Profit*Point,myticket); if (OrderType() == OP_SELL) X9_ModifySL(OrderOpenPrice()-E_BE_Profit*Point,myticket); } } if (E_ExitParaTSOn) { double paraSAR=iSAR(NULL,0,0.02,0.2,1); // if(U_WriteDebug) L3_WriteDebug("ParaTS: "+paraSAR+" TP"+OrderTakeProfit()+" SL"+OrderStopLoss()+" Bid"+Bid); if(OrderType() == OP_BUY) if(paraSAR<Bid && OrderProfit()>0) OrderClose(OrderTicket(),OrderLots(),Bid,AcceptSlip,Red); //X9_ModifyTrailingStop(myticket,minStop,0); if(OrderType() == OP_SELL) if(paraSAR>Ask && OrderProfit()>0) OrderClose(OrderTicket(),OrderLots(),Ask,AcceptSlip,Red); } else if (E_ExitStaticTSOn) { X9_ModifyTrailingStop(myticket,StaticTS,E_DelayTS); } } void X1_ForceClose_or_GraceModify(int ticket) //contrib by HerbertH in original Phoenix 2007 thread. { int PerForce = E_ForceHours*3600; int PerGrace = E_GraceHours*3600; double newSL =0; OrderSelect(ticket, SELECT_BY_POS, MODE_TRADES); //TODO verify this line is redundant and unnecessary if (PerForce!=0) { if((OrderOpenTime() + PerForce) < Time[0]) { if(OrderType() == OP_BUY) OrderClose(OrderTicket(),OrderLots(),Bid,3,Red); //3 points slippage allowed? if(OrderType() == OP_SELL) OrderClose(OrderTicket(),OrderLots(),Ask,3,Red); } } if(PerGrace!=0) { if(OrderOpenTime() + PerGrace < Time[0]) { X9_ModifyTrailingStop(ticket, E_GraceTS,-1000); // -1000=No profit delay on TS with PerGrace } } } void X9_ModifyTrailingStop(int ticket, int tsvalue, int delayts) { double slvalue; if(tsvalue>=minStop) //check minimal value allowed by broker { //TODO decrease tsvalue to make constricting difference between TP and SL. if(TSConstrictOn) { //Code currently broken if(OrderProfit()>0) tsvalue=((OrderTakeProfit()-OrderStopLoss())/Point)*0.5; if(tsvalue<minStop) tsvalue=minStop; } } else { //Set safe value tsvalue=minStop; } if(U_WriteDebug) L3_WriteDebug("EXIT:TS ticket:"+ticket+" tsvalue:"+tsvalue+" delayts:"+delayts); if (OrderType() == OP_BUY) { slvalue=Bid-(Point*tsvalue); if (OrderStopLoss() < slvalue && OrderOpenPrice()+Point*delayts<Bid+tsvalue*Point) { //if(U_WriteDebug) L3_WriteDebug("OrderSL:" +OrderStopLoss()+ " slvalue:"+ slvalue); if(!X9_ModifySL(slvalue,ticket)) { L4_WriteError(); L3_WriteDebug("ERROR OrderSL:" +OrderStopLoss()+ " slvalue:"+ slvalue); } } } else if (OrderType() == OP_SELL) { slvalue=Ask+(Point*tsvalue); if (OrderStopLoss() > slvalue && OrderOpenPrice()-Point*delayts>Ask-tsvalue*Point) { //if(U_WriteDebug) L3_WriteDebug("OrderSL:" +OrderStopLoss()+ " slvalue:"+ slvalue); if(!X9_ModifySL(slvalue,ticket)) { L4_WriteError(); L3_WriteDebug("ERROR OrderSL:" +OrderStopLoss()+ " slvalue:"+ slvalue); } } } } bool X9_ModifySL(double sl, int ticket) { double MoveTP; if(E_MoveTPonTS !=0) { if (OrderType() == OP_SELL) { MoveTP=E_MoveTPonTS*(-1)*Point; if(Ask-OrderTakeProfit()+MoveTP<minStop*Point) MoveTP=minStop*Point*(-1) -OrderTakeProfit(); //Set the new distance to minimum safe point, -OTP() cancels OTP() } else { MoveTP=E_MoveTPonTS*Point; if(OrderTakeProfit()-Bid+MoveTP<minStop*Point) MoveTP=minStop*Point -OrderTakeProfit(); //Set the new distance to minimum safe point, -OTP() cancels OTP() } } if(U_WriteDebug) L3_WriteDebug("MODIFY Ticket:"+ticket+" OpenPrice:"+OrderOpenPrice()+" SL:"+sl+" TP:"+(OrderTakeProfit()+MoveTP*Point)); if(OrderModify ( ticket, OrderOpenPrice(), sl, OrderTakeProfit()+MoveTP, 0, Red) ==(-1)) return(false); else return(true); } //********************** SIGNALS *********************// int Z_S1_EntrySignal1() { //Envelope Filter int Signal=None; double HighEnvelope1 = iEnvelopes(NULL,0,P_EnvPer,MODE_SMA,0,PRICE_CLOSE,P_EnvPerc,MODE_UPPER,1); double LowEnvelope1 = iEnvelopes(NULL,0,P_EnvPer,MODE_SMA,0,PRICE_CLOSE,P_EnvPerc,MODE_LOWER,1); double CloseBar1 = iClose(NULL,0,1); if(CloseBar1 > HighEnvelope1) {Signal=Sell;} if(CloseBar1 < LowEnvelope1) {Signal=Buy; } if(U_WriteDebug) L3_WriteDebug("Signal 1 "+Signal+" HighEnv:"+HighEnvelope1+" LowEnv:"+LowEnvelope1+" Close:"+CloseBar1); return (Signal); } int Z_S2_EntrySignal2() { //SMA Difference int Signal=None; double SMA1=iMA(NULL,0,P_SMAPer,0,MODE_SMA,PRICE_CLOSE,1); double SMA2=iMA(NULL,0,P_SMAPer,0,MODE_SMA,PRICE_CLOSE,P_SMA2Bars); if (SMA2>SMA1 ) Signal=Buy; else Signal=Sell; if(U_WriteDebug) L3_WriteDebug("Signal2 "+Signal+" SMA Diff:"+(SMA2-SMA1)+" SMA2:"+SMA2+" SMA1:"+SMA1); return (Signal); } int Z_S3_EntrySignal3() { //OSMA Cross int Signal=None; double OsMABar2=iOsMA(NULL,0,P_OSMAFast,P_OSMASlow,P_OSMASignal,PRICE_CLOSE,2); double OsMABar1=iOsMA(NULL,0,P_OSMAFast,P_OSMASlow,P_OSMASignal,PRICE_CLOSE,1); if (OsMABar2>OsMABar1) Signal=Buy; else Signal=Sell; if(U_WriteDebug) L3_WriteDebug("Signal3 "+Signal+" OsMA Diff:"+(OsMABar2-OsMABar1)+" OsMABar2:"+OsMABar2+" OsMABar1:"+OsMABar1); return (Signal); } int Z_S4_EntrySignal4() { //Divergence Trading Signal int Signal; double diverge = ZZ_F1_Divergence(P_Fast_Per, P_Slow_Per, P_Fast_Price, P_Slow_Price,0); if(diverge >= W_DVBuySell && diverge <= W_DVStayOut) Signal=Buy; else if(diverge <= (W_DVBuySell*(-1)) && diverge >= (W_DVStayOut*(-1))) Signal=Sell; if(U_WriteDebug) L3_WriteDebug("Signal4 "+Signal+" diverge:"+diverge+" W_DVBuySell:"+W_DVBuySell+" W_DVStayOut:"+W_DVStayOut); return (Signal); } int Z_S5_EntrySignal5() { int value=0; if(W_RSIBar<Bars) { //This should be based on bars, reduces check to once every bar. W_RSIBar=Bars; W_RSI3=W_RSI2; //This reduces computation to 1/3 W_RSI2=W_RSI1; W_RSI1 = iRSI(NULL, Period(), P_RSI_Per, PRICE_CLOSE, 1); } if (W_RSI1 < P_RSI_High) //Save CPU cycles with quick filters { if(W_RSI2 < W_RSI1 && W_RSI3 < W_RSI2) value=Buy; } else if (W_RSI1 > P_RSI_Low) //only one set needs to be checked, and not always. if(W_RSI2 > W_RSI1 && W_RSI3 > W_RSI2) value=Sell; if(U_WriteDebug) L3_WriteDebug("SignalRSI: "+value+" W_RSI1:"+W_RSI1+" W_RSI2:"+W_RSI2+" W_RSI3:"+W_RSI3); return(value); } int Z_S6_EntrySignal6() { int value=0; double w_RSI = iRSI(NULL, Period(), P_RSI_Per, PRICE_CLOSE, 1); if (w_RSI < P_RSI_High) //Save CPU cycles with quick filters value=Buy; else if (w_RSI > P_RSI_Low) //only one set needs to be checked, and not always. value=Sell; if(U_WriteDebug) L3_WriteDebug("SignalRSI: "+value+" w_RSI:"+w_RSI); return(value); } bool Z_F1_BlockTradingFilter1() { //Original code Contributed by Wackena bool BlockTrade=false; //trade by default double w_ATR; double dAtrShort = iATR(NULL, 0, F_ATRShort, 0); //double dAtrLong = iATR(NULL, 0, F_ATRLong, 0); //if(dAtrLong != 0) w_ATR = dAtrShort / dAtrLong; //if(w_ATR<F_ATR)BlockTrade=true; if(dAtrShort<F_ATR)BlockTrade=true; return (BlockTrade); } bool Z_F2_BlockTradingFilter2() { //Time Expiry bool BlockTrade=true; //only trade during permitted hours // if(TimeHour(TimeCurrent())!=currentHour) // { currentHour=TimeHour(TimeCurrent()); //one global variable saves thousands of CPU cycles if(TimeDayOfWeek(Time[0])==0) //Sunday { if(currentHour>=F_SunAt && currentHour<F_SunTo) BlockTrade=false; } else if(TimeDayOfWeek(Time[0])==5) //Friday { //if(U_WriteDebug) L3_WriteDebug("Today is Friday:"+currentHour); if(currentHour>=F_FriAt && currentHour<F_FriTo) BlockTrade=false; } else if(TimeDayOfWeek(Time[0])==1) //Monday { //if(U_WriteDebug) L3_WriteDebug("Today is Friday:"+currentHour); if(currentHour>=F_MonAt && currentHour<F_MonTo) BlockTrade=false; } else if((currentHour>=F_AllAt1 && currentHour<F_AllTo1) || (currentHour>=F_AllAt2 && currentHour<F_AllTo2)) BlockTrade=false; // } return (BlockTrade); } bool Z_F3_BlockTradingFilter3() //if BUY Signal, check buy trend. True = quit. { bool BlockTrade=false; double TrendB=iMA(NULL,0,U_TrendPer,U_TrendShift,MODE_LWMA,PRICE_MEDIAN,0)-High[1]; if(P_TrendStr*Point<TrendB) { BlockTrade=true; if(U_WriteDebug) L3_WriteDebug("EntryFilter3 TrendMA:"+TrendB+" Buy="+BlockTrade+" Buy Allowed"); } else { if(U_WriteDebug) L3_WriteDebug("EntryFilter3 TrendMA:"+TrendB+" Buy="+BlockTrade+" Buy DisAllowed"); } return(BlockTrade); } bool Z_F4_BlockTradingFilter4() { //if SELL Signal, check sell trend //Currently assuming that rising and falling trends have similar properties. bool BlockTrade=false; double TrendS=Low[1]-iMA(NULL,0,U_TrendPer,U_TrendShift,MODE_LWMA,PRICE_MEDIAN,0); if(P_TrendStr*Point<TrendS) { BlockTrade=true; if(U_WriteDebug) L3_WriteDebug("EntryFilter4 TrendMA:"+TrendS+" Sell="+BlockTrade+" Sell DisAllowed"); } else { if(U_WriteDebug) L3_WriteDebug("EntryFilter4 TrendMA:"+TrendS+" Sell="+BlockTrade+" Sell Allowed"); } return(BlockTrade); } //bool Z_F5_BlockTradingFilter5() //TODO S&R // { // return (false); //trade by default // } //********************** Signal Functions ******************// double ZZ_F1_Divergence(int F_Per, int S_Per, int F_Price, int S_Price, int mypos) { int i; double maF2 = iMA(Symbol(), 0, F_Per, 0, MODE_SMA, F_Price, mypos + 1); double maS2 = iMA(Symbol(), 0, S_Per, 0, MODE_SMA, S_Price, mypos + 1); return((maF2-maS2)/Point); } //*********************** LOGGING **************************// void L1_OpenLogFile(string strName) { if (!U_WriteLog && !U_WriteDebug) return; if (TimeCurrent() / (60 * 60 * 24) > nDaysSince1970 || LogHandle <= 0) { //Pick a new filename and open it. if (LogHandle > 0) FileClose(LogHandle); string strMonthPad = "" ; if (Month() < 10) strMonthPad = "0"; string strDayPad = "" ; if (Day() < 10) strDayPad = "0"; string strFilename = StringConcatenate(strName, "_", Year(), strMonthPad, Month(), strDayPad, Day(), "_log.txt"); LogHandle =FileOpen(strFilename, FILE_CSV | FILE_READ | FILE_WRITE); nDaysSince1970 = TimeCurrent() / (60 * 60 * 24); } FileFlush(LogHandle); FileSeek(LogHandle, 0, SEEK_END); } void L2_WriteLog(string msg) { if (!U_WriteLog) return; if (LogHandle <= 0) return; msg = TimeToStr(TimeCurrent(), TIME_DATE | TIME_MINUTES | TIME_SECONDS) + " " + msg; FileWrite(LogHandle, msg); } void L3_WriteDebug(string msg) //Signal Debugging, rarely called { // if (!U_WriteDebug) return; if (LogHandle <= 0) return; msg = TimeToStr(TimeCurrent(), TIME_DATE | TIME_MINUTES | TIME_SECONDS) + " " + msg; FileWrite(LogHandle, msg); } void L4_WriteError() { if (!U_WriteLog) return; if (LogHandle <= 0) return; string msg="Error:"+ GetLastError()+" OrderType:"+OrderType()+" Ticket:"+OrderTicket(); msg = TimeToStr(TimeCurrent(), TIME_DATE | TIME_MINUTES | TIME_SECONDS) + " " + msg; FileWrite(LogHandle, msg); } void L9_FlushLog() { if (!U_WriteLog) return; FileFlush(LogHandle); } //End Of File
Sample
Analysis
Market Information Used:
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
Series array that contains close prices for each bar
Indicator Curves created:
Indicators Used:
Parabolic Stop and Reverse system
Envelopes indicator
Moving average indicator
Moving Average of Oscillator
Relative strength index
Indicator of the average true range
Custom Indicators Used:
Order Management characteristics:
Checks for the total of open orders
It Closes Orders by itself
Other Features:
It issuies visual alerts to the screen
Uses files from the file system
It writes information to file