#property copyright "Copyright 2022, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "AutoFib TradeZones "
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_label1 "High"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrLime
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
#property indicator_label2 "Low"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrRed
#property indicator_style2 STYLE_SOLID
#property indicator_width2 1
input int Fib_Period = 240;
input bool Show_StartLine = false;
input bool Show_EndLine = false;
input bool Show_Channel = false;
input int Fib_Style = 5;
input color Fib_Color = Gold;
input color StartLine_Color = RoyalBlue;
input color EndLine_Color = FireBrick;
input color BuyZone_Color = MidnightBlue;
input color SellZone_Color = FireBrick;
//---- buffers
double WWBuffer1[];
double WWBuffer2[];
double level_array[10]={0,0.236,0.382,0.5,0.618,0.764,1,1.618,2.618,4.236};
string leveldesc_array[13]={"0","23.6%","38.2%","50%","61.8%","76.4%","100%","161.8%","261.80%","423.6%"};
int level_count;
string level_name;
string StartLine = "Start Line";
string EndLine = "End Line";
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
if (Show_Channel)
{
SetIndexBuffer(0, WWBuffer1);
SetIndexBuffer(1, WWBuffer2);
}
IndicatorSetInteger(INDICATOR_DIGITS,Digits());
ObjectCreate(0,"FibLevels", OBJ_FIBO, 0, iTime(_Symbol, PERIOD_CURRENT, 0) ,iHigh(_Symbol, PERIOD_CURRENT, 0) ,iTime(_Symbol,PERIOD_CURRENT, 0) ,iLow(_Symbol, PERIOD_CURRENT, 0));
ObjectCreate(0, "BuyZone", OBJ_RECTANGLE, 0,0,0,0);
ObjectCreate(0, "SellZone", OBJ_RECTANGLE, 0,0,0,0);
if (Show_StartLine)
{if (ObjectFind(0, StartLine)==-1)
{
ObjectCreate(0, StartLine,OBJ_VLINE,0,iTime(_Symbol, PERIOD_CURRENT,Fib_Period) ,iClose(_Symbol, PERIOD_CURRENT, 0));
ObjectSetInteger(0, StartLine,OBJPROP_COLOR,StartLine_Color);
ObjectSetInteger(0, StartLine,OBJPROP_WIDTH ,5);
ObjectSetInteger(0, StartLine,OBJPROP_SELECTABLE ,true);
}
}
if (Show_EndLine)
{if (ObjectFind(0, EndLine)==-1)
{
ObjectCreate(0, EndLine,OBJ_VLINE,0,iTime(_Symbol,PERIOD_CURRENT,0) ,iClose(_Symbol, PERIOD_CURRENT, 0));
ObjectSetInteger(0, EndLine,OBJPROP_COLOR,EndLine_Color);
ObjectSetInteger(0, EndLine,OBJPROP_WIDTH ,5);
ObjectSetInteger(0, EndLine,OBJPROP_SELECTABLE,true);
}
}
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason)
{
ObjectDelete(0, "FibLevels");
ObjectDelete(0, "BuyZone");
ObjectDelete(0, "SellZone");
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const int begin,
const double &price[])
{
//---
//Start Line -------------------------------------------
int BarShift;
if (Show_StartLine)
{
datetime HLineTime=ObjectGetValueByTime(0, StartLine, OBJPROP_TIME, 0);
if (HLineTime>=iTime(_Symbol,PERIOD_CURRENT,0)) {
BarShift=0;
}
BarShift=iBarShift(NULL,0,HLineTime);
}
else if (!Show_StartLine){BarShift=0;}
if (ObjectFind(0, StartLine)==-1) {BarShift=0;}
//End Line -------------------------------------------
int BarShift2;
if (Show_EndLine)
{
datetime HLine2Time=ObjectGetTimeByValue(0,EndLine,OBJPROP_TIME, 0);
Print(HLine2Time);
if (HLine2Time>=iTime(_Symbol, PERIOD_CURRENT, 0)) {
BarShift2=0;
}
BarShift2=iBarShift(NULL,0,HLine2Time);
}
else if (!Show_EndLine){
BarShift2=0;
}
if (ObjectFind(0, EndLine)==-1) {
BarShift2=0;
}
//----------------------------------------------------------
double SellZoneHigh,BuyZoneLow;
if (Show_StartLine) {
SellZoneHigh = iHigh(_Symbol,0,iHighest(_Symbol,0,MODE_HIGH,BarShift-BarShift2,BarShift2+1));
BuyZoneLow = iLow(_Symbol,0,iLowest(_Symbol,0,MODE_LOW,BarShift-BarShift2,BarShift2+1));
}
if (!Show_StartLine) {
SellZoneHigh = iHigh(_Symbol,0,iHighest(_Symbol,0,MODE_HIGH,Fib_Period,1));
BuyZoneLow = iLow(_Symbol,0,iLowest(_Symbol,0,MODE_LOW,Fib_Period,1));
}
double PriceRange = SellZoneHigh - BuyZoneLow;
double BuyZoneHigh = BuyZoneLow + (0.236*PriceRange);
double SellZoneLow = SellZoneHigh - (0.236*PriceRange);
datetime StartZoneTime =iTime(_Symbol,PERIOD_CURRENT, Fib_Period);
datetime EndZoneTime =iTime(_Symbol, PERIOD_CURRENT, 0) +iTime(_Symbol, PERIOD_CURRENT, 0);
level_count=ArraySize(level_array);
int bars;
int counted_bars=prev_calculated;
int limit,i;
bars=rates_total-1;
if(counted_bars>0) counted_bars--;
limit=bars-counted_bars;
for(i=limit-1; i>=0; i--) {
WWBuffer1[i] = getPeriodHigh(Fib_Period,i);
WWBuffer2[i] = getPeriodLow(Fib_Period,i);
if (Show_StartLine)
{
ObjectSetInteger(0, "FibLevels", OBJPROP_TIME, 0, iTime(_Symbol, PERIOD_CURRENT,BarShift));
ObjectSetInteger(0,"FibLevels", OBJPROP_TIME, 1, iTime(_Symbol, PERIOD_CURRENT, BarShift2));
}
if (!Show_StartLine) {
ObjectSetInteger(0,"FibLevels", OBJPROP_TIME, 0, StartZoneTime);}
ObjectSetInteger(0,"FibLevels", OBJPROP_TIME, 1, iTime(_Symbol, PERIOD_CURRENT, 0));
if (iOpen(_Symbol, PERIOD_CURRENT, Fib_Period) < iOpen(_Symbol, PERIOD_CURRENT, 0)) // Up
{
if (Show_StartLine) {
ObjectSetDouble(0,"FibLevels", OBJPROP_PRICE,0, SellZoneHigh);
ObjectSetDouble(0,"FibLevels", OBJPROP_PRICE,1, BuyZoneLow);
}
if (!Show_StartLine) {
ObjectSetDouble(0,"FibLevels", OBJPROP_PRICE, 0, getPeriodHigh(Fib_Period,i));
ObjectSetDouble(0,"FibLevels", OBJPROP_PRICE,1, getPeriodLow(Fib_Period,i));
}
} else {
if (Show_StartLine) {
ObjectSetDouble(0,"FibLevels", OBJPROP_PRICE,0, BuyZoneLow);
ObjectSetDouble(0,"FibLevels", OBJPROP_PRICE, 1, SellZoneHigh);
}
if (!Show_StartLine) {
ObjectSetDouble(0,"FibLevels", OBJPROP_PRICE, 0, getPeriodLow(Fib_Period,i));
ObjectSetDouble(0,"FibLevels", OBJPROP_PRICE, 1, getPeriodHigh(Fib_Period,i));
}
}
ObjectSetInteger(0,"FibLevels", OBJPROP_LEVELCOLOR, Fib_Color);
ObjectSetInteger(0,"FibLevels", OBJPROP_STYLE, Fib_Style);
//ObjectSetInteger(0,"FibLevels", OBJ_FIBO, level_count);
for(int j=0; j<level_count; j++) {
//ObjectSetInteger(0,ObjectSetInteger(0,"FibLevels", OBJPROP_FIRSTLEVEL+j, level_array[j]);
ObjectSetDouble(0,"FibLevels",OBJPROP_LEVELVALUE,j,level_array[j]);
ObjectSetString(0,"FibLevels" ,OBJPROP_TEXT, j, leveldesc_array[j]);
}
if (Show_StartLine) {
ObjectSetInteger(0,"BuyZone", OBJPROP_TIME, 1, iTime(_Symbol,PERIOD_CURRENT,BarShift));
ObjectSetInteger(0,"BuyZone", OBJPROP_TIME,0, iTime(_Symbol,PERIOD_CURRENT,BarShift2));
}
if (!Show_StartLine) {
ObjectSetInteger(0,"BuyZone", OBJPROP_TIME, 1, StartZoneTime);
}
ObjectSetInteger(0,"BuyZone", OBJPROP_TIME, 0, EndZoneTime);
ObjectSetDouble(0,"BuyZone", OBJPROP_PRICE,0, BuyZoneLow);
ObjectSetDouble(0,"BuyZone", OBJPROP_PRICE, 1,BuyZoneHigh);
ObjectSetInteger(0,"BuyZone", OBJPROP_COLOR, BuyZone_Color);
if (Show_StartLine) {
ObjectSetInteger(0,"SellZone", OBJPROP_TIME, 1, iTime(_Symbol, PERIOD_CURRENT,BarShift));
ObjectSetInteger(0,"SellZone", OBJPROP_TIME,0, iTime(_Symbol, PERIOD_CURRENT,BarShift2));
}
if (!Show_StartLine) {
ObjectSetInteger(0,"SellZone", OBJPROP_TIME,1, StartZoneTime);
}
ObjectSetInteger(0,"SellZone", OBJPROP_TIME,0, EndZoneTime);
ObjectSetDouble(0,"SellZone", OBJPROP_PRICE,0, SellZoneLow);
ObjectSetDouble(0,"SellZone", OBJPROP_PRICE, 1, SellZoneHigh);
ObjectSetInteger(0,"SellZone", OBJPROP_COLOR, SellZone_Color);
}
//--- return value of prev_calculated for next call
return(rates_total);
}
double getPeriodHigh(int period, int pos)
{
double buffer = 0;
for (int i=pos;i<=pos+period;i++)
{
if (iHigh(_Symbol, PERIOD_CURRENT, i) > buffer)
{
buffer = iHigh(_Symbol, PERIOD_CURRENT, i);
}
else {
if (iOpen(_Symbol, PERIOD_CURRENT, i) > iClose(_Symbol, PERIOD_CURRENT, i)) // Down
{
if (iOpen(_Symbol, PERIOD_CURRENT, i) > buffer)
{
buffer = iOpen(_Symbol, PERIOD_CURRENT, i);
}
}
}
}
return (buffer);
}
double getPeriodLow(int period, int pos) {
double buffer = 100000;
for (int i=pos;i<=pos+period;i++)
{
if (iLow(_Symbol, PERIOD_CURRENT, i) < buffer)
{
buffer = iLow(_Symbol, PERIOD_CURRENT, i);
}
else {
if (iOpen(_Symbol, PERIOD_CURRENT, i) > iClose(_Symbol, PERIOD_CURRENT, i)) // Down
{
if (iClose(_Symbol, PERIOD_CURRENT, i) < buffer)
{
buffer = iClose(_Symbol, PERIOD_CURRENT, i);
}
} else {
if (iOpen(_Symbol, PERIOD_CURRENT, i) < buffer) {
buffer = iOpen(_Symbol, PERIOD_CURRENT, i);
}
}
}
}
return (buffer);
}