Está en la página 1de 11

//-----------------------------------------------------------------// AMA w STN ExpAdv V2.

mq4 // // Use Kaufman Adaptive Moving Avg indicator to trend follow // Watch for flat period, y bars, enter on breakout, // exit on STN over 70 or history comparison. // Check EA strategy against history on active chart // Produce testing data to determine best values for EA inputs // V2. Modify start() logic flow #property copyright "Intrigue Investments Inc." #property link "igandfm@gmail.com" #include <stdlib.mqh> #define #define #define #define #define #define #define EXPERT_NAME TS_MODE_DISABLE TS_MODE_FIXED_SL TS_MODE_ATR TS_MODE_HALF_VOLATILITY TS_MODE_BREAKOUT TS_MODE_BREAKEVEN "AMA w STN EA V2" 0 1 2 3 4 5

// ---------- input parameters : price values in tenths of pip --------extern string _____Entry_Position_____; extern double Lots = 1; // Fixed lot size - use 1 for testing pure pip count double Lots_PCT = 5.0; // Bet more when you have positive exp entancy bool Use_Lots_PCT = false; // Turn on more betting to use Lots_PC T value extern int TP = 0; // Take Profit - fixed value extern int SL = 0; // Stop Loss - fixed value extern int SL_Mode = 2; // Mode to set initial stop value // 0 None // 1 Fixed stoploss (input SL:= X) // 2 ATR (ATR(14) * dynamic factor) // 3 Volatility (range of bar[1] * dynamic fa ctor) // 4 Breakout (prev H or L) extern int Breakeven_Pips = 0; // # of pips from open price to adjus t to break even extern string extern int ______Trailing_Stop_____; TS_Mode = 2; // Mode to set trailing stops // 0 None // 1 Fixed stoploss (input SL:= X) // 2 ATR (ATR(14) * dynamic factor) // 3 Volatility (range of bar[1] * dynamic fa

ctor) // 4 Breakout (prev H or L) extern int TS_Trigger = 100; // Price move required before first st op adjustment extern int TS_Sensitivity = 30; // Price move required for subsequent stop adjustments extern double TS_DynamicFactor = 2.0; // multiplier for Mode = 2 or 3 extern extern extern extern string int double int _______Indicators______; AMA_Period = 10; // Adaptive Moving Average period Stn_Pct = 0.80; // Signal to Noise take profit value Flat_Bar_Count = 4; // Number of consecutive bars where AM

A is flat // A period of consolodation to watch for a breakout string extern bool et below extern int extern int extern int extern int _______Session_______; Filter_Session = true; From_Hour = 5; From_Min = 30; To_Hour = 18; To_Min = 30; // unique ID number in ticket queue // Default slippage to enter trade // Default slippage to exit trade-m // Buying or Selling // At what price // track when we have a new bar on // store AMA data local to expert a // store Signal to Noise data local // use ATR(14) for mode 2 stop calc // High, Low, and Range of flat bar // Trade only during the time values s

int main_magic; to find our tickets int open_slippage = 5; int close_slippage = 10; ore leway to get out int orderType; double orderPrice; double Zero_Bar_Open; the chart double ama_data[25]; dvisor double stn_data[25]; ly double ATRrange; ulations double HF, LF, RF; count int start() { // --------- Is there a new bar if( Zero_Bar_Open != Time[0] ) { Zero_Bar_Open = Time[0]; bool NewBar = true;

on the chart? --------// new bar on screen // reset Zero_Bar_Open to wait for next bar // flag true only once at start of new bar

// -------- Get new data from indicators ---------AMA(0); // Adaptive Moving Average // get stn_data and ama_data for 20 bars pri or to bar i ATRrange = Range(1); // return ATR(14) from bar i double spread = Ask - Bid; // save the current spread } // --------- Do we have active order and take profit condition? --------int ticket = OrderTicketByMagicNum( main_magic ); if( stn_data[1] > Stn_Pct && NewBar == true && ticket > 0 ) { Alert("Taking Profit via Signal 2 Noise Indicator: " + DoubleToStr(stn_dat a[1], 2) ); CloseNow(ticket); } // ---------- set breakeven and trailing stops ---------if( ticket > 0 && Breakeven_Pips > 0 ) ControlStop( ticket, SL, TS_MODE_BREAKEVEN, Breakeven_Pips, TS_DynamicFact or, TS_Sensitivity );

if( ticket > 0 && TS_Mode > 0 ) ControlStop( ticket, SL, TS_Mode, TS_Trigger, TS_DynamicFactor, TS_Sensiti vity ); // ---------- filter out entries if not in trading session ---------double From_Time = From_Hour * 60 + From_Min ; double To_Time = To_Hour * 60 + To_Min; double Cur_Time = TimeHour(Time[0]) * 60 + TimeMinute(Time[0]); if( !( From_Time <= Cur_Time && Cur_Time <= To_Time ) && Filter_Session ) bool ActiveSession = False; else ActiveSession = True; // --------- Examine AMA to set values that will execute orders --------// We are looking for consolidation when the indicator is flat followed by a breakout if( NewBar == true ) { bool flat = true; // assume ama trend line is flat for( int i = Flat_Bar_Count; i > 1; i-- ) if( ama_data[i] != ama_data[i -1] ) // find one that isn't and set t o false flat = false; if( flat == true && ActiveSession == true && ticket == 0 ) { HF = High[ iHighest(NULL, 0, MODE_HIGH, Flat_Bar_Count, 1) ] + spread * 3; // High Flat LF = Low[ iLowest(NULL, 0, MODE_LOW, Flat_Bar_Count, 1) ] - spread * 3; // Low Flat RF = HF - LF; // Range Flat } } // --------- Enter on price break out of flat range---------if( HF > 0 && // flat period set High Price to break out of Ask > HF && // bar 0 crosses above flat range high price ActiveSession && // correct time to trade stn_data[1] <= 0.50 && // don't enter if late on move up ticket == 0 // and NO active ticket ) if( BuyNow() > 0 ) // enter trade at open of bar 0 { HF = 0; // reset HF to zero waiting for next flat period LF = 0; } if( LF > 0 && // flat period set Low Price to break through Bid < LF && // bar 0 crosses below flat range low price ActiveSession && // correct time to trade stn_data[1] <= 0.50 && // don't enter if late on move up ticket == 0 // and NO active ticket ) if( SellNow() > 0 ) // enter trade and set flag { HF = 0;

LF = 0; }

// reset LF to zero waiting for next flat period

return(0); // end of start() } //-----------------------------------------------------------------// Buy int BuyNow() { double trueSL, trueTP, lotSize; lotSize = GetLots( Symbol(), Lots, Lots_PCT, Use_Lots_PCT ); trueSL = Get_SL (OP_BUY, Ask, Ask, SL, SL_Mode, TS_DynamicFactor ); if( TP > 0 ) trueTP = Bid + ( TP*Point ); int ticket = OrderSendEx( Symbol(), OP_BUY, lotSize, Ask, open_slippage*Point , trueSL, trueTP, EXPERT_NAME + " " + Symbol() + Period(), main_magic, 0, Yellow ); if( ticket > 0 ) orderType = OP_BUY; orderPrice = Ask; return( ticket ); } //-----------------------------------------------------------------// Sell int SellNow() { double trueSL, trueTP, lotSize; lotSize = GetLots( Symbol(), Lots, Lots_PCT, Use_Lots_PCT ); trueSL = Get_SL( OP_SELL, Bid, Bid, SL, SL_Mode, TS_DynamicFactor ); if( TP > 0 ) trueTP = Bid - ( TP*Point ); int ticket = OrderSendEx( Symbol(), OP_SELL, lotSize, Bid, open_slippage*Poin t, trueSL, trueTP, EXPERT_NAME + " " + Symbol() + Period(), main_magic, 0, Yello w ); if( ticket > 0 ) orderType = OP_SELL; orderPrice = Bid; return( ticket ); } //-----------------------------------------------------------------// Control stop : modify active order, or exit if price crosses stop void ControlStop( int ticket, double SL, int TS_Mode, int TS_Trigger, double TS_ DynamicFactor, int TS_Sensitivity ) { if (ticket == 0 TS_Mode == 0) return; double ts; if( OrderSelectEx( ticket, SELECT_BY_TICKET, MODE_TRADES ) == false ) return; if( OrderType() == OP_BUY ) { ts = Get_SL( OP_BUY, OrderOpenPrice(), Bid, SL, TS_Mode, TS_DynamicFactor ); if( ( ts >= OrderStopLoss() + TS_Sensitivity*Point ) && ( ts > 0 ) && ( Bid >= OrderOpenPrice() + TS_Trigger*Point ) ) { if( Bid - ts >= 5 * Point ) { OrderModifyEx( ticket, OrderOpenPrice(), ts, OrderTakeProfit(), 0, R ed );

} else if( Bid <= ts ) { CloseNow( ticket ); } } } if( OrderType() == OP_SELL ) { ts = Get_SL( OP_SELL, OrderOpenPrice(), Ask, SL, TS_Mode, TS_DynamicFactor ); if( ( ts <= OrderStopLoss() - TS_Sensitivity*Point ) && ( ts > 0 ) && // O rderStopLoss = 0 if SL_MODE = 0 ( Ask <= OrderOpenPrice() - TS_Trigger*Point ) ) { if( ts - Ask >= 5 * Point ) { OrderModifyEx( ticket, OrderOpenPrice(), ts, OrderTakeProfit(), 0, R ed ); } else if( ts <= Ask ) { CloseNow(ticket); } } } } //-----------------------------------------------------------------// Return a valid stop price for new or existing order double Get_SL( int order_type, double order_price, double price, double sl, int sl_mode, double sl_dynamicfactor ) { if( sl_mode == 0 ) return(0); double ts; double ma_0, hh, ll; if( order_type == OP_BUY ) { switch ( sl_mode ) { case TS_MODE_FIXED_SL: break; case TS_MODE_ATR: ge ); break; case TS_MODE_HALF_VOLATILITY: 1] - Low[1] ) ); break; case TS_MODE_BREAKOUT: case TS_MODE_BREAKEVEN: } } if( order_type == OP_SELL ) { switch ( sl_mode ) { case TS_MODE_FIXED_SL: break;

if( sl > 0 ) ts = price - ( Point*sl ); ts = Low[1] - ( sl_dynamicfactor * ATRran ts = Low[1] - ( sl_dynamicfactor *( High[ ts = Low[1] - Point; break; ts = order_price; break;

if( sl > 0 ) ts = price + ( Point*sl );

case TS_MODE_ATR: ts = High[1] + ( sl_dynamicfactor * ATRra nge ); break; case TS_MODE_HALF_VOLATILITY: ts = High[1] + ( sl_dynamicfactor *( High [1] - Low[1] ) ); break; case TS_MODE_BREAKOUT: ts = High[1] + Point; break; case TS_MODE_BREAKEVEN: ts = order_price; break; } } // Alert("ts = " + DoubleToStr( ts, Digits ) ); return(ts); } //-----------------------------------------------------------------// Close at market price bool CloseNow( int ticket ) { if (OrderSelectEx(ticket, SELECT_BY_TICKET ) ) { if( OrderType() == OP_BUY ) { OrderCloseEx(ticket, OrderLots(), Bid, close_slippage ); } else if( OrderType() == OP_SELL ) { OrderCloseEx(ticket, OrderLots(), Ask, close_slippage ); } } } //-----------------------------------------------------------------// Lots size functions (fixed lot, compound lot, etc) double GetLots( string symbol, double lots, double lots_pct, bool use_lots_pct ) { double lot; if( !use_lots_pct ) { lot = lots; } else { double lotStep = MarketInfo( symbol, MODE_LOTSTEP ); double lotSize = MarketInfo( symbol, MODE_LOTSIZE ) / AccountLeverage(); lot = ( AccountBalance() * ( lots_pct/100 ) ) / lotSize; double leftover = MathMod( lot, lotStep ); if (MathMod( lot/lotStep, 1 ) >= 0.00001 ) lot = lot - leftover; } return(lot); } //-----------------------------------------------------------------// Extended order execution functions for used in multiple pairs // with automatic retry attempts. int OrderSendEx(string symbol, int cmd, double volume, double price, int slippag e, double stoploss, double takeprofit, string comment, int magic, datetime expiration=0, color arrow_color=CLR_NONE)

{ if( !WaitWhileBusy() ) { Print( "Error in OrderSendEx(): Timeout encountered" ); return(-1); } SetBusyState(); int ticket = OrderSend( symbol, cmd, volume, price, slippage, stoploss, takep rofit, comment, magic, expiration, arrow_color ); Sleep(6000); ReleaseBusyState(); return(ticket); } bool OrderCloseEx( int ticket, double lots, double price, int slippage, color Co lor=CLR_NONE ) { if( !WaitWhileBusy() ) { Print( "Error in OrderCloseEx(): Timeout encountered" ); return( false ); } SetBusyState(); bool ret = OrderClose(ticket, lots, price, slippage, Color); Sleep(6000); ReleaseBusyState(); return( ret ); } bool OrderModifyEx( int ticket, double price, double stoploss, double takeprofit , datetime expiration, color arrow_color=CLR_NONE ) { if( !WaitWhileBusy() ) { Print( "Error in OrderModifyEx(): Timeout encountered" ); return( false ); } SetBusyState(); bool ret = OrderModify(ticket, price, stoploss, takeprofit, expiration, arrow _color); if(ret) { Sleep( 6000 ); } else { Print( "Error in OrderModifyEx(): ", LastErrorText() ); } ReleaseBusyState(); return( ret ); } bool OrderSelectEx( int index, int select, int pool = MODE_TRADES ) { if( OrderSelect( index, select, pool ) == true ) { return(true); } else {

Print("Error: Order #", index ," cannot be selected. ", LastErrorText()); } } //-----------------------------------------------------------------// Calling state functions bool WaitWhileBusy() { datetime OldCurTime; int timeoutsec = 6; OldCurTime = CurTime(); while( GlobalVariableCheck( "InTrade" ) !IsTradeAllowed() ) { if( OldCurTime + timeoutsec <= CurTime() ) { return( false ); } Sleep( 1000 ); } return( true ); } void SetBusyState() { GlobalVariableSet( "InTrade", CurTime() ); // set lock indicator } void ReleaseBusyState() { GlobalVariableDel( "InTrade" ); }

// clear lock indicator

//-----------------------------------------------------------------// Return the ticket number of the first order in the list we find // that matches our magic number // Executes every tic int OrderTicketByMagicNum(int magic_number) { for( int i = 0; i < OrdersTotal(); i++) // loop won't execute if OrdersTotal == 0 { if (OrderSelect(i, SELECT_BY_POS) == false) continue; // skip if we don't find an order if (OrderMagicNumber() == magic_number) return(OrderTicket()); // find our order and return ticket number } return(0); // Force a zero return if we don't have an active order. } //------------------------------------------------------------------// Time frame interval appropriation function int GetTimeframeConstant( int chart_period ) { switch( chart_period ) { case 1: return(50); // M1

case case case case case case case case } }

5: 15: 30: 60: 240: 1440: 10080: 43200:

return(100); return(150); return(200); return(250); return(300); return(350); return(400); return(450);

// // // // // // //

M5 M15 M30 H1 H4 D1 W1

//-----------------------------------------------------------------// Symbol to index (standard account or mini account?) int GetSymbolConstant( string symbol ) { if( symbol == "EURUSD" symbol == "mEURUSD" symbol == "EURUSDm " ) { return(1); } else if( symbol == "GBPUSD" symbol == "GBPUSDm" ) { return(2); } else if( symbol == "USDCHF" symbol == "USDCHFm" ) { return(3); } else if( symbol == "USDJPY" symbol == "USDJPYm" ) { return(4); } else if( symbol == "USDCAD" symbol == "USDCADm" ) { return(5); } else if( symbol == "AUDUSD" symbol == "AUDUSDm" ) { return(6); } else if( symbol == "CHFJPY" symbol == "CHFJPYm" ) { return(7); } else if( symbol == "EURAUD" symbol == "EURAUDm" ) { return(8); } else if( symbol == "EURCAD" symbol == "EURCADm" ) { return(9); } else if( symbol == "EURCHF" symbol == "EURCHFm" ) { return(10); } else if( symbol == "EURGBP" symbol == "EURGBPm" ) { return(11); } else if( symbol == "EURJPY" symbol == "EURJPYm" ) { return(12); } else if( symbol == "GBPCHF" symbol == "GBPCHFm" ) { return(13); } else if( symbol == "GBPJPY" symbol == "GBPJPYm" ) { return(14); } else if( symbol == "GOLD" symbol == "GOLDm") { return(15); } else { Print("Error: Unexpected symbol."); return(0); } } //-----------------------------------------------------------------// Get last error description string LastErrorText() { return( ErrorDescription( GetLastError() ) ); } /* Save for controling multiple reversals in a trading day datetime StripTime( datetime dt )

{ return ( dt - ( TimeHour( dt )*3600 ) - ( TimeMinute( dt )*60 ) - TimeSeconds( dt) ); } datetime Today() { return ( StripTime( CurTime() ) ); } */ void watermark() { ObjectCreate( "WaterMark", OBJ_LABEL, 0, 0, 0 ); ObjectSetText( "WaterMark", EXPERT_NAME, 8, "r_ansi", RoyalBlue ); ObjectSet( "WaterMark", OBJPROP_CORNER, 2 ); ObjectSet( "WaterMark", OBJPROP_XDISTANCE, 5 ); ObjectSet( "WaterMark", OBJPROP_YDISTANCE, 10 ); return( 0 ); } //-----------------------------------------------------------------// expert initialization function int init() { main_magic = 300000 + GetTimeframeConstant(Period()) + GetSymbolConstant(Symb ol()); watermark(); Zero_Bar_Open=Time[0]; AMA(0); // Get initial data from indicators for bar 0 return(0); } //-----------------------------------------------------------------// expert deinitialization function int deinit() { ObjectDelete( "WaterMark" ); return(0); } //-----------------------------------------------------------------// AMA calculations for value bar i - typically called at each new bar // can also be called for history calculations // populates stn_data and ama_data with correct data for 20 bars prior to bar i double AMA(int i) { int k = i + 19; // set k to 19 bars before current bar (usually 0) int h = 19; // index for data arrays ama_data[h + 1] = Close[k + 1]; // pre-load price data from bar +20 for Expo nential calculations while( k >= i ) // calculate bar i as well { double vt = 0; // reset value each iteration double ms = MathAbs(Close[k] - Close[k + AMA_Period]); //close to close for( int j = 0; j < AMA_Period; j++ ) vt = vt + MathAbs( (Close[k + j] - Close[k + j + 1]) );

stn_data[h] = NormalizeDouble( ms/vt, 3); // signal to noise data double pr = MathPow( ( ( (ms/vt) * 0.6022) + 0.0645), 2 ); // square function // if( pr > 1) Alert("ms: ", ms, " vt: ", vt, " pr: ", pr); // reality check - bad ama_data[h]= NormalizeDouble( Close[k] * pr + ama_data[k + 1] * (1 - pr), Digits -1 ); // ama data // Alert(" " + DoubleToStr(stn_data[h], 3) + " " + DoubleToStr(ama_data[h], Digits -1) ); k--; h--; } } //-----------------------------------------------------------------// Calculate Range(14) for bar x double Range( int x ) { double sum; for(int i = x; i < x + 14; i++ ) sum+= High[i] - Low[i]; return( NormalizeDouble( sum/14, Digits ) ); }

También podría gustarte