Warrior_EA/Signals/SignalIchimoku.mqh

643 lines
33 KiB
MQL5
Raw Permalink Normal View History

//+------------------------------------------------------------------+
//| SignalIchimoku.mqh |
//| AnimateDread |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#include "..\Expert\ExpertSignalCustom.mqh"
// wizard description start
//+------------------------------------------------------------------+
//| Description of the class |
//| Title=Signals of indicator 'Ichimoku Kinko Hyo' |
//| Type=SignalAdvanced |
//| Name=Ichimoku |
//| ShortName=Ichimoku |
//| Class=CSignalIchimoku |
//| Page=signal_ichimoku |
//| Parameter=PeriodTenkan,int,9,Tenkan-sen period |
//| Parameter=PeriodKijun,int,26,Kijun-sen period |
//| Parameter=PeriodSenkou,int,52,Senkou Span B period |
//+------------------------------------------------------------------+
// wizard description end
//+------------------------------------------------------------------+
//| Class CSignalIchimoku. |
//| Purpose: Class of generator of trade signals based on the |
//| 'Ichimoku Kinko Hyo' indicator. |
//| Is derived from the CExpertSignalCustom class. |
//| |
//| Written from scratch - unlike MA/RSI/MACD there is NO Ichimoku |
//| signal module in the MQL5 standard library to port, so the |
//| twelve market models below encode the conventional Ichimoku |
//| readings directly rather than inheriting a stock pattern set. |
//| Between them they cover the full canonical repertoire: |
//| |
//| - Tenkan/Kijun cross, GRADED the classic three ways by where |
//| the cross happens relative to the Kumo: below it = weak |
//| (model 3), inside it = neutral (model 5), above it = strong |
//| (model 10), mirrored for shorts. Grading is the point of the |
//| TK cross in Ichimoku doctrine - an ungraded cross treats a |
//| counter-trend cross under the cloud as if it were a trend |
//| continuation above it, which is precisely the trade the |
//| method tells you to stand down on. |
//| - Kumo breakout (model 8), and the same breakout through a |
//| THIN cloud (model 9) - cloud thickness is Ichimoku's own |
//| measure of how much support/resistance is actually there, so |
//| a break through a thin Kumo is the higher-quality one. |
//| - Chikou Span confirmation (model 2): the lagging span clear |
//| of BOTH the price 26 periods back and the cloud at that |
//| point, which is the full form of the confirmation rather |
//| than the price-only shorthand. |
//| - Kijun-sen cross (model 6) and the Kijun-sen bounce (model 7) |
//| - the pull-back entry that the base line's "magnet" effect |
//| produces, which is why that model also requires the line to |
//| be holding its level rather than sloping against the trade. |
//| - Kumo twist (model 4): Senkou A actually CROSSING Senkou B |
//| in the projected cloud, as distinct from the cloud merely |
//| BEING one colour or the other (model 1). |
//| - Price vs the cloud (model 0), the standing trend bias every |
//| other reading is confirmed against. |
//| - Sanyaku Kouten / Sanyaku Gyakuten (model 11), the "three |
//| roles" alignment - Tenkan above Kijun, Chikou clear of past |
//| price, price clear of the cloud, all at once. Ichimoku's own |
//| strongest signal, hence the top weight. |
//| |
//| Pattern numbering is ordered by conviction, weakest first, so |
//| the highest-numbered match wins - the same convention the stock |
//| wizard signals use (see LongCondition() below). Weights follow |
//| the standard library's own scheme: the confirming STATES that |
//| hold across long stretches of bars (models 0-2) plus the weak |
//| cross grade (model 3) all sit at the 10 floor that CSignalMA, |
//| CSignalRSI and CSignalMACD give their Pattern_0, and the event |
//| models are spread across 30-100 by how much the method itself |
//| trusts each. Nothing between 10 and 30 - a reading either |
//| corroborates or it triggers. |
//| |
//| LOOKAHEAD - the single thing to get right in this class. MT5's |
//| iIchimoku does NOT pre-shift its buffers; it stores raw |
//| per-bar values and shifts only the DRAWING (Ichimoku.mq5: |
//| PlotIndexSetInteger(2,PLOT_SHIFT,InpKijun) for the Span A/B |
//| cloud plot, and (3,PLOT_SHIFT,-InpKijun) for Chikou). In |
//| series (reverse) indexing that means: |
//| - SenkouSpanA/B(i) is computed FROM bar i and is DRAWN at bar |
//| i-Kijun, i.e. Kijun bars into the future. So the cloud |
//| actually sitting under bar `idx` is SenkouSpanA/B(idx+Kijun) |
//| - derived from bar idx+Kijun and older, hence strictly past |
//| data. That +Kijun offset is what CloudTop()/CloudBottom() |
//| below exist to apply; reading SenkouSpanA/B(idx) as "the |
//| cloud here" is the classic Ichimoku backtest bug. |
//| - SenkouSpanA/B(idx) with NO offset is legitimate as the |
//| PROJECTED cloud (what the chart already draws ahead of the |
//| current bar) - it is computed from bar idx, so a live bar |
//| really does know it. Models 2 and 3 use it in exactly that |
//| sense, and nothing here ever indexes BELOW idx. |
//| - ChinkouSpan(i) is just Close(i), drawn at i+Kijun. The |
//| Chikou value plotted AT bar idx would be Close(idx-Kijun) - |
//| a bar Kijun into the FUTURE - so it is never read. The |
//| lookahead-free statement of the same reading is "is this |
//| bar's close clear of what price was Kijun bars ago", i.e. |
//| Close(idx) vs Close(idx+Kijun), and of the cloud that was |
//| plotted THERE, i.e. the spans at idx+2*Kijun. That is what |
//| model 9 does, and why CiIchimoku::ChinkouSpan() is |
//| deliberately never called anywhere in this file. |
//+------------------------------------------------------------------+
class CSignalIchimoku : public CExpertSignalCustom
{
protected:
CiIchimoku m_ichimoku; // object-indicator
//--- adjusted parameters
int m_period_tenkan; // the "Tenkan-sen period" parameter of the indicator
int m_period_kijun; // the "Kijun-sen period" parameter of the indicator
int m_period_senkou; // the "Senkou Span B period" parameter of the indicator
//--- "weights" of market models (0-100), numbered weakest-to-strongest so the last match in the
//--- if-chain is always the highest-conviction one (see the class comment). Models 0-3 are the
//--- CONFIRMING readings and all carry the standard-library floor weight of 10: each describes a
//--- standing STATE that is true across long stretches of bars rather than an event, so any of them
//--- alone must never approach the Min vote to open gate - they exist to corroborate an event model
//--- below, exactly as Pattern_0 does in CSignalMA/CSignalRSI/CSignalMACD. Models 4-11 are events
//--- (or, for 11, the full three-role confluence) and are spread across the same 30-100 band the
//--- standard library uses, ranked by how much the method itself trusts each one.
int m_pattern_0; // model 0 "price is on the necessary side of the cloud"
int m_pattern_1; // model 1 "the projected cloud is the necessary colour"
int m_pattern_2; // model 2 "Chikou Span confirmation (clear of past price AND cloud)"
int m_pattern_3; // model 3 "TK cross on the WRONG side of the cloud (weak grade)"
int m_pattern_4; // model 4 "Kumo twist - projected Senkou A crossed Senkou B"
int m_pattern_5; // model 5 "TK cross INSIDE the cloud (neutral grade)"
int m_pattern_6; // model 6 "price crossed Kijun-sen in the necessary direction"
int m_pattern_7; // model 7 "Kijun-sen bounce - pull-back to the base line, resumed"
int m_pattern_8; // model 8 "Kumo breakout"
int m_pattern_9; // model 9 "Kumo breakout through a THIN cloud"
int m_pattern_10; // model 10 "TK cross on the RIGHT side of the cloud (strong grade)"
int m_pattern_11; // model 11 "Sanyaku Kouten/Gyakuten - all three roles aligned"
public:
CSignalIchimoku(void);
~CSignalIchimoku(void);
//--- methods of setting adjustable parameters
void PeriodTenkan(int value) { m_period_tenkan = value; }
void PeriodKijun(int value) { m_period_kijun = value; }
void PeriodSenkou(int value) { m_period_senkou = value; }
//--- methods of adjusting "weights" of market models
void Pattern_0(int value) { m_pattern_0 = value; }
void Pattern_1(int value) { m_pattern_1 = value; }
void Pattern_2(int value) { m_pattern_2 = value; }
void Pattern_3(int value) { m_pattern_3 = value; }
void Pattern_4(int value) { m_pattern_4 = value; }
void Pattern_5(int value) { m_pattern_5 = value; }
void Pattern_6(int value) { m_pattern_6 = value; }
void Pattern_7(int value) { m_pattern_7 = value; }
void Pattern_8(int value) { m_pattern_8 = value; }
void Pattern_9(int value) { m_pattern_9 = value; }
void Pattern_10(int value) { m_pattern_10 = value; }
void Pattern_11(int value) { m_pattern_11 = value; }
virtual void ApplyPatternWeight(int patternNumber, int weight);
//--- method of verification of settings
virtual bool ValidationSettings(void);
//--- method of creating the indicator and timeseries
virtual bool InitIndicators(CIndicators *indicators);
//--- methods of checking if the market models are formed
virtual int LongCondition(void);
virtual int ShortCondition(void);
protected:
//--- method of initialization of the indicator
bool InitIchimoku(CIndicators *indicators);
//--- methods of getting data
double Tenkan(int ind) { return(m_ichimoku.TenkanSen(ind)); }
double Kijun(int ind) { return(m_ichimoku.KijunSen(ind)); }
//--- cloud AS PLOTTED AT bar `ind` - the +m_period_kijun offset is the whole point, see the class
//--- comment's LOOKAHEAD note. Never call SenkouSpan*(ind) directly for a "cloud here" reading.
double SpanAAt(int ind) { return(m_ichimoku.SenkouSpanA(ind + m_period_kijun)); }
double SpanBAt(int ind) { return(m_ichimoku.SenkouSpanB(ind + m_period_kijun)); }
double CloudTop(int ind) { return(MathMax(SpanAAt(ind), SpanBAt(ind))); }
double CloudBottom(int ind) { return(MathMin(SpanAAt(ind), SpanBAt(ind))); }
double CloudThickness(int ind) { return(MathAbs(SpanAAt(ind) - SpanBAt(ind))); }
//--- PROJECTED cloud - the values the chart draws m_period_kijun bars ahead of bar `ind`, computed
//--- from bar `ind` itself, so a live bar genuinely has them (again, see the class comment).
double FutureSpanA(int ind) { return(m_ichimoku.SenkouSpanA(ind)); }
double FutureSpanB(int ind) { return(m_ichimoku.SenkouSpanB(ind)); }
//--- classification helpers shared by the long and short models
bool CloudIsThin(int ind);
bool TKCrossUp(int ind) { return(Tenkan(ind) > Kijun(ind) && Tenkan(ind + 1) <= Kijun(ind + 1)); }
bool TKCrossDown(int ind) { return(Tenkan(ind) < Kijun(ind) && Tenkan(ind + 1) >= Kijun(ind + 1)); }
//--- true if every value the models read at `ind` is present (enough history loaded)
bool DataReady(int ind);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CSignalIchimoku::CSignalIchimoku(void) : m_period_tenkan(9),
m_period_kijun(26),
m_period_senkou(52),
m_pattern_0(10), // confirming state - price vs the cloud
m_pattern_1(10), // confirming state - projected cloud colour
m_pattern_2(10), // confirming state - Chikou clear
m_pattern_3(10), // the WEAK cross grade: doctrine's "stand down", so it sits at the floor too
m_pattern_4(30), // Kumo twist: anticipatory, and the only event not involving price at all
m_pattern_5(40), // neutral cross grade - the Kumo offers no bias either way here
m_pattern_6(60), // Kijun cross - the same conviction CSignalMA gives its own price/level crosses
m_pattern_7(70), // Kijun bounce - a cross with established trend context behind it
m_pattern_8(80), // Kumo breakout - a structural break, not just a line cross
m_pattern_9(90), // ...through a thin cloud: the break the method rates most likely to hold
m_pattern_10(90), // the STRONG cross grade - the one Ichimoku actually wants traded
m_pattern_11(100) // Sanyaku: all three roles at once, the method's own top signal
{
m_id = "Ichimoku";
m_pattern_count = 12;
//--- initialization of protected data. High/Low are needed by the Kijun-sen bounce (model 6), which has
//--- to see the bar actually reach down to / up to the base line, not merely close near it.
m_used_series = USE_SERIES_HIGH + USE_SERIES_LOW + USE_SERIES_CLOSE;
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CSignalIchimoku::~CSignalIchimoku(void)
{
}
//+------------------------------------------------------------------+
//| Validation settings protected data. |
//+------------------------------------------------------------------+
bool CSignalIchimoku::ValidationSettings(void)
{
//--- validation settings of additional filters
if(!CExpertSignalCustom::ValidationSettings())
return(false);
//--- initial data checks
if(m_period_tenkan <= 0 || m_period_kijun <= 0 || m_period_senkou <= 0)
{
printf(__FUNCTION__ + ": all Ichimoku periods must be greater than 0");
return(false);
}
//--- Tenkan < Kijun < Senkou B is not cosmetic: Tenkan is meant to be the FAST line (a TK cross has no
//--- meaning if it is the slower of the two), and Senkou B is the widest lookback, so an inverted set
//--- would silently invert every model below rather than fail.
if(m_period_tenkan >= m_period_kijun)
{
printf(__FUNCTION__ + ": Kijun-sen period must be greater than Tenkan-sen period");
return(false);
}
if(m_period_kijun >= m_period_senkou)
{
printf(__FUNCTION__ + ": Senkou Span B period must be greater than Kijun-sen period");
return(false);
}
//--- ok
return(true);
}
//+------------------------------------------------------------------+
//| Create indicators. |
//+------------------------------------------------------------------+
bool CSignalIchimoku::InitIndicators(CIndicators *indicators)
{
//--- check pointer
if(indicators == NULL)
return(false);
//--- initialization of indicators and timeseries of additional filters
if(!CExpertSignalCustom::InitIndicators(indicators))
return(false);
//--- create and initialize Ichimoku indicator
if(!InitIchimoku(indicators))
return(false);
//--- ok
return(true);
}
//+------------------------------------------------------------------+
//| Initialize Ichimoku indicator. |
//+------------------------------------------------------------------+
bool CSignalIchimoku::InitIchimoku(CIndicators *indicators)
{
//--- check pointer
if(indicators == NULL)
return(false);
//--- add object to collection
if(!indicators.Add(GetPointer(m_ichimoku)))
{
printf(__FUNCTION__ + ": error adding object");
return(false);
}
//--- initialize object
if(!m_ichimoku.Create(m_symbol.Name(), m_period, m_period_tenkan, m_period_kijun, m_period_senkou))
{
printf(__FUNCTION__ + ": error initializing object");
return(false);
}
//--- ok
return(true);
}
//+------------------------------------------------------------------+
//| Cloud thickness is Ichimoku's own measure of how much support or |
//| resistance the Kumo actually represents - a break through a thin |
//| cloud is the one the method treats as meaningful, a thick one is |
//| expected to absorb the attempt. "Thin" is deliberately expressed |
//| RELATIVE to this instrument's own recent cloud rather than as an |
//| absolute price distance, so the test carries across symbols and |
//| timeframes with no scaling constant to tune - the same reasoning |
//| the AI feature side applies when it ATR-normalizes thickness. |
//| Averaged over m_period_kijun bars, i.e. the same horizon the |
//| cloud is projected across. |
//+------------------------------------------------------------------+
bool CSignalIchimoku::CloudIsThin(int ind)
{
double sum = 0.0;
int count = 0;
for(int i = 0; i < m_period_kijun; i++)
{
double t = CloudThickness(ind + i);
if(t == EMPTY_VALUE)
break;
sum += t;
count++;
}
if(count == 0)
return(false);
double average = sum / count;
//--- a degenerate (zero-width) average means there is no cloud to speak of over the whole window, which
//--- is not the same statement as "this bar's cloud is unusually thin" - decline rather than divide.
if(average <= 0.0)
return(false);
return(CloudThickness(ind) < 0.5 * average);
}
//+------------------------------------------------------------------+
//| Every value the models below read, checked in one place. The |
//| deepest read is the cloud plotted at the CHIKOU's own position |
//| (model 9), which is the spans at ind + 2*m_period_kijun; the |
//| thin-cloud average (model 8) walks a further m_period_kijun bars |
//| of cloud but tolerates running short on its own. Early in the |
//| loaded history the lines can be valid while the cloud is not, so |
//| one gate covers both rather than a per-value check per model. |
//+------------------------------------------------------------------+
bool CSignalIchimoku::DataReady(int ind)
{
if(Tenkan(ind) == EMPTY_VALUE || Tenkan(ind + 1) == EMPTY_VALUE)
return(false);
if(Kijun(ind) == EMPTY_VALUE || Kijun(ind + 1) == EMPTY_VALUE)
return(false);
if(SpanAAt(ind) == EMPTY_VALUE || SpanBAt(ind) == EMPTY_VALUE)
return(false);
if(SpanAAt(ind + 1) == EMPTY_VALUE || SpanBAt(ind + 1) == EMPTY_VALUE)
return(false);
if(FutureSpanA(ind) == EMPTY_VALUE || FutureSpanB(ind) == EMPTY_VALUE)
return(false);
if(FutureSpanA(ind + 1) == EMPTY_VALUE || FutureSpanB(ind + 1) == EMPTY_VALUE)
return(false);
//--- the cloud plotted at the Chikou's own position, i.e. ind + 2*m_period_kijun in span terms
if(SpanAAt(ind + m_period_kijun) == EMPTY_VALUE || SpanBAt(ind + m_period_kijun) == EMPTY_VALUE)
return(false);
if(Close(ind) == EMPTY_VALUE || Close(ind + 1) == EMPTY_VALUE)
return(false);
if(Close(ind + m_period_kijun) == EMPTY_VALUE)
return(false);
if(Low(ind) == EMPTY_VALUE || High(ind) == EMPTY_VALUE)
return(false);
//--- ok
return(true);
}
//+------------------------------------------------------------------+
//| "Voting" that price will grow. |
//+------------------------------------------------------------------+
int CSignalIchimoku::LongCondition(void)
{
int result = 0;
int idx = StartIndex();
if(!DataReady(idx))
return(0);
double close = Close(idx);
double closePrev = Close(idx + 1);
double kijun = Kijun(idx);
double kijunPrev = Kijun(idx + 1);
double cloudTop = CloudTop(idx);
double cloudBottom = CloudBottom(idx);
double cloudTopPrev = CloudTop(idx + 1);
//--- price position relative to the Kumo, the axis every graded model below is graded against
bool aboveCloud = (close > cloudTop);
bool insideCloud = (close >= cloudBottom && close <= cloudTop);
bool crossUp = TKCrossUp(idx);
//--- Chikou clear of BOTH the price Kijun bars back and the cloud plotted at that same position - the
//--- full form of the confirmation. Both references sit further into the PAST than this bar, never the
//--- future; see the class comment for why that direction is the lookahead-free one.
bool chikouClear = (close > Close(idx + m_period_kijun) && close > CloudTop(idx + m_period_kijun));
//--- every model enters at the current price. Ichimoku's own levels (Kijun, cloud edge) are the
//--- textbook pull-back targets, but each of these models is a BREAK/CROSS/BOUNCE that has already
//--- happened, so resting a limit order back at the level it just left would routinely never fill on
//--- the move the model voted for. Left at market for all twelve, deliberately.
m_base_price = 0.0;
//--- model 0: price is above the cloud - the standing bullish bias the stronger models confirm against,
//--- rather than an event in its own right.
if(IS_PATTERN_USAGE(0) && aboveCloud)
{
result = m_pattern_0;
m_active_pattern = "Pattern_0";
}
//--- model 1: the projected cloud is bullish (Senkou A above Senkou B ahead of this bar). This is the
//--- cloud's COLOUR - a state, not the twist event; model 4 is the event. See the class comment for why
//--- reading the spans unshifted here is correct and is not lookahead.
if(IS_PATTERN_USAGE(1) && FutureSpanA(idx) > FutureSpanB(idx))
{
result = m_pattern_1;
m_active_pattern = "Pattern_1";
}
//--- model 2: Chikou Span confirmation in its full form - the lagging span clear of the price Kijun
//--- bars back AND of the cloud that was plotted there, with price above the cloud now. Demanding, but
//--- still a STATE that holds for long stretches of a trend rather than an entry trigger, which is why
//--- it sits with the confirming models at weight 10 despite how much it asks for.
if(IS_PATTERN_USAGE(2) && chikouClear && aboveCloud)
{
result = m_pattern_2;
m_active_pattern = "Pattern_2";
}
//--- model 3: WEAK grade - a bullish TK cross occurring BELOW the cloud, i.e. against the prevailing
//--- Kumo bias. This is the grade Ichimoku doctrine tells you to stand down on, so it carries the same
//--- floor weight as the confirming states rather than being lumped in with a real cross.
if(IS_PATTERN_USAGE(3) && crossUp && close < cloudBottom)
{
result = m_pattern_3;
m_active_pattern = "Pattern_3";
}
//--- model 4: Kumo twist - Senkou A actually CROSSED above Senkou B in the projected cloud on this bar,
//--- the moment the future cloud changes colour. The lowest-weighted event: it is anticipatory, and the
//--- only model here that does not involve price at all.
if(IS_PATTERN_USAGE(4) && FutureSpanA(idx) > FutureSpanB(idx) && FutureSpanA(idx + 1) <= FutureSpanB(idx + 1))
{
result = m_pattern_4;
m_active_pattern = "Pattern_4";
}
//--- model 5: NEUTRAL grade - a bullish TK cross occurring INSIDE the cloud, where the Kumo offers no
//--- bias either way.
if(IS_PATTERN_USAGE(5) && crossUp && insideCloud)
{
result = m_pattern_5;
m_active_pattern = "Pattern_5";
}
//--- model 6: price crossed above the Kijun-sen - the equilibrium line, Ichimoku's nearest analogue to
//--- the MA cross CSignalMA votes on, and weighted to match what that signal gives its own crosses.
if(IS_PATTERN_USAGE(6) && close > kijun && closePrev <= kijunPrev)
{
result = m_pattern_6;
m_active_pattern = "Pattern_6";
}
//--- model 7: Kijun-sen bounce - price was already above the base line, dipped down to touch or pierce
//--- it, and closed back above. The pull-back entry the base line's magnet effect produces; requiring
//--- the previous close to have been above it is what separates this from the fresh cross in model 6,
//--- and requiring price above the cloud keeps it a trend continuation rather than a catch of a fall.
//--- The base line must also be flat or rising - the magnet effect is what makes this trade, and it
//--- only exists while the Kijun holds its level; bouncing off a FALLING base line in a long is just
//--- buying into a line that is coming down to meet you. Rated above the plain cross in model 6 for
//--- exactly that added trend context.
if(IS_PATTERN_USAGE(7) && aboveCloud && closePrev > kijunPrev && Low(idx) <= kijun && close > kijun &&
kijun >= kijunPrev)
{
result = m_pattern_7;
m_active_pattern = "Pattern_7";
}
//--- model 8: Kumo breakout - price closed above the cloud having not been above it on the previous bar
//--- (it left the cloud, or gapped over it, upward). A structural break rather than a line cross, hence
//--- the step up from models 6/7.
if(IS_PATTERN_USAGE(8) && aboveCloud && closePrev <= cloudTopPrev)
{
result = m_pattern_8;
m_active_pattern = "Pattern_8";
}
//--- model 9: the same breakout, but through a THIN cloud - little real resistance stood in the way, so
//--- Ichimoku rates the break more likely to hold than one through a thick Kumo.
if(IS_PATTERN_USAGE(9) && aboveCloud && closePrev <= cloudTopPrev && CloudIsThin(idx))
{
result = m_pattern_9;
m_active_pattern = "Pattern_9";
}
//--- model 10: STRONG grade - a bullish TK cross occurring ABOVE the cloud, so Kumo bias and trigger
//--- agree. The grade Ichimoku actually wants you trading.
if(IS_PATTERN_USAGE(10) && crossUp && aboveCloud)
{
result = m_pattern_10;
m_active_pattern = "Pattern_10";
}
//--- model 11: Sanyaku Kouten - the "three roles turning bullish" alignment, Ichimoku's own strongest
//--- signal: Tenkan above Kijun, Chikou clear of past price and cloud, and price clear above the Kumo,
//--- all true together. Note this asks for the cross STATE (Tenkan above Kijun), not the cross event -
//--- the alignment is what matters, and demanding all three flip on the same bar would fire almost
//--- never. Last, so it overwrites any weaker match above.
if(IS_PATTERN_USAGE(11) && Tenkan(idx) > Kijun(idx) && chikouClear && aboveCloud)
{
result = m_pattern_11;
m_active_pattern = "Pattern_11";
}
if(result != 0)
{
m_active_direction = "Buy";
}
//--- return the result
return(result);
}
//+------------------------------------------------------------------+
//| "Voting" that price will fall. |
//+------------------------------------------------------------------+
int CSignalIchimoku::ShortCondition(void)
{
int result = 0;
int idx = StartIndex();
if(!DataReady(idx))
return(0);
double close = Close(idx);
double closePrev = Close(idx + 1);
double kijun = Kijun(idx);
double kijunPrev = Kijun(idx + 1);
double cloudTop = CloudTop(idx);
double cloudBottom = CloudBottom(idx);
double cloudBottomPrev = CloudBottom(idx + 1);
bool belowCloud = (close < cloudBottom);
bool insideCloud = (close >= cloudBottom && close <= cloudTop);
bool crossDown = TKCrossDown(idx);
//--- mirror of LongCondition()'s chikouClear - clear BELOW past price and below the cloud plotted there
bool chikouClear = (close < Close(idx + m_period_kijun) && close < CloudBottom(idx + m_period_kijun));
//--- see LongCondition() for why every model enters at market
m_base_price = 0.0;
//--- model 0: price is below the cloud
if(IS_PATTERN_USAGE(0) && belowCloud)
{
result = m_pattern_0;
m_active_pattern = "Pattern_0";
}
//--- model 1: the projected cloud is bearish (Senkou A below Senkou B ahead of this bar) - colour, not
//--- the twist event; model 4 is the event
if(IS_PATTERN_USAGE(1) && FutureSpanA(idx) < FutureSpanB(idx))
{
result = m_pattern_1;
m_active_pattern = "Pattern_1";
}
//--- model 2: Chikou Span confirmation, full form - see LongCondition() for why a reading this
//--- demanding still sits at the confirming floor weight
if(IS_PATTERN_USAGE(2) && chikouClear && belowCloud)
{
result = m_pattern_2;
m_active_pattern = "Pattern_2";
}
//--- model 3: WEAK grade - bearish TK cross occurring ABOVE the cloud, against the prevailing bias
if(IS_PATTERN_USAGE(3) && crossDown && close > cloudTop)
{
result = m_pattern_3;
m_active_pattern = "Pattern_3";
}
//--- model 4: Kumo twist - Senkou A crossed BELOW Senkou B in the projected cloud on this bar
if(IS_PATTERN_USAGE(4) && FutureSpanA(idx) < FutureSpanB(idx) && FutureSpanA(idx + 1) >= FutureSpanB(idx + 1))
{
result = m_pattern_4;
m_active_pattern = "Pattern_4";
}
//--- model 5: NEUTRAL grade - bearish TK cross occurring INSIDE the cloud
if(IS_PATTERN_USAGE(5) && crossDown && insideCloud)
{
result = m_pattern_5;
m_active_pattern = "Pattern_5";
}
//--- model 6: price crossed below the Kijun-sen
if(IS_PATTERN_USAGE(6) && close < kijun && closePrev >= kijunPrev)
{
result = m_pattern_6;
m_active_pattern = "Pattern_6";
}
//--- model 7: Kijun-sen bounce - price was already below the base line, rallied up to touch or pierce
//--- it, and closed back below, with the base line flat or falling. See LongCondition()'s model 7 for
//--- why the slope condition is part of the model rather than a weight adjustment.
if(IS_PATTERN_USAGE(7) && belowCloud && closePrev < kijunPrev && High(idx) >= kijun && close < kijun &&
kijun <= kijunPrev)
{
result = m_pattern_7;
m_active_pattern = "Pattern_7";
}
//--- model 8: Kumo breakout - price closed below the cloud having not been below it on the previous bar
if(IS_PATTERN_USAGE(8) && belowCloud && closePrev >= cloudBottomPrev)
{
result = m_pattern_8;
m_active_pattern = "Pattern_8";
}
//--- model 9: the same breakout through a THIN cloud
if(IS_PATTERN_USAGE(9) && belowCloud && closePrev >= cloudBottomPrev && CloudIsThin(idx))
{
result = m_pattern_9;
m_active_pattern = "Pattern_9";
}
//--- model 10: STRONG grade - bearish TK cross occurring BELOW the cloud
if(IS_PATTERN_USAGE(10) && crossDown && belowCloud)
{
result = m_pattern_10;
m_active_pattern = "Pattern_10";
}
//--- model 11: Sanyaku Gyakuten - the bearish "three roles" alignment
if(IS_PATTERN_USAGE(11) && Tenkan(idx) < Kijun(idx) && chikouClear && belowCloud)
{
result = m_pattern_11;
m_active_pattern = "Pattern_11";
}
if(result != 0)
{
m_active_direction = "Sell";
}
//--- return the result
return(result);
}
//+------------------------------------------------------------------+
//| Set the specified pattern's weight to the specified value |
//+------------------------------------------------------------------+
void CSignalIchimoku::ApplyPatternWeight(int patternNumber, int weight)
{
switch(patternNumber)
{
default:
break;
case 0:
Pattern_0(weight);
break;
case 1:
Pattern_1(weight);
break;
case 2:
Pattern_2(weight);
break;
case 3:
Pattern_3(weight);
break;
case 4:
Pattern_4(weight);
break;
case 5:
Pattern_5(weight);
break;
case 6:
Pattern_6(weight);
break;
case 7:
Pattern_7(weight);
break;
case 8:
Pattern_8(weight);
break;
case 9:
Pattern_9(weight);
break;
case 10:
Pattern_10(weight);
break;
case 11:
Pattern_11(weight);
break;
}
}
//+------------------------------------------------------------------+