Solution implemented using the python3.8 programming language in a docker container.
I retrieve data from the finnhub website.
I store historical data in a SQLite database, I have chosen this solution because SQLite is a lightweight database that doesn’t require a separate server process but store the entire data as a file.
I installed the following libraries:
- plotext as suggested, to plot data directly on the terminal,
- requests to send HTTP request, in order to ease the interaction with the API of the finnhub website,
- pandas to handle the interaction with the database, to ease the insertion of data in it and the query requests.
In order to execute the application inside the docker container:
I created a simple script to build and run the docker image. This way you can easily access the container and run the code inside it, without polluting your local env.
sh docker/run.sh
You can run the application with the following command:
python -m src
Once started the application will first create the database and then launch an interactive menu that will allow you to choose one functionality at a time among the 5 supported, until you decide to quit the application. Once chosen a functionality the application will ask you to insert your inputs.
The supported functionalities are:
- '1': to get historical stock quotes for a given stock and a given foreign currency
- '2': to get the latest quote for a given stock
- '3': to get a graph of the whole historical quotes for a given exchange rate
- '4': to get a graph of the whole historical data for a stock
- '5': to get a graph of the historical quotes for a given stock and a given time interval
- 'q': to quit
I retrieve the list of supported stock symbols with the Stock Symbol api, I use one of these stock symbols at a time to call the Company Profile 2 api until I get 100 responses (it can happen that the API return an empty response, in this case I skip and I go to the next stock symbol). I store these 100 response in the table.
I retrieve the list of supported stock symbols with the Stock Symbol api, I use one of these stock symbols at a time to call the Stock Candle api until I get 100 responses (it can happen that the API return an empty response, in this case I skip and I go to the next stock symbol). I call the api giving the time interval (from,to)=(today, today-365) with weekly resolution. I have chosen this time interval since the free api only allow to get data of the last year. I store the close prices of these 100 responses in the table.
I retrieve the list of supported agencies that provide forex exchanges with the Forex Exchanges api. For every agency I call the Forex Symbol api that return me a list of supported forex exchanges. I store as a row in the database the elements of this list that satisfies the requirements "displaySymbol"=(AUD/USD, EUR/USD, GBP/USD)
I decided to store data provided from the agency "Oanda", so I call the Forex Candle api with time interval (from,to)=(today, today-365), with weekly resolution and with "symbol" once at a time equal to all the "symbol" that I stored in the table "exchangeRateAnagraphicData" for the "oanda" agency. I store the close prices of these responses in the table.
I retrieve the historical data of the required stock from the table "stockHistoricalData". I retrieve the currency convertion value with the api Forex Rate. I print the result.
I retrieve the current quote for the required stock with the Quote api. I retrieve the currency convertion value with the api Forex Rate. I print the result.
I retrieve the historical data of the required forex exchange from the "exchangeRatesHistoricalData" table. If the currency to which the conversion is required is not the default USD I compute the conversion, always using data from the "exchangeRatesHistoricalData" table. I print the graph.
I retrieve the historical data of the required stock from the "stockHistoricalData" table and I print the graph.
I retrieve the requested data with the api Forex Candle with daily resolution and I print the graph.
I introduced the class inputValidator to isolate all the methods needed to perform the validation of the data given as input.
I introduced the classes interactionAPI and interactionDB to hava a single element interfacing with the API/DB, handling the connections and handling the related errors.
I stored the constant value that the app needs to know all along the execution in the file constants.py. I stored some utility functions in the file utility.py
python -m pytest