//============================================================================= // Fluid Turquoise 3.4.mq4 // Derk Wehler // fibofx@gmail.com // // Taken from FB3.3 by Matt Pavlovich: fibofx@gmail.com. // One change made by Derk Wehler, suggested by TradeForexFx: The use of the // difference of two moving averages instead of the accelorator oscillator. // Search for "TradeForexFx" to find changes. // // Robert Hill // 1/11/2007 // Added automatic calculation of MagicNumber using Symbol and Timeframe of chart // so that this can be tested on any currency pair and timeframe // version 1.1 1/12/07 // added code to select AC or MA indicator // Changed code where OrdersTotal() was used instead of total // Added functions for GetStopLoss, GetTakeProfit, GetTrailingStop // // Replaced 0 timeframe with Period_H4 for backtesting on lower timeframes // I think this might give more accurate results // // Added MAdif to use values other than 1 for difference // // Added MaxSpread as input so other pairs can be tested // // Changed the following from comment in forum about using < 0 and > 0 in double down etc // Modified to use testBuy and testSell instead of 0 and 1 // especially in code for double down etc where 0 was used // This now reflects better use of MA // Added single value for risk as a form of money management // Modified formulas to use riskm, riskM and riskS divisor // to achieve same values for old riskm, riskM and riskS // Made more modular for easier understanding of code // // version 1.2 // Removed some change line comments for easier reading of code //============================================================================= #property copyright "Matt Pavlovich" #property link "fibofx@gmail.com" #include <stdlib.mqh> #include <stderror.mqh> // Robert Added UseAC to determine which works better AC or MA extern int UseAC = 1; // 1 use AC, 0 use MA extern int MAdif = 1; extern int MaxSpread = 3; // 3 for EURUSD extern double MinTime = 120; extern double drawdown1 = 10; extern double drawdown2 = 20; extern double drawdown3 = 30; extern double MaxLots = 100; extern double stop = 1;//1 - 4hr// extern double profit = 3;//3 - 4hr// extern double trailer = 0.5; // Line introduced to have desirable profit target for each trade extern double PipProfit = 4; extern bool DoubleDown = true; extern bool TrippleDown = true; extern bool QuadDown = true; extern bool Reverse = false; extern bool micro = true; extern bool mini = false; extern bool standard = false; /* // Robert modified for a form of money management double riskm = 75; // micro=75, mini=7.5, standard=.75 // double riskM = 7.5; // micro=75, mini=7.5, standard=.75 // double riskS = 0.75; // micro=75, mini=7.5, standard=.75 // */ extern double risk = 75; double riskm = 100000.0; // micro=75, mini=7.5, standard=.75 // double riskM = 1000000.0; // micro=75, mini=7.5, standard=.75 // double riskS = 10000000.0; // micro=75, mini=7.5, standard=.75 // double Lots; // int MagicNumber = 333; - original line // Modified to calculate MagicNumber in Init by Robert extern int MagicBase = 3000; int MagicNumber; //This is a reverse Martingale system. It trades with the trend, doubling down as the // position goes against you. It is an "Always in Play" system as well, so be ready // to place a lot of trades! //PLACE ON EURUSD 4HR CHART. YOU MUST HAVE AT LEAST $500 TO START WITH A MICRO ACCOUNT, // $5000 FOR A MINI, AND $50,000 FOR A STANDARD ACCOUNT. THIS SYSTEM HAS NOT YET BEEN // TESTED. AS SUCH, DEMO TEST BEFORE GOING LIVE. AS ALWAYS, SPECULATING IN FOREX AND // ANY OTHER MARKETS IS RISKY. YOU COULD LOOSE EVERY CENT YOU HAVE. BE SMART! ALSO, // USE ONLY WITH A BROKER WITH A 2 PIP SPREAD ON THE EURUSD, AS WELL AS A VOLATILE FEED. // THE LATTER DOES NOT INCLUDE THE LIKES OF INTERBANK FX, ALPARI, ETC. THERE IS NOTHING // WRONG WITH THESE BROKERS, BUT THEIR FEEDS TEND TO BE LESS VOLATILE THAN THEIR // COMPETITORS. I PERSONALLY RECOMMEND VELOCITY4X. I AM NOT AN IB. HAPPY TRADING! //------------------------------------------------------------- // expert initialization function //------------------------------------------------------------- int init() { MagicNumber = MagicBase + func_Symbol2Val(Symbol())*100 + func_TimeFrame_Const2Val(Period()); } //------------------------------------------------------------- // GetEntrySignal // // Get entry signal to place trades // // Change made for TradeForexFx to use moving average instead of iAC: // myao = iAC(Symbol(), 0, 0); // original line // Change made to select either AC or MA by Robert //------------------------------------------------------------- double GetEntrySignal() { double signal; if (UseAC == 1) signal = iAC(Symbol(), PERIOD_H4, 0); else signal = (iMA(NULL, PERIOD_H4, 5, 0, MODE_LWMA, PRICE_CLOSE, 0) - iMA(NULL, PERIOD_H4, 8, 0, MODE_LWMA, PRICE_CLOSE, 0)) / Point; return(signal); } //============================================================================= // Start //============================================================================= int start() { int cnt, ticket, myTotal, testBuy, testSell; double TrailingStop; double msd, myrsi, myao; if (Lots > MaxLots) Lots = MaxLots; if (Lots >= 100) Alert("Take your profits and run!! Your broker will not allow more than 100 lots! You cannot double down from here! Stop trading!"); Lots = GetLots(); myao = GetEntrySignal(); if (!IsTesting()) Comment(" TrailingStop=", DoubleToStr(TrailingStop, 4)); if (UseAC == 1) { testBuy = 0; testSell = 0; } else { testBuy = MAdif; testSell = -MAdif; } myTotal = GetTotalOpenOrders(); switch (myTotal) { case 0 : if (SpreadOK()) { if (myao > testBuy) PlaceOrder(OP_BUY, Lots); if (myao < testSell) PlaceOrder(OP_SELL, Lots); } break; case 1 : if (DoubleDown) { if (SpreadOK()) { if (OrderOpenPrice() - Ask >= drawdown1 * Point && myao > testBuy) PlaceOrder(OP_BUY, Lots*2); if (Bid - OrderOpenPrice() >= drawdown1 * Point && myao < testSell) PlaceOrder(OP_SELL, Lots*2); } } break; case 2 : if (TrippleDown) { if (SpreadOK()) { if (OrderOpenPrice() - Ask >= drawdown2 * Point && myao > testBuy) PlaceOrder(OP_BUY, Lots*4); if (Bid - OrderOpenPrice() >= drawdown2 * Point && myao < testSell) PlaceOrder(OP_SELL, Lots*4); } } break; case 3 : if (QuadDown) { if (SpreadOK()) { if (OrderOpenPrice() - Ask >= drawdown3 * Point && myao > testBuy) PlaceOrder(OP_BUY, Lots*8); if (Bid - OrderOpenPrice() >= drawdown3 * Point && myao < testSell) PlaceOrder(OP_SELL, Lots*8); } } } myTotal = GetTotalOpenOrders(); for(cnt=myTotal-1; cnt >= 0; cnt--) { OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES); if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) { // TrailingStop = iATR(Symbol(), PERIOD_H4, 14, 1) * trailer; - line changed by Robert TrailingStop = GetTrailingStop(); if (TrailingStop <= 0.0005) TrailingStop=0.0006; if (OrderType() == OP_BUY) // long position is opened // { // if ((Bid - OrderOpenPrice() >= 4 * Point && CurTime() - OrderOpenTime() >= MinTime)) - original line if ((Bid - OrderOpenPrice() >= PipProfit * Point && CurTime() - OrderOpenTime() >= MinTime)) { RefreshRates(); OrderClose(OrderTicket(), OrderLots(), Bid, 1, Violet); // close position return(0); // exit } if (Reverse) // if (myao < 0) - line changed by Robert if (myao < testSell) { RefreshRates(); OrderClose(OrderTicket(), OrderLots(), Bid, 1, Violet); // close position return(0); // exit } // check for trailing stop if (TrailingStop > 0) { if (Bid - OrderOpenPrice() > TrailingStop) { if (OrderStopLoss() < Bid - TrailingStop) { RefreshRates(); OrderModify(OrderTicket(), OrderOpenPrice(), Bid - TrailingStop, OrderTakeProfit(), 0, Blue); } } } } if (OrderType() == OP_SELL) // short position is opened // { // if ((OrderOpenPrice() - Ask >= 4 * Point && CurTime() - OrderOpenTime() >= MinTime))- original line if ((OrderOpenPrice() - Ask >= PipProfit * Point && CurTime() - OrderOpenTime() >= MinTime)) { RefreshRates(); OrderClose(OrderTicket(), OrderLots(), Ask, 1, Violet); // close position return(0); // exit } if (Reverse) // if (myao > 0) - line changed by Robert if (myao > testBuy) { RefreshRates(); OrderClose(OrderTicket(), OrderLots(), Ask, 1, Violet); // close position return(0); // exit } // check for trailing stop if (TrailingStop > 0) { if ((OrderOpenPrice() - Ask) > (TrailingStop)) { if ((OrderStopLoss() > (Ask + TrailingStop)) || (OrderStopLoss() == 0)) { RefreshRates(); OrderModify(OrderTicket(), OrderOpenPrice(), Ask + TrailingStop, OrderTakeProfit(), 0, Red); } } } } } } } void PlaceOrder(int cmd, double mLots) { int err, ticket; double SL, TP; if (cmd == OP_BUY) { // SL = Ask - iATR(Symbol(), PERIOD_H4, 14, 0) * stop; - line changed by Robert // TP = Ask + iATR(Symbol(), PERIOD_H4, 14, 0) * profit; - line changed by Robert SL = GetStopLoss(OP_BUY); TP = GetTakeProfit(OP_BUY); ticket = OrderSend(Symbol(), OP_BUY, mLots, Ask, 1, SL, TP, "", MagicNumber, 0, Blue); if (ticket > 0) { if (OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES)) { Print("BUY order opened : ", OrderOpenPrice()); } } else { err = GetLastError(); Print("Error opening BUY order : (" + err + ") " + ErrorDescription(err)); } } if (cmd == OP_SELL) { // SL = Bid + iATR(Symbol(), PERIOD_H4, 14, 0) * stop; - line changed by Robert // TP = Bid - iATR(Symbol(), PERIOD_H4, 14, 0) * profit; - line changed by Robert SL = GetStopLoss(OP_SELL); TP = GetTakeProfit(OP_SELL); ticket = OrderSend(Symbol(), OP_SELL, mLots, Bid, 1, SL, TP, "", MagicNumber, 0, Red); if (ticket > 0) { if (OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES)) { Print("SELL order opened : ", OrderOpenPrice()); } } else { err = GetLastError(); Print("Error opening SELL order : (" + err + ") " + ErrorDescription(err)); } } } //------------------------------------------------------------- // GetTotalOpenOrders // // Get total number of orders open for this ea //------------------------------------------------------------- int GetTotalOpenOrders() { int cnt, total; total = 0; for (cnt=OrdersTotal()-1; cnt >= 0; cnt--) { OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES); if (OrderSymbol() != Symbol()) continue; if (OrderMagicNumber() != MagicNumber) continue; if (OrderType() == OP_BUY) total++; if (OrderType() == OP_SELL) total++; } return (total); } //------------------------------------------------------------- // SpreadOK // // Check if spread is smaller then Maximum spread allowed //------------------------------------------------------------- bool SpreadOK() { if (Ask - Bid <= MaxSpread * Point) return(true); return(false); } //------------------------------------------------------------- // GetLots // Modified by Robert for money management // if (micro) // Lots = MathCeil(AccountEquity() * riskm / 100000) / 100; // // if (mini) // Lots = MathCeil(AccountEquity() * riskM / 100000) / 10; // // if (standard) // Lots = MathCeil(AccountEquity() * riskS / 100000); //------------------------------------------------------------- double GetLots() { double mLots; if (micro) mLots = MathCeil(AccountEquity() * risk / riskm) / 100; if (mini) mLots = MathCeil(AccountEquity() * risk / riskM) / 10; if (standard) mLots = MathCeil(AccountEquity() * risk / riskS); return(mLots); } //------------------------------------------------------------- // GetStopLoss // // Uses original formula in a function // so easier changes can be made // //------------------------------------------------------------- double GetStopLoss(int cmd) { double mySL; if (cmd == OP_BUY) mySL = Ask - iATR(Symbol(), PERIOD_H4, 14, 0) * stop; else mySL = Bid + iATR(Symbol(), PERIOD_H4, 14, 0) * stop; return(mySL); } //------------------------------------------------------------- // GetTakeProfit // // Uses original formula in a function // so easier changes can be made // //------------------------------------------------------------- double GetTakeProfit(int cmd) { double myTP; if (cmd == OP_BUY) myTP = Ask + iATR(Symbol(), PERIOD_H4, 14, 0) * profit; else myTP = Bid - iATR(Symbol(), PERIOD_H4, 14, 0) * profit; return(myTP); } //------------------------------------------------------------- // GetTrailingStop // // Uses original formula in a function // so easier changes can be made // //------------------------------------------------------------- double GetTrailingStop() { double myTS; myTS = iATR(Symbol(), PERIOD_H4, 14, 1) * trailer; return(myTS); } //------------------------------------------------------------- // Time frame interval appropriation function //------------------------------------------------------------- int func_TimeFrame_Const2Val(int Constant ) { switch(Constant) { case 1 : return(1); // M1 case 5 : return(2); // M5 case 15 : return(3); case 30 : return(4); case 60 : return(5); case 240 : return(6); case 1440 : return(7); case 10080 : return(8); case 43200 : return(9); } } //------------------------------------------------------------- // Convert symbol to number for calculation of magic number //------------------------------------------------------------- int func_Symbol2Val(string symbol) { string mySymbol = StringSubstr(symbol,0,6); if(mySymbol=="AUDCAD") return(1); if(mySymbol=="AUDJPY") return(2); if(mySymbol=="AUDNZD") return(3); if(mySymbol=="AUDUSD") return(4); if(mySymbol=="CHFJPY") return(5); if(mySymbol=="EURAUD") return(6); if(mySymbol=="EURCAD") return(7); if(mySymbol=="EURCHF") return(8); if(mySymbol=="EURGBP") return(9); if(mySymbol=="EURJPY") return(10); if(mySymbol=="EURUSD") return(11); if(mySymbol=="GBPCHF") return(12); if(mySymbol=="GBPJPY") return(13); if(mySymbol=="GBPUSD") return(14); if(mySymbol=="NZDUSD") return(15); if(mySymbol=="USDCAD") return(16); if(mySymbol=="USDCHF") return(17); if(mySymbol=="USDJPY") return(18); Comment("unexpected Symbol"); return(19); }
Sample
Analysis
Market Information Used:
Indicator Curves created:
Indicators Used:
Bill Williams Accelerator/Decelerator oscillator
Moving average indicator
Indicator of the average true range
Custom Indicators Used:
Order Management characteristics:
It Closes Orders by itself
It can change open orders parameters, due to possible stepping strategy
It automatically opens orders when conditions are reached
Checks for the total of open orders
Other Features:
It issuies visual alerts to the screen