diff --git a/README.md b/README.md index a006324..6e23ef3 100644 --- a/README.md +++ b/README.md @@ -71,9 +71,45 @@ In honor of the `black_76` model, the `_76` on the end of functions indicates a This model is built to price financial option contracts on a wide variety of financial commodities. These options are widely used and represent the benchmark to which other (more complicated) models are compared. While those more complicated models may outperform these models in specific areas, out-performance is relatively uncommon. By an large, these models have taken on all challengers and remain the de-facto industry standard. ## TDAmeritrade Option Chain API -This library provides the ability to fetch up-to-date option chain data using TDAmeritrade's option chain API. In order to use this functionality, the user is required to get his own API key. This can be done by creating a developer account on https://developer.tdameritrade.com/. +This library provides the ability to fetch up-to-date data using TDAmeritrade'sAPI. In order to use this functionality, the user is required to get his own API key. This can be done by creating a developer account on https://developer.tdameritrade.com/. -The API accepts the following query parameters. +### Historical Data +The historical data API accepts the following query parameters. +* `apikey`. Required. Application consumer key on TDAmeritrade platform. +* `symbol`. Required. Symbol to get option chain for. +* `periodType`. The type of period to show. Valid values are `day`, `month`, `year`, or `ytd` (year to date). Default is `day`. +* `period`. The number of periods to show. + + Example: For a 2 day / 1 min chart, the values would be: + * period: 2 + * periodType: `day` + * frequency: 1 + * frequencyType: `minute` + + Valid `periods` by `periodType` (defaults marked with an asterisk): + * `day`: 1, 2, 3, 4, 5, 10* + * `month`: 1*, 2, 3, 6 + * `year`: 1*, 2, 3, 5, 10, 15, 20 + * `ytd`: 1* +* `frequencyType`. The type of frequency with which a new candle is formed. + + Valid frequencyTypes by `periodType` (defaults marked with an asterisk): + * `day`: `minute`* + * `month`: `daily`, `weekly`* + * `year`: `daily`, `weekly`, `monthly`* + * `ytd`: `daily`, `weekly`* +* `frequency`. The type of frequency with which a new candle is formed. + Valid frequencyTypes by periodType (defaults marked with an asterisk): + * `day`: `minute`* + * `month`: `daily`, `weekly`* + * `year`: `daily`, `weekly`, `monthly`* + * `ytd`: `daily`, `weekly`* +* `startDate`. Start date as milliseconds since epoch. +* `endDate`. End date as milliseconds since epoch. +* `needExtendedHoursData`. to return extended hours data, false for regular market hours only. + +### Option Chains +The option chain API accepts the following query parameters. * `apikey`. Required. Application consumer key on TDAmeritrade platform. * `symbol`. Required. Symbol to get option chain for. * `contractType`. Type of contracts to return in the chain. Can be `CALL`, `PUT`, or `ALL`. Default is `ALL`. diff --git a/optlib/api.py b/optlib/api.py index 958d115..cc67ff6 100644 --- a/optlib/api.py +++ b/optlib/api.py @@ -1,7 +1,11 @@ -import subprocess +from subprocess import check_output import json -ENDPOINT = "https://api.tdameritrade.com/v1/marketdata/chains" +# ------------------------------ +# This class defines the URLs to the implemented endpoints. +class Endpoint: + CHAIN = "https://api.tdameritrade.com/v1/marketdata/chains" + HIST = "https://api.tdameritrade.com/v1/marketdata/{0}/pricehistory" # ------------------------------ # This class defines the Exception that gets thrown when the api input is bad. @@ -15,7 +19,17 @@ def _test_input(*args, **kwargs): if ("apikey" not in kwargs.keys()) or ("symbol" not in kwargs.keys()): raise API_InputError("Bad input. `apikey` and `symbol` are required.") -def get(*args, **kwargs): +# ------------------------------ +# This function sends the request to the specified API endpoint. +def _get(endpoint, *args, **kwargs): + + url = "?".join([endpoint, "&".join(f"{k}={v}" for k, v in kwargs.items())]) + if (resp := json.loads(check_output(["curl", "-gs", url]))).get("error"): + raise API_InputError(f"{0}".format(resp["error"])) + + return resp + +def get_chain(*args, **kwargs): """Request an option chain from TDAmeritrade's API. Args: @@ -42,9 +56,27 @@ def get(*args, **kwargs): """ _test_input(*args, **kwargs) - url = "?".join([ENDPOINT, "&".join(f"{k}={v}" for k, v in kwargs.items())]) - resp = json.loads(subprocess.check_output(["curl", "-gs", url])) - if resp.get("error"): - raise API_InputError("Bad query. Contains unknown query parameters.") + endpoint = Endpoint.CHAIN + return _get(endpoint, *args, **kwargs) - return resp +def get_historical(*args, **kwargs): + """Request historical price data from TDAmeritrade's API. + + Args: + apikey (str): API key to api.tdameritrade.com. + symbol (str): Stock symbol to get the option chain for. + periodType (str): The type of period to show. Can be day, month, year, or ytd. + period (int): The number of periods to show. + frequencyType (str): The type of frequency with which a new candle is formed. Can be day, month, year, ytd. + frequency (str): The number of the frequencyType to be included in each candle. + startDate (int): Start date as milliseconds since epoch. + endDate (int): End date as milliseconds since epoch. + needExtendedHoursData (str): true to return extended hours data, false for regular market hours only. + + Returns: + resp (dict): API response with historical price data. + """ + _test_input(*args, **kwargs) + + endpoint = Endpoint.HIST.format(kwargs["symbol"]) + return _get(endpoint, *args, **kwargs) diff --git a/setup.py b/setup.py index 5a8ba25..8847540 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup setup( name="optlib", - version="0.2.0", + version="0.3.0", description="A library for financial options pricing written in Python.", url="http://github.com/bartolomed/optlib", author="Davis Edwards & Daniel Rojas",