MagicOscillator1.22
Download scriptThis tool is a technical analysis indicator designed for the MetaTrader platform. It functions as a momentum and trend oscillator, providing visual cues and alerts to help traders identify potential "Buy" and "Sell" opportunities based on price action dynamics.
Core Logic and Mechanism
The script operates by analyzing the relationship between recent price movements and moving averages. Here is a breakdown of how it processes data:
1. Trend Analysis (Moving Averages) The indicator calculates the difference between two different moving averages (a fast period and a slow period). By comparing these two values, the tool determines the current momentum of the market. If the fast moving average is above the slow one, it suggests upward pressure; if it is below, it suggests downward pressure.
2. Price Action "Delta" Calculations Unlike simple indicators that only look at averages, this script examines the high, low, and closing prices of the last three candles. It calculates a "Delta"—essentially a measurement of how much the price has moved relative to its previous boundaries.
- It checks whether the closing price of a candle is in the upper or lower half of its range.
- It then measures the distance between the current price and the previous candle's extremes.
3. Signal Filtering (The "Break" System) The script uses a hierarchical filtering system to determine the final signal. It looks for specific "breaks" in price action across three consecutive time steps.
- It evaluates whether these price breaks align with the momentum indicated by the moving averages.
- If a strong enough price break occurs in the direction of the trend, it prioritizes that signal.
- If no significant "break" is detected in the most recent data, the script falls back to the secondary and tertiary historical points to see if a trend is established there.
4. Final Output Generation The tool translates these complex calculations into two distinct visual histograms:
- Buy Signal: When the conditions favor an upward move (positive momentum combined with bullish price breaks), it populates the Buy histogram.
- Sell Signal: When conditions favor a downward move (negative momentum combined with bearish price breaks), it populates the Sell histogram.
User Alerts
The script includes an automated notification system. It is designed to trigger an alert only when a "flip" occurs—meaning the indicator switches from a Buy state to a Sell state (or vice versa). This prevents the user from receiving repetitive alerts on every single candle, ensuring that notifications only occur at significant turning points in the trend.
//+------------------------------------------------------------------+
//| MagicOscillator1.2.mq4 |
//| zfs |
//| @ |
//+------------------------------------------------------------------+
#property copyright "zfs"
#property link "vasbsm@mail.ru"
//---- indicator settings
#property indicator_separate_window
#property indicator_buffers 3
#property indicator_color2 Red
#property indicator_color3 Blue
#property indicator_width2 5
#property indicator_width3 5
#property indicator_minimum 0
#property indicator_maximum 1
//----
#define SIGNAL_BAR 0
//----
extern bool Alerts=true;
extern int Period1=5;//îñíîâíîé ïåðèîä
extern int Period2=34;//ñãëàæèâàþùèé ïåðèîä
extern int TypeMA=MODE_SMA;//0-3
extern int TypePrice=PRICE_MEDIAN;//0-6
extern int delta1buy=0;//îòêëþ÷åíèå -1
extern int delta1sell=0;//îòêëþ÷åíèå -1
extern int delta2buy=0;//îòêëþ÷åíèå -1
extern int delta2sell=0;//îòêëþ÷åíèå -1
extern int delta3buy=0;//îòêëþ÷åíèå -1
extern int delta3sell=0;//îòêëþ÷åíèå -1
//---- indicator buffers
double TempBuffer[];
double OscBuyBuffer[];
double OscSellBuffer[];
int init()
{
SetIndexStyle(0,DRAW_NONE);
SetIndexStyle(1,DRAW_HISTOGRAM);
SetIndexStyle(2,DRAW_HISTOGRAM);
IndicatorDigits(Digits-2);
SetIndexDrawBegin(0,Period2);
SetIndexDrawBegin(1,Period2);
SetIndexDrawBegin(2,Period2);
SetIndexBuffer(0,TempBuffer);
SetIndexBuffer(1,OscBuyBuffer);
SetIndexBuffer(2,OscSellBuffer);
IndicatorShortName("MAGIC OSCILLATOR 1.22");
SetIndexLabel(1,NULL);
SetIndexLabel(2,NULL);
return(0);
}
int start()
{
int limit;
int counted_bars=IndicatorCounted();
double prev,current;
if(counted_bars>0) counted_bars--;
limit=Bars-counted_bars;
for(int i=0; i<limit; i++)
{
double high3=iHigh(NULL,0,i+3);
double low3=iLow(NULL,0,i+3);
double close3=iClose(NULL,0,i+3);
double high2=iHigh(NULL,0,i+2);
double low2=iLow(NULL,0,i+2);
double close2=iClose(NULL,0,i+2);
double high1=iHigh(NULL,0,i+1);
double low1=iLow(NULL,0,i+1);
double close1=iClose(NULL,0,i+1);
double ao1=iMA(NULL,0,Period1,0,TypeMA,TypePrice,i+1)-iMA(NULL,0,Period2,0,TypeMA,TypePrice,i+1);
double ao0=iMA(NULL,0,Period1,0,TypeMA,TypePrice,i)-iMA(NULL,0,Period2,0,TypeMA,TypePrice,i);
double close0=iClose(NULL,0,i);//òåêóùàÿ öåíà
double deltab1=0;double deltas1=0;
double deltab2=0;double deltas2=0;
double deltab3=0;double deltas3=0;
if (close1>(high1+low1)/2.0)deltab1=close0-high1;
if (close1<(high1+low1)/2.0)deltas1=low1-close0;
if (close2>(high2+low2)/2.0)deltab2=close1-high2;
if (close2<(high2+low2)/2.0)deltas2=low2-close1;
if (close3>(high3+low3)/2.0)deltab3=close2-high3;
if (close3<(high3+low3)/2.0)deltas3=low3-close2;
if (delta1buy==-1)delta1buy=9999;
if (delta2buy==-1)delta2buy=9999;
if (delta3buy==-1)delta3buy=9999;
if (delta1sell==-1)delta1sell=9999;
if (delta2sell==-1)delta2sell=9999;
if (delta3sell==-1)delta3sell=9999;
int Break1=0;
int Break2=0;
int Break3=0;
if (deltas3>delta3sell*Point&&deltas3>=deltab3&&ao0>ao1)Break1=-1;
if (deltab3>delta3buy*Point&&deltab3>=deltas3&&ao0<ao1)Break1=1;
if (deltas2>delta2sell*Point&&deltas2>=deltab2&&ao0>ao1)Break2=-1;
if (deltab2>delta2buy*Point&&deltab2>=deltas2&&ao0<ao1)Break2=1;
if (deltas1>delta1sell*Point&&deltas1>=deltab1&&ao0>ao1)Break3=-1;
if (deltab1>delta1buy*Point&&deltab1>=deltas1&&ao0<ao1)Break3=1;
if (Break1==1)TempBuffer[i]=1;
if (Break1==-1)TempBuffer[i]=-1;
if (Break1==0)
{
if (Break2==1)TempBuffer[i]=1;
if (Break2==-1)TempBuffer[i]=-1;
if (Break2==0)
{
if (Break3==1)TempBuffer[i]=1;
if (Break3==-1)TempBuffer[i]=-1;
if (Break3==0)
{
if (ao0>ao1)TempBuffer[i]=1;
else TempBuffer[i]=-1;
}
}
}
}
for(i=0; i<limit; i++)
{
if (TempBuffer[i]>0)
{
OscBuyBuffer[i]=TempBuffer[i];
OscSellBuffer[i]=0;
}
if (TempBuffer[i]<0)
{
OscSellBuffer[i]=-TempBuffer[i];
OscBuyBuffer[i]=0;
}
}
if (Alerts)
{
//---- Ñòàòè÷åñêèå ïåðåìåííûå, â êîòîðûõ õðàíÿòñÿ
//---- âðåìÿ ïîñëåäíåãî áàðà è íàïðàâëåíèå ïîñëåäíåãî ñèãíàëà
static int PrevSignal = 0, PrevTime = 0;
//---- Åñëè áàðîì äëÿ àíàëèçà âûáðàí íå 0-é, íàì íåò ñìûñëà ïðîâåðÿòü ñèãíàë
//---- íåñêîëüêî ðàç. Åñëè íå íà÷àëñÿ íîâûé áàð, âûõîäèì.
if(SIGNAL_BAR > 0 && Time[0] <= PrevTime )
return(0);
//---- Îòìå÷àåì, ÷òî ýòîò áàð ïðîâåðåí
PrevTime = Time[0];
//---- Åñëè ïðåäûäóùèé ñèãíàë áûë ÑÅËË èëè ýòî ïåðâûé çàïóñê (PrevSignal=0)
if(PrevSignal <= 0)
{
if(OscBuyBuffer[SIGNAL_BAR]> 0 && OscSellBuffer[SIGNAL_BAR+1]> 0)
{
PrevSignal = 1;
Alert("MAGIC (", Symbol(), ", ", Period(), ") - BUY!!!");
}
}
if(PrevSignal >= 0)
{
if(OscSellBuffer[SIGNAL_BAR]> 0 && OscBuyBuffer[SIGNAL_BAR+1]> 0)
{
PrevSignal = -1;
Alert("MAGIC (", Symbol(), ", ", Period(), ") - SELL!!!");
}
}
}
//--
return(0);
}
Comments