15 popular candle patterns

Here you can post and download custom indicators. PLEASE: Do not start topics unless you are posting your own indicator, they will be moved to appropriate section even if you do.

Moderator: admin

Re: 15 popular candle patterns

Postby jcervinka » Mon Sep 13, 2010 2:38 pm

Can you make a sound signal for this indicator??
Whenever the bar you choose, after his closing, to have a sound signal..

Thanks

Jernej
jcervinka
 
Posts: 41
Joined: Sat Aug 07, 2010 11:38 am


Re: 15 popular candle patterns

Postby Alexander.Gettinger » Wed Sep 15, 2010 1:42 am

In indicator are added 14 new patterns.

Code: Select all
function Init()
    indicator:name("Candle Pattern 3");
    indicator:description("");
    indicator:requiredSource(core.Bar);
    indicator:type(core.Indicator);

    indicator.parameters:addInteger("EQ", "Maximum of pips distance between equal prices", "", 1, 0, 100);
    indicator.parameters:addBoolean("PAT_DOUBLE_INSIDE", "Enable Double Inside", "", true);
    indicator.parameters:addBoolean("PAT_INSIDE", "Enable Inside", "", true);
    indicator.parameters:addBoolean("PAT_OUTSIDE", "Enable Outside", "", true);
    indicator.parameters:addBoolean("PAT_PINUP", "Enable Pin Up", "", true);
    indicator.parameters:addBoolean("PAT_PINDOWN", "Enable Pin Down", "", true);
    indicator.parameters:addBoolean("PAT_PPRUP", "Enable Pivot Point Reversal Up", "", true);
    indicator.parameters:addBoolean("PAT_PPRDN", "Enable Pivot Point Reversal Down", "", true);
    indicator.parameters:addBoolean("PAT_DBLHC", "Enable Double Bar Low With A Higher Close", "", true);
    indicator.parameters:addBoolean("PAT_DBHLC", "Enable Double Bar High With A Lower Close", "", true);
    indicator.parameters:addBoolean("PAT_CPRU", "Enable Close Price Reversal Up", "", true);
    indicator.parameters:addBoolean("PAT_CPRD", "Enable Close Price Reversal Down", "", true);
    indicator.parameters:addBoolean("PAT_NB", "Enable Neutral Bar", "", true);
    indicator.parameters:addBoolean("PAT_FBU", "Enable Force Bar Up", "", true);
    indicator.parameters:addBoolean("PAT_FBD", "Enable Force Bar Down", "", true);
    indicator.parameters:addBoolean("PAT_MB", "Enable Mirror Bar", "", true);
    indicator.parameters:addBoolean("PAT_HAMMER", "Enable Hammer", "", true);
    indicator.parameters:addBoolean("PAT_SHOOTSTAR", "Enable Shooting Star", "", true);
    indicator.parameters:addBoolean("PAT_EVSTAR", "Enable Evening Star", "", true);
    indicator.parameters:addBoolean("PAT_MORNSTAR", "Enable Morning Star", "", true);
    indicator.parameters:addBoolean("PAT_EVDJSTAR", "Enable Evening Doji Star", "", true);
    indicator.parameters:addBoolean("PAT_MORNDJSTAR", "Enable Morning Doji Star", "", true);
    indicator.parameters:addBoolean("PAT_BEARHARAMI", "Enable Bearish Harami", "", true);
    indicator.parameters:addBoolean("PAT_BEARHARAMICROSS", "Enable Bearish Harami Cross", "", true);
    indicator.parameters:addBoolean("PAT_BULLHARAMI", "Enable Bullish Harami", "", true);
    indicator.parameters:addBoolean("PAT_BULLHARAMICROSS", "Enable Bullish Harami Cross", "", true);
    indicator.parameters:addBoolean("PAT_DARKCLOUD", "Enable Dark Cloud Cover", "", true);
    indicator.parameters:addBoolean("PAT_DOJISTAR", "Enable Doji Star", "", true);
    indicator.parameters:addBoolean("PAT_ENGBEARLINE", "Enable Engulfing Bearish Line", "", true);
    indicator.parameters:addBoolean("PAT_ENGBULLLINE", "Enable Engulfing Bullish Line", "", true);
   

    indicator.parameters:addGroup("Style");
    indicator.parameters:addInteger("FontSize", "Font Size", "", 6, 4, 12);
    indicator.parameters:addColor("LblColor", "Color for pattern labels", "", core.COLOR_LABEL);
end

local source;
local P;
local UP;
local DN;
local EQ;

function Prepare()
    EQ = instance.parameters.EQ * instance.source:pipSize();
    source = instance.source;
    InitPattern(source);

    local name;
    name = profile:id();
    instance:name(name);

    UP = instance:createTextOutput("L", "L", "Arial", instance.parameters.FontSize, core.H_Center, core.V_Top, instance.parameters.LblColor, 0);
    DN = instance:createTextOutput("L", "L", "Arial", instance.parameters.FontSize, core.H_Center, core.V_Bottom, instance.parameters.LblColor, 0);
end

local prevSerial = nil;

function Update(period, mode)
    if period == 0 then
        prevSerial = source:serial(period);
    else
        if prevSerial ~= source:serial(period) then
            prevSerial = source:serial(period);
            UpdatePattern(period - 1);
        end
    end
end

function RegisterPattern(period, pattern)
    local short, long, up, length;
    local price;
    short, long, up, length = DecodePattern(pattern);
    if length~=nil then
     if up then
         price = core.max(source.high, core.rangeTo(period, length));
         UP:set(period, price, short, long);
     else
         price = core.min(source.low, core.rangeTo(period, length));
         DN:set(period, price, short, long);
     end
    end
end

local O, H, L, C, T, B, BL, US, LS; -- open, high, low, close prices, top and bottom of the candle, body, upper shadow and lower shadow length

function InitPattern(source)
    O = source.open;
    H = source.high;
    L = source.low;
    C = source.close;
    T = instance:addInternalStream(0, 0);
    B = instance:addInternalStream(0, 0);
    BL = instance:addInternalStream(0, 0);
    US = instance:addInternalStream(0, 0);
    LS = instance:addInternalStream(0, 0);
end

local PAT_NONE = 0;
local PAT_DOUBLE_INSIDE = 1;
local PAT_INSIDE = 2;
local PAT_OUTSIDE = 4;
local PAT_PINUP = 5;
local PAT_PINDOWN = 6;
local PAT_PPRUP = 7;
local PAT_PPRDN = 8;
local PAT_DBLHC = 9;
local PAT_DBHLC = 10;
local PAT_CPRU = 11;
local PAT_CPRD = 12;
local PAT_NB = 13;
local PAT_FBU = 14;
local PAT_FBD = 15;
local PAT_MB = 16;

local PAT_HAMMER=17;
local PAT_SHOOTSTAR=18;
local PAT_EVSTAR=19;
local PAT_MORNSTAR=20;
local PAT_BEARHARAMI=21;
local PAT_BEARHARAMICROSS=22;
local PAT_BULLHARAMI=23;
local PAT_BULLHARAMICROSS=24;
local PAT_DARKCLOUD=25;
local PAT_DOJISTAR=26;
local PAT_ENGBEARLINE=27;
local PAT_ENGBULLLINE=28;
local PAT_EVDJSTAR=29;
local PAT_MORNDJSTAR=30;

-- short name, name, up/down flag, length of pattern
function DecodePattern(pattern)
    if pattern == PAT_NONE then
        return nil, nil, nil, nil;
    elseif pattern == PAT_DOUBLE_INSIDE and instance.parameters:getBoolean("PAT_DOUBLE_INSIDE")==true then
        return "DblIn", "Double Inside", true, 3;
    elseif pattern == PAT_INSIDE and instance.parameters:getBoolean("PAT_INSIDE")==true then
        return "In", "Inside", true, 2;
    elseif pattern == PAT_OUTSIDE and instance.parameters:getBoolean("PAT_OUTSIDE")==true then
        return "Out", "Outside", true, 2;
    elseif pattern == PAT_PINUP and instance.parameters:getBoolean("PAT_PINUP")==true then
        return "PnUp", "Pin Up", true, 2;
    elseif pattern == PAT_PINDOWN and instance.parameters:getBoolean("PAT_PINDOWN")==true then
        return "PnDn", "Pin Down", false, 2;
    elseif pattern == PAT_PPRUP and instance.parameters:getBoolean("PAT_PPRUP")==true then
        return "PPRU", "Pivot Point Reversal Up", false, 3;
    elseif pattern == PAT_PPRDN and instance.parameters:getBoolean("PAT_PPRDN")==true then
        return "PPRD", "Pivot Point Reversal Down", true, 3;
    elseif pattern == PAT_DBLHC and instance.parameters:getBoolean("PAT_DBLHC")==true then
        return "DBLHC", "Double Bar Low With A Higher Close", false, 2;
    elseif pattern == PAT_DBHLC and instance.parameters:getBoolean("PAT_DBHLC")==true then
        return "DBHLC", "Double Bar High With A Lower Close", true, 2;
    elseif pattern == PAT_CPRU and instance.parameters:getBoolean("PAT_CPRU")==true then
        return "CPRU", "Close Price Reversal Up", false, 3;
    elseif pattern == PAT_CPRD and instance.parameters:getBoolean("PAT_CPRD")==true then
        return "CPRD", "Close Price Reversal Down", true, 3;
    elseif pattern == PAT_NB and instance.parameters:getBoolean("PAT_NB")==true then
        return "NB", "Neutral Bar", true, 1;
    elseif pattern == PAT_FBU and instance.parameters:getBoolean("PAT_FBU")==true then
        return "FBU", "Force Bar Up", false, 1;
    elseif pattern == PAT_FBD and instance.parameters:getBoolean("PAT_FBD")==true then
        return "FBD", "Force Bar Down", true, 1;
    elseif pattern == PAT_MB and instance.parameters:getBoolean("PAT_MB")==true then
        return "MB", "Mirror Bar", true, 2;
    elseif pattern == PAT_HAMMER and instance.parameters:getBoolean("PAT_HAMMER")==true then
        return "HAMMER", "Hammer Pattern", true, 1;
    elseif pattern == PAT_SHOOTSTAR and instance.parameters:getBoolean("PAT_SHOOTSTAR")==true then
        return "SHOOTSTAR", "Shooting Star", true, 1;
    elseif pattern == PAT_EVSTAR and instance.parameters:getBoolean("PAT_EVSTAR")==true then
        return "EVSTAR", "Evening Star", true, 3;
    elseif pattern == PAT_MORNSTAR and instance.parameters:getBoolean("PAT_MORNSTAR")==true then
        return "MORNSTAR", "Morning Star", true, 3;
    elseif pattern == PAT_EVDJSTAR and instance.parameters:getBoolean("PAT_EVDJSTAR")==true then
        return "EVDJSTAR", "Evening Doji Star", true, 3;
    elseif pattern == PAT_MORNDJSTAR and instance.parameters:getBoolean("PAT_MORNDJSTAR")==true then
        return "MORNDJSTAR", "Morning Doji Star", true, 3;
    elseif pattern == PAT_BEARHARAMI and instance.parameters:getBoolean("PAT_BEARHARAMI")==true then
        return "BEARHARAMI", "Bearish Harami", true, 2;
    elseif pattern == PAT_BEARHARAMICROSS and instance.parameters:getBoolean("PAT_BEARHARAMICROSS")==true then
        return "BEARHARAMICROSS", "Bearish Harami Cross", true, 2;
    elseif pattern == PAT_BULLHARAMI and instance.parameters:getBoolean("PAT_BULLHARAMI")==true then
        return "BULLHARAMI", "Bullish Harami", true, 2;
    elseif pattern == PAT_BULLHARAMICROSS and instance.parameters:getBoolean("PAT_BULLHARAMICROSS")==true then
        return "BULLHARAMICROSS", "Bullish Harami Cross", true, 2;
    elseif pattern == PAT_DARKCLOUD and instance.parameters:getBoolean("PAT_DARKCLOUD")==true then
        return "DARKCLOUD", "Dark Cloud Cover", true, 2;
    elseif pattern == PAT_DOJISTAR and instance.parameters:getBoolean("PAT_DOJISTAR")==true then
        return "DOJISTAR", "Doji Star", true, 2;
    elseif pattern == PAT_ENGBEARLINE and instance.parameters:getBoolean("PAT_ENGBEARLINE")==true then
        return "ENGBEARLINE", "Engulfing Bearish Line", true, 2;
    elseif pattern == PAT_ENGBULLLINE and instance.parameters:getBoolean("PAT_ENGBULLLINE")==true then
        return "ENGBULLLINE", "Engulfing Bullish Line", true, 2;
    else
        return nil, nil, nil, nil;
    end
end

function Cmp(price1, price2)
    if math.abs(price1 - price2) < EQ then
        return 0;
    elseif price1 > price2 then
        return 1;
    else
        return -1;
    end
end

function UpdatePattern(p)
    T[p] = math.max(O[p], C[p]);
    B[p] = math.min(O[p], C[p]);
    BL[p] = T[p] - B[p];
    US[p] = H[p] - T[p];
    LS[p] = B[p] - L[p];

    if p >= 0 then
        -- 1 - candle patterns
        if Cmp(O[p], C[p]) == 0 and US[p] > math.max(EQ * 4, source:pipSize() * 4) and
                                    LS[p] > math.max(EQ * 4, source:pipSize() * 4) then
           RegisterPattern(p, PAT_NB);
        end

        if C[p] == H[p] then
           RegisterPattern(p, PAT_FBU);
        end

        if C[p] == L[p] then
           RegisterPattern(p, PAT_FBD);
        end
       
        if US[p] <= math.max(EQ, source:pipSize()) and LS[p]>2.*BL[p] then
           RegisterPattern(p, PAT_HAMMER);
        end

        if LS[p] <= math.max(EQ, source:pipSize()) and US[p]>2.*BL[p] then
           RegisterPattern(p, PAT_SHOOTSTAR);
        end
    end
    if p >= 1 then
        -- 2 - candle patterns
       if Cmp(H[p], H[p - 1]) < 0 and Cmp(L[p], L[p - 1]) > 0 then
           RegisterPattern(p, PAT_INSIDE);
       end
       if Cmp(H[p], H[p - 1]) > 0 and Cmp(L[p], L[p - 1]) < 0 then
           RegisterPattern(p, PAT_OUTSIDE);
       end
       if Cmp(H[p], H[p - 1]) == 0 and Cmp(C[p], C[p - 1]) < 0 and Cmp(L[p], L[p - 1]) <= 0 then
           RegisterPattern(p, PAT_DBHLC);
       end
       if Cmp(L[p], L[p - 1]) == 0 and Cmp(C[p], C[p - 1]) > 0 and Cmp(H[p], H[p - 1]) >= 0  then
           RegisterPattern(p, PAT_DBLHC);
       end
       if Cmp(BL[p - 1], BL[p]) == 0 and Cmp(O[p - 1], C[p]) == 0 then
           RegisterPattern(p, PAT_MB);
       end
       if Cmp(H[p],H[p-1])<0 and Cmp(L[p],L[p-1])>0 and Cmp(C[p-1],O[p-1])>0 and
       Cmp(C[p],O[p])<0 and Cmp(BL[p-1],BL[p])>0 and Cmp(C[p-1],O[p])>0 and Cmp(O[p-1],C[p])<0 then
           RegisterPattern(p, PAT_BEARHARAMI);
       end
       if Cmp(H[p],H[p-1])<0 and Cmp(L[p],L[p-1])>0 and Cmp(C[p-1],O[p-1])>0 and Cmp(O[p],C[p])==0 and
       Cmp(BL[p-1],BL[p])>0 and Cmp(C[p-1],O[p])>0 and Cmp(O[p-1],C[p])<0 then
           RegisterPattern(p, PAT_BEARHARAMICROSS);
       end
       if Cmp(H[p],H[p-1])<0 and Cmp(L[p],L[p-1])>0 and Cmp(C[p-1],O[p-1])<0 and
       Cmp(C[p],O[p])>0 and Cmp(BL[p-1],BL[p])>0 and Cmp(C[p-1],O[p])<0 and Cmp(O[p-1],C[p])>0 then
           RegisterPattern(p, PAT_BULLHARAMI);
       end
       if Cmp(H[p],H[p-1])<0 and Cmp(L[p],L[p-1])>0 and Cmp(C[p-1],O[p-1])<0 and Cmp(O[p],C[p])==0 and
       Cmp(BL[p-1],BL[p])>0 and Cmp(C[p-1],O[p])<0 and Cmp(O[p-1],C[p])>0 then
           RegisterPattern(p, PAT_BULLHARAMICROSS);
       end
       if Cmp(C[p-1],O[p-1])>0 and Cmp(C[p],O[p])<0 and Cmp(H[p-1],O[p])<0 and Cmp(C[p],C[p-1])<0 and Cmp(C[p],O[p-1])>0 then
           RegisterPattern(p, PAT_DARKCLOUD);
       end
       if Cmp(O[p],C[p])==0 and ((Cmp(C[p-1],O[p-1])>0 and Cmp(O[p],H[p-1])>0) or (Cmp(C[p-1],O[p-1])<0 and Cmp(O[p],L[p-1])<0)) then
           RegisterPattern(p, PAT_DOJISTAR);
       end
       if Cmp(C[p-1],O[p-1])>0 and Cmp(C[p],O[p])<0 and Cmp(O[p],C[p-1])>0 and Cmp(C[p],O[p-1])<0 then
           RegisterPattern(p, PAT_ENGBEARLINE);
       end
       if Cmp(C[p-1],O[p-1])<0 and Cmp(C[p],O[p])>0 and Cmp(O[p],C[p-1])<0 and Cmp(C[p],O[p-1])>0 then
           RegisterPattern(p, PAT_ENGBULLLINE);
       end
    end

    if p >= 2 then
        -- 3 - candle patterns
        if Cmp(H[p], H[p - 1]) < 0 and Cmp(L[p], L[p - 1]) > 0 and
           Cmp(H[p - 1], H[p - 2]) < 0 and Cmp(L[p - 1], L[p - 2]) > 0 then
            RegisterPattern(p, PAT_DOUBLE_INSIDE);
        end
        if Cmp(H[p - 1], H[p - 2]) > 0 and Cmp(H[p - 1], H[p]) > 0 and
           Cmp(L[p - 1], L[p - 2]) > 0 and Cmp(L[p - 1], L[p]) > 0 and
           BL[p - 1] * 2 < US[p - 1] then
            RegisterPattern(p - 1, PAT_PINUP);
        end
        if Cmp(H[p - 1], H[p - 2]) < 0 and Cmp(H[p - 1], H[p]) < 0 and
           Cmp(L[p - 1], L[p - 2]) < 0 and Cmp(L[p - 1], L[p]) < 0 and
           BL[p - 1] * 2 < LS[p - 1] then
            RegisterPattern(p - 1, PAT_PINDOWN);
        end
        if Cmp(H[p - 1], H[p - 2]) > 0 and Cmp(H[p - 1], H[p]) > 0 and
           Cmp(L[p - 1], L[p - 2]) > 0 and Cmp(L[p - 1], L[p]) > 0 and
           Cmp(C[p], L[p - 1]) < 0 then
            RegisterPattern(p, PAT_PPRDN);
        end
        if Cmp(H[p - 1], H[p - 2]) < 0 and Cmp(H[p - 1], H[p]) < 0 and
           Cmp(L[p - 1], L[p - 2]) < 0 and Cmp(L[p - 1], L[p]) < 0 and
           Cmp(C[p], H[p - 1]) > 0 then
            RegisterPattern(p, PAT_PPRUP);
        end
        if Cmp(H[p - 1], H[p - 2]) < 0 and Cmp(L[p - 1], L[p - 2]) < 0 and
           Cmp(H[p], H[p - 1]) < 0 and Cmp(L[p], L[p - 1]) < 0 and
           Cmp(C[p], C[p - 1]) > 0 and Cmp(O[p], C[p]) < 0 then
            RegisterPattern(p, PAT_CPRU);
        end
        if Cmp(H[p - 1], H[p - 2]) > 0 and Cmp(L[p - 1], L[p - 2]) > 0 and
           Cmp(H[p], H[p - 1]) > 0 and Cmp(L[p], L[p - 1]) > 0 and
           Cmp(C[p], C[p - 1]) < 0 and Cmp(O[p], C[p]) > 0 then
            RegisterPattern(p, PAT_CPRD);
        end
        if Cmp(C[p-2],O[p-2])>0 and Cmp(C[p-1],O[p-1])>0 and Cmp(C[p],O[p])<0 and Cmp(C[p-2],O[p-1])<0 and
   Cmp(BL[p-2],BL[p-1])>0 and Cmp(BL[p-1],BL[p])<0 and Cmp(C[p],O[p-2])>0 and Cmp(C[p],C[p-2])<0 then
       RegisterPattern(p, PAT_EVSTAR);
   end
        if Cmp(C[p-2],O[p-2])<0 and Cmp(C[p-1],O[p-1])>0 and Cmp(C[p],O[p])>0 and Cmp(C[p-2],O[p-1])>0 and
   Cmp(BL[p-2],BL[p-1])>0 and Cmp(BL[p-1],BL[p])<0 and Cmp(C[p],C[p-2])>0 and Cmp(C[p],O[p-2])<0 then
       RegisterPattern(p, PAT_MORNSTAR);
   end
        if Cmp(C[p-2],O[p-2])>0 and Cmp(C[p-1],O[p-1])==0 and Cmp(C[p],O[p])<0 and Cmp(C[p-2],O[p-1])<0 and
   Cmp(BL[p-2],BL[p-1])>0 and Cmp(BL[p-1],BL[p])<0 and Cmp(C[p],O[p-2])>0 and Cmp(C[p],C[p-2])<0 then
       RegisterPattern(p, PAT_EVDJSTAR);
   end
        if Cmp(C[p-2],O[p-2])<0 and Cmp(C[p-1],O[p-1])==0 and Cmp(C[p],O[p])>0 and Cmp(C[p-2],O[p-1])>0 and
   Cmp(BL[p-2],BL[p-1])>0 and Cmp(BL[p-1],BL[p])<0 and Cmp(C[p],C[p-2])>0 and Cmp(C[p],O[p-2])<0 then
       RegisterPattern(p, PAT_MORNDJSTAR);
   end
    end
end
Attachments
Patterns3.lua
(16.31 KiB) Downloaded 3009 times
Last edited by Alexander.Gettinger on Wed Sep 15, 2010 9:16 pm, edited 1 time in total.
Alexander.Gettinger
FXCodeBase: Confirmed User
 
Posts: 3785
Joined: Wed Mar 31, 2010 9:40 pm
Location: Russia, Omsk

Re: 15 popular candle patterns

Postby Alexander.Gettinger » Wed Sep 15, 2010 1:51 am

HAMMER
Hammer.png
Hammer.png (188 Bytes) Viewed 8564 times

Little body (black or white) with long bottom and without top shadow.

SHOOTSTAR - Shooting Star
Image
Little body (black or white) with long top and without bottom shadow.

EVENING STAR - Shooting Star
Image
After big white body follows small white with top breakup. Third black candle must have close price within first body.
Last edited by Alexander.Gettinger on Wed Sep 15, 2010 4:09 pm, edited 7 times in total.
Alexander.Gettinger
FXCodeBase: Confirmed User
 
Posts: 3785
Joined: Wed Mar 31, 2010 9:40 pm
Location: Russia, Omsk

Re: 15 popular candle patterns

Postby Alexander.Gettinger » Wed Sep 15, 2010 1:56 am

MORNSTAR - Morning Star
Image
After big black body follows small white with bottom breakup. Third white candle must have close price within first body.

BEARHARAMI - Bearish Harami
Image
Small black body follows big white candle and it is found between high and low first candle.

BEARHARAMICROSS - Bearish Harami Cross
Image
Doji follows big white candle and it is found between high and low first candle.
Alexander.Gettinger
FXCodeBase: Confirmed User
 
Posts: 3785
Joined: Wed Mar 31, 2010 9:40 pm
Location: Russia, Omsk

Re: 15 popular candle patterns

Postby Alexander.Gettinger » Wed Sep 15, 2010 2:06 am

BULLHARAMI - Bullish Harami
Image
Small white body follows big black candle and it is found between high and low first candle.

BULLHARAMICROSS Bullish Harami Cross
Image
Doji follows big black candle and it is found between high and low first candle.

DARKCLOUD - Dark Cloud Cover
Image
After white candle follow black candle. Black candle opened above high of white candle and closed within white candle.
Alexander.Gettinger
FXCodeBase: Confirmed User
 
Posts: 3785
Joined: Wed Mar 31, 2010 9:40 pm
Location: Russia, Omsk

Re: 15 popular candle patterns

Postby Alexander.Gettinger » Wed Sep 15, 2010 2:11 am

DOJISTAR - Doji Star
Image
After white or black candle follow doji candle. Doji opened above or below high of first candle.

ENGBEARLINE - Engulfing Bearish Line
Image
After small white candle follow big outside black candle.

ENGBULLLINE - Engulfing Bullish Line
Image
After small black candle follow big outside white candle.
Last edited by Alexander.Gettinger on Wed Sep 15, 2010 9:10 pm, edited 1 time in total.
Alexander.Gettinger
FXCodeBase: Confirmed User
 
Posts: 3785
Joined: Wed Mar 31, 2010 9:40 pm
Location: Russia, Omsk

Re: 15 popular candle patterns

Postby Alexander.Gettinger » Wed Sep 15, 2010 2:14 am

EVDJSTAR - Evening Doji Star
Image
After big white body follows doji with top breakup. Third black candle must have close price within first body.

MORNDJSTAR - Morning Doji Star
Image
After big black body follows doji with bottom breakup. Third white candle must have close price within first body.
Alexander.Gettinger
FXCodeBase: Confirmed User
 
Posts: 3785
Joined: Wed Mar 31, 2010 9:40 pm
Location: Russia, Omsk

Re: 15 popular candle patterns

Postby Alexander.Gettinger » Thu Sep 16, 2010 12:44 am

Signals for candle patterns.

Patterns3_Signal.png


Code: Select all
function Init()
    strategy:name("Candle patterns signal");
    strategy:description("Candle patterns signal");

    strategy.parameters:addInteger("EQ", "Maximum of pips distance between equal prices", "", 1, 0, 100);
    strategy.parameters:addBoolean("PAT_DOUBLE_INSIDE", "Enable Double Inside", "", true);
    strategy.parameters:addBoolean("PAT_INSIDE", "Enable Inside", "", true);
    strategy.parameters:addBoolean("PAT_OUTSIDE", "Enable Outside", "", true);
    strategy.parameters:addBoolean("PAT_PINUP", "Enable Pin Up", "", true);
    strategy.parameters:addBoolean("PAT_PINDOWN", "Enable Pin Down", "", true);
    strategy.parameters:addBoolean("PAT_PPRUP", "Enable Pivot Point Reversal Up", "", true);
    strategy.parameters:addBoolean("PAT_PPRDN", "Enable Pivot Point Reversal Down", "", true);
    strategy.parameters:addBoolean("PAT_DBLHC", "Enable Double Bar Low With A Higher Close", "", true);
    strategy.parameters:addBoolean("PAT_DBHLC", "Enable Double Bar High With A Lower Close", "", true);
    strategy.parameters:addBoolean("PAT_CPRU", "Enable Close Price Reversal Up", "", true);
    strategy.parameters:addBoolean("PAT_CPRD", "Enable Close Price Reversal Down", "", true);
    strategy.parameters:addBoolean("PAT_NB", "Enable Neutral Bar", "", true);
    strategy.parameters:addBoolean("PAT_FBU", "Enable Force Bar Up", "", true);
    strategy.parameters:addBoolean("PAT_FBD", "Enable Force Bar Down", "", true);
    strategy.parameters:addBoolean("PAT_MB", "Enable Mirror Bar", "", true);
    strategy.parameters:addBoolean("PAT_HAMMER", "Enable Hammer", "", true);
    strategy.parameters:addBoolean("PAT_SHOOTSTAR", "Enable Shooting Star", "", true);
    strategy.parameters:addBoolean("PAT_EVSTAR", "Enable Evening Star", "", true);
    strategy.parameters:addBoolean("PAT_MORNSTAR", "Enable Morning Star", "", true);
    strategy.parameters:addBoolean("PAT_EVDJSTAR", "Enable Evening Doji Star", "", true);
    strategy.parameters:addBoolean("PAT_MORNDJSTAR", "Enable Morning Doji Star", "", true);
    strategy.parameters:addBoolean("PAT_BEARHARAMI", "Enable Bearish Harami", "", true);
    strategy.parameters:addBoolean("PAT_BEARHARAMICROSS", "Enable Bearish Harami Cross", "", true);
    strategy.parameters:addBoolean("PAT_BULLHARAMI", "Enable Bullish Harami", "", true);
    strategy.parameters:addBoolean("PAT_BULLHARAMICROSS", "Enable Bullish Harami Cross", "", true);
    strategy.parameters:addBoolean("PAT_DARKCLOUD", "Enable Dark Cloud Cover", "", true);
    strategy.parameters:addBoolean("PAT_DOJISTAR", "Enable Doji Star", "", true);
    strategy.parameters:addBoolean("PAT_ENGBEARLINE", "Enable Engulfing Bearish Line", "", true);
    strategy.parameters:addBoolean("PAT_ENGBULLLINE", "Enable Engulfing Bullish Line", "", true);

    strategy.parameters:addString("Period", "Time frame", "", "m1");
    strategy.parameters:setFlag("Period", core.FLAG_PERIODS);

    strategy.parameters:addBoolean("ShowAlert", "Show Alert", "", true);
    strategy.parameters:addBoolean("PlaySound", "Play Sound", "", false);
    strategy.parameters:addFile("SoundFile", "Sound file", "", "");
end

local SoundFile;
local gSource = nil;

local PAT_NONE = 0;
local PAT_DOUBLE_INSIDE = 1;
local PAT_INSIDE = 2;
local PAT_OUTSIDE = 4;
local PAT_PINUP = 5;
local PAT_PINDOWN = 6;
local PAT_PPRUP = 7;
local PAT_PPRDN = 8;
local PAT_DBLHC = 9;
local PAT_DBHLC = 10;
local PAT_CPRU = 11;
local PAT_CPRD = 12;
local PAT_NB = 13;
local PAT_FBU = 14;
local PAT_FBD = 15;
local PAT_MB = 16;

local PAT_HAMMER=17;
local PAT_SHOOTSTAR=18;
local PAT_EVSTAR=19;
local PAT_MORNSTAR=20;
local PAT_BEARHARAMI=21;
local PAT_BEARHARAMICROSS=22;
local PAT_BULLHARAMI=23;
local PAT_BULLHARAMICROSS=24;
local PAT_DARKCLOUD=25;
local PAT_DOJISTAR=26;
local PAT_ENGBEARLINE=27;
local PAT_ENGBULLLINE=28;
local PAT_EVDJSTAR=29;
local PAT_MORNDJSTAR=30;

local EQ;

function DecodePattern(pattern)
    if pattern == PAT_NONE then
        return nil, nil, nil, nil;
    elseif pattern == PAT_DOUBLE_INSIDE and instance.parameters:getBoolean("PAT_DOUBLE_INSIDE")==true then
        return "DblIn", "Double Inside", true, 3;
    elseif pattern == PAT_INSIDE and instance.parameters:getBoolean("PAT_INSIDE")==true then
        return "In", "Inside", true, 2;
    elseif pattern == PAT_OUTSIDE and instance.parameters:getBoolean("PAT_OUTSIDE")==true then
        return "Out", "Outside", true, 2;
    elseif pattern == PAT_PINUP and instance.parameters:getBoolean("PAT_PINUP")==true then
        return "PnUp", "Pin Up", true, 2;
    elseif pattern == PAT_PINDOWN and instance.parameters:getBoolean("PAT_PINDOWN")==true then
        return "PnDn", "Pin Down", false, 2;
    elseif pattern == PAT_PPRUP and instance.parameters:getBoolean("PAT_PPRUP")==true then
        return "PPRU", "Pivot Point Reversal Up", false, 3;
    elseif pattern == PAT_PPRDN and instance.parameters:getBoolean("PAT_PPRDN")==true then
        return "PPRD", "Pivot Point Reversal Down", true, 3;
    elseif pattern == PAT_DBLHC and instance.parameters:getBoolean("PAT_DBLHC")==true then
        return "DBLHC", "Double Bar Low With A Higher Close", false, 2;
    elseif pattern == PAT_DBHLC and instance.parameters:getBoolean("PAT_DBHLC")==true then
        return "DBHLC", "Double Bar High With A Lower Close", true, 2;
    elseif pattern == PAT_CPRU and instance.parameters:getBoolean("PAT_CPRU")==true then
        return "CPRU", "Close Price Reversal Up", false, 3;
    elseif pattern == PAT_CPRD and instance.parameters:getBoolean("PAT_CPRD")==true then
        return "CPRD", "Close Price Reversal Down", true, 3;
    elseif pattern == PAT_NB and instance.parameters:getBoolean("PAT_NB")==true then
        return "NB", "Neutral Bar", true, 1;
    elseif pattern == PAT_FBU and instance.parameters:getBoolean("PAT_FBU")==true then
        return "FBU", "Force Bar Up", false, 1;
    elseif pattern == PAT_FBD and instance.parameters:getBoolean("PAT_FBD")==true then
        return "FBD", "Force Bar Down", true, 1;
    elseif pattern == PAT_MB and instance.parameters:getBoolean("PAT_MB")==true then
        return "MB", "Mirror Bar", true, 2;
    elseif pattern == PAT_HAMMER and instance.parameters:getBoolean("PAT_HAMMER")==true then
        return "HAMMER", "Hammer Pattern", true, 1;
    elseif pattern == PAT_SHOOTSTAR and instance.parameters:getBoolean("PAT_SHOOTSTAR")==true then
        return "SHOOTSTAR", "Shooting Star", true, 1;
    elseif pattern == PAT_EVSTAR and instance.parameters:getBoolean("PAT_EVSTAR")==true then
        return "EVSTAR", "Evening Star", true, 3;
    elseif pattern == PAT_MORNSTAR and instance.parameters:getBoolean("PAT_MORNSTAR")==true then
        return "MORNSTAR", "Morning Star", true, 3;
    elseif pattern == PAT_EVDJSTAR and instance.parameters:getBoolean("PAT_EVDJSTAR")==true then
        return "EVDJSTAR", "Evening Doji Star", true, 3;
    elseif pattern == PAT_MORNDJSTAR and instance.parameters:getBoolean("PAT_MORNDJSTAR")==true then
        return "MORNDJSTAR", "Morning Doji Star", true, 3;
    elseif pattern == PAT_BEARHARAMI and instance.parameters:getBoolean("PAT_BEARHARAMI")==true then
        return "BEARHARAMI", "Bearish Harami", true, 2;
    elseif pattern == PAT_BEARHARAMICROSS and instance.parameters:getBoolean("PAT_BEARHARAMICROSS")==true then
        return "BEARHARAMICROSS", "Bearish Harami Cross", true, 2;
    elseif pattern == PAT_BULLHARAMI and instance.parameters:getBoolean("PAT_BULLHARAMI")==true then
        return "BULLHARAMI", "Bullish Harami", true, 2;
    elseif pattern == PAT_BULLHARAMICROSS and instance.parameters:getBoolean("PAT_BULLHARAMICROSS")==true then
        return "BULLHARAMICROSS", "Bullish Harami Cross", true, 2;
    elseif pattern == PAT_DARKCLOUD and instance.parameters:getBoolean("PAT_DARKCLOUD")==true then
        return "DARKCLOUD", "Dark Cloud Cover", true, 2;
    elseif pattern == PAT_DOJISTAR and instance.parameters:getBoolean("PAT_DOJISTAR")==true then
        return "DOJISTAR", "Doji Star", true, 2;
    elseif pattern == PAT_ENGBEARLINE and instance.parameters:getBoolean("PAT_ENGBEARLINE")==true then
        return "ENGBEARLINE", "Engulfing Bearish Line", true, 2;
    elseif pattern == PAT_ENGBULLLINE and instance.parameters:getBoolean("PAT_ENGBULLLINE")==true then
        return "ENGBULLLINE", "Engulfing Bullish Line", true, 2;
    else
        return nil, nil, nil, nil;
    end
end

function RegisterPattern(period, pattern)
    local short, long, up, length;
    local price;
    short, long, up, length = DecodePattern(pattern);
    if length~=nil then
     if up then
         ExtSignal(gSource.high, period, long, SoundFile);
     else
         ExtSignal(gSource.low, period, long, SoundFile);
     end
    end
end


function Cmp(price1, price2)
    if math.abs(price1 - price2) < EQ then
        return 0;
    elseif price1 > price2 then
        return 1;
    else
        return -1;
    end
end

function Prepare()

    ShowAlert = instance.parameters.ShowAlert;
   
    if instance.parameters.PlaySound then
        SoundFile = instance.parameters.SoundFile;
    else
        SoundFile = nil;
    end

    assert(not(PlaySound) or (PlaySound and SoundFile ~= ""), "Sound file must be specified");

    ExtSetupSignal(profile:id() .. ":", ShowAlert);

    assert(instance.parameters.Period ~= "t1", "Can't be applied on ticks!");

    gSource = ExtSubscribe(1, nil, instance.parameters.Period, true, "bar");
   
    EQ = instance.parameters.EQ * gSource:pipSize();

    local name = profile:id() .. "(" .. instance.bid:instrument()  .. "(" .. instance.parameters.Period  .. ")" .. ")";
    instance:name(name);
end

local O, H, L, C, T, B, BL, US, LS;
local O1, H1, L1, C1, T1, B1, BL1, US1, LS1;
local O2, H2, L2, C2, T2, B2, BL2, US2, LS2;

-- when tick source is updated
function ExtUpdate(id, source, period)
    if period <= 3 then
        return ;
    end
   
    O=gSource.open[period];
    H=gSource.high[period];
    L=gSource.low[period];
    C=gSource.close[period];
    T=math.max(O,C);
    B=math.min(O,C);
    BL=T-B;
    US=H-T;
    LS=B-L;
    O1=gSource.open[period-1];
    H1=gSource.high[period-1];
    L1=gSource.low[period-1];
    C1=gSource.close[period-1];
    T1=math.max(O1,C1);
    B1=math.min(O1,C1);
    BL1=T1-B1;
    US1=H1-T1;
    LS1=B1-L1;
    O2=gSource.open[period-2];
    H2=gSource.high[period-2];
    L2=gSource.low[period-2];
    C2=gSource.close[period-2];
    T2=math.max(O2,C2);
    B2=math.min(O2,C2);
    BL2=T2-B2;
    US2=H2-T2;
    LS2=B2-L2;


-- 1 - candle patterns
   
    if Cmp(O, C) == 0 and US > math.max(EQ * 4, gSource:pipSize() * 4) and
       LS > math.max(EQ * 4, gSource:pipSize() * 4) then
     RegisterPattern(period, PAT_NB);
    end

    if C == H then
     RegisterPattern(period, PAT_FBU);
    end

    if C == L then
     RegisterPattern(period, PAT_FBD);
    end

    if US <= math.max(EQ, gSource:pipSize()) and LS>2.*BL then
     RegisterPattern(period, PAT_HAMMER);
    end

    if LS <= math.max(EQ, gSource:pipSize()) and US>2.*BL then
     RegisterPattern(period, PAT_SHOOTSTAR);
    end
   
-- 2 - candle patterns   

       if Cmp(H, H1) < 0 and Cmp(L, L1) > 0 then
           RegisterPattern(period, PAT_INSIDE);
       end
       
       if Cmp(H, H1) > 0 and Cmp(L, L1) < 0 then
           RegisterPattern(period, PAT_OUTSIDE);
       end
       
       if Cmp(H, H1) == 0 and Cmp(C, C1) < 0 and Cmp(L, L1) <= 0 then
           RegisterPattern(period, PAT_DBHLC);
       end
       
       if Cmp(L, L1) == 0 and Cmp(C, C1) > 0 and Cmp(H, H1) >= 0  then
           RegisterPattern(period, PAT_DBLHC);
       end
       
       if Cmp(BL1, BL) == 0 and Cmp(O1, C) == 0 then
           RegisterPattern(period, PAT_MB);
       end
       
       if Cmp(H,H1)<0 and Cmp(L,L1)>0 and Cmp(C1,O1)>0 and
       Cmp(C,O)<0 and Cmp(BL1,BL)>0 and Cmp(C1,O)>0 and Cmp(O1,C)<0 then
           RegisterPattern(period, PAT_BEARHARAMI);
       end
       
       if Cmp(H,H1)<0 and Cmp(L,L1)>0 and Cmp(C1,O1)>0 and Cmp(O,C)==0 and
       Cmp(BL1,BL)>0 and Cmp(C1,O)>0 and Cmp(O1,C)<0 then
           RegisterPattern(period, PAT_BEARHARAMICROSS);
       end
       
       if Cmp(H,H1)<0 and Cmp(L,L1)>0 and Cmp(C1,O1)<0 and
       Cmp(C,O)>0 and Cmp(BL1,BL)>0 and Cmp(C1,O)<0 and Cmp(O1,C)>0 then
           RegisterPattern(period, PAT_BULLHARAMI);
       end
       
       if Cmp(H,H1)<0 and Cmp(L,L1)>0 and Cmp(C1,O1)<0 and Cmp(O,C)==0 and
       Cmp(BL1,BL)>0 and Cmp(C1,O)<0 and Cmp(O1,C)>0 then
           RegisterPattern(period, PAT_BULLHARAMICROSS);
       end
       
       if Cmp(C1,O1)>0 and Cmp(C,O)<0 and Cmp(H1,O)<0 and Cmp(C,C1)<0 and Cmp(C,O1)>0 then
           RegisterPattern(period, PAT_DARKCLOUD);
       end
       
       if Cmp(O,C)==0 and ((Cmp(C1,O1)>0 and Cmp(O,H1)>0) or (Cmp(C1,O1)<0 and Cmp(O,L1)<0)) then
           RegisterPattern(period, PAT_DOJISTAR);
       end
       
       if Cmp(C1,O1)>0 and Cmp(C,O)<0 and Cmp(O,C1)>0 and Cmp(C,O1)<0 then
           RegisterPattern(period, PAT_ENGBEARLINE);
       end
       
       if Cmp(C1,O1)<0 and Cmp(C,O)>0 and Cmp(O,C1)<0 and Cmp(C,O1)>0 then
           RegisterPattern(period, PAT_ENGBULLLINE);
       end
       
       
-- 3 - candle patterns           

        if Cmp(H, H1) < 0 and Cmp(L, L1) > 0 and
           Cmp(H1, H2) < 0 and Cmp(L1, L2) > 0 then
            RegisterPattern(period, PAT_DOUBLE_INSIDE);
        end
       
        if Cmp(H1, H2) > 0 and Cmp(H1, H) > 0 and
           Cmp(L1, L2) > 0 and Cmp(L1, L) > 0 and
           BL1 * 2 < US1 then
            RegisterPattern(period, PAT_PINUP);
        end
       
        if Cmp(H1, H2) < 0 and Cmp(H1, H) < 0 and
           Cmp(L1, L2) < 0 and Cmp(L1, L) < 0 and
           BL1 * 2 < LS1 then
            RegisterPattern(period, PAT_PINDOWN);
        end
       
        if Cmp(H1, H2) > 0 and Cmp(H1, H) > 0 and
           Cmp(L1, L2) > 0 and Cmp(L1, L) > 0 and
           Cmp(C, L1) < 0 then
            RegisterPattern(period, PAT_PPRDN);
        end
       
        if Cmp(H1, H2) < 0 and Cmp(H1, H) < 0 and
           Cmp(L1, L2) < 0 and Cmp(L1, L) < 0 and
           Cmp(C, H1) > 0 then
            RegisterPattern(period, PAT_PPRUP);
        end
       
        if Cmp(H1, H2) < 0 and Cmp(L1, L2) < 0 and
           Cmp(H, H1) < 0 and Cmp(L, L1) < 0 and
           Cmp(C, C1) > 0 and Cmp(O, C) < 0 then
            RegisterPattern(period, PAT_CPRU);
        end
       
        if Cmp(H1, H2) > 0 and Cmp(L1, L2) > 0 and
           Cmp(H, H1) > 0 and Cmp(L, L1) > 0 and
           Cmp(C, C1) < 0 and Cmp(O, C) > 0 then
            RegisterPattern(period, PAT_CPRD);
        end
       
        if Cmp(C2,O2)>0 and Cmp(C1,O1)>0 and Cmp(C,O)<0 and Cmp(C2,O1)<0 and
   Cmp(BL2,BL1)>0 and Cmp(BL1,BL)<0 and Cmp(C,O2)>0 and Cmp(C,C2)<0 then
       RegisterPattern(period, PAT_EVSTAR);
   end
   
        if Cmp(C2,O2)<0 and Cmp(C1,O1)>0 and Cmp(C,O)>0 and Cmp(C2,O1)>0 and
   Cmp(BL2,BL1)>0 and Cmp(BL1,BL)<0 and Cmp(C,C2)>0 and Cmp(C,O2)<0 then
       RegisterPattern(period, PAT_MORNSTAR);
   end
   
        if Cmp(C2,O2)>0 and Cmp(C1,O1)==0 and Cmp(C,O)<0 and Cmp(C2,O1)<0 and
   Cmp(BL2,BL1)>0 and Cmp(BL1,BL)<0 and Cmp(C,O2)>0 and Cmp(C,C2)<0 then
       RegisterPattern(period, PAT_EVDJSTAR);
   end
   
        if Cmp(C2,O2)<0 and Cmp(C1,O1)==0 and Cmp(C,O)>0 and Cmp(C2,O1)>0 and
   Cmp(BL2,BL1)>0 and Cmp(BL1,BL)<0 and Cmp(C,C2)>0 and Cmp(C,O2)<0 then
       RegisterPattern(period, PAT_MORNDJSTAR);
   end

end

dofile(core.app_path() .. "\\strategies\\standard\\include\\helper.lua");


Program must be installed as strategy.
Attachments
Patterns3_Signal.lua
(15.54 KiB) Downloaded 2778 times
Alexander.Gettinger
FXCodeBase: Confirmed User
 
Posts: 3785
Joined: Wed Mar 31, 2010 9:40 pm
Location: Russia, Omsk

Re: 15 popular candle patterns

Postby Alexander.Gettinger » Mon Sep 20, 2010 9:40 pm

In indicator and signal added pattern NB2: two consecutive Neutral Bars.

Indicator:
Code: Select all
function Init()
    indicator:name("Candle Pattern 3");
    indicator:description("");
    indicator:requiredSource(core.Bar);
    indicator:type(core.Indicator);

    indicator.parameters:addInteger("EQ", "Maximum of pips distance between equal prices", "", 1, 0, 100);
    indicator.parameters:addBoolean("PAT_DOUBLE_INSIDE", "Enable Double Inside", "", true);
    indicator.parameters:addBoolean("PAT_INSIDE", "Enable Inside", "", true);
    indicator.parameters:addBoolean("PAT_OUTSIDE", "Enable Outside", "", true);
    indicator.parameters:addBoolean("PAT_PINUP", "Enable Pin Up", "", true);
    indicator.parameters:addBoolean("PAT_PINDOWN", "Enable Pin Down", "", true);
    indicator.parameters:addBoolean("PAT_PPRUP", "Enable Pivot Point Reversal Up", "", true);
    indicator.parameters:addBoolean("PAT_PPRDN", "Enable Pivot Point Reversal Down", "", true);
    indicator.parameters:addBoolean("PAT_DBLHC", "Enable Double Bar Low With A Higher Close", "", true);
    indicator.parameters:addBoolean("PAT_DBHLC", "Enable Double Bar High With A Lower Close", "", true);
    indicator.parameters:addBoolean("PAT_CPRU", "Enable Close Price Reversal Up", "", true);
    indicator.parameters:addBoolean("PAT_CPRD", "Enable Close Price Reversal Down", "", true);
    indicator.parameters:addBoolean("PAT_NB", "Enable Neutral Bar", "", true);
    indicator.parameters:addBoolean("PAT_NB2", "Enable 2 Neutral Bars", "", true);
    indicator.parameters:addBoolean("PAT_FBU", "Enable Force Bar Up", "", true);
    indicator.parameters:addBoolean("PAT_FBD", "Enable Force Bar Down", "", true);
    indicator.parameters:addBoolean("PAT_MB", "Enable Mirror Bar", "", true);
    indicator.parameters:addBoolean("PAT_HAMMER", "Enable Hammer", "", true);
    indicator.parameters:addBoolean("PAT_SHOOTSTAR", "Enable Shooting Star", "", true);
    indicator.parameters:addBoolean("PAT_EVSTAR", "Enable Evening Star", "", true);
    indicator.parameters:addBoolean("PAT_MORNSTAR", "Enable Morning Star", "", true);
    indicator.parameters:addBoolean("PAT_EVDJSTAR", "Enable Evening Doji Star", "", true);
    indicator.parameters:addBoolean("PAT_MORNDJSTAR", "Enable Morning Doji Star", "", true);
    indicator.parameters:addBoolean("PAT_BEARHARAMI", "Enable Bearish Harami", "", true);
    indicator.parameters:addBoolean("PAT_BEARHARAMICROSS", "Enable Bearish Harami Cross", "", true);
    indicator.parameters:addBoolean("PAT_BULLHARAMI", "Enable Bullish Harami", "", true);
    indicator.parameters:addBoolean("PAT_BULLHARAMICROSS", "Enable Bullish Harami Cross", "", true);
    indicator.parameters:addBoolean("PAT_DARKCLOUD", "Enable Dark Cloud Cover", "", true);
    indicator.parameters:addBoolean("PAT_DOJISTAR", "Enable Doji Star", "", true);
    indicator.parameters:addBoolean("PAT_ENGBEARLINE", "Enable Engulfing Bearish Line", "", true);
    indicator.parameters:addBoolean("PAT_ENGBULLLINE", "Enable Engulfing Bullish Line", "", true);
   

    indicator.parameters:addGroup("Style");
    indicator.parameters:addInteger("FontSize", "Font Size", "", 6, 4, 12);
    indicator.parameters:addColor("LblColor", "Color for pattern labels", "", core.COLOR_LABEL);
end

local source;
local P;
local UP;
local DN;
local EQ;

function Prepare()
    EQ = instance.parameters.EQ * instance.source:pipSize();
    source = instance.source;
    InitPattern(source);

    local name;
    name = profile:id();
    instance:name(name);

    UP = instance:createTextOutput("L", "L", "Arial", instance.parameters.FontSize, core.H_Center, core.V_Top, instance.parameters.LblColor, 0);
    DN = instance:createTextOutput("L", "L", "Arial", instance.parameters.FontSize, core.H_Center, core.V_Bottom, instance.parameters.LblColor, 0);
end

local prevSerial = nil;

function Update(period, mode)
    if period == 0 then
        prevSerial = source:serial(period);
    else
        if prevSerial ~= source:serial(period) then
            prevSerial = source:serial(period);
            UpdatePattern(period - 1);
        end
    end
end

function RegisterPattern(period, pattern)
    local short, long, up, length;
    local price;
    short, long, up, length = DecodePattern(pattern);
    if length~=nil then
     if up then
         price = core.max(source.high, core.rangeTo(period, length));
         UP:set(period, price, short, long);
     else
         price = core.min(source.low, core.rangeTo(period, length));
         DN:set(period, price, short, long);
     end
    end
end

local O, H, L, C, T, B, BL, US, LS; -- open, high, low, close prices, top and bottom of the candle, body, upper shadow and lower shadow length

function InitPattern(source)
    O = source.open;
    H = source.high;
    L = source.low;
    C = source.close;
    T = instance:addInternalStream(0, 0);
    B = instance:addInternalStream(0, 0);
    BL = instance:addInternalStream(0, 0);
    US = instance:addInternalStream(0, 0);
    LS = instance:addInternalStream(0, 0);
end

local PAT_NONE = 0;
local PAT_DOUBLE_INSIDE = 1;
local PAT_INSIDE = 2;
local PAT_OUTSIDE = 4;
local PAT_PINUP = 5;
local PAT_PINDOWN = 6;
local PAT_PPRUP = 7;
local PAT_PPRDN = 8;
local PAT_DBLHC = 9;
local PAT_DBHLC = 10;
local PAT_CPRU = 11;
local PAT_CPRD = 12;
local PAT_NB = 13;
local PAT_FBU = 14;
local PAT_FBD = 15;
local PAT_MB = 16;

local PAT_HAMMER=17;
local PAT_SHOOTSTAR=18;
local PAT_EVSTAR=19;
local PAT_MORNSTAR=20;
local PAT_BEARHARAMI=21;
local PAT_BEARHARAMICROSS=22;
local PAT_BULLHARAMI=23;
local PAT_BULLHARAMICROSS=24;
local PAT_DARKCLOUD=25;
local PAT_DOJISTAR=26;
local PAT_ENGBEARLINE=27;
local PAT_ENGBULLLINE=28;
local PAT_EVDJSTAR=29;
local PAT_MORNDJSTAR=30;
local PAT_NB2 = 31;

-- short name, name, up/down flag, length of pattern
function DecodePattern(pattern)
    if pattern == PAT_NONE then
        return nil, nil, nil, nil;
    elseif pattern == PAT_DOUBLE_INSIDE and instance.parameters:getBoolean("PAT_DOUBLE_INSIDE")==true then
        return "DblIn", "Double Inside", true, 3;
    elseif pattern == PAT_INSIDE and instance.parameters:getBoolean("PAT_INSIDE")==true then
        return "In", "Inside", true, 2;
    elseif pattern == PAT_OUTSIDE and instance.parameters:getBoolean("PAT_OUTSIDE")==true then
        return "Out", "Outside", true, 2;
    elseif pattern == PAT_PINUP and instance.parameters:getBoolean("PAT_PINUP")==true then
        return "PnUp", "Pin Up", true, 2;
    elseif pattern == PAT_PINDOWN and instance.parameters:getBoolean("PAT_PINDOWN")==true then
        return "PnDn", "Pin Down", false, 2;
    elseif pattern == PAT_PPRUP and instance.parameters:getBoolean("PAT_PPRUP")==true then
        return "PPRU", "Pivot Point Reversal Up", false, 3;
    elseif pattern == PAT_PPRDN and instance.parameters:getBoolean("PAT_PPRDN")==true then
        return "PPRD", "Pivot Point Reversal Down", true, 3;
    elseif pattern == PAT_DBLHC and instance.parameters:getBoolean("PAT_DBLHC")==true then
        return "DBLHC", "Double Bar Low With A Higher Close", false, 2;
    elseif pattern == PAT_DBHLC and instance.parameters:getBoolean("PAT_DBHLC")==true then
        return "DBHLC", "Double Bar High With A Lower Close", true, 2;
    elseif pattern == PAT_CPRU and instance.parameters:getBoolean("PAT_CPRU")==true then
        return "CPRU", "Close Price Reversal Up", false, 3;
    elseif pattern == PAT_CPRD and instance.parameters:getBoolean("PAT_CPRD")==true then
        return "CPRD", "Close Price Reversal Down", true, 3;
    elseif pattern == PAT_NB and instance.parameters:getBoolean("PAT_NB")==true then
        return "NB", "Neutral Bar", true, 1;
    elseif pattern == PAT_FBU and instance.parameters:getBoolean("PAT_FBU")==true then
        return "FBU", "Force Bar Up", false, 1;
    elseif pattern == PAT_FBD and instance.parameters:getBoolean("PAT_FBD")==true then
        return "FBD", "Force Bar Down", true, 1;
    elseif pattern == PAT_MB and instance.parameters:getBoolean("PAT_MB")==true then
        return "MB", "Mirror Bar", true, 2;
    elseif pattern == PAT_HAMMER and instance.parameters:getBoolean("PAT_HAMMER")==true then
        return "HAMMER", "Hammer Pattern", true, 1;
    elseif pattern == PAT_SHOOTSTAR and instance.parameters:getBoolean("PAT_SHOOTSTAR")==true then
        return "SHOOTSTAR", "Shooting Star", true, 1;
    elseif pattern == PAT_EVSTAR and instance.parameters:getBoolean("PAT_EVSTAR")==true then
        return "EVSTAR", "Evening Star", true, 3;
    elseif pattern == PAT_MORNSTAR and instance.parameters:getBoolean("PAT_MORNSTAR")==true then
        return "MORNSTAR", "Morning Star", true, 3;
    elseif pattern == PAT_EVDJSTAR and instance.parameters:getBoolean("PAT_EVDJSTAR")==true then
        return "EVDJSTAR", "Evening Doji Star", true, 3;
    elseif pattern == PAT_MORNDJSTAR and instance.parameters:getBoolean("PAT_MORNDJSTAR")==true then
        return "MORNDJSTAR", "Morning Doji Star", true, 3;
    elseif pattern == PAT_BEARHARAMI and instance.parameters:getBoolean("PAT_BEARHARAMI")==true then
        return "BEARHARAMI", "Bearish Harami", true, 2;
    elseif pattern == PAT_BEARHARAMICROSS and instance.parameters:getBoolean("PAT_BEARHARAMICROSS")==true then
        return "BEARHARAMICROSS", "Bearish Harami Cross", true, 2;
    elseif pattern == PAT_BULLHARAMI and instance.parameters:getBoolean("PAT_BULLHARAMI")==true then
        return "BULLHARAMI", "Bullish Harami", true, 2;
    elseif pattern == PAT_BULLHARAMICROSS and instance.parameters:getBoolean("PAT_BULLHARAMICROSS")==true then
        return "BULLHARAMICROSS", "Bullish Harami Cross", true, 2;
    elseif pattern == PAT_DARKCLOUD and instance.parameters:getBoolean("PAT_DARKCLOUD")==true then
        return "DARKCLOUD", "Dark Cloud Cover", true, 2;
    elseif pattern == PAT_DOJISTAR and instance.parameters:getBoolean("PAT_DOJISTAR")==true then
        return "DOJISTAR", "Doji Star", true, 2;
    elseif pattern == PAT_ENGBEARLINE and instance.parameters:getBoolean("PAT_ENGBEARLINE")==true then
        return "ENGBEARLINE", "Engulfing Bearish Line", true, 2;
    elseif pattern == PAT_ENGBULLLINE and instance.parameters:getBoolean("PAT_ENGBULLLINE")==true then
        return "ENGBULLLINE", "Engulfing Bullish Line", true, 2;
    elseif pattern == PAT_NB2 and instance.parameters:getBoolean("PAT_NB2")==true then
        return "NB2", "2 Neutral Bars", true, 2;
    else
        return nil, nil, nil, nil;
    end
end

function Cmp(price1, price2)
    if math.abs(price1 - price2) < EQ then
        return 0;
    elseif price1 > price2 then
        return 1;
    else
        return -1;
    end
end

function UpdatePattern(p)
    T[p] = math.max(O[p], C[p]);
    B[p] = math.min(O[p], C[p]);
    BL[p] = T[p] - B[p];
    US[p] = H[p] - T[p];
    LS[p] = B[p] - L[p];

    if p >= 0 then
        -- 1 - candle patterns
        if Cmp(O[p], C[p]) == 0 and US[p] > math.max(EQ * 4, source:pipSize() * 4) and
                                    LS[p] > math.max(EQ * 4, source:pipSize() * 4) then
           RegisterPattern(p, PAT_NB);
        end

        if C[p] == H[p] then
           RegisterPattern(p, PAT_FBU);
        end

        if C[p] == L[p] then
           RegisterPattern(p, PAT_FBD);
        end
       
        if US[p] <= math.max(EQ, source:pipSize()) and LS[p]>2.*BL[p] then
           RegisterPattern(p, PAT_HAMMER);
        end

        if LS[p] <= math.max(EQ, source:pipSize()) and US[p]>2.*BL[p] then
           RegisterPattern(p, PAT_SHOOTSTAR);
        end
    end
    if p >= 1 then
        -- 2 - candle patterns
       if Cmp(H[p], H[p - 1]) < 0 and Cmp(L[p], L[p - 1]) > 0 then
           RegisterPattern(p, PAT_INSIDE);
       end
       if Cmp(H[p], H[p - 1]) > 0 and Cmp(L[p], L[p - 1]) < 0 then
           RegisterPattern(p, PAT_OUTSIDE);
       end
       if Cmp(H[p], H[p - 1]) == 0 and Cmp(C[p], C[p - 1]) < 0 and Cmp(L[p], L[p - 1]) <= 0 then
           RegisterPattern(p, PAT_DBHLC);
       end
       if Cmp(L[p], L[p - 1]) == 0 and Cmp(C[p], C[p - 1]) > 0 and Cmp(H[p], H[p - 1]) >= 0  then
           RegisterPattern(p, PAT_DBLHC);
       end
       if Cmp(BL[p - 1], BL[p]) == 0 and Cmp(O[p - 1], C[p]) == 0 then
           RegisterPattern(p, PAT_MB);
       end
       if Cmp(H[p],H[p-1])<0 and Cmp(L[p],L[p-1])>0 and Cmp(C[p-1],O[p-1])>0 and
       Cmp(C[p],O[p])<0 and Cmp(BL[p-1],BL[p])>0 and Cmp(C[p-1],O[p])>0 and Cmp(O[p-1],C[p])<0 then
           RegisterPattern(p, PAT_BEARHARAMI);
       end
       if Cmp(H[p],H[p-1])<0 and Cmp(L[p],L[p-1])>0 and Cmp(C[p-1],O[p-1])>0 and Cmp(O[p],C[p])==0 and
       Cmp(BL[p-1],BL[p])>0 and Cmp(C[p-1],O[p])>0 and Cmp(O[p-1],C[p])<0 then
           RegisterPattern(p, PAT_BEARHARAMICROSS);
       end
       if Cmp(H[p],H[p-1])<0 and Cmp(L[p],L[p-1])>0 and Cmp(C[p-1],O[p-1])<0 and
       Cmp(C[p],O[p])>0 and Cmp(BL[p-1],BL[p])>0 and Cmp(C[p-1],O[p])<0 and Cmp(O[p-1],C[p])>0 then
           RegisterPattern(p, PAT_BULLHARAMI);
       end
       if Cmp(H[p],H[p-1])<0 and Cmp(L[p],L[p-1])>0 and Cmp(C[p-1],O[p-1])<0 and Cmp(O[p],C[p])==0 and
       Cmp(BL[p-1],BL[p])>0 and Cmp(C[p-1],O[p])<0 and Cmp(O[p-1],C[p])>0 then
           RegisterPattern(p, PAT_BULLHARAMICROSS);
       end
       if Cmp(C[p-1],O[p-1])>0 and Cmp(C[p],O[p])<0 and Cmp(H[p-1],O[p])<0 and Cmp(C[p],C[p-1])<0 and Cmp(C[p],O[p-1])>0 then
           RegisterPattern(p, PAT_DARKCLOUD);
       end
       if Cmp(O[p],C[p])==0 and ((Cmp(C[p-1],O[p-1])>0 and Cmp(O[p],H[p-1])>0) or (Cmp(C[p-1],O[p-1])<0 and Cmp(O[p],L[p-1])<0)) then
           RegisterPattern(p, PAT_DOJISTAR);
       end
       if Cmp(C[p-1],O[p-1])>0 and Cmp(C[p],O[p])<0 and Cmp(O[p],C[p-1])>0 and Cmp(C[p],O[p-1])<0 then
           RegisterPattern(p, PAT_ENGBEARLINE);
       end
       if Cmp(C[p-1],O[p-1])<0 and Cmp(C[p],O[p])>0 and Cmp(O[p],C[p-1])<0 and Cmp(C[p],O[p-1])>0 then
           RegisterPattern(p, PAT_ENGBULLLINE);
       end
        if Cmp(O[p], C[p]) == 0 and US[p] > math.max(EQ * 4, source:pipSize() * 4) and
                                    LS[p] > math.max(EQ * 4, source:pipSize() * 4) and
      Cmp(O[p-1], C[p-1]) == 0 and US[p-1] > math.max(EQ * 4, source:pipSize() * 4) and
                                LS[p-1] > math.max(EQ * 4, source:pipSize() * 4) then
           RegisterPattern(p, PAT_NB2);
        end
    end

    if p >= 2 then
        -- 3 - candle patterns
        if Cmp(H[p], H[p - 1]) < 0 and Cmp(L[p], L[p - 1]) > 0 and
           Cmp(H[p - 1], H[p - 2]) < 0 and Cmp(L[p - 1], L[p - 2]) > 0 then
            RegisterPattern(p, PAT_DOUBLE_INSIDE);
        end
        if Cmp(H[p - 1], H[p - 2]) > 0 and Cmp(H[p - 1], H[p]) > 0 and
           Cmp(L[p - 1], L[p - 2]) > 0 and Cmp(L[p - 1], L[p]) > 0 and
           BL[p - 1] * 2 < US[p - 1] then
            RegisterPattern(p - 1, PAT_PINUP);
        end
        if Cmp(H[p - 1], H[p - 2]) < 0 and Cmp(H[p - 1], H[p]) < 0 and
           Cmp(L[p - 1], L[p - 2]) < 0 and Cmp(L[p - 1], L[p]) < 0 and
           BL[p - 1] * 2 < LS[p - 1] then
            RegisterPattern(p - 1, PAT_PINDOWN);
        end
        if Cmp(H[p - 1], H[p - 2]) > 0 and Cmp(H[p - 1], H[p]) > 0 and
           Cmp(L[p - 1], L[p - 2]) > 0 and Cmp(L[p - 1], L[p]) > 0 and
           Cmp(C[p], L[p - 1]) < 0 then
            RegisterPattern(p, PAT_PPRDN);
        end
        if Cmp(H[p - 1], H[p - 2]) < 0 and Cmp(H[p - 1], H[p]) < 0 and
           Cmp(L[p - 1], L[p - 2]) < 0 and Cmp(L[p - 1], L[p]) < 0 and
           Cmp(C[p], H[p - 1]) > 0 then
            RegisterPattern(p, PAT_PPRUP);
        end
        if Cmp(H[p - 1], H[p - 2]) < 0 and Cmp(L[p - 1], L[p - 2]) < 0 and
           Cmp(H[p], H[p - 1]) < 0 and Cmp(L[p], L[p - 1]) < 0 and
           Cmp(C[p], C[p - 1]) > 0 and Cmp(O[p], C[p]) < 0 then
            RegisterPattern(p, PAT_CPRU);
        end
        if Cmp(H[p - 1], H[p - 2]) > 0 and Cmp(L[p - 1], L[p - 2]) > 0 and
           Cmp(H[p], H[p - 1]) > 0 and Cmp(L[p], L[p - 1]) > 0 and
           Cmp(C[p], C[p - 1]) < 0 and Cmp(O[p], C[p]) > 0 then
            RegisterPattern(p, PAT_CPRD);
        end
        if Cmp(C[p-2],O[p-2])>0 and Cmp(C[p-1],O[p-1])>0 and Cmp(C[p],O[p])<0 and Cmp(C[p-2],O[p-1])<0 and
   Cmp(BL[p-2],BL[p-1])>0 and Cmp(BL[p-1],BL[p])<0 and Cmp(C[p],O[p-2])>0 and Cmp(C[p],C[p-2])<0 then
       RegisterPattern(p, PAT_EVSTAR);
   end
        if Cmp(C[p-2],O[p-2])<0 and Cmp(C[p-1],O[p-1])>0 and Cmp(C[p],O[p])>0 and Cmp(C[p-2],O[p-1])>0 and
   Cmp(BL[p-2],BL[p-1])>0 and Cmp(BL[p-1],BL[p])<0 and Cmp(C[p],C[p-2])>0 and Cmp(C[p],O[p-2])<0 then
       RegisterPattern(p, PAT_MORNSTAR);
   end
        if Cmp(C[p-2],O[p-2])>0 and Cmp(C[p-1],O[p-1])==0 and Cmp(C[p],O[p])<0 and Cmp(C[p-2],O[p-1])<0 and
   Cmp(BL[p-2],BL[p-1])>0 and Cmp(BL[p-1],BL[p])<0 and Cmp(C[p],O[p-2])>0 and Cmp(C[p],C[p-2])<0 then
       RegisterPattern(p, PAT_EVDJSTAR);
   end
        if Cmp(C[p-2],O[p-2])<0 and Cmp(C[p-1],O[p-1])==0 and Cmp(C[p],O[p])>0 and Cmp(C[p-2],O[p-1])>0 and
   Cmp(BL[p-2],BL[p-1])>0 and Cmp(BL[p-1],BL[p])<0 and Cmp(C[p],C[p-2])>0 and Cmp(C[p],O[p-2])<0 then
       RegisterPattern(p, PAT_MORNDJSTAR);
   end
    end
end


Signal:
Code: Select all
function Init()
    strategy:name("Candle patterns signal");
    strategy:description("Candle patterns signal");

    strategy.parameters:addInteger("EQ", "Maximum of pips distance between equal prices", "", 1, 0, 100);
    strategy.parameters:addBoolean("PAT_DOUBLE_INSIDE", "Enable Double Inside", "", true);
    strategy.parameters:addBoolean("PAT_INSIDE", "Enable Inside", "", true);
    strategy.parameters:addBoolean("PAT_OUTSIDE", "Enable Outside", "", true);
    strategy.parameters:addBoolean("PAT_PINUP", "Enable Pin Up", "", true);
    strategy.parameters:addBoolean("PAT_PINDOWN", "Enable Pin Down", "", true);
    strategy.parameters:addBoolean("PAT_PPRUP", "Enable Pivot Point Reversal Up", "", true);
    strategy.parameters:addBoolean("PAT_PPRDN", "Enable Pivot Point Reversal Down", "", true);
    strategy.parameters:addBoolean("PAT_DBLHC", "Enable Double Bar Low With A Higher Close", "", true);
    strategy.parameters:addBoolean("PAT_DBHLC", "Enable Double Bar High With A Lower Close", "", true);
    strategy.parameters:addBoolean("PAT_CPRU", "Enable Close Price Reversal Up", "", true);
    strategy.parameters:addBoolean("PAT_CPRD", "Enable Close Price Reversal Down", "", true);
    strategy.parameters:addBoolean("PAT_NB", "Enable Neutral Bar", "", true);
    strategy.parameters:addBoolean("PAT_NB2", "Enable 2 Neutral Bars", "", true);
    strategy.parameters:addBoolean("PAT_FBU", "Enable Force Bar Up", "", true);
    strategy.parameters:addBoolean("PAT_FBD", "Enable Force Bar Down", "", true);
    strategy.parameters:addBoolean("PAT_MB", "Enable Mirror Bar", "", true);
    strategy.parameters:addBoolean("PAT_HAMMER", "Enable Hammer", "", true);
    strategy.parameters:addBoolean("PAT_SHOOTSTAR", "Enable Shooting Star", "", true);
    strategy.parameters:addBoolean("PAT_EVSTAR", "Enable Evening Star", "", true);
    strategy.parameters:addBoolean("PAT_MORNSTAR", "Enable Morning Star", "", true);
    strategy.parameters:addBoolean("PAT_EVDJSTAR", "Enable Evening Doji Star", "", true);
    strategy.parameters:addBoolean("PAT_MORNDJSTAR", "Enable Morning Doji Star", "", true);
    strategy.parameters:addBoolean("PAT_BEARHARAMI", "Enable Bearish Harami", "", true);
    strategy.parameters:addBoolean("PAT_BEARHARAMICROSS", "Enable Bearish Harami Cross", "", true);
    strategy.parameters:addBoolean("PAT_BULLHARAMI", "Enable Bullish Harami", "", true);
    strategy.parameters:addBoolean("PAT_BULLHARAMICROSS", "Enable Bullish Harami Cross", "", true);
    strategy.parameters:addBoolean("PAT_DARKCLOUD", "Enable Dark Cloud Cover", "", true);
    strategy.parameters:addBoolean("PAT_DOJISTAR", "Enable Doji Star", "", true);
    strategy.parameters:addBoolean("PAT_ENGBEARLINE", "Enable Engulfing Bearish Line", "", true);
    strategy.parameters:addBoolean("PAT_ENGBULLLINE", "Enable Engulfing Bullish Line", "", true);

    strategy.parameters:addString("Period", "Time frame", "", "m1");
    strategy.parameters:setFlag("Period", core.FLAG_PERIODS);

    strategy.parameters:addBoolean("ShowAlert", "Show Alert", "", true);
    strategy.parameters:addBoolean("PlaySound", "Play Sound", "", false);
    strategy.parameters:addFile("SoundFile", "Sound file", "", "");
end

local SoundFile;
local gSource = nil;

local PAT_NONE = 0;
local PAT_DOUBLE_INSIDE = 1;
local PAT_INSIDE = 2;
local PAT_OUTSIDE = 4;
local PAT_PINUP = 5;
local PAT_PINDOWN = 6;
local PAT_PPRUP = 7;
local PAT_PPRDN = 8;
local PAT_DBLHC = 9;
local PAT_DBHLC = 10;
local PAT_CPRU = 11;
local PAT_CPRD = 12;
local PAT_NB = 13;
local PAT_FBU = 14;
local PAT_FBD = 15;
local PAT_MB = 16;

local PAT_HAMMER=17;
local PAT_SHOOTSTAR=18;
local PAT_EVSTAR=19;
local PAT_MORNSTAR=20;
local PAT_BEARHARAMI=21;
local PAT_BEARHARAMICROSS=22;
local PAT_BULLHARAMI=23;
local PAT_BULLHARAMICROSS=24;
local PAT_DARKCLOUD=25;
local PAT_DOJISTAR=26;
local PAT_ENGBEARLINE=27;
local PAT_ENGBULLLINE=28;
local PAT_EVDJSTAR=29;
local PAT_MORNDJSTAR=30;
local PAT_NB2 = 31;

local EQ;

function DecodePattern(pattern)
    if pattern == PAT_NONE then
        return nil, nil, nil, nil;
    elseif pattern == PAT_DOUBLE_INSIDE and instance.parameters:getBoolean("PAT_DOUBLE_INSIDE")==true then
        return "DblIn", "Double Inside", true, 3;
    elseif pattern == PAT_INSIDE and instance.parameters:getBoolean("PAT_INSIDE")==true then
        return "In", "Inside", true, 2;
    elseif pattern == PAT_OUTSIDE and instance.parameters:getBoolean("PAT_OUTSIDE")==true then
        return "Out", "Outside", true, 2;
    elseif pattern == PAT_PINUP and instance.parameters:getBoolean("PAT_PINUP")==true then
        return "PnUp", "Pin Up", true, 2;
    elseif pattern == PAT_PINDOWN and instance.parameters:getBoolean("PAT_PINDOWN")==true then
        return "PnDn", "Pin Down", false, 2;
    elseif pattern == PAT_PPRUP and instance.parameters:getBoolean("PAT_PPRUP")==true then
        return "PPRU", "Pivot Point Reversal Up", false, 3;
    elseif pattern == PAT_PPRDN and instance.parameters:getBoolean("PAT_PPRDN")==true then
        return "PPRD", "Pivot Point Reversal Down", true, 3;
    elseif pattern == PAT_DBLHC and instance.parameters:getBoolean("PAT_DBLHC")==true then
        return "DBLHC", "Double Bar Low With A Higher Close", false, 2;
    elseif pattern == PAT_DBHLC and instance.parameters:getBoolean("PAT_DBHLC")==true then
        return "DBHLC", "Double Bar High With A Lower Close", true, 2;
    elseif pattern == PAT_CPRU and instance.parameters:getBoolean("PAT_CPRU")==true then
        return "CPRU", "Close Price Reversal Up", false, 3;
    elseif pattern == PAT_CPRD and instance.parameters:getBoolean("PAT_CPRD")==true then
        return "CPRD", "Close Price Reversal Down", true, 3;
    elseif pattern == PAT_NB and instance.parameters:getBoolean("PAT_NB")==true then
        return "NB", "Neutral Bar", true, 1;
    elseif pattern == PAT_FBU and instance.parameters:getBoolean("PAT_FBU")==true then
        return "FBU", "Force Bar Up", false, 1;
    elseif pattern == PAT_FBD and instance.parameters:getBoolean("PAT_FBD")==true then
        return "FBD", "Force Bar Down", true, 1;
    elseif pattern == PAT_MB and instance.parameters:getBoolean("PAT_MB")==true then
        return "MB", "Mirror Bar", true, 2;
    elseif pattern == PAT_HAMMER and instance.parameters:getBoolean("PAT_HAMMER")==true then
        return "HAMMER", "Hammer Pattern", true, 1;
    elseif pattern == PAT_SHOOTSTAR and instance.parameters:getBoolean("PAT_SHOOTSTAR")==true then
        return "SHOOTSTAR", "Shooting Star", true, 1;
    elseif pattern == PAT_EVSTAR and instance.parameters:getBoolean("PAT_EVSTAR")==true then
        return "EVSTAR", "Evening Star", true, 3;
    elseif pattern == PAT_MORNSTAR and instance.parameters:getBoolean("PAT_MORNSTAR")==true then
        return "MORNSTAR", "Morning Star", true, 3;
    elseif pattern == PAT_EVDJSTAR and instance.parameters:getBoolean("PAT_EVDJSTAR")==true then
        return "EVDJSTAR", "Evening Doji Star", true, 3;
    elseif pattern == PAT_MORNDJSTAR and instance.parameters:getBoolean("PAT_MORNDJSTAR")==true then
        return "MORNDJSTAR", "Morning Doji Star", true, 3;
    elseif pattern == PAT_BEARHARAMI and instance.parameters:getBoolean("PAT_BEARHARAMI")==true then
        return "BEARHARAMI", "Bearish Harami", true, 2;
    elseif pattern == PAT_BEARHARAMICROSS and instance.parameters:getBoolean("PAT_BEARHARAMICROSS")==true then
        return "BEARHARAMICROSS", "Bearish Harami Cross", true, 2;
    elseif pattern == PAT_BULLHARAMI and instance.parameters:getBoolean("PAT_BULLHARAMI")==true then
        return "BULLHARAMI", "Bullish Harami", true, 2;
    elseif pattern == PAT_BULLHARAMICROSS and instance.parameters:getBoolean("PAT_BULLHARAMICROSS")==true then
        return "BULLHARAMICROSS", "Bullish Harami Cross", true, 2;
    elseif pattern == PAT_DARKCLOUD and instance.parameters:getBoolean("PAT_DARKCLOUD")==true then
        return "DARKCLOUD", "Dark Cloud Cover", true, 2;
    elseif pattern == PAT_DOJISTAR and instance.parameters:getBoolean("PAT_DOJISTAR")==true then
        return "DOJISTAR", "Doji Star", true, 2;
    elseif pattern == PAT_ENGBEARLINE and instance.parameters:getBoolean("PAT_ENGBEARLINE")==true then
        return "ENGBEARLINE", "Engulfing Bearish Line", true, 2;
    elseif pattern == PAT_ENGBULLLINE and instance.parameters:getBoolean("PAT_ENGBULLLINE")==true then
        return "ENGBULLLINE", "Engulfing Bullish Line", true, 2;
    elseif pattern == PAT_NB2 and instance.parameters:getBoolean("PAT_NB2")==true then
        return "NB2", "2 Neutral Bar", true, 2;
    else
        return nil, nil, nil, nil;
    end
end

function RegisterPattern(period, pattern)
    local short, long, up, length;
    local price;
    short, long, up, length = DecodePattern(pattern);
    if length~=nil then
     if up then
         ExtSignal(gSource.high, period, long, SoundFile);
     else
         ExtSignal(gSource.low, period, long, SoundFile);
     end
    end
end


function Cmp(price1, price2)
    if math.abs(price1 - price2) < EQ then
        return 0;
    elseif price1 > price2 then
        return 1;
    else
        return -1;
    end
end

function Prepare()

    ShowAlert = instance.parameters.ShowAlert;
   
    if instance.parameters.PlaySound then
        SoundFile = instance.parameters.SoundFile;
    else
        SoundFile = nil;
    end

    assert(not(PlaySound) or (PlaySound and SoundFile ~= ""), "Sound file must be specified");

    ExtSetupSignal(profile:id() .. ":", ShowAlert);

    assert(instance.parameters.Period ~= "t1", "Can't be applied on ticks!");

    gSource = ExtSubscribe(1, nil, instance.parameters.Period, true, "bar");
   
    EQ = instance.parameters.EQ * gSource:pipSize();

    local name = profile:id() .. "(" .. instance.bid:instrument()  .. "(" .. instance.parameters.Period  .. ")" .. ")";
    instance:name(name);
end

local O, H, L, C, T, B, BL, US, LS;
local O1, H1, L1, C1, T1, B1, BL1, US1, LS1;
local O2, H2, L2, C2, T2, B2, BL2, US2, LS2;

-- when tick source is updated
function ExtUpdate(id, source, period)
    if period <= 3 then
        return ;
    end
   
    O=gSource.open[period];
    H=gSource.high[period];
    L=gSource.low[period];
    C=gSource.close[period];
    T=math.max(O,C);
    B=math.min(O,C);
    BL=T-B;
    US=H-T;
    LS=B-L;
    O1=gSource.open[period-1];
    H1=gSource.high[period-1];
    L1=gSource.low[period-1];
    C1=gSource.close[period-1];
    T1=math.max(O1,C1);
    B1=math.min(O1,C1);
    BL1=T1-B1;
    US1=H1-T1;
    LS1=B1-L1;
    O2=gSource.open[period-2];
    H2=gSource.high[period-2];
    L2=gSource.low[period-2];
    C2=gSource.close[period-2];
    T2=math.max(O2,C2);
    B2=math.min(O2,C2);
    BL2=T2-B2;
    US2=H2-T2;
    LS2=B2-L2;


-- 1 - candle patterns
   
    if Cmp(O, C) == 0 and US > math.max(EQ * 4, gSource:pipSize() * 4) and
       LS > math.max(EQ * 4, gSource:pipSize() * 4) then
     RegisterPattern(period, PAT_NB);
    end

    if C == H then
     RegisterPattern(period, PAT_FBU);
    end

    if C == L then
     RegisterPattern(period, PAT_FBD);
    end

    if US <= math.max(EQ, gSource:pipSize()) and LS>2.*BL then
     RegisterPattern(period, PAT_HAMMER);
    end

    if LS <= math.max(EQ, gSource:pipSize()) and US>2.*BL then
     RegisterPattern(period, PAT_SHOOTSTAR);
    end
   
-- 2 - candle patterns   

       if Cmp(H, H1) < 0 and Cmp(L, L1) > 0 then
           RegisterPattern(period, PAT_INSIDE);
       end
       
       if Cmp(H, H1) > 0 and Cmp(L, L1) < 0 then
           RegisterPattern(period, PAT_OUTSIDE);
       end
       
       if Cmp(H, H1) == 0 and Cmp(C, C1) < 0 and Cmp(L, L1) <= 0 then
           RegisterPattern(period, PAT_DBHLC);
       end
       
       if Cmp(L, L1) == 0 and Cmp(C, C1) > 0 and Cmp(H, H1) >= 0  then
           RegisterPattern(period, PAT_DBLHC);
       end
       
       if Cmp(BL1, BL) == 0 and Cmp(O1, C) == 0 then
           RegisterPattern(period, PAT_MB);
       end
       
       if Cmp(H,H1)<0 and Cmp(L,L1)>0 and Cmp(C1,O1)>0 and
       Cmp(C,O)<0 and Cmp(BL1,BL)>0 and Cmp(C1,O)>0 and Cmp(O1,C)<0 then
           RegisterPattern(period, PAT_BEARHARAMI);
       end
       
       if Cmp(H,H1)<0 and Cmp(L,L1)>0 and Cmp(C1,O1)>0 and Cmp(O,C)==0 and
       Cmp(BL1,BL)>0 and Cmp(C1,O)>0 and Cmp(O1,C)<0 then
           RegisterPattern(period, PAT_BEARHARAMICROSS);
       end
       
       if Cmp(H,H1)<0 and Cmp(L,L1)>0 and Cmp(C1,O1)<0 and
       Cmp(C,O)>0 and Cmp(BL1,BL)>0 and Cmp(C1,O)<0 and Cmp(O1,C)>0 then
           RegisterPattern(period, PAT_BULLHARAMI);
       end
       
       if Cmp(H,H1)<0 and Cmp(L,L1)>0 and Cmp(C1,O1)<0 and Cmp(O,C)==0 and
       Cmp(BL1,BL)>0 and Cmp(C1,O)<0 and Cmp(O1,C)>0 then
           RegisterPattern(period, PAT_BULLHARAMICROSS);
       end
       
       if Cmp(C1,O1)>0 and Cmp(C,O)<0 and Cmp(H1,O)<0 and Cmp(C,C1)<0 and Cmp(C,O1)>0 then
           RegisterPattern(period, PAT_DARKCLOUD);
       end
       
       if Cmp(O,C)==0 and ((Cmp(C1,O1)>0 and Cmp(O,H1)>0) or (Cmp(C1,O1)<0 and Cmp(O,L1)<0)) then
           RegisterPattern(period, PAT_DOJISTAR);
       end
       
       if Cmp(C1,O1)>0 and Cmp(C,O)<0 and Cmp(O,C1)>0 and Cmp(C,O1)<0 then
           RegisterPattern(period, PAT_ENGBEARLINE);
       end
       
       if Cmp(C1,O1)<0 and Cmp(C,O)>0 and Cmp(O,C1)<0 and Cmp(C,O1)>0 then
           RegisterPattern(period, PAT_ENGBULLLINE);
       end
       
       if Cmp(O, C) == 0 and US > math.max(EQ * 4, gSource:pipSize() * 4) and
          LS > math.max(EQ * 4, gSource:pipSize() * 4) and
     Cmp(O1, C1) == 0 and US1 > math.max(EQ * 4, gSource:pipSize() * 4) and
     LS1 > math.max(EQ * 4, gSource:pipSize() * 4) then
        RegisterPattern(period, PAT_NB2);
       end
       
-- 3 - candle patterns           

        if Cmp(H, H1) < 0 and Cmp(L, L1) > 0 and
           Cmp(H1, H2) < 0 and Cmp(L1, L2) > 0 then
            RegisterPattern(period, PAT_DOUBLE_INSIDE);
        end
       
        if Cmp(H1, H2) > 0 and Cmp(H1, H) > 0 and
           Cmp(L1, L2) > 0 and Cmp(L1, L) > 0 and
           BL1 * 2 < US1 then
            RegisterPattern(period, PAT_PINUP);
        end
       
        if Cmp(H1, H2) < 0 and Cmp(H1, H) < 0 and
           Cmp(L1, L2) < 0 and Cmp(L1, L) < 0 and
           BL1 * 2 < LS1 then
            RegisterPattern(period, PAT_PINDOWN);
        end
       
        if Cmp(H1, H2) > 0 and Cmp(H1, H) > 0 and
           Cmp(L1, L2) > 0 and Cmp(L1, L) > 0 and
           Cmp(C, L1) < 0 then
            RegisterPattern(period, PAT_PPRDN);
        end
       
        if Cmp(H1, H2) < 0 and Cmp(H1, H) < 0 and
           Cmp(L1, L2) < 0 and Cmp(L1, L) < 0 and
           Cmp(C, H1) > 0 then
            RegisterPattern(period, PAT_PPRUP);
        end
       
        if Cmp(H1, H2) < 0 and Cmp(L1, L2) < 0 and
           Cmp(H, H1) < 0 and Cmp(L, L1) < 0 and
           Cmp(C, C1) > 0 and Cmp(O, C) < 0 then
            RegisterPattern(period, PAT_CPRU);
        end
       
        if Cmp(H1, H2) > 0 and Cmp(L1, L2) > 0 and
           Cmp(H, H1) > 0 and Cmp(L, L1) > 0 and
           Cmp(C, C1) < 0 and Cmp(O, C) > 0 then
            RegisterPattern(period, PAT_CPRD);
        end
       
        if Cmp(C2,O2)>0 and Cmp(C1,O1)>0 and Cmp(C,O)<0 and Cmp(C2,O1)<0 and
   Cmp(BL2,BL1)>0 and Cmp(BL1,BL)<0 and Cmp(C,O2)>0 and Cmp(C,C2)<0 then
       RegisterPattern(period, PAT_EVSTAR);
   end
   
        if Cmp(C2,O2)<0 and Cmp(C1,O1)>0 and Cmp(C,O)>0 and Cmp(C2,O1)>0 and
   Cmp(BL2,BL1)>0 and Cmp(BL1,BL)<0 and Cmp(C,C2)>0 and Cmp(C,O2)<0 then
       RegisterPattern(period, PAT_MORNSTAR);
   end
   
        if Cmp(C2,O2)>0 and Cmp(C1,O1)==0 and Cmp(C,O)<0 and Cmp(C2,O1)<0 and
   Cmp(BL2,BL1)>0 and Cmp(BL1,BL)<0 and Cmp(C,O2)>0 and Cmp(C,C2)<0 then
       RegisterPattern(period, PAT_EVDJSTAR);
   end
   
        if Cmp(C2,O2)<0 and Cmp(C1,O1)==0 and Cmp(C,O)>0 and Cmp(C2,O1)>0 and
   Cmp(BL2,BL1)>0 and Cmp(BL1,BL)<0 and Cmp(C,C2)>0 and Cmp(C,O2)<0 then
       RegisterPattern(period, PAT_MORNDJSTAR);
   end

end

dofile(core.app_path() .. "\\strategies\\standard\\include\\helper.lua");
Attachments
Patterns3.lua
(16.94 KiB) Downloaded 3100 times
Patterns3_Signal.lua
(16.09 KiB) Downloaded 2823 times
Alexander.Gettinger
FXCodeBase: Confirmed User
 
Posts: 3785
Joined: Wed Mar 31, 2010 9:40 pm
Location: Russia, Omsk

PreviousNext

Return to Custom Indicators

Who is online

Users browsing this forum: Majestic-12 [Bot] and 9 guests