Algorithm of actions: we catch the transaction 'TRADE_TRANSACTION_DEAL_ADD' (adding a deal to history). Next, we check the property of the deal from the ENUM_DEAL_REASON (The reason or source for deal execution) enumeration - if it is 'DEAL_REASON_SL' or 'DEAL_REASON_TP', we send a signal.
Example: a simple Expert Advisor at the intersection of two iMA (Moving Average, MA) indicators.
Code: Simple Two iMA Crossing.mq5
ATTENTION: To get indicator data in an MQL5 Expert Advisor, you must adhere to the following rules:
The indicator handle is created in OnInit
Then (as a rule, in OnTick), the indicator data is received using CopyBuffer
Creating indicator handles in OnInit
//+------------------------------------------------------------------+//| Expert initialization function |//+------------------------------------------------------------------+intOnInit()
{
//---ResetLastError();
if(!m_symbol.Name(Symbol())) // sets symbol name
{
Print(__FILE__," ",__FUNCTION__,", ERROR: CSymbolInfo.Name");
return(INIT_FAILED);
}
RefreshRates();
//---
m_trade.SetExpertMagicNumber(InpMagic);
m_trade.SetMarginMode();
m_trade.SetTypeFillingBySymbol(m_symbol.Name());
m_trade.SetDeviationInPoints(InpDeviation);
//--- create handle of the indicator iMA
handle_iMA_Fast=iMA(m_symbol.Name(),Period(),Inp_MA_Fast_ma_period,Inp_MA_Fast_ma_shift,
Inp_MA_Fast_ma_method,Inp_MA_Fast_applied_price);
//--- if the handle is not createdif(handle_iMA_Fast==INVALID_HANDLE)
{
//--- tell about the failure and output the error codePrintFormat("Failed to create handle of the iMA ('Fast') indicator for the symbol %s/%s, error code %d",
m_symbol.Name(),
EnumToString(Period()),
GetLastError());
//--- the indicator is stopped earlyreturn(INIT_FAILED);
}
//--- create handle of the indicator iMA
handle_iMA_Slow=iMA(m_symbol.Name(),Period(),Inp_MA_Slow_ma_period,Inp_MA_Slow_ma_shift,
Inp_MA_Slow_ma_method,Inp_MA_Slow_applied_price);
//--- if the handle is not createdif(handle_iMA_Slow==INVALID_HANDLE)
{
//--- tell about the failure and output the error codePrintFormat("Failed to create handle of the iMA ('Slow') indicator for the symbol %s/%s, error code %d",
m_symbol.Name(),
EnumToString(Period()),
GetLastError());
//--- the indicator is stopped earlyreturn(INIT_FAILED);
}//---return(INIT_SUCCEEDED);
}
So, the EA will look for a signal only at the moment of a new bar birth. The code responsible for finding a new bar:
//+------------------------------------------------------------------+//| Expert tick function |//+------------------------------------------------------------------+voidOnTick()
{
***
//--- we work only at the time of the birth of new bardatetime time_0=iTime(m_symbol.Name(),Period(),0);
if(time_0==m_prev_bars)
return;
m_prev_bars=time_0;
***
}
If a new bar is found, look for a signal: compare the values of the two iMA indicators ('Fast' and 'Slow') on bar # 2 and on bar # 1. Please note that the current bar - bar # 0 is not used. When a signal is received to open a BUY position, we issue an order to close SELL positions and vice versa: when a signal is received to open a SELL position, we issue an order to close a BUY.
//+------------------------------------------------------------------+//| Expert tick function |//+------------------------------------------------------------------+voidOnTick()
{
***
//---double fast[],slow[];
ArraySetAsSeries(fast,true);
ArraySetAsSeries(slow,true);
int start_pos=0,count=6;
if(!iGetArray(handle_iMA_Fast,0,start_pos,count,fast) || !iGetArray(handle_iMA_Slow,0,start_pos,count,slow))
{
m_prev_bars=0;
return;
}
//--- check signal close SELL and open BUYif(fast[1]>slow[1]&&fast[2]<slow[2])
{
m_need_close_sells=true;
m_need_open_buy=true;
return;
}
//--- check signal close BUY and open SELLif(fast[1]<slow[1]&&fast[2]>slow[2])
{
m_need_close_buys=true;
m_need_open_sell=true;
return;
}
}
Counting of elements of copied data (indicator buffer with the index buffer_num) from the starting position is performed from the present to the past, i.e., starting position of 0 means the current bar (indicator value for the current bar). When copying the yet unknown amount of data, it is recommended to use a dynamic array as a buffer[]...
Example: if the Moving Average indicator dropped below the Close price, close the BUY positions, if the Moving Average indicator rose above the Close price, close the SELL positions.
Code: Simple iMA Above Below Close.mq5
An example of creating an indicator is described in detail above (#112), and here I will dwell in more detail on receiving a signal and not implementing a signal.
So, at the moment of the birth of a new bar
//--- we work only at the time of the birth of new bardatetime time_0=iTime(m_symbol.Name(),Period(),0);
if(time_0==m_prev_bars)
return;
m_prev_bars=time_0;
//---
check if it is necessary to close positions (compare the Moving Average indicator value on bar #1 and the Close price of bar #1)
//--- check signal close BUY if(ma[1]<rates[1].close)
{
m_need_close_buys=true;
return;
}
//--- check signal close SELLif(ma[1]>rates[1].close)
{
m_need_close_sells=true;
return;
}
In OnTick (that is, at each tick) we check the ' m_need_close_buys ' and ' m_need_close_sells ' flags - and, if necessary, close the positions of the selected direction.
//+------------------------------------------------------------------+//| Expert tick function |//+------------------------------------------------------------------+voidOnTick()
{
//--- need close BUY positions OR SELL positionsif(m_need_close_buys || m_need_close_sells)
{
int count_buys = 0;
int count_sells = 0;
CalculateAllPositions(count_buys,count_sells);
//---if(m_need_close_buys)
{
if(count_buys>0)
{
ClosePositions(POSITION_TYPE_BUY);
return;
}
else
m_need_close_buys=false;
}
//---if(m_need_close_sells)
{
if(count_sells>0)
{
ClosePositions(POSITION_TYPE_SELL);
return;
}
else
m_need_close_sells=false;
}
}
This is a blank - an example of how to control a trading signal. This code avoids the situation: opening multiple positions. How it works: after a trade order is generated, we increase the 'SPosition' structure. In OnTick, if 'SPosition' is greater than zero, go to the block for opening positions. In OnTradeTransaction, we monitor the situation when a position appears exactly on our signal.
//+------------------------------------------------------------------+//| Expert initialization function |//+------------------------------------------------------------------+intOnInit()
{
//--- create handle of the indicator iMAhandle_iMA=iMA(Symbol(),Period(),Inp_MA_ma_period,Inp_MA_ma_shift,
Inp_MA_ma_method,Inp_MA_applied_price);//--- if the handle is not createdif(handle_iMA==INVALID_HANDLE)
{
//--- tell about the failure and output the error codePrintFormat("Failed to create handle of the iMA indicator for the symbol %s/%s, error code %d",
Symbol(),
EnumToString(Period()),
GetLastError());
//--- the indicator is stopped earlyreturn(INIT_FAILED);
}
//---return(INIT_SUCCEEDED);
}
Getting values (I use the iGetArray generic function). Please note: for the array "array_ma" I use "ArraySetAsSeries" - in this case, in the “array_ma” array, the element with the index “0” corresponds to the rightmost bar on the chart (bar # 0)
Patrine Peniston : Hey, new here. Im unsure if it was mentioned before but im trying to figure out how to open a position on the NEW Candle open price . is this possible?
No, this is impossible: since the candle has opened and this event is IN THE PAST :)
But the problem can be formulated differently: how to catch the moment of the birth of a new bar and open a position at that moment. Will this formulation of the question suit you?
Example: tracking the triggering of Stop Loss or Take Profit
Code: SL TP Triggered.mq5
Algorithm of actions: we catch the transaction 'TRADE_TRANSACTION_DEAL_ADD' (adding a deal to history). Next, we check the property of the deal from the ENUM_DEAL_REASON (The reason or source for deal execution) enumeration - if it is 'DEAL_REASON_SL' or 'DEAL_REASON_TP', we send a signal.
Example: a simple Expert Advisor at the intersection of two iMA (Moving Average, MA) indicators.
Code: Simple Two iMA Crossing.mq5
ATTENTION: To get indicator data in an MQL5 Expert Advisor, you must adhere to the following rules:
Creating indicator handles in OnInit
So, the EA will look for a signal only at the moment of a new bar birth. The code responsible for finding a new bar:
If a new bar is found, look for a signal: compare the values of the two iMA indicators ('Fast' and 'Slow') on bar # 2 and on bar # 1. Please note that the current bar - bar # 0 is not used. When a signal is received to open a BUY position, we issue an order to close SELL positions and vice versa: when a signal is received to open a SELL position, we issue an order to close a BUY.
Example: if the Moving Average indicator dropped below the Close price, close the BUY positions, if the Moving Average indicator rose above the Close price, close the SELL positions.
Code: Simple iMA Above Below Close.mq5
An example of creating an indicator is described in detail above (#112), and here I will dwell in more detail on receiving a signal and not implementing a signal.
So, at the moment of the birth of a new bar
check if it is necessary to close positions (compare the Moving Average indicator value on bar #1 and the Close price of bar #1)
In OnTick (that is, at each tick) we check the ' m_need_close_buys ' and ' m_need_close_sells ' flags - and, if necessary, close the positions of the selected direction.
We catch the transaction
Code: We catch the transaction.mq5
This is a blank - an example of how to control a trading signal. This code avoids the situation: opening multiple positions. How it works: after a trade order is generated, we increase the 'SPosition' structure. In OnTick, if 'SPosition' is greater than zero, go to the block for opening positions. In OnTradeTransaction, we monitor the situation when a position appears exactly on our signal.
Example: find the most losing position and the most profitable position
Сode: Search Max Loss and Max Profit.mq5
Example: catching a Take Profit trigger
The code: Last Deal Take Profit activation.mq5
An example of online work (via OnTradeTransaction).
Receiving data from an indicator in an MQL5.
Scheme:
An example for the iMA indicator:
Forum on trading, automated trading systems and testing trading strategies
How to start with MQL5
Vladimir Karputov, 2020.03.08 09:04
Creating an iMA indicator handle, getting indicator values
(code: iMA Values on a Chart)
The main rule: the indicator handle needs to be received once (it is optimal to do this in the OnInit function).
Input parameters and the variable in which the indicator handle is stored:
Creating a handle (checking the result)
Getting values (I use the iGetArray generic function). Please note: for the array "array_ma" I use "ArraySetAsSeries" - in this case, in the “array_ma” array, the element with the index “0” corresponds to the rightmost bar on the chart (bar # 0)
The result of work:
Pic. 1. Get value on bar #0, #1, #2
Hey, new here. Im unsure if it was mentioned before but im trying to figure out how to open a position on the NEW Candle open price . is this possible?
No, this is impossible: since the candle has opened and this event is IN THE PAST :)
But the problem can be formulated differently: how to catch the moment of the birth of a new bar and open a position at that moment. Will this formulation of the question suit you?
Example: at the moment of the birth of a new bar, a position of 1.0 lot is opened
The code: Open a position on a new bar.mq5