Your task is to create a package that is able to get the median prices for each the symbols given while removing any outliers.
The package must be able to do the following features:
- The main function must accept a list of symbols and return a list of the corresponding prices in USD or an error.
- Must be able to calculate the median price of each symbol.
- The code must be able to handle errors for symbols that aren't supported by the exchanges.
- The code must filter out symbols does not have at least three sources out of the given five.
- The code must filter out the prices that are outliers. The method for filtering the outliers is up to your discretion.
- The code must not use the outlier prices during calculations.
The only allowed imports are those that are built directly into the Python Standard Library, requests, aiohttp, httpx and urllib3.
You should design the code similar to how you would design a package. A boilerplate structure will be given in this repository and an example folder structure can be seen below:
...
├── band_assignment
│ ├── handler # Contain the API handlers
│ │ ├── __init__.py
│ │ ├── binance.py # API handler for Binance
│ │ ├── coingecko.py # API handler for CoinGecko
│ │ ├── coinmarketcap.py # API handler for CoinMarketCap
│ │ ├── kraken.py # API handler for Kraken
│ │ ├── okx.py # API handler for OKX
│ │ └── wrapper.py # wrapper function to call all API handlers
│ │
│ ├── calculator # Contains any modules that requires calculations
│ │ ├── __init__.py
│ │ ├── median.py
│ │ ├── outlier.py
│ │ └── ...
│ │
│ ├── structs # Contains custom structs/errors if any
│ │ ├── __init__.py
│ │ ├── errors # Contains custom errors if any
│ │ └── ...
│ │
│ └── main.py # Contains the main function to run
│
├── tests # Contains test scripts
│ ├── conftest.py # Conftest file [Optional]
│ ├── demo.py # Demo script for using the package
│ ├── test_cases.json # Contains the test cases
│ └── tests.py # Unit-tests [Optional]
│
├── README.md # Contains the task instructions
└── report.md # Contains the final report
The API that are to be used and its corresponding documentations are given below:
Please be aware you will need to create an account for CoinMarketCap in order to get an API key
def get_exchange_prices(symbols: List[str]) -> List[Optional[float]]:
# Insert logic here
return prices
if the following code is run:
if __name__ == "__main__":
exchange_prices = get_exchange_prices(["BTC", "ETH", "NOTAREALTOKEN"])
exchange_prices
should be returned in a format equivalent to this:
exchange_prices = [23541.0, 1532.32, None]
def filter_outliers(prices: List[float]) -> List[float]:
# Insert logic here
return filtered_prices
def get_median_price(filtered_prices: List[float]) -> float:
# Insert logic here
return median_price
If the following code is run:
if __name__ == "__main__":
prices_list = [
[10.0, 10.1, 9.8, 1000],
[200.1, 200.1, 200.8, 0.9],
]
median_prices = []
for prices in prices_list:
filtered_prices = filter_outliers(prices)
median_prices.append(get_median_price(filtered_prices))
filtered_prices
and median_prices
should be in a format equivalent to this:
# Loop 1
filtered_price = [10.0, 10.1, 9.8]
median_prices = [10.0]
# Loop 2
filtered_price = [200.1, 200.1, 200.8]
median_prices = [10.0, 200.1]
def get_prices(symbols: List[str]) -> Dict[str, Optional[float]]:
# Insert logic here
return prices
If the following code is run:
if __name__ == "__main__":
results = get_prices(["BTC", "ETH", "NOTAREALTOKEN"])
results
should be returned in a format equivalent to this:
results = {
"BTC": 23541.0,
"ETH": 1532.32,
"NOTAREALTOKEN": None,
}
The test cases can be found under tests/test_cases.json
in this repository.
- Think about how the code should be structured, follow PEP 8 guidelines and use type hinting via the typing library.
- Consider factors such as API rate limit/weights, coding efficiency and how long your function takes to complete when designing your solution.
- Include a demo in the demo.py file that showcases the results from the test cases.
- In the README.md, document all the technical decisions and trade-offs you've made, why you made those decisions or trade-offs, the specific outlier rejection method you've used and why you chose that method and any other feature you've left out that you would implement if given more time.
For bonus points, you can write a set of unit tests. Make sure to think of the possible edge cases and create a conftest file to simulate the handler functions
If you have any doubts, questions or would like to request an extension, feel free to contact us at any time. You can reach us at [email protected] or through posting an issue in this repository.