497 lines
18 KiB
MQL5
497 lines
18 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| Scalping Robot 2.0.mq5 |
|
|
//| Venkatesh CR |
|
|
//| https://www.tamilcadd.graphy.com |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Venkatesh CR"
|
|
#property link "https://www.tamilcadd.graphy.com"
|
|
#property version "1.00"
|
|
|
|
#include <Trade/Trade.mqh>
|
|
|
|
CTrade *Trade;
|
|
CPositionInfo Positioninfo;
|
|
COrderInfo Orderinfo;
|
|
|
|
input group "General Parameters"
|
|
input double RiskPercentage = 2;
|
|
input ENUM_TIMEFRAMES Timeframe = PERIOD_M5;
|
|
input int MaxSlippage = 1;
|
|
input int CandlestickN = 5;
|
|
double OrderDistPoints = 100;
|
|
input int ExpirationCandles = 100;
|
|
input int EAMagic = 369737;
|
|
|
|
input group "Trading Profiles"
|
|
|
|
enum SystemType {Forex=0,Bitcoin=1,_Gold=2,Us_index=3};
|
|
input SystemType SType = 1;
|
|
int SysChoice;
|
|
double Tpoints,Slpoints,TsPoints,TsTriggerPoints;
|
|
|
|
input group "=== Trading Allowed by Days ==="
|
|
|
|
input bool AllowedMonday = true; // Trading Allowed on Monday?
|
|
input bool AllowedTuesday = true; // Trading Allowed on Tuesday?
|
|
input bool AllowedWednesday = true; // Trading Allowed on Wednesday?
|
|
input bool AllowedThursday = true; // Trading Allowed on Thursday?
|
|
input bool AllowedFriday = true; // Trading Allowed on Friday?
|
|
input bool AllowedSaturday = false; // Trading Allowed on Saturday?
|
|
input bool AllowedSunday = false; // Trading Allowed on Sunday?
|
|
|
|
bool DayFilterOn = true; // Enable Day Filtering?
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
input group "=== Forex Related Input === (effective only under Forex profile)"
|
|
input int Tppointsinput = 200; // Take Profit (10 points = 1 pip)
|
|
input int SlPointsinput = 200; // Stop Loss (10 points = 1 pip)
|
|
input int TsPointsinput = 10; // Trailing Stop Loss (10 points = 1 pip)
|
|
input int TsTriggerPointsinput = 20; // Points in profit before Trailing SL is activated (10 points = 1 pip)
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
input group "=== Crypto Related Input === (effective only under Bitcoin profile)"
|
|
input double TPasPct = 0.4; // TP as % of Price
|
|
input double SLasPct = 0.4; // SL as % of Price
|
|
input double TSLasPctofTP = 5; // Trail SL as % of TP
|
|
input double TSLTrgrasPctofTP = 10;// Trigger of Trail SL % of TP
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
input group "=== Gold Related Input === (effective only under Gold profile)"
|
|
input double TPasPctGold = 0.2; // TP as % of Price
|
|
input double SLasPctGold = 0.2; // SL as % of Price
|
|
input double TSLasPctofTPGold = 5; // Trail SL as % of TP
|
|
input double TSLTrgrasPctofTPGold = 10;// Trigger of Trail SL % of TP
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
input group "=== Indices Related Input === (effective only under Indices profile)"
|
|
input double TPasPctIndices = 0.2; // TP as % of Price
|
|
input double SLasPctIndices = 0.2; // SL as % of Price
|
|
input double TSLasPctofTPIndices = 5; // Trail SL as % of TP
|
|
input double TSLTrgrasPctofTPIndices = 10;// Trigger of Trail SL % of TP
|
|
|
|
input group "TIMEZONE SETTINGS"
|
|
input bool UseTimeZoneFilter = true;
|
|
input int StartHour1 = 07;
|
|
input int StartMinute1 = 00;
|
|
input int EndHour1 = 21;
|
|
input int EndMinute1 = 00;
|
|
int StartTimeSeconds1,EndTimeSeconds1;
|
|
|
|
input group "NEWS FILTER INPUTS"
|
|
input bool UseNewsFilter = true;
|
|
input ENUM_CALENDAR_EVENT_IMPORTANCE NewsImportance = CALENDAR_IMPORTANCE_HIGH;
|
|
input uint MinutesToNews = 30;
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Expert initialization function |
|
|
//+------------------------------------------------------------------+
|
|
int OnInit()
|
|
{
|
|
|
|
Trade = new CTrade();
|
|
Trade.SetExpertMagicNumber(EAMagic);
|
|
Trade.SetDeviationInPoints(MaxSlippage*10);
|
|
|
|
if(SType==0)
|
|
SysChoice =0;
|
|
if(SType==1)
|
|
SysChoice =1;
|
|
if(SType==2)
|
|
SysChoice =2;
|
|
if(SType==3)
|
|
SysChoice =3;
|
|
|
|
Tpoints = Tppointsinput;
|
|
Slpoints = SlPointsinput;
|
|
TsPoints = TsPointsinput;
|
|
TsTriggerPoints = TsTriggerPointsinput;
|
|
|
|
ChartSetInteger(0,CHART_SHOW_GRID,false);
|
|
ChartSetInteger(0,CHART_MODE,CHART_CANDLES);
|
|
ChartSetInteger(0,CHART_COLOR_BACKGROUND,clrBlack);
|
|
ChartSetInteger(0,CHART_COLOR_FOREGROUND,clrWhite);
|
|
ChartSetInteger(0,CHART_COLOR_CANDLE_BULL,clrGreen);
|
|
ChartSetInteger(0,CHART_COLOR_CHART_UP,clrGreen);
|
|
ChartSetInteger(0,CHART_COLOR_CANDLE_BEAR,clrWhite);
|
|
ChartSetInteger(0,CHART_COLOR_CHART_DOWN,clrWhite);
|
|
ChartSetInteger(0,CHART_COLOR_STOP_LEVEL,clrGold);
|
|
ChartSetInteger(0,CHART_SHOW_VOLUMES,false);
|
|
|
|
StartTimeSeconds1 = (60*60*StartHour1)+(60*StartMinute1);
|
|
EndTimeSeconds1 = (60*60*EndHour1)+(60*EndMinute1);
|
|
|
|
return(INIT_SUCCEEDED);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Expert deinitialization function |
|
|
//+------------------------------------------------------------------+
|
|
void OnDeinit(const int reason)
|
|
{
|
|
|
|
delete Trade;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Expert tick function |
|
|
//+------------------------------------------------------------------+
|
|
void OnTick()
|
|
{
|
|
|
|
TrailStop();
|
|
|
|
if(!IsNewCandlestick())
|
|
return ;
|
|
|
|
if(TradeSession1()&&!NewsPresent(NewsImportance,MinutesToNews*60)&&IsTradingAllowedbyDay())
|
|
{
|
|
|
|
if(SysChoice == 1)
|
|
{
|
|
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
|
|
Tpoints = ask * TPasPct;
|
|
Slpoints = ask * SLasPct;
|
|
OrderDistPoints = Tpoints / 2;
|
|
TsPoints = Tpoints * TSLasPctofTP / 100;
|
|
TsTriggerPoints = Tpoints * TSLTrgrasPctofTP / 100;
|
|
}
|
|
|
|
if(SysChoice == 2)
|
|
{
|
|
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
|
|
Tpoints = ask * TPasPctGold;
|
|
Slpoints = ask * SLasPctGold;
|
|
OrderDistPoints = Tpoints / 2;
|
|
TsPoints = Tpoints * TSLasPctofTPGold / 100;
|
|
TsTriggerPoints = Tpoints * TSLTrgrasPctofTPGold / 100;
|
|
}
|
|
|
|
if(SysChoice == 3)
|
|
{
|
|
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
|
|
Tpoints = ask * TPasPctIndices;
|
|
Slpoints = ask * SLasPctIndices;
|
|
OrderDistPoints = Tpoints / 2;
|
|
TsPoints = Tpoints * TSLasPctofTPIndices / 100;
|
|
TsTriggerPoints = Tpoints * TSLTrgrasPctofTPIndices / 100;
|
|
}
|
|
|
|
int BuyTotal = 0;
|
|
int SellTotal = 0;
|
|
|
|
for(int i = OrdersTotal() - 1; i >= 0; i--)
|
|
{
|
|
Orderinfo.SelectByIndex(i);
|
|
if(Orderinfo.OrderType() == ORDER_TYPE_BUY_STOP && Orderinfo.Symbol() == _Symbol && Orderinfo.Magic() == EAMagic)
|
|
BuyTotal++;
|
|
if(Orderinfo.OrderType() == ORDER_TYPE_SELL_STOP && Orderinfo.Symbol() == _Symbol && Orderinfo.Magic() == EAMagic)
|
|
SellTotal++;
|
|
}
|
|
|
|
for(int i = PositionsTotal() - 1; i >= 0; i--)
|
|
{
|
|
Positioninfo.SelectByIndex(i);
|
|
if(Positioninfo.PositionType() == POSITION_TYPE_BUY && Positioninfo.Symbol() == _Symbol && Positioninfo.Magic() == EAMagic)
|
|
BuyTotal++;
|
|
if(Positioninfo.PositionType() == POSITION_TYPE_SELL && Positioninfo.Symbol() == _Symbol && Positioninfo.Magic() == EAMagic)
|
|
SellTotal++;
|
|
}
|
|
|
|
if(BuyTotal <= 0)
|
|
{
|
|
double high = NewHigh();
|
|
if(high > 0)
|
|
{
|
|
BuyOrderBreakOut(high);
|
|
}
|
|
}
|
|
|
|
if(SellTotal <= 0)
|
|
{
|
|
double low = NewLow();
|
|
if(low > 0)
|
|
{
|
|
SellOrderBreakeOut(low);
|
|
}
|
|
}
|
|
|
|
}
|
|
else
|
|
CloseAllOrders();
|
|
return ;
|
|
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
bool IsNewCandlestick()
|
|
{
|
|
static datetime previousTime = 0;
|
|
datetime currentTime = iTime(_Symbol,PERIOD_CURRENT,0);
|
|
if(previousTime!=currentTime)
|
|
{
|
|
previousTime=currentTime;
|
|
return true;
|
|
}
|
|
return false;
|
|
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
double NewHigh()
|
|
{
|
|
double highestHigh = 0;
|
|
|
|
for(int i = 0; i < 200; i++)
|
|
{
|
|
double high = iHigh(_Symbol, Timeframe, i);
|
|
if(i >= CandlestickN && iHighest(_Symbol, Timeframe, MODE_HIGH, CandlestickN * 2 + 1, i-CandlestickN) == i)
|
|
{
|
|
if(high > highestHigh)
|
|
{
|
|
return high;
|
|
}
|
|
}
|
|
highestHigh = MathMax(high,highestHigh);
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
double NewLow()
|
|
{
|
|
double lowestLow = DBL_MAX;
|
|
for(int i = 0; i < 200; i++)
|
|
{
|
|
double low = iLow(_Symbol, Timeframe, i);
|
|
if(i >= CandlestickN && iLowest(_Symbol, Timeframe, MODE_LOW, CandlestickN * 2 + 1, i-CandlestickN) == i)
|
|
{
|
|
if(low < lowestLow)
|
|
{
|
|
return low;
|
|
}
|
|
}
|
|
lowestLow = MathMin(low,lowestLow);
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
double calcLots(double slPoints)
|
|
{
|
|
|
|
double risk = AccountInfoDouble(ACCOUNT_BALANCE) * RiskPercentage / 100;
|
|
|
|
double ticksize = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
|
|
double tickvalue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
|
|
double lotstep = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
|
|
|
|
double moneyPerLotstep = slPoints / ticksize * tickvalue * lotstep;
|
|
|
|
double lots = MathFloor(risk / moneyPerLotstep) * lotstep;
|
|
|
|
double minvolume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
|
|
double maxvolume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
|
|
double volumelimit = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_LIMIT);
|
|
|
|
if(volumelimit != 0)
|
|
lots = MathMin(lots, volumelimit);
|
|
if(maxvolume != 0)
|
|
lots = MathMin(lots, maxvolume);
|
|
if(minvolume != 0)
|
|
lots = MathMax(lots, minvolume);
|
|
|
|
lots = NormalizeDouble(lots, 2);
|
|
|
|
return lots;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
void BuyOrderBreakOut(double entry)
|
|
{
|
|
|
|
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
|
|
|
|
if(ask > entry - OrderDistPoints * _Point)
|
|
return;
|
|
|
|
double tp = entry + Tpoints * _Point;
|
|
double sl = entry - Slpoints * _Point;
|
|
|
|
double lots = 0.01;
|
|
if(RiskPercentage > 0)
|
|
lots = calcLots(entry - sl);
|
|
|
|
datetime expiration = iTime(_Symbol, Timeframe, 0) + ExpirationCandles * PeriodSeconds(Timeframe);
|
|
|
|
Trade.BuyStop(lots,entry,_Symbol,sl,tp,ORDER_TIME_SPECIFIED,expiration,"BuyOrderBreakeOut");
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
void SellOrderBreakeOut(double entry)
|
|
{
|
|
|
|
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
|
|
if(bid < entry + OrderDistPoints * _Point)
|
|
return;
|
|
|
|
double tp = entry - Tpoints * _Point;
|
|
double sl = entry + Slpoints * _Point;
|
|
|
|
double lots = 0.01;
|
|
if(RiskPercentage> 0)
|
|
lots = calcLots(sl - entry);
|
|
|
|
datetime expiration = iTime(_Symbol, Timeframe, 0) + ExpirationCandles * PeriodSeconds(Timeframe);
|
|
|
|
Trade.SellStop(lots,entry,_Symbol,sl,tp,ORDER_TIME_SPECIFIED,expiration,"SellOrderBreakeOut");
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
void CloseAllOrders()
|
|
{
|
|
for(int i = OrdersTotal() - 1; i >= 0; i--)
|
|
{
|
|
Orderinfo.SelectByIndex(i);
|
|
ulong ticket = Orderinfo.Ticket();
|
|
if(Orderinfo.Symbol() == _Symbol && Orderinfo.Magic() == EAMagic)
|
|
{
|
|
Trade.OrderDelete(ticket);
|
|
}
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
void TrailStop()
|
|
{
|
|
double sl = 0;
|
|
double tp = 0;
|
|
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
|
|
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
|
|
|
|
for(int i = PositionsTotal() - 1; i >= 0; i--)
|
|
{
|
|
if(Positioninfo.SelectByIndex(i))
|
|
{
|
|
ulong ticket = Positioninfo.Ticket();
|
|
if(Positioninfo.Magic() == EAMagic && Positioninfo.Symbol() == _Symbol)
|
|
{
|
|
if(Positioninfo.PositionType() == POSITION_TYPE_BUY)
|
|
{
|
|
if(bid - Positioninfo.PriceOpen() > TsTriggerPoints * _Point)
|
|
{
|
|
tp = Positioninfo.TakeProfit();
|
|
sl = bid - (TsPoints * _Point);
|
|
if(sl > Positioninfo.StopLoss() && sl != 0)
|
|
{
|
|
Trade.PositionModify(ticket, sl, tp);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
if(Positioninfo.PositionType() == POSITION_TYPE_SELL)
|
|
{
|
|
if(ask + TsTriggerPoints * _Point < Positioninfo.PriceOpen())
|
|
{
|
|
tp = Positioninfo.TakeProfit();
|
|
sl = ask + (TsPoints * _Point);
|
|
if(sl < Positioninfo.StopLoss() && sl != 0)
|
|
{
|
|
Trade.PositionModify(ticket, sl, tp);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
bool TradeSession1()
|
|
{
|
|
if(!UseTimeZoneFilter)
|
|
return true;
|
|
datetime MidNight = iTime(_Symbol,PERIOD_D1,0);
|
|
datetime StartingTime = MidNight + (datetime)StartTimeSeconds1;
|
|
datetime EndTime = MidNight + (datetime)EndTimeSeconds1;
|
|
datetime CurrentTime = TimeCurrent();
|
|
if(CurrentTime>=StartingTime&&CurrentTime<EndTime)
|
|
return true;
|
|
return false;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
bool NewsPresent(ENUM_CALENDAR_EVENT_IMPORTANCE Importance,uint Seconds = 900)
|
|
{
|
|
if(!UseNewsFilter)
|
|
return false;
|
|
MqlCalendarValue Values[];
|
|
ResetLastError();
|
|
int NewsTotal = CalendarValueHistory(Values,TimeCurrent(),TimeCurrent()+Seconds,NULL,NULL);
|
|
if(NewsTotal<=0)
|
|
{
|
|
if(GetLastError()>0)
|
|
Print("Failed To get News Because of Error :", GetLastError());
|
|
else
|
|
{
|
|
Print("There is no News for the current symbol");
|
|
return false;
|
|
}
|
|
}
|
|
for(int i=0;i<NewsTotal;i++)
|
|
{
|
|
MqlCalendarEvent Event;
|
|
CalendarEventById(Values[i].event_id,Event);
|
|
MqlCalendarCountry Country;
|
|
CalendarCountryById(Event.country_id,Country);
|
|
if(StringFind(_Symbol,Country.currency)>-1)
|
|
{
|
|
if(Event.importance == Importance)
|
|
if(TimeCurrent()-Values[i].time<=Seconds)
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
|
|
bool IsTradingAllowedbyDay()
|
|
{
|
|
MqlDateTime today;
|
|
TimeCurrent(today);
|
|
string Daytoday = EnumToString((ENUM_DAY_OF_WEEK)today.day_of_week);
|
|
|
|
if(AllowedMonday && Daytoday == "MONDAY") return true;
|
|
if(AllowedTuesday && Daytoday == "TUESDAY") return true;
|
|
if(AllowedWednesday && Daytoday == "WEDNESDAY") return true;
|
|
if(AllowedThursday && Daytoday == "THURSDAY") return true;
|
|
if(AllowedFriday && Daytoday == "FRIDAY") return true;
|
|
if(AllowedSaturday && Daytoday == "SATURDAY") return true;
|
|
if(AllowedSunday && Daytoday == "SUNDAY") return true;
|
|
|
|
return false;
|
|
}
|