add MQL5Test Workspace Content as BKP Solution ...
This commit is contained in:
@@ -0,0 +1,262 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Demo_iIchimoku.mq5 |
|
||||
//| Copyright 2011, MetaQuotes Software Corp. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2000-2024, MetaQuotes Ltd."
|
||||
#property link "https://www.mql5.com"
|
||||
#property version "1.00"
|
||||
#property description "The indicator demonstrates how to obtain data"
|
||||
#property description "of indicator buffers for the iIchimoku technical indicator."
|
||||
#property description "A symbol and timeframe used for calculation of the indicator,"
|
||||
#property description "are set by the symbol and period parameters."
|
||||
#property description "The method of creation of the handle is set through the 'type' parameter (function type)."
|
||||
#property description "All other parameters just like in the standard Ichimoku Kinko Hyo."
|
||||
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 5
|
||||
#property indicator_plots 4
|
||||
//--- the Tenkan_sen plot
|
||||
#property indicator_label1 "Tenkan_sen"
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrRed
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 1
|
||||
//--- the Kijun_sen plot
|
||||
#property indicator_label2 "Kijun_sen"
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 clrBlue
|
||||
#property indicator_style2 STYLE_SOLID
|
||||
#property indicator_width2 1
|
||||
//--- the Senkou_Span plot
|
||||
#property indicator_label3 "Senkou Span A;Senkou Span B" // two fields will be shown in Data Window
|
||||
#property indicator_type3 DRAW_FILLING
|
||||
#property indicator_color3 clrSandyBrown, clrThistle
|
||||
#property indicator_style3 STYLE_SOLID
|
||||
#property indicator_width3 1
|
||||
//--- the Chikou_Span plot
|
||||
#property indicator_label4 "Chinkou_Span"
|
||||
#property indicator_type4 DRAW_LINE
|
||||
#property indicator_color4 clrLime
|
||||
#property indicator_style4 STYLE_SOLID
|
||||
#property indicator_width4 1
|
||||
//+------------------------------------------------------------------+
|
||||
//| Enumeration of the methods of handle creation |
|
||||
//+------------------------------------------------------------------+
|
||||
enum Creation
|
||||
{
|
||||
Call_iIchimoku, // use iIchimoku
|
||||
Call_IndicatorCreate // use IndicatorCreate
|
||||
};
|
||||
//--- input parameters
|
||||
input Creation type=Call_iIchimoku; // type of the function
|
||||
input int tenkan_sen=9; // period of Tenkan-sen
|
||||
input int kijun_sen=26; // period of Kijun-sen
|
||||
input int senkou_span_b=52; // period of Senkou Span B
|
||||
input string symbol=" "; // symbol
|
||||
input ENUM_TIMEFRAMES period=PERIOD_CURRENT; // timeframe
|
||||
//--- indicator buffer
|
||||
double Tenkan_sen_Buffer[];
|
||||
double Kijun_sen_Buffer[];
|
||||
double Senkou_Span_A_Buffer[];
|
||||
double Senkou_Span_B_Buffer[];
|
||||
double Chinkou_Span_Buffer[];
|
||||
//--- variable for storing the handle of the iIchimoku indicator
|
||||
int handle;
|
||||
//--- variable for storing
|
||||
string name=symbol;
|
||||
//--- name of the indicator on a chart
|
||||
string short_name;
|
||||
//--- we will keep the number of values in the Ichimoku Kinko Hyo indicator
|
||||
int bars_calculated=0;
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
//--- assignment of arrays to indicator buffers
|
||||
SetIndexBuffer(0,Tenkan_sen_Buffer,INDICATOR_DATA);
|
||||
SetIndexBuffer(1,Kijun_sen_Buffer,INDICATOR_DATA);
|
||||
SetIndexBuffer(2,Senkou_Span_A_Buffer,INDICATOR_DATA);
|
||||
SetIndexBuffer(3,Senkou_Span_B_Buffer,INDICATOR_DATA);
|
||||
SetIndexBuffer(4,Chinkou_Span_Buffer,INDICATOR_DATA);
|
||||
//--- set the shift for the Senkou Span channel of kijun_sen bars in the future direction
|
||||
PlotIndexSetInteger(2,PLOT_SHIFT,kijun_sen);
|
||||
//--- setting a shift for the Chikou Span line is not required, since the Chinkou data Span
|
||||
//--- is already stored with a shift in iIchimoku
|
||||
//--- determine the symbol the indicator is drawn for
|
||||
name=symbol;
|
||||
//--- delete spaces to the right and to the left
|
||||
StringTrimRight(name);
|
||||
StringTrimLeft(name);
|
||||
//--- if it results in zero length of the 'name' string
|
||||
if(StringLen(name)==0)
|
||||
{
|
||||
//--- take the symbol of the chart the indicator is attached to
|
||||
name=_Symbol;
|
||||
}
|
||||
//--- create handle of the indicator
|
||||
if(type==Call_iIchimoku)
|
||||
handle=iIchimoku(name,period,tenkan_sen,kijun_sen,senkou_span_b);
|
||||
else
|
||||
{
|
||||
//--- fill the structure with parameters of the indicator
|
||||
MqlParam pars[3];
|
||||
//--- periods and shifts of the Alligator lines
|
||||
pars[0].type=TYPE_INT;
|
||||
pars[0].integer_value=tenkan_sen;
|
||||
pars[1].type=TYPE_INT;
|
||||
pars[1].integer_value=kijun_sen;
|
||||
pars[2].type=TYPE_INT;
|
||||
pars[2].integer_value=senkou_span_b;
|
||||
//--- create handle
|
||||
handle=IndicatorCreate(name,period,IND_ICHIMOKU,3,pars);
|
||||
}
|
||||
//--- if the handle is not created
|
||||
if(handle==INVALID_HANDLE)
|
||||
{
|
||||
//--- tell about the failure and output the error code
|
||||
PrintFormat("Failed to create handle of the iIchimoku indicator for the symbol %s/%s, error code %d",
|
||||
name,
|
||||
EnumToString(period),
|
||||
GetLastError());
|
||||
//--- the indicator is stopped early
|
||||
return(INIT_FAILED);
|
||||
}
|
||||
//--- show the symbol/timeframe the Ichimoku Kinko Hyo indicator is calculated for
|
||||
short_name=StringFormat("iIchimoku(%s/%s, %d, %d ,%d)",name,EnumToString(period),
|
||||
tenkan_sen,kijun_sen,senkou_span_b);
|
||||
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
|
||||
//--- normal initialization of the indicator
|
||||
return(INIT_SUCCEEDED);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator iteration function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnCalculate(const int rates_total,
|
||||
const int prev_calculated,
|
||||
const datetime &time[],
|
||||
const double &open[],
|
||||
const double &high[],
|
||||
const double &low[],
|
||||
const double &close[],
|
||||
const long &tick_volume[],
|
||||
const long &volume[],
|
||||
const int &spread[])
|
||||
{
|
||||
//--- number of values copied from the iIchimoku indicator
|
||||
int values_to_copy;
|
||||
//--- determine the number of values calculated in the indicator
|
||||
int calculated=BarsCalculated(handle);
|
||||
if(calculated<=0)
|
||||
{
|
||||
PrintFormat("BarsCalculated() returned %d, error code %d",calculated,GetLastError());
|
||||
return(0);
|
||||
}
|
||||
//--- if it is the first start of calculation of the indicator or if the number of values in the iIchimoku indicator changed
|
||||
//---or if it is necessary to calculated the indicator for two or more bars (it means something has changed in the price history)
|
||||
if(prev_calculated==0 || calculated!=bars_calculated || rates_total>prev_calculated+1)
|
||||
{
|
||||
//--- if the Tenkan_sen_Buffer array is greater than the number of values in the iIchimoku indicator for symbol/period, then we don't copy everything
|
||||
//--- otherwise, we copy less than the size of indicator buffers
|
||||
if(calculated>rates_total) values_to_copy=rates_total;
|
||||
else values_to_copy=calculated;
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- it means that it's not the first time of the indicator calculation, and since the last call of OnCalculate()
|
||||
//--- for calculation not more than one bar is added
|
||||
values_to_copy=(rates_total-prev_calculated)+1;
|
||||
}
|
||||
//--- fill the arrays with values of the Ichimoku Kinko Hyo indicator
|
||||
//--- if FillArraysFromBuffer returns false, it means the information is nor ready yet, quit operation
|
||||
if(!FillArraysFromBuffers(Tenkan_sen_Buffer,Kijun_sen_Buffer,Senkou_Span_A_Buffer,Senkou_Span_B_Buffer,Chinkou_Span_Buffer,
|
||||
kijun_sen,handle,values_to_copy)) return(0);
|
||||
//--- form the message
|
||||
string comm=StringFormat("%s ==> Updated value in the indicator %s: %d",
|
||||
TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS),
|
||||
short_name,
|
||||
values_to_copy);
|
||||
//--- display the service message on the chart
|
||||
Comment(comm);
|
||||
//--- memorize the number of values in the Ichimoku Kinko Hyo indicator
|
||||
bars_calculated=calculated;
|
||||
//--- return the prev_calculated value for the next call
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Filling indicator buffers from the iIchimoku indicator |
|
||||
//+------------------------------------------------------------------+
|
||||
bool FillArraysFromBuffers(double &tenkan_sen_buffer[], // indicator buffer of the Tenkan-sen line
|
||||
double &kijun_sen_buffer[], // indicator buffer of the Kijun_sen line
|
||||
double &senkou_span_A_buffer[], // indicator buffer of the Senkou Span A line
|
||||
double &senkou_span_B_buffer[], // indicator buffer of the Senkou Span B line
|
||||
double &chinkou_span_buffer[], // indicator buffer of the Chinkou Span line
|
||||
int senkou_span_shift, // shift of the Senkou Span lines in the future direction
|
||||
int ind_handle, // handle of the iIchimoku indicator
|
||||
int amount // number of copied values
|
||||
)
|
||||
{
|
||||
//--- reset error code
|
||||
ResetLastError();
|
||||
//--- fill a part of the Tenkan_sen_Buffer array with values from the indicator buffer that has 0 index
|
||||
if(CopyBuffer(ind_handle,0,0,amount,tenkan_sen_buffer)<0)
|
||||
{
|
||||
//--- if the copying fails, tell the error code
|
||||
PrintFormat("1.Failed to copy data from the iIchimoku indicator, error code %d",GetLastError());
|
||||
//--- quit with zero result - it means that the indicator is considered as not calculated
|
||||
return(false);
|
||||
}
|
||||
|
||||
//--- fill a part of the Kijun_sen_Buffer array with values from the indicator buffer that has index 1
|
||||
if(CopyBuffer(ind_handle,1,0,amount,kijun_sen_buffer)<0)
|
||||
{
|
||||
//--- if the copying fails, tell the error code
|
||||
PrintFormat("2.Failed to copy data from the iIchimoku indicator, error code %d",GetLastError());
|
||||
//--- quit with zero result - it means that the indicator is considered as not calculated
|
||||
return(false);
|
||||
}
|
||||
|
||||
//--- fill a part of the Chinkou_Span_Buffer array with values from the indicator buffer that has index 2
|
||||
//--- if senkou_span_shift>0, the line is shifted in the future direction by senkou_span_shift bars
|
||||
if(CopyBuffer(ind_handle,2,-senkou_span_shift,amount,senkou_span_A_buffer)<0)
|
||||
{
|
||||
//--- if the copying fails, tell the error code
|
||||
PrintFormat("3.Failed to copy data from the iIchimoku indicator, error code %d",GetLastError());
|
||||
//--- quit with zero result - it means that the indicator is considered as not calculated
|
||||
return(false);
|
||||
}
|
||||
|
||||
//--- fill a part of the Senkou_Span_A_Buffer array with values from the indicator buffer that has index 3
|
||||
//--- if senkou_span_shift>0, the line is shifted in the future direction by senkou_span_shift bars
|
||||
if(CopyBuffer(ind_handle,3,-senkou_span_shift,amount,senkou_span_B_buffer)<0)
|
||||
{
|
||||
//--- if the copying fails, tell the error code
|
||||
PrintFormat("4.Failed to copy data from the iIchimoku indicator, error code %d",GetLastError());
|
||||
//--- quit with zero result - it means that the indicator is considered as not calculated
|
||||
return(false);
|
||||
}
|
||||
|
||||
//--- fill a part of the Senkou_Span_B_Buffer array with values from the indicator buffer that has 0 index
|
||||
//--- when copying Chinkou Span, we don't need to consider the shift, since the Chinkou Span data
|
||||
//--- is already stored with a shift in iIchimoku
|
||||
if(CopyBuffer(ind_handle,4,0,amount,chinkou_span_buffer)<0)
|
||||
{
|
||||
//--- if the copying fails, tell the error code
|
||||
PrintFormat("5.Failed to copy data from the iIchimoku indicator, error code %d",GetLastError());
|
||||
//--- quit with zero result - it means that the indicator is considered as not calculated
|
||||
return(false);
|
||||
}
|
||||
//--- everything is fine
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Indicator deinitialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
if(handle!=INVALID_HANDLE)
|
||||
IndicatorRelease(handle);
|
||||
//--- clear the chart after deleting the indicator
|
||||
Comment("");
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,675 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| ATRStopLoss_Ind.mq5 |
|
||||
//| Rosh Jardine |
|
||||
//| https://roshjardine.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Rosh Jardine (MQL5/MQL4)"
|
||||
#property link "https://roshjardine.com"
|
||||
#property version "1.00"
|
||||
#property description "Based on https://www.mql5.com/en/forum/349885 , this indicator will draw ATR based stop loss calculation with adjustable multiplier and ATR period."
|
||||
#property description "This indicator includes helper functions and example to run calculation via function call so the calculation logic can be placed in external include file"
|
||||
#property indicator_chart_window
|
||||
|
||||
#property indicator_buffers 5
|
||||
#property indicator_plots 2
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 Orchid
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 2
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_style2 STYLE_SOLID
|
||||
#property indicator_width2 2
|
||||
#property indicator_color2 Blue
|
||||
#property indicator_label1 "Up"
|
||||
#property indicator_label2 "Dn"
|
||||
|
||||
|
||||
//---- input parameters
|
||||
input int Length=10; //how many look back periods to check the price
|
||||
input int ATRperiod=10;
|
||||
input double Kv=2.5;
|
||||
//---- indicator buffers
|
||||
double UpBuffer1[];
|
||||
double DnBuffer1[];
|
||||
double smin[];
|
||||
double smax[];
|
||||
double trend[];
|
||||
|
||||
int AtrHandle;
|
||||
double AtrBfr[1];
|
||||
int bars_calculated;
|
||||
string short_name;
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
bars_calculated = 0;
|
||||
|
||||
short_name="ATRStopLoss_Ind";
|
||||
AtrHandle = iATR(_Symbol,_Period,ATRperiod);
|
||||
if(AtrHandle==INVALID_HANDLE)
|
||||
{
|
||||
return(INIT_FAILED);
|
||||
}
|
||||
ArrayInitialize(AtrBfr,EMPTY_VALUE);
|
||||
SetIndexBuffer(0,UpBuffer1);
|
||||
SetIndexBuffer(1,DnBuffer1);
|
||||
SetIndexBuffer(2,smin);
|
||||
SetIndexBuffer(3,smax);
|
||||
SetIndexBuffer(4,trend);
|
||||
IndicatorSetInteger(INDICATOR_DIGITS,Digits());
|
||||
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
|
||||
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,Length);
|
||||
PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,Length);
|
||||
PlotIndexSetInteger(0,PLOT_SHIFT,0);
|
||||
PlotIndexSetInteger(1,PLOT_SHIFT,0);
|
||||
return(INIT_SUCCEEDED);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnCalculate(const int rates_total,
|
||||
const int prev_calculated,
|
||||
const datetime &time[],
|
||||
const double &open[],
|
||||
const double &high[],
|
||||
const double &low[],
|
||||
const double &close[],
|
||||
const long &tick_volume[],
|
||||
const long &volume[],
|
||||
const int &spread[])
|
||||
{
|
||||
int limit;
|
||||
if(rates_total<=Length)
|
||||
return(0);
|
||||
if(prev_calculated<1)
|
||||
{
|
||||
/*
|
||||
int shift;
|
||||
ArrayInitialize(UpBuffer1,EMPTY_VALUE);
|
||||
ArrayInitialize(DnBuffer1,EMPTY_VALUE);
|
||||
ArrayInitialize(smin,EMPTY_VALUE);
|
||||
ArrayInitialize(smax,EMPTY_VALUE);
|
||||
ArrayInitialize(trend,EMPTY_VALUE);
|
||||
ArraySetAsSeries(UpBuffer1,true);
|
||||
ArraySetAsSeries(DnBuffer1,true);
|
||||
ArraySetAsSeries(smin,true);
|
||||
ArraySetAsSeries(smax,true);
|
||||
ArraySetAsSeries(trend,true);
|
||||
|
||||
limit = rates_total-Length-1;
|
||||
|
||||
for (shift=limit;shift>=0;shift--)
|
||||
{
|
||||
smin[shift] = -100000; smax[shift] = 100000;
|
||||
for(int i=Length-1;i>=0;i--)
|
||||
{
|
||||
int copybuffer = CopyBuffer(AtrHandle,0,shift+i,1,AtrBfr);
|
||||
if (copybuffer<1)
|
||||
{
|
||||
StopIndicator();
|
||||
}
|
||||
smin[shift] = MathMax( smin[shift], iHigh(_Symbol,_Period,shift+i) - Kv*AtrBfr[0]);
|
||||
smax[shift] = MathMin( smax[shift], iLow(_Symbol,_Period,shift+i) + Kv*AtrBfr[0]);
|
||||
}
|
||||
trend[shift]= trend[shift+1];
|
||||
if ( iClose(_Symbol,_Period,shift) > smax[shift+1] )
|
||||
{
|
||||
trend[shift] = 1;
|
||||
}
|
||||
if ( iClose(_Symbol,_Period,shift) < smin[shift+1] )
|
||||
{
|
||||
trend[shift] = -1;
|
||||
}
|
||||
if ( trend[shift] >0 )
|
||||
{
|
||||
if( smin[shift]<smin[shift+1] ) smin[shift]=smin[shift+1];
|
||||
UpBuffer1[shift] = smin[shift];
|
||||
DnBuffer1[shift] = EMPTY_VALUE;
|
||||
}
|
||||
if ( trend[shift] <0 )
|
||||
{
|
||||
if( smax[shift]>smax[shift+1] ) smax[shift]=smax[shift+1];
|
||||
UpBuffer1[shift] = EMPTY_VALUE;
|
||||
DnBuffer1[shift] = smax[shift];
|
||||
}
|
||||
}
|
||||
*/
|
||||
limit = rates_total-Length-1;
|
||||
if(!AtrStopFirstRun(limit,UpBuffer1,DnBuffer1,smin,smax,trend,AtrHandle,AtrBfr,Length,_Symbol,_Period,Kv))
|
||||
{
|
||||
StopIndicator();
|
||||
}
|
||||
bars_calculated = limit;
|
||||
return(rates_total);
|
||||
}
|
||||
|
||||
|
||||
else
|
||||
{
|
||||
limit=prev_calculated-Length-1;
|
||||
|
||||
if(limit>bars_calculated)
|
||||
{
|
||||
if(!AtrStopNextRun(bars_calculated+1,UpBuffer1,DnBuffer1,smin,smax,trend,AtrHandle,AtrBfr,Length,_Symbol,_Period,Kv,false))
|
||||
{
|
||||
StopIndicator();
|
||||
}
|
||||
bars_calculated +=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!AtrStopNextRun(bars_calculated+1,UpBuffer1,DnBuffer1,smin,smax,trend,AtrHandle,AtrBfr,Length,_Symbol,_Period,Kv,true))
|
||||
{
|
||||
StopIndicator();
|
||||
}
|
||||
}
|
||||
/*
|
||||
if (limit>bars_calculated)
|
||||
{
|
||||
ArrayResize(UpBuffer1,bars_calculated+1);
|
||||
ArrayResize(DnBuffer1,bars_calculated+1);
|
||||
ArrayResize(smin,bars_calculated+1);
|
||||
ArrayResize(smax,bars_calculated+1);
|
||||
ArrayResize(trend,bars_calculated+1);
|
||||
UpBuffer1[0] = DnBuffer1[0]= smin[0] = smax[0] = trend[0] = EMPTY_VALUE;
|
||||
bars_calculated +=1;
|
||||
}
|
||||
for(int j=0;j<=1;j++)
|
||||
{
|
||||
smin[j] = -100000; smax[j] = 100000;
|
||||
for(int k=0;k<=Length-1;k++)
|
||||
{
|
||||
int copybuffer = CopyBuffer(AtrHandle,0,j+k,1,AtrBfr);
|
||||
if (copybuffer<1)
|
||||
{
|
||||
StopIndicator();
|
||||
|
||||
}
|
||||
smin[j] = MathMax( smin[j], iHigh(_Symbol,_Period,j+k) - Kv*AtrBfr[0]);
|
||||
smax[j] = MathMin( smax[j], iLow(_Symbol,_Period,j+k) + Kv*AtrBfr[0]);
|
||||
}
|
||||
trend[j]= trend[j+1];
|
||||
if ( iClose(_Symbol,_Period,j) > smax[j+1] ) trend[j] = 1;
|
||||
if ( iClose(_Symbol,_Period,j) < smin[j+1] ) trend[j] = -1;
|
||||
|
||||
if ( trend[j] >0 )
|
||||
{
|
||||
if( smin[j]<smin[j+1] ) smin[j]=smin[j+1];
|
||||
UpBuffer1[j] = smin[j];
|
||||
DnBuffer1[j] = EMPTY_VALUE;
|
||||
}
|
||||
if ( trend[j] <0 )
|
||||
{
|
||||
if( smax[j]>smax[j+1] ) smax[j]=smax[j+1];
|
||||
UpBuffer1[j] = EMPTY_VALUE;
|
||||
DnBuffer1[j] = smax[j];
|
||||
}
|
||||
}*/
|
||||
return(rates_total);
|
||||
}
|
||||
}
|
||||
|
||||
/************************************ AS HELPERS ************************************/
|
||||
bool AtrStopNextRun(int newlimit,double &upbfr[],
|
||||
double &dnbfr[],double &min[],
|
||||
double &max[],double &trd[],int &atrhandler,
|
||||
double &atrbuffer[],int atrlength,
|
||||
const string symbol,ENUM_TIMEFRAMES tframe,
|
||||
double multiplier,bool samebar)
|
||||
{
|
||||
if(!samebar)
|
||||
{
|
||||
ArrayResize(upbfr,newlimit);
|
||||
ArrayResize(dnbfr,newlimit);
|
||||
ArrayResize(min,newlimit);
|
||||
ArrayResize(max,newlimit);
|
||||
ArrayResize(trd,newlimit);
|
||||
upbfr[0] = dnbfr[0]= min[0] = max[0] = trd[0] = EMPTY_VALUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
upbfr[0] = dnbfr[0]= min[0] = max[0] = trd[0] = EMPTY_VALUE;
|
||||
}
|
||||
for(int j=0; j<=1; j++)
|
||||
{
|
||||
min[j] = -100000;
|
||||
max[j] = 100000;
|
||||
for(int k=0; k<=atrlength-1; k++)
|
||||
{
|
||||
int copybuffer = CopyBuffer(atrhandler,0,j+k,1,atrbuffer);
|
||||
if(copybuffer<1)
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
min[j] = MathMax(smin[j], iHigh(symbol,tframe,j+k) - multiplier*AtrBfr[0]);
|
||||
max[j] = MathMin(smax[j], iLow(symbol,tframe,j+k) + multiplier*AtrBfr[0]);
|
||||
}
|
||||
trd[j]= trd[j+1];
|
||||
if(iClose(symbol,tframe,j) > max[j+1])
|
||||
{
|
||||
trd[j] = 1;
|
||||
}
|
||||
if(iClose(symbol,tframe,j) < min[j+1])
|
||||
{
|
||||
trd[j] = -1;
|
||||
}
|
||||
if(trd[j] >0)
|
||||
{
|
||||
if(min[j]<min[j+1])
|
||||
{
|
||||
min[j] = min[j+1];
|
||||
}
|
||||
upbfr[j] = min[j];
|
||||
dnbfr[j] = EMPTY_VALUE;
|
||||
}
|
||||
if(trend[j] <0)
|
||||
{
|
||||
if(max[j]>max[j+1])
|
||||
{
|
||||
max[j]=max[j+1];
|
||||
}
|
||||
upbfr[j] = EMPTY_VALUE;
|
||||
dnbfr[j] = max[j];
|
||||
}
|
||||
}
|
||||
return(true);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
bool AtrStopFirstRun(int limit,double &upbfr[],
|
||||
double &dnbfr[],double &min[],
|
||||
double &max[],double &trd[],int &atrhandler,
|
||||
double &atrbuffer[],int atrlength,
|
||||
const string symbol,ENUM_TIMEFRAMES tframe,
|
||||
double multiplier
|
||||
)
|
||||
{
|
||||
ArrayInitialize(upbfr,EMPTY_VALUE);
|
||||
ArrayInitialize(dnbfr,EMPTY_VALUE);
|
||||
ArrayInitialize(min,EMPTY_VALUE);
|
||||
ArrayInitialize(max,EMPTY_VALUE);
|
||||
ArrayInitialize(trd,EMPTY_VALUE);
|
||||
ArraySetAsSeries(upbfr,true);
|
||||
ArraySetAsSeries(dnbfr,true);
|
||||
ArraySetAsSeries(min,true);
|
||||
ArraySetAsSeries(max,true);
|
||||
ArraySetAsSeries(trd,true);
|
||||
int shift = 0;
|
||||
for(shift=limit; shift>=0; shift--)
|
||||
{
|
||||
min[shift] = -100000;
|
||||
max[shift] = 100000;
|
||||
for(int i=atrlength-1; i>=0; i--)
|
||||
{
|
||||
int copybuffer = CopyBuffer(atrhandler,0,shift+i,1,atrbuffer);
|
||||
if(copybuffer<1)
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
min[shift] = MathMax(min[shift], iHigh(symbol,tframe,shift+i) - multiplier*atrbuffer[0]);
|
||||
max[shift] = MathMin(max[shift], iLow(symbol,tframe,shift+i) + multiplier*atrbuffer[0]);
|
||||
}
|
||||
trd[shift] = trd[shift+1];
|
||||
if(iClose(symbol,tframe,shift) > max[shift+1])
|
||||
{
|
||||
trd[shift] = 1;
|
||||
}
|
||||
if(iClose(symbol,tframe,shift) < min[shift+1])
|
||||
{
|
||||
trd[shift] = -1;
|
||||
}
|
||||
if(trd[shift] >0)
|
||||
{
|
||||
if(min[shift]<min[shift+1])
|
||||
{
|
||||
min[shift] = min[shift+1];
|
||||
}
|
||||
upbfr[shift] = min[shift];
|
||||
dnbfr[shift] = EMPTY_VALUE;
|
||||
}
|
||||
if(trd[shift] <0)
|
||||
{
|
||||
if(max[shift]>max[shift+1])
|
||||
{
|
||||
max[shift] = max[shift+1];
|
||||
}
|
||||
upbfr[shift] = EMPTY_VALUE;
|
||||
dnbfr[shift] = max[shift];
|
||||
}
|
||||
}
|
||||
return(true);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
void StopIndicator()
|
||||
{
|
||||
IndicatorRelease(AtrHandle);
|
||||
ChartIndicatorDelete(ChartID(),0,short_name);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
if(AtrHandle!=INVALID_HANDLE)
|
||||
IndicatorRelease(AtrHandle);
|
||||
}
|
||||
|
||||
|
||||
//---
|
||||
//--- MQL4
|
||||
//---
|
||||
|
||||
#ifdef __MQL4__
|
||||
#property indicator_buffers 2
|
||||
#property indicator_color1 Blue
|
||||
#property indicator_color2 Red
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 2
|
||||
#property indicator_style2 STYLE_SOLID
|
||||
#property indicator_width2 2
|
||||
//---- input parameters
|
||||
extern int Length=10;
|
||||
extern int ATRperiod=10;
|
||||
extern double Kv=2.5;
|
||||
double UpBuffer1[];
|
||||
double DnBuffer1[];
|
||||
double smin[];
|
||||
double smax[];
|
||||
double trend[];
|
||||
|
||||
double AtrBfr[1];
|
||||
int bars_calculated;
|
||||
string short_name;
|
||||
int OnInit()
|
||||
{
|
||||
bars_calculated = 0;
|
||||
|
||||
short_name="ATRStopLoss_Ind";
|
||||
SetIndexStyle(0,DRAW_LINE);
|
||||
SetIndexStyle(1,DRAW_LINE);
|
||||
IndicatorBuffers(5);
|
||||
SetIndexBuffer(0,UpBuffer1);
|
||||
SetIndexBuffer(1,DnBuffer1);
|
||||
SetIndexBuffer(2,smin);
|
||||
SetIndexBuffer(3,smax);
|
||||
SetIndexBuffer(4,trend);
|
||||
IndicatorShortName(short_name);
|
||||
SetIndexLabel(0,"Up");
|
||||
SetIndexLabel(1,"Dn");
|
||||
SetIndexDrawBegin(0,Length);
|
||||
SetIndexDrawBegin(1,Length);
|
||||
return(INIT_SUCCEEDED);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnCalculate(const int rates_total,
|
||||
const int prev_calculated,
|
||||
const datetime &time[],
|
||||
const double &open[],
|
||||
const double &high[],
|
||||
const double &low[],
|
||||
const double &close[],
|
||||
const long &tick_volume[],
|
||||
const long &volume[],
|
||||
const int &spread[])
|
||||
{
|
||||
int limit;
|
||||
if(rates_total<=Length)
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
if(prev_calculated<1)
|
||||
{
|
||||
/*
|
||||
int shift;
|
||||
ArrayInitialize(UpBuffer1,EMPTY_VALUE);
|
||||
ArrayInitialize(DnBuffer1,EMPTY_VALUE);
|
||||
ArrayInitialize(smin,EMPTY_VALUE);
|
||||
ArrayInitialize(smax,EMPTY_VALUE);
|
||||
ArrayInitialize(trend,EMPTY_VALUE);
|
||||
ArraySetAsSeries(UpBuffer1,true);
|
||||
ArraySetAsSeries(DnBuffer1,true);
|
||||
ArraySetAsSeries(smin,true);
|
||||
ArraySetAsSeries(smax,true);
|
||||
ArraySetAsSeries(trend,true);
|
||||
limit = rates_total-Length-1;
|
||||
for (shift=limit;shift>=0;shift--)
|
||||
{
|
||||
smin[shift] = -100000;
|
||||
smax[shift] = 100000;
|
||||
for(int i=Length-1;i>=0;i--)
|
||||
{
|
||||
smin[shift] = MathMax( smin[shift], iHigh(_Symbol,_Period,shift+i) - Kv*iATR(Symbol(),Period(),ATRperiod,shift+i));
|
||||
smax[shift] = MathMin( smax[shift], iLow(_Symbol,_Period,shift+i) + Kv*iATR(Symbol(),Period(),ATRperiod,shift+i));
|
||||
}
|
||||
trend[shift]= trend[shift+1];
|
||||
if ( iClose(_Symbol,_Period,shift) > smax[shift+1] )
|
||||
{
|
||||
trend[shift] = 1;
|
||||
}
|
||||
if ( iClose(_Symbol,_Period,shift) < smin[shift+1] )
|
||||
{
|
||||
trend[shift] = -1;
|
||||
}
|
||||
if ( trend[shift] >0 )
|
||||
{
|
||||
if( smin[shift]<smin[shift+1] ) smin[shift]=smin[shift+1];
|
||||
UpBuffer1[shift] = smin[shift];
|
||||
DnBuffer1[shift] = EMPTY_VALUE;
|
||||
}
|
||||
if ( trend[shift] <0 )
|
||||
{
|
||||
if( smax[shift]>smax[shift+1] ) smax[shift]=smax[shift+1];
|
||||
UpBuffer1[shift] = EMPTY_VALUE;
|
||||
DnBuffer1[shift] = smax[shift];
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*** AS FUNCTION CALL EXAMPLE ***/
|
||||
|
||||
limit = rates_total-Length-1;
|
||||
if(!AtrStopFirstRun(limit,UpBuffer1,DnBuffer1,smin,smax,trend,Length,Symbol(),Period(),Kv))
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
bars_calculated = limit;
|
||||
return(rates_total);
|
||||
}
|
||||
else
|
||||
{
|
||||
limit = prev_calculated-Length-1;
|
||||
/*** AS FUNCTION CALL EXAMPLE ***/
|
||||
if(limit>bars_calculated)
|
||||
{
|
||||
if(!AtrStopNextRun(bars_calculated+1,UpBuffer1,DnBuffer1,smin,smax,trend,Length,Symbol(),Period(),Kv,false))
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
if(!AtrStopNextRun(bars_calculated+1,UpBuffer1,DnBuffer1,smin,smax,trend,Length,Symbol(),Period(),Kv,true))
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
/*
|
||||
if (limit>bars_calculated)
|
||||
{
|
||||
ArrayResize(UpBuffer1,bars_calculated+1);
|
||||
ArrayResize(DnBuffer1,bars_calculated+1);
|
||||
ArrayResize(smin,bars_calculated+1);
|
||||
ArrayResize(smax,bars_calculated+1);
|
||||
ArrayResize(trend,bars_calculated+1);
|
||||
UpBuffer1[0] = DnBuffer1[0]= smin[0] = smax[0] = trend[0] = EMPTY_VALUE;
|
||||
bars_calculated +=1;
|
||||
}
|
||||
for(int j=0;j<=1;j++)
|
||||
{
|
||||
smin[j] = -100000;
|
||||
smax[j] = 100000;
|
||||
for(int k=0;k<=Length-1;k++)
|
||||
{
|
||||
smin[j] = MathMax( smin[j], iHigh(Symbol(),Period(),j+k) - Kv*iATR(Symbol(),Period(),ATRperiod,j+k));
|
||||
smax[j] = MathMin( smax[j], iLow(Symbol(),Period(),j+k) + Kv*AtrBfr[0]);
|
||||
}
|
||||
trend[j]= trend[j+1];
|
||||
if ( iClose(Symbol(),Period(),j) > smax[j+1] ) trend[j] = 1;
|
||||
if ( iClose(Symbol(),Period(),j) < smin[j+1] ) trend[j] = -1;
|
||||
|
||||
if ( trend[j] >0 )
|
||||
{
|
||||
if( smin[j]<smin[j+1] ) smin[j]=smin[j+1];
|
||||
UpBuffer1[j] = smin[j];
|
||||
DnBuffer1[j] = EMPTY_VALUE;
|
||||
}
|
||||
if ( trend[j] <0 )
|
||||
{
|
||||
if( smax[j]>smax[j+1] ) smax[j]=smax[j+1];
|
||||
UpBuffer1[j] = EMPTY_VALUE;
|
||||
DnBuffer1[j] = smax[j];
|
||||
}
|
||||
}
|
||||
*/
|
||||
return(rates_total);
|
||||
}
|
||||
}
|
||||
|
||||
/************************************ AS HELPERS ************************************/
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
bool AtrStopFirstRun(int limit,double &upbfr[],
|
||||
double &dnbfr[],double &min[],
|
||||
double &max[],double &trd[],int atrlength,
|
||||
const string symbol,const int tframe,
|
||||
double multiplier
|
||||
)
|
||||
{
|
||||
ArrayInitialize(upbfr,EMPTY_VALUE);
|
||||
ArrayInitialize(dnbfr,EMPTY_VALUE);
|
||||
ArrayInitialize(min,EMPTY_VALUE);
|
||||
ArrayInitialize(max,EMPTY_VALUE);
|
||||
ArrayInitialize(trd,EMPTY_VALUE);
|
||||
ArraySetAsSeries(upbfr,true);
|
||||
ArraySetAsSeries(dnbfr,true);
|
||||
ArraySetAsSeries(min,true);
|
||||
ArraySetAsSeries(max,true);
|
||||
ArraySetAsSeries(trd,true);
|
||||
int shift = 0;
|
||||
for(shift=limit; shift>=0; shift--)
|
||||
{
|
||||
min[shift] = -100000;
|
||||
max[shift] = 100000;
|
||||
for(int i=atrlength-1; i>=0; i--)
|
||||
{
|
||||
min[shift] = MathMax(min[shift], iHigh(symbol,tframe,shift+i) - multiplier*iATR(symbol,tframe,ATRperiod,shift+1));
|
||||
max[shift] = MathMin(max[shift], iLow(symbol,tframe,shift+i) + multiplier*iATR(symbol,tframe,ATRperiod,shift+1));
|
||||
}
|
||||
trd[shift] = trd[shift+1];
|
||||
if(iClose(symbol,tframe,shift) > max[shift+1])
|
||||
{
|
||||
trd[shift] = 1;
|
||||
}
|
||||
if(iClose(symbol,tframe,shift) < min[shift+1])
|
||||
{
|
||||
trd[shift] = -1;
|
||||
}
|
||||
if(trd[shift] >0)
|
||||
{
|
||||
if(min[shift]<min[shift+1])
|
||||
{
|
||||
min[shift] = min[shift+1];
|
||||
}
|
||||
upbfr[shift] = min[shift];
|
||||
dnbfr[shift] = EMPTY_VALUE;
|
||||
}
|
||||
if(trd[shift] <0)
|
||||
{
|
||||
if(max[shift]>max[shift+1])
|
||||
{
|
||||
max[shift]= max[shift+1];
|
||||
}
|
||||
upbfr[shift] = EMPTY_VALUE;
|
||||
dnbfr[shift] = max[shift];
|
||||
}
|
||||
}
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
bool AtrStopNextRun(int newlimit,double &upbfr[],
|
||||
double &dnbfr[],double &min[],
|
||||
double &max[],double &trd[],int atrlength,
|
||||
const string symbol,const int tframe,
|
||||
double multiplier,bool samebar)
|
||||
{
|
||||
if(!samebar)
|
||||
{
|
||||
ArrayResize(upbfr,newlimit);
|
||||
ArrayResize(dnbfr,newlimit);
|
||||
ArrayResize(min,newlimit);
|
||||
ArrayResize(max,newlimit);
|
||||
ArrayResize(trd,newlimit);
|
||||
upbfr[0] = dnbfr[0]= min[0] = max[0] = trd[0] = EMPTY_VALUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
upbfr[0] = dnbfr[0]= min[0] = max[0] = trd[0] = EMPTY_VALUE;
|
||||
}
|
||||
for(int j=0; j<=1; j++)
|
||||
{
|
||||
min[j] = -100000;
|
||||
max[j] = 100000;
|
||||
for(int k=0; k<=atrlength-1; k++)
|
||||
{
|
||||
min[j] = MathMax(smin[j], iHigh(symbol,tframe,j+k) - multiplier*iATR(symbol,tframe,ATRperiod,j+k));
|
||||
max[j] = MathMin(smax[j], iLow(symbol,tframe,j+k) + multiplier*iATR(symbol,tframe,ATRperiod,j+k));
|
||||
}
|
||||
trd[j] = trd[j+1];
|
||||
if(iClose(symbol,tframe,j) > max[j+1])
|
||||
{
|
||||
trd[j] = 1;
|
||||
}
|
||||
if(iClose(symbol,tframe,j) < min[j+1])
|
||||
{
|
||||
trd[j] = -1;
|
||||
}
|
||||
if(trd[j] >0)
|
||||
{
|
||||
if(min[j]<min[j+1])
|
||||
{
|
||||
min[j] = min[j+1];
|
||||
}
|
||||
upbfr[j] = min[j];
|
||||
dnbfr[j] = EMPTY_VALUE;
|
||||
}
|
||||
if(trend[j] <0)
|
||||
{
|
||||
if(max[j]>max[j+1])
|
||||
{
|
||||
max[j] = max[j+1];
|
||||
}
|
||||
upbfr[j] = EMPTY_VALUE;
|
||||
dnbfr[j] = max[j];
|
||||
}
|
||||
}
|
||||
return(true);
|
||||
}
|
||||
#endif
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
Binary file not shown.
@@ -0,0 +1,62 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| CandleTimeStationary|
|
||||
//| |
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
#property indicator_chart_window
|
||||
#property strict
|
||||
|
||||
//---- input parameters
|
||||
input color Clock_Color = clrDimGray;
|
||||
input ENUM_BASE_CORNER Corner = CORNER_RIGHT_UPPER;
|
||||
|
||||
string objname="Spread&Bar";
|
||||
double s1[];
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| expert initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
ObjectCreate(0, objname, OBJ_LABEL,0, 0, 0);
|
||||
ObjectSetInteger(0, objname, OBJPROP_CORNER, Corner);
|
||||
ObjectSetInteger(0, objname, OBJPROP_XDISTANCE, 10);
|
||||
ObjectSetInteger(0, objname, OBJPROP_YDISTANCE, 2);
|
||||
ENUM_ANCHOR_POINT Anchor = ANCHOR_LEFT_UPPER;
|
||||
switch (Corner)
|
||||
{
|
||||
case CORNER_LEFT_UPPER: Anchor=ANCHOR_LEFT_UPPER; break;
|
||||
case CORNER_RIGHT_UPPER: Anchor=ANCHOR_RIGHT_UPPER; break;
|
||||
case CORNER_LEFT_LOWER: Anchor=ANCHOR_LEFT_LOWER; break;
|
||||
case CORNER_RIGHT_LOWER: Anchor=ANCHOR_RIGHT_LOWER; break;
|
||||
}
|
||||
ObjectSetInteger(0, objname, OBJPROP_ANCHOR, Anchor);
|
||||
|
||||
return(INIT_SUCCEEDED);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
void OnDeinit(const int reason) { ObjectDelete(0, objname); }
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
int OnCalculate(const int rates_total, const int prev_calculated, const datetime& time[], const double& open[], const double& high[], const double& low[], const double& close[], const long& tick_volume[], const long& volume[], const int& spreads[])
|
||||
{
|
||||
ArraySetAsSeries(time, true);
|
||||
int m=int(time[0]+PeriodSeconds()-TimeCurrent());
|
||||
int s=m%60;
|
||||
m=(m-s)/60;
|
||||
long spread=SymbolInfoInteger(Symbol(), SYMBOL_SPREAD);
|
||||
|
||||
string _sp="",_m="",_s="";
|
||||
if (spread<10) _sp="..";
|
||||
else if (spread<100) _sp=".";
|
||||
if (m<10) _m="0";
|
||||
if (s<10) _s="0";
|
||||
|
||||
ObjectSetString(0, objname, OBJPROP_TEXT, "Spread: " +IntegerToString(spread)+_sp+" Next Bar in "+_m+IntegerToString(m)+":"+_s+IntegerToString(s));
|
||||
ObjectSetInteger(0, objname, OBJPROP_FONTSIZE, 10);
|
||||
ObjectSetInteger(0, objname, OBJPROP_COLOR, Clock_Color);
|
||||
ObjectSetString(0, objname, OBJPROP_FONT, "Courier");
|
||||
|
||||
return(rates_total);
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,172 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| DemoTradeEventProcessing.mq5 |
|
||||
//| Copyright 2011, MetaQuotes Software Corp. |
|
||||
//| http://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2011, MetaQuotes Software Corp."
|
||||
#property link "http://www.mql5.com"
|
||||
#property version "1.00"
|
||||
|
||||
input int days=7; // depth of trade history in days
|
||||
int orders; // number of active orders
|
||||
int positions; // number of open positions
|
||||
int deals; // number of deals in the trade history cache
|
||||
int history_orders; // number of orders in the trade history cache
|
||||
bool started=false; // flag of initialization of the counters
|
||||
//--- let's set the limits of the trade history on the global scope
|
||||
datetime start; // start date for trade history in cache
|
||||
datetime end; // end date for trade history in cache
|
||||
//+------------------------------------------------------------------+
|
||||
//| Expert initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
//---
|
||||
end=TimeCurrent();
|
||||
start=end-days*PeriodSeconds(PERIOD_D1);
|
||||
PrintFormat("Limits of the history to be loaded: start - %s, end - %s",
|
||||
TimeToString(start),TimeToString(end));
|
||||
InitCounters();
|
||||
//---
|
||||
return(0);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Expert tick function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnTick()
|
||||
{
|
||||
//---
|
||||
if(started) SimpleTradeProcessor();
|
||||
else InitCounters();
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Called when a Trade event comes |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnTrade()
|
||||
{
|
||||
if(started) SimpleTradeProcessor();
|
||||
else InitCounters();
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| initialization of the counters of positions, orders and deals |
|
||||
//+------------------------------------------------------------------+
|
||||
void InitCounters()
|
||||
{
|
||||
ResetLastError();
|
||||
//--- load history
|
||||
bool selected=HistorySelect(start,end);
|
||||
if(!selected)
|
||||
{
|
||||
PrintFormat("%s. Failed to load the history from %s to %s to the cache. Error code: %d",
|
||||
__FUNCTION__,TimeToString(start),TimeToString(end),GetLastError());
|
||||
return;
|
||||
}
|
||||
//--- get current value
|
||||
orders=OrdersTotal();
|
||||
positions=PositionsTotal();
|
||||
deals=HistoryDealsTotal();
|
||||
history_orders=HistoryOrdersTotal();
|
||||
started=true;
|
||||
Print("The counters of orders, positions and deals are successfully initialized");
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| a simple example of processing changes in trade and history |
|
||||
//+------------------------------------------------------------------+
|
||||
void SimpleTradeProcessor()
|
||||
{
|
||||
end=TimeCurrent();
|
||||
ResetLastError();
|
||||
//--- load history
|
||||
bool selected=HistorySelect(start,end);
|
||||
if(!selected)
|
||||
{
|
||||
PrintFormat("%s. Failed to load the history from %s to %s to the cache. Error code: %d",
|
||||
__FUNCTION__,TimeToString(start),TimeToString(end),GetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
//--- get current value
|
||||
int curr_orders=OrdersTotal();
|
||||
int curr_positions=PositionsTotal();
|
||||
int curr_deals=HistoryDealsTotal();
|
||||
int curr_history_orders=HistoryOrdersTotal();
|
||||
|
||||
//--- check if the number of active orders has been changed
|
||||
if(curr_orders!=orders)
|
||||
{
|
||||
//--- number of active orders has been changed
|
||||
PrintFormat("Number of orders has been changed. Previous value is %d, current value is %d",
|
||||
orders,curr_orders);
|
||||
/*
|
||||
other actions connected with change of orders
|
||||
*/
|
||||
//--- update value
|
||||
orders=curr_orders;
|
||||
}
|
||||
|
||||
//--- changes in the number of open positions
|
||||
if(curr_positions!=positions)
|
||||
{
|
||||
//--- number of open positions has been changed
|
||||
PrintFormat("Number of positions has been changed. Previous value is %d, current value is %d",
|
||||
positions,curr_positions);
|
||||
/*
|
||||
other actions connected with change of positions
|
||||
*/
|
||||
//--- update value
|
||||
positions=curr_positions;
|
||||
}
|
||||
|
||||
//--- changes in the number of deals in the trade history cache
|
||||
if(curr_deals!=deals)
|
||||
{
|
||||
//--- number of deals in the trade history cache has been changed
|
||||
PrintFormat("Number of deals has been changed. Previous value is %d, current value is %d",
|
||||
deals,curr_deals);
|
||||
/*
|
||||
other actions connected with change of deals
|
||||
*/
|
||||
//--- update value
|
||||
deals=curr_deals;
|
||||
}
|
||||
|
||||
//--- changes in the number of history orders in the trade history cache
|
||||
if(curr_history_orders!=history_orders)
|
||||
{
|
||||
//--- number of history orders in the trade history cache has been changed
|
||||
PrintFormat("Number of orders in the history has been changed. Previous value is %d, current value is %d",
|
||||
history_orders,curr_history_orders);
|
||||
/*
|
||||
other actions connected with change of the number of orders in the trade history cache
|
||||
*/
|
||||
//--- update value
|
||||
history_orders=curr_history_orders;
|
||||
}
|
||||
//--- checking if it is necessary to change the limits of th trade history to be requested in cache
|
||||
CheckStartDateInTradeHistory();
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| changing the start date for requesting of the trade history |
|
||||
//+------------------------------------------------------------------+
|
||||
void CheckStartDateInTradeHistory()
|
||||
{
|
||||
//--- initial interval, as if we started working right now
|
||||
datetime curr_start=TimeCurrent()-days*PeriodSeconds(PERIOD_D1);
|
||||
//--- make sure that the start limit of the trade history has not gone
|
||||
//--- more than 1 day over intended date
|
||||
if(curr_start-start>PeriodSeconds(PERIOD_D1))
|
||||
{
|
||||
//--- we should correct the start date of history to be loaded in the cache
|
||||
start=curr_start;
|
||||
PrintFormat("New start limit of the trade history to be loaded: start => %s",
|
||||
TimeToString(start));
|
||||
|
||||
//--- now load the trade history for the corrected period again
|
||||
HistorySelect(start,end);
|
||||
|
||||
//--- correct the number of deals and orders in the history for further comparison
|
||||
history_orders=HistoryOrdersTotal();
|
||||
deals=HistoryDealsTotal();
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,247 @@
|
||||
//------------------------------------------------------------------
|
||||
#property copyright "mladen"
|
||||
#property link "mladenfx@gmail.com"
|
||||
#property link "www.forex-station.com"
|
||||
//------------------------------------------------------------------
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 2
|
||||
#property indicator_color1 clrLimeGreen
|
||||
#property indicator_color2 clrOrangeRed
|
||||
#property indicator_width1 2
|
||||
#property indicator_width2 2
|
||||
#property strict
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
enum enPrices
|
||||
{
|
||||
pr_close, // Close
|
||||
pr_open, // Open
|
||||
pr_high, // High
|
||||
pr_low, // Low
|
||||
pr_median, // Median
|
||||
pr_typical, // Typical
|
||||
pr_weighted, // Weighted
|
||||
pr_average, // Average (high+low+open+close)/4
|
||||
pr_medianb, // Average median body (open+close)/2
|
||||
pr_tbiased, // Trend biased price
|
||||
pr_tbiased2, // Trend biased (extreme) price
|
||||
pr_haclose, // Heiken ashi close
|
||||
pr_haopen , // Heiken ashi open
|
||||
pr_hahigh, // Heiken ashi high
|
||||
pr_halow, // Heiken ashi low
|
||||
pr_hamedian, // Heiken ashi median
|
||||
pr_hatypical, // Heiken ashi typical
|
||||
pr_haweighted, // Heiken ashi weighted
|
||||
pr_haaverage, // Heiken ashi average
|
||||
pr_hamedianb, // Heiken ashi median body
|
||||
pr_hatbiased, // Heiken ashi trend biased price
|
||||
pr_hatbiased2 // Heiken ashi trend biased (extreme) price
|
||||
};
|
||||
enum enColorOn
|
||||
{
|
||||
chg_onZero, // Change color on zero cross
|
||||
chg_onOuter, // Change color on levels cross
|
||||
chg_onOuter2, // Change color on opposite levels cross
|
||||
chg_onSlope // Change color on slope change
|
||||
};
|
||||
input int DspPeriod = 14; // DSP period
|
||||
input enPrices Price = pr_median; // DSP price
|
||||
extern int SignalPeriod = 9; // Signal period
|
||||
input enColorOn ColorOn = chg_onOuter; // Change color on :
|
||||
|
||||
double val[],histu[],histd[],levelu[],leveld[],state[];
|
||||
|
||||
//------------------------------------------------------------------
|
||||
//
|
||||
//------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
int OnInit()
|
||||
{
|
||||
IndicatorBuffers(6);
|
||||
SetIndexBuffer( 0, histu); SetIndexStyle(0,DRAW_HISTOGRAM);
|
||||
SetIndexBuffer( 1, histd); SetIndexStyle(1,DRAW_HISTOGRAM);
|
||||
SetIndexBuffer( 2, val);
|
||||
SetIndexBuffer( 3, levelu);
|
||||
SetIndexBuffer( 4, leveld);
|
||||
SetIndexBuffer( 5, state);
|
||||
IndicatorShortName("DSP bars ("+(string)DspPeriod+")");
|
||||
return(0);
|
||||
}
|
||||
void OnDeinit(const int reason) { }
|
||||
//------------------------------------------------------------------
|
||||
//
|
||||
//------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
int OnCalculate(const int rates_total,
|
||||
const int prev_calculated,
|
||||
const datetime &time[],
|
||||
const double &open[],
|
||||
const double &high[],
|
||||
const double &low[],
|
||||
const double &close[],
|
||||
const long &tick_volume[],
|
||||
const long &volume[],
|
||||
const int &spread[])
|
||||
{
|
||||
int counted_bars = prev_calculated;
|
||||
if(counted_bars < 0) return(-1);
|
||||
if(counted_bars > 0) counted_bars--;
|
||||
int limit=MathMin(rates_total-counted_bars,rates_total-1);
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
double alphas = 2.0/(1.0+SignalPeriod);
|
||||
double alpham = 2.0/(1.0+DspPeriod);
|
||||
for(int i=limit; i>=0 && !_StopFlag; i--)
|
||||
{
|
||||
double price = getPrice(Price,open,close,high,low,i,rates_total);
|
||||
val[i] = iEma(price,alpham,i,rates_total,0)-iEma(price,alpham/2.0,i,rates_total,1);
|
||||
levelu[i] = (i<Bars-1) ? (val[i]>0) ? levelu[i+1]+alphas*(val[i]-levelu[i+1]) : levelu[i+1] : 0;
|
||||
leveld[i] = (i<Bars-1) ? (val[i]<0) ? leveld[i+1]+alphas*(val[i]-leveld[i+1]) : leveld[i+1] : 0;
|
||||
switch(ColorOn)
|
||||
{
|
||||
case chg_onOuter : state[i] = (val[i]>levelu[i]) ? 1 : (val[i]<leveld[i]) ? -1 : 0; break;
|
||||
case chg_onOuter2 : state[i] = (val[i]>levelu[i]) ? 1 : (val[i]<leveld[i]) ? -1 : (i<rates_total-1) ? state[i+1]: 0; break;
|
||||
case chg_onZero : state[i] = (val[i]>0) ? 1 : (val[i]<0) ? -1 : 0; break;
|
||||
default : state[i] = (i<rates_total-1) ? (val[i]>val[i+1]) ? 1 : (val[i]<val[i+1]) ? -1 : state[i+1] : 0;
|
||||
}
|
||||
histu[i] = EMPTY_VALUE; histd[i] = EMPTY_VALUE;
|
||||
if (state[i] == 1) { histu[i] = high[i]; histd[i] = low[i]; }
|
||||
if (state[i] == -1) { histd[i] = high[i]; histu[i] = low[i]; }
|
||||
}
|
||||
return(rates_total);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
//
|
||||
//------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
double workEma[][2];
|
||||
double iEma(double price, double alpha, int r, int _bars, int instanceNo=0)
|
||||
{
|
||||
if (ArrayRange(workEma,0)!= _bars) ArrayResize(workEma,_bars); r=_bars-r-1;
|
||||
|
||||
workEma[r][instanceNo] = price;
|
||||
if (r>0 && alpha!=-1)
|
||||
workEma[r][instanceNo] = workEma[r-1][instanceNo]+alpha*(price-workEma[r-1][instanceNo]);
|
||||
return(workEma[r][instanceNo]);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
//
|
||||
//------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
#define _priceInstances 1
|
||||
#define _priceInstancesSize 4
|
||||
double workHa[][_priceInstances*_priceInstancesSize];
|
||||
double getPrice(int tprice, const double& open[], const double& close[], const double& high[], const double& low[], int i, int bars, int instanceNo=0)
|
||||
{
|
||||
if (tprice>=pr_haclose)
|
||||
{
|
||||
if (ArrayRange(workHa,0)!= bars) ArrayResize(workHa,bars); instanceNo*=_priceInstancesSize;
|
||||
int r = bars-i-1;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
double haOpen;
|
||||
if (r>0)
|
||||
haOpen = (workHa[r-1][instanceNo+2] + workHa[r-1][instanceNo+3])/2.0;
|
||||
else haOpen = (open[i]+close[i])/2;
|
||||
double haClose = (open[i] + high[i] + low[i] + close[i]) / 4.0;
|
||||
double haHigh = MathMax(high[i], MathMax(haOpen,haClose));
|
||||
double haLow = MathMin(low[i] , MathMin(haOpen,haClose));
|
||||
|
||||
if(haOpen <haClose) { workHa[r][instanceNo+0] = haLow; workHa[r][instanceNo+1] = haHigh; }
|
||||
else { workHa[r][instanceNo+0] = haHigh; workHa[r][instanceNo+1] = haLow; }
|
||||
workHa[r][instanceNo+2] = haOpen;
|
||||
workHa[r][instanceNo+3] = haClose;
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
switch (tprice)
|
||||
{
|
||||
case pr_haclose: return(haClose);
|
||||
case pr_haopen: return(haOpen);
|
||||
case pr_hahigh: return(haHigh);
|
||||
case pr_halow: return(haLow);
|
||||
case pr_hamedian: return((haHigh+haLow)/2.0);
|
||||
case pr_hamedianb: return((haOpen+haClose)/2.0);
|
||||
case pr_hatypical: return((haHigh+haLow+haClose)/3.0);
|
||||
case pr_haweighted: return((haHigh+haLow+haClose+haClose)/4.0);
|
||||
case pr_haaverage: return((haHigh+haLow+haClose+haOpen)/4.0);
|
||||
case pr_hatbiased:
|
||||
if (haClose>haOpen)
|
||||
return((haHigh+haClose)/2.0);
|
||||
else return((haLow+haClose)/2.0);
|
||||
case pr_hatbiased2:
|
||||
if (haClose>haOpen) return(haHigh);
|
||||
if (haClose<haOpen) return(haLow);
|
||||
return(haClose);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
switch (tprice)
|
||||
{
|
||||
case pr_close: return(close[i]);
|
||||
case pr_open: return(open[i]);
|
||||
case pr_high: return(high[i]);
|
||||
case pr_low: return(low[i]);
|
||||
case pr_median: return((high[i]+low[i])/2.0);
|
||||
case pr_medianb: return((open[i]+close[i])/2.0);
|
||||
case pr_typical: return((high[i]+low[i]+close[i])/3.0);
|
||||
case pr_weighted: return((high[i]+low[i]+close[i]+close[i])/4.0);
|
||||
case pr_average: return((high[i]+low[i]+close[i]+open[i])/4.0);
|
||||
case pr_tbiased:
|
||||
if (close[i]>open[i])
|
||||
return((high[i]+close[i])/2.0);
|
||||
else return((low[i]+close[i])/2.0);
|
||||
case pr_tbiased2:
|
||||
if (close[i]>open[i]) return(high[i]);
|
||||
if (close[i]<open[i]) return(low[i]);
|
||||
return(close[i]);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,143 @@
|
||||
#property copyright "Copyright 2021, mfx123 & Conor Dailey"
|
||||
#property version "1.00"
|
||||
#property description "No need to tick anything below"
|
||||
#property strict
|
||||
#property indicator_chart_window
|
||||
|
||||
string total;
|
||||
double total_sl, total_tp;
|
||||
double prev_total_sl, prev_total_tp;
|
||||
string label = "sltp";
|
||||
//+------------------------------------------------------------------+
|
||||
//| Expert initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
total_sl = GetTotalSLValue();
|
||||
total_tp = GetTotalTPValue();
|
||||
ObjectCreate(0, label, OBJ_LABEL, 0, 0, 0);
|
||||
ObjectSetInteger(0, label, OBJPROP_CORNER, CORNER_LEFT_LOWER);
|
||||
ObjectSetInteger(0, label, OBJPROP_XDISTANCE, 0);
|
||||
ObjectSetInteger(0, label, OBJPROP_YDISTANCE, 50);
|
||||
ObjectSetInteger(0, label, OBJPROP_COLOR, clrGoldenrod);
|
||||
ObjectSetString(0, label, OBJPROP_FONT, "Arial");
|
||||
ObjectSetInteger(0, label, OBJPROP_FONTSIZE, 16);
|
||||
ObjectSetInteger(0, label, OBJPROP_HIDDEN, true);
|
||||
ObjectSetInteger(0, label, OBJPROP_BACK, false);
|
||||
ObjectSetInteger(0, label, OBJPROP_SELECTED, true);
|
||||
ObjectSetInteger(0, label, OBJPROP_SELECTABLE, true);
|
||||
ObjectSetInteger(0, label, OBJPROP_ZORDER, 0);
|
||||
Display_Info();
|
||||
return(INIT_SUCCEEDED);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Expert deinitialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
ObjectDelete(0, label);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Expert tick function |
|
||||
//+------------------------------------------------------------------+
|
||||
int GetMultiplier(string s)
|
||||
{
|
||||
int m = 0;
|
||||
int digits = SymbolInfoInteger(s, SYMBOL_DIGITS);
|
||||
if(digits == 5)
|
||||
m = 10000;
|
||||
if(digits == 4)
|
||||
m = 1000;
|
||||
if(digits == 2 || digits == 3)
|
||||
m = 100;
|
||||
if(digits == 1)
|
||||
m = 10;
|
||||
return(m);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
double GetPips2Dbl(string s)
|
||||
{
|
||||
int digits = SymbolInfoInteger(s, SYMBOL_DIGITS);
|
||||
double p = 0;
|
||||
if(digits == 5 || digits == 3)
|
||||
p = SymbolInfoDouble(s, SYMBOL_POINT) * 10;
|
||||
else
|
||||
p = SymbolInfoDouble(s, SYMBOL_POINT);
|
||||
return(p);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
double GetTotalSLValue()
|
||||
{
|
||||
double sl_value = 0, total_sl_value = 0, delta;
|
||||
|
||||
for(int v = PositionsTotal() - 1; v >= 0; v--)
|
||||
{
|
||||
ulong positionticket = PositionGetTicket(v);
|
||||
if(PositionSelectByTicket(positionticket))
|
||||
{
|
||||
if(PositionGetDouble(POSITION_SL) != 0)
|
||||
{
|
||||
|
||||
delta = (SymbolInfoDouble(PositionGetString(POSITION_SYMBOL), SYMBOL_TRADE_TICK_VALUE) / SymbolInfoDouble(PositionGetString(POSITION_SYMBOL), SYMBOL_TRADE_TICK_SIZE)) * GetPips2Dbl(PositionGetString(POSITION_SYMBOL));
|
||||
sl_value = ((MathAbs(PositionGetDouble(POSITION_PRICE_OPEN) - PositionGetDouble(POSITION_SL)) * delta) * PositionGetDouble(POSITION_VOLUME)) * GetMultiplier(PositionGetString(POSITION_SYMBOL));
|
||||
sl_value -= PositionGetDouble(POSITION_SWAP);
|
||||
sl_value = -(sl_value);
|
||||
total_sl_value += sl_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return(NormalizeDouble(total_sl_value, 2));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
double GetTotalTPValue()
|
||||
{
|
||||
double tp_value = 0, total_tp_value = 0, delta;
|
||||
|
||||
for(int v = PositionsTotal() - 1; v >= 0; v--)
|
||||
{
|
||||
ulong positionticket = PositionGetTicket(v);
|
||||
if(PositionSelectByTicket(positionticket))
|
||||
{
|
||||
if(PositionGetDouble(POSITION_TP) != 0)
|
||||
{
|
||||
delta = (SymbolInfoDouble(PositionGetString(POSITION_SYMBOL), SYMBOL_TRADE_TICK_VALUE) / SymbolInfoDouble(PositionGetString(POSITION_SYMBOL), SYMBOL_TRADE_TICK_SIZE)) * GetPips2Dbl(PositionGetString(POSITION_SYMBOL));
|
||||
tp_value = ((MathAbs(PositionGetDouble(POSITION_PRICE_OPEN) - PositionGetDouble(POSITION_TP)) * delta) * PositionGetDouble(POSITION_VOLUME)) * GetMultiplier(PositionGetString(POSITION_SYMBOL));
|
||||
tp_value -= PositionGetDouble(POSITION_SWAP);
|
||||
total_tp_value += tp_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return(NormalizeDouble(total_tp_value, 2));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
void Display_Info()
|
||||
{
|
||||
total = ""
|
||||
+ "SL: $ " + DoubleToString(total_sl, 2) + " " + "TP: $ " + DoubleToString(total_tp, 2);
|
||||
ObjectSetString(0, label, OBJPROP_TEXT, total);
|
||||
ChartRedraw(0);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnTick()
|
||||
{
|
||||
total_sl = GetTotalSLValue();
|
||||
total_tp = GetTotalTPValue();
|
||||
if((total_sl != prev_total_sl) || (total_tp != prev_total_tp))
|
||||
{
|
||||
Display_Info();
|
||||
prev_total_sl = total_sl;
|
||||
prev_total_tp = total_tp;
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
Binary file not shown.
@@ -0,0 +1,87 @@
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Heiken_Ashi.mq5 |
|
||||
//| Copyright 2009, MetaQuotes Software Corp. |
|
||||
//| http://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "2009, MetaQuotes Software Corp."
|
||||
#property link "http://www.mql5.com"
|
||||
//--- indicator settings
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 5
|
||||
#property indicator_plots 1
|
||||
#property indicator_type1 DRAW_COLOR_CANDLES
|
||||
#property indicator_color1 DodgerBlue, Red
|
||||
#property indicator_label1 "Heiken Ashi Open;Heiken Ashi High;Heiken Ashi Low;Heiken Ashi Close"
|
||||
//--- indicator buffers
|
||||
double ExtOBuffer[];
|
||||
double ExtHBuffer[];
|
||||
double ExtLBuffer[];
|
||||
double ExtCBuffer[];
|
||||
double ExtColorBuffer[];
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnInit()
|
||||
{
|
||||
//--- indicator buffers mapping
|
||||
SetIndexBuffer(0,ExtOBuffer,INDICATOR_DATA);
|
||||
SetIndexBuffer(1,ExtHBuffer,INDICATOR_DATA);
|
||||
SetIndexBuffer(2,ExtLBuffer,INDICATOR_DATA);
|
||||
SetIndexBuffer(3,ExtCBuffer,INDICATOR_DATA);
|
||||
SetIndexBuffer(4,ExtColorBuffer,INDICATOR_COLOR_INDEX);
|
||||
//---
|
||||
IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
|
||||
//--- sets first bar from what index will be drawn
|
||||
IndicatorSetString(INDICATOR_SHORTNAME,"Heiken Ashi");
|
||||
//--- sets drawing line empty value
|
||||
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
|
||||
//--- initialization done
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Heiken Ashi |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnCalculate(const int rates_total,const int prev_calculated,
|
||||
const datetime &Time[],
|
||||
const double &Open[],
|
||||
const double &High[],
|
||||
const double &Low[],
|
||||
const double &Close[],
|
||||
const long &TickVolume[],
|
||||
const long &Volume[],
|
||||
const int &Spread[])
|
||||
{
|
||||
int i,limit;
|
||||
//--- preliminary calculations
|
||||
if(prev_calculated==0)
|
||||
{
|
||||
//--- set first candle
|
||||
ExtLBuffer[0]=Low[0];
|
||||
ExtHBuffer[0]=High[0];
|
||||
ExtOBuffer[0]=Open[0];
|
||||
ExtCBuffer[0]=Close[0];
|
||||
limit=1;
|
||||
}
|
||||
else limit=prev_calculated-1;
|
||||
|
||||
//--- the main loop of calculations
|
||||
for(i=limit;i<rates_total && !IsStopped();i++)
|
||||
{
|
||||
double haOpen=(ExtOBuffer[i-1]+ExtCBuffer[i-1])/2;
|
||||
double haClose=(Open[i]+High[i]+Low[i]+Close[i])/4;
|
||||
double haHigh=MathMax(High[i],MathMax(haOpen,haClose));
|
||||
double haLow=MathMin(Low[i],MathMin(haOpen,haClose));
|
||||
|
||||
ExtLBuffer[i]=haLow;
|
||||
ExtHBuffer[i]=haHigh;
|
||||
ExtOBuffer[i]=haOpen;
|
||||
ExtCBuffer[i]=haClose;
|
||||
|
||||
//--- set candle color
|
||||
if(haOpen<haClose) ExtColorBuffer[i]=0.0; // set color DodgerBlue
|
||||
else ExtColorBuffer[i]=1.0; // set color Red
|
||||
}
|
||||
//--- done
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,115 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| SSL Channel Chart.mq5 |
|
||||
//| Copyright 2020, MetaQuotes Software Corp. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2020, MetaQuotes Software Corp."
|
||||
#property link "https://www.mql5.com"
|
||||
|
||||
//------------------------------------------------------------------
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 3
|
||||
#property indicator_plots 2
|
||||
#property indicator_label1 "Bears"
|
||||
#property indicator_color1 clrOrange
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_width1 2
|
||||
#property indicator_label2 "Bulls"
|
||||
#property indicator_color2 clrAqua
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_width2 2
|
||||
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
||||
//---- input parameters
|
||||
input ENUM_MA_METHOD MA_Method = MODE_SMA; // Method
|
||||
input int Lb = 10;
|
||||
//---- buffers
|
||||
|
||||
double ssld[];
|
||||
double sslu[];
|
||||
double Hlv[];
|
||||
|
||||
int hMAHigh;
|
||||
int hMALow;
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
|
||||
SetIndexBuffer(0, ssld, INDICATOR_DATA);
|
||||
SetIndexBuffer(1, sslu, INDICATOR_DATA);
|
||||
SetIndexBuffer(2, Hlv, INDICATOR_CALCULATIONS);
|
||||
|
||||
hMAHigh = iMA(_Symbol, PERIOD_CURRENT, Lb, 0, MA_Method, PRICE_HIGH);
|
||||
hMALow = iMA(_Symbol, PERIOD_CURRENT, Lb, 0, MA_Method, PRICE_LOW);
|
||||
|
||||
|
||||
if(hMAHigh==INVALID_HANDLE)Print(" Failed to get handle of the iMA indicator");
|
||||
if(hMALow==INVALID_HANDLE)Print(" Failed to get handle of the iMA indicator");
|
||||
|
||||
ArraySetAsSeries(ssld,true);
|
||||
ArraySetAsSeries(sslu,true);
|
||||
ArraySetAsSeries(Hlv,true);
|
||||
//---
|
||||
return(INIT_SUCCEEDED);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator iteration function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnCalculate(const int rates_total,
|
||||
const int prev_calculated,
|
||||
const datetime &time[],
|
||||
const double &open[],
|
||||
const double &high[],
|
||||
const double &low[],
|
||||
const double &close[],
|
||||
const long &tick_volume[],
|
||||
const long &volume[],
|
||||
const int &spread[])
|
||||
{
|
||||
//---
|
||||
int counted_bars = prev_calculated;
|
||||
int i,limit;
|
||||
|
||||
double MAHigh[];
|
||||
double MALow[];
|
||||
|
||||
if(counted_bars<0) return(-1);
|
||||
if(counted_bars>0) counted_bars--;
|
||||
|
||||
limit = MathMax(rates_total - counted_bars - Lb, 1);
|
||||
|
||||
|
||||
|
||||
CopyBuffer(hMAHigh, 0, 0, limit+1, MAHigh);
|
||||
CopyBuffer(hMALow, 0, 0, limit+1, MALow);
|
||||
|
||||
for(i=limit; i>=0; i--)
|
||||
{
|
||||
|
||||
Hlv[i]=Hlv[i+1];
|
||||
|
||||
if (close[rates_total-1-i] > MAHigh[limit-i]) Hlv[i]= 1;
|
||||
if (close[rates_total-1-i] < MALow[limit-i]) Hlv[i]= -1;
|
||||
|
||||
if(Hlv[i]==-1)
|
||||
{
|
||||
ssld[i] = MAHigh[limit-i];
|
||||
sslu[i] = MALow[limit-i];
|
||||
}
|
||||
else
|
||||
{
|
||||
ssld[i] = MALow[limit-i];
|
||||
sslu[i] = MAHigh[limit-i];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//--- return value of prev_calculated for next call
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,115 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| SSL Channel Chart.mq5 |
|
||||
//| Copyright 2020, MetaQuotes Software Corp. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2020, MetaQuotes Software Corp."
|
||||
#property link "https://www.mql5.com"
|
||||
|
||||
//------------------------------------------------------------------
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 3
|
||||
#property indicator_plots 2
|
||||
#property indicator_label1 "Bears"
|
||||
#property indicator_color1 clrOrange
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_width1 2
|
||||
#property indicator_label2 "Bulls"
|
||||
#property indicator_color2 clrAqua
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_width2 2
|
||||
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
||||
//---- input parameters
|
||||
input ENUM_MA_METHOD MA_Method = MODE_SMA; // Method
|
||||
input int Lb = 10;
|
||||
//---- buffers
|
||||
|
||||
double ssld[];
|
||||
double sslu[];
|
||||
double Hlv[];
|
||||
|
||||
int hMAHigh;
|
||||
int hMALow;
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
|
||||
SetIndexBuffer(0, ssld, INDICATOR_DATA);
|
||||
SetIndexBuffer(1, sslu, INDICATOR_DATA);
|
||||
SetIndexBuffer(2, Hlv, INDICATOR_CALCULATIONS);
|
||||
|
||||
hMAHigh = iMA(_Symbol, PERIOD_CURRENT, Lb, 0, MA_Method, PRICE_HIGH);
|
||||
hMALow = iMA(_Symbol, PERIOD_CURRENT, Lb, 0, MA_Method, PRICE_LOW);
|
||||
|
||||
|
||||
if(hMAHigh==INVALID_HANDLE)Print(" Failed to get handle of the iMA indicator");
|
||||
if(hMALow==INVALID_HANDLE)Print(" Failed to get handle of the iMA indicator");
|
||||
|
||||
ArraySetAsSeries(ssld,true);
|
||||
ArraySetAsSeries(sslu,true);
|
||||
ArraySetAsSeries(Hlv,true);
|
||||
//---
|
||||
return(INIT_SUCCEEDED);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator iteration function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnCalculate(const int rates_total,
|
||||
const int prev_calculated,
|
||||
const datetime &time[],
|
||||
const double &open[],
|
||||
const double &high[],
|
||||
const double &low[],
|
||||
const double &close[],
|
||||
const long &tick_volume[],
|
||||
const long &volume[],
|
||||
const int &spread[])
|
||||
{
|
||||
//---
|
||||
int counted_bars = prev_calculated;
|
||||
int i,limit;
|
||||
|
||||
double MAHigh[];
|
||||
double MALow[];
|
||||
|
||||
if(counted_bars<0) return(-1);
|
||||
if(counted_bars>0) counted_bars--;
|
||||
|
||||
limit = MathMax(rates_total - counted_bars - Lb, 1);
|
||||
|
||||
|
||||
|
||||
CopyBuffer(hMAHigh, 0, 0, limit+1, MAHigh);
|
||||
CopyBuffer(hMALow, 0, 0, limit+1, MALow);
|
||||
|
||||
for(i=limit; i>=0; i--)
|
||||
{
|
||||
|
||||
Hlv[i]=Hlv[i+1];
|
||||
|
||||
if (close[rates_total-1-i] > MAHigh[limit-i]) Hlv[i]= 1;
|
||||
if (close[rates_total-1-i] < MALow[limit-i]) Hlv[i]= -1;
|
||||
|
||||
if(Hlv[i]==-1)
|
||||
{
|
||||
ssld[i] = MAHigh[limit-i];
|
||||
sslu[i] = MALow[limit-i];
|
||||
}
|
||||
else
|
||||
{
|
||||
ssld[i] = MALow[limit-i];
|
||||
sslu[i] = MAHigh[limit-i];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//--- return value of prev_calculated for next call
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
Binary file not shown.
@@ -0,0 +1,505 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| TradeControl_en.mq5 |
|
||||
//| Copyright KlimMalgin |
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "KlimMalgin"
|
||||
#property link ""
|
||||
#property version "1.00"
|
||||
|
||||
|
||||
datetime start_date = 0; // Date, from which we begin to read history
|
||||
|
||||
int OrdersPrev = 0; // Number of orders at the time of previous OnTrade() call
|
||||
int PositionsPrev = 0; // Number of positions at the time of previous OnTrade() call
|
||||
ulong LastOrderTicket = 0; // Ticket of the last processed order
|
||||
|
||||
int _GetLastError=0; // Error code
|
||||
long state=0; // Order state
|
||||
|
||||
/*
|
||||
*
|
||||
* Structure that stores information about positions
|
||||
*
|
||||
*/
|
||||
struct _position
|
||||
{
|
||||
|
||||
long type, // Position type
|
||||
magic; // Magic number for position
|
||||
datetime time; // Time of position opening
|
||||
|
||||
double volume, // Position volume
|
||||
priceopen, // Position price
|
||||
sl, // Stop Loss level for opened position
|
||||
tp, // Take Profit level for opened position
|
||||
pricecurrent, // Symbol current price
|
||||
comission, // Commission
|
||||
swap, // Accumulated swap
|
||||
profit; // Current profit
|
||||
|
||||
string symbol, // Symbol, by which the position has been opened
|
||||
comment; // Comment to position
|
||||
};
|
||||
|
||||
int _ExpertPositionsTotal = 0;
|
||||
|
||||
_position PositionList[], // Array that stores info about position
|
||||
PrevPositionList[];
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Structure that stores information about orders
|
||||
*
|
||||
*/
|
||||
struct _orders
|
||||
{
|
||||
|
||||
datetime time_setup, // Time of order placement
|
||||
time_expiration, // Time of order expiration
|
||||
time_done; // Time of order execution or cancellation
|
||||
|
||||
long type, // Order type
|
||||
state, // Order state
|
||||
type_filling, // Type of execution by remainder
|
||||
type_time, // Order lifetime
|
||||
ticket; // Order ticket
|
||||
|
||||
long magic, // Id of Expert Advisor, that placed an order
|
||||
// (intended to ensure that each Expert
|
||||
// must place it's own unique number)
|
||||
|
||||
position_id; // Position id, that is placed on order,
|
||||
// when it is executed. Each executed order invokes a
|
||||
// deal, that opens new or changes existing
|
||||
// position. Id of that position is placed on
|
||||
// executed order in this moment.
|
||||
|
||||
double volume_initial, // Initial volume on order placement
|
||||
volume_current, // Unfilled volume
|
||||
price_open, // Price, specified in the order
|
||||
sl, // Stop Loss level
|
||||
tp, // Take Profit level
|
||||
price_current, // Current price by order symbol
|
||||
price_stoplimit; // Price of placing Limit order when StopLimit order is triggered
|
||||
|
||||
string symbol, // Symbol, by which the order has been placed
|
||||
comment; // Comment
|
||||
|
||||
};
|
||||
|
||||
int _ExpertOrdersTotal = 0;
|
||||
|
||||
_orders OrderList[], // Arrays that store info about orders
|
||||
PrevOrderList[];
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Expert initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
//---
|
||||
start_date = 0;
|
||||
|
||||
OrdersPrev = OrdersTotal();
|
||||
PositionsPrev = PositionsTotal();
|
||||
|
||||
GetPosition(PrevPositionList);
|
||||
GetOrders(PrevOrderList);
|
||||
//---
|
||||
return(0);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Expert deinitialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//---
|
||||
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| OnTrade function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnTrade()
|
||||
{
|
||||
//---
|
||||
GetPosition(PositionList);
|
||||
GetOrders(OrderList);
|
||||
datetime dc = TimeCurrent();
|
||||
HistorySelect(start_date,dc);
|
||||
|
||||
|
||||
Alert("The Trade event occurred");
|
||||
|
||||
if (OrdersPrev < OrdersTotal())
|
||||
{
|
||||
OrderGetTicket(OrdersTotal()-1);// Select the last order to work with
|
||||
_GetLastError=GetLastError();
|
||||
Print("Error #",_GetLastError);ResetLastError();
|
||||
//--
|
||||
if (OrderGetInteger(ORDER_STATE) == ORDER_STATE_STARTED)
|
||||
{
|
||||
Alert(OrderGetTicket(OrdersTotal()-1),"Order has arrived for processing");
|
||||
LastOrderTicket = OrderGetTicket(OrdersTotal()-1); // Saving the order ticket for further work
|
||||
}
|
||||
|
||||
|
||||
state = OrderGetInteger(ORDER_STATE);
|
||||
if (state == ORDER_STATE_PLACED)
|
||||
{
|
||||
switch(OrderGetInteger(ORDER_TYPE))
|
||||
{
|
||||
case 2:
|
||||
Alert("Pending order Buy Limit #", OrderGetTicket(OrdersTotal()-1)," accepted!");
|
||||
break;
|
||||
|
||||
case 3:
|
||||
Alert("Pending order Sell Limit #", OrderGetTicket(OrdersTotal()-1)," accepted!");
|
||||
break;
|
||||
|
||||
case 4:
|
||||
Alert("Pending order Buy Stop #", OrderGetTicket(OrdersTotal()-1)," accepted!");
|
||||
break;
|
||||
|
||||
case 5:
|
||||
Alert("Pending order Sell Stop #", OrderGetTicket(OrdersTotal()-1)," accepted!");
|
||||
break;
|
||||
|
||||
case 6:
|
||||
Alert("Pending order Buy Stop Limit #", OrderGetTicket(OrdersTotal()-1)," accepted!");
|
||||
break;
|
||||
|
||||
case 7:
|
||||
Alert("Pending order Sell Stop Limit #", OrderGetTicket(OrdersTotal()-1)," accepted!");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
else if(OrdersPrev > OrdersTotal())
|
||||
{
|
||||
state = HistoryOrderGetInteger(LastOrderTicket,ORDER_STATE);
|
||||
|
||||
// If order is not found, generate an error
|
||||
_GetLastError=GetLastError();
|
||||
if (_GetLastError != 0){Alert("Error #",_GetLastError," Order ",LastOrderTicket," is not found!");LastOrderTicket = 0;}
|
||||
Print("Error #",_GetLastError," state: ",state);ResetLastError();
|
||||
|
||||
|
||||
// If order is fully executed
|
||||
if (state == ORDER_STATE_FILLED)
|
||||
{
|
||||
// Then analyze the last deal
|
||||
// --
|
||||
Alert(LastOrderTicket, "Order executed, going to deal");
|
||||
switch(HistoryDealGetInteger(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_ENTRY))
|
||||
{
|
||||
|
||||
// Entering the market
|
||||
case DEAL_ENTRY_IN:
|
||||
Alert(HistoryDealGetInteger(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_ORDER),
|
||||
" order invoked deal #",HistoryDealGetTicket(HistoryDealsTotal()-1));
|
||||
|
||||
switch(HistoryDealGetInteger(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_TYPE))
|
||||
{
|
||||
case 0:
|
||||
// If volumes of position and deal are equal, then position has just been opened
|
||||
if (PositionSelect(HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL))
|
||||
&& (PositionGetDouble(POSITION_VOLUME) == HistoryDealGetDouble(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_VOLUME)))
|
||||
{
|
||||
Alert("Buy position has been opened on pair ",
|
||||
HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL));
|
||||
}
|
||||
else
|
||||
// If volumes of position and deal are not equal, then position has been incremented
|
||||
if (PositionSelect(HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL))
|
||||
&& (PositionGetDouble(POSITION_VOLUME) > HistoryDealGetDouble(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_VOLUME)))
|
||||
{
|
||||
Alert("Buy position has incremented on pair ",
|
||||
HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL));
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// If volumes of position and deal are equal, then position has just been opened
|
||||
if (PositionSelect(HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL))
|
||||
&& (PositionGetDouble(POSITION_VOLUME) == HistoryDealGetDouble(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_VOLUME)))
|
||||
{
|
||||
Alert("Sell position has been opened on pair ",
|
||||
HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL));
|
||||
}
|
||||
else
|
||||
// If volumes of position and deal are not equal, then position has been incremented
|
||||
if (PositionSelect(HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL))
|
||||
&& (PositionGetDouble(POSITION_VOLUME) > HistoryDealGetDouble(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_VOLUME)))
|
||||
{
|
||||
Alert("Sell position has incremented on pair ",
|
||||
HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
Alert("Unprocessed code of type: ",
|
||||
HistoryDealGetInteger(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_TYPE));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
// Âûõîä èç ðûíêà
|
||||
case DEAL_ENTRY_OUT:
|
||||
Alert(HistoryDealGetInteger(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_ORDER),
|
||||
" order invoked deal #",HistoryDealGetTicket(HistoryDealsTotal()-1));
|
||||
|
||||
switch(HistoryDealGetInteger(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_TYPE))
|
||||
{
|
||||
case 0:
|
||||
// If position, we tried to close, is still present, then we have closed only part of it
|
||||
if (PositionSelect(HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL)) == true)
|
||||
{
|
||||
Alert("Part of Sell position has been closed on pair ",
|
||||
HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL),
|
||||
" with profit = ",
|
||||
HistoryDealGetDouble(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_PROFIT));
|
||||
}
|
||||
else
|
||||
// If position is not found, then it is fully closed
|
||||
if (PositionSelect(HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL)) == false)
|
||||
{
|
||||
Alert("Sell position has been closed on pair ",
|
||||
HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL),
|
||||
" with profit = ",
|
||||
HistoryDealGetDouble(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_PROFIT));
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// If position, we tried to close, is still present, then we have closed only part of it
|
||||
if (PositionSelect(HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL)) == true)
|
||||
{
|
||||
Alert("Part of Buy position has been closed on pair ",
|
||||
HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL),
|
||||
" with profit = ",
|
||||
HistoryDealGetDouble(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_PROFIT));
|
||||
}
|
||||
else
|
||||
// If position is not found, then it is fully closed
|
||||
if (PositionSelect(HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL)) == false)
|
||||
{
|
||||
Alert("Buy position has been closed on pair ",
|
||||
HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL),
|
||||
" with profit = ",
|
||||
HistoryDealGetDouble(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_PROFIT));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
Alert("Unprocessed code of type: ",
|
||||
HistoryDealGetInteger(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_TYPE));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
// Reverse
|
||||
case DEAL_ENTRY_INOUT:
|
||||
Alert(HistoryDealGetInteger(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_ORDER),
|
||||
" order invoked deal #",HistoryDealGetTicket(HistoryDealsTotal()-1));
|
||||
|
||||
switch(HistoryDealGetInteger(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_TYPE))
|
||||
{
|
||||
case 0:
|
||||
Alert("Sell is reversed to Buy on pair ",
|
||||
HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL),
|
||||
" resulting profit = ",
|
||||
HistoryDealGetDouble(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_PROFIT));
|
||||
break;
|
||||
|
||||
case 1:
|
||||
Alert("Buy is reversed to Sell on pair ",
|
||||
HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL),
|
||||
" resulting profit = ",
|
||||
HistoryDealGetDouble(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_PROFIT));
|
||||
break;
|
||||
|
||||
default:
|
||||
Alert("Unprocessed code of type: ",
|
||||
HistoryDealGetInteger(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_TYPE));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
// Indicates the state record
|
||||
case DEAL_ENTRY_STATE:
|
||||
Alert("Indicates the state record. Unprocessed code of direction: ",
|
||||
HistoryDealGetInteger(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_TYPE));
|
||||
break;
|
||||
}
|
||||
// --
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if ((PositionsPrev == PositionsTotal()) && (OrdersPrev == OrdersTotal()))
|
||||
{
|
||||
string _alerts = "";
|
||||
bool modify = false;
|
||||
|
||||
for (int i=0;i<_ExpertPositionsTotal;i++)
|
||||
{
|
||||
if (PrevPositionList[i].sl != PositionList[i].sl)
|
||||
{
|
||||
_alerts += "On pair "+PositionList[i].symbol+" Stop Loss changed from "+ PrevPositionList[i].sl +" to "+ PositionList[i].sl +"\n";
|
||||
modify = true;
|
||||
}
|
||||
if (PrevPositionList[i].tp != PositionList[i].tp)
|
||||
{
|
||||
_alerts += "On pair "+PositionList[i].symbol+" Take Profit changed from "+ PrevPositionList[i].tp +" to "+ PositionList[i].tp +"\n";
|
||||
modify = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (int i = 0;i<_ExpertOrdersTotal;i++)
|
||||
{
|
||||
if (PrevOrderList[i].sl != OrderList[i].sl)
|
||||
{
|
||||
_alerts += "Order "+OrderList[i].ticket+" has changed Stop Loss from "+ PrevOrderList[i].sl +" to "+ OrderList[i].sl +"\n";
|
||||
modify = true;
|
||||
}
|
||||
if (PrevOrderList[i].tp != OrderList[i].tp)
|
||||
{
|
||||
_alerts += "Order "+OrderList[i].ticket+" has changed Take Profit from "+ PrevOrderList[i].tp +" to "+ OrderList[i].tp +"\n";
|
||||
modify = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (modify == true)
|
||||
{
|
||||
Alert(_alerts);
|
||||
modify = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GetPosition(PrevPositionList);
|
||||
GetOrders(PrevOrderList);
|
||||
OrdersPrev = OrdersTotal();
|
||||
PositionsPrev = PositionsTotal();
|
||||
|
||||
//---
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Expert tick function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnTick()
|
||||
{
|
||||
//---
|
||||
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
|
||||
|
||||
void GetPosition(_position &Array[])
|
||||
{
|
||||
int _GetLastError=0,_PositionsTotal=PositionsTotal();
|
||||
|
||||
int temp_value=(int)MathMax(_PositionsTotal,1);
|
||||
ArrayResize(Array, temp_value);
|
||||
|
||||
_ExpertPositionsTotal=0;
|
||||
for(int z=_PositionsTotal-1; z>=0; z--)
|
||||
{
|
||||
if(!PositionSelect(PositionGetSymbol(z)))
|
||||
{
|
||||
_GetLastError=GetLastError();
|
||||
Print("OrderSelect() - Error #",_GetLastError);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the position is found, then put its info to the array
|
||||
Array[z].type = PositionGetInteger(POSITION_TYPE);
|
||||
Array[z].time = PositionGetInteger(POSITION_TIME);
|
||||
Array[z].magic = PositionGetInteger(POSITION_MAGIC);
|
||||
Array[z].volume = PositionGetDouble(POSITION_VOLUME);
|
||||
Array[z].priceopen = PositionGetDouble(POSITION_PRICE_OPEN);
|
||||
Array[z].sl = PositionGetDouble(POSITION_SL);
|
||||
Array[z].tp = PositionGetDouble(POSITION_TP);
|
||||
Array[z].pricecurrent = PositionGetDouble(POSITION_PRICE_CURRENT);
|
||||
Array[z].comission = PositionGetDouble(POSITION_COMMISSION);
|
||||
Array[z].swap = PositionGetDouble(POSITION_SWAP);
|
||||
Array[z].profit = PositionGetDouble(POSITION_PROFIT);
|
||||
Array[z].symbol = PositionGetString(POSITION_SYMBOL);
|
||||
Array[z].comment = PositionGetString(POSITION_COMMENT);
|
||||
_ExpertPositionsTotal++;
|
||||
}
|
||||
}
|
||||
|
||||
temp_value=(int)MathMax(_ExpertPositionsTotal,1);
|
||||
ArrayResize(Array,temp_value);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Function GetOrders() |
|
||||
//+------------------------------------------------------------------+
|
||||
void GetOrders(_orders &OrdersList[])
|
||||
{
|
||||
|
||||
int _GetLastError=0,_OrdersTotal=OrdersTotal();
|
||||
|
||||
int temp_value=(int)MathMax(_OrdersTotal,1);
|
||||
ArrayResize(OrdersList,temp_value);
|
||||
|
||||
_ExpertOrdersTotal=0;
|
||||
for(int z=_OrdersTotal-1; z>=0; z--)
|
||||
{
|
||||
if(!OrderGetTicket(z))
|
||||
{
|
||||
_GetLastError=GetLastError();
|
||||
Print("GetOrders() - Error #",_GetLastError);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
OrdersList[z].ticket = OrderGetTicket(z);
|
||||
OrdersList[z].time_setup = OrderGetInteger(ORDER_TIME_SETUP);
|
||||
OrdersList[z].time_expiration = OrderGetInteger(ORDER_TIME_EXPIRATION);
|
||||
OrdersList[z].time_done = OrderGetInteger(ORDER_TIME_DONE);
|
||||
OrdersList[z].type = OrderGetInteger(ORDER_TYPE);
|
||||
|
||||
OrdersList[z].state = OrderGetInteger(ORDER_STATE);
|
||||
OrdersList[z].type_filling = OrderGetInteger(ORDER_TYPE_FILLING);
|
||||
OrdersList[z].type_time = OrderGetInteger(ORDER_TYPE_TIME);
|
||||
OrdersList[z].magic = OrderGetInteger(ORDER_MAGIC);
|
||||
OrdersList[z].position_id = OrderGetInteger(ORDER_POSITION_ID);
|
||||
|
||||
OrdersList[z].volume_initial = OrderGetDouble(ORDER_VOLUME_INITIAL);
|
||||
OrdersList[z].volume_current = OrderGetDouble(ORDER_VOLUME_CURRENT);
|
||||
OrdersList[z].price_open = OrderGetDouble(ORDER_PRICE_OPEN);
|
||||
OrdersList[z].sl = OrderGetDouble(ORDER_SL);
|
||||
OrdersList[z].tp = OrderGetDouble(ORDER_TP);
|
||||
OrdersList[z].price_current = OrderGetDouble(ORDER_PRICE_CURRENT);
|
||||
OrdersList[z].price_stoplimit = OrderGetDouble(ORDER_PRICE_STOPLIMIT);
|
||||
|
||||
OrdersList[z].symbol = OrderGetString(ORDER_SYMBOL);
|
||||
OrdersList[z].comment = OrderGetString(ORDER_COMMENT);
|
||||
|
||||
_ExpertOrdersTotal++;
|
||||
}
|
||||
}
|
||||
|
||||
temp_value=(int)MathMax(_ExpertOrdersTotal,1);
|
||||
ArrayResize(OrdersList,temp_value);
|
||||
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user