//+-----------------------------------------------------------------------------------+ //| Stoch_Power_Hedger_V4.6.mq4 | //| David Moser, 02/MAR/2010 | //| dmoser71@gmail.com | //| Copyright 2009, David Moser | //| | //| A special thanks and recognition to Forrest Miller for the original concept, | //| Wackena, and Spike for getting SPH V3 code to where it was, and to the | //| [MT_E and I] community for all their feedback and support of this project! | //| | //| forrest@thevision.net wackena@bogie-enterprises.com | //| Spike bulldogge1232000@yahoo.com Peter Wu pwu8@san.rr.com | //+-----------------------------------------------------------------------------------+ // Please, do not sell this EA because it's FREE // //+-----------------------------------------------------------------------------------+ //| Change Log: | //| 20091007 (V4.0_Beta1): added AutoGMT function, reworked trading hours logic, and | //| restructured the code base to make it more manageable. Corrected the prior | //| hacks made to the code. Program core completely re-engineered. -David Moser | //| | //| 20091008 (V4.0_Beta1): Removed the following per Spike's request: | //| AllSymbolsProtect, Manual, OrdersTimeAlive, EquityProtection, | //| AccountMoneyProtection, AccountEquityPercentProtection. -David Moser | //| | //| DDControl enhanced to work during backtest or during live trading. | //| Trading hours logic revamped, now only one set of trading times based on GMT. | //| System auto-detects account type and adjusts risk accordingly. -David Moser | //| | //| 20091015: (V4.0_Beta2): Added special risk management algorithm (mm=2), plus | //| added a trade recovery feature that will catch up trades missed during non-trade | //| times according to pip spacing rules. Added additional error handling in trade | //| opening and closing routines, including checking for sufficient margin to open | //| new trades. Fixed Account Sentry Hook so that the EA will close all trades and | //| remain disabled. Fixed My Money Profit Target logic. Added a Max DD indicator to | //| gauge the amount of draw down per trade sequence if SL is hit. -David Moser | //| | //| 20091016: (V4.0): Removed ExitOnStoch Parameter, added Strategy Parameter to make | //| it easy to implement new trading strategies. Made the Lot Size Array sensitive | //| to account draw down so that trade sequence sizing is not broken, added globals | //| to preserve lot size sequences between restarts of EA. | //| | //| 20091028: (V4.01): Fixed GMT Offset bug in time management code. Updated time | //| management parameters to indicate that Start/End Times are in GMT. Chart format | //| improved. | //| | //| 20091104: (V4.2): Fixed problem where the EA would not close out trades on Friday | //| sometimes. Also, added a new parameter FridayGMTStopHour which if left on its | //| default of -1, does nothing, but if is increased to 0 or higher, will not trade | //| on Fridays starting at that hour GMT. If used with TTMGoFlat, can close all your | //| positions at the end of each trading week at whatever GMT Hour you specify. | //| | //| 20091109: (V4.2): Fixed problem on 4-digit brokers where sometimes the OrderSend | //| & Orderclose functions would fail with invalid prices. | //| | //| 20091126: (V4.3): Rewrote CloseAllOrders subroutine to address issue where some | //| orders will be orphaned when the system needs to close all buy or sell orders. | //| | //| 20091214: (V4.3TB): Corrected error with maxtrades greater then stop loss. | //| All trades now use level 1 stop loss and highest level take profit. | //| | //| 20100212: (V4.4): Fixed divide by zero error when MaxTrades=0 and mm=2, removed | //| the MagicMigrate extern since no longer needed. Merged in Tom B & Peter Wu's | //| changes and tweaked for proper integration. Merged in Spike's latest set files. | //| Updated MaxDDControl/MaxDDPercent control code to use MathAbs. | //| | //| 20100214: (V4.41): Added functionality for blackout dates - by David Heath | //| | //| 20100220: (V4.5): Removed Limit Orders function. Fixed EURUSD GoFlat param per | //| Spike near the bottom of the program. Tweaked Blackout hooks to maintain | //| existing open positions' TSL's, etc., but to not open any new positions as | //| discussed in the MT E&I thread. Defined EAName at the top to use throughout EA. | //| | //| 20100226: (V4.6): Added parameter input checking for proper range and bounds. The | //| EA will now halt when initializing if there are any problems in the inputs and | //| will provide a useful message on the chart and in the output logs. Also, more | //| robust error handling was added to all trade handling operations, especially in | //| the CloseAllOrders subroutine, which now returns a boolean status which is now | //| handled from the calling side in start(). | //| | //| | //| | //+-----------------------------------------------------------------------------------+ #property copyright "Copyright 2009, David Moser" #property link "http://www.ForexMT4.com/mt_yahoo/" #define EAName "SPH 4.6" #import "wininet.dll" int InternetOpenA(string param1, int param2, string param3, string param4, int param5); int InternetOpenUrlA(int param1, string param2, string param3, int param4, int param5, int param6); int InternetReadFile(int param1, string paramp, int param3, int ¶m4[]); int InternetCloseHandle(int param1); #import #include #include extern string INFO46="Stoch_Power_Hedger_V4.6"; extern string INFO46LU="Last Updated: 20 Feb 2010"; extern string InternalInfo1="If you use the INTERNAL Auto Pair Settings"; extern string InternalInfo2="All inputs below are ignored except the"; extern string InternalInfo3="GMT inputs, which must be set correctly"; extern bool USE_INTERNAL_AUTO_PAIR_SETTINGS = true; extern string s00="--Set your broker GMT offset below--"; extern bool UseAutoGMToffset = true; // If true, attempt to connect to public time source to detect GMT offset. extern bool AutoFallbackOnFail = true; // If true, will use the ManualGMToffset value if the EA cannot read from the public time source. extern int ManualGMToffset = 0; // Set your broker's GMT Offset here in case AutoGMT fails extern string InternalInfo4="If INTERNAL Auto Pair is False, then"; extern string InternalInfo5="EA will use the following inputs below"; extern string s01="--STOCH SETTINGS--"; extern int K_Period = 145; extern int D_Period = 20; extern int Slow_Period = 80; extern int Stoch_TF = 60; extern int shift= 4; extern int H_level = 78; extern int L_level = 22; extern string ChooseMAMode46="Choose 1=mode SMA, 2=mode LWMA, 3=mode EMA, 4=mode SMMA"; extern int stochMAmode = 1; extern string s02="--ENVELOPE SETTINGS--"; extern int ENVELOPE_Slow_Period = 14; extern int ENVELOPE_TF = 1440; extern string s03="--MOVING AVERAGE SETTINGS--"; extern int MA_TF = 60; extern int MA_Long_Period = 190; extern int MA_Short_Period = 80; extern string s04="--TRADE SETTINGS--"; extern int Strategy = 1; // S1 is Spike's original SPH strategy, S2 is Spike's new SPH strategy extern double Lots = 0.01; // We start with this number of lots extern int TakeProfit = 110; // Profit Goal in PIPs for the latest order opened extern double multiply= 1.7; extern int MaxTrades= 6; // Maximum number of orders to open extern int Pips= 90; // Distance in Pips from one order to another extern int StopLoss = 600; // StopLoss extern int TrailingStop = 0; // Pips to trail the StopLoss extern int TrailingStep = 0; // Pip interval to increment Trailing StopLoss by each time extern bool RecoveryMode = false; // If non-trading hours blocks opening more than 1 market order to maintain // PIP spacing, then open up 2+ orders as needed if true, only 1 if false. extern string s05="--MONEY MANAGEMENT--"; extern string MM_0="mm=0, risk is ignored, just use Lots parameter"; extern string MM_1="mm=1, risk is basic multiplier based on account balance"; extern string MM_2="mm=2, risk is % of account balance to risk per sequence"; extern int mm= 2; extern string MyRisk="set risk to use when calculating lot size"; extern double risk= 15; // risk to calculate the lots size (only if mm is enabled) extern bool TradeMicroLots = false; // will auto-detect account types, but override available here extern string s06="--MAGIC NUMBERS--"; extern int MagicNumber= 222777; // Primary Magic number for all orders placed extern string s07="--CUTLOSS SETTING--"; extern bool MyMoneyProfitTarget=false; extern double My_Money_Profit_Target=5000; extern bool SecureProfitProtection=false; extern string SP46="If profit made is bigger than SecureProfit we close the orders"; extern int SecureProfit= 15; // If profit made is bigger than SecureProfit we close the orders extern string OTP46="Number of orders to trigger SP Protection"; extern int OrderstoProtect= 3; // Number of orders to enable the account protection 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 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. // If used in conjunction with TTMGoFlat, will close all trades at the end of the trading week. extern bool TTMGoFlat = false; extern string s09="--DRAWDOWN CONTROL TOOL--"; extern string DDC1="Max DD in money allowed?"; extern bool MaxDDControl = false; extern double MaxAllowedDD = 1000.0; extern string DDC2="Max DD in percentage allowed?"; extern bool MaxPercentDDControl = false; extern double MaxAllowedPercentDD = 30.0; extern string s10="--DRAWDOWN REPORTING=="; extern bool ShowDDinfoOnChart = true; extern string s11="--OTHER SETTINGS--"; extern string reverse46="If true, the decision to go long/short will be reversed"; extern bool ReverseCondition= false; // if one the decision to go long/short will be reversed color ArrowsColor= Yellow; // color for the orders arrows // Code added by David Heath to handle no new trade times extern string s12="-- Use this section to exclude trading days"; extern bool EnableBlackout = True; extern int StartBlackoutDay = 20; extern int StartBlackoutMonth = 12; extern int StopBlackoutDay = 15; extern int StopBlackoutMonth = 01; int StartBlackout = 0; int StopBlackout = 0; // End code added by David Heath // Program Variables for Time Management int InternetHandle; string GMTOffsetStatusInfo; bool AutoGMTfailure=false; bool OneTimeInitialize=true; bool EADisabled=false; bool TradingDisabled=false; datetime dtBuyAllowed=0, dtSellAllowed=0; // This is used to control the manual confirmation dialog // Program Variables for Order Management bool exitBuy = false, exitSell = false; int CurrentOpenOrders[2]={0,0}; int MarketOpenOrders[2]={0,0}; int PreviousOpenOrders[2]={0,0}; datetime LastOrderOpenTime[2]={0,0}; double LastOrderOpenPrice[2]={0,0}; double MMProfit[2]={0,0}; // Track MyMoney Profit Target Info double SPProfit[2]={0,0}; // Track Secure Profit Protection Info double sl=0, tp=0, BuyPrice=0, SellPrice=0; double BaseLot=0, myBaseLot=0; double LotSizeArray[100,2]; // Element 99,0 and 99,1 used to hold account balance at start of sequence // Second dimension *,0 or *,1 is OP_BUY, OP_SELL specification int mode=0, myOrderTypetmp=0, slippage=50; // Program Variables for Order Opening double Stoch, Var1, Var2, Var3, Var4, Var5, Var6, Var7, Var8; // Program Variables for Statistical Tracking double MaxDD,MaxPercentDD; // General Program Variables string text="", TTstatus = "False", MMPTstatus = "False", SPPstatus = "False", LBOT, LSOT; double ActualRiskPercentS, ActualRiskPercentB; bool result; int cnt=0, myDigits; //+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ int init() { //---- OneTimeInitialize=true; EADisabled=false; if (USE_INTERNAL_AUTO_PAIR_SETTINGS) SetParameters(); //DM: Merged in PW's code if (EADisabled) return(-1); //DM: Need to catch and handle if you set USE_INTERNAL_AUTO_PAIR_SETTINGS to true on unsupported currency if (false) LogPerformance(); //DM: I put this dummy call here to prevent compilation warnings if (!IsDllsAllowed() && UseAutoGMToffset && !IsTesting()) { text="Error: Parameter \"AllowDLL Imports\" must be ON."; Print(text); EADisabled=true; Print("EA Disabled due to DLL setting conflict with UseAutoGMTOffset."); return(-1); } while (!IsConnected()) { Comment("Waiting for connection..."); Sleep(1000); } myDigits=MarketInfo(Symbol(),MODE_DIGITS); int x; if(myDigits==2) x= 1; if(myDigits==3) x=10; if(myDigits==4) x= 1; if(myDigits==5) x=10; TakeProfit *= x; StopLoss *= x; Pips *= x; TrailingStop *= x; TrailingStep *= x; // Determine Existing Orders, if any. UpdateOrderStatus(true); // Set status strings for display on chart if (MyMoneyProfitTarget) MMPTstatus = "True"; if (SecureProfitProtection) SPPstatus = "True"; // Determine Lot Sizing if (IsTesting()) { CalculateLotArray(OP_BUY,0); CalculateLotArray(OP_SELL,0); } else { ReadLotArray(); // Load LotArray from Globals and/or call for initial calculation as needed } // Need to validate all the various inputs next... if (MaxTrades != MathMin(MaxTrades, MathCeil(StopLoss / Pips)+1)) { text="Pipspacing is too large or the Stop Loss is too small for the number of Maxtrades."; Print(text); EADisabled=true; Print("EA Disabled due to Pipspacing - MaxTrades - StopLoss setting conflict."); return(-1); } // Continue validating inputs... if (( K_Period < 2 ) || ( D_Period < 2 ) || ( Slow_Period < 2 ) || ( ENVELOPE_Slow_Period < 2 ) || ( MA_Long_Period < 2 ) || ( MA_Short_Period < 2 )) { text="A Period input is less than 2:\nK_Period, D_Period, Slow_Period, ENVELOPE_Slow_Period, MA_Long_Period, or MA_Short_Period."; Print(text); EADisabled=true; Print("EA Disabled due to Period input that is too small."); return(-1); } // Continue validating inputs... if (( Stoch_TF != 1 && Stoch_TF != 5 && Stoch_TF != 15 && Stoch_TF != 30 && Stoch_TF != 60 && Stoch_TF != 240 && Stoch_TF != 1440 && Stoch_TF != 10080 && Stoch_TF != 43200 ) || ( ENVELOPE_TF != 1 && ENVELOPE_TF != 5 && ENVELOPE_TF != 15 && ENVELOPE_TF != 30 && ENVELOPE_TF != 60 && ENVELOPE_TF != 240 && ENVELOPE_TF != 1440 && ENVELOPE_TF != 10080 && ENVELOPE_TF != 43200 ) || ( MA_TF != 1 && MA_TF != 5 && MA_TF != 15 && MA_TF != 30 && MA_TF != 60 && MA_TF != 240 && MA_TF != 1440 && MA_TF != 10080 && MA_TF != 43200 )) { text="A TimeFrame (TF) input is incorrect.\nAll TFs must be either 1, 5, 15, 30, 60, 240, 1440, 10080, or 43200.\nCheck Stoch_TF, ENVELOPE_TF, and MA_TF."; Print(text); EADisabled=true; Print("EA Disabled due to incorrect TimeFrame (TF) input."); return(-1); } // Continue validating inputs... if (( risk < 0 ) || ( MagicNumber < 0 ) || ( Strategy < 0 ) || ( shift < 0 )) { text="An input is less than 0.\nCheck risk, MagicNumber, Strategy, and shift."; Print(text); EADisabled=true; Print("EA Disabled due to incorrect input."); return(-1); } // Continue validating inputs... if (( MyMoneyProfitTarget ) && ( My_Money_Profit_Target < 0 )) { text="MyMoneyProfitTarget is enabled but My_Money_Profit_Target is less than 0."; Print(text); EADisabled=true; Print("EA Disabled due to incorrect MMPT input."); return(-1); } // Continue validating inputs... if (( SecureProfitProtection ) && ( OrderstoProtect < 1 )) { text="SecureProfitProtection is enabled but OrderstoProtect is less than 1."; Print(text); EADisabled=true; Print("EA Disabled due to incorrect SPP input."); return(-1); } // Continue validating inputs... if (( H_level < 0 ) || ( H_level > 100 ) || ( L_level < 0 ) || ( L_level > 100 )) { text="A level input is less than 0 or greater than 100.\nCheck H_level and L_level."; Print(text); EADisabled=true; Print("EA Disabled due to incorrect level input."); return(-1); } // Continue validating inputs... if (( stochMAmode < 1 ) || ( stochMAmode > 4 )) { text="stochMAmode input is less than 1 or greater than 4.\nCheck stochMAmode and make sure it is from 1-4."; Print(text); EADisabled=true; Print("EA Disabled due to incorrect stochMAmode input."); return(-1); } // Continue validating inputs... if (( mm < 0 ) || ( mm > 2 )) { text="mm input is less than 0 or greater than 2.\nCheck mm and choose a valid Money Management parameter from 0-2."; Print(text); EADisabled=true; Print("EA Disabled due to incorrect mm input."); return(-1); } // Continue validating inputs... if (( TakeProfit < 0 ) || ( MaxTrades < 0 ) || ( StopLoss < 0 ) || ( TrailingStop < 0 ) || ( TrailingStep < 0 )) { text="An input is less than 0:\nTakeProfit, MaxTrades, StopLoss, TrailingStop, or TrailingStep."; Print(text); EADisabled=true; Print("EA Disabled due to input that is less than 0."); return(-1); } // Continue validating inputs... if ( Lots < 0.01 ) { text="Lots input is less than 0.01."; Print(text); EADisabled=true; Print("EA Disabled due to Lots input that is less than 0.01."); return(-1); } // Continue validating inputs... if ( multiply <= 0 ) { text="The multiply input is less than or equal to 0. Normal values are 1 or larger."; Print(text); EADisabled=true; Print("EA Disabled due to multiply input that is less than or equal to 0."); return(-1); } // Continue validating inputs... if ( Pips < 1 ) { text="The Pips input used for spacing out trades is less than 1.\nNormal values are 10 or larger."; Print(text); EADisabled=true; Print("EA Disabled due to Pips input that is less than 1."); return(-1); } // Continue validating inputs... if (( StartBlackoutDay < 1 ) || ( StartBlackoutDay > 31 ) || ( StartBlackoutMonth < 1 ) || ( StartBlackoutMonth > 12 ) || ( StopBlackoutDay < 1 ) || ( StopBlackoutDay > 31 ) || ( StopBlackoutMonth < 1 ) || ( StopBlackoutMonth > 12 )) { text="A month or day input is out of range. Valid months are 1-12. Valid days are 1-31.\nCheck StartBlackoutDay, StartBlackoutMonth, StopBlackoutDay, and StopBlackoutMonth."; Print(text); EADisabled=true; Print("EA Disabled due to Blackout Day or Month input that is out of range."); return(-1); } //**************David Heath - Code for blackout dates StartBlackout = DayNumber(StartBlackoutMonth, StartBlackoutDay); StopBlackout = DayNumber(StopBlackoutMonth, StopBlackoutDay); //******************************************************************************************** return(0); } //+------------------------------------------------------------------+ //| expert deinitialization function | //+------------------------------------------------------------------+ int deinit() { //---- if (!IsTesting()) WriteLotArray(); Print("MaxDD: ",MaxDD); Print("MaxPercDD: ",MaxPercentDD); DeleteAllObjects(); //---- return(0); } //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() { if (EADisabled) { if (IsTesting()) Comment("EA Disabled! Check Journal Log for details.\n"+text); else Comment("EA Disabled! Check Experts Log for details.\n"+text); return(0); } // One-time Initialization of GMT Offset and Time-based variables if (OneTimeInitialize) { while (InitializeTimeVariables() < 0) Sleep(1000); return(0); } //**************ADDED FOR ACCOUNT SENTRY *************** if (GlobalVariableGet("GV_CloseAllAndHalt") > 0) { while(!CloseAllOrders(OP_BUY)) Sleep(1000); //SPH 4.6: will keep trying to close all orders until succeeding while(!CloseAllOrders(OP_SELL)) Sleep(1000); //SPH 4.6: will keep trying to close all orders until succeeding EADisabled = true; text="Account Sentry Signaled to Close All and Halt"; return (0); } else //**************END ACCOUNT SENTRY HOOK **************** text=""; TrackDrawDown(); exitBuy = false; exitSell = false; int CloseOutStatus = CloseOutTradesCheck(); // Check to see if we should go flat on long or short positions if (CloseOutStatus > 0) // CloseOutTradesCheck also updates profit information { if (exitBuy) { while(!CloseAllOrders(OP_BUY)) Sleep(1000); //SPH 4.6: will keep trying to close all orders until succeeding } if (exitSell) { while(!CloseAllOrders(OP_SELL)) Sleep(1000); //SPH 4.6: will keep trying to close all orders until succeeding } if (CloseOutStatus == 2) { EADisabled = true; text="My Money Profit Target Achieved!"; Print(text); return(0); } if (CloseOutStatus == 3) { EADisabled = true; text="DrawDown Threshold Breached!"; Print(text); return(0); } } else // no reason to close out trades and/or disable the EA, so let's continue... { bool TT = false; if (IsTradingTime() && !TradingDisabled) { TT = true; PrepareIndicators(); // Obtain indicator data values // Check for new entry signals. myOrderTypetmp = 1 for sell, 2 for buy, 3 for no signal. myOrderTypetmp=CheckEntrySignal(); if (ReverseCondition) { if (myOrderTypetmp==1) myOrderTypetmp=2; else if (myOrderTypetmp==2) myOrderTypetmp=1; } if (myOrderTypetmp==1 && CurrentOpenOrders[OP_SELL]==0 && IsTradeAllowed() && dtSellAllowed < TimeCurrent()) { Print("Starting New SELL Sequence"); OpenMarketOrders(myOrderTypetmp); // Pass along the Sell Signal } if (myOrderTypetmp==2 && CurrentOpenOrders[OP_BUY]==0 && IsTradeAllowed() && dtBuyAllowed < TimeCurrent()) { Print("Starting New BUY Sequence"); OpenMarketOrders(myOrderTypetmp); // Pass along the Buy Signal } if (IsTradeAllowed()) OpenMarketOrders(3); // Called with no signal present and will open new orders in an existing sequence as needed } } // Now execute the following code whenever the EA is active, regardless of trade time restrictions or disabled trading condition TSManager(); // Check and maintain trailing stops TTstatus = "False"; if (TT) TTstatus = "True"; if (SecureProfitProtection && MarketOpenOrders[OP_BUY]>=OrderstoProtect) text=StringConcatenate(text, "\nSecure Profit Protection Active on BUY sequence."); if (SecureProfitProtection && MarketOpenOrders[OP_SELL]>=OrderstoProtect) text=StringConcatenate(text, "\nSecure Profit Protection Active on SELL sequence."); if (MyMoneyProfitTarget) text=StringConcatenate(text, "\nMy Money Profit Target Progress: ", DoubleToStr(MMProfit[OP_BUY]+MMProfit[OP_SELL],2), " of ", DoubleToStr(My_Money_Profit_Target,2)); //**************Added/Updated for Black out trading times ****** if (!BlackoutTime() && myOrderTypetmp!=2 && CurrentOpenOrders[OP_BUY]==0 && MaxTrades>0) text=StringConcatenate(text, "\nWAITING FOR BUY SIGNAL..."); if (!BlackoutTime() && myOrderTypetmp!=1 && CurrentOpenOrders[OP_SELL]==0 && MaxTrades>0) text=StringConcatenate(text, "\nWAITING FOR SELL SIGNAL..."); if (BlackoutTime()) text=StringConcatenate(text, "\n*** Black out Trading Day. If you want the EA to trade, Change the dates set Blackout to False ***"); //****************************************************** if (LastOrderOpenTime[OP_BUY]==0) LBOT="............................"; else LBOT=TimeToStr(LastOrderOpenTime[OP_BUY],TIME_DATE|TIME_SECONDS); if (LastOrderOpenTime[OP_SELL]==0) LSOT="............................"; else LSOT=TimeToStr(LastOrderOpenTime[OP_SELL],TIME_DATE|TIME_SECONDS); string myComment=StringConcatenate(GMTOffsetStatusInfo,ShowLotSizeSequence(), "\nIsTradeTime=",TTstatus,", myOrderTypetmp=",myOrderTypetmp,", SPP Enabled=",SPPstatus,", MMPT Enabled=",MMPTstatus, "\nBuy: Last Price=",DoubleToStr(LastOrderOpenPrice[OP_BUY],Digits),", Last Time=",LBOT,", Open Mkt Orders=",MarketOpenOrders[OP_BUY],"/",MaxTrades,", Open Profit=",DoubleToStr(SPProfit[OP_BUY],2), "\nSell: Last Price=",DoubleToStr(LastOrderOpenPrice[OP_SELL],Digits),", Last Time=",LSOT,", Open Mkt Orders=",MarketOpenOrders[OP_SELL],"/",MaxTrades,", Open Profit=",DoubleToStr(SPProfit[OP_SELL],2), "\nDay of the Year = ",DayOfYear(),", StartBlackout=", StartBlackout, ", StopBlackout=", StopBlackout, ", Blackout= ", BlackoutTime(), text); Comment(myComment); return(0); } //+------------------------------------------------------------------+ int CheckEntrySignal() // Check for new entry signals. Return 1 for sell, 2 for buy, 3 for no signal. { int myOrderType = 3; if (Strategy == 1) // Spike's Original SPH Strategy { if ((Var7 < Var6 && Var7 < Var8)||(Var3 < Var4 && ((Var1 < Var2) || (Stoch>H_level)) && (Var7 > Var6 && Var7 < Var5))) myOrderType = 1; // signal a sell if ((Var7 > Var5 && Var7 > Var8)||(Var3 > Var4 && ((Var1 > Var2) || (Stoch Var6 && Var7 < Var5))) myOrderType = 2; // signal a buy } ////////////////////////////////////////// // // // ADD NEW STRATEGIES BELOW HERE! // // // ////////////////////////////////////////// if (Strategy == 2) // Spike's New Strategy { if (((Var3 < Var4 && ((Var1 < Var2) || (Stoch>H_level)) && (Var7 > Var6 && Var7 < Var5)||(Var7 < Var6 && Var7 < Var8)))) myOrderType=1; // signal a sell if (((Var3 > Var4 && ((Var1 > Var2) || (Stoch Var6 && Var7 < Var5)||(Var7 > Var6 && Var7 > Var8)))) myOrderType=2; // signal a buy } return(myOrderType); } void PrepareIndicators() { int myMAMode=0; switch (stochMAmode) { case 1: myMAMode=MODE_SMA; break; case 2: myMAMode=MODE_LWMA; break; case 3: myMAMode=MODE_EMA; break; case 4: myMAMode=MODE_SMMA; break; default: myMAMode=MODE_LWMA; break; } // If you add a new indicator, don't forget to add a global variable for it just after the externs. Stoch = iStochastic(NULL, Stoch_TF, K_Period, D_Period, Slow_Period, myMAMode, 0, MODE_SIGNAL, shift); Var1 = iStochastic(NULL, Stoch_TF, 145, D_Period, Slow_Period, MODE_SMA, 1, MODE_MAIN, 0); Var2 = iStochastic(NULL, Stoch_TF, 124, D_Period, Slow_Period, MODE_EMA, 1, MODE_SIGNAL, 0); Var3 = iMA(NULL, MA_TF,MA_Long_Period, 0, MODE_SMA, PRICE_CLOSE, 0); Var4 = iMA(NULL, MA_TF,MA_Short_Period, 0, MODE_EMA, PRICE_CLOSE, 0); Var5 = iEnvelopes(NULL,ENVELOPE_TF ,ENVELOPE_Slow_Period, MODE_SMA, 0, PRICE_CLOSE, 0.9, 1, 1); Var6 = iEnvelopes(NULL,ENVELOPE_TF ,ENVELOPE_Slow_Period, MODE_SMA, 0, PRICE_CLOSE, 0.9, 2, 1); Var7 = iMA(NULL, PERIOD_D1, 2, 0, MODE_SMA, PRICE_CLOSE, 0); Var8 = iMA(NULL, PERIOD_D1, 56, 0, MODE_SMMA, PRICE_CLOSE, 0); } void TSManager() { int gle=0; if (TrailingStop>0) { cnt=OrdersTotal()-1; while(cnt>=0) { if(OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES)==false) break; if (IsMyOrder()) { if (OrderType()==OP_SELL) { if ((OrderOpenPrice()-MarketInfo(OrderSymbol(),MODE_ASK))>=(TrailingStop*Point+Pips*Point)) { if (OrderStopLoss()-TrailingStep*Point>(MarketInfo(OrderSymbol(),MODE_ASK)+TrailingStop*Point)) { GetTradeContext(); RefreshRates(); result=OrderModify(OrderTicket(),OrderOpenPrice(),MarketInfo(OrderSymbol(),MODE_ASK)+TrailingStop*Point,OrderTakeProfit(),0,Purple); if(result!=true) { gle=GetLastError(); Print("Trailing Stop Error = ", gle, ": ",ErrorDescription(gle)); HandleGLE(gle); } else { OrderPrint(); } } } } if (OrderType()==OP_BUY) { if ((MarketInfo(OrderSymbol(),MODE_BID)-OrderOpenPrice())>=(TrailingStop*Point+Pips*Point)) { if (OrderStopLoss()+TrailingStep*Point<(MarketInfo(OrderSymbol(),MODE_BID)-TrailingStop*Point)) { GetTradeContext(); RefreshRates(); result=OrderModify(OrderTicket(),OrderOpenPrice(),MarketInfo(OrderSymbol(),MODE_BID)-TrailingStop*Point,OrderTakeProfit(),0,ArrowsColor); if(result!=true) { gle=GetLastError(); Print("Trailing Stop Error = ", gle, ": ",ErrorDescription(gle)); HandleGLE(gle); } else { OrderPrint(); } } } } } cnt--; } } } void OpenMarketOrders(int mySignal) // mySignal = 1 for sell, 2 for buy, 3 for no signal. { int cnt=0, gle=0, ticket, attempts, myCount; bool ModifySucceeded; if ((mySignal==1 || mySignal==3) && (dtSellAllowed < TimeCurrent()) && ((CurrentOpenOrders[OP_SELL]>0 && CurrentOpenOrders[OP_SELL]=Pips*Point) && (LastOrderOpenPrice[OP_SELL]>0)) || (CurrentOpenOrders[OP_SELL]==0 && mySignal==1))) { myCount=1; if (RecoveryMode && CurrentOpenOrders[OP_SELL]>0 && CurrentOpenOrders[OP_SELL]=Pips*Point*2) myCount = MathFloor((Bid-LastOrderOpenPrice[OP_SELL])/(Pips*Point)); CalculateLotArray(OP_SELL,CurrentOpenOrders[OP_SELL]); for(cnt=0;cnt0) { if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) { Print("SELL order opened : ",OrderOpenPrice()); LastOrderOpenPrice[OP_SELL]=OrderOpenPrice(); LastOrderOpenTime[OP_SELL]=OrderOpenTime(); UpdateOrderStatus(true); break; } } else { gle=GetLastError(); if (gle==2 || gle==144) { dtSellAllowed = TimeCurrent() + 3600; Print("Manual Trade Confirmation Dialog aborted. No Sell Positions will be attempted for the next 1 hour."); return; } Print("Error opening SELL order: ",gle,": ",ErrorDescription(gle)); HandleGLE(gle); attempts++; RefreshRates(); } if(attempts >= 20) { Print("20 attempts to open SELL position have failed"); break; } } ModifySucceeded=false; attempts=0; while(!ModifySucceeded && attempts<100) { GetTradeContext(); RefreshRates(); ModifySucceeded=OrderModify(ticket,OrderOpenPrice(),sl,tp,0,GreenYellow); if(!ModifySucceeded) { gle=GetLastError(); if (gle==2 || gle==144 || gle==4051) { Print("Manual Trade Confirmation Dialog aborted or invalid ticket. No Sell Positions will be attempted for the next 1 hour."); dtSellAllowed = TimeCurrent() + 3600; return; } Print("Error modifying SELL order: ",gle,": ",ErrorDescription(gle)); Print("cnt=",cnt,", myBaseLot=",myBaseLot,", BuyPrice=",BuyPrice,", ticket=",ticket); HandleGLE(gle); attempts++; RefreshRates(); } } if(attempts >= 50) { Print("A Critical Error Occurred! The expert could not modify SELL position!"); } //************************************************************************************************************************ //*************TOM - added call to new routine to revise all trades in set to new tp value ******************************* if (tp > 0) { ModifyTakeProfits(tp, MagicNumber, OP_SELL); } //************************************************************************************************************************ } } if ((mySignal==2 || mySignal==3) && (dtBuyAllowed < TimeCurrent()) && ((CurrentOpenOrders[OP_BUY]>0 && CurrentOpenOrders[OP_BUY]=Pips*Point) && (LastOrderOpenPrice[OP_BUY]>0)) || (CurrentOpenOrders[OP_BUY]==0 && mySignal==2))) { myCount=1; if (RecoveryMode && CurrentOpenOrders[OP_BUY]>0 && CurrentOpenOrders[OP_BUY]=Pips*Point*2) myCount = MathFloor((LastOrderOpenPrice[OP_BUY]-Ask)/(Pips*Point)); CalculateLotArray(OP_BUY,CurrentOpenOrders[OP_BUY]); for(cnt=0;cnt0) { if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) { Print("BUY order opened : ",OrderOpenPrice()); LastOrderOpenPrice[OP_BUY]=OrderOpenPrice(); LastOrderOpenTime[OP_BUY]=OrderOpenTime(); UpdateOrderStatus(true); break; } } else { gle=GetLastError(); if (gle==2 || gle==144) { Print("Manual Trade Confirmation Dialog aborted. No Buy Positions will be attempted for the next 1 hour."); dtBuyAllowed = TimeCurrent() + 3600; return; } Print("Error opening BUY order: ",gle,": ",ErrorDescription(gle)); HandleGLE(gle); attempts++; RefreshRates(); } if(attempts >= 20) { Print("20 attempts to open BUY position have failed"); break; } } ModifySucceeded=false; attempts=0; while(!ModifySucceeded && attempts<100) { GetTradeContext(); RefreshRates(); ModifySucceeded=OrderModify(ticket,OrderOpenPrice(),sl,tp,0,GreenYellow); if(!ModifySucceeded) { gle=GetLastError(); if (gle==2 || gle==144 || gle==4051) { Print("Manual Trade Confirmation Dialog aborted or invalid ticket. No Buy Positions will be attempted for the next 1 hour."); dtBuyAllowed = TimeCurrent() + 3600; return; } Print("Error modifying BUY order: ",gle,": ",ErrorDescription(gle)); Print("cnt=",cnt,", myBaseLot=",myBaseLot,", BuyPrice=",BuyPrice,", ticket=",ticket); HandleGLE(gle); attempts++; RefreshRates(); } } if(attempts >= 50) { Print("A Critical Error Occurred! The expert could not modify BUY position!"); } //************************************************************************************************************************ //*************TOM - added call to new routine to revise all trades in set to new tp value ******************************* if (tp > 0) { ModifyTakeProfits(tp, MagicNumber, OP_BUY); } //************************************************************************************************************************ } } } bool GetTradeContext() { bool hadToWait=false; while(!IsTradeAllowed()) { Sleep(5000); hadToWait=true; } while(IsTradeContextBusy()) { Sleep(200); hadToWait=true; } return(hadToWait); } void DeleteAllObjects() { ObjectDelete("MaxDD"); ObjectDelete("B/E"); int obj_total=ObjectsTotal(); string name; for(int i=0;i<=obj_total;i++) { name=ObjectName(i); if (name!="") ObjectDelete(name); } } bool IsTradingTime() { 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); } string GMTSourceURL = "http://wwp.greenwichmeantime.com/time/scripts/clock-8/x.php"; string GMTUserAgent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)"; int AutoGMTOffset() { string gvName1 = StringConcatenate(AccountNumber(),"_GMTOffset_Value"); string gvName2 = StringConcatenate(AccountNumber(),"_GMTOffset_Timestamp"); double gvValue1 = GlobalVariableGet(gvName1); double gvValue2 = GlobalVariableGet(gvName2); if ((GlobalVariableCheck(gvName1) && GlobalVariableCheck(gvName2)) && !((DayOfWeek() < TimeDayOfWeek(gvValue2)) || (DayOfWeek()== TimeDayOfWeek(gvValue2) && TimeCurrent()-gvValue2 > 86400) || (DayOfWeek() > TimeDayOfWeek(gvValue2) && TimeCurrent()-gvValue2 > 604800))) // Values are valid and we have not passed over a Sunday since the last valid time GMT was checked // We add the above restrictions and use the global variable to minimize hits to the new public time source { //Print ("Successfully read GMT Offset from globals"); return (gvValue1); } else { Comment("Connecting to public GMT time source..."); string status; int result, offsetTmp; InternetHandle = InternetOpenA(GMTUserAgent, 0, "0", "0", 0); string myBuffer = "ABCDEFGHIJ"; if (!RetrieveURLData(GMTSourceURL, myBuffer)) { if (InternetHandle == 0) status = "Error connecting to AutoGMT time source."; result = -999999999; Comment(status); Print(status); Sleep(3000); } else { offsetTmp = TimeCurrent() - StrToInteger(myBuffer); result = MathFloor((offsetTmp + 1800) / 3600); if (result <= 24 && result >= -24) { GlobalVariableSet(gvName1,result); GlobalVariableSet(gvName2,TimeCurrent()); //Print ("Successfully stored GMT Offset in globals"); } } InternetCloseHandle(InternetHandle); return(result); } } bool RetrieveURLData(string URL, string &datum) { int thisHandle = InternetOpenUrlA(InternetHandle, URL, "0", 0, -2080374528, 0); if (thisHandle == 0) return (false); //failure int a[] = {1}; string anotherBuffer = "abcdefghij"; int myStatus = InternetReadFile(thisHandle, anotherBuffer, 10, a); if (thisHandle != 0) InternetCloseHandle(thisHandle); datum = anotherBuffer; return(true); //since datum is a pointer, its contents updated between functions } // Normalize hours to fall into 0-23 range, regardless of input int NormalizedHourParam(int myParam) { while (true) { if (myParam >= 24) { myParam -= 24; continue; } if (myParam >= 0) break; myParam += 24; } return(myParam); } // Track Draw Down statistics for this traded symbol void TrackDrawDown() { double OpenProfit = SPProfit[0]+SPProfit[1]; if (OpenProfit < MaxDD) MaxDD = OpenProfit; if ((OpenProfit/AccountBalance())*100 < MaxPercentDD) MaxPercentDD = (OpenProfit/AccountBalance())*100; if (ShowDDinfoOnChart) { ObjectCreate( "B/E", OBJ_LABEL,0,0,0,0,0,0); ObjectSet( "B/E", OBJPROP_CORNER,3); ObjectSet( "B/E", OBJPROP_XDISTANCE, 3); ObjectSet( "B/E", OBJPROP_YDISTANCE, 30); ObjectSetText("B/E", "B/E: $"+DoubleToStr(NormalizeDouble(AccountBalance(),2),2)+"/"+DoubleToStr(NormalizeDouble(AccountEquity(),2),2),12,"Impact",White); ObjectCreate( "MaxDD", OBJ_LABEL,0,0,0,0,0,0); ObjectSet( "MaxDD", OBJPROP_CORNER,3); ObjectSet( "MaxDD", OBJPROP_XDISTANCE, 3); ObjectSet( "MaxDD", OBJPROP_YDISTANCE, 2); ObjectSetText("MaxDD", "RDD Max: $"+DoubleToStr(NormalizeDouble(MaxDD,2),2)+"/"+DoubleToStr(NormalizeDouble(MaxPercentDD,2),1)+"%",12,"Impact",White); } return; } // Check for any conditions where we should close out trades and possibly halt further trading on this symbol // return 0: no close signal, 1: close for buy, sell or both, 2: close for buy, sell or both, and Disable EA // return 3: Signal Disabling of EA due to Draw Down Control int CloseOutTradesCheck() { int result = 0; // Check to see if I reached my equity + closed profit target for this symbol + magic numbers if (MyMoneyProfitTarget) { MMProfit[0]=0; MMProfit[1]=0; // First, we iterate through all open positions for this symbol for(cnt=0;cnt= My_Money_Profit_Target) { text = text + "\nClosing all orders and stop trading because My_Money_Profit_Target reached for this symbol."; Print("Closing all orders and stop trading because My_Money_Profit_Target reached for this symbol."); Print("Profit: ",NormalizeDouble(MMProfit[OP_BUY]+MMProfit[OP_SELL],2)," Equity: ",NormalizeDouble(AccountEquity(),2)); result = 2; exitBuy = true; exitSell = true; } } // SecureProfit Protection: Close out long running trades with a small profit SPProfit[0]=0; SPProfit[1]=0; for(cnt=0;cnt=SecureProfit && MarketOpenOrders[OP_BUY]>=OrderstoProtect) { text = text + "\nClosing BUY orders because account protection with SecureProfit was triggered."; Print("Closing BUY orders because account protection with SecureProfit was triggered."); Print("Balance: ",NormalizeDouble(AccountBalance(),2)," Equity: ", NormalizeDouble(AccountEquity(),2)," Profit: ",NormalizeDouble(SPProfit[OP_BUY],2)); result = 1; exitBuy = true; } if (SecureProfitProtection && SPProfit[OP_SELL]>=SecureProfit && MarketOpenOrders[OP_SELL]>=OrderstoProtect) { text = text + "\nClosing SELL orders because account protection with SecureProfit was triggered."; Print("Closing SELL orders because account protection with SecureProfit was triggered."); Print("Balance: ",NormalizeDouble(AccountBalance(),2)," Equity: ", NormalizeDouble(AccountEquity(),2)," Profit: ",NormalizeDouble(SPProfit[OP_SELL],2)); result = 1; exitSell = true; } // Check to see if any trades recently closed due to hitting StopLoss or TakeProfit, if so, close out that sequence //UpdateOrderStatus(false); // Refresh current open order count, but leave previous count alone UpdateOrderStatus(true); // Refresh current open order count, disable auto-closing routine if (PreviousOpenOrders[OP_BUY] > CurrentOpenOrders[OP_BUY]) { exitBuy = true; result = 1; } if (PreviousOpenOrders[OP_SELL] > CurrentOpenOrders[OP_SELL]) { exitSell = true; result = 1; } // Close out any open trades if TTMGoFlat=true and we are outside of trading hours or trading days if (!IsTradingTime() && TTMGoFlat && CurrentOpenOrders[0]+CurrentOpenOrders[1]>0) { text = text + "\nClosing orders because outside of trading window."; Print("Closing orders because outside of trading window."); Print("Balance: ",NormalizeDouble(AccountBalance(),2)," Equity: ", NormalizeDouble(AccountEquity(),2)," Profit: ",NormalizeDouble(SPProfit[OP_BUY]+SPProfit[OP_SELL],2)); exitBuy = true; exitSell = true; result = 1; } // If DDC thresholds are breached, go flat and disabled further trading if ((MaxDDControl && MathAbs(MaxDD)>=MathAbs(MaxAllowedDD)) || (MaxPercentDDControl && MathAbs(MaxPercentDD)>=MathAbs(MaxAllowedPercentDD))) { exitBuy = true; exitSell = true; result = 3; } return(result); } // All the fancy risk management code is here. If mm=0, just use the user-specified lot size. // If mm=1, use the basic risk multiplier approach. If mm=2, set max % of account balance to risk per trade sequence void CalculateLotArray(int myDirection,int openTradeCount) { double MaxLossAmount; if (mm <= 0 || mm > 2 ) { LotSizeArray[0,myDirection]=NormalizedLots(Lots,true); for (cnt=1;cnt0 && AccountBalance() > LotSizeArray[99,myDirection])) // Only recalc if no trades open or if account balance has increased since the trade sequence has begun { double myLotStep = MarketInfo(Symbol(), MODE_LOTSTEP); if (TradeMicroLots) myLotStep = 0.01; BaseLot=MathCeil(AccountBalance()*risk/10000)/100; // BaseLot amount to 0.01 precision BaseLot=BaseLot * 100000 / MarketInfo(Symbol(), MODE_LOTSIZE); // Adjust for broker lot size information (mini vs. std) LotSizeArray[0,myDirection]=NormalizedLots(BaseLot,true); for (cnt=1;cnt0 && (openTradeCount==0 || (openTradeCount>0 && AccountBalance() > LotSizeArray[99,myDirection]))) // Only recalc if no trades open or if account balance has increased since the trade sequence has begun { MaxLossAmount = 0; for (cnt=0;cnt=MaxTradeLotSize1) { // Assign incrementally increasing lot size values from the outside in to ramp up risk more evenly // Also called to handle when MaxTradeLotSize exceeds maximum allowed by broker LotSizeArray[MaxTrades-1,myDirection]=MaxTradeLotSize2; for (cnt=MaxTrades-2;cnt>=0;cnt--) LotSizeArray[cnt,myDirection]=LotSizeArray[cnt+1,myDirection]/multiply; for (cnt=MaxTrades-2;cnt>=0;cnt--) LotSizeArray[cnt,myDirection]=NormalizedLots(LotSizeArray[cnt,myDirection],false); } else { // BaseLot is below Minimum Allowed Lotsize, so MaxTradeLotSize2 not large enough to properly spread out the risk LotSizeArray[0,myDirection]=NormalizedLots(BaseLot,false); for (cnt=1;cntMarketInfo(Symbol(), MODE_MAXLOT)) myLotSize=MarketInfo(Symbol(), MODE_MAXLOT); return(myLotSize); } // Get all the time variables set to a proper 0-23 range after adjusting for GMT offset using public time server // or manual GMT offset depending on the configuration parameter externs // Following function updated on 20100211 to handle errors better int InitializeTimeVariables() { int tmpGMToffset; string GMTMode; if (UseAutoGMToffset) { if (!IsTesting()) { tmpGMToffset = AutoGMTOffset(); if (tmpGMToffset > 24 || tmpGMToffset < -24) { if (AutoFallbackOnFail) { GMTMode = " (auto-fallback)"; } else { text="Failure getting AutoGMToffset, cannot open time-based trades until condition clears."; Comment(text); Print(text); Sleep(120000); // After 2 minutes, we will try again. return(-1); } } else { ManualGMToffset = tmpGMToffset; GMTMode = " (auto)"; } } else { text="WARNING: When backtesting, only ManualGMTOffset value can be used, ensure it is set correctly!"; Print(text); GMTMode = " (manual)"; } } else { GMTMode = " (manual)"; } GMTOffsetStatusInfo = StringConcatenate("GMT Offset: ", DoubleToStr(ManualGMToffset, 1), GMTMode); GMTStartHour = NormalizedHourParam(GMTStartHour); GMTStopHour = NormalizedHourParam(GMTStopHour); OneTimeInitialize = false; // clear the flag so this code base runs only one time return(0); } // Move this frequently used code block here to make the code easier to maintain bool IsMyOrder() { //if (OrderSymbol() == Symbol() && (OrderMagicNumber() == MagicNumber || OrderMagicNumber() == MagicMigrate)) return(true); //DM: removed MagicMigrate on 20100211 if (OrderSymbol() == Symbol() && (OrderMagicNumber() == MagicNumber)) return(true); return(false); } // Close all Buy or Sell orders. orderMode should be OP_BUY or OP_SELL // Function returns false if it fails, true if it succeeds bool CloseAllOrders(int orderMode) { int OrderCount=0, gle=0; 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 (IsMyOrder()) { if ((mode==orderMode) || (mode==(orderMode+2)) || (mode==(orderMode+4))) { 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)); HandleGLE(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;cnt0) { if (OrderSelect(TicketArray[cnt], SELECT_BY_TICKET, MODE_TRADES)) { mode=OrderType(); GetTradeContext(); RefreshRates(); if (mode==OP_BUY) ClosePrice=NormalizeDouble(Bid,myDigits); if (mode==OP_SELL) ClosePrice=NormalizeDouble(Ask,myDigits); 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)); HandleGLE(gle); } } else { if (OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Bid,myDigits),slippage,ArrowsColor)) { TicketArray[cnt]=0; } else { gle=GetLastError(); Print("Error closing order #",TicketArray[cnt],": Error #",gle,": ",ErrorDescription(gle)); HandleGLE(gle); } } } else { gle=GetLastError(); Print("Error selecting order #",TicketArray[cnt],": Error #",gle,": ",ErrorDescription(gle)); HandleGLE(gle); } } } retries++; } bool CloseAllSuccess=true; for(cnt=0;cnt0) { CloseAllSuccess=false; Alert("Could not close ticket #",TicketArray[cnt],"! Will keep retrying."); } } if(CloseAllSuccess) { PreviousOpenOrders[orderMode] = 0; CurrentOpenOrders[orderMode] = 0; LastOrderOpenPrice[orderMode] = 0; CalculateLotArray(orderMode,0); // Recalculate lots now that the account balance has changed so the chart display is refreshed 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 } } // The following function added in 4.6 to better implement recommended error handling of opening, modifying and closing orders // per the MQL4 documentation and best practices by waiting a specified period of time before retrying certain actions void HandleGLE(int k) { if(k==4) Sleep(30000); if(k==6) Sleep(5000); if(k==8) Sleep(5000); if(k==128) Sleep(60000); if(k==129) Sleep(5000); if(k==130) Sleep(5000); if(k==132) Sleep(300000); if(k==135) return; if(k==136) Sleep(5000); if(k==138) return; if(k==141) Sleep(5000); if(k==142) Sleep(60000); if(k==143) Sleep(60000); if(k==145) Sleep(15000); if(k==146) GetTradeContext(); return; } void UpdateOrderStatus(bool init) { CurrentOpenOrders[OP_BUY]=0; CurrentOpenOrders[OP_SELL]=0; MarketOpenOrders[OP_BUY]=0; MarketOpenOrders[OP_SELL]=0; int myOrderType; for(cnt=0;cnt 1) myOrderType-=2; // Normalize all buy types to OP_BUY and all sell types to OP_SELL CurrentOpenOrders[myOrderType]++; if(LastOrderOpenTime[myOrderType]0) { // iterate array result=StringConcatenate("\nBuy LotSizing: ",DoubleToStr(LotSizeArray[0,OP_BUY],x)); for (int myCount=1;myCount0 || CurrentOpenOrders[OP_SELL]>0) { for (int count=0;count 0 && CurrentOpenOrders[OP_BUY]>0) // BUY Lot Array Entry { a = StringFind(gvName, "_", StringLen(gvBase) + 1); b = StringFind(gvName, "_", a + 1); a += 1; StoredPos = StrToInteger(StringSubstr(gvName,a,b-a)); LotSizeArray[StoredPos,OP_BUY] = GlobalVariableGet(gvName); } if (StringFind(gvName, "S_", StringLen(gvBase)-1) > 0 && CurrentOpenOrders[OP_SELL]>0) // SELL Lot Array Entry { a = StringFind(gvName, "_", StringLen(gvBase) + 1); b = StringFind(gvName, "_", a + 1); a += 1; StoredPos = StrToInteger(StringSubstr(gvName,a,b-a)); LotSizeArray[StoredPos,OP_SELL] = GlobalVariableGet(gvName); } } } // Now verify arrays, if either is inconsistent, we will just recalculate that one for (count=0;count0)) BuyReadSuccess=false; if (!(LotSizeArray[count,OP_SELL]>0)) SellReadSuccess=false; } if (!(LotSizeArray[99,OP_BUY]>0)) BuyReadSuccess=false; if (!(LotSizeArray[99,OP_SELL]>0)) SellReadSuccess=false; if (!BuyReadSuccess) CalculateLotArray(OP_BUY,0); if (!SellReadSuccess) CalculateLotArray(OP_SELL,0); } else // No BUY or SELL orders opened { CalculateLotArray(OP_BUY,0); CalculateLotArray(OP_SELL,0); } // Calculate the maximum draw down potential per sequence here // This is the same code from the bottom of the CalculateLotArray function double MaxLossAmount = 0; for (cnt=0;cnt1) for(cnt=0;cnt 1) { Print("LastError = (", err, "): ", ErrorDescription(err)); HandleGLE(err); } else { OrderPrint(); } } } } } //********************************************************************************************************************* //********************************************************************************************************************* //******************TOM - new routine for derermining the set's stop loss which would be with the level 1 order ******* //****************** I'm just looping through the set but you could probably just grab the oldest trade ********** double CalcStopLoss(int op) { int ticket; double HighestBuy, LowestSell; double HighestBuySL, LowestSellSL; double newSL; //---- HighestBuy = 0; LowestSell = 9999; HighestBuySL = 0; LowestSellSL = 0; newSL = -1; //SPH 4.6: Will force an error on OrderModify if there is an internal error in this function by initializing to -1 for(int i=0;i HighestBuy) { HighestBuy = OrderOpenPrice(); HighestBuySL = OrderStopLoss(); } } if (op == OP_SELL && OrderType() == OP_SELL) { if (OrderOpenPrice() < LowestSell) { LowestSell = OrderOpenPrice(); LowestSellSL = OrderStopLoss(); } } } switch (op) { case OP_BUY: if (HighestBuySL==0) newSL = BuyPrice-StopLoss*Point; else newSL = HighestBuySL; break; case OP_SELL: if (LowestSellSL==0) newSL = SellPrice+StopLoss*Point; else newSL = LowestSellSL; break; default: break; } return (newSL); } //********************************************************************************************************************* //********************************************************************************************************************* //********** TOM - still on my to do list - plan to log DD info for each bar to plot in excel ************************* //********** I want to overlay all the pairs to see if we have tendency for confluence of DD given ************** //********** natural pair correlations - getting hit by an occasional wave (SL) should be expected ************** //********** but want to try and avoid rogue waves where we get hit by multiple at same time ******************** //********** I have not hooked this in as I'm still deciding what I want to log ********************************* void LogPerformance() { int handle; handle=FileOpen(StringConcatenate(EAName, " Log ", Symbol(), ".txt"), FILE_CSV|FILE_READ|FILE_WRITE, ';'); if(handle > 0) { FileSeek(handle, 0, SEEK_END); FileWrite(handle, Symbol(), TimeToStr(TimeCurrent()), AccountBalance(), AccountEquity()); FileClose(handle); } } //********************************************************************************************************************* //****************** Code added by David Heath to handle Black Out days //********************************************************************************************************************* 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); } //******************** Added by David Heath to handle Black out Days //The following function merged in from Peter Wu's code contribution //These come from Spike's latest set files. //DO NOT override GMT settings from inputs. void SetParameters() { int SettingLoaded = 0; //s05=--MONEY MANAGEMENT-- //MM_0=mm=0, risk is ignored, just use Lots parameter //MM_1=mm=1, risk is basic multiplier based on account balance //MM_2=mm=2, risk is % of account balance to risk per sequence mm=2; //MyRisk=set risk to use when calculating lot size risk=15.00000000; TradeMicroLots=0; //s06=--MAGIC NUMBERS-- MagicNumber=222777; //s09=--DRAWDOWN CONTROL TOOL-- //DDC1=Max DD in money allowed? MaxDDControl=0; MaxAllowedDD=10000.00000000; //DDC2=Max DD in percentage allowed? MaxPercentDDControl=0; MaxAllowedPercentDD=30.00000000; //s10=--DRAWDOWN REPORTING== ShowDDinfoOnChart=1; //s11=--OTHER SETTINGS-- //reverse=if one the desition to go long/short will be reversed ReverseCondition=0; if(StringSubstr(Symbol(),0,6) == "USDJPY") ///////////////////////////////////////////1 { //s01=--STOCH SETTINGS-- K_Period=145; D_Period=20; Slow_Period=80; Stoch_TF=60; shift=4; H_level=78; L_level=22; //ChooseMAMode=Choose 1=mode SMA, 2=mode LWMA, 3=mode EMA, 4=mode SMMA stochMAmode=1; //s02=--ENVELOPE SETTINGS-- ENVELOPE_Slow_Period=16; ENVELOPE_TF=1440; //s03=--MOVING AVERAGE SETTINGS-- MA_TF=60; MA_Long_Period=190; MA_Short_Period=80; //s04=--TRADE SETTINGS-- Strategy=1; Lots=0.0100000; TakeProfit=110; multiply=2.00000000; MaxTrades=5; Pips=90; StopLoss=580; TrailingStop=0; TrailingStep=0; RecoveryMode=0; //s07=--CUTLOSS SETTING-- MyMoneyProfitTarget=0; My_Money_Profit_Target=50.00000000; SecureProfitProtection=0; //SP=If profit made is bigger than SecureProfit we close the orders SecureProfit=10; //OTP=Number of orders to enable the account protection OrderstoProtect=3; //s08=--TRADING TIME MANAGEMENT-- //TTM1=Set time frames when new trades can open. //TTM2=If Starthour = Stophour, then trade 24/5. //TTM3=If TTMGoFlat=true, close all open trades //TTM4=when outside trading hours or days. GMTStartHour=0; GMTStopHour=0; TradeOnFriday=1; TTMGoFlat=0; SettingLoaded = 1; } else if(StringSubstr(Symbol(),0,6) == "AUDUSD") ///////////////////////////////////////////2 { //s01=--STOCH SETTINGS-- K_Period=145; D_Period=20; Slow_Period=80; Stoch_TF=60; shift=4; H_level=78; L_level=22; //ChooseMAMode=Choose 1=mode SMA, 2=mode LWMA, 3=mode EMA, 4=mode SMMA stochMAmode=1; //s02=--ENVELOPE SETTINGS-- ENVELOPE_Slow_Period=14; ENVELOPE_TF=1440; //s03=--MOVING AVERAGE SETTINGS-- MA_TF=60; MA_Long_Period=190; MA_Short_Period=80; //s04=--TRADE SETTINGS-- Strategy=1; Lots=0.0100000; TakeProfit=95; multiply=2.20000000; MaxTrades=5; Pips=120; StopLoss=675; TrailingStop=0; TrailingStep=0; RecoveryMode=0; //s07=--CUTLOSS SETTING-- MyMoneyProfitTarget=0; My_Money_Profit_Target=50.00000000; SecureProfitProtection=0; //SP=If profit made is bigger than SecureProfit we close the orders SecureProfit=2; //OTP=Number of orders to enable the account protection OrderstoProtect=3; //s08=--TRADING TIME MANAGEMENT-- //TTM1=Set time frames when new trades can open. //TTM2=If Starthour = Stophour, then trade 24/5. //TTM3=If TTMGoFlat=true, close all open trades //TTM4=when outside trading hours or days. GMTStartHour=0; GMTStopHour=0; TradeOnFriday=1; TTMGoFlat=0; SettingLoaded = 2; } else if(StringSubstr(Symbol(),0,6) == "EURAUD") ///////////////////////////////////////////3 { //s01=--STOCH SETTINGS-- K_Period=145; D_Period=20; Slow_Period=80; Stoch_TF=60; shift=4; H_level=95; L_level=5; //ChooseMAMode=Choose 1=mode SMA, 2=mode LWMA, 3=mode EMA, 4=mode SMMA stochMAmode=1; //s02=--ENVELOPE SETTINGS-- ENVELOPE_Slow_Period=12; ENVELOPE_TF=1440; //s03=--MOVING AVERAGE SETTINGS-- MA_TF=240; MA_Long_Period=110; MA_Short_Period=90; //s04=--TRADE SETTINGS-- Strategy=1; Lots=0.0100000; TakeProfit=170; multiply=1.80000000; MaxTrades=6; Pips=60; StopLoss=650; TrailingStop=0; TrailingStep=0; RecoveryMode=0; //s07=--CUTLOSS SETTING-- MyMoneyProfitTarget=0; My_Money_Profit_Target=50.00000000; SecureProfitProtection=1; //SP=If profit made is bigger than SecureProfit we close the orders SecureProfit=15; //OTP=Number of orders to enable the account protection OrderstoProtect=3; //s08=--TRADING TIME MANAGEMENT-- //TTM1=Set time frames when new trades can open. //TTM2=If Starthour = Stophour, then trade 24/5. //TTM3=If TTMGoFlat=true, close all open trades //TTM4=when outside trading hours or days. GMTStartHour=0; GMTStopHour=0; TradeOnFriday=1; TTMGoFlat=0; SettingLoaded = 3;} else if(StringSubstr(Symbol(),0,6) == "EURCAD") ///////////////////////////////////////////4 { //s01=--STOCH SETTINGS-- K_Period=145; D_Period=20; Slow_Period=80; Stoch_TF=60; shift=4; H_level=95; L_level=5; //ChooseMAMode=Choose 1=mode SMA, 2=mode LWMA, 3=mode EMA, 4=mode SMMA stochMAmode=1; //s02=--ENVELOPE SETTINGS-- ENVELOPE_Slow_Period=10; ENVELOPE_TF=1440; //s03=--MOVING AVERAGE SETTINGS-- MA_TF=240; MA_Long_Period=190; MA_Short_Period=80; //s04=--TRADE SETTINGS-- Strategy=1; Lots=0.1000000; TakeProfit=100; multiply=1.70000000; MaxTrades=6; Pips=70; StopLoss=490; TrailingStop=0; TrailingStep=0; RecoveryMode=0; //s07=--CUTLOSS SETTING-- MyMoneyProfitTarget=0; My_Money_Profit_Target=50.00000000; SecureProfitProtection=1; //SP=If profit made is bigger than SecureProfit we close the orders SecureProfit=10; //OTP=Number of orders to enable the account protection OrderstoProtect=4; //s08=--TRADING TIME MANAGEMENT-- //TTM1=Set time frames when new trades can open. //TTM2=If Starthour = Stophour, then trade 24/5. //TTM3=If TTMGoFlat=true, close all open trades //TTM4=when outside trading hours or days. GMTStartHour=0; GMTStopHour=0; TradeOnFriday=1; TTMGoFlat=0; SettingLoaded = 4; } else if(StringSubstr(Symbol(),0,6) == "EURCHF") ///////////////////////////////////////////5 { //s01=--STOCH SETTINGS-- K_Period=145; D_Period=20; Slow_Period=80; Stoch_TF=60; shift=4; H_level=70; L_level=30; //ChooseMAMode=Choose 1=mode SMA, 2=mode LWMA, 3=mode EMA, 4=mode SMMA stochMAmode=1; //s02=--ENVELOPE SETTINGS-- ENVELOPE_Slow_Period=16; ENVELOPE_TF=1440; //s03=--MOVING AVERAGE SETTINGS-- MA_TF=60; MA_Long_Period=190; MA_Short_Period=80; //s04=--TRADE SETTINGS-- Strategy=2; Lots=0.0100000; TakeProfit=70; multiply=1.10000000; MaxTrades=5; Pips=20; StopLoss=250; TrailingStop=0; TrailingStep=0; RecoveryMode=0; //s07=--CUTLOSS SETTING-- MyMoneyProfitTarget=0; My_Money_Profit_Target=50.00000000; SecureProfitProtection=0; //SP=If profit made is bigger than SecureProfit we close the orders SecureProfit=7; //OTP=Number of orders to enable the account protection OrderstoProtect=3; //s08=--TRADING TIME MANAGEMENT-- //TTM1=Set time frames when new trades can open. //TTM2=If Starthour = Stophour, then trade 24/5. //TTM3=If TTMGoFlat=true, close all open trades //TTM4=when outside trading hours or days. GMTStartHour=0; GMTStopHour=0; TradeOnFriday=1; TTMGoFlat=0; SettingLoaded = 5; } else if(StringSubstr(Symbol(),0,6) == "EURUSD") ///////////////////////////////////////////6 { //s01=--STOCH SETTINGS-- K_Period=145; D_Period=20; Slow_Period=80; Stoch_TF=60; shift=4; H_level=78; L_level=22; //ChooseMAMode=Choose 1=mode SMA, 2=mode LWMA, 3=mode EMA, 4=mode SMMA stochMAmode=1; //s02=--ENVELOPE SETTINGS-- ENVELOPE_Slow_Period=11; ENVELOPE_TF=1440; //s03=--MOVING AVERAGE SETTINGS-- MA_TF=240; MA_Long_Period=190; MA_Short_Period=80; //s04=--TRADE SETTINGS-- Strategy=1; Lots=0.0100000; TakeProfit=109; multiply=1.8000000; MaxTrades=6; Pips=95; StopLoss=660; TrailingStop=0; TrailingStep=0; RecoveryMode=0; //s07=--CUTLOSS SETTING-- MyMoneyProfitTarget=0; My_Money_Profit_Target=50.00000000; SecureProfitProtection=1; //SP=If profit made is bigger than SecureProfit we close the orders SecureProfit=5; //OTP=Number of orders to enable the account protection OrderstoProtect=5; //s08=--TRADING TIME MANAGEMENT-- //TTM1=Set time frames when new trades can open. //TTM2=If Starthour = Stophour, then trade 24/5. //TTM3=If TTMGoFlat=true, close all open trades //TTM4=when outside trading hours or days. GMTStartHour=0; GMTStopHour=0; TradeOnFriday=1; TTMGoFlat=0; SettingLoaded = 6; } else if(StringSubstr(Symbol(),0,6) == "GBPCHF") ///////////////////////////////////////////7 { //s01=--STOCH SETTINGS-- K_Period=145; D_Period=20; Slow_Period=80; Stoch_TF=60; shift=4; H_level=78; L_level=22; //ChooseMAMode=Choose 1=mode SMA, 2=mode LWMA, 3=mode EMA, 4=mode SMMA stochMAmode=1; //s02=--ENVELOPE SETTINGS-- ENVELOPE_Slow_Period=14; ENVELOPE_TF=1440; //s03=--MOVING AVERAGE SETTINGS-- MA_TF=60; MA_Long_Period=190; MA_Short_Period=80; //s04=--TRADE SETTINGS-- Strategy=1; Lots=0.0100000; TakeProfit=110; multiply=1.70000000; MaxTrades=6; Pips=90; StopLoss=600; TrailingStop=0; TrailingStep=0; RecoveryMode=0; //s07=--CUTLOSS SETTING-- MyMoneyProfitTarget=0; My_Money_Profit_Target=50.00000000; SecureProfitProtection=1; //SP=If profit made is bigger than SecureProfit we close the orders SecureProfit=3; //OTP=Number of orders to enable the account protection OrderstoProtect=5; //s08=--TRADING TIME MANAGEMENT-- //TTM1=Set time frames when new trades can open. //TTM2=If Starthour = Stophour, then trade 24/5. //TTM3=If TTMGoFlat=true, close all open trades //TTM4=when outside trading hours or days. GMTStartHour=0; GMTStopHour=0; TradeOnFriday=1; TTMGoFlat=0; SettingLoaded = 7; } else if(StringSubstr(Symbol(),0,6) == "USDCAD") ///////////////////////////////////////////8 { //s01=--STOCH SETTINGS-- K_Period=145; D_Period=20; Slow_Period=80; Stoch_TF=60; shift=4; H_level=95; L_level=5; //ChooseMAMode=Choose 1=mode SMA, 2=mode LWMA, 3=mode EMA, 4=mode SMMA stochMAmode=1; //s02=--ENVELOPE SETTINGS-- ENVELOPE_Slow_Period=10; ENVELOPE_TF=1440; //s03=--MOVING AVERAGE SETTINGS-- MA_TF=240; MA_Long_Period=190; MA_Short_Period=80; //s04=--TRADE SETTINGS-- Strategy=1; Lots=0.0100000; TakeProfit=90; multiply=1.80000000; MaxTrades=6; Pips=60; StopLoss=400; TrailingStop=0; TrailingStep=0; RecoveryMode=0; //s07=--CUTLOSS SETTING-- MyMoneyProfitTarget=0; My_Money_Profit_Target=50.00000000; SecureProfitProtection=0; //SP=If profit made is bigger than SecureProfit we close the orders SecureProfit=10; //OTP=Number of orders to enable the account protection OrderstoProtect=3; //s08=--TRADING TIME MANAGEMENT-- //TTM1=Set time frames when new trades can open. //TTM2=If Starthour = Stophour, then trade 24/5. //TTM3=If TTMGoFlat=true, close all open trades //TTM4=when outside trading hours or days. GMTStartHour=0; GMTStopHour=0; TradeOnFriday=1; TTMGoFlat=0; SettingLoaded = 8; } else if(StringSubstr(Symbol(),0,6) == "USDCHF") ///////////////////////////////////////////8 { //s01=--STOCH SETTINGS-- K_Period=145; D_Period=20; Slow_Period=80; Stoch_TF=60; shift=4; H_level=78; L_level=22; //ChooseMAMode=Choose 1=mode SMA, 2=mode LWMA, 3=mode EMA, 4=mode SMMA stochMAmode=1; //s02=--ENVELOPE SETTINGS-- ENVELOPE_Slow_Period=11; ENVELOPE_TF=1440; //s03=--MOVING AVERAGE SETTINGS-- MA_TF=60; MA_Long_Period=190; MA_Short_Period=80; //s04=--TRADE SETTINGS-- Strategy=1; Lots=0.0100000; TakeProfit=119; multiply=1.80000000; MaxTrades=4; Pips=101; StopLoss=400; TrailingStop=0; TrailingStep=0; RecoveryMode=0; //s07=--CUTLOSS SETTING-- MyMoneyProfitTarget=0; My_Money_Profit_Target=50.00000000; SecureProfitProtection=0; //SP=If profit made is bigger than SecureProfit we close the orders SecureProfit=7; //OTP=Number of orders to enable the account protection OrderstoProtect=3; //s08=--TRADING TIME MANAGEMENT-- //TTM1=Set time frames when new trades can open. //TTM2=If Starthour = Stophour, then trade 24/5. //TTM3=If TTMGoFlat=true, close all open trades //TTM4=when outside trading hours or days. GMTStartHour=0; GMTStopHour=0; TradeOnFriday=1; TTMGoFlat=0; SettingLoaded = 9; } if(SettingLoaded == 0) { EADisabled = true; text="=== CURRENCY PAIR NOT SUPPORTED ==="; } else { Comment("\n\n=== SET FILE #", SettingLoaded, " LOADED ==="); } }