Pine Script v4 - 每月最后 n 天和前 n 天的背景着色

Pine Script v4 - Background Coloring last n days and first n days of the month

这是我第一次 post 在这里,对于我在 post 中可能犯的任何错误,我深表歉意,而且我对 PineScript 代码还不是很实用,我在“试错”阶段。

根据标题,我想知道是否有任何机会能够为图表的背景着色,指定从月末开始多少天和从月初开始多少天。

我做了一些研究,最终得到了这个

我设法修改了 PineCoders-LucF 提供的代码的版本 2 post,唯一的问题是到了周末代码就不再工作了。

更具体地说:

//@version=4
study("BgColor", overlay=true)

fromDay         = input(-4)
toDay           = input(+4)
weekdaysOnly    = input(true)
useVline        = input(false)

dayIsOk = not weekdaysOnly or (dayofweek != dayofweek.saturday and dayofweek != dayofweek.sunday)

t1 = timestamp("GMT-5", year, month, fromDay, 00, 00)
t2 = timestamp("GMT-5", year, month, toDay,   00, 00)

timeIsOk = (time >= t1) and (time <= t2)
bgcolor( not useVline and timeIsOk and dayIsOk ? color.orange : na, transp = 80)

if useVline and timeIsOk and dayIsOk
    line.new(bar_index, low * .9999, bar_index, high * 1.0001, xloc.bar_index, extend.both, #FF8000ff, line.style_solid, 1)

它以某种方式完成了工作,但如您所见,当周末介于从月底或月初指定的 n 天之间时,它会出现一些问题。

我的问题是,是否可以告诉代码跳过周末,如果是周末,则在可用的第一个工作日绘制背景颜色。

另外一个问题是:以后有没有代码可以绘制下面的代码?例如,指定输入多少个月后我希望看到绘制的背景颜色。

感谢您的关注。

筒仓

下面的代码将达到您的预期。
但有一个警告:它不考虑非交易日,因为我不知道每年有一种一致的方法来识别假期。
因此,例如,您会在 7 月 4 日左右或感恩节前后看到不一致。
为清楚起见,我将负数天设为红色,正数天数设为绿色。

//@version=4
study("BgColor", overlay=true)

fromDay         = input(-3, "fromDay", maxval=0)
toDay           = input( 3, "toDay",   minval=0)

var int[] TradingDays = array.new_int(na)

f_isLeapYear(_year) =>
    // Any year that is evenly divisible by 4 is a leap year
    // A year that is evenly divisible by 100 (for example, 1900) is a leap year only if it is also evenly divisible by 400.
    (_year % 100 == 0) and (_year % 400 != 0) ? true : (_year % 4 == 0)

f_daysInMonth(_year, _month) =>
    int dpm = na
    if _month == 2
        dpm := 28 + (f_isLeapYear(_year) ? 1 : 0)
    else 
        evenMonth = _month % 2 == 0
        beforeAug = _month < 8
        dpm := 30 + (((not evenMonth and beforeAug) or (evenMonth and not beforeAug)) ? 1 : 0)

f_initTradingDays(_arr, _month) =>
    array.clear(_arr)
    for dom = 1 to f_daysInMonth(year, _month)
        dow = dayofweek(timestamp(year, _month, dom, 0, 0, 0))
        if (dow != dayofweek.saturday) and (dow != dayofweek.sunday)
            array.push(_arr, dom)

f_getStartStopDay(_arr, _negDelta, _posDelta) =>
    dStart  = array.min(array.slice(TradingDays, array.size(TradingDays) - abs(_negDelta)))
    dStop   = array.max(array.slice(TradingDays, 0, abs(_posDelta)))
    [dStart, dStop]

if change(time("M")) or barstate.isfirst
    f_initTradingDays(TradingDays, month)

[startDay, stopDay] = f_getStartStopDay(TradingDays, fromDay, toDay)

showStartDay    = dayofmonth >= startDay
showStopDay     = dayofmonth <= stopDay

bgcolor(showStartDay ? color.red   : na)
bgcolor(showStopDay  ? color.green : na)

//Future
stopDaysShort   = max(0, stopDay - dayofmonth)

arrStop = array.new_int(na)
for i=1 to stopDaysShort
    array.push(arrStop, i)
    
bgcolor(barstate.islast and array.includes(arrStop, 1) ? color.green : na, offset=1)
bgcolor(barstate.islast and array.includes(arrStop, 2) ? color.green : na, offset=2)
bgcolor(barstate.islast and array.includes(arrStop, 3) ? color.green : na, offset=3)
bgcolor(barstate.islast and array.includes(arrStop, 4) ? color.green : na, offset=4)