Created
November 3, 2021 11:39
-
-
Save uhtred/1855bd8b17c467c693203efe7a0ea34a to your computer and use it in GitHub Desktop.
France expert advisor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Trade\Trade.mqh> | |
#include <Trade\SymbolInfo.mqh> | |
CTrade trade; | |
CSymbolInfo m_symbol; | |
MqlDateTime mql_StartTime, mql_StopTime, mql_CloseOrdersTime, mql_currentDateTime; | |
//--- input parameters | |
input double Volume = 1; | |
input double TakeProfit_Level = 20; // Take Profit | |
input double StopLoss = 20; // Stop Loss | |
// EMA Inputs | |
input group "Trailinig Stop"; | |
input double Inp_trailing_level = 50; // Trailing Level | |
input double Inp_trailing_gain = 5; // Trailing Gain | |
// Momentum Inputs | |
input group "Break Even"; | |
input double Inp_breakEven_level = 20; // Break Even Level | |
input double Inp_breakEven_gain = 10; // Break Even Gain | |
// Time Inputs | |
input group "Time"; | |
input string StartTime = "9:20"; // Start Time | |
input string StopTime = "16:00"; // Close Time | |
input string CloseOrdersTime = "17:45"; // Close Orders Time | |
// Momentum Inputs | |
input group "Momentum"; | |
input ushort Inp_momentum_period = 14; // Period | |
// EMA Inputs | |
input group "EMA"; | |
input bool Inp_ma_enabled = true; // Enabled | |
input ushort Inp_ma_slower_period = 200; // Slower | |
input ushort Inp_ma_faster_period = 50; // Faster | |
input ushort Inp_ma_distance = 50; // Distance | |
// MACD Inputs | |
input group "MACD"; | |
input ushort Inp_MACD_fast_ema_period = 12; // Faster | |
input ushort Inp_MACD_slow_ema_period = 26; // Slower | |
input ushort Inp_MACD_signal_period = 9; // Signal | |
input ushort Inp_MACD_distance = 10; // Distance from 0 | |
input ushort Inp_MACD_main_distance = 10;// Main Distance from Signal | |
input int Magic_Number = -1; | |
double poen; | |
void getEMABuffer(double &bufferArray[], int period) { | |
int EMAHandle = iMA(_Symbol, _Period, period, 0, MODE_EMA, PRICE_CLOSE); | |
ArraySetAsSeries(bufferArray, true); | |
CopyBuffer(EMAHandle, 0, 0, 3, bufferArray); | |
} | |
double MACDDistance; | |
string MACDCrossed = "WAIT"; | |
string getMACDSignal() | |
{ | |
string signal = "WAIT"; | |
string Signals[]; | |
int MACD_Handle = iMACD(_Symbol, _Period, Inp_MACD_fast_ema_period, Inp_MACD_slow_ema_period, Inp_MACD_signal_period, PRICE_CLOSE); | |
double MACD_Main[]; | |
ArraySetAsSeries(MACD_Main, true); | |
CopyBuffer(MACD_Handle, 0, 0, 3, MACD_Main); | |
double MACD_Signal[]; | |
ArraySetAsSeries(MACD_Signal, true); | |
CopyBuffer(MACD_Handle, 1, 0, 3, MACD_Signal); | |
if( ArraySize(MACD_Main) > 2 ) { | |
double MACD_MainValue = NormalizeDouble(MACD_Main[0], 2); | |
MACDDistance = MathAbs(MACD_Main[0]); | |
if( MACDDistance > Inp_MACD_distance ) { | |
// Crossover | |
if(MACD_Main[1] < MACD_Signal[1] && MACD_Main[0] > MACD_Signal[0]) { | |
MACDCrossed = "UP"; | |
} else if(MACD_Main[1] > MACD_Signal[1] && MACD_Main[0] < MACD_Signal[0]) { | |
MACDCrossed = "DOWN"; | |
} | |
} | |
if(MACDCrossed == "UP" && (MACD_Main[0] - MACD_Signal[0] > Inp_MACD_main_distance) ) { | |
signal = "BUY"; | |
MACDCrossed = "WAIT"; | |
} | |
if(MACDCrossed == "DOWN" && (MACD_Signal[0] - MACD_Main[0] > Inp_MACD_main_distance) ) { | |
signal = "SELL"; | |
MACDCrossed = "WAIT"; | |
} | |
} | |
return signal; | |
} | |
string getMomentumSignal() | |
{ | |
string signal; | |
double myPriceArray[]; | |
int iMomentumDefinition = iMomentum(_Symbol, _Period, Inp_momentum_period, PRICE_CLOSE); | |
ArraySetAsSeries(myPriceArray, true); | |
CopyBuffer(iMomentumDefinition, 0, 0, 3, myPriceArray); | |
double myMomentumValue = NormalizeDouble(myPriceArray[0], 2); | |
if(myMomentumValue < 100.0) | |
{ | |
signal = "BUY"; | |
} | |
if(myMomentumValue > 100.0 ) | |
{ | |
signal = "SELL"; | |
} | |
return signal; | |
} | |
double EMADistance; | |
string getMASignal(){ | |
string signal = "WAIT"; | |
double movingAverageSlower[]; | |
//int movingAverageSlowerDef = iMA(_Symbol, _Period, Inp_ma_slower_period, 0, MODE_EMA, PRICE_CLOSE); | |
//ArraySetAsSeries(movingAverageSlower, true); | |
//CopyBuffer(movingAverageSlowerDef, 0, 0, 3, movingAverageSlower); | |
getEMABuffer(movingAverageSlower, Inp_ma_slower_period); | |
double movingAverageFaster[]; | |
int movingAverageFasterDef = iMA(_Symbol, _Period, Inp_ma_faster_period, 0, MODE_EMA, PRICE_CLOSE); | |
ArraySetAsSeries(movingAverageFaster, true); | |
CopyBuffer(movingAverageFasterDef, 0, 0, 3, movingAverageFaster); | |
EMADistance = MathAbs(movingAverageFaster[0] - movingAverageSlower[0]); | |
//if( EMADistance > Inp_ma_distance ) { | |
//if( movingAverageFaster[0] > movingAverageSlower[0] ) { | |
if( currentAsk > movingAverageSlower[0] + Inp_ma_distance ) { | |
signal = "BUY"; | |
} else if( currentBid < movingAverageSlower[0] - Inp_ma_distance ) { | |
signal = "SELL"; | |
} | |
//} | |
return signal; | |
} | |
double priceArray[]; | |
string positionStatus; | |
//int stopTimeInteger = StringToTime(StopTime); | |
bool HorarioEntrada() | |
{ | |
TimeToStruct(TimeCurrent(),mql_currentDateTime); | |
if(mql_currentDateTime.hour >= mql_StartTime.hour && mql_currentDateTime.hour <= mql_StopTime.hour) | |
{ | |
// Hora atual igual a de início | |
if(mql_currentDateTime.hour == mql_StartTime.hour) | |
// Se minuto atual maior ou igual ao de início => está no horário de entradas | |
if(mql_currentDateTime.min >= mql_StartTime.min) | |
return true; | |
// Do contrário não está no horário de entradas | |
else | |
return false; | |
// Hora atual igual a de término | |
if(mql_currentDateTime.hour == mql_StopTime.hour) | |
// Se minuto atual menor ou igual ao de término => está no horário de entradas | |
if(mql_currentDateTime.min <= mql_StopTime.min) | |
return true; | |
// Do contrário não está no horário de entradas | |
else | |
return false; | |
// Hora atual maior que a de início e menor que a de término | |
return true; | |
} | |
// Hora fora do horário de entradas | |
return false; | |
} | |
bool HorarioFechamento() | |
{ | |
TimeToStruct(TimeCurrent(), mql_currentDateTime); | |
// Hora dentro do horário de fechamento | |
if(mql_currentDateTime.hour >= mql_CloseOrdersTime.hour) | |
{ | |
// Hora atual igual a de fechamento | |
if(mql_currentDateTime.hour == mql_CloseOrdersTime.hour) | |
// Se minuto atual maior ou igual ao de fechamento => está no horário de fechamento | |
if(mql_currentDateTime.min >= mql_CloseOrdersTime.min) | |
return true; | |
// Do contrário não está no horário de fechamento | |
else | |
return false; | |
// Hora atual maior que a de fechamento | |
return true; | |
} | |
// Hora fora do horário de fechamento | |
return false; | |
} | |
int OnInit() | |
{ | |
TimeToStruct(StringToTime(StartTime), mql_StartTime); | |
TimeToStruct(StringToTime(StopTime), mql_StopTime); | |
TimeToStruct(StringToTime(CloseOrdersTime), mql_CloseOrdersTime); | |
if ( _Digits == 3 || _Digits == 5 ) { | |
poen = 10*Point(); | |
} else { | |
poen = Point(); | |
} | |
return INIT_SUCCEEDED; | |
} | |
void Buy(double currentPrice) { | |
currentOrderProfit = normalizePrice(currentPrice + TakeProfit_Level); | |
currentOrderStopLoss = normalizePrice(currentPrice - StopLoss); | |
trade.PositionOpen(_Symbol, ORDER_TYPE_BUY, Volume, currentPrice, currentOrderStopLoss, currentOrderProfit); | |
} | |
void Sell(double currentPrice) { | |
currentOrderProfit = normalizePrice(currentPrice - TakeProfit_Level); | |
currentOrderStopLoss = normalizePrice(currentPrice + StopLoss); | |
trade.PositionOpen(_Symbol, ORDER_TYPE_SELL, Volume, currentPrice, currentOrderStopLoss , currentOrderProfit); | |
} | |
void Modify(double newStopLoss) { | |
trade.PositionModify(_Symbol, newStopLoss, currentOrderProfit); | |
} | |
double normalizePrice(double value) { | |
return NormalizeDouble(value * poen, _Digits); | |
} | |
int trailingStopCount = 1; | |
void handleTrailingStop() { | |
double newStopLoss; | |
if(currentOrderEntry == "BUY") { | |
if(currentAsk > (currentOrderPrice + Inp_trailing_level * trailingStopCount)) { | |
Print("Trailing stop buy: " + trailingStopCount); | |
newStopLoss = normalizePrice(currentOrderPrice + (Inp_trailing_gain * trailingStopCount)); | |
currentOrderStopLoss = newStopLoss; | |
Modify(newStopLoss); | |
trailingStopCount++; | |
} | |
} | |
if(currentOrderEntry == "SELL") { | |
if(currentBid < (currentOrderPrice - Inp_trailing_level * trailingStopCount)) { | |
Print("Trailing stop sell: " + trailingStopCount); | |
newStopLoss = normalizePrice(currentOrderPrice - (Inp_trailing_gain * trailingStopCount)); | |
currentOrderStopLoss = newStopLoss; | |
Modify(newStopLoss); | |
trailingStopCount++; | |
} | |
} | |
} | |
void handleBreakEven() { | |
double newStopLoss; | |
if(!breakEvenActive && currentOrderEntry == "BUY") { | |
if(currentAsk > (currentOrderPrice + Inp_breakEven_level)) { | |
Print("Break Even BUY"); | |
newStopLoss = normalizePrice(currentOrderPrice + Inp_breakEven_gain); | |
currentOrderStopLoss = newStopLoss; | |
trade.PositionModify(_Symbol, newStopLoss, currentOrderProfit); | |
breakEvenActive = true; | |
} | |
} | |
if(!breakEvenActive && currentOrderEntry == "SELL") { | |
if(currentBid < (currentOrderPrice - Inp_breakEven_level)) { | |
Print("Break Even SELL"); | |
newStopLoss = normalizePrice(currentOrderPrice - Inp_breakEven_gain); | |
currentOrderStopLoss = newStopLoss; | |
trade.PositionModify(_Symbol, newStopLoss, currentOrderProfit); | |
breakEvenActive = true; | |
} | |
} | |
} | |
bool hasOperation = false; | |
bool breakEvenActive = false; | |
double currentOrderPrice; | |
string currentOrderEntry; | |
double currentOrderProfit; | |
double currentOrderStopLoss; | |
double currentAsk; | |
double currentBid; | |
string momentumSignal = "WAIT"; | |
string EMASignal = "WAIT"; | |
string MACDSignal = "WAIT"; | |
void OnTick() | |
{ | |
currentAsk = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_ASK), _Digits); | |
currentBid = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_BID), _Digits); | |
if( HorarioEntrada() ) { | |
if( PositionsTotal() == 0 ) { | |
breakEvenActive = false; | |
trailingStopCount = 1; | |
//momentumSignal = getMomentumSignal(); | |
EMASignal = getMASignal(); | |
string MACD_Signals = getMACDSignal(); | |
//if(MACD_Signals == EMASignal && MACD_Signals != "WAIT") { | |
if(MACD_Signals != "WAIT") { | |
currentOrderEntry = MACD_Signals; | |
if(currentOrderEntry == "BUY" ) { | |
currentOrderPrice = currentAsk; | |
Buy(currentAsk); | |
} else { | |
currentOrderPrice = currentBid; | |
Sell(currentBid); | |
} | |
} | |
Comment( | |
"Point(): ", Point()+"\n", | |
"Digits(): ", Digits()+"\n", | |
"Points: ", (currentBid - currentOrderPrice) +"\n", | |
"momentumSignal: ", momentumSignal +"\n", | |
"EMASignal: ", EMASignal +"\n", | |
"MACDSignal: ", MACD_Signals +"\n", | |
"EMADistance: ", EMADistance +"\n", | |
"MACDDistance: ", MACDDistance +"\n" | |
); | |
} | |
if( PositionsTotal() > 0 ) { | |
handleBreakEven(); | |
if(breakEvenActive) { | |
handleTrailingStop(); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment