"""AlphaVantage FX Model.""" import argparse import logging import os from typing import Any, Dict, List import pandas as pd import requests from openbb_terminal import config_terminal as cfg from openbb_terminal.decorators import log_start_end from openbb_terminal.rich_config import console logger = logging.getLogger(__name__) @log_start_end(log=logger) def get_currency_list() -> List: """Load AV currency codes from a local file.""" path = os.path.join(os.path.dirname(__file__), "data/av_forex_currencies.csv") return list(pd.read_csv(path)["currency code"]) CURRENCY_LIST = get_currency_list() @log_start_end(log=logger) def check_valid_forex_currency(symbol: str) -> str: """Check if given symbol is supported on alphavantage. Parameters ---------- symbol : str Symbol to check Returns ------- str Currency symbol Raises ------ argparse.ArgumentTypeError Symbol not valid on alphavantage """ if symbol.upper() in CURRENCY_LIST: return symbol.upper() raise argparse.ArgumentTypeError( f"{symbol.upper()} not found in alphavantage supported currency codes. " ) @log_start_end(log=logger) def get_quote(to_symbol: str = "USD", from_symbol: str = "EUR") -> Dict[str, Any]: """Get current exchange rate quote from alpha vantage. Parameters ---------- to_symbol : str To forex symbol from_symbol : str From forex symbol Returns ------- Dict[str, Any] Dictionary of exchange rate """ url = ( "https://www.alphavantage.co/query?function=CURRENCY_EXCHANGE_RATE" + f"&from_currency={from_symbol}" + f"&to_currency={to_symbol}" + f"&apikey={cfg.API_KEY_ALPHAVANTAGE}" ) response = requests.get(url) response_json = response.json() result = {} # If the returned data was unsuccessful if "Error Message" in response_json: console.print(response_json["Error Message"]) logger.error(response_json["Error Message"]) else: # check if json is empty if not response_json: console.print("No data found.\n") else: result = response_json return result @log_start_end(log=logger) def get_historical( to_symbol: str = "USD", from_symbol: str = "EUR", resolution: str = "d", interval: int = 5, start_date: str = "", ) -> pd.DataFrame: """Get historical forex data. Parameters ---------- to_symbol : str To forex symbol from_symbol : str From forex symbol resolution : str, optional Resolution of data. Can be "i", "d", "w", "m" for intraday, daily, weekly or monthly interval : int, optional Interval for intraday data start_date : str, optional Start date for data. Returns ------- pd.DataFrame Historical data for forex pair """ d_res = {"i": "FX_INTRADAY", "d": "FX_DAILY", "w": "FX_WEEKLY", "m": "FX_MONTHLY"} url = f"https://www.alphavantage.co/query?function={d_res[resolution]}&from_symbol={from_symbol}" url += f"&to_symbol={to_symbol}&outputsize=full&apikey={cfg.API_KEY_ALPHAVANTAGE}" if resolution == "i": url += f"&interval={interval}min" r = requests.get(url) response_json = r.json() if r.status_code != 200: return pd.DataFrame() df = pd.DataFrame() # If the returned data was unsuccessful if "Error Message" in response_json: console.print(response_json["Error Message"]) elif "Note" in response_json: console.print(response_json["Note"]) else: # check if json is empty if not response_json: console.print("No data found.\n") else: key = list(response_json.keys())[1] df = pd.DataFrame.from_dict(response_json[key], orient="index") if start_date and resolution != "i": df = df[df.index > start_date] df = df.rename( columns={ "1. open": "Open", "2. high": "High", "3. low": "Low", "4. close": "Close", } ) df.index = pd.DatetimeIndex(df.index) df = df[::-1] return df.astype(float)