292 lines
23 KiB
MQL5
292 lines
23 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| One Candle Theory Signals.mq5 |
|
|
//| Copyright 2025, ElOportunista |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Copyright 2025, ElOportunista"
|
|
#property link "https://www.mql5.com"
|
|
#property version "1.00"
|
|
#property indicator_chart_window
|
|
#property indicator_buffers 2
|
|
#property indicator_plots 2
|
|
|
|
#property indicator_label1 "Buy Signal"
|
|
#property indicator_type1 DRAW_ARROW
|
|
#property indicator_color1 clrLime
|
|
#property indicator_width1 3
|
|
|
|
#property indicator_label2 "Sell Signal"
|
|
#property indicator_type2 DRAW_ARROW
|
|
#property indicator_color2 clrRed
|
|
#property indicator_width2 3
|
|
|
|
input int Maperiod = 20;
|
|
input bool Use_MediaMovil = false;
|
|
input int MinCandleSize = 200;
|
|
input double MinPurpleZone = 50;
|
|
input double MaxPurpleZonePercent = 80;
|
|
input bool ShowAlerts = true;
|
|
input bool DrawLevels = true;
|
|
input bool See_text = true;
|
|
input int mult = 2;
|
|
|
|
//--- indicator buffers
|
|
double BuySignalBuffer[];
|
|
double SellSignalBuffer[];
|
|
|
|
//--- global variables
|
|
datetime lastProcessedH4 = 0;
|
|
string symbol;
|
|
int digits;
|
|
double mypoint;
|
|
int emaHandle;
|
|
|
|
//+------------------------------------------------------------------+
|
|
int OnInit()
|
|
{
|
|
SetIndexBuffer(0, BuySignalBuffer, INDICATOR_DATA);
|
|
SetIndexBuffer(1, SellSignalBuffer, INDICATOR_DATA);
|
|
|
|
PlotIndexSetInteger(0, PLOT_ARROW, 233);
|
|
PlotIndexSetInteger(1, PLOT_ARROW, 234);
|
|
|
|
PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 0.0);
|
|
PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, 0.0);
|
|
|
|
ArraySetAsSeries(BuySignalBuffer, true);
|
|
ArraySetAsSeries(SellSignalBuffer, true);
|
|
|
|
symbol = _Symbol;
|
|
digits = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS);
|
|
mypoint = SymbolInfoDouble(symbol, SYMBOL_POINT);
|
|
|
|
if(digits % 2 == 1)
|
|
mypoint *= 10;
|
|
|
|
if(Use_MediaMovil)
|
|
{
|
|
emaHandle = iMA(symbol, PERIOD_H4, Maperiod, 0, MODE_EMA, PRICE_CLOSE);
|
|
if(emaHandle == INVALID_HANDLE)
|
|
return(INIT_FAILED);
|
|
}
|
|
|
|
Print("Indicador iniciado en ", EnumToString(Period()), " - Analizando H4");
|
|
|
|
return(INIT_SUCCEEDED);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
void OnDeinit(const int reason)
|
|
{
|
|
ObjectsDeleteAll(0, "OCT_", 0, -1);
|
|
|
|
if(Use_MediaMovil && emaHandle != INVALID_HANDLE)
|
|
IndicatorRelease(emaHandle);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
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[])
|
|
{
|
|
ArraySetAsSeries(time, true);
|
|
|
|
|
|
datetime currentH4Time = iTime(symbol, PERIOD_H4, 1);
|
|
|
|
|
|
if(currentH4Time != lastProcessedH4)
|
|
{
|
|
|
|
DrawH4Analysis(currentH4Time);
|
|
lastProcessedH4 = currentH4Time;
|
|
}
|
|
|
|
return(rates_total);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
void DrawH4Analysis(datetime h4Time)
|
|
{
|
|
datetime temp = iTime(symbol, PERIOD_H4, 1);
|
|
double hi = iHigh(symbol, PERIOD_H4, 1);
|
|
double lo = iLow(symbol, PERIOD_H4, 1);
|
|
double op = iOpen(symbol, PERIOD_H4, 1);
|
|
double cl = iClose(symbol, PERIOD_H4, 1);
|
|
|
|
datetime temp2 = iTime(symbol, PERIOD_H4, 2);
|
|
double hi2 = iHigh(symbol, PERIOD_H4, 2);
|
|
double lo2 = iLow(symbol, PERIOD_H4, 2);
|
|
|
|
datetime tempw = iTime(symbol, PERIOD_W1, 1);
|
|
double hiw = iHigh(symbol, PERIOD_W1, 1);
|
|
double lo_w = iLow(symbol, PERIOD_W1, 1);
|
|
|
|
datetime tempd = iTime(symbol, PERIOD_D1, 1);
|
|
double hid = iHigh(symbol, PERIOD_D1, 1);
|
|
double lod = iLow(symbol, PERIOD_D1, 1);
|
|
|
|
double candlesize = (hi - lo) / mypoint;
|
|
double purpleZoneUp = (cl - lo) / mypoint;
|
|
double purpleZoneDn = (hi - cl) / mypoint;
|
|
|
|
if(candlesize < MinCandleSize) return;
|
|
|
|
if(DrawLevels)
|
|
{
|
|
string suffix = TimeToString(temp, TIME_DATE|TIME_MINUTES);
|
|
|
|
TrendCreate(0, "OCT_trendwhi_"+suffix, 0, tempw, hiw, tempw + 2*PeriodSeconds(PERIOD_W1), hiw, clrGray, STYLE_SOLID, 1, false);
|
|
TrendCreate(0, "OCT_trendwlo_"+suffix, 0, tempw, lo_w, tempw + 2*PeriodSeconds(PERIOD_W1), lo_w, clrGray, STYLE_SOLID, 1, false);
|
|
|
|
TrendCreate(0, "OCT_trenddhi_"+suffix, 0, tempd, hid, tempd + 4*PeriodSeconds(PERIOD_D1), hid, clrDodgerBlue, STYLE_SOLID, 1, false);
|
|
TrendCreate(0, "OCT_trenddlo_"+suffix, 0, tempd, lod, tempd + 4*PeriodSeconds(PERIOD_D1), lod, clrDodgerBlue, STYLE_SOLID, 1, false);
|
|
|
|
if(See_text)
|
|
{
|
|
TextCreate(0, "OCT_text1_"+suffix, 0, tempw+PeriodSeconds(PERIOD_W1), hiw+10*mypoint, "Weekly High: "+DoubleToString(hiw,digits), "Arial", 8, clrWhite);
|
|
TextCreate(0, "OCT_text2_"+suffix, 0, tempw+PeriodSeconds(PERIOD_W1), lo_w-5*mypoint, "Weekly Low: "+DoubleToString(lo_w,digits), "Arial", 8, clrWhite);
|
|
TextCreate(0, "OCT_text3_"+suffix, 0, tempd+PeriodSeconds(PERIOD_D1), hid+10*mypoint, "Daily High: "+DoubleToString(hid,digits), "Arial", 8, clrWhite);
|
|
TextCreate(0, "OCT_text4_"+suffix, 0, tempd+PeriodSeconds(PERIOD_D1), lod-5*mypoint, "Daily Low: "+DoubleToString(lod,digits), "Arial", 8, clrWhite);
|
|
}
|
|
}
|
|
|
|
bool isBullish = (cl >= op);
|
|
double purpleZone = isBullish ? purpleZoneUp : purpleZoneDn;
|
|
double purplePercent = (candlesize > 0) ? (purpleZone / candlesize) * 100 : 0;
|
|
|
|
// Validar purple zone
|
|
if(purpleZone < MinPurpleZone || purplePercent > MaxPurpleZonePercent) return;
|
|
|
|
// Verificar EMA si está activo
|
|
if(Use_MediaMovil)
|
|
{
|
|
double ema[];
|
|
ArraySetAsSeries(ema, true);
|
|
if(CopyBuffer(emaHandle, 0, 1, 1, ema) > 0)
|
|
{
|
|
if(isBullish && cl < ema[0]) return;
|
|
if(!isBullish && cl > ema[0]) return;
|
|
}
|
|
}
|
|
|
|
string suffix = TimeToString(temp, TIME_DATE|TIME_MINUTES);
|
|
|
|
if(isBullish)
|
|
{
|
|
RectangleCreate(0, "OCT_rect_"+suffix, 0, temp, cl, temp+mult*PeriodSeconds(PERIOD_H4), lo, clrPurple);
|
|
|
|
TrendCreate(0, "OCT_trend1_"+suffix, 0, temp, hi, temp+mult*PeriodSeconds(PERIOD_H4), hi, clrGray, STYLE_SOLID, 1, false);
|
|
TrendCreate(0, "OCT_trend2_"+suffix, 0, temp, lo, temp+mult*PeriodSeconds(PERIOD_H4), lo, clrGray, STYLE_SOLID, 1, false);
|
|
TrendCreate(0, "OCT_trend3_"+suffix, 0, temp, hi2, temp+mult*PeriodSeconds(PERIOD_H4), hi2, clrGray, STYLE_SOLID, 1, false);
|
|
TrendCreate(0, "OCT_trend4_"+suffix, 0, temp, lo2, temp+mult*PeriodSeconds(PERIOD_H4), lo2, clrGray, STYLE_SOLID, 1, false);
|
|
|
|
if(See_text)
|
|
{
|
|
string rangeText = "Range: " + DoubleToString(candlesize, (digits==2||digits==4)?digits:2) + " pips";
|
|
string zoneText = "Zone: " + DoubleToString(purpleZoneUp, (digits==2||digits==4)?digits:2) + " pips";
|
|
|
|
TextCreate(0, "OCT_text5_"+suffix, 0, temp+PeriodSeconds(PERIOD_H1), hi+(5*mypoint), rangeText, "Arial", 8, clrWhite);
|
|
TextCreate(0, "OCT_text6_"+suffix, 0, temp+PeriodSeconds(PERIOD_H1), lo-(5*mypoint), zoneText, "Arial", 8, clrWhite);
|
|
}
|
|
|
|
int barShift = iBarShift(symbol, PERIOD_CURRENT, temp);
|
|
if(barShift >= 0)
|
|
{
|
|
BuySignalBuffer[barShift] = iLow(symbol, PERIOD_CURRENT, barShift) - (10*mypoint);
|
|
}
|
|
|
|
if(ShowAlerts)
|
|
Alert("ONE CANDLE THEORY BUY - ", symbol, " - Range: ", DoubleToString(candlesize,1), " pips");
|
|
}
|
|
else
|
|
{
|
|
RectangleCreate(0, "OCT_rect_"+suffix, 0, temp, cl, temp+mult*PeriodSeconds(PERIOD_H4), hi, clrPurple);
|
|
|
|
TrendCreate(0, "OCT_trend1_"+suffix, 0, temp, hi, temp+mult*PeriodSeconds(PERIOD_H4), hi, clrGray, STYLE_SOLID, 1, false);
|
|
TrendCreate(0, "OCT_trend2_"+suffix, 0, temp, lo, temp+mult*PeriodSeconds(PERIOD_H4), lo, clrGray, STYLE_SOLID, 1, false);
|
|
TrendCreate(0, "OCT_trend3_"+suffix, 0, temp, hi2, temp+mult*PeriodSeconds(PERIOD_H4), hi2, clrGray, STYLE_SOLID, 1, false);
|
|
TrendCreate(0, "OCT_trend4_"+suffix, 0, temp, lo2, temp+mult*PeriodSeconds(PERIOD_H4), lo2, clrGray, STYLE_SOLID, 1, false);
|
|
|
|
if(See_text)
|
|
{
|
|
string rangeText = "Range: " + DoubleToString(candlesize, (digits==2||digits==4)?digits:2) + " pips";
|
|
string zoneText = "Zone: " + DoubleToString(purpleZoneDn, (digits==2||digits==4)?digits:2) + " pips";
|
|
|
|
TextCreate(0, "OCT_text5_"+suffix, 0, temp+PeriodSeconds(PERIOD_H1), hi+(5*mypoint), rangeText, "Arial", 8, clrWhite);
|
|
TextCreate(0, "OCT_text6_"+suffix, 0, temp+PeriodSeconds(PERIOD_H1), lo-(5*mypoint), zoneText, "Arial", 8, clrWhite);
|
|
}
|
|
|
|
int barShift = iBarShift(symbol, PERIOD_CURRENT, temp);
|
|
if(barShift >= 0)
|
|
{
|
|
SellSignalBuffer[barShift] = iHigh(symbol, PERIOD_CURRENT, barShift) + (10*mypoint);
|
|
}
|
|
|
|
if(ShowAlerts)
|
|
Alert("ONE CANDLE THEORY SELL - ", symbol, " - Range: ", DoubleToString(candlesize,1), " pips");
|
|
}
|
|
|
|
ChartRedraw();
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
bool TrendCreate(const long chart_ID, const string name, const int sub_window,
|
|
datetime time1, double price1, datetime time2, double price2,
|
|
const color clr, const ENUM_LINE_STYLE style, const int width,
|
|
const bool ray_right)
|
|
{
|
|
ObjectDelete(chart_ID, name);
|
|
|
|
if(!ObjectCreate(chart_ID, name, OBJ_TREND, sub_window, time1, price1, time2, price2))
|
|
return(false);
|
|
|
|
ObjectSetInteger(chart_ID, name, OBJPROP_COLOR, clr);
|
|
ObjectSetInteger(chart_ID, name, OBJPROP_STYLE, style);
|
|
ObjectSetInteger(chart_ID, name, OBJPROP_WIDTH, width);
|
|
ObjectSetInteger(chart_ID, name, OBJPROP_RAY_RIGHT, ray_right);
|
|
ObjectSetInteger(chart_ID, name, OBJPROP_BACK, true);
|
|
|
|
return(true);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
bool TextCreate(const long chart_ID, const string name, const int sub_window,
|
|
datetime time, double price, const string text, const string font,
|
|
const int font_size, const color clr)
|
|
{
|
|
ObjectDelete(chart_ID, name);
|
|
|
|
if(!ObjectCreate(chart_ID, name, OBJ_TEXT, sub_window, time, price))
|
|
return(false);
|
|
|
|
ObjectSetString(chart_ID, name, OBJPROP_TEXT, text);
|
|
ObjectSetString(chart_ID, name, OBJPROP_FONT, font);
|
|
ObjectSetInteger(chart_ID, name, OBJPROP_FONTSIZE, font_size);
|
|
ObjectSetInteger(chart_ID, name, OBJPROP_COLOR, clr);
|
|
|
|
return(true);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
bool RectangleCreate(const long chart_ID, const string name, const int sub_window,
|
|
datetime time1, double price1, datetime time2, double price2,
|
|
const color clr)
|
|
{
|
|
ObjectDelete(chart_ID, name);
|
|
|
|
if(!ObjectCreate(chart_ID, name, OBJ_RECTANGLE, sub_window, time1, price1, time2, price2))
|
|
return(false);
|
|
|
|
ObjectSetInteger(chart_ID, name, OBJPROP_COLOR, clr);
|
|
ObjectSetInteger(chart_ID, name, OBJPROP_FILL, true);
|
|
ObjectSetInteger(chart_ID, name, OBJPROP_BACK, true);
|
|
|
|
return(true);
|
|
}
|