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
}
}
}
Related
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.
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", "")
I have written the following function:
iterations_per_minute = function() {
Sys.setenv(TZ='GMT+5') ## This line is optional; it just sets my timezone
final_instant = as.numeric(format(Sys.time(), "%H.%M")) + 0.01
counter = 0
while(as.numeric(format(Sys.time(), "%H.%M")) < final_instant) {
counter = counter + 1
}
return(counter)
}
You can infer from the code what the function does, but allow me to explain in lay words anyway: what number can you reach by counting as fast as possible during one minute starting from the number 1? Think of the computer doing exactly that same thing. The output of this function is the number that the computer reaches after counting for a whole minute.
Or at least that is how I would like this function to behave. It does work the way I have described if we pair exactly the call to the function with the beginning of a minute in the clock. However, it will count for less than a minute if we execute this function when the second hand of the clock is pointing at any other number besides twelve. How do I fix this?
Also, I figure I probably won't get the desired output if I execute the function between 23:59 and 0:00. How can this other issue be fixed?
Seems to me like you're trying to introduce more moving parts than you need.
Consider the following:
a <- Sys.time()
a
# [1] "2020-07-25 16:21:40 CDT"
a + 60
# [1] "2020-07-25 16:22:40 CDT"
So, we can just add 60 to Sys.time() without worrying about conversions or whatever else:
iterations_per_minute = function() {
counter = 0
end <- Sys.time() + 60
while( Sys.time() < end ) {
counter = counter + 1
}
return(counter)
}
Using this function, apparently my machine can count to 1474572 in one minute.
So I'm trying to do a recursive calculation with time-steps h, and the time is t.
I want the second if-function (in the while-loop) to check if the time t is an integer. It works for the first loop when t=9, but after that it ignores when t=8,7,6,... and so on. And right now I just don't understand why.
I would be very grateful for any help or ideas!
h=1/12;
b1=10000;
b2=25000*0.15*12; #45000
mu_10=0.004183;
mu_12=0.002136;
mu_20=0.0050196;
mu_21=0.005;
V1_start=h*(-b1);
V2_start=h*(b2);
t_vektor<-c(10);
V1_vektor<-c(V1_start);
V2_vektor<-c(V2_start);
t=as.integer(9);
while (t>0){
if(t==1){
V1_ny=V1_start+h*(-log(1.04)*V1_start+b1-mu_10*V1_start+mu_12*(V2_start-V1_start));
}else{
V1_ny=V1_start+h*(-log(1.04)*V1_start-mu_10*V1_start+mu_12*(V2_start-V1_start));
}
V2_ny=V2_start+h*(-log(1.04)*V2_start+b2-mu_20*V2_start+mu_21*(V1_start-V2_start));
if(round(t)==t){
V1_vektor<-c(V1_vektor,V1_ny);
V2_vektor<-c(V2_vektor,V2_ny);
t_vektor<-c(t_vektor,t);
V2_start=V2_ny;
V1_start=V1_ny;
t=t-h;
}else{
V2_start=V2_ny;
V1_start=V1_ny;
t=t-h;
print(t)
}
}
This has to do with the way numbers are stored, see also here.
An example for your case, see the output of the following code:
t = 9
h=1/12
for(i in 1:12)
{
t=t-h
}
print(t) # 8
print(t==8) # FALSE
all.equal(t,8) # TRUE
in your case, try:
isTRUE(all.equal(round(t),t))
Hope this helps!
Instead of if(round(t)==t) use:
tolerance = h/2;
if(min(abs(c(t%%1, t%%1-1))) < tolerance){
...
}
You make your test on t, but you change t before printing it by the line "t=t-h";
So you don't see the value witch was tested ..
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!