Квартальные линии с плавающими таймфреймами

Индикатор квартальных линий "Kvartal Line ".

  1. : ( Auto ) Линии Условных Кварталов в году :

                                        (Start) День . Месяц - (End) День . Месяц
     1я пара линий ( High, Low ) :  в пятницу 2й недели . 03 - 5 . 06    
     2я пара линий ( High, Low ) :  в пятницу 2й недели . 06 - 4 . 09
     3я пара линий ( High, Low ) :  в пятницу 2й недели . 09 - 4 . 12
     4я пара линий ( High, Low ) :  в пятницу 2й недели . 12 - 6 . 03
    

Линии ( High, Low ) последнего квартала по соответствию формулы : от последнего завершенного квартала присутствие баров являющийся будущим кварталом. И далее, в случае присутствия текущих параметров, формула линий (из баров) : на графике (tikerid) присутствие 2й пятницы ( ~ присутствие 12 баров от последнего завершенного квартала до last_bar_index )

90 ( квартал ) - 12 ( 2я пятница ) = 78 ( будущих баров, от текущего бара - last_bar_index ) .

  1. ( Auto ) Годовая разметка ( вертикальная линия, color.gray (default) ) .

  2. ( Auto ) Квартальный разделитель ( вертикальная линия, color.silver (default) ) .

Квартальный разделитель для текущего ( последнего ) квартала . ( current values - от последнего завершенного квартала присутствие баров являющийся будущим кварталом ). И далее, в случае присутствия текущих параметров, вертикальная линия на основании формулы : на графике (tikerid) присутствие 2й пятницы ( ~ присутствие 12 баров от последнего завершенного квартала до last_bar_index )

90 ( квартал ) - 12 ( 2я пятница ) = 78 ( после будущих баров, в присутствии, от текущего бара ) .

  1. Timeframe :

    4 H  ->  YTD
    1 D  ->  YTD
    1 W  ->  YTD
    1 M  ->  YTD
    

2е версии кода : в 1й (через bar_index) - все идеально, но Timeframe функционирует только " 1 D -> YTD "; во 2й (для улучшения Timeframe позиций по условию, через time) - все идеально, но не так работает скрипт pine, как надо. Не судите молодого студента, если что-то не то в скрипте. За ранее благодарен.


1я версия кода :


//@version=5
indicator(" Kvartal line ", overlay=true, max_lines_count=500)

//
//
//---- I -----------    User   values   -----------------------------------------------------------------------------------------
// 
// 
string group_1 = "---------- ГОРИЗОНТАЛЬНЫЕ линии High и Low,  цвета и толщина  ----------"
//
color clr_High = input.color(color.green,  "Color High  ",  group=group_1)    //  " Color High "
color clr_Low  = input.color(color.red,      "Color Low  ",   group=group_1)    //  " Color Low "
// 
int width_High = input.int(1,  " width line, High  ",   group=group_1)    //  color.navy, "Color Low")
int width_Low  = input.int(1,  " width line, Low  ",    group=group_1)    //  color.navy, "Color Low")
// 
// 
string group_2 = "---------- ВЕРТИКАЛЬНЫЕ линии ----------"
//
color clr_Year = input.color(color.gray,   "Color year ",   group=group_2)   // year line
color clr_3M   = input.color(#81c385,    "Color 3M ",     group=group_2)    // квартальная line
//
int width_Year = input.int(2,  " width line, Year  ",   group=group_2)     
int width_3M   = input.int(1,  " width line, 3M  ",     group=group_2)   
// 
// 
// 
//---- II -------------    Structuring    ---------------------------------------------------------------------
// 
// 
int current_bar = bar_index     //   Определие текущего бара
// 
//  
// >>>>>>>>>>>>>>>>    дорисовать будущий квартал   (FK)    >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// 
//  Устанавка условия для сохраненного обновления current Kvartal (current_K)
//  при следующей прорисовке добавления нового бара
var int current_K = na   //  Определие бара последнего прошлого квартала ( ... _end), чтобы дорисовать будущий
int period_Index  = 10  //  Разница  (last_bar_index - current_K) , чтобы дорисовать будущий квартал
//
//   Определие количества баров будущего квартала ( n ... last_bar_index )
int bars_before = last_bar_index - current_K    //    !     ( to last_bar_index = ) 28 ... last_bar_index      
int _bars_in_K = 90                           //   Бары  будущего квартала  = min =  90  баров 
//
bool is_FK = ( bars_before < _bars_in_K )    //   Присутствие Будущего квартала 
//  
// 
if is_FK        //  Определие количества баров будущего квартала (n ... last_bar_index)
    period_Index := bars_before - 5 //   из 2й пятницы месяца  ( 2nd friday )
// 
float Price_H_period = ta.highest(period_Index) 
float Price_L_period = ta.lowest(period_Index)
//  
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<    дорисовать будущий квартал     <<<<<<<<<<<<<
// 
// 
// 
// 
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>    Годовая разметка     >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
// 
is_year_start = year != year[1]
//  
if is_year_start
    line.new(bar_index, low, bar_index, high, extend=extend.both,  width= width_Year, color=clr_Year) //, style=line.style_dotted)
// 
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<  Годовая разметка  <<<<<<<<<<<
// 
// 
//       Функция для получения даты второй пятницы месяца
// 
second_friday(y, m) =>
    first_day_of_month = timestamp(y, m, 1)
    first_day_of_month_dow = dayofweek(first_day_of_month)
    second_friday_day = 1 + (5 - first_day_of_month_dow + 7) % 7 + 7
    timestamp(y, m, second_friday_day)
// 
// 
//       Определение временных интервалов кварталов
// 
//      1я  пара линий ( High, Low ) :  в пятницу 2й недели . 03 - 5 . 06   
sec_friday_1 = second_friday(year, 3)
Q_1_start = sec_friday_1
Q_1_end = timestamp(year, 6, 5, 23, 59)
// 
//      2я пара линий ( High, Low ) :  в пятницу 2й недели . 06 - 4 . 09
sec_friday_2 = second_friday(year, 6)
Q_2_start = sec_friday_2
Q_2_end = timestamp(year, 9, 4, 23, 59)
// 
//      3я пара линий ( High, Low ) :  в пятницу 2й недели . 09 - 4 . 12
sec_friday_3 = second_friday(year, 9)
Q_3_start = sec_friday_3
Q_3_end = timestamp(year, 12, 4, 23, 59)
// 
//      4я пара линий ( High, Low ) :  в пятницу 2й недели . 12  - 6 . 03
sec_friday_4 = second_friday(year, 12)
Q_4_start = sec_friday_4
Q_4_end = timestamp(year, 3, 6, 23, 59)
// 
// 
//       Функция для получения индекса бара по времени
// 
F_Get_BarIndexAtTime(_time) =>
    var int barIndex = na
    if (_time <= time and (_time > time[1] or bar_index == 0))
        barIndex := bar_index
    barIndex
// 
// 
//       Получение индексов баров для каждого квартала
// 
int inBar_q1_start = request.security(syminfo.tickerid, "D", F_Get_BarIndexAtTime(Q_1_start))
int inBar_q1_end   = request.security(syminfo.tickerid, "D", F_Get_BarIndexAtTime(Q_1_end))
// 
int inBar_q2_start = request.security(syminfo.tickerid, "D", F_Get_BarIndexAtTime(Q_2_start))
int inBar_q2_end   = request.security(syminfo.tickerid, "D", F_Get_BarIndexAtTime(Q_2_end))
// 
int inBar_q3_start = request.security(syminfo.tickerid, "D", F_Get_BarIndexAtTime(Q_3_start))
int inBar_q3_end   = request.security(syminfo.tickerid, "D", F_Get_BarIndexAtTime(Q_3_end))
// 
int inBar_q4_start = request.security(syminfo.tickerid, "D", F_Get_BarIndexAtTime(Q_4_start))
int inBar_q4_end   = request.security(syminfo.tickerid, "D", F_Get_BarIndexAtTime(Q_4_end))
// 
// 
//       Функция для определения High и Low за квартал
// 
F_Get_High_Low(  startMonth, startDay,   endMonth, endDay  ) =>
    var float highPrice = na
    var float lowPrice = na
    if (month == startMonth and dayofmonth == startDay)
        highPrice := high
        lowPrice := low
    if (month >= startMonth and month <= endMonth)
        highPrice := math.max(highPrice, high)
        lowPrice := math.min(lowPrice, low) 
    else
        if (month == endMonth and dayofmonth > endDay)
            na
        else
            highPrice := math.max(highPrice, high)
            lowPrice := math.min(lowPrice, low)
    [highPrice, lowPrice]
// 
// 
// 
//       Определение квартальных периодов -     [highPrice, lowPrice]
// 
[q1_High, q1_Low] = F_Get_High_Low( 3, dayofmonth(Q_1_start),   6, dayofmonth(Q_1_end) )
[q2_High, q2_Low] = F_Get_High_Low( 6, dayofmonth(Q_2_start),   9, dayofmonth(Q_2_end) )
[q3_High, q3_Low] = F_Get_High_Low( 9, dayofmonth(Q_3_start),   12, dayofmonth(Q_3_end) )
[q4_High, q4_Low] = F_Get_High_Low( 12, dayofmonth(Q_4_start),   3, dayofmonth(Q_4_end) )
// 
// 
// 
//       Отрисовка линий и меток
// 
if not ( barstate.islast )      // if timeframe.change('3M')      //   Определяем бары    
// if  not ( current_bar == last_bar_index )
    if current_bar == inBar_q1_end   //    if bar_index == inBar_q1_end
        line.new(inBar_q1_start, q1_High, inBar_q1_end, q1_High, width= width_High, color=clr_High) //, style=line.style_arrow_both)
        line.new(inBar_q1_start, q1_Low, inBar_q1_end, q1_Low, width= width_Low, color=clr_Low) //, style=line.style_arrow_both)
//       label.new(bar_index, high*1.4, text="Q1 start=" + str.tostring(inBar_q1_start) +"\n" +
//          " inBar_q1_ end =" + str.tostring(inBar_q1_end) +"\n" +
//          " High=" + str.tostring(q1_High) + " Low=" + str.tostring(q1_Low) +"\n" +
//          " current_bar = " + str.tostring(current_bar)  +"\n" +
//          " current_K = " + str.tostring(current_K)
//          )
// 
        line.new(bar_index, low, bar_index, high, extend=extend.both,  width= width_3M, color=clr_3M, style=line.style_dotted ) // line.style_dashed )
        current_K := current_bar +1      
// 
    if current_bar == inBar_q2_end   // if bar_index == inBar_q2_end
        line.new(inBar_q2_start, q2_High, inBar_q2_end, q2_High, width= width_High, color= clr_High) //, style=line.style_arrow_both)
        line.new(inBar_q2_start, q2_Low,  inBar_q2_end, q2_Low,  width= width_Low,  color= clr_Low) //, style=line.style_arrow_both)
//     label.new(inBar_q2_end, high * 1.95, text="Q2 start=" + str.tostring(inBar_q2_start) + " end=" + str.tostring(inBar_q2_end) + "\n High=" + str.tostring(q2_High) + " Low=" + str.tostring(q2_Low))
        line.new(bar_index, low, bar_index, high, extend=extend.both,  width= width_3M, color=clr_3M, style=line.style_dotted ) // line.style_dotted)
        current_K := current_bar +1
// 
    if current_bar == inBar_q3_end   // if bar_index == inBar_q3_end
        line.new(inBar_q3_start, q3_High, inBar_q3_end, q3_High, width= width_High, color= clr_High) //, style=line.style_arrow_both)
        line.new(inBar_q3_start, q3_Low,  inBar_q3_end, q3_Low,  width= width_Low,  color= clr_Low) //, style=line.style_arrow_both)
    // label.new(bar_index, high * 0.9, text="Q3 start=" + str.tostring(inBar_q3_start) + " end=" + str.tostring(inBar_q3_end) + " High=" + str.tostring(q3_High) + " Low=" + str.tostring(q3_Low))
        line.new(bar_index, low, bar_index, high, extend=extend.both,  width= width_3M, color=clr_3M, style=line.style_dotted) // line.style_dotted)
        current_K := current_bar +1
// 
    if current_bar == inBar_q4_end   // if bar_index == inBar_q4_end
        line.new(inBar_q4_start, q4_High, inBar_q4_end, q4_High, width= width_High, color= clr_High) //, style=line.style_arrow_both)
        line.new(inBar_q4_start, q4_Low,  inBar_q4_end, q4_Low,  width= width_Low,  color= clr_Low) //, style=line.style_arrow_both)
//     label.new(bar_index, high * 0.85, text="Q4 start=" + str.tostring(inBar_q4_start) + " end=" + str.tostring(inBar_q4_end) + " High=" + str.tostring(q4_High) + " Low=" + str.tostring(q4_Low))
        line.new(bar_index, low, bar_index, high, extend=extend.both,  width= width_3M, color=clr_3M, style=line.style_dotted) // line.style_dotted)
        current_K := current_bar +1
// 
else 
// 
//            (     from                 last_bar_index     )
//  
//      Определяю бары :       bar_before   [ ... ]    last_bar_index    [ ... ]    bar_after
// 
// 
//   Присутствие Будущего квартала и оптимально - 2й пятницы после последнего прошлого квартала
    is_FK := ( bars_before >= 13  )
// 
// 
    if is_FK
//
        bar_before = current_K          //  !  to last_bar_index = 28 ... last_bar_index   [ bar_index-_bars_in_K +1 ]     
// 
        bars_after =  90 - bars_before               //  !  from last_bar_index =  last_bar_index  ...  68
        bar_after  =  current_bar + bars_after     //  !  from last_bar_index =  last_bar_index  ...  68
// 
    // label.new(current_bar, high*1.2, textcolor=color.white , text= " bar_before= " + str.tostring(bar_before) +"\n" +
    //       " bar_after =" + str.tostring(bar_after) +"\n" +
    //       " period_Index =" + str.tostring(period_Index) +"\n" +
    //       " last_bar_index =" + str.tostring(last_bar_index) +"\n" +
    //       " bar_index =" + str.tostring(bar_index) +"\n" +
    //       " current_bar = " + str.tostring(current_bar)  +"\n"+
    //       " bars_before =" + str.tostring(bars_before) +"\n" +
    //       " bars_after =" + str.tostring(bars_after) +"\n"
    //       )

// paint ->  горизонтальные линии  High и Low  из 2й пятницы
        line.new(x1=bar_before + 6, y1=Price_H_period, x2=bar_after, y2=Price_H_period, color=clr_High, width= width_High )
        line.new(x1=bar_before + 6, y1=Price_L_period, x2=bar_after, y2=Price_L_period, color=clr_Low,  width= width_Low  )
// 
        line.new(x1=bar_after, y1=high, x2=bar_after, y2=high, extend=extend.both,  width= width_3M, color = clr_3M, style=line.style_dotted) // line.style_dashed)
// 
// 
// // // // // // // //        "Year Start Lines with Future Line"        // // // // // // // //
// 
//   Количество дней в году
    days_in_year = 365 + (year % 4 == 0 ? 1 : 0)        // Учитываю високосные годы
    current_date = timestamp(year, month, dayofmonth)   // Текущая дата
    start_of_year = timestamp(year, 1, 1)               // Первый день текущего года
    current_day_of_year = ( (current_date - start_of_year) / 86400000 )   // Текущий день года
    days_left_in_year = days_in_year - current_day_of_year               // Определение оставшихся дней до конца года
    bars_in_future = days_left_in_year                                  // Определение смещения в барах
// 
//      Рисование линии на оставшееся количество дней до конца года от последнего бара
    var line future_line = na
// 
//    bool is_LastK = (is_FK) and ( ( bar_after - last_bar_index ) <= 89 ) // прорисовка годовой линии в присутствии последнего квартала в году
// 
//    прорисовка годовой линии в приближающемся последнем квартале из 2й пятницы в текущем году
    bool is_LastK = ( bars_in_future <= (_bars_in_K - 12) )
// 
// if ( bar_index == last_bar_index )
    if is_LastK
        if na(future_line)        
            future_line := line.new(bar_index + bars_in_future, low, bar_index + bars_in_future, high, extend=extend.both, width= width_Year, color=clr_Year)
        else
            line.set_xy1(future_line, bar_index + bars_in_future, low)
            line.set_xy2(future_line, bar_index + bars_in_future, high)

//  END

2я версия кода :


//@version=5
indicator("Kvartal line", overlay=true)

// Установка цветов для линий High и Low
color clr_High = input.color(color.green, "Color High")
color clr_Low = input.color(color.red, "Color Low")

int current_Bar  = bar_index   //   Определение текущнго bar
int current_Time = time        //   Определение текущнго time
//
int _1D = 86400000         // 86400000 - количество миллисекунд в   1 торговом дне
//
var float current_K = na   //  Определение баров последнего прошлого квартала ( ... _end), чтобы дорисовать будущий


// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>    Годовая разметка     >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//          
is_year_start = year != year[1]
//  
if is_year_start
    line.new(bar_index, low, bar_index, high, extend=extend.both,  width= width_Year, color=color.gray) //, style=line.style_dotted)
//
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<    Годовая разметка    <<<<<<<
//
// 
//       Функция для получения даты второй пятницы месяца
// 
second_friday(y, m) =>
    first_day_of_month = timestamp(y, m, 1)
    first_day_of_month_dow = dayofweek(first_day_of_month)
    second_friday_day = 1 + (5 - first_day_of_month_dow + 7) % 7 + 7
    timestamp(y, m, second_friday_day)

// 
//       Определение временных интервалов кварталов
// 
// 
//      1я  пара линий ( High, Low ) :  в пятницу 2й недели . 03 - 5 . 06
sec_friday_1 = second_friday(year, 3)
Q_1_start = sec_friday_1
Q_1_end = timestamp(year, 6, 5, 23, 59)

//      2я пара линий ( High, Low ) :  в пятницу 2й недели . 06 - 4 . 09
sec_friday_2 = second_friday(year, 6)
Q_2_start = sec_friday_2
Q_2_end = timestamp(year, 9, 4, 23, 59)

//      3я пара линий ( High, Low ) :  в пятницу 2й недели . 09 - 4 . 12
sec_friday_3 = second_friday(year, 9)
Q_3_start = sec_friday_3
Q_3_end = timestamp(year, 12, 4, 23, 59)

//      4я пара линий ( High, Low ) :  в пятницу 2й недели . 12  - 6 . 03
sec_friday_4 = second_friday(year, 12)
Q_4_start = sec_friday_4
Q_4_end = timestamp(year + 1, 3, 6, 23, 59)

// 
//       Определение максимумов и минимумов за квартал
// 
F_Get_High_Low(start, end) =>
    var float highPrice = na
    var float lowPrice = na
    period = (end - start) / _1D  // 86400000 - количество миллисекунд в дне
    highPrice := ta.highest(high, period)
    lowPrice  := ta.lowest(low, period)
    [highPrice, lowPrice]

// 
//       Получение максимумов и минимумов для каждого квартала
// 
[q1_High, q1_Low] = F_Get_High_Low(Q_1_start, Q_1_end)
// [q1_High, q1_Low] = request.security(syminfo.tickerid, "D", [Q_1_start,Q_1_end], lookahead = barmerge.lookahead_off)

[q2_High, q2_Low] = F_Get_High_Low(Q_2_start, Q_2_end)
[q3_High, q3_Low] = F_Get_High_Low(Q_3_start, Q_3_end)
[q4_High, q4_Low] = F_Get_High_Low(Q_4_start, Q_4_end)

// 
//       Отрисовка линий и меток
//

// bool is_Q_1 = (time == Q_1_end)

bool is_Q_1 = (current_Time >= Q_1_start and current_Time <= Q_1_end  )
bool is_Q_2 = (current_Time >= Q_2_start and current_Time <= Q_2_end  )  //   -  if (time == Q_2_end)
bool is_Q_3 = (current_Time >= Q_3_start and current_Time <= Q_3_end  )  //   -  if (time == Q_3_end)
bool is_Q_4 = (current_Time >= Q_4_start and current_Time <= Q_4_end  )  //   -  if (time == Q_4_end)



// if not ( bar_time.islast )      // if timeframe.change('3M')      //   Определяем бары    

if not ( barstate.islast ) 
    
// if current_Time >= Q_1_end    //   -  if (time == Q_1_end)
// if (current_Time >= Q_1_start and current_Time <= Q_1_end  )  //   -  if (time == Q_1_end)

    if  is_Q_1

// if  not ( current_bar == last_bar_index )
    // if current_bar == inBar_q1_end   //    if bar_index == inBar_q1_end
        line.new(x1=Q_1_start, y1=q1_High, x2=Q_1_end, y2=q1_High, width=2, color=clr_High, style=line.style_arrow_both, xloc=xloc.bar_time)
        line.new(x1=Q_1_start, y1=q1_Low,  x2=Q_1_end, y2=q1_Low,  width=2, color=clr_Low,  style=line.style_arrow_both, xloc=xloc.bar_time)
        // квартальные разделители :
        line.new(bar_index, low, bar_index, high, extend=extend.both,  width= 2, color=color.gray, style= line.style_dashed ) // line.style_dotted )
    //  для прорисовки последнего квартала
        // current_K := current_Time + 1   // _1D   
        current_K := current_Bar + 1   // _1D   

// if (time >= Q_2_end)
// if (time == Q_2_end)
// if (current_Time >= Q_2_start and current_Time <= Q_2_end  )  //   -  if (time == Q_1_end)

// if  is_Q_2

    // line.new(x1=Q_2_start, y1=q2_High, x2=Q_2_end, y2=q2_High, width=2, color=clr_High, style=line.style_arrow_both, xloc=xloc.bar_time)
    // line.new(x1=Q_2_start, y1=q2_Low, x2=Q_2_end, y2=q2_Low, width=2, color=clr_Low, style=line.style_arrow_both, xloc=xloc.bar_time)
    // квартальные разделители :
    //    line.new(bar_index, low, bar_index, high, extend=extend.both,  width= 2, color=color.gray, style= line.style_dashed ) // line.style_dotted )
     
    // current_K := current_Bar +1      //  для прорисовки последнего квартала

// if (time >= Q_3_end)
// if (time == Q_3_end)    
// if (current_Time >= Q_3_start and current_Time <= Q_3_end  )  //   -  if (time == Q_1_end)

// if  is_Q_3

    // line.new(x1=Q_3_start, y1=q3_High, x2=Q_3_end, y2=q3_High, width=2, color=clr_High, style=line.style_arrow_both, xloc=xloc.bar_time)
    // line.new(x1=Q_3_start, y1=q3_Low, x2=Q_3_end, y2=q3_Low, width=2, color=clr_Low, style=line.style_arrow_both, xloc=xloc.bar_time)
    // квартальные разделители :
    // line.new(bar_index, low, bar_index, high, extend=extend.both,  width= 2, color=color.gray, style= line.style_dashed ) // line.style_dotted )
     
    // current_K := current_Bar +1      //  для прорисовки последнего квартала

// if (time >= Q_4_end)
// if (time == Q_4_end)    
// if (current_Time >= Q_4_start and current_Time <= Q_4_end  )  //   -  if (time == Q_1_end)

// if  is_Q_4

    // line.new(x1=Q_4_start, y1=q4_High, x2=Q_4_end, y2=q4_High, width=2, color=clr_High, style=line.style_arrow_both, xloc=xloc.bar_time)
    // line.new(x1=Q_4_start, y1=q4_Low, x2=Q_4_end, y2=q4_Low, width=2, color=clr_Low, style=line.style_arrow_both, xloc=xloc.bar_time)
    // квартальные разделители :
    // line.new(bar_index, low, bar_index, high, extend=extend.both,  width= 2, color=color.gray, style= line.style_dashed ) // line.style_dotted )
     
    // current_K:= current_Bar +1       //  для прорисовки последнего квартала

//  END


Ответы (0 шт):