def get_price(s3_client: S3Client, s3_bucket: str, ticker: str, trading_day: arrow.arrow.Arrow, stack_calls: int = 0) -> Optional[float]: """ Returns the adjusted close for a ticker on the date. If trading_day is not a valid trading day on the NYSE, the most recent day, up to `trading_day` is used. """ stack_calls += 1 max_stack_calls = 50 if stack_calls > max_stack_calls: raise RuntimeError( f"stack_calls exceeded max_stack_calls: {max_stack_calls} for {ticker} on {trading_day.format('YYYY-MM-DD')}" ) while not is_valid_trading_day(trading_day): trading_day = trading_day.shift(days=-1) df = get_eod_prices(s3_client, s3_bucket, trading_day) price = None try: price = df.loc[ticker]["adjusted_close"] except KeyError: # unable to get price for given ticker. Rewind day until we retrieve valid price price = get_price(s3_client, s3_bucket, ticker, trading_day.shift(days=-1), stack_calls) return price
def calculate_lookback_window(now: arrow.arrow.Arrow, lookback_months: int) -> LookbackPeriod: """ Calculate lookback period for momentum. start period defined as the first day of the month, 13 months ago, enabling us to get initial value to compare """ start_period = now.shift(months=-lookback_months).replace(day=1) # end period excludes the most recent full month, (exclusive) end_period = now.shift(months=-1).replace(day=1) return LookbackPeriod(start_period, end_period)