339 lines
37 KiB
MQL5
339 lines
37 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| AlligatorAndStochastic rectangles.mq5 |
|
|
//| Copyright © 2018, Vladimir Karputov |
|
|
//| http://wmua.ru/slesar/ |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Copyright © 2018, Vladimir Karputov"
|
|
#property link "http://wmua.ru/slesar/"
|
|
#property version "1.002"
|
|
#property indicator_chart_window
|
|
#property indicator_buffers 0
|
|
#property indicator_plots 0
|
|
//--- input parameters
|
|
input int Inp_Alligator_jaw_period = 13; // Alligator: period for the calculation of jaws
|
|
input int Inp_Alligator_jaw_shift = 8; // Alligator: horizontal shift of jaws
|
|
input int Inp_Alligator_teeth_period = 8; // Alligator: period for the calculation of teeth
|
|
input int Inp_Alligator_teeth_shift = 5; // Alligator: horizontal shift of teeth
|
|
input int Inp_Alligator_lips_period = 5; // Alligator: period for the calculation of lips
|
|
input int Inp_Alligator_lips_shift = 3; // Alligator: horizontal shift of lips
|
|
input ENUM_MA_METHOD Inp_Alligator_ma_method = MODE_SMMA; // Alligator: type of smoothing
|
|
input ENUM_APPLIED_PRICE Inp_Alligator_applied_price= PRICE_MEDIAN; // Alligator: type of price
|
|
//---
|
|
input int Inp_Stochastic_Kperiod = 5; // Stochastic: K-period (number of bars for calculations)
|
|
input int Inp_Stochastic_Dperiod = 3; // Stochastic: D-period (period of first smoothing)
|
|
input int Inp_Stochastic_slowing = 3; // Stochastic: final smoothing
|
|
input ENUM_MA_METHOD Inp_Stochastic_ma_method = MODE_SMA; // Stochastic: type of smoothing
|
|
input ENUM_STO_PRICE Inp_Stochastic_price_field = STO_LOWHIGH; // Stochastic: stochastic calculation method
|
|
//---
|
|
input datetime Inp_time_open_start = D'1970.01.01 08:59:00'; // Time to open positions start
|
|
input datetime Inp_time_open_end = D'1970.01.01 10:59:00'; // Time to open positions end
|
|
input datetime Inp_time_close_start = D'1970.01.01 19:59:00'; // Time to close positions start
|
|
input datetime Inp_time_close_end = D'1970.01.01 21:59:00'; // Time to close positions end
|
|
//---
|
|
input color Inp_Rectangle_Open_Color = clrMediumPurple; // Rectangle Open: Color
|
|
input color Inp_Rectangle_Close_Color = clrLawnGreen; // Rectangle Close: Color
|
|
input ENUM_LINE_STYLE Inp_Rectangle_Style = STYLE_DASH; // Rectangle: Style
|
|
input int Inp_Rectangle_Width = 2; // Rectangle: Width
|
|
input bool Inp_Rectangle_Fill = false; // Rectangle: Filling color
|
|
input bool Inp_Rectangle_Back = false; // Rectangle: Background
|
|
input bool Inp_Rectangle_Selection = false; // Rectangle: Highlight to move
|
|
input bool Inp_Rectangle_Hidden = true; // Rectangle: Hidden in the object list
|
|
input long Inp_Rectangle_ZOrder = 0; // Rectangle: Priority for mouse click
|
|
//---
|
|
MqlDateTime SOpenStart;
|
|
MqlDateTime SOpenEnd;
|
|
MqlDateTime SCloseStart;
|
|
MqlDateTime SCloseEnd;
|
|
long open_start;
|
|
long open_end;
|
|
long close_start;
|
|
long close_end;
|
|
//---
|
|
string name_open = "Rectangle_open_"; // Rectangle name
|
|
string name_close = "Rectangle_close_"; // Rectangle name
|
|
string pref_stoch = "Stoch_";
|
|
//+------------------------------------------------------------------+
|
|
//| Custom indicator initialization function |
|
|
//+------------------------------------------------------------------+
|
|
int OnInit()
|
|
{
|
|
//--- check input parameters
|
|
TimeToStruct(Inp_time_open_start,SOpenStart);
|
|
TimeToStruct(Inp_time_open_end,SOpenEnd);
|
|
TimeToStruct(Inp_time_close_start,SCloseStart);
|
|
TimeToStruct(Inp_time_close_end,SCloseEnd);
|
|
open_start = SOpenStart.hour*3600+SOpenStart.min*60+SOpenStart.sec;
|
|
open_end = SOpenEnd.hour*3600+SOpenEnd.min*60+SOpenEnd.sec;
|
|
close_start = SCloseStart.hour*3600+SCloseStart.min*60+SCloseStart.sec;
|
|
close_end = SCloseEnd.hour*3600+SCloseEnd.min*60+SCloseEnd.sec;
|
|
if(open_start>=open_end)
|
|
{
|
|
Print(__FUNCTION__,
|
|
" ERROR: \"Time to open positions start\" (",TimeToString(Inp_time_open_start,TIME_SECONDS),
|
|
") >= \"Time to open positions end\" (",TimeToString(Inp_time_open_end,TIME_SECONDS),")");
|
|
return(INIT_PARAMETERS_INCORRECT);
|
|
}
|
|
if(close_start>=close_end)
|
|
{
|
|
Print(__FUNCTION__,
|
|
" ERROR: \"Time to close positions start\" (",TimeToString(Inp_time_close_start,TIME_SECONDS),
|
|
") >= \"Time to close positions end\" (",TimeToString(Inp_time_close_end,TIME_SECONDS),")");
|
|
return(INIT_PARAMETERS_INCORRECT);
|
|
}
|
|
if(open_end>=close_start)
|
|
{
|
|
Print(__FUNCTION__,
|
|
" ERROR: \"Time to open positions end\" (",TimeToString(Inp_time_open_end,TIME_SECONDS),
|
|
") >= \"Time to close positions start\" (",TimeToString(Inp_time_close_start,TIME_SECONDS),")");
|
|
return(INIT_PARAMETERS_INCORRECT);
|
|
}
|
|
//--- print time's
|
|
Print("\"Time to open positions start\": ",TimeToString(Inp_time_open_start,TIME_SECONDS));
|
|
Print("\"Time to open positions end\" : ",TimeToString(Inp_time_open_end,TIME_SECONDS));
|
|
Print("\"Time to close positions start\": ",TimeToString(Inp_time_close_start,TIME_SECONDS));
|
|
Print("\"Time to close positions end\" : ",TimeToString(Inp_time_close_end,TIME_SECONDS));
|
|
Print("//---");
|
|
//---
|
|
return(INIT_SUCCEEDED);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Custom indicator deinitialization function |
|
|
//+------------------------------------------------------------------+
|
|
void OnDeinit(const int reason)
|
|
{
|
|
ObjectsDeleteAll(0,"Rectangle_",0,OBJ_RECTANGLE);
|
|
ObjectsDeleteAll(0,pref_stoch,1,OBJ_RECTANGLE);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| 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[])
|
|
{
|
|
//---
|
|
MqlDateTime STime;
|
|
static datetime open_start_time = 0; // first point time ("0" -> D'1970.01.01 00:00:00')
|
|
static double open_start_up_price = 0; // first point price ("0" -> D'1970.01.01 00:00:00')
|
|
static datetime open_end_time = 0; // second point time
|
|
static double open_end_down_price = 0; // second point price
|
|
static string open_name = "";
|
|
static datetime close_start_time = 0; // first point time ("0" -> D'1970.01.01 00:00:00')
|
|
static double close_start_up_price = 0; // first point price ("0" -> D'1970.01.01 00:00:00')
|
|
static datetime close_end_time = 0; // second point time
|
|
static double close_end_down_price = 0; // second point price
|
|
static string close_name = "";
|
|
//---
|
|
int limit=prev_calculated-1;
|
|
if(prev_calculated==0)
|
|
{
|
|
limit = 0;
|
|
open_start_time = 0; // first point time ("0" -> D'1970.01.01 00:00:00')
|
|
open_start_up_price = 0; // first point price ("0" -> D'1970.01.01 00:00:00')
|
|
open_end_time = 0; // second point time
|
|
open_end_down_price = 0; // second point price
|
|
open_name = "";
|
|
close_start_time = 0; // first point time ("0" -> D'1970.01.01 00:00:00')
|
|
close_start_up_price = 0; // first point price ("0" -> D'1970.01.01 00:00:00')
|
|
close_end_time = 0; // second point time
|
|
close_end_down_price = 0; // second point price
|
|
close_name = "";
|
|
}
|
|
for(int i=limit;i<rates_total;i++)
|
|
{
|
|
TimeToStruct(time[i],STime);
|
|
long long_time=STime.hour*3600+STime.min*60+STime.sec;
|
|
static int PrevDayOfYear=0;
|
|
if(STime.day_of_year!=PrevDayOfYear)
|
|
{
|
|
open_start_time = 0; // first point time ("0" -> D'1970.01.01 00:00:00')
|
|
open_start_up_price = 0; // first point price ("0" -> D'1970.01.01 00:00:00')
|
|
open_end_time = 0; // second point time
|
|
open_end_down_price = 0; // second point price
|
|
open_name = "";
|
|
close_start_time = 0; // first point time ("0" -> D'1970.01.01 00:00:00')
|
|
close_start_up_price = 0; // first point price ("0" -> D'1970.01.01 00:00:00')
|
|
close_end_time = 0; // second point time
|
|
close_end_down_price = 0; // second point price
|
|
close_name = "";
|
|
}
|
|
PrevDayOfYear=STime.day_of_year;
|
|
//--- rectangle open
|
|
if(open_start<=long_time && long_time<=open_end)
|
|
{
|
|
if(open_start_time==D'1970.01.01 00:00:00')
|
|
{
|
|
open_start_time = time[i];
|
|
open_start_up_price = high[i];
|
|
open_end_time = open_start_time;
|
|
open_end_down_price = low[i];
|
|
open_name = name_open+"_"+TimeToString(open_start_time,TIME_DATE);
|
|
//--- create a rectangle in the sub-window "0"
|
|
RectangleCreate(0,open_name,0,open_start_time,open_start_up_price,open_end_time,open_end_down_price,
|
|
Inp_Rectangle_Open_Color,Inp_Rectangle_Style,Inp_Rectangle_Width,Inp_Rectangle_Fill,Inp_Rectangle_Back,
|
|
Inp_Rectangle_Selection,Inp_Rectangle_Hidden,Inp_Rectangle_ZOrder);
|
|
//--- create a rectangle in the sub-window "1"
|
|
int sub_window = 1;
|
|
double price1 = 90.0;
|
|
double price2 = 10.0;
|
|
RectangleCreate(0,pref_stoch+open_name,sub_window,open_start_time,price1,open_end_time,price2,
|
|
Inp_Rectangle_Open_Color,Inp_Rectangle_Style,Inp_Rectangle_Width,Inp_Rectangle_Fill,Inp_Rectangle_Back,
|
|
Inp_Rectangle_Selection,Inp_Rectangle_Hidden,Inp_Rectangle_ZOrder);
|
|
}
|
|
else
|
|
{
|
|
if(open_end_time<time[i] || open_end_down_price>low[i])
|
|
{
|
|
if(open_end_time<time[i])
|
|
{
|
|
open_end_time=time[i];
|
|
//--- move the rectangle in sub-window Stoch, point index "1"
|
|
double price=10.0;
|
|
RectanglePointChange(0,pref_stoch+open_name,1,open_end_time,price);
|
|
}
|
|
if(open_end_down_price>low[i])
|
|
open_end_down_price=low[i];
|
|
RectanglePointChange(0,open_name,1,open_end_time,open_end_down_price);
|
|
}
|
|
if(open_start_up_price<high[i])
|
|
{
|
|
open_start_up_price=high[i];
|
|
RectanglePointChange(0,open_name,0,open_start_time,open_start_up_price);
|
|
}
|
|
}
|
|
}
|
|
//--- rectangle close
|
|
if(close_start<=long_time && long_time<=close_end)
|
|
{
|
|
if(close_start_time==D'1970.01.01 00:00:00')
|
|
{
|
|
close_start_time = time[i];
|
|
close_start_up_price = high[i];
|
|
close_end_time = open_start_time;
|
|
close_end_down_price = low[i];
|
|
close_name = name_close+"_"+TimeToString(close_start_time,TIME_DATE);
|
|
//--- create a rectangle in the sub-window "0"
|
|
RectangleCreate(0,close_name,0,close_start_time,close_start_up_price,close_end_time,close_end_down_price,
|
|
Inp_Rectangle_Close_Color,Inp_Rectangle_Style,Inp_Rectangle_Width,Inp_Rectangle_Fill,Inp_Rectangle_Back,
|
|
Inp_Rectangle_Selection,Inp_Rectangle_Hidden,Inp_Rectangle_ZOrder);
|
|
//--- create a rectangle in the sub-window "1"
|
|
int sub_window = 1;
|
|
double price1 = 90.0;
|
|
double price2 = 10.0;
|
|
RectangleCreate(0,pref_stoch+close_name,sub_window,close_start_time,price1,close_end_time,price2,
|
|
Inp_Rectangle_Close_Color,Inp_Rectangle_Style,Inp_Rectangle_Width,Inp_Rectangle_Fill,Inp_Rectangle_Back,
|
|
Inp_Rectangle_Selection,Inp_Rectangle_Hidden,Inp_Rectangle_ZOrder);
|
|
}
|
|
else
|
|
{
|
|
if(close_end_time<time[i] || close_end_down_price>low[i])
|
|
{
|
|
if(close_end_time<time[i])
|
|
{
|
|
close_end_time=time[i];
|
|
//--- move the rectangle in sub-window Stoch, point index "1"
|
|
double price=10.0;
|
|
RectanglePointChange(0,pref_stoch+close_name,1,close_end_time,price);
|
|
}
|
|
if(close_end_down_price>low[i])
|
|
close_end_down_price=low[i];
|
|
RectanglePointChange(0,close_name,1,close_end_time,close_end_down_price);
|
|
}
|
|
if(close_start_up_price<high[i])
|
|
{
|
|
close_start_up_price=high[i];
|
|
RectanglePointChange(0,close_name,0,close_start_time,close_start_up_price);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//--- return value of prev_calculated for next call
|
|
return(rates_total);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Create rectangle by the given coordinates |
|
|
//+------------------------------------------------------------------+
|
|
bool RectangleCreate(const long chart_ID=0, // chart's ID
|
|
const string name="Rectangle", // rectangle name
|
|
const int sub_window=0, // subwindow index
|
|
datetime time1=0, // first point time
|
|
double price1=0, // first point price
|
|
datetime time2=0, // second point time
|
|
double price2=0, // second point price
|
|
const color clr=clrRed, // rectangle color
|
|
const ENUM_LINE_STYLE style=STYLE_SOLID, // style of rectangle lines
|
|
const int width=1, // width of rectangle lines
|
|
const bool fill=false, // filling rectangle with color
|
|
const bool back=false, // in the background
|
|
const bool selection=true, // highlight to move
|
|
const bool hidden=true, // hidden in the object list
|
|
const long z_order=0) // priority for mouse click
|
|
{
|
|
////--- set anchor points' coordinates if they are not set
|
|
//ChangeRectangleEmptyPoints(time1,price1,time2,price2);
|
|
//--- reset the error value
|
|
ResetLastError();
|
|
//--- create a rectangle by the given coordinates
|
|
if(!ObjectCreate(chart_ID,name,OBJ_RECTANGLE,sub_window,time1,price1,time2,price2))
|
|
{
|
|
Print(__FUNCTION__,
|
|
": failed to create a rectangle! Error code = ",GetLastError());
|
|
return(false);
|
|
}
|
|
//--- set rectangle color
|
|
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
|
|
//--- set the style of rectangle lines
|
|
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
|
|
//--- set width of the rectangle lines
|
|
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
|
|
//--- enable (true) or disable (false) the mode of filling the rectangle
|
|
ObjectSetInteger(chart_ID,name,OBJPROP_FILL,fill);
|
|
//--- display in the foreground (false) or background (true)
|
|
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
|
|
//--- enable (true) or disable (false) the mode of highlighting the rectangle for moving
|
|
//--- when creating a graphical object using ObjectCreate function, the object cannot be
|
|
//--- highlighted and moved by default. Inside this method, selection parameter
|
|
//--- is true by default making it possible to highlight and move the object
|
|
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
|
|
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
|
|
//--- hide (true) or display (false) graphical object name in the object list
|
|
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
|
|
//--- set the priority for receiving the event of a mouse click in the chart
|
|
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
|
|
//--- successful execution
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Move the rectangle anchor point |
|
|
//+------------------------------------------------------------------+
|
|
bool RectanglePointChange(const long chart_ID=0, // chart's ID
|
|
const string name="Rectangle", // rectangle name
|
|
const int point_index=0, // anchor point index
|
|
datetime time=0, // anchor point time coordinate
|
|
double price=0) // anchor point price coordinate
|
|
{
|
|
//--- if point position is not set, move it to the current bar having Bid price
|
|
if(!time)
|
|
time=TimeCurrent();
|
|
if(!price)
|
|
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
|
|
//--- reset the error value
|
|
ResetLastError();
|
|
//--- move the anchor point
|
|
if(!ObjectMove(chart_ID,name,point_index,time,price))
|
|
{
|
|
Print(__FUNCTION__,
|
|
": failed to move the anchor point! Error code = ",GetLastError());
|
|
return(false);
|
|
}
|
|
//--- successful execution
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|