- MultiSignal Confluence EA v1.11 (stop loss bug fixed) - Harmonic Pattern Finder v2 (optimized) - Candlestick Pattern EA (fixed) - Pivot Fade EA v4 (fixed) - Bot series (10001, 10002, EnhancedEA) Performance: ~19% return in 2 months on 00k account
1979 lines
218 KiB
Plaintext
Executable File
1979 lines
218 KiB
Plaintext
Executable File
//+------------------------------------------------------------------+
|
|
//| HarmonicPatternFinderV2.mq5 |
|
|
//| Copyright 2016, André S. Enger. |
|
|
//| andre_enger@hotmail.com |
|
|
//| Contribs |
|
|
//| David Gadelha |
|
|
//| dgadelha@gmail.com |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Copyright 2016, Andre S. Enger."
|
|
#property link "andre_enger@hotmail.com"
|
|
#property version "2.0"
|
|
#property description "Indicator to display existent and emerging harmonic chart patterns."
|
|
|
|
#property indicator_chart_window
|
|
#property indicator_buffers 2
|
|
#property indicator_plots 1
|
|
|
|
#property indicator_label1 "Zig Zag"
|
|
#property indicator_type1 DRAW_ZIGZAG
|
|
#property indicator_color1 clrNONE
|
|
#property indicator_style1 STYLE_SOLID
|
|
#property indicator_width1 1
|
|
//--- Describes patterns
|
|
struct PATTERN_DESCRIPTOR
|
|
{
|
|
double ab2xa_min;
|
|
double ab2xa_max;
|
|
double bc2ab_min;
|
|
double bc2ab_max;
|
|
double cd2bc_min;
|
|
double cd2bc_max;
|
|
double ad2xa_min;
|
|
double ad2xa_max;
|
|
double cd2xc_min;
|
|
double cd2xc_max;
|
|
double xc2xa_min;
|
|
double xc2xa_max;
|
|
double cd2ab_min;
|
|
double cd2ab_max;
|
|
};
|
|
//--- Identifies drawn patterns
|
|
struct PATTERN_INSTANCE
|
|
{
|
|
int patternIndex;
|
|
int patternBufferIndex;
|
|
bool bullish;
|
|
bool overlapping;
|
|
datetime XDateTime;
|
|
datetime ADateTime;
|
|
datetime BDateTime;
|
|
datetime CDateTime;
|
|
datetime DDateTime;
|
|
double X;
|
|
double A;
|
|
double B;
|
|
double C;
|
|
double D;
|
|
double PRZ;
|
|
};
|
|
//--- Number keys of patterns
|
|
enum PATTERN_INDEX
|
|
{
|
|
TRENDLIKE1_ABCD=0,
|
|
TRENDLIKE2_ABCD,
|
|
PERFECT_ABCD,
|
|
IDEAL1_ABCD,
|
|
IDEAL2_ABCD,
|
|
RANGELIKE_ABCD,
|
|
ALT127_TRENDLIKE1_ABCD,
|
|
ALT127_TRENDLIKE2_ABCD,
|
|
ALT127_PERFECT_ABCD,
|
|
ALT127_IDEAL1_ABCD,
|
|
ALT127_IDEAL2_ABCD,
|
|
ALT127_RANGELIKE_ABCD,
|
|
REC_TRENDLIKE1_ABCD,
|
|
REC_TRENDLIKE2_ABCD,
|
|
REC_PERFECT_ABCD,
|
|
REC_IDEAL1_ABCD,
|
|
REC_IDEAL2_ABCD,
|
|
REC_RANGELIKE_ABCD,
|
|
GARTLEY,
|
|
BAT,
|
|
ALTBAT,
|
|
FIVEO,
|
|
BUTTERFLY,
|
|
CRAB,
|
|
DEEPCRAB,
|
|
THREEDRIVES,
|
|
CYPHER,
|
|
SHARK,
|
|
NENSTAR,
|
|
BLACKSWAN,
|
|
WHITESWAN,
|
|
ONE2ONE,
|
|
NEWCYPHER,
|
|
NAVARRO200,
|
|
LEONARDO,
|
|
KANE,
|
|
GARFLY,
|
|
MAXBAT,
|
|
MAXGARTLEY,
|
|
MAXBUTTERFLY,
|
|
GARTLEY113,
|
|
BUTTERFLY113,
|
|
ANTI_GARTLEY,
|
|
ANTI_BAT,
|
|
ANTI_ALTBAT,
|
|
ANTI_FIVEO,
|
|
ANTI_BUTTERFLY,
|
|
ANTI_CRAB,
|
|
ANTI_DEEPCRAB,
|
|
ANTI_THREEDRIVES,
|
|
ANTI_CYPHER,
|
|
ANTI_SHARK,
|
|
ANTI_NENSTAR,
|
|
ANTI_BLACKSWAN,
|
|
ANTI_WHITESWAN,
|
|
ANTI_ONE2ONE,
|
|
ANTI_NEWCYPHER,
|
|
ANTI_NAVARRO200,
|
|
ANTI_LEONARDO,
|
|
ANTI_KANE,
|
|
ANTI_GARFLY,
|
|
ANTI_MAXBAT,
|
|
ANTI_MAXGARTLEY,
|
|
ANTI_MAXBUTTERFLY,
|
|
ANTI_GARTLEY113,
|
|
ANTI_BUTTERFLY113,
|
|
};
|
|
//--- ZigZag selection
|
|
enum ZIGZAGTYPE
|
|
{
|
|
FASTZZ,//Fast ZZ
|
|
ALEXSTAL,//Alexstal ZZ
|
|
SWINGCHART //Swing ZZ
|
|
};
|
|
|
|
//--- Constants and macros
|
|
#define SIZE_PATTERN_BUFFER 10
|
|
#define NUM_PATTERNS 66
|
|
#define NON_EXISTENT_DATETIME D'19.07.1980 12:30:27'
|
|
|
|
const string _identifier="HPF";
|
|
|
|
//--- User Inputs
|
|
input string indicatorSettings="-=Indicator Settings=-"; //-=Indicator Settings=-
|
|
input ZIGZAGTYPE zztype=ALEXSTAL; //ZigZag type
|
|
input int zzperiod=12; //AlexStal ZZ period
|
|
input int zzamplitude=10; //AlexStal ZZ amplitude
|
|
input int zzminmotion=0; //AlexStal ZZ minimum motion
|
|
input int SwingSize=200; //Fast ZZ sensitivity in points
|
|
input int BarsAnalyzed=200; //Max. bars per pattern
|
|
input int History=1000; //Max. history bars to process
|
|
input int MaxSamePoints=2; //Max. shared points per pattern
|
|
input double SlackRange=0.01; //Max. slack for fib ratios (range)
|
|
input double SlackUnary=0.1; //Max. slack for fib ratios (unary)
|
|
input string indicatorColors="-=Display Settings=-"; //-=Display Settings=-
|
|
input color ClrBull=clrLightSkyBlue; //Color for bullish patterns (5 points)
|
|
input color ClrBear=clrSalmon; //Color for bearish patterns (5 points)
|
|
input color ClrBull4P=clrBlue; //Color for bullish patterns (4 points)
|
|
input color ClrBear4P=clrRed; //Color for bearish patterns (4 points)
|
|
input color ClrBullProjection=clrSeaGreen; //Color for projected bullish patterns
|
|
input color ClrBearProjection=clrDarkOrange; //Color for projected bearish patterns
|
|
input color ClrRatio=clrGray; //Color for patterns ratios
|
|
input bool Fill_Patterns=false; //Fill 5 point patterns found
|
|
input bool Show_descriptions=true; //Show pattern descriptions
|
|
input bool Show_PRZ=true; //Show potential reversal zone (PRZ)
|
|
input bool EmergingPatterns=true; //Show emerging patterns
|
|
input bool OneAheadProjection=false; //Show "one-ahead" projections
|
|
input bool showPatternNames=false; //Show comment box
|
|
input int l_width=2; //Pattern line width (5 points)
|
|
input int l_width4p=2; //Patterns line width (4 points)
|
|
input int l_width_proj=2; //Emerging patterns line width
|
|
input int Font_size=08; //Font size
|
|
input ENUM_LINE_STYLE Style_5P=STYLE_SOLID; //Style for 5 points patterns
|
|
input ENUM_LINE_STYLE Style_4P=STYLE_DASH; //Style for 4 points patterns
|
|
input ENUM_LINE_STYLE Style_Proj=STYLE_DASHDOTDOT; //Style for projections
|
|
input ENUM_LINE_STYLE Style_Ratio=STYLE_DOT; //Style for ratio lines
|
|
input ENUM_LINE_STYLE Style_PRZ=STYLE_DASHDOT; //Style for PRZ
|
|
input string indicatorPatternsQuick="-=Patterns Quick=-"; //-=Patterns Quick=-
|
|
input bool Show_abcd=true; //Display AB=CD patterns
|
|
input bool Show_alt127_abcd=true; //Display 1.27 AB=CD patterns
|
|
input bool Show_rec_abcd=true; //Display Rec. AB=CD patterns
|
|
input bool Show_patterns=true; //Display normal 5-point patterns
|
|
input bool Show_antipatterns=false; //Display anti 5-point patterns
|
|
input string indicatorPatternsIndividual="-=Patterns Individual=-"; //-=Patterns Individual=-
|
|
input bool Show_trendlike1_abcd=true; //Display Trendlike AB=CD #1
|
|
input bool Show_trendlike2_abcd=true; //Display Trendlike AB=CD #2
|
|
input bool Show_perfect_abcd=true; //Display Perfect AB=CD
|
|
input bool Show_ideal1_abcd=true; //Display Ideal AB=CD #1
|
|
input bool Show_ideal2_abcd=true; //Display Ideal AB=CD #2
|
|
input bool Show_rangelike_abcd=true; //Display Rangelike AB=CD
|
|
input bool Show_alt127_trendlike1_abcd=true; //Display Trendlike 1.27 AB=CD #1
|
|
input bool Show_alt127_trendlike2_abcd=true; //Display Trendlike 1.27 AB=CD #2
|
|
input bool Show_alt127_perfect_abcd=true; //Display Perfect 1.27 AB=CD
|
|
input bool Show_alt127_ideal1_abcd=true; //Display Ideal 1.27 AB=CD #1
|
|
input bool Show_alt127_ideal2_abcd=true; //Display Ideal 1.27 AB=CD #2
|
|
input bool Show_alt127_rangelike_abcd=true; //Display Rangelike 1.27 AB=CD
|
|
input bool Show_rec_trendlike1_abcd=true; //Display Rec. Trendlike AB=CD #1
|
|
input bool Show_rec_trendlike2_abcd=true; //Display Rec. Trendlike AB=CD #2
|
|
input bool Show_rec_perfect_abcd=true; //Display Rec. Perfect AB=CD
|
|
input bool Show_rec_ideal1_abcd=true; //Display Rec. Ideal AB=CD #1
|
|
input bool Show_rec_ideal2_abcd=true; //Display Rec. Ideal AB=CD #2
|
|
input bool Show_rec_rangelike_abcd=true; //Display Rec. Rangelike AB=CD
|
|
input bool Show_gartley=true; //Display Gartley
|
|
input bool Show_bat=true; //Display Bat
|
|
input bool Show_altbat=true; //Display Alt. Bat
|
|
input bool Show_fiveo=true; //Display 5-0
|
|
input bool Show_butterfly=true; //Display Butterfly
|
|
input bool Show_crab=true; //Display Crab
|
|
input bool Show_deepcrab=true; //Display Deepcrab
|
|
input bool Show_threedrives=true; //Display Three Drives
|
|
input bool Show_cypher=true; //Display Cypher
|
|
input bool Show_shark=true; //Display Shark
|
|
input bool Show_nenstar=true; //Display Nen Star
|
|
input bool Show_blackswan=true; //Display Black Swan
|
|
input bool Show_whiteswan=true; //Display White Swan
|
|
input bool Show_one2one=true; //Display One2One
|
|
input bool Show_newCypher=true; //Display New Cypher
|
|
input bool Show_navarro200=true; //Display Navarro 200
|
|
input bool Show_leonardo=true; //Display Leonardo
|
|
input bool Show_kane=true; //Display Kane
|
|
input bool Show_garfly=true; //Display Garfly
|
|
input bool Show_maxbat=true; //Display Max. Bat
|
|
input bool Show_maxgartley=true; //Display Max. Gartley
|
|
input bool Show_maxbutterfly=true; //Display Max. Butterfly
|
|
input bool Show_gartley113=true; //Display Gartley 113
|
|
input bool Show_butterfly113=true; //Display Butterfly 113
|
|
input bool Show_antigartley=true; //Display Anti Gartley
|
|
input bool Show_antibat=true; //Display Anti Bat
|
|
input bool Show_antialtbat=true; //Display Anti Alt. Bat
|
|
input bool Show_antifiveo=true; //Display Anti 5-0
|
|
input bool Show_antibutterfly=true; //Display Anti Butterfly
|
|
input bool Show_anticrab=true; //Display Anti Crab
|
|
input bool Show_antideepcrab=true; //Display Anti Deepcrab
|
|
input bool Show_antithreedrives=true; //Display Anti Three Drives
|
|
input bool Show_anticypher=true; //Display Anti Cypher
|
|
input bool Show_antishark=true; //Display Anti Shark
|
|
input bool Show_antinenstar=true; //Display Anti Nen Star
|
|
input bool Show_antiblackswan=true; //Display Anti Black Swan
|
|
input bool Show_antiwhiteswan=true; //Display Anti White Swan
|
|
input bool Show_antione2one=true; //Display Anti One2One
|
|
input bool Show_antinewCypher=true; //Display Anti New Cypher
|
|
input bool Show_antinavarro200=true; //Display Anti Navarro 200
|
|
input bool Show_antileonardo=true; //Display Anti Leonardo
|
|
input bool Show_antikane=true; //Display Anti Kane
|
|
input bool Show_antigarfly=true; //Display Anti Garfly
|
|
input bool Show_antimaxbat=true; //Display Anti Max. Bat
|
|
input bool Show_antimaxgartley=true; //Display Anti Max. Gartley
|
|
input bool Show_antimaxbutterfly=true; //Display Anti Max. Butterfly
|
|
input bool Show_antigartley113=true; //Display Anti Gartley 113
|
|
input bool Show_antibutterfly113=true; //Display Anti Butterfly 113
|
|
//--- Indicator buffer arrays
|
|
double peaks[],troughs[];
|
|
|
|
//--- Globals
|
|
bool _lastDirection;
|
|
double _lastPeakValue;
|
|
double _lastTroughValue;
|
|
int _lastPeak;
|
|
int _lastTrough;
|
|
int _patternInstanceCounter;
|
|
int _maxPatternInstances;
|
|
int _projectionInstanceCounter;
|
|
int _maxProjectionInstances;
|
|
int _drawnProjectionInstanceCounter;
|
|
int _maxDrawnProjectionInstances;
|
|
int _zzHandle;
|
|
PATTERN_INSTANCE _patternInstances[];
|
|
PATTERN_INSTANCE _projectionInstances[];
|
|
PATTERN_INSTANCE _drawnProjectionInstances[];
|
|
PATTERN_DESCRIPTOR _patterns[];
|
|
string _patternNames[];
|
|
int _patternCounter[];
|
|
datetime _patternX[][SIZE_PATTERN_BUFFER];
|
|
datetime _patternA[][SIZE_PATTERN_BUFFER];
|
|
datetime _patternB[][SIZE_PATTERN_BUFFER];
|
|
datetime _patternC[][SIZE_PATTERN_BUFFER];
|
|
datetime _patternD[][SIZE_PATTERN_BUFFER];
|
|
string com1="",com2="",com3="",com4="",com5="",com6="",com7="",com8="",com9="";
|
|
int _timeOfInit;
|
|
//+------------------------------------------------------------------+
|
|
//| Indicator initialization function |
|
|
//+------------------------------------------------------------------+
|
|
int OnInit()
|
|
{
|
|
//--- indicator buffers mapping
|
|
SetIndexBuffer(0,peaks,INDICATOR_DATA);
|
|
SetIndexBuffer(1,troughs,INDICATOR_DATA);
|
|
IndicatorSetInteger(INDICATOR_DIGITS,Digits());
|
|
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
|
|
PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,0.0);
|
|
//--- memory
|
|
switch(zztype)
|
|
{
|
|
case FASTZZ:
|
|
_zzHandle=iCustom(NULL,0,"Downloads\\fastzz",SwingSize);
|
|
break;
|
|
case ALEXSTAL:
|
|
_zzHandle=iCustom(NULL,0,"Downloads\\alexstal_zigzagprof",zzperiod,zzamplitude,zzminmotion,true);
|
|
break;
|
|
case SWINGCHART:
|
|
default:
|
|
_zzHandle=iCustom(NULL,0,"Downloads\\swingchart");
|
|
}
|
|
if(_zzHandle==INVALID_HANDLE)
|
|
{
|
|
printf("Error obtaining handle");
|
|
return(INIT_FAILED);
|
|
}
|
|
MathSrand(GetTickCount());
|
|
_timeOfInit=MathRand();
|
|
for(int i=ObjectsTotal(0,0,-1)-1; i>=0; i--)
|
|
{
|
|
string name=ObjectName(0,i,0,-1);
|
|
if(StringFind(name,"U "+_identifier)!=-1 || StringFind(name,"D "+_identifier)!=-1)
|
|
ObjectDelete(0,name);
|
|
}
|
|
return PopulatePatterns();
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Indicator deinitialization function |
|
|
//+------------------------------------------------------------------+
|
|
void OnDeinit(const int reason)
|
|
{
|
|
OnReinit();
|
|
Comment("");
|
|
ArrayFree(_patterns);
|
|
ArrayFree(_patternInstances);
|
|
ArrayFree(_projectionInstances);
|
|
ArrayFree(_drawnProjectionInstances);
|
|
ArrayFree(_patternNames);
|
|
ArrayFree(_patternCounter);
|
|
ArrayFree(_patternX);
|
|
ArrayFree(_patternA);
|
|
ArrayFree(_patternB);
|
|
ArrayFree(_patternC);
|
|
ArrayFree(_patternD);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Indicator reinitialization function |
|
|
//+------------------------------------------------------------------+
|
|
void OnReinit()
|
|
{
|
|
//----
|
|
_lastPeak=0;
|
|
_lastTrough=0;
|
|
_lastPeakValue=0;
|
|
_lastTroughValue=0;
|
|
_patternInstanceCounter=0;
|
|
_drawnProjectionInstanceCounter=0;
|
|
ArrayFill(_patternCounter,0,NUM_PATTERNS,0);
|
|
for(int i=0; i<NUM_PATTERNS; i++)
|
|
{
|
|
for(int j=0; j<SIZE_PATTERN_BUFFER; j++)
|
|
{
|
|
_patternX[i][j]=0;
|
|
_patternA[i][j]=0;
|
|
_patternB[i][j]=0;
|
|
_patternC[i][j]=0;
|
|
_patternD[i][j]=0;
|
|
}
|
|
}
|
|
for(int i=ObjectsTotal(0,0,-1)-1; i>=0; i--)
|
|
{
|
|
string name=ObjectName(0,i,0,-1);
|
|
if(StringFind(name,"U "+_identifier+StringFormat("%x",_timeOfInit))!=-1 || StringFind(name,"D "+_identifier+StringFormat("%x",_timeOfInit))!=-1)
|
|
ObjectDelete(0,name);
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| 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[])
|
|
{
|
|
//---
|
|
int start=0;
|
|
if(prev_calculated>rates_total || prev_calculated<=0)
|
|
OnReinit();
|
|
else
|
|
start=prev_calculated-1;
|
|
start=MathMax(1,start);
|
|
//--- copy data
|
|
if(BarsCalculated(_zzHandle)<rates_total)
|
|
{
|
|
printf("ZigZag not calculated: "+IntegerToString(GetLastError()));
|
|
return 0;
|
|
}
|
|
if(CopyBuffer(_zzHandle,0,0,rates_total,peaks)<=0)
|
|
{
|
|
printf("ZigZag peaks not copied: "+IntegerToString(GetLastError()));
|
|
return 0;
|
|
}
|
|
if(CopyBuffer(_zzHandle,1,0,rates_total,troughs)<=0)
|
|
{
|
|
printf("ZigZag troughs not copied: "+IntegerToString(GetLastError()));
|
|
return 0;
|
|
}
|
|
//--- main loop
|
|
for(int bar=start; bar<rates_total && !IsStopped(); bar++)
|
|
{
|
|
//--- Efficency checks
|
|
if(bar<rates_total-History)
|
|
continue;
|
|
int lastPeak=FirstNonZeroFrom(bar,peaks);
|
|
int lastTrough=FirstNonZeroFrom(bar,troughs);
|
|
if(lastPeak==-1 || lastTrough==-1)
|
|
continue;
|
|
double lastPeakValue=peaks[lastPeak];
|
|
double lastTroughValue=troughs[lastTrough];
|
|
if(lastPeakValue==_lastPeakValue && lastTroughValue==_lastTroughValue)
|
|
continue;
|
|
//--- ZZ assessment
|
|
bool endsInTrough=lastTrough>lastPeak;
|
|
if(lastTrough==lastPeak)
|
|
{
|
|
int zzDirection=ZigZagDirection(lastPeak);
|
|
if(zzDirection==0) continue;
|
|
else if(zzDirection==-1) endsInTrough=true;
|
|
else if(zzDirection==1) endsInTrough=false;
|
|
}
|
|
//--- Remove old projections
|
|
UndisplayProjections();
|
|
//--- Remove old patterns (on ZZ swing continuation) or store them (on new ZZ direction)
|
|
if(_lastDirection==endsInTrough && !(_lastPeak<lastPeak && _lastTrough<lastTrough))
|
|
UndisplayPatterns();
|
|
else for(int i=0; i<_patternInstanceCounter; i++)
|
|
{
|
|
PATTERN_INSTANCE instance=_patternInstances[i];
|
|
int k=instance.patternIndex;
|
|
bool bullish=instance.bullish;
|
|
datetime XDateTime=instance.XDateTime;
|
|
datetime ADateTime=instance.ADateTime;
|
|
datetime BDateTime=instance.BDateTime;
|
|
datetime CDateTime=instance.CDateTime;
|
|
datetime DDateTime=instance.DDateTime;
|
|
StoreOverlaps(k,XDateTime,ADateTime,BDateTime,CDateTime,DDateTime);
|
|
}
|
|
if(Show_PRZ)
|
|
UndisplayPRZs();
|
|
_patternInstanceCounter=0;
|
|
//--- Save most recent peaks/troughs and direction
|
|
_lastPeak=lastPeak;
|
|
_lastTrough=lastTrough;
|
|
_lastPeakValue=lastPeakValue;
|
|
_lastTroughValue=lastTroughValue;
|
|
_lastDirection=endsInTrough;
|
|
//--- Check each pattern for matches
|
|
for(int patternIndex=0; patternIndex<NUM_PATTERNS && !IsStopped(); patternIndex++)
|
|
{
|
|
//--- Check if pattern should be displayed
|
|
if(patternIndex==TRENDLIKE1_ABCD && (!Show_trendlike1_abcd || !Show_abcd)) continue;
|
|
if(patternIndex==TRENDLIKE2_ABCD && (!Show_trendlike2_abcd || !Show_abcd)) continue;
|
|
if(patternIndex==PERFECT_ABCD && (!Show_perfect_abcd || !Show_abcd)) continue;
|
|
if(patternIndex==IDEAL1_ABCD && (!Show_ideal1_abcd || !Show_abcd)) continue;
|
|
if(patternIndex==IDEAL2_ABCD && (!Show_ideal2_abcd || !Show_abcd)) continue;
|
|
if(patternIndex==RANGELIKE_ABCD && (!Show_rangelike_abcd || !Show_abcd)) continue;
|
|
if(patternIndex==ALT127_TRENDLIKE1_ABCD && (!Show_alt127_trendlike1_abcd || !Show_alt127_abcd)) continue;
|
|
if(patternIndex==ALT127_TRENDLIKE2_ABCD && (!Show_alt127_trendlike2_abcd || !Show_alt127_abcd)) continue;
|
|
if(patternIndex==ALT127_PERFECT_ABCD && (!Show_alt127_perfect_abcd || !Show_alt127_abcd)) continue;
|
|
if(patternIndex==ALT127_IDEAL1_ABCD && (!Show_alt127_ideal1_abcd || !Show_alt127_abcd)) continue;
|
|
if(patternIndex==ALT127_IDEAL2_ABCD && (!Show_alt127_ideal2_abcd || !Show_alt127_abcd)) continue;
|
|
if(patternIndex==ALT127_RANGELIKE_ABCD && (!Show_alt127_rangelike_abcd || !Show_alt127_abcd)) continue;
|
|
if(patternIndex==REC_TRENDLIKE1_ABCD && (!Show_rec_trendlike1_abcd || !Show_rec_abcd)) continue;
|
|
if(patternIndex==REC_TRENDLIKE2_ABCD && (!Show_rec_trendlike2_abcd || !Show_rec_abcd)) continue;
|
|
if(patternIndex==REC_PERFECT_ABCD && (!Show_rec_perfect_abcd || !Show_rec_abcd)) continue;
|
|
if(patternIndex==REC_IDEAL1_ABCD && (!Show_rec_ideal1_abcd || !Show_rec_abcd)) continue;
|
|
if(patternIndex==REC_IDEAL2_ABCD && (!Show_rec_ideal2_abcd || !Show_rec_abcd)) continue;
|
|
if(patternIndex==REC_RANGELIKE_ABCD && (!Show_rec_rangelike_abcd || !Show_rec_abcd)) continue;
|
|
if(patternIndex==GARTLEY && (!Show_gartley || !Show_patterns)) continue;
|
|
if(patternIndex==BAT && (!Show_bat || !Show_patterns)) continue;
|
|
if(patternIndex==ALTBAT && (!Show_altbat || !Show_patterns)) continue;
|
|
if(patternIndex==FIVEO && (!Show_fiveo || !Show_patterns)) continue;
|
|
if(patternIndex==BUTTERFLY && (!Show_butterfly || !Show_patterns)) continue;
|
|
if(patternIndex==CRAB && (!Show_crab || !Show_patterns)) continue;
|
|
if(patternIndex==DEEPCRAB && (!Show_deepcrab || !Show_patterns)) continue;
|
|
if(patternIndex==THREEDRIVES && (!Show_threedrives || !Show_patterns)) continue;
|
|
if(patternIndex==CYPHER && (!Show_cypher || !Show_patterns)) continue;
|
|
if(patternIndex==SHARK && (!Show_shark || !Show_patterns)) continue;
|
|
if(patternIndex==NENSTAR && (!Show_nenstar || !Show_patterns)) continue;
|
|
if(patternIndex==BLACKSWAN && (!Show_blackswan || !Show_patterns)) continue;
|
|
if(patternIndex==WHITESWAN && (!Show_whiteswan || !Show_patterns)) continue;
|
|
if(patternIndex==ONE2ONE && (!Show_one2one || !Show_patterns)) continue;
|
|
if(patternIndex==NEWCYPHER && (!Show_newCypher || !Show_patterns)) continue;
|
|
if(patternIndex==NAVARRO200 && (!Show_navarro200 || !Show_patterns)) continue;
|
|
if(patternIndex==LEONARDO && (!Show_leonardo || !Show_patterns)) continue;
|
|
if(patternIndex==KANE && (!Show_kane || !Show_patterns)) continue;
|
|
if(patternIndex==GARFLY && (!Show_garfly || !Show_patterns)) continue;
|
|
if(patternIndex==MAXBAT && (!Show_maxbat || !Show_patterns)) continue;
|
|
if(patternIndex==MAXGARTLEY && (!Show_maxgartley || !Show_patterns)) continue;
|
|
if(patternIndex==MAXBUTTERFLY && (!Show_maxbutterfly || !Show_patterns)) continue;
|
|
if(patternIndex==GARTLEY113 && (!Show_gartley113 || !Show_patterns)) continue;
|
|
if(patternIndex==BUTTERFLY113 && (!Show_butterfly113 || !Show_patterns)) continue;
|
|
if(patternIndex==ANTI_GARTLEY && (!Show_antigartley || !Show_antipatterns)) continue;
|
|
if(patternIndex==ANTI_BAT && (!Show_antibat || !Show_antipatterns)) continue;
|
|
if(patternIndex==ANTI_ALTBAT && (!Show_antialtbat || !Show_antipatterns)) continue;
|
|
if(patternIndex==ANTI_FIVEO && (!Show_antifiveo || !Show_antipatterns)) continue;
|
|
if(patternIndex==ANTI_BUTTERFLY && (!Show_antibutterfly || !Show_antipatterns)) continue;
|
|
if(patternIndex==ANTI_CRAB && (!Show_anticrab || !Show_antipatterns)) continue;
|
|
if(patternIndex==ANTI_DEEPCRAB && (!Show_antideepcrab || !Show_antipatterns)) continue;
|
|
if(patternIndex==ANTI_THREEDRIVES && (!Show_antithreedrives || !Show_antipatterns)) continue;
|
|
if(patternIndex==ANTI_CYPHER && (!Show_anticypher || !Show_antipatterns)) continue;
|
|
if(patternIndex==ANTI_SHARK && (!Show_antishark || !Show_antipatterns)) continue;
|
|
if(patternIndex==ANTI_NENSTAR && (!Show_antinenstar || !Show_antipatterns)) continue;
|
|
if(patternIndex==ANTI_BLACKSWAN && (!Show_antiblackswan || !Show_antipatterns)) continue;
|
|
if(patternIndex==ANTI_WHITESWAN && (!Show_antiwhiteswan || !Show_antipatterns)) continue;
|
|
if(patternIndex==ANTI_ONE2ONE && (!Show_antione2one || !Show_antipatterns)) continue;
|
|
if(patternIndex==ANTI_NEWCYPHER && (!Show_antinewCypher || !Show_antipatterns)) continue;
|
|
if(patternIndex==ANTI_NAVARRO200 && (!Show_antinavarro200 || !Show_antipatterns)) continue;
|
|
if(patternIndex==ANTI_LEONARDO && (!Show_antileonardo || !Show_antipatterns)) continue;
|
|
if(patternIndex==ANTI_KANE && (!Show_antikane || !Show_antipatterns)) continue;
|
|
if(patternIndex==ANTI_GARFLY && (!Show_antigarfly || !Show_antipatterns)) continue;
|
|
if(patternIndex==ANTI_MAXBAT && (!Show_antimaxbat || !Show_antipatterns)) continue;
|
|
if(patternIndex==ANTI_MAXGARTLEY && (!Show_antimaxgartley || !Show_antipatterns)) continue;
|
|
if(patternIndex==ANTI_MAXBUTTERFLY && (!Show_antimaxbutterfly || !Show_antipatterns)) continue;
|
|
if(patternIndex==ANTI_GARTLEY113 && (!Show_antigartley113 || !Show_antipatterns)) continue;
|
|
if(patternIndex==ANTI_BUTTERFLY113 && (!Show_antibutterfly113 || !Show_antipatterns)) continue;
|
|
PATTERN_DESCRIPTOR pattern=_patterns[patternIndex];
|
|
//--- What constraints does the pattern have?
|
|
bool ab2xaConstraint=pattern.ab2xa_max!=0 && pattern.ab2xa_min!=0;
|
|
bool ad2xaConstraint=pattern.ad2xa_max!=0 && pattern.ad2xa_min!=0;
|
|
bool bc2abConstraint=pattern.bc2ab_max!=0 && pattern.bc2ab_min!=0;
|
|
bool cd2bcConstraint=pattern.cd2bc_max!=0 && pattern.cd2bc_min!=0;
|
|
bool cd2xcConstraint=pattern.cd2xc_max!=0 && pattern.cd2xc_min!=0;
|
|
bool xc2xaConstraint=pattern.xc2xa_max!=0 && pattern.xc2xa_min!=0;
|
|
bool cd2abConstraint=pattern.cd2ab_max!=0 && pattern.cd2ab_min!=0;
|
|
//--- Which constraints are unary vs range?
|
|
double ab2xaSlack=pattern.ab2xa_max==pattern.ab2xa_min ? SlackUnary : SlackRange;
|
|
double ad2xaSlack=pattern.ad2xa_max==pattern.ad2xa_min ? SlackUnary : SlackRange;
|
|
double bc2abSlack=pattern.bc2ab_max==pattern.bc2ab_min ? SlackUnary : SlackRange;
|
|
double cd2bcSlack=pattern.cd2bc_max==pattern.cd2bc_min ? SlackUnary : SlackRange;
|
|
double cd2xcSlack=pattern.cd2xc_max==pattern.cd2xc_min ? SlackUnary : SlackRange;
|
|
double xc2xaSlack=pattern.xc2xa_max==pattern.xc2xa_min ? SlackUnary : SlackRange;
|
|
double cd2abSlack=pattern.cd2ab_max==pattern.cd2ab_min ? SlackUnary : SlackRange;
|
|
//--- Start searching from current bar - 'BarsAnalyzed'
|
|
_projectionInstanceCounter=0;
|
|
bool xFirstRun=true;
|
|
for(int XIndex=bar-BarsAnalyzed; XIndex<=bar && !IsStopped(); XIndex++)
|
|
{
|
|
if(XIndex<=0)
|
|
continue;
|
|
bool isPeak=IsProperValue(peaks[XIndex]);
|
|
bool isTrough=IsProperValue(troughs[XIndex]);
|
|
if(!isPeak && !isTrough)
|
|
continue;
|
|
bool startsInTrough=isTrough;
|
|
bool xVerticalZZ=isPeak && isTrough;
|
|
bool xZZDirection=!startsInTrough;
|
|
if(xVerticalZZ)
|
|
{
|
|
if(xFirstRun)
|
|
startsInTrough=!startsInTrough;
|
|
int zzDirection=ZigZagDirection(XIndex);
|
|
if(zzDirection==0) continue;
|
|
else if(zzDirection==-1) xZZDirection=false;
|
|
else if(zzDirection==1) xZZDirection=true;
|
|
}
|
|
double X=startsInTrough ? troughs[XIndex]: peaks[XIndex];
|
|
double extremeA=startsInTrough ? DBL_MIN : DBL_MAX;
|
|
//--- Skip first AIndex if vertical zz at X and opposite extremum is before X
|
|
int aSkip=0;
|
|
if(xVerticalZZ && ((xZZDirection && !startsInTrough) || (!xZZDirection && startsInTrough))) aSkip=1;
|
|
for(int AIndex=XIndex+aSkip; AIndex<=bar && !IsStopped(); AIndex++)
|
|
{
|
|
//--- Ensure that X is the extremum on [X, A], i.e. there is no lower low (higher high)
|
|
int extremeIndexXA=XIndex==AIndex ? AIndex : AIndex-1;
|
|
if((startsInTrough && IsProperValue(troughs[extremeIndexXA]) && troughs[extremeIndexXA]<X)
|
|
|| (!startsInTrough && IsProperValue(peaks[extremeIndexXA]) && peaks[extremeIndexXA]>X))
|
|
break;
|
|
if((XIndex!=AIndex && IsProperValue(troughs[AIndex]) && IsProperValue(peaks[AIndex]))
|
|
&& ((startsInTrough && ZigZagDirection(AIndex)==1 && troughs[AIndex]<X)
|
|
|| (!startsInTrough && ZigZagDirection(AIndex)==-1 && peaks[AIndex]>X)))
|
|
break;
|
|
//--- Only check increasing (decreasing) A's
|
|
double A=startsInTrough ? peaks[AIndex]: troughs[AIndex];
|
|
if(!IsProperValue(A) || (startsInTrough && A<extremeA) || (!startsInTrough && A>extremeA))
|
|
continue;
|
|
extremeA=A;
|
|
//--- For ratios
|
|
double XA=MathAbs(A-X);
|
|
if(XA==0)
|
|
continue;
|
|
//--- Find B index
|
|
double extremeB=startsInTrough ? DBL_MAX : DBL_MIN;
|
|
//--- Skip first BIndex if vertical zz at X and both X and A is on it
|
|
int bSkip=0;
|
|
if(XIndex==AIndex) bSkip=1;
|
|
for(int BIndex=AIndex+bSkip; BIndex<=bar && !IsStopped(); BIndex++)
|
|
{
|
|
//--- Ensure that A is the extremum on [A, B], i.e. there is no higher high (lower low)
|
|
int extremeIndexAB=AIndex==BIndex ? BIndex : BIndex-1;
|
|
if((!startsInTrough && IsProperValue(troughs[extremeIndexAB]) && troughs[extremeIndexAB]<A)
|
|
|| (startsInTrough && IsProperValue(peaks[extremeIndexAB]) && peaks[extremeIndexAB]>A))
|
|
break;
|
|
if((AIndex!=BIndex && IsProperValue(troughs[BIndex]) && IsProperValue(peaks[BIndex]))
|
|
&& ((!startsInTrough && ZigZagDirection(BIndex)==1 && troughs[BIndex]<A)
|
|
|| (startsInTrough && ZigZagDirection(BIndex)==-1 && peaks[BIndex]>A)))
|
|
break;
|
|
//--- Only check decreasing (increasing) B's
|
|
double B=startsInTrough ? troughs[BIndex]: peaks[BIndex];
|
|
if(!IsProperValue(B) || (startsInTrough && B>extremeB) || (!startsInTrough && B<extremeB))
|
|
continue;
|
|
extremeB=B;
|
|
//--- Second check for vertical ZZ at AB leg and B comes before A
|
|
if(AIndex==BIndex)
|
|
{
|
|
int zzDirection=ZigZagDirection(AIndex);
|
|
if(zzDirection==0) continue;
|
|
else if(zzDirection==-1 && !startsInTrough) continue;
|
|
else if(zzDirection==1 && startsInTrough) continue;
|
|
}
|
|
//--- Ratios
|
|
double AB=MathAbs(A-B);
|
|
if(AB==0)
|
|
continue;
|
|
double ab2xaRatio=AB/XA;
|
|
//--- Possible analytical continue: B does not extend far enough evidenced by 'ab2xaRatio' being too short
|
|
bool ab2xaContinue=ab2xaConstraint;
|
|
ab2xaContinue&=ab2xaRatio<pattern.ab2xa_min-ab2xaSlack;
|
|
if(ab2xaContinue)
|
|
continue;
|
|
//--- Possible analytical cutoff: B extends too far evidenced by 'ab2xaRatio' being too large
|
|
bool ab2xaCutoff=ab2xaConstraint;
|
|
ab2xaCutoff&=ab2xaRatio>pattern.ab2xa_max+ab2xaSlack;
|
|
if(ab2xaCutoff)
|
|
break;
|
|
//--- Find C
|
|
double extremeC=startsInTrough ? DBL_MIN : DBL_MAX;
|
|
//--- Skip first CIndex if vertical zz at B and both A and B is on it
|
|
int cSkip=0;
|
|
if(AIndex==BIndex) cSkip = 1;
|
|
for(int CIndex=BIndex+cSkip; CIndex<=bar && !IsStopped(); CIndex++)
|
|
{
|
|
//--- Ensure that B is the extremum on [B, C], i.e. there is no lower low (higher high)
|
|
int extremeIndexBC=BIndex==CIndex ? CIndex : CIndex-1;
|
|
if((startsInTrough && IsProperValue(troughs[extremeIndexBC]) && troughs[extremeIndexBC]<B)
|
|
|| (!startsInTrough && IsProperValue(peaks[extremeIndexBC]) && peaks[extremeIndexBC]>B))
|
|
break;
|
|
if((BIndex!=CIndex && IsProperValue(troughs[CIndex]) && IsProperValue(peaks[CIndex]))
|
|
&& ((startsInTrough && ZigZagDirection(CIndex)==1 && troughs[CIndex]<B)
|
|
|| (!startsInTrough && ZigZagDirection(CIndex)==-1 && peaks[CIndex]>B)))
|
|
break;
|
|
//--- Only check increasing (decreasing) C's
|
|
double C=startsInTrough ? peaks[CIndex]: troughs[CIndex];
|
|
if(!IsProperValue(C))
|
|
continue;
|
|
if((startsInTrough && C<extremeC) || (!startsInTrough && C>extremeC))
|
|
continue;
|
|
extremeC=C;
|
|
//--- Second check for vertical ZZ at BC leg and C comes before B
|
|
if(BIndex==CIndex)
|
|
{
|
|
int zzDirection=ZigZagDirection(BIndex);
|
|
if(zzDirection==0) continue;
|
|
else if(zzDirection==-1 && startsInTrough) continue;
|
|
else if(zzDirection==1 && !startsInTrough) continue;
|
|
}
|
|
//--- Ratios
|
|
double BC=MathAbs(C-B);
|
|
double XC=MathAbs(X-C);
|
|
if(BC==0) continue;
|
|
if(XC==0) continue;
|
|
double bc2abRatio=BC/AB;
|
|
double xc2xaRatio=XC/XA;
|
|
//--- Analytical continue: C not far enough by short 'bc2abRatio' or 'xc2xaRatio'
|
|
bool bc2abContinue=bc2abConstraint;
|
|
bool xc2xaContinue=xc2xaConstraint;
|
|
bc2abContinue&=bc2abRatio<pattern.bc2ab_min-bc2abSlack;
|
|
xc2xaContinue&=xc2xaRatio<pattern.xc2xa_min-xc2xaSlack;
|
|
if(bc2abContinue || xc2xaContinue)
|
|
continue;
|
|
//--- Analytical cutoff: C too far by long 'bc2abRatio' or 'xc2xaRatio'
|
|
bool bc2abCutoff=bc2abConstraint;
|
|
bool xc2xaCutoff=xc2xaConstraint;
|
|
bc2abCutoff&=bc2abRatio>pattern.bc2ab_max+bc2abSlack;
|
|
xc2xaCutoff&=xc2xaRatio>pattern.xc2xa_max+xc2xaSlack;
|
|
if(bc2abCutoff || xc2xaCutoff)
|
|
break;
|
|
//--- Check if C is the extreme until end-of-search, only then it should be used to project
|
|
bool lastExtremeC=true;
|
|
for(int i=CIndex+1; i<=bar; i++)
|
|
{
|
|
if((startsInTrough && IsProperValue(peaks[i]) && peaks[i]>C)
|
|
|| (!startsInTrough && IsProperValue(troughs[i]) && troughs[i]<C))
|
|
{
|
|
lastExtremeC=false;
|
|
break;
|
|
}
|
|
}
|
|
//--- Find D
|
|
double extremeD=startsInTrough ? DBL_MAX : DBL_MIN;
|
|
//--- Skip first DIndex if vertical zz at C and both B and C is on it
|
|
int dSkip=0;
|
|
if(BIndex==CIndex) dSkip = 1;
|
|
for(int DIndex=CIndex+dSkip; DIndex<=bar && !IsStopped(); DIndex++)
|
|
{
|
|
//--- Ensure that C is the extremum on [C, D], i.e. there is no higher high (lower low)
|
|
int extremeIndexCD=CIndex==DIndex ? DIndex : DIndex-1;
|
|
if((!startsInTrough && IsProperValue(troughs[extremeIndexCD]) && troughs[extremeIndexCD]<C)
|
|
|| (startsInTrough && IsProperValue(peaks[extremeIndexCD]) && peaks[extremeIndexCD]>C))
|
|
break;
|
|
if((CIndex!=DIndex && IsProperValue(troughs[DIndex]) && IsProperValue(peaks[DIndex]))
|
|
&& ((!startsInTrough && ZigZagDirection(DIndex)==1 && troughs[DIndex]<C)
|
|
|| (startsInTrough && ZigZagDirection(DIndex)==-1 && peaks[DIndex]>C)))
|
|
break;
|
|
//--- If CIndex is last, use imaginary D for projections
|
|
bool imaginaryD=((startsInTrough && CIndex==lastPeak && lastTrough<=lastPeak)
|
|
|| (!startsInTrough && CIndex==lastTrough && lastPeak<=lastTrough));
|
|
if(imaginaryD && lastPeak==lastTrough)
|
|
imaginaryD &=(startsInTrough && ZigZagDirection(lastPeak)==1)
|
|
|| (!startsInTrough && ZigZagDirection(lastPeak)==-1);
|
|
//--- Only check decreasing (increasing) D's
|
|
double D=startsInTrough ? troughs[DIndex]: peaks[DIndex];
|
|
if(!imaginaryD && (!IsProperValue(D) || (startsInTrough && D>extremeD) || (!startsInTrough && D<extremeD)))
|
|
continue;
|
|
extremeD=D;
|
|
//--- Second check for vertical ZZ at CD leg and D comes before C
|
|
if(!imaginaryD && CIndex==DIndex)
|
|
{
|
|
int zzDirection=ZigZagDirection(CIndex);
|
|
if(zzDirection==0) continue;
|
|
else if(zzDirection==-1 && !startsInTrough) continue;
|
|
else if(zzDirection==1 && startsInTrough) continue;
|
|
}
|
|
//--- Check if D is the extreme until end-of-search, only then it should be used to project
|
|
bool lastExtremeD=true;
|
|
if(!imaginaryD)
|
|
{
|
|
for(int i=DIndex+1; i<=bar; i++)
|
|
{
|
|
if((!startsInTrough && IsProperValue(peaks[i]) && peaks[i]>D)
|
|
|| (startsInTrough && IsProperValue(troughs[i]) && troughs[i]<D))
|
|
{
|
|
lastExtremeD=false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
//--- Check if potential pattern is on active swing (rightmost on chart)
|
|
bool activeSwing=((endsInTrough && startsInTrough && DIndex==lastTrough) || (!endsInTrough && !startsInTrough && DIndex==lastPeak));
|
|
//--- Analytical solution to harmonic window
|
|
double nearD_cd2bc;
|
|
double nearD_ad2xa;
|
|
double nearD_cd2xc;
|
|
double nearD_cd2ab;
|
|
double farD_cd2bc;
|
|
double farD_ad2xa;
|
|
double farD_cd2xc;
|
|
double farD_cd2ab;
|
|
if(startsInTrough)
|
|
{
|
|
nearD_cd2bc=C-(pattern.cd2bc_min-cd2bcSlack)*BC;
|
|
nearD_ad2xa=A-(pattern.ad2xa_min-ad2xaSlack)*XA;
|
|
nearD_cd2xc=C-(pattern.cd2xc_min-cd2xcSlack)*XC;
|
|
nearD_cd2ab=C-(pattern.cd2ab_min-cd2abSlack)*AB;
|
|
farD_cd2bc=C-(pattern.cd2bc_max+cd2bcSlack)*BC;
|
|
farD_ad2xa=A-(pattern.ad2xa_max+ad2xaSlack)*XA;
|
|
farD_cd2xc=C-(pattern.cd2xc_max+cd2xcSlack)*XC;
|
|
farD_cd2ab=C-(pattern.cd2ab_max+cd2abSlack)*AB;
|
|
}
|
|
else
|
|
{
|
|
nearD_cd2bc=C+(pattern.cd2bc_min-cd2bcSlack)*BC;
|
|
nearD_ad2xa=A+(pattern.ad2xa_min-ad2xaSlack)*XA;
|
|
nearD_cd2xc=C+(pattern.cd2xc_min-cd2xcSlack)*XC;
|
|
nearD_cd2ab=C+(pattern.cd2ab_min-cd2abSlack)*AB;
|
|
farD_cd2bc=C+(pattern.cd2bc_max+cd2bcSlack)*BC;
|
|
farD_ad2xa=A+(pattern.ad2xa_max+ad2xaSlack)*XA;
|
|
farD_cd2xc=C+(pattern.cd2xc_max+cd2xcSlack)*XC;
|
|
farD_cd2ab=C+(pattern.cd2ab_max+cd2abSlack)*AB;
|
|
}
|
|
double nearD=startsInTrough ? DBL_MAX : DBL_MIN;
|
|
double farD=startsInTrough ? DBL_MIN : DBL_MAX;
|
|
if(cd2bcConstraint)
|
|
{
|
|
nearD=startsInTrough ? MathMin(nearD,nearD_cd2bc) : MathMax(nearD,nearD_cd2bc);
|
|
farD=startsInTrough ? MathMax(farD,farD_cd2bc) : MathMin(farD,farD_cd2bc);
|
|
}
|
|
if(ad2xaConstraint)
|
|
{
|
|
nearD=startsInTrough ? MathMin(nearD,nearD_ad2xa) : MathMax(nearD,nearD_ad2xa);
|
|
farD=startsInTrough ? MathMax(farD,farD_ad2xa) : MathMin(farD,farD_ad2xa);
|
|
}
|
|
if(cd2xcConstraint)
|
|
{
|
|
nearD=startsInTrough ? MathMin(nearD,nearD_cd2xc) : MathMax(nearD,nearD_cd2xc);
|
|
farD=startsInTrough ? MathMax(farD,farD_cd2xc) : MathMin(farD,farD_cd2xc);
|
|
}
|
|
if(cd2abConstraint)
|
|
{
|
|
nearD=startsInTrough ? MathMin(nearD,nearD_cd2ab) : MathMax(nearD,nearD_cd2ab);
|
|
farD=startsInTrough ? MathMax(farD,farD_cd2ab) : MathMin(farD,farD_cd2ab);
|
|
}
|
|
//--- Imaginary D only used when no further D's can exist
|
|
if(imaginaryD && !OneAheadProjection)
|
|
break;
|
|
//--- Continue/Pattern undershot
|
|
else if(imaginaryD || (startsInTrough && D>nearD) || (!startsInTrough && D<nearD))
|
|
{
|
|
//--- The XABC are such that no D can satisfy the pattern
|
|
if((startsInTrough && farD>nearD) || (!startsInTrough && farD<nearD))
|
|
break;
|
|
//--- In these two cases, a match or overshot pattern can occur later
|
|
if(!lastExtremeC || !lastExtremeD)
|
|
continue;
|
|
if(!EmergingPatterns)
|
|
break;
|
|
//--- 4-point
|
|
if(Is4PointPattern(patternIndex))
|
|
StoreProjection(patternIndex,startsInTrough,0,0,time[AIndex],A,time[BIndex],B,time[CIndex],C,time[bar],nearD,farD);
|
|
//--- 5-point
|
|
else
|
|
StoreProjection(patternIndex,startsInTrough,time[XIndex],X,time[AIndex],A,time[BIndex],B,time[CIndex],C,time[bar],nearD,farD);
|
|
break;
|
|
}
|
|
//--- Cutoff
|
|
else if((startsInTrough && D<farD) || (!startsInTrough && D>farD))
|
|
break;
|
|
//--- Match
|
|
else
|
|
{
|
|
//--- Invalidate if overlapping
|
|
if(Overlaps(patternIndex,time[XIndex],time[AIndex],time[BIndex],time[CIndex],time[DIndex]))
|
|
continue;
|
|
//--- 4-point
|
|
if(Is4PointPattern(patternIndex))
|
|
{
|
|
DisplayPattern(patternIndex,startsInTrough,time[AIndex],A,time[BIndex],B,time[CIndex],C,time[DIndex],D);
|
|
if(activeSwing)
|
|
{
|
|
StorePattern(patternIndex,startsInTrough,0,time[AIndex],time[BIndex],time[CIndex],time[DIndex]);
|
|
if(Show_PRZ)
|
|
DisplayPRZ(patternIndex,startsInTrough,time[AIndex],A,time[BIndex],time[CIndex],C,time[DIndex],D,farD);
|
|
}
|
|
else
|
|
StoreOverlaps(patternIndex,0,time[AIndex],time[BIndex],time[CIndex],time[DIndex]);
|
|
}
|
|
//--- 5-point
|
|
else
|
|
{
|
|
DisplayPattern(patternIndex,startsInTrough,time[XIndex],X,time[AIndex],A,time[BIndex],B,time[CIndex],C,time[DIndex],D);
|
|
if(activeSwing)
|
|
{
|
|
StorePattern(patternIndex,startsInTrough,time[XIndex],time[AIndex],time[BIndex],time[CIndex],time[DIndex]);
|
|
if(Show_PRZ)
|
|
DisplayPRZ(patternIndex,startsInTrough,time[XIndex],X,time[AIndex],A,time[BIndex],time[CIndex],C,time[DIndex],D,farD);
|
|
}
|
|
else
|
|
StoreOverlaps(patternIndex,time[XIndex],time[AIndex],time[BIndex],time[CIndex],time[DIndex]);
|
|
}
|
|
}
|
|
} //--- End DIndex-loop
|
|
} //--- End CIndex-loop
|
|
} //--- End BIndex-loop
|
|
} //--- End AIndex-loop
|
|
//--- Run same XIndex twice if ZigZag is vertical
|
|
if(xVerticalZZ)
|
|
{
|
|
if(xFirstRun)
|
|
{
|
|
XIndex--;
|
|
xFirstRun=false;
|
|
}
|
|
else
|
|
xFirstRun=true;
|
|
}
|
|
} //--- End XIndex-loop
|
|
//--- Sort projections
|
|
for(int i=1; i<_projectionInstanceCounter; i++)
|
|
{
|
|
_projectionInstances[i].overlapping=false;
|
|
int j=i;
|
|
while(j>0 && _projectionInstances[j-1].D>_projectionInstances[j].D)
|
|
{
|
|
PATTERN_INSTANCE tmp=_projectionInstances[j];
|
|
_projectionInstances[j]=_projectionInstances[j-1];
|
|
_projectionInstances[j-1]=tmp;
|
|
j--;
|
|
}
|
|
}
|
|
_projectionInstances[0].overlapping=false;
|
|
//--- Display projections
|
|
bool forward=true;
|
|
int i=0;
|
|
while(_projectionInstanceCounter!=0)
|
|
{
|
|
bool bullish=_projectionInstances[i].bullish;
|
|
if((forward && !bullish) || (!forward && bullish))
|
|
{
|
|
datetime XDateTime=_projectionInstances[i].XDateTime;
|
|
datetime ADateTime=_projectionInstances[i].ADateTime;
|
|
datetime BDateTime=_projectionInstances[i].BDateTime;
|
|
datetime CDateTime=_projectionInstances[i].CDateTime;
|
|
datetime DDateTime=_projectionInstances[i].DDateTime;
|
|
double X=_projectionInstances[i].X;
|
|
double A=_projectionInstances[i].A;
|
|
double B=_projectionInstances[i].B;
|
|
double C=_projectionInstances[i].C;
|
|
double D=_projectionInstances[i].D;
|
|
double farD=_projectionInstances[i].PRZ;
|
|
//--- Invalidate projection if overlapping other patterns
|
|
if(Overlaps(patternIndex,XDateTime,ADateTime,BDateTime,CDateTime,NON_EXISTENT_DATETIME))
|
|
_projectionInstances[i].overlapping=true;
|
|
//--- Invalidate projection if overlapping other projections
|
|
int j=i;
|
|
while(true)
|
|
{
|
|
//--- Loop condition
|
|
if(forward)
|
|
{
|
|
if(j==0) break;
|
|
else j--;
|
|
}
|
|
else
|
|
{
|
|
if(j==_projectionInstanceCounter-1) break;
|
|
else j++;
|
|
}
|
|
//--- Overlap check
|
|
if(!_projectionInstances[j].overlapping && _projectionInstances[j].bullish==bullish)
|
|
{
|
|
datetime XDateTimeActive=_projectionInstances[j].XDateTime;
|
|
datetime ADateTimeActive=_projectionInstances[j].ADateTime;
|
|
datetime BDateTimeActive=_projectionInstances[j].BDateTime;
|
|
datetime CDateTimeActive=_projectionInstances[j].CDateTime;
|
|
datetime DDateTimeActive=_projectionInstances[j].DDateTime;
|
|
int numMatches=0;
|
|
if(!Is4PointPattern(patternIndex) && XDateTime==XDateTimeActive) numMatches++;
|
|
if(ADateTime==ADateTimeActive) numMatches++;
|
|
if(BDateTime==BDateTimeActive) numMatches++;
|
|
if(CDateTime==CDateTimeActive) numMatches++;
|
|
//if(DDateTime==DDateTimeActive) numMatches++;
|
|
if(numMatches>MaxSamePoints)
|
|
{
|
|
_projectionInstances[i].overlapping=true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
//--- Display projection
|
|
if(!_projectionInstances[i].overlapping)
|
|
{
|
|
if(Is4PointPattern(patternIndex))
|
|
DisplayProjection(patternIndex,bullish,ADateTime,A,BDateTime,B,CDateTime,C,DDateTime,D);
|
|
else
|
|
DisplayProjection(patternIndex,bullish,XDateTime,X,ADateTime,A,BDateTime,B,CDateTime,C,DDateTime,D);
|
|
_drawnProjectionInstances[_drawnProjectionInstanceCounter]=_projectionInstances[i];
|
|
_drawnProjectionInstanceCounter++;
|
|
if(_drawnProjectionInstanceCounter>=_maxDrawnProjectionInstances)
|
|
{
|
|
_maxDrawnProjectionInstances*=2;
|
|
if(ArrayResize(_drawnProjectionInstances,_maxDrawnProjectionInstances)<_maxDrawnProjectionInstances)
|
|
printf("Error allocating array");
|
|
}
|
|
}
|
|
}
|
|
//--- Loop condition
|
|
if(forward)
|
|
{
|
|
if(i==_projectionInstanceCounter-1) forward=false;
|
|
else i++;
|
|
}
|
|
else
|
|
{
|
|
if(i==0) break;
|
|
else i--;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//--- return value of prev_calculated for next call
|
|
return(rates_total);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Helper method determines 4 point patterns |
|
|
//+------------------------------------------------------------------+
|
|
bool Is4PointPattern(int patternIndex)
|
|
{
|
|
if(patternIndex == TRENDLIKE1_ABCD) return true;
|
|
if(patternIndex == TRENDLIKE2_ABCD) return true;
|
|
if(patternIndex == PERFECT_ABCD) return true;
|
|
if(patternIndex == IDEAL1_ABCD) return true;
|
|
if(patternIndex == IDEAL2_ABCD) return true;
|
|
if(patternIndex == RANGELIKE_ABCD) return true;
|
|
if(patternIndex == ALT127_TRENDLIKE1_ABCD) return true;
|
|
if(patternIndex == ALT127_TRENDLIKE2_ABCD) return true;
|
|
if(patternIndex == ALT127_PERFECT_ABCD) return true;
|
|
if(patternIndex == ALT127_IDEAL1_ABCD) return true;
|
|
if(patternIndex == ALT127_IDEAL2_ABCD) return true;
|
|
if(patternIndex == ALT127_RANGELIKE_ABCD) return true;
|
|
if(patternIndex == REC_TRENDLIKE1_ABCD) return true;
|
|
if(patternIndex == REC_TRENDLIKE2_ABCD) return true;
|
|
if(patternIndex == REC_PERFECT_ABCD) return true;
|
|
if(patternIndex == REC_IDEAL1_ABCD) return true;
|
|
if(patternIndex == REC_IDEAL2_ABCD) return true;
|
|
if(patternIndex == REC_RANGELIKE_ABCD) return true;
|
|
return false;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Helper method finds ZigZag direction in before index |
|
|
//+------------------------------------------------------------------+
|
|
int ZigZagDirection(int index)
|
|
{
|
|
int lastPeakBefore=FirstNonZeroFrom(index-1,peaks);
|
|
int lastTroughBefore=FirstNonZeroFrom(index-1,troughs);
|
|
while(lastPeakBefore==lastTroughBefore)
|
|
{
|
|
lastPeakBefore=FirstNonZeroFrom(lastPeakBefore-1,peaks);
|
|
lastTroughBefore=FirstNonZeroFrom(lastTroughBefore-1,troughs);
|
|
if(lastPeakBefore==-1 || lastTroughBefore==-1) return 0;
|
|
}
|
|
if(lastPeakBefore==-1 || lastTroughBefore==-1) return 0;
|
|
else if(lastPeakBefore<lastTroughBefore) return -1;
|
|
else return 1;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Helper method finds first proper value from start |
|
|
//+------------------------------------------------------------------+
|
|
int FirstNonZeroFrom(int start,double &array[])
|
|
{
|
|
for(int j=start; j>=0; j--)
|
|
if(IsProperValue(array[j]))
|
|
return j;
|
|
return -1;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Helper method determines proper value |
|
|
//+------------------------------------------------------------------+
|
|
bool IsProperValue(double value)
|
|
{
|
|
return (value!=0 && value!=EMPTY_VALUE);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Comment |
|
|
//+------------------------------------------------------------------+
|
|
void ShowComment(string sComment)
|
|
{
|
|
if(sComment!="")
|
|
{
|
|
com9=com8; //--- discards last comment line
|
|
com8=com7; //--- and shifts
|
|
com7=com6;
|
|
com6=com5;
|
|
com5=com4;
|
|
com4=com3;
|
|
com3=com2;
|
|
com2=com1;
|
|
com1=sComment;
|
|
}
|
|
Comment("HarmonicPatternFinderV2 © 2016","\n","\n",com1,"\n",com2,"\n",com3,"\n",com4,"\n",com5,"\n",com6,"\n",com7,"\n",com8,"\n",com9,"\n");
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Helper method checks if pattern overlaps |
|
|
//+------------------------------------------------------------------+
|
|
bool Overlaps(int k,datetime XDateTime,datetime ADateTime,datetime BDateTime,datetime CDateTime,datetime DDateTime)
|
|
{
|
|
bool overlaps=false;
|
|
//--- Check old patterns in fixed size ring buffer
|
|
for(int i=0; i<SIZE_PATTERN_BUFFER; i++)
|
|
{
|
|
int numMatches=0;
|
|
if(!Is4PointPattern(k) && XDateTime==_patternX[k][i]) numMatches++;
|
|
if(ADateTime==_patternA[k][i]) numMatches++;
|
|
if(BDateTime==_patternB[k][i]) numMatches++;
|
|
if(CDateTime==_patternC[k][i]) numMatches++;
|
|
if(DDateTime==_patternD[k][i]) numMatches++;
|
|
if(numMatches>MaxSamePoints)
|
|
return true;
|
|
}
|
|
//--- Check active patterns in unlimited size array
|
|
for(int i=0; i<_patternInstanceCounter; i++)
|
|
{
|
|
PATTERN_INSTANCE instance=_patternInstances[i];
|
|
int patternIndexActive=_patternInstances[i].patternIndex;
|
|
if(patternIndexActive!=k)
|
|
continue;
|
|
bool bullish=instance.bullish;
|
|
datetime XDateTimeActive=instance.XDateTime;
|
|
datetime ADateTimeActive=instance.ADateTime;
|
|
datetime BDateTimeActive=instance.BDateTime;
|
|
datetime CDateTimeActive=instance.CDateTime;
|
|
datetime DDateTimeActive=instance.DDateTime;
|
|
int numMatches=0;
|
|
if(!Is4PointPattern(k) && XDateTime==XDateTimeActive) numMatches++;
|
|
if(ADateTime==ADateTimeActive) numMatches++;
|
|
if(BDateTime==BDateTimeActive) numMatches++;
|
|
if(CDateTime==CDateTimeActive) numMatches++;
|
|
if(DDateTime==DDateTimeActive) numMatches++;
|
|
if(numMatches>MaxSamePoints)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Helper method stores if pattern overlaps |
|
|
//+------------------------------------------------------------------+
|
|
void StoreOverlaps(int k,datetime XDateTime,datetime ADateTime,datetime BDateTime,datetime CDateTime,datetime DDateTime)
|
|
{
|
|
int index=_patternCounter[k];
|
|
_patternCounter[k]=(index+1)%SIZE_PATTERN_BUFFER;
|
|
_patternX[k][index]=XDateTime;
|
|
_patternA[k][index]=ADateTime;
|
|
_patternB[k][index]=BDateTime;
|
|
_patternC[k][index]=CDateTime;
|
|
_patternD[k][index]=DDateTime;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Helper method stores patterns |
|
|
//+------------------------------------------------------------------+
|
|
void StorePattern(int k,bool bullish,datetime XDateTime,datetime ADateTime,datetime BDateTime,datetime CDateTime,datetime DDateTime)
|
|
{
|
|
_patternInstances[_patternInstanceCounter].patternIndex=k;
|
|
_patternInstances[_patternInstanceCounter].bullish=bullish;
|
|
_patternInstances[_patternInstanceCounter].XDateTime=XDateTime;
|
|
_patternInstances[_patternInstanceCounter].ADateTime=ADateTime;
|
|
_patternInstances[_patternInstanceCounter].BDateTime=BDateTime;
|
|
_patternInstances[_patternInstanceCounter].CDateTime=CDateTime;
|
|
_patternInstances[_patternInstanceCounter].DDateTime=DDateTime;
|
|
_patternInstanceCounter++;
|
|
if(_patternInstanceCounter>=_maxPatternInstances)
|
|
{
|
|
_maxPatternInstances*=2;
|
|
if(ArrayResize(_patternInstances,_maxPatternInstances)<_maxPatternInstances)
|
|
printf("Error allocating array");
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Helper method stores projections |
|
|
//+------------------------------------------------------------------+
|
|
void StoreProjection(int k,bool bullish,
|
|
datetime XDateTime,double X,
|
|
datetime ADateTime,double A,
|
|
datetime BDateTime,double B,
|
|
datetime CDateTime,double C,
|
|
datetime DDateTime,double D,
|
|
double farD)
|
|
{
|
|
_projectionInstances[_projectionInstanceCounter].patternIndex=k;
|
|
_projectionInstances[_projectionInstanceCounter].bullish=bullish;
|
|
_projectionInstances[_projectionInstanceCounter].XDateTime=XDateTime;
|
|
_projectionInstances[_projectionInstanceCounter].ADateTime=ADateTime;
|
|
_projectionInstances[_projectionInstanceCounter].BDateTime=BDateTime;
|
|
_projectionInstances[_projectionInstanceCounter].CDateTime=CDateTime;
|
|
_projectionInstances[_projectionInstanceCounter].DDateTime=DDateTime;
|
|
_projectionInstances[_projectionInstanceCounter].X=X;
|
|
_projectionInstances[_projectionInstanceCounter].A=A;
|
|
_projectionInstances[_projectionInstanceCounter].B=B;
|
|
_projectionInstances[_projectionInstanceCounter].C=C;
|
|
_projectionInstances[_projectionInstanceCounter].D=D;
|
|
_projectionInstances[_projectionInstanceCounter].PRZ=farD;
|
|
_projectionInstanceCounter++;
|
|
if(_projectionInstanceCounter>=_maxProjectionInstances)
|
|
{
|
|
_maxProjectionInstances*=2;
|
|
if(ArrayResize(_projectionInstances,_maxProjectionInstances)<_maxProjectionInstances)
|
|
printf("Error allocating array");
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Helper method displays 4-point PRZ |
|
|
//+------------------------------------------------------------------+
|
|
void DisplayPRZ(int k,bool bullish,
|
|
datetime ADateTime,double A,
|
|
datetime BDateTime,
|
|
datetime CDateTime,double C,
|
|
datetime DDateTime,double D,
|
|
double farD)
|
|
{
|
|
string unique=UniqueIdentifier(ADateTime,BDateTime,CDateTime,DDateTime);
|
|
string prefix=(bullish ? "Bullish " : "Bearish ");
|
|
string prefixName=(bullish ? "U "+_identifier : "D "+_identifier);
|
|
string name=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" PRZ"+unique;
|
|
ObjectCreate(0,name,OBJ_TREND,0,DDateTime-1,farD,DDateTime,farD);
|
|
ObjectSetInteger(0,name,OBJPROP_RAY_RIGHT,true);
|
|
ObjectSetInteger(0,name,OBJPROP_COLOR,bullish ? ClrBull4P : ClrBear4P);
|
|
ObjectSetInteger(0,name,OBJPROP_STYLE,Style_PRZ);
|
|
ObjectSetString(0,name,OBJPROP_TOOLTIP,prefix+_patternNames[k]+" PRZ stop "+DoubleToString(farD));
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Helper method displays 5-point PRZ |
|
|
//+------------------------------------------------------------------+
|
|
void DisplayPRZ(int k,bool bullish,
|
|
datetime XDateTime,double X,
|
|
datetime ADateTime,double A,
|
|
datetime BDateTime,
|
|
datetime CDateTime,double C,
|
|
datetime DDateTime,double D,
|
|
double farD)
|
|
{
|
|
string unique=UniqueIdentifier(XDateTime,ADateTime,BDateTime,CDateTime,DDateTime);
|
|
string prefix=(bullish ? "Bullish " : "Bearish ");
|
|
string prefixName=(bullish ? "U "+_identifier : "D "+_identifier);
|
|
string name=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" PRZ"+unique;
|
|
ObjectCreate(0,name,OBJ_TREND,0,DDateTime-1,farD,DDateTime,farD);
|
|
ObjectSetInteger(0,name,OBJPROP_RAY_RIGHT,true);
|
|
ObjectSetInteger(0,name,OBJPROP_COLOR,bullish ? ClrBull: ClrBear);
|
|
ObjectSetInteger(0,name,OBJPROP_STYLE,Style_PRZ);
|
|
ObjectSetString(0,name,OBJPROP_TOOLTIP,prefix+_patternNames[k]+" PRZ stop "+DoubleToString(farD));
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Helper method displays 4-point patterns |
|
|
//+------------------------------------------------------------------+
|
|
void DisplayPattern(int k,bool bullish,
|
|
datetime ADateTime,double A,
|
|
datetime BDateTime,double B,
|
|
datetime CDateTime,double C,
|
|
datetime DDateTime,double D)
|
|
{
|
|
string unique=UniqueIdentifier(ADateTime,BDateTime,CDateTime,DDateTime);
|
|
string prefix=(bullish ? "Bullish " : "Bearish ");
|
|
string prefixName=(bullish ? "U "+_identifier : "D "+_identifier);
|
|
string name0=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" AB"+unique;
|
|
string name1=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" BC"+unique;
|
|
string name2=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" CD"+unique;
|
|
string pointA=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" PA"+unique;
|
|
string pointB=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" PB"+unique;
|
|
string pointC=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" PC"+unique;
|
|
string pointD=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" PD"+unique;
|
|
//--- Create lines on the chart
|
|
ObjectCreate(0,name0,OBJ_TREND,0,ADateTime,A,BDateTime,B);
|
|
ObjectCreate(0,name1,OBJ_TREND,0,BDateTime,B,CDateTime,C);
|
|
ObjectCreate(0,name2,OBJ_ARROWED_LINE,0,CDateTime,C,DDateTime,D);
|
|
ObjectSetInteger(0,name0,OBJPROP_COLOR, bullish ? ClrBull4P : ClrBear4P);
|
|
ObjectSetInteger(0,name1,OBJPROP_COLOR, bullish ? ClrBull4P : ClrBear4P);
|
|
ObjectSetInteger(0,name2,OBJPROP_COLOR, bullish ? ClrBull4P : ClrBear4P);
|
|
ObjectSetInteger(0,name0,OBJPROP_SELECTABLE,true);
|
|
ObjectSetInteger(0,name1,OBJPROP_SELECTABLE,true);
|
|
ObjectSetInteger(0,name2,OBJPROP_SELECTABLE,true);
|
|
ObjectSetInteger(0,name0,OBJPROP_WIDTH,l_width4p);
|
|
ObjectSetInteger(0,name1,OBJPROP_WIDTH,l_width4p);
|
|
ObjectSetInteger(0,name2,OBJPROP_WIDTH,l_width4p);
|
|
ObjectSetInteger(0,name0,OBJPROP_STYLE,Style_4P);
|
|
ObjectSetInteger(0,name1,OBJPROP_STYLE,Style_4P);
|
|
ObjectSetInteger(0,name2,OBJPROP_STYLE,Style_4P);
|
|
ObjectSetString(0,name0,OBJPROP_TOOLTIP,prefix+_patternNames[k]+" AB");
|
|
ObjectSetString(0,name1,OBJPROP_TOOLTIP,prefix+_patternNames[k]+" BC");
|
|
ObjectSetString(0,name2,OBJPROP_TOOLTIP,prefix+_patternNames[k]+" CD");
|
|
if(Show_descriptions)
|
|
{
|
|
int numOverlapping=0;
|
|
for(int i=0; i<NUM_PATTERNS; i++)
|
|
{
|
|
for(int j=0; j<SIZE_PATTERN_BUFFER; j++)
|
|
{
|
|
if(ADateTime==_patternX[i][j]) numOverlapping++;
|
|
if(Is4PointPattern(i) && ADateTime==_patternA[i][j]) numOverlapping++;
|
|
}
|
|
}
|
|
for(int i=0; i<_patternInstanceCounter; i++)
|
|
{
|
|
PATTERN_INSTANCE instance=_patternInstances[i];
|
|
int patternIndexActive=_patternInstances[i].patternIndex;
|
|
datetime XDateTimeActive=instance.XDateTime;
|
|
datetime ADateTimeActive=instance.ADateTime;
|
|
if(ADateTime==XDateTimeActive) numOverlapping++;
|
|
if(Is4PointPattern(patternIndexActive) && ADateTime==ADateTimeActive) numOverlapping++;
|
|
}
|
|
int x1=0;
|
|
int y1=0;
|
|
int x2=0;
|
|
int y2=0;
|
|
ChartTimePriceToXY(0,0,ADateTime,A,x1,y1);
|
|
ChartTimePriceToXY(0,0,ADateTime,A+1,x2,y2);
|
|
double pixelsPerPrice=MathAbs(y1-y2);
|
|
double change=pixelsPerPrice!=0 ? numOverlapping*(Font_size)/pixelsPerPrice : 0;
|
|
double price=(bullish ? A+change : A-change);
|
|
ObjectCreate(0,pointA,OBJ_TEXT,0,ADateTime,price);
|
|
ObjectCreate(0,pointB,OBJ_TEXT,0,BDateTime,B);
|
|
ObjectCreate(0,pointC,OBJ_TEXT,0,CDateTime,C);
|
|
ObjectCreate(0,pointD,OBJ_TEXT,0,DDateTime,D);
|
|
ObjectSetString(0,pointA,OBJPROP_TOOLTIP,prefix+_patternNames[k]+" PA");
|
|
ObjectSetString(0,pointB,OBJPROP_TOOLTIP,prefix+_patternNames[k]+" PB");
|
|
ObjectSetString(0,pointC,OBJPROP_TOOLTIP,prefix+_patternNames[k]+" PC");
|
|
ObjectSetString(0,pointD,OBJPROP_TOOLTIP,prefix+_patternNames[k]+" PD");
|
|
ObjectSetString(0,pointA,OBJPROP_TEXT,"A "+prefix+_patternNames[k]);
|
|
ObjectSetString(0,pointA,OBJPROP_FONT,"Arial");
|
|
ObjectSetInteger(0,pointA,OBJPROP_FONTSIZE,08);
|
|
ObjectSetInteger(0,pointA,OBJPROP_COLOR,bullish ? ClrBull4P : ClrBear4P);
|
|
ObjectSetString(0,pointB,OBJPROP_TEXT,"B");
|
|
ObjectSetString(0,pointB,OBJPROP_FONT,"Arial");
|
|
ObjectSetInteger(0,pointB,OBJPROP_FONTSIZE,08);
|
|
ObjectSetInteger(0,pointB,OBJPROP_COLOR,bullish ? ClrBull4P : ClrBear4P);
|
|
ObjectSetString(0,pointC,OBJPROP_TEXT,"C");
|
|
ObjectSetString(0,pointC,OBJPROP_FONT,"Arial");
|
|
ObjectSetInteger(0,pointC,OBJPROP_FONTSIZE,08);
|
|
ObjectSetInteger(0,pointC,OBJPROP_COLOR,bullish ? ClrBull4P : ClrBear4P);
|
|
ObjectSetString(0,pointD,OBJPROP_TEXT,"D");
|
|
ObjectSetString(0,pointD,OBJPROP_FONT,"Arial");
|
|
ObjectSetInteger(0,pointD,OBJPROP_FONTSIZE,08);
|
|
ObjectSetInteger(0,pointD,OBJPROP_COLOR,bullish ? ClrBull4P : ClrBear4P);
|
|
}
|
|
if(showPatternNames)
|
|
ShowComment(prefix+_patternNames[k]+" @ "+TimeToString(DDateTime));
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Helper method displays 5-point patterns |
|
|
//+------------------------------------------------------------------+
|
|
void DisplayPattern(int k,bool bullish,
|
|
datetime XDateTime,double X,
|
|
datetime ADateTime,double A,
|
|
datetime BDateTime,double B,
|
|
datetime CDateTime,double C,
|
|
datetime DDateTime,double D)
|
|
{
|
|
string unique=UniqueIdentifier(XDateTime,ADateTime,BDateTime,CDateTime,DDateTime);
|
|
string prefix=(bullish ? "Bullish " : "Bearish ");
|
|
string prefixName=(bullish ? "U "+_identifier : "D "+_identifier);
|
|
string name0=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" XA"+unique;
|
|
string name1=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" AB"+unique;
|
|
string name2=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" BC"+unique;
|
|
string name3=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" CD"+unique;
|
|
string name4=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" XAB"+unique;
|
|
string name5=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" XAD"+unique;
|
|
string name6=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" ABC"+unique;
|
|
string name7=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" BCD"+unique;
|
|
string triangle_XB=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" XB"+unique;
|
|
string triangle_BD=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" BD"+unique;
|
|
string pointX=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" PX"+unique;
|
|
string pointA=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" PA"+unique;
|
|
string pointB=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" PB"+unique;
|
|
string pointC=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" PC"+unique;
|
|
string pointD=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" PD"+unique;
|
|
string xab=IntegerToString((int) MathRound(100*MathAbs(A-B)/MathAbs(X-A)));
|
|
string xad=IntegerToString((int) MathRound(100*MathAbs(D-A)/MathAbs(X-A)));
|
|
string abc=IntegerToString((int) MathRound(100*MathAbs(C-B)/MathAbs(B-A)));
|
|
if(k==CYPHER || k==NENSTAR || k==NEWCYPHER)
|
|
abc=IntegerToString((int) MathRound(100*MathAbs(X-C)/MathAbs(X-A)));
|
|
string bcd=IntegerToString((int) MathRound(100*MathAbs(C-D)/MathAbs(B-C)));
|
|
ObjectCreate(0,name0,OBJ_TREND,0,XDateTime,X,ADateTime,A);
|
|
ObjectCreate(0,name1,OBJ_TREND,0,ADateTime,A,BDateTime,B);
|
|
ObjectCreate(0,name2,OBJ_TREND,0,BDateTime,B,CDateTime,C);
|
|
ObjectCreate(0,name3,(!Fill_Patterns || (k==THREEDRIVES) || (k==FIVEO)) ? OBJ_ARROWED_LINE : OBJ_TREND,0,CDateTime,C,DDateTime,D); //Arrowed lines if not triangles
|
|
ObjectCreate(0,name4,OBJ_TREND,0,XDateTime,X,BDateTime,B);
|
|
//--- Point labels
|
|
if(Show_descriptions)
|
|
{
|
|
int numOverlapping=0;
|
|
for(int i=0; i<NUM_PATTERNS; i++)
|
|
{
|
|
for(int j=0; j<SIZE_PATTERN_BUFFER; j++)
|
|
{
|
|
if(XDateTime==_patternX[i][j]) numOverlapping++;
|
|
if(Is4PointPattern(i) && XDateTime==_patternA[i][j]) numOverlapping++;
|
|
}
|
|
}
|
|
for(int i=0; i<_patternInstanceCounter; i++)
|
|
{
|
|
PATTERN_INSTANCE instance=_patternInstances[i];
|
|
int patternIndexActive=_patternInstances[i].patternIndex;
|
|
datetime XDateTimeActive=instance.XDateTime;
|
|
datetime ADateTimeActive=instance.ADateTime;
|
|
if(XDateTime==XDateTimeActive) numOverlapping++;
|
|
if(Is4PointPattern(patternIndexActive) && XDateTime==ADateTimeActive) numOverlapping++;
|
|
}
|
|
int x1=0;
|
|
int y1=0;
|
|
int x2=0;
|
|
int y2=0;
|
|
ChartTimePriceToXY(0,0,XDateTime,X,x1,y1);
|
|
ChartTimePriceToXY(0,0,XDateTime,X+1,x2,y2);
|
|
double pixelsPerPrice=MathAbs(y1-y2);
|
|
double change=pixelsPerPrice!=0 ? numOverlapping*(Font_size)/pixelsPerPrice : 0;
|
|
double price=(bullish ? X-change : X+change);
|
|
ObjectCreate(0,pointX,OBJ_TEXT,0,XDateTime,price);
|
|
ObjectCreate(0,pointA,OBJ_TEXT,0,ADateTime,A);
|
|
ObjectCreate(0,pointB,OBJ_TEXT,0,BDateTime,B);
|
|
ObjectCreate(0,pointC,OBJ_TEXT,0,CDateTime,C);
|
|
ObjectCreate(0,pointD,OBJ_TEXT,0,DDateTime,D);
|
|
ObjectSetString(0,pointX,OBJPROP_TOOLTIP,prefix+_patternNames[k]+" PX");
|
|
ObjectSetString(0,pointA,OBJPROP_TOOLTIP,prefix+_patternNames[k]+" PA");
|
|
ObjectSetString(0,pointB,OBJPROP_TOOLTIP,prefix+_patternNames[k]+" PB");
|
|
ObjectSetString(0,pointC,OBJPROP_TOOLTIP,prefix+_patternNames[k]+" PC");
|
|
ObjectSetString(0,pointD,OBJPROP_TOOLTIP,prefix+_patternNames[k]+" PD");
|
|
ObjectSetString(0,pointX,OBJPROP_TEXT,"X "+prefix+_patternNames[k]);
|
|
ObjectSetString(0,pointX,OBJPROP_FONT,"Arial");
|
|
ObjectSetInteger(0,pointX,OBJPROP_FONTSIZE,Font_size);
|
|
ObjectSetInteger(0,pointX,OBJPROP_COLOR,bullish ? ClrBull : ClrBear);
|
|
ObjectSetString(0,pointA,OBJPROP_TEXT,"A");
|
|
ObjectSetString(0,pointA,OBJPROP_FONT,"Arial");
|
|
ObjectSetInteger(0,pointA,OBJPROP_FONTSIZE,Font_size);
|
|
ObjectSetInteger(0,pointA,OBJPROP_COLOR,bullish ? ClrBull : ClrBear);
|
|
ObjectSetString(0,pointB,OBJPROP_TEXT,"B");
|
|
ObjectSetString(0,pointB,OBJPROP_FONT,"Arial");
|
|
ObjectSetInteger(0,pointB,OBJPROP_FONTSIZE,Font_size);
|
|
ObjectSetInteger(0,pointB,OBJPROP_COLOR,bullish ? ClrBull : ClrBear);
|
|
ObjectSetString(0,pointC,OBJPROP_TEXT,"C");
|
|
ObjectSetString(0,pointC,OBJPROP_FONT,"Arial");
|
|
ObjectSetInteger(0,pointC,OBJPROP_FONTSIZE,Font_size);
|
|
ObjectSetInteger(0,pointC,OBJPROP_COLOR,bullish ? ClrBull : ClrBear);
|
|
ObjectSetString(0,pointD,OBJPROP_TEXT,"D");
|
|
ObjectSetString(0,pointD,OBJPROP_FONT,"Arial");
|
|
ObjectSetInteger(0,pointD,OBJPROP_FONTSIZE,Font_size);
|
|
ObjectSetInteger(0,pointD,OBJPROP_COLOR,bullish ? ClrBull : ClrBear);
|
|
}
|
|
//--- No X-D for 5-0
|
|
if(k!=FIVEO) ObjectCreate(0,name5,OBJ_TREND,0,XDateTime,X,DDateTime,D);
|
|
ObjectCreate(0,name6,OBJ_TREND,0,ADateTime,A,CDateTime,C);
|
|
ObjectCreate(0,name7,OBJ_TREND,0,BDateTime,B,DDateTime,D);
|
|
ObjectSetInteger(0,name0,OBJPROP_COLOR, bullish ? ClrBull : ClrBear);
|
|
ObjectSetInteger(0,name1,OBJPROP_COLOR, bullish ? ClrBull : ClrBear);
|
|
ObjectSetInteger(0,name2,OBJPROP_COLOR, bullish ? ClrBull : ClrBear);
|
|
ObjectSetInteger(0,name3,OBJPROP_COLOR, bullish ? ClrBull : ClrBear);
|
|
ObjectSetInteger(0,name0,OBJPROP_STYLE,Style_5P);
|
|
ObjectSetInteger(0,name1,OBJPROP_STYLE,Style_5P);
|
|
ObjectSetInteger(0,name3,OBJPROP_STYLE,Style_5P);
|
|
ObjectSetInteger(0,name4,OBJPROP_COLOR,ClrRatio);
|
|
if(k!=FIVEO) ObjectSetInteger(0,name5,OBJPROP_COLOR,ClrRatio);
|
|
ObjectSetInteger(0,name6,OBJPROP_COLOR,ClrRatio);
|
|
ObjectSetInteger(0,name7,OBJPROP_COLOR,ClrRatio);
|
|
ObjectSetInteger(0,name4,OBJPROP_STYLE,Style_Ratio);
|
|
if(k!=FIVEO) ObjectSetInteger(0,name5,OBJPROP_STYLE,Style_Ratio);
|
|
ObjectSetInteger(0,name6,OBJPROP_STYLE,Style_Ratio);
|
|
ObjectSetInteger(0,name7,OBJPROP_STYLE,Style_Ratio);
|
|
ObjectSetInteger(0,name0,OBJPROP_SELECTABLE,true);
|
|
ObjectSetInteger(0,name1,OBJPROP_SELECTABLE,true);
|
|
ObjectSetInteger(0,name2,OBJPROP_SELECTABLE,true);
|
|
ObjectSetInteger(0,name3,OBJPROP_SELECTABLE,true);
|
|
ObjectSetInteger(0,name4,OBJPROP_SELECTABLE,true);
|
|
if(k!=FIVEO) ObjectSetInteger(0,name5,OBJPROP_SELECTABLE,true);
|
|
ObjectSetInteger(0,name6,OBJPROP_SELECTABLE,true);
|
|
ObjectSetInteger(0,name7,OBJPROP_SELECTABLE,true);
|
|
ObjectSetString(0,name0,OBJPROP_TOOLTIP,prefix+_patternNames[k]+" XA");
|
|
ObjectSetString(0,name1,OBJPROP_TOOLTIP,prefix+_patternNames[k]+" AB");
|
|
ObjectSetString(0,name2,OBJPROP_TOOLTIP,prefix+_patternNames[k]+" BC");
|
|
ObjectSetString(0,name3,OBJPROP_TOOLTIP,prefix+_patternNames[k]+" CD");
|
|
ObjectSetString(0,name4,OBJPROP_TOOLTIP,prefix+_patternNames[k]+" XAB="+xab);
|
|
if(k!=FIVEO) ObjectSetString(0,name5,OBJPROP_TOOLTIP,prefix+_patternNames[k]+" XAD="+xad);
|
|
ObjectSetString(0,name6,OBJPROP_TOOLTIP,prefix+_patternNames[k]+" ABC="+abc);
|
|
ObjectSetString(0,name7,OBJPROP_TOOLTIP,prefix+_patternNames[k]+" BCD="+bcd);
|
|
ObjectSetInteger(0,name0,OBJPROP_WIDTH,l_width);
|
|
ObjectSetInteger(0,name1,OBJPROP_WIDTH,l_width);
|
|
ObjectSetInteger(0,name2,OBJPROP_WIDTH,l_width);
|
|
ObjectSetInteger(0,name3,OBJPROP_WIDTH,l_width);
|
|
if(Fill_Patterns && (k!=FIVEO && k!=THREEDRIVES))
|
|
{
|
|
ObjectCreate(0,triangle_XB,OBJ_TRIANGLE,0,XDateTime,X,ADateTime,A,BDateTime,B);
|
|
ObjectCreate(0,triangle_BD,OBJ_TRIANGLE,0,BDateTime,B,CDateTime,C,DDateTime,D);
|
|
ObjectSetInteger(0,triangle_XB,OBJPROP_COLOR,bullish ? ClrBull : ClrBear);
|
|
ObjectSetInteger(0,triangle_XB,OBJPROP_STYLE,STYLE_SOLID);
|
|
ObjectSetInteger(0,triangle_XB,OBJPROP_FILL,true);
|
|
ObjectSetInteger(0,triangle_XB,OBJPROP_BACK,true);
|
|
ObjectSetInteger(0,triangle_XB,OBJPROP_SELECTABLE,true);
|
|
ObjectSetInteger(0,triangle_XB,OBJPROP_SELECTED,false);
|
|
ObjectSetInteger(0,triangle_BD,OBJPROP_COLOR,bullish ? ClrBull : ClrBear);
|
|
ObjectSetInteger(0,triangle_BD,OBJPROP_STYLE,STYLE_SOLID);
|
|
ObjectSetInteger(0,triangle_BD,OBJPROP_FILL,true);
|
|
ObjectSetInteger(0,triangle_BD,OBJPROP_BACK,true);
|
|
ObjectSetInteger(0,triangle_BD,OBJPROP_SELECTABLE,true);
|
|
ObjectSetInteger(0,triangle_BD,OBJPROP_SELECTED,false);
|
|
}
|
|
if(showPatternNames)
|
|
ShowComment(prefix+_patternNames[k]+" @ "+TimeToString(DDateTime));
|
|
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Helper method displays 4-point projections |
|
|
//+------------------------------------------------------------------+
|
|
void DisplayProjection(int k,bool bullish,
|
|
datetime ADateTime,double A,
|
|
datetime BDateTime,double B,
|
|
datetime CDateTime,double C,
|
|
datetime DDateTime,double D)
|
|
{
|
|
string unique=UniqueIdentifier(ADateTime,BDateTime,CDateTime,DDateTime);
|
|
string prefix=(bullish ? "Projected Bullish " : "Projected Bearish ");
|
|
string prefixName=(bullish ? "PU "+_identifier : "PD "+_identifier);
|
|
string name0=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" AB"+unique;
|
|
string name1=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" BC"+unique;
|
|
string name2=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" CD"+unique;
|
|
string pointA=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" PA"+unique;
|
|
string pointB=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" PB"+unique;
|
|
string pointC=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" PC"+unique;
|
|
string pointD=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" PD"+unique;
|
|
ObjectCreate(0,name0,OBJ_TREND,0,ADateTime,A,BDateTime,B);
|
|
ObjectCreate(0,name1,OBJ_TREND,0,BDateTime,B,CDateTime,C);
|
|
ObjectCreate(0,name2,OBJ_TREND,0,CDateTime,C,DDateTime,D);
|
|
ObjectSetInteger(0,name0,OBJPROP_COLOR, bullish ? ClrBullProjection : ClrBearProjection);
|
|
ObjectSetInteger(0,name1,OBJPROP_COLOR, bullish ? ClrBullProjection : ClrBearProjection);
|
|
ObjectSetInteger(0,name2,OBJPROP_COLOR, bullish ? ClrBullProjection : ClrBearProjection);
|
|
ObjectSetInteger(0,name0,OBJPROP_SELECTABLE,true);
|
|
ObjectSetInteger(0,name1,OBJPROP_SELECTABLE,true);
|
|
ObjectSetInteger(0,name2,OBJPROP_SELECTABLE,true);
|
|
ObjectSetString(0,name0,OBJPROP_TOOLTIP,prefix+_patternNames[k]+" AB");
|
|
ObjectSetString(0,name1,OBJPROP_TOOLTIP,prefix+_patternNames[k]+" BC");
|
|
ObjectSetString(0,name2,OBJPROP_TOOLTIP,prefix+_patternNames[k]+" CD");
|
|
ObjectSetInteger(0,name0,OBJPROP_WIDTH,l_width_proj);
|
|
ObjectSetInteger(0,name1,OBJPROP_WIDTH,l_width_proj);
|
|
ObjectSetInteger(0,name2,OBJPROP_WIDTH,l_width_proj);
|
|
ObjectSetInteger(0,name0,OBJPROP_STYLE,Style_Proj);
|
|
ObjectSetInteger(0,name1,OBJPROP_STYLE,Style_Proj);
|
|
ObjectSetInteger(0,name2,OBJPROP_STYLE,Style_Proj);
|
|
if(Show_descriptions)
|
|
{
|
|
ObjectCreate(0,pointA,OBJ_TEXT,0,ADateTime,A);
|
|
ObjectCreate(0,pointB,OBJ_TEXT,0,BDateTime,B);
|
|
ObjectCreate(0,pointC,OBJ_TEXT,0,CDateTime,C);
|
|
ObjectCreate(0,pointD,OBJ_TEXT,0,DDateTime,D);
|
|
ObjectSetString(0,pointA,OBJPROP_TOOLTIP,prefix+_patternNames[k]+" PA");
|
|
ObjectSetString(0,pointB,OBJPROP_TOOLTIP,prefix+_patternNames[k]+" PB");
|
|
ObjectSetString(0,pointC,OBJPROP_TOOLTIP,prefix+_patternNames[k]+" PC");
|
|
ObjectSetString(0,pointD,OBJPROP_TOOLTIP,prefix+_patternNames[k]+" PD");
|
|
ObjectSetString(0,pointA,OBJPROP_TEXT,"A");
|
|
ObjectSetString(0,pointA,OBJPROP_FONT,"Arial");
|
|
ObjectSetInteger(0,pointA,OBJPROP_FONTSIZE,Font_size);
|
|
ObjectSetInteger(0,pointA,OBJPROP_COLOR,bullish ? ClrBullProjection : ClrBearProjection);
|
|
ObjectSetString(0,pointB,OBJPROP_TEXT,"B");
|
|
ObjectSetString(0,pointB,OBJPROP_FONT,"Arial");
|
|
ObjectSetInteger(0,pointB,OBJPROP_FONTSIZE,Font_size);
|
|
ObjectSetInteger(0,pointB,OBJPROP_COLOR,bullish ? ClrBullProjection : ClrBearProjection);
|
|
ObjectSetString(0,pointC,OBJPROP_TEXT,"C");
|
|
ObjectSetString(0,pointC,OBJPROP_FONT,"Arial");
|
|
ObjectSetInteger(0,pointC,OBJPROP_FONTSIZE,Font_size);
|
|
ObjectSetInteger(0,pointC,OBJPROP_COLOR,bullish ? ClrBullProjection : ClrBearProjection);
|
|
ObjectSetString(0,pointD,OBJPROP_TEXT," D "+prefix+_patternNames[k]);
|
|
ObjectSetString(0,pointD,OBJPROP_FONT,"Arial");
|
|
ObjectSetInteger(0,pointD,OBJPROP_FONTSIZE,Font_size);
|
|
ObjectSetInteger(0,pointD,OBJPROP_COLOR,bullish ? ClrBullProjection : ClrBearProjection);
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Helper method displays 5-point projections |
|
|
//+------------------------------------------------------------------+
|
|
void DisplayProjection(int k,bool bullish,
|
|
datetime XDateTime,double X,
|
|
datetime ADateTime,double A,
|
|
datetime BDateTime,double B,
|
|
datetime CDateTime,double C,
|
|
datetime DDateTime,double D)
|
|
{
|
|
string unique=UniqueIdentifier(XDateTime,ADateTime,BDateTime,CDateTime,DDateTime);
|
|
string prefix=(bullish ? "Projected Bullish " : "Projected Bearish ");
|
|
string prefixName=(bullish ? "PU "+_identifier : "PD "+_identifier);
|
|
string name0=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" XA"+unique;
|
|
string name1=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" AB"+unique;
|
|
string name2=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" BC"+unique;
|
|
string name3=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" CD"+unique;
|
|
string name4=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" XAB"+unique;
|
|
string name5=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" XAD"+unique;
|
|
string name6=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" ABC"+unique;
|
|
string name7=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" BCD"+unique;
|
|
string pointX=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" PX"+unique;
|
|
string pointA=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" PA"+unique;
|
|
string pointB=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" PB"+unique;
|
|
string pointC=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" PC"+unique;
|
|
string pointD=prefixName+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" PD"+unique;
|
|
string xab=IntegerToString((int) MathRound(100*MathAbs(A-B)/MathAbs(X-A)));
|
|
string xad=IntegerToString((int) MathRound(100*MathAbs(D-A)/MathAbs(X-A)));
|
|
string abc=IntegerToString((int) MathRound(100*MathAbs(C-B)/MathAbs(B-A)));
|
|
//--- Cypher and Nen Start have the A-C top as XC/XA instead of CB/BA
|
|
if(k==CYPHER || k==NENSTAR || k==NEWCYPHER)
|
|
abc=IntegerToString((int) MathRound(100*MathAbs(X-C)/MathAbs(X-A)));
|
|
string bcd=IntegerToString((int) MathRound(100*MathAbs(C-D)/MathAbs(B-C)));
|
|
ObjectCreate(0,name0,OBJ_TREND,0,XDateTime,X,ADateTime,A);
|
|
ObjectCreate(0,name1,OBJ_TREND,0,ADateTime,A,BDateTime,B);
|
|
ObjectCreate(0,name2,OBJ_TREND,0,BDateTime,B,CDateTime,C);
|
|
ObjectCreate(0,name3,OBJ_TREND,0,CDateTime,C,DDateTime,D);
|
|
ObjectCreate(0,name4,OBJ_TREND,0,XDateTime,X,BDateTime,B);
|
|
if(k!=FIVEO) ObjectCreate(0,name5,OBJ_TREND,0,XDateTime,X,DDateTime,D);
|
|
ObjectCreate(0,name6,OBJ_TREND,0,ADateTime,A,CDateTime,C);
|
|
ObjectCreate(0,name7,OBJ_TREND,0,BDateTime,B,DDateTime,D);
|
|
ObjectSetInteger(0,name0,OBJPROP_COLOR, bullish ? ClrBullProjection : ClrBearProjection);
|
|
ObjectSetInteger(0,name1,OBJPROP_COLOR, bullish ? ClrBullProjection : ClrBearProjection);
|
|
ObjectSetInteger(0,name2,OBJPROP_COLOR, bullish ? ClrBullProjection : ClrBearProjection);
|
|
ObjectSetInteger(0,name3,OBJPROP_COLOR, bullish ? ClrBullProjection : ClrBearProjection);
|
|
ObjectSetInteger(0,name4,OBJPROP_COLOR,ClrRatio);
|
|
if(k!=FIVEO) ObjectSetInteger(0,name5,OBJPROP_COLOR,ClrRatio);
|
|
ObjectSetInteger(0,name6,OBJPROP_COLOR,ClrRatio);
|
|
ObjectSetInteger(0,name7,OBJPROP_COLOR,ClrRatio);
|
|
ObjectSetInteger(0,name0,OBJPROP_STYLE,Style_Proj);
|
|
ObjectSetInteger(0,name1,OBJPROP_STYLE,Style_Proj);
|
|
ObjectSetInteger(0,name2,OBJPROP_STYLE,Style_Proj);
|
|
ObjectSetInteger(0,name3,OBJPROP_STYLE,Style_Proj);
|
|
ObjectSetInteger(0,name4,OBJPROP_STYLE,Style_Ratio);
|
|
ObjectSetInteger(0,name5,OBJPROP_STYLE,Style_Ratio);
|
|
ObjectSetInteger(0,name6,OBJPROP_STYLE,Style_Ratio);
|
|
ObjectSetInteger(0,name7,OBJPROP_STYLE,Style_Ratio);
|
|
ObjectSetInteger(0,name0,OBJPROP_SELECTABLE,true);
|
|
ObjectSetInteger(0,name1,OBJPROP_SELECTABLE,true);
|
|
ObjectSetInteger(0,name2,OBJPROP_SELECTABLE,true);
|
|
ObjectSetInteger(0,name3,OBJPROP_SELECTABLE,true);
|
|
ObjectSetInteger(0,name4,OBJPROP_SELECTABLE,true);
|
|
if(k!=FIVEO) ObjectSetInteger(0,name5,OBJPROP_SELECTABLE,true);
|
|
ObjectSetInteger(0,name6,OBJPROP_SELECTABLE,true);
|
|
ObjectSetInteger(0,name7,OBJPROP_SELECTABLE,true);
|
|
ObjectSetString(0,name0,OBJPROP_TOOLTIP,prefix+_patternNames[k]+" XA");
|
|
ObjectSetString(0,name1,OBJPROP_TOOLTIP,prefix+_patternNames[k]+" AB");
|
|
ObjectSetString(0,name2,OBJPROP_TOOLTIP,prefix+_patternNames[k]+" BC");
|
|
ObjectSetString(0,name3,OBJPROP_TOOLTIP,prefix+_patternNames[k]+" CD");
|
|
ObjectSetString(0,name4,OBJPROP_TOOLTIP,prefix+_patternNames[k]+" XAB="+xab);
|
|
if(k!=FIVEO) ObjectSetString(0,name5,OBJPROP_TOOLTIP,prefix+_patternNames[k]+" XAD="+xad);
|
|
ObjectSetString(0,name6,OBJPROP_TOOLTIP,prefix+_patternNames[k]+" ABC="+abc);
|
|
ObjectSetString(0,name7,OBJPROP_TOOLTIP,prefix+_patternNames[k]+" BCD="+bcd);
|
|
if(Show_descriptions)
|
|
{
|
|
ObjectCreate(0,pointX,OBJ_TEXT,0,XDateTime,X);
|
|
ObjectCreate(0,pointA,OBJ_TEXT,0,ADateTime,A);
|
|
ObjectCreate(0,pointB,OBJ_TEXT,0,BDateTime,B);
|
|
ObjectCreate(0,pointC,OBJ_TEXT,0,CDateTime,C);
|
|
ObjectCreate(0,pointD,OBJ_TEXT,0,DDateTime,D);
|
|
ObjectSetString(0,pointX,OBJPROP_TOOLTIP,prefix+_patternNames[k]+" PX");
|
|
ObjectSetString(0,pointA,OBJPROP_TOOLTIP,prefix+_patternNames[k]+" PA");
|
|
ObjectSetString(0,pointB,OBJPROP_TOOLTIP,prefix+_patternNames[k]+" PB");
|
|
ObjectSetString(0,pointC,OBJPROP_TOOLTIP,prefix+_patternNames[k]+" PC");
|
|
ObjectSetString(0,pointD,OBJPROP_TOOLTIP,prefix+_patternNames[k]+" PD");
|
|
ObjectSetInteger(0,name0,OBJPROP_WIDTH,l_width_proj);
|
|
ObjectSetInteger(0,name1,OBJPROP_WIDTH,l_width_proj);
|
|
ObjectSetInteger(0,name2,OBJPROP_WIDTH,l_width_proj);
|
|
ObjectSetInteger(0,name3,OBJPROP_WIDTH,l_width_proj);
|
|
ObjectSetString(0,pointX,OBJPROP_TEXT,"X");
|
|
ObjectSetString(0,pointX,OBJPROP_FONT,"Arial");
|
|
ObjectSetInteger(0,pointX,OBJPROP_FONTSIZE,Font_size);
|
|
ObjectSetInteger(0,pointX,OBJPROP_COLOR,bullish ? ClrBullProjection : ClrBearProjection);
|
|
ObjectSetString(0,pointA,OBJPROP_TEXT,"A");
|
|
ObjectSetString(0,pointA,OBJPROP_FONT,"Arial");
|
|
ObjectSetInteger(0,pointA,OBJPROP_FONTSIZE,Font_size);
|
|
ObjectSetInteger(0,pointA,OBJPROP_COLOR,bullish ? ClrBullProjection : ClrBearProjection);
|
|
ObjectSetString(0,pointB,OBJPROP_TEXT,"B");
|
|
ObjectSetString(0,pointB,OBJPROP_FONT,"Arial");
|
|
ObjectSetInteger(0,pointB,OBJPROP_FONTSIZE,Font_size);
|
|
ObjectSetInteger(0,pointB,OBJPROP_COLOR,bullish ? ClrBullProjection : ClrBearProjection);
|
|
ObjectSetString(0,pointC,OBJPROP_TEXT,"C");
|
|
ObjectSetString(0,pointC,OBJPROP_FONT,"Arial");
|
|
ObjectSetInteger(0,pointC,OBJPROP_FONTSIZE,Font_size);
|
|
ObjectSetInteger(0,pointC,OBJPROP_COLOR,bullish ? ClrBullProjection : ClrBearProjection);
|
|
ObjectSetString(0,pointD,OBJPROP_TEXT," D "+prefix+_patternNames[k]);
|
|
ObjectSetString(0,pointD,OBJPROP_FONT,"Arial");
|
|
ObjectSetInteger(0,pointD,OBJPROP_FONTSIZE,Font_size);
|
|
ObjectSetInteger(0,pointD,OBJPROP_COLOR,bullish ? ClrBullProjection : ClrBearProjection);
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Helper method undisplays projections |
|
|
//+------------------------------------------------------------------+
|
|
void UndisplayProjections()
|
|
{
|
|
for(int i=0; i<_drawnProjectionInstanceCounter; i++)
|
|
{
|
|
PATTERN_INSTANCE instance=_drawnProjectionInstances[i];
|
|
int k=instance.patternIndex;
|
|
bool bullish=instance.bullish;
|
|
datetime XDateTime=instance.XDateTime;
|
|
datetime ADateTime=instance.ADateTime;
|
|
datetime BDateTime=instance.BDateTime;
|
|
datetime CDateTime=instance.CDateTime;
|
|
datetime DDateTime=instance.DDateTime;
|
|
//--- Delete pattern from chart
|
|
string unique=Is4PointPattern(k)?UniqueIdentifier(ADateTime,BDateTime,CDateTime,DDateTime) : UniqueIdentifier(XDateTime,ADateTime,BDateTime,CDateTime,DDateTime);
|
|
string prefix=(bullish ? "PU "+_identifier : "PD "+_identifier);
|
|
string name0=prefix+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" XA"+unique;
|
|
string name1=prefix+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" AB"+unique;
|
|
string name2=prefix+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" BC"+unique;
|
|
string name3=prefix+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" CD"+unique;
|
|
string name4=prefix+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" XAB"+unique;
|
|
string name5=prefix+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" XAD"+unique;
|
|
string name6=prefix+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" ABC"+unique;
|
|
string name7=prefix+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" BCD"+unique;
|
|
string pointX=prefix+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" PX"+unique;
|
|
string pointA=prefix+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" PA"+unique;
|
|
string pointB=prefix+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" PB"+unique;
|
|
string pointC=prefix+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" PC"+unique;
|
|
string pointD=prefix+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" PD"+unique;
|
|
ObjectDelete(0,name0);
|
|
ObjectDelete(0,name1);
|
|
ObjectDelete(0,name2);
|
|
ObjectDelete(0,name3);
|
|
ObjectDelete(0,name4);
|
|
ObjectDelete(0,name5);
|
|
ObjectDelete(0,name6);
|
|
ObjectDelete(0,name7);
|
|
ObjectDelete(0,pointX);
|
|
ObjectDelete(0,pointA);
|
|
ObjectDelete(0,pointB);
|
|
ObjectDelete(0,pointC);
|
|
ObjectDelete(0,pointD);
|
|
}
|
|
_drawnProjectionInstanceCounter=0;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Helper method undisplays recently drawn patterns |
|
|
//+------------------------------------------------------------------+
|
|
void UndisplayPatterns()
|
|
{
|
|
for(int i=0; i<_patternInstanceCounter; i++)
|
|
{
|
|
PATTERN_INSTANCE instance=_patternInstances[i];
|
|
int k=instance.patternIndex;
|
|
bool bullish=instance.bullish;
|
|
datetime XDateTime=instance.XDateTime;
|
|
datetime ADateTime=instance.ADateTime;
|
|
datetime BDateTime=instance.BDateTime;
|
|
datetime CDateTime=instance.CDateTime;
|
|
datetime DDateTime=instance.DDateTime;
|
|
//--- Delete pattern from chart
|
|
string unique=Is4PointPattern(k)?UniqueIdentifier(ADateTime,BDateTime,CDateTime,DDateTime) : UniqueIdentifier(XDateTime,ADateTime,BDateTime,CDateTime,DDateTime);
|
|
string prefix=(bullish ? "U "+_identifier : "D "+_identifier);
|
|
string name0=prefix+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" XA"+unique;
|
|
string name1=prefix+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" AB"+unique;
|
|
string name2=prefix+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" BC"+unique;
|
|
string name3=prefix+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" CD"+unique;
|
|
string name4=prefix+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" XAB"+unique;
|
|
string name5=prefix+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" XAD"+unique;
|
|
string name6=prefix+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" ABC"+unique;
|
|
string name7=prefix+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" BCD"+unique;
|
|
string triangle_XB=prefix+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" XB"+unique;
|
|
string triangle_BD=prefix+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" BD"+unique;
|
|
string pointX=prefix+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" PX"+unique;
|
|
string pointA=prefix+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" PA"+unique;
|
|
string pointB=prefix+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" PB"+unique;
|
|
string pointC=prefix+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" PC"+unique;
|
|
string pointD=prefix+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" PD"+unique;
|
|
ObjectDelete(0,name0);
|
|
ObjectDelete(0,name1);
|
|
ObjectDelete(0,name2);
|
|
ObjectDelete(0,name3);
|
|
ObjectDelete(0,name4);
|
|
ObjectDelete(0,name5);
|
|
ObjectDelete(0,name6);
|
|
ObjectDelete(0,name7);
|
|
ObjectDelete(0,triangle_XB);
|
|
ObjectDelete(0,triangle_BD);
|
|
ObjectDelete(0,pointX);
|
|
ObjectDelete(0,pointA);
|
|
ObjectDelete(0,pointB);
|
|
ObjectDelete(0,pointC);
|
|
ObjectDelete(0,pointD);
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Helper method undisplays recently drawn PRZ |
|
|
//+------------------------------------------------------------------+
|
|
void UndisplayPRZs()
|
|
{
|
|
for(int i=0; i<_patternInstanceCounter; i++)
|
|
{
|
|
PATTERN_INSTANCE instance=_patternInstances[i];
|
|
int k=instance.patternIndex;
|
|
bool bullish=instance.bullish;
|
|
datetime XDateTime=instance.XDateTime;
|
|
datetime ADateTime=instance.ADateTime;
|
|
datetime BDateTime=instance.BDateTime;
|
|
datetime CDateTime=instance.CDateTime;
|
|
datetime DDateTime=instance.DDateTime;
|
|
//--- Delete pattern from chart
|
|
string unique=Is4PointPattern(k)?UniqueIdentifier(ADateTime,BDateTime,CDateTime,DDateTime) : UniqueIdentifier(XDateTime,ADateTime,BDateTime,CDateTime,DDateTime);
|
|
string prefix=(bullish ? "U "+_identifier : "D "+_identifier);
|
|
string linePRZ=prefix+StringFormat("%x",_timeOfInit)+IntegerToString(k)+" PRZ"+unique;
|
|
ObjectDelete(0,linePRZ);
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
//+------------------------------------------------------------------+
|
|
//| Helper method populates pattern arrays |
|
|
//+------------------------------------------------------------------+
|
|
int PopulatePatterns()
|
|
{
|
|
//--- Create pattern descriptor structs with relevant ratios
|
|
PATTERN_DESCRIPTOR trendlike1_abcd= {0,0,0.382,0.382,2.618,2.618,0,0,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR trendlike2_abcd= {0,0,0.5,0.5,2.0,2.0,0,0,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR perfect_abcd= {0,0,0.618,0.618,1.618,1.618,0,0,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR ideal1_abcd= {0,0,0.707,0.707,1.41,1.41,0,0,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR ideal2_abcd= {0,0,0.786,0.786,1.27,1.27,0,0,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR rangelike_abcd= {0,0,0.886,0.886,1.13,1.13,0,0,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR alt127_trendlike1_abcd= {0,0,0.382,0.382,2.618,3.618,0,0,0,0,0,0,1.272,1.272};
|
|
PATTERN_DESCRIPTOR alt127_trendlike2_abcd= {0,0,0.5,0.5,2.0,3.618,0,0,0,0,0,0,1.272,1.272};
|
|
PATTERN_DESCRIPTOR alt127_perfect_abcd= {0,0,0.618,0.618,1.618,3.618,0,0,0,0,0,0,1.272,1.272};
|
|
PATTERN_DESCRIPTOR alt127_ideal1_abcd= {0,0,0.707,0.707,1.41,3.618,0,0,0,0,0,0,1.272,1.272};
|
|
PATTERN_DESCRIPTOR alt127_ideal2_abcd= {0,0,0.786,0.786,1.27,3.618,0,0,0,0,0,0,1.272,1.272};
|
|
PATTERN_DESCRIPTOR alt127_rangelike_abcd= {0,0,0.886,0.886,1.13,3.618,0,0,0,0,0,0,1.272,1.272};
|
|
PATTERN_DESCRIPTOR rec_trendlike1_abcd= {0,0,2.618,2.618,0.382,0.382,0,0,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR rec_trendlike2_abcd= {0,0,2.0,2.0,0.5,0.5,0,0,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR rec_perfect_abcd= {0,0,1.618,1.618,0.618,0.618,0,0,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR rec_ideal1_abcd= {0,0,1.41,1.41,0.707,0.707,0,0,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR rec_ideal2_abcd= {0,0,1.27,1.27,0.786,0.786,0,0,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR rec_rangelike_abcd= {0,0,1.13,1.13,0.886,0.886,0,0,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR gartley= {0.618,0.618,0.382,0.886,1.272,1.618,0.786,0.786,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR bat= {0.382,0.5,0.382,0.886,1.618,2.618,0.886,0.886,0,0,0,0,0,0 };
|
|
PATTERN_DESCRIPTOR altbat= {0.382,0.382,0.382,0.886,2.0,3.618,1.13,1.13,0,0,0,0,0,0 };
|
|
PATTERN_DESCRIPTOR fiveo= {1.13,1.618,1.618,2.24,0.5,0.5,0,0,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR butterfly= {0.786,0.786,0.382,0.886,1.618,2.618,1.272,1.618,0,0,0,0,0,0 };
|
|
PATTERN_DESCRIPTOR crab= {0.382,0.618,0.382,0.886,2.24,3.618,1.618,1.618,0,0,0,0,0,0 };
|
|
PATTERN_DESCRIPTOR deepcrab= {0.886,0.886,0.382,0.886,2.0,3.618,1.618,1.618,0,0,0,0,0,0 };
|
|
PATTERN_DESCRIPTOR threedrives= {1.272,1.618,0.618,0.786,1.272,1.618,0,0,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR shark= {0,0,1.13,1.618,1.618,2.24,0,0,0.886,1.13,0,0,0,0};
|
|
PATTERN_DESCRIPTOR cypher= {0.382,0.618,0,0,0,0,0,0,0.786,0.786,1.13,1.414,0,0};
|
|
PATTERN_DESCRIPTOR nenstar= {0.382,0.618,0,0,0,0,0,0,1.272,1.272,1.13,1.414,0,0};
|
|
PATTERN_DESCRIPTOR blackswan= {1.382,2.618,0.236,0.5,1.128,2,1.128,2.618,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR whiteswan= {0.382,0.724,2,4.237,0.5,0.886,0.382,0.886,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR one2one= {0.5,0.786,1.128,3.618,0.382,0.786,0.382,0.786,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR newcypher= {0.382,0.618,0,0,0,0,0,0,0.786,0.786,1.414,2.14,0,0};
|
|
PATTERN_DESCRIPTOR navarro200= {0.382,0.786,0.886,1.128,0.886,3.618,0.886,1.128,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR leonardo= {0.5,0.5,0.382,0.886,1.128,2.618,0.786,0.786,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR kane= {0.685,0.685,0.382,0.886,0,0,1.460,1.460,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR garfly= {0.618,0.618,0.382,0.886,1.618,2.24,1.272,1.272,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR maxbat= {0.382,0.618,0.382,0.886,1.272,2.618,0.886,0.886,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR maxgartley= {0.382,0.618,0.382,0.886,1.128,2.236,0.618,0.786,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR maxbutterfly= {0.618,0.886,0.382,0.886,1.272,2.618,1.272,1.618,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR gartley113= {0.618,0.618,0.382,0.886,1.13,1.13,0.786,0.786,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR butterfly113= {0.786,1,0.618,1,1.128,1.618,1.128,1.128,0,0,0,0,0,0 };
|
|
PATTERN_DESCRIPTOR anti_gartley= {0.618,0.786,1.129,2.618,1.618,1.618,1.272,1.272,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR anti_bat= {0.382,0.618,1.129,2.618,2.000,2.618,1.129,1.129,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR anti_altbat= {0.276,0.500,1.129,2.618,2.618,2.618,0.885,0.885,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR anti_fiveo= {2.000,2.000,0.446,0.618,0.618,0.885,0,0,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR anti_butterfly= {0.382,0.618,1.129,2.618,1.272,1.272,0.618,0.786,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR anti_crab= {0.276,0.446,1.129,2.618,1.618,2.618,0.618,0.618,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR anti_deepcrab= {0.276,0.500,1.129,2.618,1.129,1.129,0.618,0.618,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR anti_threedrives= {0.618,0.786,1.272,1.618,0.618,0.786,0,0,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR anti_shark= {0.446,0.618,0.618,0.885,0,0,0,0,0.885,1.129,0,0,0,0};
|
|
PATTERN_DESCRIPTOR anti_cypher= {0,0,0,0,1.618,2.618,0,0,1.272,1.272,0.707,0.885,0,0};
|
|
PATTERN_DESCRIPTOR anti_nenstar= {0,0,0,0,1.618,2.618,0,0,0.786,0.786,0.707,0.885,0,0};
|
|
PATTERN_DESCRIPTOR anti_blackswan= {0.500,0.887,2.000,4.237,0.382,0.724,0.382,0.887,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR anti_whiteswan= {1.129,2.000,0.236,0.500,1.381,2.618,1.129,2.618,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR anti_one2one= {1.272,2.618,0.276,0.887,1.272,2.000,1.272,2.618,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR anti_newcypher= {0,0,0,0,1.618,2.618,0,0,1.272,1.272,0.467,0.707,0,0};
|
|
PATTERN_DESCRIPTOR anti_navarro200= {0.276,1.129,0.887,1.129,1.272,2.618,0.887,1.129,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR anti_leonardo= {0.382,0.887,1.129,2.618,2.000,2.000,1.272,1.272,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR anti_kane= {0,0,1.129,2.618,1.460,1.460,0.685,0.685,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR anti_garfly= {0.446,0.618,1.129,2.618,1.618,1.618,0.786,0.786,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR anti_maxbat= {0.382,0.786,1.129,2.618,1.618,2.618,1.129,1.129,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR anti_maxgartley= {0.447,0.887,1.129,2.618,1.618,2.618,1.272,1.618,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR anti_maxbutterfly= {0.382,0.786,1.129,2.618,1.129,1.618,0.618,0.786,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR anti_gartley113= {0.885,0.885,1.129,2.618,1.618,1.618,1.272,1.272,0,0,0,0,0,0};
|
|
PATTERN_DESCRIPTOR anti_butterfly113= {0.618,0.887,1.000,1.618,1.000,1.272,0.887,0.887,0,0,0,0,0,0};
|
|
|
|
//--- Initialize arrays
|
|
_maxProjectionInstances=4;
|
|
_maxPatternInstances=NUM_PATTERNS*SIZE_PATTERN_BUFFER;
|
|
_maxDrawnProjectionInstances=4;
|
|
if(ArrayResize(_patterns,NUM_PATTERNS)<NUM_PATTERNS)
|
|
{
|
|
printf("Error allocating array: "+IntegerToString(GetLastError()));
|
|
return INIT_FAILED;
|
|
}
|
|
if(ArrayResize(_patternNames,NUM_PATTERNS)<NUM_PATTERNS)
|
|
{
|
|
printf("Error allocating array: "+IntegerToString(GetLastError()));
|
|
return INIT_FAILED;
|
|
}
|
|
if(ArrayResize(_patternX,NUM_PATTERNS)<NUM_PATTERNS)
|
|
{
|
|
printf("Error allocating array: "+IntegerToString(GetLastError()));
|
|
return INIT_FAILED;
|
|
}
|
|
if(ArrayResize(_patternA,NUM_PATTERNS)<NUM_PATTERNS)
|
|
{
|
|
printf("Error allocating array: "+IntegerToString(GetLastError()));
|
|
return INIT_FAILED;
|
|
}
|
|
if(ArrayResize(_patternB,NUM_PATTERNS)<NUM_PATTERNS)
|
|
{
|
|
printf("Error allocating array: "+IntegerToString(GetLastError()));
|
|
return INIT_FAILED;
|
|
}
|
|
if(ArrayResize(_patternC,NUM_PATTERNS)<NUM_PATTERNS)
|
|
{
|
|
printf("Error allocating array: "+IntegerToString(GetLastError()));
|
|
return INIT_FAILED;
|
|
}
|
|
if(ArrayResize(_patternD,NUM_PATTERNS)<NUM_PATTERNS)
|
|
{
|
|
printf("Error allocating array: "+IntegerToString(GetLastError()));
|
|
return INIT_FAILED;
|
|
}
|
|
if(ArrayResize(_patternCounter,NUM_PATTERNS)<NUM_PATTERNS)
|
|
{
|
|
printf("Error allocating array: "+IntegerToString(GetLastError()));
|
|
return INIT_FAILED;
|
|
}
|
|
if(ArrayResize(_patternInstances,_maxPatternInstances)<_maxPatternInstances)
|
|
{
|
|
printf("Error allocating array: "+IntegerToString(GetLastError()));
|
|
return INIT_FAILED;
|
|
}
|
|
if(ArrayResize(_projectionInstances,_maxProjectionInstances)<_maxProjectionInstances)
|
|
{
|
|
printf("Error allocating array: "+IntegerToString(GetLastError()));
|
|
return INIT_FAILED;
|
|
}
|
|
if(ArrayResize(_drawnProjectionInstances,_maxDrawnProjectionInstances)<_maxDrawnProjectionInstances)
|
|
{
|
|
printf("Error allocating array: "+IntegerToString(GetLastError()));
|
|
return INIT_FAILED;
|
|
}
|
|
ArrayFill(_patternCounter,0,NUM_PATTERNS,0);
|
|
//--- Fill in the pattern arrays
|
|
_patterns[TRENDLIKE1_ABCD]=trendlike1_abcd; _patternNames[TRENDLIKE1_ABCD]="Trendlike AB=CD #1";
|
|
_patterns[TRENDLIKE2_ABCD]=trendlike2_abcd; _patternNames[TRENDLIKE2_ABCD]="Trendlike AB=CD #2";
|
|
_patterns[PERFECT_ABCD]=perfect_abcd; _patternNames[PERFECT_ABCD]="Perfect AB=CD";
|
|
_patterns[IDEAL1_ABCD]=ideal1_abcd; _patternNames[IDEAL1_ABCD]="Ideal AB=CD #1";
|
|
_patterns[IDEAL2_ABCD]=ideal2_abcd; _patternNames[IDEAL2_ABCD]="Ideal AB=CD #2";
|
|
_patterns[RANGELIKE_ABCD]=rangelike_abcd; _patternNames[RANGELIKE_ABCD]="Rangelike AB=CD";
|
|
_patterns[ALT127_TRENDLIKE1_ABCD]=alt127_trendlike1_abcd; _patternNames[ALT127_TRENDLIKE1_ABCD]="Trendlike 1.27 AB=CD #1";
|
|
_patterns[ALT127_TRENDLIKE2_ABCD]=alt127_trendlike2_abcd; _patternNames[ALT127_TRENDLIKE2_ABCD]="Trendlike 1.27 AB=CD #2";
|
|
_patterns[ALT127_PERFECT_ABCD]=alt127_perfect_abcd; _patternNames[ALT127_PERFECT_ABCD]="Perfect 1.27 AB=CD";
|
|
_patterns[ALT127_IDEAL1_ABCD]=alt127_ideal1_abcd; _patternNames[ALT127_IDEAL1_ABCD]="Ideal 1.27 AB=CD #1";
|
|
_patterns[ALT127_IDEAL2_ABCD]=alt127_ideal2_abcd; _patternNames[ALT127_IDEAL2_ABCD]="Ideal 1.27 AB=CD #2";
|
|
_patterns[ALT127_RANGELIKE_ABCD]=alt127_rangelike_abcd; _patternNames[ALT127_RANGELIKE_ABCD]="Rangelike 1.27 AB=CD";
|
|
_patterns[REC_TRENDLIKE1_ABCD]=rec_trendlike1_abcd; _patternNames[REC_TRENDLIKE1_ABCD]="Rec. Trendlike AB=CD #1";
|
|
_patterns[REC_TRENDLIKE2_ABCD]=rec_trendlike2_abcd; _patternNames[REC_TRENDLIKE2_ABCD]="Rec. Trendlike AB=CD #2";
|
|
_patterns[REC_PERFECT_ABCD]=rec_perfect_abcd; _patternNames[REC_PERFECT_ABCD]="Rec. Perfect AB=CD";
|
|
_patterns[REC_IDEAL1_ABCD]=rec_ideal1_abcd; _patternNames[REC_IDEAL1_ABCD]="Rec. Ideal AB=CD #1";
|
|
_patterns[REC_IDEAL2_ABCD]=rec_ideal2_abcd; _patternNames[REC_IDEAL2_ABCD]="Rec. Ideal AB=CD #2";
|
|
_patterns[REC_RANGELIKE_ABCD]=rec_rangelike_abcd; _patternNames[REC_RANGELIKE_ABCD]="Rec. Rangelike AB=CD";
|
|
_patterns[GARTLEY]=gartley; _patternNames[GARTLEY]="Gartley";
|
|
_patterns[BAT]=bat; _patternNames[BAT]="Bat";
|
|
_patterns[ALTBAT]=altbat; _patternNames[ALTBAT]="Alt. Bat";
|
|
_patterns[FIVEO]=fiveo; _patternNames[FIVEO]="5-0";
|
|
_patterns[BUTTERFLY]=butterfly; _patternNames[BUTTERFLY]="Butterfly";
|
|
_patterns[CRAB]=crab; _patternNames[CRAB]="Crab";
|
|
_patterns[DEEPCRAB]=deepcrab; _patternNames[DEEPCRAB]="Deep Crab";
|
|
_patterns[THREEDRIVES]=threedrives; _patternNames[THREEDRIVES]="Three Drives";
|
|
_patterns[CYPHER]=cypher; _patternNames[CYPHER]="Cypher";
|
|
_patterns[SHARK]=shark; _patternNames[SHARK]="Shark";
|
|
_patterns[NENSTAR]=nenstar; _patternNames[NENSTAR]="Nen Star";
|
|
_patterns[BLACKSWAN]=blackswan; _patternNames[BLACKSWAN]="Black Swan";
|
|
_patterns[WHITESWAN]=whiteswan; _patternNames[WHITESWAN]="White Swan";
|
|
_patterns[ONE2ONE]=one2one; _patternNames[ONE2ONE]="One2One";
|
|
_patterns[NEWCYPHER]=newcypher; _patternNames[NEWCYPHER]="New Cypher";
|
|
_patterns[NAVARRO200]=navarro200; _patternNames[NAVARRO200]="Navarro 200";
|
|
_patterns[LEONARDO]=leonardo; _patternNames[LEONARDO]="Leonardo";
|
|
_patterns[KANE]=kane; _patternNames[KANE]="Kane";
|
|
_patterns[GARFLY]=garfly; _patternNames[GARFLY]="Garfly";
|
|
_patterns[MAXBAT]=maxbat; _patternNames[MAXBAT]="Max. Bat";
|
|
_patterns[MAXGARTLEY]=maxgartley; _patternNames[MAXGARTLEY]="Max. Gartley";
|
|
_patterns[MAXBUTTERFLY]=maxbutterfly; _patternNames[MAXBUTTERFLY]="Max. Butterfly";
|
|
_patterns[GARTLEY113]=gartley113; _patternNames[GARTLEY113]="Gartley 113";
|
|
_patterns[BUTTERFLY113]=butterfly113; _patternNames[BUTTERFLY113]="Butterfly 113";
|
|
_patterns[ANTI_GARTLEY]=anti_gartley; _patternNames[ANTI_GARTLEY]="Anti Gartley";
|
|
_patterns[ANTI_BAT]=anti_bat; _patternNames[ANTI_BAT]="Anti Bat";
|
|
_patterns[ANTI_ALTBAT]=anti_altbat; _patternNames[ANTI_ALTBAT]="Anti Alt. Bat";
|
|
_patterns[ANTI_FIVEO]=anti_fiveo; _patternNames[ANTI_FIVEO]="Anti 5-0";
|
|
_patterns[ANTI_BUTTERFLY]=anti_butterfly; _patternNames[ANTI_BUTTERFLY]="Anti Butterfly";
|
|
_patterns[ANTI_CRAB]=anti_crab; _patternNames[ANTI_CRAB]="Anti Crab";
|
|
_patterns[ANTI_DEEPCRAB]=anti_deepcrab; _patternNames[ANTI_DEEPCRAB]="Anti Deep Crab";
|
|
_patterns[ANTI_THREEDRIVES]=anti_threedrives; _patternNames[ANTI_THREEDRIVES]="Anti Three Drives";
|
|
_patterns[ANTI_CYPHER]=anti_cypher; _patternNames[ANTI_CYPHER]="Anti Cypher";
|
|
_patterns[ANTI_SHARK]=anti_shark; _patternNames[ANTI_SHARK]="Anti Shark";
|
|
_patterns[ANTI_NENSTAR]=anti_nenstar; _patternNames[ANTI_NENSTAR]="Anti Nen Star";
|
|
_patterns[ANTI_BLACKSWAN]=anti_blackswan; _patternNames[ANTI_BLACKSWAN]="Anti Black Swan";
|
|
_patterns[ANTI_WHITESWAN]=anti_whiteswan; _patternNames[ANTI_WHITESWAN]="Anti White Swan";
|
|
_patterns[ANTI_ONE2ONE]=anti_one2one; _patternNames[ANTI_ONE2ONE]="Anti One2One";
|
|
_patterns[ANTI_NEWCYPHER]=anti_newcypher; _patternNames[ANTI_NEWCYPHER]="Anti New Cypher";
|
|
_patterns[ANTI_NAVARRO200]=anti_navarro200; _patternNames[ANTI_NAVARRO200]="Anti Navarro 200";
|
|
_patterns[ANTI_LEONARDO]=anti_leonardo; _patternNames[ANTI_LEONARDO]="Anti Leonardo";
|
|
_patterns[ANTI_KANE]=anti_kane; _patternNames[ANTI_KANE]="Anti Kane";
|
|
_patterns[ANTI_GARFLY]=anti_garfly; _patternNames[ANTI_GARFLY]="Anti Garfly";
|
|
_patterns[ANTI_MAXBAT]=anti_maxbat; _patternNames[ANTI_MAXBAT]="Anti Max. Bat";
|
|
_patterns[ANTI_MAXGARTLEY]=anti_maxgartley; _patternNames[ANTI_MAXGARTLEY]="Anti Max. Gartley";
|
|
_patterns[ANTI_MAXBUTTERFLY]=anti_maxbutterfly; _patternNames[ANTI_MAXBUTTERFLY]="Anti Max. Butterfly";
|
|
_patterns[ANTI_GARTLEY113]=anti_gartley113; _patternNames[ANTI_GARTLEY113]="Anti Gartley 113";
|
|
_patterns[ANTI_BUTTERFLY113]=anti_butterfly113; _patternNames[ANTI_BUTTERFLY113]="Anti Butterfly 113";
|
|
return INIT_SUCCEEDED;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Helper method creates hexadecimal encoding of datetimes |
|
|
//+------------------------------------------------------------------+
|
|
string UniqueIdentifier(datetime ADateTime,datetime BDateTime,datetime CDateTime,datetime DDateTime)
|
|
{
|
|
return " "+StringFormat("%x",ADateTime)+StringFormat("%x",BDateTime)+StringFormat("%x",CDateTime)+StringFormat("%x",DDateTime);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Helper method creates hexadecimal encoding of datetimes |
|
|
//+------------------------------------------------------------------+
|
|
string UniqueIdentifier(datetime XDateTime,datetime ADateTime,datetime BDateTime,datetime CDateTime,datetime DDateTime)
|
|
{
|
|
return " "+StringFormat("%x",XDateTime)+StringFormat("%x",ADateTime)+StringFormat("%x",BDateTime)+StringFormat("%x",CDateTime)+StringFormat("%x",DDateTime);
|
|
}
|
|
//+------------------------------------------------------------------+
|