HHLL/Mac

 avatar
s7s
java
2 months ago
20 kB
5
Indexable


//@version=5
indicator("High Low With TF [S7S7] " , overlay = true, max_lines_count = 500, max_labels_count = 500)

timeframe   = input.timeframe   (defval = '360')
Left_B      = input.int         (defval = 2, title = "Left B" , minval = 1)
Right_B     = input.int         (defval = 2, title = "Right B", minval = 1)
HH_LinColor = input.color       (defval = color.blue, title = "P H/L Line_Colors")
LL_LinColor = input.color       (defval = color.red, title = "") 
HH_BTColor  = input.color       (defval = color.lime, title = "Pivot High BG/Text Colors", inline = "HH")
HH_TxtColor = input.color       (defval = color.black, title = "", inline = "HH")
LL_BTColor  = input.color       (defval = color.red, title = "Pivot Low BG/Text Colors", inline = "LL")
LL_TxtColor = input.color       (defval = color.white, title = "", inline = "LL")
get_HHLL()=>
    float HH = ta.pivothigh(Left_B, Right_B)
    float LL = ta.pivotlow(Left_B, Right_B)
    HH_strt = HH ? time[Right_B]  : na
    HH_end  = HH ? time[Right_B-1]: na 
    LL_strt = LL ? time[Right_B]  : na
    LL_end  = LL ? time[Right_B-1]: na

    [HH, HH_strt, HH_end, LL, LL_strt, LL_end]

// ed / function tf
[HH, HH_strt, HH_end, LL, LL_strt, LL_end] = request.security(syminfo.tickerid, timeframe, get_HHLL(), lookahead = barmerge.lookahead_on)

// keep time of each bars, this is used for lines/labels
var timm = array.new_int(0)
array.unshift(timm, time)

// calculate end of the line/time for pivot high/low
HH_endLine = array.get(timm, math.min(array.indexof(timm, HH_end) + 1, array.size(timm) - 1))
LL_endLine = array.get(timm, math.min(array.indexof(timm, LL_end) + 1, array.size(timm) - 1))

// to draw once
float HH_Piv = na(HH[1]) and HH ? HH : na
float LL_Piv  = na(LL[1]) and LL ? LL : na

tik_lenth = input(350,'lenth highst / lowst')

width=(ta.highest(tik_lenth) - ta.lowest(tik_lenth)) / 50

if not na(HH_Piv)
    line.new(x1 = HH_strt   , y1 = HH_Piv, x2 = HH_endLine  , y2 = HH_Piv        , color = HH_LinColor, xloc = xloc.bar_time, width = 2)
    line.new(x1 = HH_strt   , y1 = HH_Piv, x2 = HH_strt     , y2 = HH_Piv + width, color = HH_LinColor, xloc = xloc.bar_time, width = 2)
    line.new(x1 = HH_endLine, y1 = HH_Piv, x2 = HH_endLine  , y2 = HH_Piv + width, color = HH_LinColor, xloc = xloc.bar_time, width = 2)
    label.new(x = (HH_strt + HH_endLine) / 2, y = HH_Piv + width,text = str.tostring(math.round_to_mintick(HH_Piv)), color = HH_BTColor, textcolor = HH_TxtColor,xloc = xloc.bar_time)

if not na(LL_Piv)
    line.new(x1 = LL_strt , y1 = LL_Piv, x2 = LL_endLine, y2 = LL_Piv, color = LL_LinColor, xloc = xloc.bar_time,width =2)
    line.new(x1 = LL_strt , y1 = LL_Piv, x2 = LL_strt, y2 = LL_Piv - width, color = LL_LinColor, xloc = xloc.bar_time,width = 2)
    line.new(x1 = LL_endLine, y1 = LL_Piv, x2 = LL_endLine, y2 = LL_Piv - width, color = LL_LinColor, xloc = xloc.bar_time, width = 2)
    label.new(x = (LL_strt + LL_endLine) / 2, y = LL_Piv - width,text = str.tostring(math.round_to_mintick(LL_Piv)),color = LL_BTColor, textcolor = LL_TxtColor, style = label.style_label_up,xloc = xloc.bar_time)
    

var int TYPE_UP = 1
var int TYPE_DOWN = -1
var string LINE_WIDTH1_STR = "Width 1"
var string LINE_WIDTH2_STR = "Width 2"
_get_width(string str_input) =>
    switch str_input // {string:int}
        LINE_WIDTH1_STR => 1
        LINE_WIDTH2_STR => 2

// ----------------------------------------------------------------------------
// Settings:
// {
var string GROUP_FRACT  = "Fractals"
var int n               = input.int(10, title="Fractal Period", minval=2, group=GROUP_FRACT)
var color col_hl        = input.color(color.blue, title="Plot:", inline="plot_low", group=GROUP_FRACT)
var bool show_hl        = input.bool(true, title="HL", inline="plot_low", group=GROUP_FRACT)
var color col_ll        = input.color(color.gray, title=", Plot:", inline="plot_low", group=GROUP_FRACT)
var bool show_ll        = input.bool(false, title="LL", inline="plot_low", group=GROUP_FRACT)
var color col_lh        = input.color(color.red, title="Plot:", inline="plot_high", group=GROUP_FRACT)
var bool show_lh        = input.bool(true, title="LH", inline="plot_high", group=GROUP_FRACT)
var color col_hh        = input.color(color.gray, title=", Plot:", inline="plot_high", group=GROUP_FRACT)
var bool show_hh        = input.bool(false, title="HH", inline="plot_high", group=GROUP_FRACT) 

var string GROUP_ATL    = "Auto trendlines"
var string subgroup1    = "recent line"
var color ln_col_recent = input.color(color.new(color.purple, 0), title="Recent Line", group=GROUP_ATL, inline=subgroup1)
var int lnwidth_recent  = _get_width(input.string(LINE_WIDTH1_STR, options=[LINE_WIDTH1_STR, LINE_WIDTH2_STR], title="", inline=subgroup1, group=GROUP_ATL))
var string subgroup2    = "historical line"
var color ln_col_prev   = input.color(color.new(color.gray, 50), title="Historical Line", group=GROUP_ATL, inline=subgroup2)
var int lnwidth_prev    = _get_width(input.string(LINE_WIDTH1_STR, options=[LINE_WIDTH1_STR, LINE_WIDTH2_STR], title="", inline=subgroup2, group=GROUP_ATL))

var int max_tl          = input.int(1, title="Max pair of lines", maxval=250, minval=1, group=GROUP_ATL)*2
var string _str_extend  = input.string("Right", options=["Right", "Both ways"], title="Which way to extend lines", group=GROUP_ATL)
var string str_extend   = _str_extend == "Both ways" ? extend.both : extend.right

var bool show_crosses   = input.bool(false, title="Show crosses", tooltip="Instances when closing price of a bar has crossed lower/upper trendlines", group=GROUP_ATL)
// }

// ----------------------------------------------------------------------------
// Fractal UDT and other relevant data structures: 
// Handle fractals and trendlines associated with them
// {
type fractal
    int up_or_down = na // either TYPE_UP or TYPE_DOWN
    int xloc = na 
    float yloc = na
    int xloc_parent = na
    float yloc_parent = na

var fractal[] arr_fract = array.new<fractal>()  // Can be used for multiple purposes such as:
                                                // (a) connecting trendlines but added condition to skip X no. of fractals in between
                                                // (b) create a zigzag, since knowing foo.parent's x and y
                                                // ... possibilities are endless

var line[] arr_ln_up = array.new_line() // Array of lines, newest elements inserted to front
var line[] arr_ln_dn = array.new_line()

// @function init_fractal() returns instance of fractal that has been init'ed
init_fractal(int fract_type, int xloc, float yloc, int xparent, float yparent)=>
    f = fractal.new()
    f.up_or_down := fract_type
    f.xloc := xloc
    f.yloc := yloc
    f.xloc_parent := xparent
    f.yloc_parent := yparent

    ln = line.new(xloc, yloc, xparent, yparent, xloc.bar_index, str_extend, color=ln_col_recent, style=line.style_dashed, width=lnwidth_recent)
    if f.up_or_down == TYPE_UP
        array.unshift(arr_ln_up, ln) 
    else if f.up_or_down == TYPE_DOWN
        array.unshift(arr_ln_dn, ln)
    
    array.unshift(arr_fract, f) 
    f // <- return

// @function drop_and_roll(new fractal) returns void
// Clean up: Drop oldest trendlines, change colors for previous trendline
drop_and_roll(fractal f) =>
    arr_ln = f.up_or_down == TYPE_UP ? arr_ln_up : f.up_or_down == TYPE_DOWN ? arr_ln_dn : na
    if array.size(arr_ln) > 1
        line.set_color(array.get(arr_ln, 1), ln_col_prev)
        line.set_width(array.get(arr_ln, 1), lnwidth_prev)
        while array.size(arr_ln) > math.floor(max_tl/2)
            line.delete(array.pop(arr_ln))

// @function draw_trendline() returns void
draw_trendline(fract_type, x2, y2, x1, y1) =>
    f = init_fractal(fract_type, x2, y2, x1, y1)
    drop_and_roll(f)

// } end of handle for fractals

// ----------------------------------------------------------------------------
// Fractals, implemented using ta.pivot high && low 
// ----------------------------------------------------------------------------

// A Fractal is always a Pivot H/L (but a Pivot H/L is not always a Fractal):
float ph = ta.pivothigh(n, n)[1], bool upfract = not na(ph)
float pl = ta.pivotlow(n, n)[1],  bool downfract = not na(pl)

alertcondition(not na(ph) or not na(pl), title="New trendline formed", message="New trendline formed")

// Pointers -> Recent fractals
// {
var float recent_dn1   = na,  var int i_recent_dn1 = na
var float recent_up1   = na,  var int i_recent_up1 = na
var float recent_dn2   = na,  var int i_recent_dn2 = na
var float recent_up2   = na,  var int i_recent_up2 = na

if downfract 
    recent_dn2:=recent_dn1, i_recent_dn2 := i_recent_dn1
    recent_dn1:=low[n+1],   i_recent_dn1 := bar_index-n-1
    draw_trendline(TYPE_DOWN, i_recent_dn2, recent_dn2, i_recent_dn1, recent_dn1)

if upfract 
    recent_up2:=recent_up1, i_recent_up2 := i_recent_up1
    recent_up1:=high[n+1],  i_recent_up1 := bar_index-n-1
    draw_trendline(TYPE_UP, i_recent_up2, recent_up2, i_recent_up1, recent_up1)

// }

// Plotting fractals
bool hh = upfract and recent_up1 > recent_up2 ? high[n+1] : na
bool lh = upfract and recent_up1 < recent_up2 ? high[n+1] : na
bool hl = downfract and recent_dn1 > recent_dn2 ? low[n+1] : na
bool ll = downfract and recent_dn1 < recent_dn2 ? low[n+1] : na

plotshape(show_hh and hh, style=shape.circle, size=size.tiny, offset=-n-1, title="HH", text="HH", location=location.abovebar, textcolor=col_hh, color=na, editable=false)
plotshape(show_lh and lh, style=shape.circle, size=size.tiny, offset=-n-1, title="LH", text="LH", location=location.abovebar, textcolor=col_lh, color=na, editable=false)
plotshape(show_ll and ll, style=shape.circle, size=size.tiny, offset=-n-1, title="LL", text="LL", location=location.belowbar, textcolor=col_ll, color=na, editable=false)
plotshape(show_hl and hl, style=shape.circle, size=size.tiny, offset=-n-1, title="HL", text="HL", location=location.belowbar, textcolor=col_hl, color=na, editable=false)

// ----------------------------------------------------------------------------
// Finding crosses between closing price & pair of most recent trendlines
// ----------------------------------------------------------------------------

// @function get_slope()
get_slope(xA, yA, xB, yB) =>
    (yB - yA) / (xB - xA)

// Solving for price at current x (bar_index), given two pairs of fractals with x values < bar_index.
float m_dn = get_slope(i_recent_dn1, recent_dn1, i_recent_dn2, recent_dn2)
float y_dn = (m_dn * bar_index) + recent_dn1 - (m_dn * i_recent_dn1)
float m_up = get_slope(i_recent_up1, recent_up1, i_recent_up2, recent_up2)
float y_up = (m_up * bar_index) + recent_up1 - (m_up * i_recent_up1)

// Plotting crosses
bool cross_upper = ta.cross(close, y_up) 
bool cross_lower = ta.cross(close, y_dn) 
plotshape(show_crosses and cross_upper, title = "Crossed upper trendline", style = shape.xcross, 
 location = location.belowbar, color = color.new(color = color.blue, transp = 50), size = size.small)
plotshape(show_crosses and cross_lower, title = "Crossed lower trendline", style = shape.xcross, 
 location = location.abovebar, color = color.new(color = color.red, transp = 50), size = size.small)
alertcondition(cross_upper or cross_lower, title="Upper/lower trendline crossed", message="Upper/lower trendline crossed")


// Time filter 
grTIMEset = " ------|  Testing Date Period  |------"
testPeriod() =>
    // Testing Start dates
    testStartYear   = input.int(2023, 'Start Year', inline='date1', group=grTIMEset)
    testStartMonth  = input.int(1   , 'Month', inline ='date1', group=grTIMEset)
    testStartDay    = input.int(1   , 'Day', inline='date1', group=grTIMEset)
    testStopYear    = input.int(2023, 'Stop Year', inline='date2', group=grTIMEset)
    testStopMonth   = input.int(1   , 'Stop Month', inline='date2', group=grTIMEset)
    testStopDay     = input.int(20  , 'Stop Day', inline='date2', group=grTIMEset)
    testPeriodStop  = timestamp(testStopYear, testStopMonth, testStopDay, 0, 0)
    testPeriodStart = timestamp(testStartYear, testStartMonth, testStartDay,0, 0)

    time >= testPeriodStart and time < testPeriodStop ? true : false

    testPeriodStop
    
// Time filter =================================
//                                   1# WaveTrend
f_wavetrend(_src, _chlen, _avg, _malen) =>
    _esa = ta.ema(_src, _chlen)
    _de  = ta.ema(math.abs(_src - _esa), _chlen)
    _ci  = (_src - _esa) / (0.015 * _de)
    _tci = ta.ema(_ci, _avg)
    _wt1 = _tci
    _wt2 = ta.sma(_wt1, _malen)
    [_wt1, _wt2]

////-----------------------------------|2# ( 4_ line EMA Ribbon ) 
f_emaRibbon(_src, L_SMA,L_EMA, L_WEMA, L_ALMA) =>
    _SMA = ta.sma(_src, L_SMA)
    _EMA = ta.ema(_src, L_EMA)
    _WEMA = ta.sma (_src, L_WEMA)
    _ALMA = ta.ema(_src, L_ALMA)
    [_SMA, _EMA, _WEMA, _ALMA]

// 

//                                 1# Range Size Function
//                                 2# Range Filter Function
//                                  PARAMETERS and InPut
gr_wavatrend = "------| Input WT  |------" 
//                                  1# WaveTrend
sow_WT       = input(true   , 'Sow Wave Trend','0',gr_wavatrend )
wtMASource   = input(hlc3   , title ='Source',tooltip = 'Input Wave Trend',inline = '1', group = gr_wavatrend)
wtMALen      = input(3      , title ='Length',inline = '1', group = gr_wavatrend)
wtChannelLen = input(7      , title ='WT Channel Length',inline = '1', group = gr_wavatrend)
wtAverageLen = input(15     , title ='WT Average Length',inline = '1', group = gr_wavatrend)
//                                  2# WaveTrend Over bought 
gr_WT_Bought = " ------|  .... WT Ovre_B  |------ "
obLevel      = input(80     , title='LvL 1',inline = '1',group = gr_WT_Bought)
obLevel2     = input(160     , title='LvL 2',inline = '1',group = gr_WT_Bought)
obLevel3     = input(320    , title='LvL 3',inline = '1',group = gr_WT_Bought)
//                                  3# WaveTrend Over sold lines
gr_WT_Sold = " ------|  WT Ovre_S  |------ "
osLevel      = input(-80   , title='LvL -1',inline = '2',group = gr_WT_Sold)
osLevel2     = input(-160    , title='LvL -2',inline = '2',group = gr_WT_Sold)
osLevel3     = input(-320   , title='LvL -3',inline = '2',group = gr_WT_Sold)
//                                  4# EMA Ribbon
gr_EMA = "------|  EMA Ribbon  |------"
showRibbon      = input(true   ,'_ تفعيل شريط _ EMA',group = gr_EMA)
LenSLOW_SMA     = input(7      , title='Len_7'  ,inline = '3',group = gr_EMA)
LenSLOW_EMA     = input(14     , title='Len_14' ,inline = '3',group = gr_EMA)
LenFAST_SMA     = input(7      , title='Len_7'  ,inline = '3',group = gr_EMA)
LenFAST_EMA     = input(14     , title='Len_14' ,inline = '3',group = gr_EMA)
Len_WEMA        = input(28     , title='Len_28' ,inline = '4',group = gr_EMA)
LenFAST_MA      = input(50     , title='Len_50' ,inline = '4',group = gr_EMA)
LenSLOW_MA      = input(50     , title='Len_50' ,inline = '4',group = gr_EMA)
Len_ALMA        = input(100    , title='Len_100',inline = '5',group = gr_EMA)


// set line styles
var reg_div_l_style = reg_div_l_style_ == 'Solid' ? line.style_solid : reg_div_l_style_ == 'Dashed' ? line.style_dashed : line.style_dotted
var hid_div_l_style = hid_div_l_style_ == 'Solid' ? line.style_solid : hid_div_l_style_ == 'Dashed' ? line.style_dashed : line.style_dotted

// keep indicators names and colors in arrays
// !!!!!!!! DIMAK - add num of Indicators +1
var indicators_name = array.new_string  (19)
var div_colors      = array.new_color   (4)

showlines   = input(defval=false, title='Show Divergence Lines' , group = grMAINset)
showpivot   = input(defval=false, title='Show Pivot Points'     , group = grMAINset)

ph1         = ta.pivothigh(source == 'Close' ? close : high, prd, prd)
float ph    = ta.pivothigh(source == 'Close' ? close : high, prd, prd)  
float pl    = ta.pivotlow (source == 'Close' ? close : low , prd, prd)
pl1         = ta.pivotlow (source == 'Close' ? close : low , prd, prd)

plotshape(ph==ph1 and showpivot, text='H', style=shape.labeldown, color=color.new(color.white, 100), textcolor=color.new(color.red, 0), location=location.abovebar, offset=-prd)
plotshape(pl==pl1 and showpivot, text='L', style=shape.labelup  , color=color.new(color.white, 100), textcolor=color.new(color.lime, 0), location=location.belowbar, offset=-prd)

// keep values and positions of Pivot Highs/Lows in the arrays
var int maxarraysize = 20
var ph_positions = array.new_int(maxarraysize, 0)
var pl_positions = array.new_int(maxarraysize, 0)
var ph_vals      = array.new_float(maxarraysize, 0.)
var pl_vals      = array.new_float(maxarraysize, 0.)

// add PHs to the array
if ph==ph1
    array.unshift(ph_positions, bar_index)
    array.unshift(ph_vals, ph)
    if array.size(ph_positions) > maxarraysize
        array.pop(ph_positions)
        array.pop(ph_vals)

// add PLs to the array
if pl==pl1 // ph==ph1
    array.unshift(pl_positions,bar_index)
    array.unshift(pl_vals, pl)
    if array.size(pl_positions) > maxarraysize
        array.pop(pl_positions)
        array.pop(pl_vals)

// functions to check Regular Divergences and Hidden Divergences
if pl==pl1 
    remove_last_pos_divs := false
    last_pos_div_lines := 0
    last_pos_div_lines
//
if ph==ph1
    remove_last_neg_divs := false
    last_neg_div_lines := 0
    last_neg_div_lines
//

longCondition1  = input.bool(true,"long")
longCondition2  = input.bool(true,"long")
longCondition3  = input.bool(true,"long")
longCondition4  = input.bool(true,"long")
if  longCondition1
    ########
if  longCondition2
    ########
if  longCondition3
    ########
if  longCondition4
    ########
//dimak RSI timeframe  END
// ======================= dimak RSI timeframe Begin 22222222 ====================
// ==  TEST CODE by  =================================================================================================

reverseCond = strategy.closedtrades.exit_comment(strategy.closedtrades - 1)
exitPrice   = strategy.closedtrades.exit_price(strategy.closedtrades - 1)

if strategy.position_size == 0 and reverseCond == 'LSL'
    strategy.entry('sell', strategy.short, alert_message='enter_cycle')
if strategy.position_size == 0 and reverseCond == 'SSL'
    strategy.entry('buy', strategy.long, alert_message='enter_cycle')
    
// =====  TEST CODE by   ==============================================================================================

NotMultiOrders = ((strategy.closedtrades == 0) or ((bar_index != strategy.closedtrades.entry_bar_index(strategy.closedtrades - 1))))
//NotMultiOrders = true

// ============ New order after SL =======================================================================================

var wasLong = false

if USE_SignSL and strategy.closedtrades.exit_bar_index(strategy.closedtrades-1) == bar_index and NotMultiOrders
    if wasLong
        wasLong := false
        strategy.entry('SELL _ 2 ', strategy.short, alert_message='enter_cycle')
        
    if wasShort
        wasShort := false
        strategy.entry('BUY _ 2 ', strategy.long, alert_message='enter_cycle')
//
// ===================================================================================================
// ===================================================================================================
if strategy.position_size > 0
    strategy.exit( id =' T/P  %' , from_entry='buy', stop=Long_SL_EX, limit=Long_TP_EX, alert_message='stoploss')
if strategy.position_size < 0
    strategy.exit(id='Close Short %', from_entry='sell', stop=short_SL_EX, limit=short_TP_EX, alert_message='stoploss')
// ===================================================================================================

//—————————— PRICE BOXES