L1Trend/Experts/EMAFilteredL1.mq5

319 righe
Nessun fine linea
21 KiB
MQL5

//+------------------------------------------------------------------+
//| EMAFilteredL1.mq5 |
//| Copyright 2000-2026, MetaQuotes Ltd. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2000-2026, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.00"
//--- best EMA parameters for EURUSD,H1,2025
input int FastEMA = 29; // Fast EMA
input int SlowEMA = 101; // Slow EMA
//--- trade volume
input double TradeLot = 0.1; // Lot size
//--- L1 filter parameters
input int L1TotalBars = 1000; // Total bars for L1 filter
input bool L1FilterOpen = false; // Use filter for Open
input bool L1FilterClose = false; // Use filter for Close
input double L1CoefLambda = 0.2; // Lambda in lambda_max units
//--- save statistics
input bool SaveStatistics = false; // Save statistics to file
//---
#define EMA_MAGIC 1234503
#include <Trade\Trade.mqh>
CTrade ExtTrade;
int ExtHandle = INVALID_HANDLE;
bool ExtHedging = false;
int FastHandle, SlowHandle;
string ExtStrategyName="EMA";
string ExtStrategyFileName="";
//+------------------------------------------------------------------+
//| Check new bar |
//+------------------------------------------------------------------+
bool IsNewBar()
{
static datetime last_time=0;
datetime t[1];
if(CopyTime(_Symbol,_Period,0,1,t)>0)
{
if(t[0]!=last_time)
{
last_time=t[0];
return true;
}
}
return false;
}
//+------------------------------------------------------------------+
//| CheckTrendL1 |
//+------------------------------------------------------------------+
double CheckTrendL1()
{
int max_bars=L1TotalBars;
MqlRates rates_data[];
ArrayResize(rates_data,max_bars);
ArraySetAsSeries(rates_data,false);
if(CopyRates(_Symbol,_Period,0,max_bars,rates_data) != max_bars)
{
Print("CopyRates failed for L1Trend");
return 0;
}
//--- prepare data (close prices vector)
int data_count=max_bars;
vector<double> data_close;
data_close.Resize(data_count);
for(int i=0; i<data_count; i++)
data_close[i] = rates_data[i].close;
//--- calculate L1 filter
vector<double> data_filtered;
data_filtered.Resize(data_count);
double dp=0.0;
bool res=data_close.L1TrendFilter(data_filtered,L1CoefLambda,true);
if(res)
dp = data_filtered[data_count-1] - data_filtered[data_count-2];
//---
return dp;
}
//+------------------------------------------------------------------+
//| GetTradeSignal (2EMA crossover) |
//+------------------------------------------------------------------+
bool GetTradeSignal(ENUM_ORDER_TYPE &signal)
{
signal=WRONG_VALUE;
//---
double fast[],slow[];
ArrayResize(fast,2);
ArrayResize(slow,2);
//---
ArraySetAsSeries(fast,true);
ArraySetAsSeries(slow,true);
//---
if(CopyBuffer(FastHandle,0,1,2,fast)!=2)
return false;
//---
if(CopyBuffer(SlowHandle,0,1,2,slow)!=2)
return false;
//---
if(fast[1]<slow[1] && fast[0]>slow[0])
signal=ORDER_TYPE_BUY;
if(fast[1]>slow[1] && fast[0]<slow[0])
signal=ORDER_TYPE_SELL;
//---
return true;
}
//+------------------------------------------------------------------+
//| CheckForOpen |
//+------------------------------------------------------------------+
void CheckForOpen()
{
ENUM_ORDER_TYPE signal;
//---
if(!GetTradeSignal(signal) || signal==WRONG_VALUE)
return;
//---
if(L1FilterOpen)
{
double dp=CheckTrendL1();
//---
if(signal==ORDER_TYPE_BUY && dp<0)
return;
if(signal==ORDER_TYPE_SELL && dp>0)
return;
}
//---
if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) || Bars(_Symbol,_Period)<L1TotalBars)
return;
//---
double price=(signal==ORDER_TYPE_BUY)
? SymbolInfoDouble(_Symbol,SYMBOL_ASK)
: SymbolInfoDouble(_Symbol,SYMBOL_BID);
//---
ExtTrade.PositionOpen(_Symbol,signal,TradeLot,price,0,0);
}
//+------------------------------------------------------------------+
//| CheckForClose |
//+------------------------------------------------------------------+
void CheckForClose()
{
//--- check position
if(!PositionSelect(_Symbol))
return;
//--- check position magic
if(PositionGetInteger(POSITION_MAGIC)!=EMA_MAGIC)
return;
//--- check trade signal
ENUM_ORDER_TYPE signal;
if(!GetTradeSignal(signal))
return;
//---
long type=PositionGetInteger(POSITION_TYPE);
bool close_signal=false;
//---
if(type==POSITION_TYPE_BUY && signal==ORDER_TYPE_SELL)
close_signal=true;
//---
if(type==POSITION_TYPE_SELL && signal==ORDER_TYPE_BUY)
close_signal=true;
//--- check L1 filter
if(L1FilterClose)
{
double dp = CheckTrendL1();
if(type == POSITION_TYPE_BUY && dp > 0)
{
close_signal = false;
PrintFormat("Close BUY signal cancelled by L1 trend dp=%.5f", dp);
}
if(type == POSITION_TYPE_SELL && dp < 0)
{
close_signal = false;
PrintFormat("Close SELL signal cancelled by L1 trend dp=%.5f", dp);
}
}
//---
if(close_signal)
ExtTrade.PositionClose(_Symbol,3);
}
//+------------------------------------------------------------------+
//| SelectPosition |
//+------------------------------------------------------------------+
bool SelectPosition()
{
bool res = false;
if(ExtHedging)
{
uint total = PositionsTotal();
for(uint i=0; i<total; i++)
{
string sym = PositionGetSymbol(i);
if(sym == _Symbol && PositionGetInteger(POSITION_MAGIC)==EMA_MAGIC)
{
res = true;
break;
}
}
}
else
{
if(PositionSelect(_Symbol))
res = (PositionGetInteger(POSITION_MAGIC)==EMA_MAGIC);
}
return res;
}
//+------------------------------------------------------------------+
//| Expert initialization |
//+------------------------------------------------------------------+
int OnInit()
{
ExtHedging = (AccountInfoInteger(ACCOUNT_MARGIN_MODE)==ACCOUNT_MARGIN_MODE_RETAIL_HEDGING);
ExtTrade.SetExpertMagicNumber(EMA_MAGIC);
ExtTrade.SetMarginMode();
ExtTrade.SetTypeFillingBySymbol(_Symbol);
//--- prepare indicators
FastHandle=iMA(_Symbol,_Period,FastEMA,0,MODE_EMA,PRICE_CLOSE);
SlowHandle=iMA(_Symbol,_Period,SlowEMA,0,MODE_EMA,PRICE_CLOSE);
if(FastHandle==INVALID_HANDLE || SlowHandle==INVALID_HANDLE)
return INIT_FAILED;
//--- prepare filename
ExtStrategyFileName=PrepareStrategyFileName(ExtStrategyName);
//--- delete old file if exists
if(FileIsExist(ExtStrategyFileName))
FileDelete(ExtStrategyFileName);
//---
return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
//| PrepareStrategyFileName |
//+------------------------------------------------------------------+
string PrepareStrategyFileName(string strategy_name)
{
int v=0;
if(L1FilterOpen)
v=v | 1;
//---
if(L1FilterClose)
v=v | 2;
//---
string filename=IntegerToString(v)+"_"+strategy_name+"_"+_Symbol+".txt";
return filename;
}
//+------------------------------------------------------------------+
//| Save account statistics to file |
//+------------------------------------------------------------------+
void SaveAccountStatistics()
{
//--- check file name
if(ExtStrategyFileName=="")
return;
//---
int file=FileOpen(ExtStrategyFileName,FILE_WRITE|FILE_READ|FILE_TXT|FILE_SHARE_WRITE|FILE_ANSI);
if(file==INVALID_HANDLE)
{
Print("File open error: ",GetLastError());
return;
}
//--- append
FileSeek(file,0,SEEK_END);
//--- account data
double balance = AccountInfoDouble(ACCOUNT_BALANCE);
double equity = AccountInfoDouble(ACCOUNT_EQUITY);
double margin = AccountInfoDouble(ACCOUNT_MARGIN);
double free_margin = AccountInfoDouble(ACCOUNT_MARGIN_FREE);
double margin_lvl = AccountInfoDouble(ACCOUNT_MARGIN_LEVEL);
//--- volume
double volume=0.0;
if(PositionSelect(_Symbol))
volume=PositionGetDouble(POSITION_VOLUME);
//--- time
datetime t[1];
if(CopyTime(_Symbol,_Period,0,1,t)<=0)
{
FileClose(file);
return;
}
double current_close[1];
if(CopyClose(_Symbol,_Period,0,1,current_close)<=0)
{
FileClose(file);
return;
}
string line=StringFormat("%s;%.2f;%.2f;%.2f;%.2f;%.2f;%.2f;%f",TimeToString(t[0],TIME_DATE|TIME_SECONDS),
balance,equity,margin,free_margin,margin_lvl,volume,current_close[0]);
//---
FileWrite(file,line);
//---
FileClose(file);
}
//+------------------------------------------------------------------+
//| Expert OnTick function |
//+------------------------------------------------------------------+
void OnTick()
{
//--- trade only at new bar
if(!IsNewBar())
return;
//--- check trade conditions
if(SelectPosition())
CheckForClose();
else
CheckForOpen();
//--- save account statistics
if(SaveStatistics)
SaveAccountStatistics();
}
//+------------------------------------------------------------------+
//| Expert deinitialization |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- save account statistics
if(SaveStatistics)
SaveAccountStatistics();
//--- release indicator handles
if(FastHandle!=INVALID_HANDLE)
IndicatorRelease(FastHandle);
//---
if(SlowHandle!=INVALID_HANDLE)
IndicatorRelease(SlowHandle);
}
//+------------------------------------------------------------------+