yfinance not returning todays intraday one minute bars - yfinance

This code returns 1 minute data for the last seven days, but it only returns a single quote for today. Is there a way to get the 1 minute bar data for today?
import yfinance as yf
from datetime import datetime, timedelta
x=datetime.now()
date_N_days_ago = datetime.now() - timedelta(days=7)
print(date_N_days_ago)
msft = yf.Ticker("MSFT")
data_df = yf.download("MSFT",start=date_N_days_ago.strftime("%Y"+"-"+"%m"+"-"+"%d"), interval="1m", end=x.strftime("%Y"+"-"+"%m"+"-"+"%d"))
data_df.to_csv('ds.csv')

By default yfinance takes period='max' as parameter.
To get only last day or intraday during opening times you have to specify this parameter on your own.
In your case:
data_df = yf.download("MSFT",start=date_N_days_ago.strftime("%Y"+"-"+"%m"+"-"+"%d"), interval="1m", end=x.strftime("%Y"+"-"+"%m"+"-"+"%d"))
Just open the function for more details.
This is possible values for period - always depending on your interval value
period : str
Valid periods: 1d,5d,1mo,3mo,6mo,1y,2y,5y,10y,ytd,max
Either Use period parameter or use start and end
For example period='6m', interval='1d' is the maximum yahoo delivers with 1d candles

Related

How to get the last 200 candles from bybit

import bybit
import pprint
api_key_i = "my key"
api_secret_i = "mysecret"
client = bybit.bybit(test=True, api_key="api_key_i", api_secret="api_secret_i")
x = client.LinearKline.LinearKline_get(symbol="DOTUSDT", interval="5", **{'from':1581231260}).result()
print(len(x[0]['result']))
pprint.pprint(x[0]['result'])
I know I have to change this value **{'from':1581231260} but no idea how to change this. I have never seen this kind of syntax before.
https://bybit-exchange.github.io/docs/linear/?python#t-orderbook
What you have to do is get the current UTC datetime, use a floor method that rounds that datetime to 5 min (e.g. 12:07:53 will become 12:05:00) and subtract (200 * 5 min) from it, that datetime (is the oldest candle) needs to be converted to an unix timestamp and set in the from parameter :). Let me know if you get stuck.

What is the value of the ISO 8601 duration `P1M` (in seconds)?

Suppose I have an ISO 8601 duration, expressed as "P1M". Phrased colloquially, this means "one month." Is there a standard rule for converting this into a number of seconds, assuming the start date is not known?
For 30-day months, it might be 2,592,000.
For 31-day months, it might be 2,678,400.
In February, it might be 2,419,200 or it might be 2,505,600.
My gut says there's no way to resolve "one month" to an exact number of seconds without knowing context, and where those seconds are laid out on the calendar. But are there standard rules/conventions to calculate these durations in an abstract way?
From ISO 8601 documentation that I found (page 6 - http://xml.coverpages.org/ISO-FDIS-8601.pdf), it seems you are correct in that the number of seconds in a month cannot definitively be determined. However it does note that "In certain applications a month is regarded as a unit of time of 30 days", so depending on your application this may be a valid approach.
The distinction between "Calendar Time" (Years, Months, etc) and "Absolute Time" (Hours, Minutes, Seconds, etc) is sometimes an important one. As an example, some people might complain about having 13 mortgage payments some years if they paid every 30 days as opposed to every month.
You are right, an ISO 8601 duration is dependent of the context.
A duration is a period/an interval of time between two dates.
Example :
2020-01-01/2020-02-01 = P1M = P31D
2020-02-01/2020-03-01 = P1M = P29D
2019-02-01/2019-03-01 = P1M = P28D
If you want a fixed duration indepedent of the context, use the day notation P30D, P60D, P90D... instead.
The same applies for years :
2019-01-01/2020-01-01 = P1Y = P12M = P365D
2020-01-01/2021-01-01 = P1Y = P12M = P366D
If you can't have context information about a duration, for example P1M retrieved from database or given by user input, use by default today's context.
//What is a duration of one month in seconds ?
P1M = ? (no context)
//Use default context
Today = 2020-03-31
2020-03-31/P1M = 2020-03-31/2020-04-30
=> P1M = P30D
//A month contains 2 592 000 seconds

How to choose a random time once per hour

Suppose I want to run a task once per hour, but at a variable time during the hour. It doesn't have to be truly random; I just don't want to do it at the top of the hour every hour, for example. And I want to do it once per hour only.
This eliminates several obvious approaches, such as sleeping a random amount of time between 30 and 90 minutes, then sleeping again. It would be possible (and pretty likely) for the task to run several times in a row with a sleep of little more than 30 minutes.
The approach I'm thinking about looks like this: every hour, hash the Unix timestamp of the hour, and mod the result by 3600. Add the result to the Unix timestamp of the hour, and that's the moment when the task should run. In pseudocode:
while now = clock.tick; do
// now = a unix timestamp
hour = now - now % 3600;
hash = md5sum(hour);
the_time = hour + hash % 3600;
if now == the_time; then
do_the_work();
end
end
I'm sure this will meet my requirements, but I thought it would be fun to throw this question out and see what ideas other people have!
For the next hour to do work in, just pick a random minute within that hour.
That is, pick a random time for the next interval to do work in; this might be the same interval (hour) as the current interval (hour) if work has carried over from the previous interval.
The "time to sleep" is simply the time until then. This could also be execute "immediately" on a carry-over situation if the random time was before now: this will ensure that a random time is picked each hour, unless work takes more than an hour.
Don't make it more complex than it has to be - there is no reason to hash or otherwise muck with random here. This is how "Enterprise" solutions like SharePoint Timers (with an Hourly Schedule) work.
Schedule your task (with cron or the like) to run at the top of every hour.
At the beginning of your task, sleep for a random amount of time, from 0 to (60 - (the estimated running time of your task + a fudge factor)) minutes.
If you don't want your task to run twice simultaneously, you can use a pid file. The task can check - after sleeping - for this file and wait for the currently running task to finish before starting again.
I've deployed my suggested solution and it is working very well. For example, once per minute I sample some information from a process I'm monitoring, but I do it at variable times during the minute. I created a method of a Timestamp type, called RandomlyWithin, as follows, in Go code:
func (t Timestamp) RandomlyWithin(dur Timestamp, entropy ...uint32) Timestamp {
intervalStart := t - t % dur
toHash := uint32(intervalStart)
if len(entropy) > 0 {
toHash += entropy[0]
}
md5hasher.Reset()
md5hasher.Write([]byte{
uint8(toHash >> 24 & 255),
uint8(toHash >> 16 & 255),
uint8(toHash >> 8 & 255),
uint8(toHash & 255)})
randomNum := binary.BigEndian.Uint32(md5hasher.Sum(nil)[0:4])
result := intervalStart + Timestamp(randomNum)%dur
return result
}

Check if two timestamps are the same day in Ruby

I'm a bit confused between Date, Datetime, and Time in Ruby. What's more, my application is sensitive to timezones, and I'm not sure how to convert between these three while being timezone-robust.
How can I check if two unix timestamps (seconds since epoch) represent the same day? (I don't actually mind if it uses local time or UTC; while I'd prefer local time, as long as it's consistent, I can design around that).
Using the standard library, convert a Time object to a Date.
require 'date'
Time.at(x).to_date === Time.at(y).to_date
Date has the === method that will be true if two date objects represent the same day.
ActiveSupport defines nice to_date method for Time class. That's how it looks like:
class Time
def to_date
::Date.new(year, month, day)
end
end
Using it you can compare timestamps like that:
Time.at(ts1).to_date === Time.at(ts2).to_date
And here is less controversial way without extending Time class:
t1 = Time.at(ts1) # local time corresponding to given unix timestamp ts1
t2 = Time.at(ts2)
Date.new(t1.year, t1.month, t1.day) === Date.new(t2.year, t2.month, t2.day)
Time.at(ts1).day == Time.at(ts2).day && (ts1 - ts2).abs <= 86400
Or
t1 = Time.at(ts1)
t2 = Time.at(ts2)
t1.yday == t2.yday && t1.year == t2.year
In the first case we make sure that timestamps are no more than day apart (because #day returns day of month and without this additional check Apr 1 would be equal to May 1)
An alternative is to take day of year and make sure that they are of the same year.
These methods work equally well in both 1.8 and 1.9.
We can use beginning_of_day of the time and compare them:
t1.beginning_of_day == t2.beginning_of_day
This way the timezones won't be affected.

number of days in a period that fall within another period

I have 2 independent but contiguous date ranges. The first range is the start and end date for a project. Lets say start = 3/21/10 and end = 5/16/10. The second range is a month boundary (say 3/1/10 to 3/31/10, 4/1/10 to 4/30/10, etc.) I need to figure out how many days in each month fall into the first range.
The answer to my example above is March = 10, April = 30, May = 16.
I am trying to figure out an excel formula or VBA function that will give me this value.
Any thoughts on an algorithm for this? I feel it should be rather easy but I can't seem to figure it out.
I have a formula which will return TRUE/FALSE if ANY part of the month range is within the project start/end but not the number of days. That function is below.
return month_start <= project_end And month_end >= project_start
Think it figured it out.
=MAX( MIN(project_end, month_end) - MAX(project_start,month_start) + 1 , 0 )

Resources