//+------------------------------------------------------------------+ //| US500_EA.mq4 | //| Copyright 2024, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2024, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.07" #property strict // Input parameters extern int SMA14_Period = 14; extern int SMA50_Period = 50; extern int SMA100_Period = 100; extern int DistinctTrend_Period = 10; // Period for detecting distinct trend extern int FlatRange_Period = 5; // Period for detecting flat range extern int MagicNumber = 12345; input string symbol1 = "US500"; // Global variables for trading double sma14, sma50, sma100; double upper15Percent, lower15Percent; // Constants for US500 on IC Markets const string SYMBOL = symbol1; const double LOT_SIZE = 1.0; const double POINT_VALUE = 0.1; // Adjust this based on IC Markets' US500 contract specifications const double STOP_LOSS_POINTS = 1.75; // Stop loss in points const double TAKE_PROFIT_POINTS = 1.5; // Take profit in points //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { // Check if the current symbol is US500 if (Symbol() != SYMBOL) { Print("This EA is designed to work only with ", SYMBOL); return INIT_FAILED; } CreateEMA(SMA14_Period, clrRed, "SMA 14"); CreateEMA(SMA50_Period, clrBlue, "SMA 50"); CreateEMA(SMA100_Period, clrGreen, "SMA 100"); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { // Remove all chart objects created by this EA ObjectsDeleteAll(0, OBJ_TREND); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { // Calculate and draw SMAs CalculateAndDrawIndicators(); // Check if there's already an open trade if (IsTradeOpen()) { return; // Exit the function as we don't want to open new trades } // Determine market conditions double highestHigh = High[iHighest(NULL, 0, MODE_HIGH, 100, 0)]; double lowestLow = Low[iLowest(NULL, 0, MODE_LOW, 100, 0)]; double range = highestHigh - lowestLow; upper15Percent = highestHigh - 0.15 * range; lower15Percent = lowestLow + 0.15 * range; bool distinctUptrend = IsDistinctTrend(1); bool distinctDowntrend = IsDistinctTrend(-1); bool inFibZone = (Bid >= upper15Percent || Bid <= lower15Percent); double currentSpread = MarketInfo(Symbol(), MODE_SPREAD) * POINT_VALUE; ulong startTime = GetTickCount(); datetime currentTime = TimeCurrent(); //TakeProfitOnRetracement(_Symbol); UpdateTrailSL(_Symbol); // Trading logic if (sma14 > sma50 && distinctUptrend && !inFibZone && !IsFlatRange()) { OpenOrder(OP_BUY, currentSpread); } else if (sma14 < sma50 && distinctDowntrend && !inFibZone && !IsFlatRange()) { OpenOrder(OP_SELL, currentSpread); } } //+------------------------------------------------------------------+ //| Calculate and draw SMAs | //+------------------------------------------------------------------+ void CalculateAndDrawIndicators() { int draw_begin = Bars - 1000; // Draw for the last 1000 bars // Calculate current SMA values sma14 = iMA(NULL, 0, SMA14_Period, 0, MODE_SMA, PRICE_CLOSE, 0); sma50 = iMA(NULL, 0, SMA50_Period, 0, MODE_SMA, PRICE_CLOSE, 0); sma100 = iMA(NULL, 0, SMA100_Period, 0, MODE_SMA, PRICE_CLOSE, 0); } //+------------------------------------------------------------------+ //| Draw EMA | //+------------------------------------------------------------------+ void CreateEMA(int EMAPeriod, color EMAColor, string EMAName) { if (ObjectFind(EMAName) != 0) { for(int i = 1; i < Bars; i++) { double EMAValue1 = iMA(NULL, 0, EMAPeriod, 0, MODE_SMA, PRICE_CLOSE, i); double EMAValue2 = iMA(NULL, 0, EMAPeriod, 0, MODE_SMA, PRICE_CLOSE, i - 1); ObjectCreate(EMAName + "_" + i, OBJ_TREND, 0, iTime(NULL, 0, i), EMAValue1, iTime(NULL, 0, i - 1), EMAValue2); ObjectSet(EMAName + "_" + i, OBJPROP_RAY, false); ObjectSet(EMAName + "_" + i, OBJPROP_COLOR, EMAColor); ObjectSet(EMAName + "_" + i, OBJPROP_WIDTH, 2); } } } //+------------------------------------------------------------------+ //| Draw an SMA line on the chart | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Check if the market is in a distinct trend | //+------------------------------------------------------------------+ bool IsDistinctTrend(int direction) { for (int i = 1; i <= DistinctTrend_Period; i++) { double previousSMA100 = iMA(NULL, 0, SMA100_Period, 0, MODE_SMA, PRICE_CLOSE, i); if (direction * (sma100 - previousSMA100) <= 0) return false; } return true; } //+------------------------------------------------------------------+ //| Check if the market is in a flat range | //+------------------------------------------------------------------+ bool IsFlatRange() { double previousSMA100 = iMA(NULL, 0, SMA100_Period, 0, MODE_SMA, PRICE_CLOSE, 1); double previousSMA50 = iMA(NULL, 0, SMA50_Period, 0, MODE_SMA, PRICE_CLOSE, 1); return (MathAbs(sma100 - sma50) < FlatRange_Period * POINT_VALUE && MathAbs(sma100 - previousSMA100) < 0.001 && MathAbs(sma50 - previousSMA50) < 0.001); } //+------------------------------------------------------------------+ //| Open an order | //+------------------------------------------------------------------+ void OpenOrder(int orderType, double spread) { // First, check if there's already an open trade if (IsTradeOpen()) { Print("A trade is already open. Skipping new order."); return; } double price = (orderType == OP_BUY) ? Ask : Bid; // Calculate stop loss: 1.75 points plus spread double stopLossDistance = STOP_LOSS_POINTS * POINT_VALUE + spread; double stopLoss = (orderType == OP_BUY) ? NormalizeDouble(price - stopLossDistance, Digits) : NormalizeDouble(price + stopLossDistance, Digits); // Calculate take profit: 1.5 points net double takeProfitDistance = TAKE_PROFIT_POINTS * POINT_VALUE + spread; // Adding spread to make it net double takeProfit = (orderType == OP_BUY) ? NormalizeDouble(price + takeProfitDistance, Digits) : NormalizeDouble(price - takeProfitDistance, Digits); int ticket = OrderSend(SYMBOL, orderType, LOT_SIZE, price, 3, stopLoss, takeProfit, "US500 Order", MagicNumber, 0, clrGreen); if (ticket < 0) { Print("OrderSend failed with error #", GetLastError()); } else { Print("Order opened successfully. Ticket: ", ticket, ", Stop Loss: ", stopLoss, ", Take Profit: ", takeProfit); } } //+------------------------------------------------------------------+ //| Check if there's an open trade | //+------------------------------------------------------------------+ bool IsTradeOpen() { for (int i = 0; i < OrdersTotal(); i++) { if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if (OrderSymbol() == SYMBOL && OrderMagicNumber() == MagicNumber) { return true; } } } return false; } //+------------------------------------------------------------------+ //| Modify Stop Loss to 1.75 points | //+------------------------------------------------------------------+ void ModifyStopLoss() { for (int i = 0; i < OrdersTotal(); i++) { if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if (OrderSymbol() == SYMBOL && OrderMagicNumber() == MagicNumber) { double currentPrice = (OrderType() == OP_BUY) ? Bid : Ask; double newStopLoss = (OrderType() == OP_BUY) ? NormalizeDouble(currentPrice - STOP_LOSS_POINTS * POINT_VALUE, Digits) : NormalizeDouble(currentPrice + STOP_LOSS_POINTS * POINT_VALUE, Digits); if (OrderModify(OrderTicket(), OrderOpenPrice(), newStopLoss, OrderTakeProfit(), 0, clrBlue)) { Print("Stop Loss modified successfully for order #", OrderTicket()); } else { Print("Failed to modify Stop Loss for order #", OrderTicket(), ". Error: ", GetLastError()); } } } } } //+------------------------------------------------------------------+ //| TTP | //+------------------------------------------------------------------+ //If angle stays up and gd is blue and we are more than 3 pts then do 1.5 retracements //if more than 6 pts do 2 pts if 10 pts do 3 pts if 20 then 4 pts //unless the purple crosses over prior to tp trailing then take that as close double last_ang_buy_sl = 0; double last_ang_sell_sl = 0; void UpdateTrailSL(string symbol) { for (int i = OrdersTotal() - 1; i >= 0; i--) { if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderSymbol() == symbol) { const double openPrice = OrderOpenPrice(); const int ticket = OrderTicket(); if(OrderMagicNumber() == MagicNumber){ if (OrderType() == OP_BUY) { double currentStopLoss = OrderStopLoss(); double newStopLoss = 0; double profit = OrderProfit(); double adjustment = 0; // Determine the adjustment based on profit tiers if (profit >= 4 && currentStopLoss < (OrderOpenPrice() + profit * 0.75)) { adjustment = profit * 0.75; } else if (profit > 3 && currentStopLoss < (OrderOpenPrice() + 2.5)) { adjustment = 2.5; } else if (profit > 2.5 && currentStopLoss < (OrderOpenPrice() + 2)) { adjustment = 2; } else if (profit > 2 && currentStopLoss < (OrderOpenPrice() + 1.5)) { adjustment = 1.5; } else if (profit > 1.5 && currentStopLoss < (OrderOpenPrice() + 1)) { adjustment = 1; } else if (profit > 1 && currentStopLoss < (OrderOpenPrice() + 0.5)) { adjustment = 0.5; } if (adjustment > 0) { newStopLoss = OrderOpenPrice() + adjustment; // Check if the new SL is significantly different from the current SL to avoid spamming double minimumDifference = 0.00010; // Example minimum significant difference, adjust based on your asset and strategy if (MathAbs(currentStopLoss - newStopLoss) > minimumDifference) { bool result = OrderModify(OrderTicket(), OrderOpenPrice(), newStopLoss, OrderTakeProfit(), 0, clrBlue); // Optionally, check the result and handle errors or log success } } } } if(OrderMagicNumber() == MagicNumber){ if (OrderType() == OP_SELL) { double currentStopLoss = OrderStopLoss(); double newStopLoss = 0; double profit = OrderProfit(); double adjustment = 0; // Determine the adjustment based on profit tiers if (profit >= 4 && currentStopLoss > (OrderOpenPrice() - profit * 0.75)) { adjustment = profit * 0.75; } else if (profit > 3 && currentStopLoss > (OrderOpenPrice() - 2.5)) { adjustment = 2.5; } else if (profit > 2.5 && currentStopLoss > (OrderOpenPrice() - 2)) { adjustment = 2; } else if (profit > 2 && currentStopLoss > (OrderOpenPrice() - 1.5)) { adjustment = 1.5; } else if (profit > 1.5 && currentStopLoss > (OrderOpenPrice() - 1)) { adjustment = 1; } else if (profit > 1 && currentStopLoss > (OrderOpenPrice() - 0.5)) { adjustment = 0.5; } if (adjustment > 0) { newStopLoss = OrderOpenPrice() - adjustment; // Check if the new SL is significantly different from the current SL to avoid spamming if (MathAbs(currentStopLoss - newStopLoss) > 0.25) { // SomeMinimumValue is the minimum significant difference you consider worth adjusting. bool result = OrderModify(OrderTicket(), OrderOpenPrice(), newStopLoss, OrderTakeProfit(), 0, clrRed); // Optionally, check the result and handle errors or log success } } } } if(OrderMagicNumber() == MagicNumber){ if (OrderType() == OP_BUY) { double currentStopLoss = OrderStopLoss(); double newStopLoss = 0; double profit = OrderProfit(); double adjustment = 0; // Determine the adjustment based on profit tiers if (profit > 1 && currentStopLoss < OrderOpenPrice()-1) { adjustment = -1; } if (adjustment != 0) { newStopLoss = OrderOpenPrice() + adjustment; // Check if the new SL is significantly different from the current SL to avoid spamming double minimumDifference = 0.01; // Example minimum significant difference, adjust based on your asset and strategy if (MathAbs(currentStopLoss - newStopLoss) > minimumDifference) { bool result = OrderModify(OrderTicket(), OrderOpenPrice(), newStopLoss, OrderTakeProfit(), 0, clrBlue); // Optionally, check the result and handle errors or log success } } } } if(OrderMagicNumber() == MagicNumber){ if (OrderType() == OP_SELL) { double currentStopLoss = OrderStopLoss(); double newStopLoss = 0; double profit = OrderProfit(); double adjustment = 0; // Determine the adjustment based on profit tiers if (profit > 1 && currentStopLoss > OrderOpenPrice()+1) { adjustment = -1; } if (adjustment != 0) { newStopLoss = OrderOpenPrice() - adjustment; // Check if the new SL is significantly different from the current SL to avoid spamming if (MathAbs(currentStopLoss - newStopLoss) > 0.01) { // SomeMinimumValue is the minimum significant difference you consider worth adjusting. bool result = OrderModify(OrderTicket(), OrderOpenPrice(), newStopLoss, OrderTakeProfit(), 0, clrRed); // Optionally, check the result and handle errors or log success } } } } } } }