@@ -249,6 +249,22 @@ def _date_to_iloc_linear(dtseries,date,trace=False):
249249 yitrcpt = yitrcpt1
250250 return (slope * _date_to_mdate (date )) + yitrcpt
251251
252+ def _date_to_iloc_5_7ths (dtseries ,date ,direction ,trace = False ):
253+ first = _date_to_mdate (dtseries .index [0 ])
254+ last = _date_to_mdate (dtseries .index [- 1 ])
255+ avg_days_between_points = (last - first )/ float (len (dtseries ))
256+ if avg_days_between_points < 0.33 : # intraday (not daily)
257+ return None
258+ if direction == 'forward' :
259+ delta = _date_to_mdate (date ) - _date_to_mdate (dtseries .index [- 1 ])
260+ loc_5_7ths = len (dtseries ) - 1 + (5 / 7. )* delta
261+ elif direction == 'backward' :
262+ delta = _date_to_mdate (dtseries .index [0 ]) - _date_to_mdate (date )
263+ loc_5_7ths = - (5. / 7. )* delta
264+ else :
265+ raise ValueError ('_date_to_iloc_5_7ths got BAD direction value=' + str (direction ))
266+ return loc_5_7ths
267+
252268def _date_to_iloc_extrapolate (dtseries ,date ):
253269 '''Convert a `date` to a location, given a date series w/a datetime index.
254270 If `date` does not exactly match a date in the series then interpolate between two dates.
@@ -269,33 +285,23 @@ def _date_to_iloc_extrapolate(dtseries,date):
269285
270286 d1s = dtseries .loc [date :]
271287 if len (d1s ) < 1 :
272- # xtrapolate forward:
288+ # extrapolate forward:
273289 loc_linear = _date_to_iloc_linear (dtseries ,date )
274- first = _date_to_mdate (dtseries .index [0 ])
275- last = _date_to_mdate (dtseries .index [- 1 ])
276- avg_days_between_points = (last - first )/ float (len (dtseries ))
277- if avg_days_between_points > 0.33 : # daily (not intraday)
278- delta = _date_to_mdate (date ) - _date_to_mdate (dtseries .index [- 1 ])
279- loc_5_7ths = len (dtseries ) - 1 + (5 / 7. )* delta
280- loc = (loc_linear + loc_5_7ths )/ 2.0
290+ loc_5_7ths = _date_to_iloc_5_7ths (dtseries ,date ,'forward' )
291+ if loc_5_7ths is not None :
292+ return (loc_linear + loc_5_7ths )/ 2.0
281293 else :
282- loc = loc_linear
283- return loc
294+ return loc_linear
284295 d1 = d1s .index [0 ]
285296 d2s = dtseries .loc [:date ]
286297 if len (d2s ) < 1 :
287298 # extrapolate backward:
288299 loc_linear = _date_to_iloc_linear (dtseries ,date )
289- first = _date_to_mdate (dtseries .index [0 ])
290- last = _date_to_mdate (dtseries .index [- 1 ])
291- avg_days_between_points = (last - first )/ float (len (dtseries ))
292- if avg_days_between_points > 0.33 : # daily (not intraday)
293- delta = _date_to_mdate (dtseries .index [0 ]) - _date_to_mdate (date )
294- loc_5_7ths = - (5. / 7. )* delta
295- loc = (loc_linear + loc_5_7ths )/ 2.0
300+ loc_5_7ths = _date_to_iloc_5_7ths (dtseries ,date ,'backward' )
301+ if loc_5_7ths is not None :
302+ return (loc_linear + loc_5_7ths )/ 2.0
296303 else :
297- loc = loc_linear
298- return loc
304+ return loc_linear
299305 # Below here we *interpolate* (not extrapolate)
300306 d2 = dtseries .loc [:date ].index [- 1 ]
301307 # If there are duplicate dates in the series, for example in a renko plot
0 commit comments