Untitled
unknown
c_cpp
2 years ago
11 kB
14
Indexable
//+------------------------------------------------------------------+
//| Impulse MACD strategy |
//| Copyright 2023, YourCompany |
//| https://www.yourcompany.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, YourCompany"
#property link "https://www.yourcompany.com"
#define MAGIC_NUMBER 1234518
#include <Trade/Trade.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\PositionInfo.mqh>
#include <Trade\AccountInfo.mqh>
input int MasterMA = 34;
input int SignalMA = 9;
input double longLine = -0.002;
input double shortLine = 0.002;
input int takeProfitSize = 20;
input int stopLossSize = 50;
int ExtTimeOut = 10;
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
class CImpulseMACDExpert
{
protected:
double m_adjusted_point; // point value adjusted for 3 or 5 points
CTrade m_trade; // trading object
CSymbolInfo m_symbol; // symbol info object
CPositionInfo m_position; // trade position object
CAccountInfo m_account; // account info wrapper
//--- indicators
int m_handle; // ImpulseMACD indicator handle
//--- indicator buffers
double m_buff_impulse_MACD[]; // MACD indicator main buffer
double m_buff_signal[]; // MACD indicator signal buffer
//--- indicator data for processing
double m_impulse_macd_current;
double m_impulse_macd_previous;
double m_signal_current;
double m_signal_previous;
//---
double m_stop_loss;
double m_take_profit;
public:
CImpulseMACDExpert(void);
~CImpulseMACDExpert(void);
bool Init(void);
void Deinit(void);
bool Processing(void);
protected:
bool InitCheckParameters(const int digits_adjust);
bool InitIndicators(void);
bool LongClosed(void);
bool ShortClosed(void);
bool LongModified(void);
bool ShortModified(void);
bool LongOpened(void);
bool ShortOpened(void);
};
//--- global expert
CImpulseMACDExpert ExtExpert;
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CImpulseMACDExpert::CImpulseMACDExpert(void) : m_adjusted_point(0),
m_handle(INVALID_HANDLE),
m_impulse_macd_current(0),
m_impulse_macd_previous(0),
m_signal_current(0),
m_signal_previous(0),
m_stop_loss(0),
m_take_profit(0)
{
ArraySetAsSeries(m_buff_impulse_MACD,true);
ArraySetAsSeries(m_buff_signal,true);
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CImpulseMACDExpert::~CImpulseMACDExpert(void)
{
}
//+------------------------------------------------------------------+
//| Initialization and checking for input parameters |
//+------------------------------------------------------------------+
bool CImpulseMACDExpert::Init(void)
{
//--- initialize common information
m_symbol.Name(Symbol());
m_trade.SetExpertMagicNumber(MAGIC_NUMBER);
m_trade.SetMarginMode();
m_trade.SetTypeFillingBySymbol(Symbol());
//--- tuning for 3 or 5 digits
int digits_adjust=1;
if(m_symbol.Digits()==3 || m_symbol.Digits()==5)
digits_adjust=10;
m_adjusted_point=m_symbol.Point()*digits_adjust;
//--- set default deviation for trading in adjusted points
m_stop_loss = stopLossSize*m_adjusted_point;
m_take_profit = takeProfitSize*m_adjusted_point;
//--- set default deviation for trading in adjusted points
m_trade.SetDeviationInPoints(3*digits_adjust);
//---
if(!InitCheckParameters(digits_adjust))
return(false);
if(!InitIndicators())
return(false);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Checking for input parameters |
//+------------------------------------------------------------------+
bool CImpulseMACDExpert::InitCheckParameters(const int digits_adjust)
{
//--- initial data checks
if(takeProfitSize*digits_adjust<m_symbol.StopsLevel())
{
printf("Take Profit must be greater than %d",m_symbol.StopsLevel());
return(false);
}
if(stopLossSize*digits_adjust<m_symbol.StopsLevel())
{
printf("Stop loss must be greater than %d",m_symbol.StopsLevel());
return(false);
}
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Initialization of the indicators |
//+------------------------------------------------------------------+
bool CImpulseMACDExpert::InitIndicators(void)
{
//--- create MACD indicator
if(m_handle==INVALID_HANDLE)
if((m_handle=iCustom(NULL, 0, "impulse", MasterMA, SignalMA))==INVALID_HANDLE)
{
printf("ErroMT5|Expert!11r creating ImpulseMACD indicator");
return(false);
}
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Check for long position opening |
//+------------------------------------------------------------------+
bool CImpulseMACDExpert::LongOpened(void)
{
bool res=false;
//--- check for long position (BUY) possibility
if(m_impulse_macd_current <= longLine && m_signal_current <= longLine)
if(m_impulse_macd_current>m_signal_current && m_impulse_macd_previous<m_signal_previous)
{
double price=m_symbol.Ask();
double tp =m_symbol.Bid()+m_take_profit;
double sl = m_symbol.Bid()-m_stop_loss;
double lotSize = m_account.MaxLotCheck(Symbol(), ORDER_TYPE_BUY, price) * 0.95;
lotSize = NormalizeDouble(lotSize, 2);
//--- open position
if(m_trade.PositionOpen(Symbol(),ORDER_TYPE_BUY,lotSize,price,sl,tp))
printf("Position by %s to be opened",Symbol());
else
{
printf("Error opening BUY position by %s : '%s'",Symbol(),m_trade.ResultComment());
printf("Open parameters : price=%f,TP=%f",price,tp);
}
res=true;
}
//--- result
return(res);
}
//+------------------------------------------------------------------+
//| Check for short position opening |
//+------------------------------------------------------------------+
bool CImpulseMACDExpert::ShortOpened(void)
{
bool res=false;
//--- check for short position (SELL) possibility
if(m_impulse_macd_current >= shortLine && m_signal_current >= shortLine)
if(m_impulse_macd_current<m_signal_current && m_impulse_macd_previous>m_signal_previous)
{
double price=m_symbol.Bid();
double tp =m_symbol.Ask()-m_take_profit;
double sl = m_symbol.Ask()+m_stop_loss;
double lotSize = m_account.MaxLotCheck(Symbol(), ORDER_TYPE_SELL, price) * 0.95;
lotSize = NormalizeDouble(lotSize, 2);
//--- open position
if(m_trade.PositionOpen(Symbol(),ORDER_TYPE_SELL,lotSize,price,sl,tp))
printf("Position by %s to be opened",Symbol());
else
{
printf("Error opening SELL position by %s : '%s'",Symbol(),m_trade.ResultComment());
printf("Open parameters : price=%f,TP=%f",price,tp);
}
//--- in any case we must exit from expert
res=true;
}
//--- result
return(res);
}
//+------------------------------------------------------------------+
//| main function returns true if any position processed |
//+------------------------------------------------------------------+
bool CImpulseMACDExpert::Processing(void)
{
if(!m_symbol.RefreshRates())
return(false);
if(BarsCalculated(m_handle)<2)
return(false);
if(CopyBuffer(m_handle,0,1,2,m_buff_impulse_MACD) !=2 ||
CopyBuffer(m_handle,1,1,2,m_buff_signal)!=2)
return(false);
m_impulse_macd_current = m_buff_impulse_MACD[0];
m_impulse_macd_previous = m_buff_impulse_MACD[1];
m_signal_current =m_buff_signal[0];
m_signal_previous =m_buff_signal[1];
if(m_position.Select(Symbol()))
{
// TODO
}
//--- no opened position identified
else
{
if(LongOpened())
return(true);
if(ShortOpened())
return(true);
}
//--- exit without position processing
return(false);
}
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit(void)
{
//--- create all necessary objects
if(!ExtExpert.Init())
return(INIT_FAILED);
//--- secceed
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert new tick handling function |
//+------------------------------------------------------------------+
void OnTick(void)
{
static datetime limit_time=0; // last trade processing time + timeout
//--- don't process if timeout
if(TimeCurrent()>=limit_time)
{
//--- check for data
if(Bars(Symbol(),Period())>2*SignalMA)
{
//--- change limit time by timeout in seconds if processed
if(ExtExpert.Processing())
limit_time=TimeCurrent()+ExtTimeOut;
}
}
}
//+------------------------------------------------------------------+
//crossover = ta.crossover(md[1], sb[1])
//crossunder = ta.crossunder(md[1], sb[1])
//
//longCondition = (sb[1] <= longLine and md[1] <= longLine) and crossover
//if (longCondition)
// strategy.entry("Long", strategy.long)
// alert("Long signal")
//
//shortCondition = (sb[1] >= shortLine and md[1] >= shortLine) and crossunder
//if (shortCondition)
// strategy.entry("Short", strategy.short)
// alert("Short signal")
//
//inLong = strategy.position_size > 0
//inShort = strategy.position_size < 0
//
//if inLong
// tpPrice = strategy.position_avg_price + tpPips
// slPrice = strategy.position_avg_price - slPips
// strategy.exit("TP/SL", from_entry="Long", limit=tpPrice, stop=slPrice)
//
//if inShort
// tpPrice = strategy.position_avg_price - tpPips
// slPrice = strategy.position_avg_price + slPips
// strategy.exit("TP/SL", from_entry="Short", limit=tpPrice, stop=slPrice)
Editor is loading...