Sinewave3
Download scriptThis script is designed to analyze market trends by identifying and visualizing underlying cyclical patterns in price movements. Based on mathematical principles from cybernetics analysis, it aims to strip away "market noise" to reveal the periodic waves that often govern financial assets.
Core Logic and Functionality
1. Data Smoothing and Cycle Identification The script begins by processing raw market data (the high and low prices) to create a balanced average. It then applies a smoothing filter to this data. The primary goal of this stage is to remove erratic, short-term price fluctuations, making it easier to see the broader "cycles" or waves within the market.
2. Sine Wave Generation Once the cycle is identified, the tool calculates a Sine Wave. In technical terms, this represents the rhythmic motion of the market—moving from peaks to troughs in a predictable, wave-like fashion.
- The Sine Wave: Represents the current phase of the market cycle.
- The Lead Sine Wave: This is a projected version of the wave that is shifted forward. By comparing the current wave to this "leading" wave, the script attempts to anticipate where the price might be heading next.
3. Phase and Period Analysis The logic includes complex calculations to determine the "Phase" (where we are in the current cycle) and the "Period" (how long a full cycle takes). It calculates these values dynamically so that the indicator can adapt as market conditions change. By understanding the phase, the script determines whether the market is currently in an expansionary, contractionary, or transitionary state.
4. Automated Support and Resistance Detection Beyond just drawing waves, the script includes a proactive visual aid for identifying key price levels:
- Cross-over Detection: The script monitors the relationship between the Sine Wave and the Lead Sine Wave.
- Trend Line Drawing: When specific crossovers occur (indicating a shift in momentum or a potential reversal), the script automatically identifies recent price highs and lows. It then draws visual trend lines on the chart to highlight these "Support" and "Resistance" zones.
- Green Solid Lines: Generally indicate detected support levels.
- Red Dotted Lines: Generally indicate detected resistance levels.
Summary for the User
Instead of just showing you raw price action, this tool attempts to "deconstruct" the market into its component waves. It helps traders see the rhythm of the price movement, predicts potential shifts using a leading wave, and automatically marks key horizontal zones where price has historically reacted, providing a clearer map of the current market structure.
//+------------------------------------------------------------------+
//| Sinewave3.mq4 |
//| |
//| Sinewave |
//| |
//| Algorithm taken from book |
//| "Cybernetics Analysis for Stock and Futures" |
//| by John F. Ehlers |
//| |
//| contact@mqlsoft.com |
//| http://www.mqlsoft.com/ |
//| - changed by Igorad, www.forex-tsd.com |
//+------------------------------------------------------------------+
#property copyright "Coded by Witold Wozniak"
#property link "www.mqlsoft.com"
#property indicator_separate_window
#property indicator_buffers 3
#property indicator_color1 Red
#property indicator_color2 Blue
#property indicator_color3 Yellow
#property indicator_minimum -1
#property indicator_maximum 1
#property indicator_level1 0
double Sine[];
double LeadSine[];
double Cycle[];
double Smooth[];
double Resistance[];
extern double Alpha = 0.07;
extern bool DrawPriceTrendLines = true;
int buffers = 0;
int drawBegin = 0;
double tempReal, rad2Deg, deg2Rad, label;
int ilow, ihigh;
int init() {
drawBegin = 8;
initBuffer(Sine, "Sine", DRAW_LINE);
initBuffer(LeadSine, "Lead", DRAW_LINE);
initBuffer(Cycle);
initBuffer(Smooth);
initBuffer(Resistance, "ResisT",DRAW_ARROW, STYLE_DASHDOT,1);
IndicatorBuffers(buffers);
IndicatorShortName("Sinewave 2[" + DoubleToStr(Alpha, 2) + "]");
tempReal = MathArctan(1.0);
rad2Deg = 45.0 / tempReal;
deg2Rad = 1.0 / rad2Deg;
return (0);
}
int deinit()
{
for(int i = ObjectsTotal() - 1; i >= 0; i--)
{
string label = ObjectName(i);
if(StringSubstr(label, 0, 18) != "Support Resistance")
continue;
ObjectDelete(label);
}
return(0);
}
int start() {
if (Bars <= drawBegin) return (0);
int countedBars = IndicatorCounted(), currents;
if (countedBars < 0) return (-1);
if (countedBars > 0) countedBars--;
int s, limit = Bars - countedBars - 1, Flagup,Flagdn;
currents=s;
for (s = limit; s >= 0; s--) {
Smooth[s] = (P(s) + 2.0 * P(s + 1) + 2.0 * P(s + 2) + P(s + 3)) / 6.0;
Cycle[s] = (1.0 - 0.5 * Alpha) * (1.0 - 0.5 * Alpha) * (Smooth[s] - 2.0 * Smooth[s + 1] + Smooth[s + 2])
+ 2.0 * (1.0 - Alpha) * Cycle[s + 1]
- (1.0 - Alpha) * (1.0 - Alpha) * Cycle[s + 2];
double period = iCustom(0, 0, "CyclePeriod", Alpha, 0, s);
int DCPeriod = MathFloor(period);
double RealPart = 0.0;
double ImagPart = 0.0;
for (int count = 0; count < DCPeriod; count++) {
RealPart += MathSin(deg2Rad * 360.0 * count / DCPeriod) * Cycle[s + count];
ImagPart += MathCos(deg2Rad * 360.0 * count / DCPeriod) * Cycle[s + count];
}
double DCPhase;
if (MathAbs(ImagPart) > 0.0000001) {
DCPhase = rad2Deg * MathArctan(RealPart / ImagPart);
} else if (MathAbs(ImagPart) <= 0.0000001) {
if (RealPart >= 0.0) {
DCPhase = 90.0;
} else {
DCPhase = -90.0;
}
}
DCPhase += 90.0;
if (ImagPart < 0) {
DCPhase += 180.0;
}
if (DCPhase > 315.0) {
DCPhase -= 360.0;
}
Sine[s] = MathSin(DCPhase * deg2Rad);
LeadSine[s] = MathSin((DCPhase + 45.0) * deg2Rad);
if (DCPhase == 180 && LeadSine[s + 1] > 0) {
LeadSine[s] = MathSin(45 * deg2Rad);
}
if (DCPhase == 0 && LeadSine[s + 1] < 0) {
LeadSine[s] = MathSin(225 * deg2Rad);
}
//Attemp to draw a resistance suport line at cross over
if (DrawPriceTrendLines == true)
if (LeadSine[s] > Sine[s] && LeadSine[s+1] < Sine[s+1] )
{
ilow = s;
int lobar = iLowest(NULL,0,MODE_LOW,ihigh-s, s);
double lo = Low[lobar];
DrawPriceTrendLines(Time[lobar], Time[s+1],
lo, lo, Green, STYLE_SOLID);
//Print(" s-hi=", s - ihigh);
}
if (LeadSine[s] < Sine[s] && LeadSine[s+1] > Sine[s+1] )
{
ihigh = s;
int hibar = iHighest(NULL,0,MODE_HIGH,ilow-s, s);
double hi = High[hibar];
DrawPriceTrendLines(Time[hibar], Time[s+1],
hi, hi, Red,STYLE_DOT);
//Print(" s-lo=", s - ilow);
}
}
return (0);
}
double P(int index) {
return ((High[index] + Low[index]) / 2.0);
}
void initBuffer(double array[], string label = "", int type = DRAW_NONE, int arrow = 0, int style = EMPTY, int width = EMPTY, color clr = CLR_NONE) {
SetIndexBuffer(buffers, array);
SetIndexLabel(buffers, label);
SetIndexEmptyValue(buffers, EMPTY_VALUE);
SetIndexDrawBegin(buffers, drawBegin);
SetIndexShift(buffers, 0);
SetIndexStyle(buffers, type, style, width);
SetIndexArrow(buffers, arrow);
buffers++;
}
void DrawPriceTrendLines(datetime x1, datetime x2, double y1,
double y2, color lineColor, double style)
{
string label = "Support Resistance" + DoubleToStr(x1, 0);
ObjectDelete(label);
ObjectCreate(label, OBJ_TREND, 0, x1, y1, x2, y2, 0, 0);
ObjectSet(label, OBJPROP_RAY, 0);
ObjectSet(label, OBJPROP_COLOR, lineColor);
ObjectSet(label, OBJPROP_STYLE, style);
ObjectSet(label, OBJPROP_WIDTH, 3);
}
Comments