@@ -249,6 +249,22 @@ def _date_to_iloc_linear(dtseries,date,trace=False):
249
249
yitrcpt = yitrcpt1
250
250
return (slope * _date_to_mdate (date )) + yitrcpt
251
251
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
+
252
268
def _date_to_iloc_extrapolate (dtseries ,date ):
253
269
'''Convert a `date` to a location, given a date series w/a datetime index.
254
270
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):
269
285
270
286
d1s = dtseries .loc [date :]
271
287
if len (d1s ) < 1 :
272
- # xtrapolate forward:
288
+ # extrapolate forward:
273
289
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
281
293
else :
282
- loc = loc_linear
283
- return loc
294
+ return loc_linear
284
295
d1 = d1s .index [0 ]
285
296
d2s = dtseries .loc [:date ]
286
297
if len (d2s ) < 1 :
287
298
# extrapolate backward:
288
299
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
296
303
else :
297
- loc = loc_linear
298
- return loc
304
+ return loc_linear
299
305
# Below here we *interpolate* (not extrapolate)
300
306
d2 = dtseries .loc [:date ].index [- 1 ]
301
307
# If there are duplicate dates in the series, for example in a renko plot
0 commit comments