python - How to build custom pandas.tseries.offsets class? -
i want find way build custom pandas.tseries.offsets
class @ 1 second frequency trading hours. main requirement here time offset object smart enough know next second of '2015-06-18 16:00:00' '2015-06-19 09:30:00 or 09:30:01', , time delta computed these 2 time stamps 1s (custom offset 1s, similar bday(1)
business day frequency) instead of duration of closing hours.
the reason when plotting pd.series intraday data across few trading days, see simulated example below, there lots of 'step line' (linear interpolation) between close , next day open prices represent time duration of closing hours. there way rid of this? i've @ source codes of pandas.tseries.offsets
, find pd.tseries.offsets.businesshour
, pd.tseries.offsets.businessmixin
may don't know how use those.
import pandas pd import numpy np pandas.tseries.holiday import usfederalholidaycalendar pandas.tseries.offsets import custombusinessday # set 'constant' object shared codes in script bday_us = custombusinessday(calender=usfederalholidaycalendar()) sample_freq = '5min' dates = pd.date_range(start='2015-01-01', end='2015-01-31', freq=bday_us).date # exculde 09:30:00 included in first time bucket times = pd.date_range(start='09:30:00', end='16:00:00', freq=sample_freq).time[1:] time_stamps = [dt.datetime.combine(date, time) date in dates time in times] s = pd.series(np.random.randn(len(time_stamps)).cumsum() + 100, index=time_stamps) s.plot()
another way can think of partially fix problem first reset_index()
default consecutive integer index each row, , calculating difference between consecutive integer index time(in seconds) elapsed. plotting integer index x-axis , relabel them appropriate time labels. show me how matplotlib
well?
thanks jeff's comments. check on-line docs businesshour()
, find may useful in case. follow-up question(s): businesshour
in hour frequency, there way make @ 1s frequency? also, how combine custombusinessday
object?
to use businesshour()
from pandas.tseries.offsets import * bhour = businesshour(start='09:30', end='16:00') time = pd.timestamp('2015-06-18 15:00:00') print(time) 2015-06-18 15:00:00 # hourly increment works nicely print(time + bhour * 1) 2015-06-19 09:30:00 # not @ minute or second frequency print(time + minute(61)) 2015-06-18 16:01:00 print(time + second(60*60 + 1)) 2015-06-18 16:00:01
many many thanks, , highly appreciated.
as mention in comment, potentially have 2 different problems
- you need able plot business times timeseries without long linear interpolations.
- you need object can datetime arithmetic (in seconds) ignoring non-business times
i've given solution account 1 seems immediate issue. if need 2, or both - let know in comments:
1. plot points business days adjacent
most graphs in matplotlib
can have index formatters applied axes via ticker
api. i'll adapt this example suit case
import pandas pd import numpy np pandas.tseries.holiday import usfederalholidaycalendar pandas.tseries.offsets import custombusinessday import datetime dt import matplotlib.pyplot plt import matplotlib.ticker ticker # set 'constant' object shared codes in script bday_us = custombusinessday(calender=usfederalholidaycalendar()) sample_freq = '5min' dates = pd.date_range(start='2015-01-01', end='2015-01-31', freq=bday_us).date # exculde 09:30:00 included in first time bucket times = pd.date_range(start='09:30:00', end='16:00:00', freq=sample_freq).time[1:] time_stamps = [dt.datetime.combine(date, time) date in dates time in times] s = pd.series(np.random.randn(len(time_stamps)).cumsum() + 100, index=time_stamps) data_length = len(s) s.index.name = 'date_time_index' s.name='stock_price' s_new = s.reset_index() ax = s_new.plot(y='stock_price') #plot data against new linearised index... def format_date(x,pos=none): thisind = np.clip(int(x+0.5), 0, data_length-1) return s_new.date_time_index[thisind].strftime('%y-%m-%d %h:%m:%s') ax.xaxis.set_major_formatter(ticker.funcformatter(format_date)) fig = plt.gcf() fig.autofmt_xdate() plt.show()
this gives output follows, first @ zoomed out natural scale, second zoomed in can see transition between friday 16:00 , monday 09:00
Comments
Post a Comment