How to calculate the number of day-off trading like weekend, holidays? - datetime

Good Morning All!
The question in Pinescript,
Is there any trick to let my code determines whether the day before (yesterday) was day-off trading?
For example, I want my code to calculate the number of days-off.
I've coded this one, but it doesn't work perfectly at running data especially on the first day after off-market, but it works fine at historical data.
T=security(syminfo.tickerid, "1440", time)
fun()=>
NumDays= change(T)/86400000
Please Help!

This should work.
//#version=4
study("StackOverflow", overlay=true, max_labels_count=500)
daysBetween = change(dayofmonth(time))
if daysBetween > 1
label.new(bar_index, high, tostring(daysBetween) + " days", yloc=yloc.abovebar)
Edit: New code example.
This should work better.
I've actually asked a question about this myself recently.
See Detecting session breaks
//#version=4
study("NewSession", overlay=true)
var int days_off = na
var float change_in_ms = na
var int ms_per_day = 24 * 60 * 60 * 1000
change_in_ms := change(time("D"))
if change_in_ms
days_off := int(change_in_ms / ms_per_day)-1
bgcolor(change_in_ms ? color.yellow : na, 60)
plotchar(days_off, "days_off", "")

Related

How to plot line only on first value of crossover condition met in Pine Script

I need help in Pine script coding, i want to plot the first crossover value alone not entire series of values for whole day. so if crossover condition is true for 1st or 2nd or 3rd or n times, i need to plot the line from the first condition met to end of day and ignore 2nd or 3rd or 4th or nth series values to plot. how to do it? and i don't want to use line.new() since i want to backtest in tradingview.com, for historical bars i want to use Plot(). so kindly help me with the code.
Strategy im trying: Added 30pts above from 5mins High-Low, if 5 mins candle crossover the 30pts at first time from High need to plot line, ignore if condition met again in a day.
`
//#version=5
indicator(title="Crossover", shorttitle="Crossover", overlay=true)
//*5Mins High Low calculation*//
inputMax = input(5, title= "ORB total time (minutes)")
sess = input("0915-0920", title="Session Time")
t = time(timeframe.period, sess + ":1234567")
hide = timeframe.isintraday and timeframe.multiplier <= inputMax
is_newbar(res) => ta.change(time(res)) != 0
in_session = not na(t)
is_first = in_session and not in_session[1]
orb_high = float(na)
orb_low = float(na)
if is_first
orb_high := high
orb_low := low
else
orb_high := orb_high[1]
orb_low := orb_low[1]
if high > orb_high and in_session
orb_high := high
if low < orb_low and in_session
orb_low := low
plot(hide ? orb_high : na , style=plot.style_line, color=orb_high[1] != orb_high ? na : color.green , title="ORB High", linewidth=3)
plot(hide ? orb_low : na , style=plot.style_line, color=orb_low[1] != orb_low ? na : color.red, title="ORB Low", linewidth=3)
//*Crossover condition*//
var Up = 0.0
Up := orb_high + 30
var b_i = 0.0
cross_over_happened = if(ta.crossover(close, Up)) and barstate.isconfirmed
1
else
0
b_i := ta.valuewhen(cross_over_happened, close, 0)
plot(b_i, color = color.black, linewidth = 2)
`
the above code will plot whenever condition met, but i need to plot only the first value of crossover condition, not for entire series. Kindly help with the code.
I would go about this in a slightly different way (which is very close to what you have done). I would add a bool that will check if a cross already happened today, and will change the value of b_i only when the cross and the new bool are true.
First set the variables that we're going to need:
var float orb_high = na
var float orb_low = na
var bool already_had_crossover_today = false
var float b_i = na
Second, reset those variables on each new day:
if ta.change(time("D"))
orb_high := high
orb_low := low
already_had_crossover_today := false
b_i := na
Third, we'll check for the crossover, regardless if it's the first one on the day or not:
Up = orb_high + 30
cross_over_happened = ta.crossover(close, Up)
And lastly, we'll check if we had a crossover and during the day a crossover hasn't happened yet:
if cross_over_happened and not already_had_crossover_today
b_i := close
already_had_crossover_today := true
Than we can just use plot, and for better visualization use the style parameter:
plot(b_i, style = plot.style_linebr)

plotter only plot the time, not the date

im trying to follow this guide on plotting a time series chart but ive run into a small issue. is there any way to change the bottom label to only show the current time (H:M:S) instead of the current date? ive been trying for a while now to find a way to do this but it still havent been able to. im following the code in the guide so this is the code im working with:
use plotters::prelude::*;
use chrono::{Utc, TimeZone};
fn main() {
let root_area = BitMapBackend::new("images/2.11.png", (600, 400))
.into_drawing_area();
root_area.fill(&WHITE).unwrap();
let start_date = Utc.ymd(2019, 10, 1);
let end_date = Utc.ymd(2019, 10, 18);
let mut ctx = ChartBuilder::on(&root_area)
.set_label_area_size(LabelAreaPosition::Left, 40)
.set_label_area_size(LabelAreaPosition::Bottom, 40)
.caption("MSFT daily close price", ("sans-serif", 40))
.build_cartesian_2d(start_date..end_date, 130.0..145.0)
.unwrap();
ctx.configure_mesh().draw().unwrap();
ctx.draw_series(
LineSeries::new(
(0..).zip(DATA.iter()).map(|(idx, price)| {
let day = (idx / 5) * 7 + idx % 5 + 1;
let date = Utc.ymd(2019,10, day);
(date, *price)
}),
&BLUE,
)
).unwrap();
}
const DATA: [f64; 14] = [ 137.24, 136.37, 138.43, 137.41, 139.69, 140.41, 141.58, 139.55, 139.68, 139.10, 138.24, 135.67, 137.12, 138.12];
ive tried using chrono's NaiveTime but it doesnt seem to be supported, DateTime causes the entire date and time to be printed instead of just the time, and ive also tried creating my own element series but i cant figure out how to get that working. anyone have any ideas?
You can add this line, or something like it to the ChartBuilder:
.x_label_formatter(&|x| format!("{:02}:{:02}", x.hour(), x.minute()))
where x is a DateTime struct. You can use other DateTime functions to get different parts of the time, as required.

How to mark High of today if it has a particular decimal say ".55" at end for a 5m interval chart in Tradingview using Pine script

What I want to do is to mark the candle in 5m chart for the current day if it meets following two condition:
1) The candle should be highest of the day and it's high=1234.75 (at end ".75" decimal)
2) The candle should be lowest of the day and it's low=900.25 (at end "0.25" decimal)
I could mark a candle if it's high value consist of ".75" decimal at end and low value consist of ".25" decimal behind any value using below code but it shows all candles whose high ends with "0.75". I want to mark only Day high candle if it meets 0.75 criteria. Please refer and help me out.. Thank you in advance
// This source code is subject to the terms of the Mozilla Public License 2.0 at
https://mozilla.org/MPL/2.0/
//#version=4
study("(75-25)", overlay=true)
ch = high[0]
cl = low[0]
truncate(number, decimals) =>
factor = pow(10, decimals)
int(number * factor) / factor
chA = truncate(ch,0)
chB = ch - chA
data = chB == 0.75
clA = truncate(cl,0)
clB = cl - clA
data1 = clB == 0.25
plotshape(data, style=shape.triangledown, size=size.small, location=location.abovebar,
color=color.red)
plotshape(data1, style=shape.triangleup, size=size.small, location=location.belowbar,
color=color.green)
You can use the security() function to get the daily high and lows. However, you would miss the intraday actions for backtesting. What you need I believe is, if the price is the daily high/low from the session start until that specific bar.
You can use the following method the keep track of the daily high/low and update the values if a new high/low forms.
var dailyHigh = high
var dailyLow = low
t = time("1440", session.regular) // Get the session open
isSessionFirstBar = na(t[1]) and not na(t) or t[1] < t // True: If first bar in the session
dailyHigh := iff(isSessionFirstBar, high, iff(high > dailyHigh, high, dailyHigh))
dailyLow := iff(isSessionFirstBar, low, iff(low < dailyLow, low, dailyLow))
Then you should combine this with your data and data1 variables.
data = (chB == 0.75) and (close == dailyHigh)
data1 = (clB == 0.25) and (close == dailyLow)

Issues with RQuantLib advance date function

I'm relatively new to R and have found to SO invaluable to my coding journey, so first off: thank you to all contributors!
I'm writing some code looking at options trading, but I'm having issues with some of the RQuantLib functions. I am trying to 'add' days to a date using the "UnitedStates/NYSE" calendar. If you run the code below you can see the value is not as expected from the businessDaysBetween function (note the dates and the number of days returned or as an argument):
library(RQuantLib)
# This shows there is only one business day between the dates using the "UnitedStates/NYSE" calendar
businessDaysBetween(calendar = "UnitedStates/NYSE", from = as.Date("2010-06-20"), to = as.Date("2010-06-22"))
# And this next line of code should advance the date to "2010-06-22" but doesn't...
advance(calendar = "UnitedStates/NYSE", dates = as.Date("2010-06-20"), n = 1, timeUnit = 0)
Any help would be greatly appreciated as it's doing my nut in!
Best,
L
OK, so not a great start for me. I realised what the issue is: advance moves to the first business day after the date you supply if it is not a business day.
I wrote the following function to do that if it's useful. If anyone else knows a better way around this, please let us know!
GenerateClosestBusinessDay <- function(date) {
d <- 0
repeat {
if (isBusinessDay(calendar = cal, dates = as.Date(date + d))) {
return(as.Date(date + d))
break
} else {
d <- d + 1
}
}
}

R and apply info

I could find any answers to that. So I've got the following code and trying to put it into apply, so it does the work quicker, my data set is 130k rows long. I need an apply that will calculate the missing times of the horses from Behind(in Length) and the winning Horse time. The problem is that the column Behind gives a the distance behind the horse before, not the first 1. So I'm in need to create a variable that will carry on as the function goes and if new race is identified, finds that the position == 1, it resets the variables.
missingTimes <- function(x) {
L <- 2.4384
for(i in 1:nrow(x) - 10) {
distanceL <- (x$distance[i] * 1000) / L
LperS <- x$Winner.Race.time[i] / distanceL
if(x$position[i] == 1 && !is.na(x$position[i])) {
distanceL <- NULL
LperS <- NULL
}
if(grepl("L",x$Behind[i])) {
x$results[i] <- (distanceL + as.numeric(sub("L", "", x$Behind[i]))) * LperS
}
}
}
I need at least 10 reputation to post images, thats why I give you links instead!
http://i.stack.imgur.com/xN23M.png
http://i.stack.imgur.com/Cspfr.png
The results should just give me a column with the proper times for the finish times of the other horses, in a form like the column Winner Race Time
For further understanding Imma count a few results myself for you:
Starting with first row, it sees position = 1, so it cleans the variables.
Then it takes the distance * 1000, and divides it by the constant L,
2.375 * 1000 / 2.4384 = 973.99
Then It need to get the time in seconds it takes to complete 1 length(L),
290.9 / 973.99 = 0.298
Now to get the finish time for the second horse It adds the length BEHIND to the distance of the racing track and multiplies it by the length per second,
973.99 + 2.25 = 976.24 * 0.298 = 290.91952
Then for the next horses time it'd be:
976.24 + 13 = 989.24 * 0.298 = 294.79352
and so on, remember when it hits position = 1, distance needs to reset
What I've done alternatively is put the distanceL in a separate column, same with LperS, of course after calculation.
If you could walk me through steps required to get that done It'd be great. I'm a complete rookie to the R stuff, so please be descriptive. I hope you catch my understanding!
Thank you!

Resources