Feature/options - OpenBB Options Enhancement Proposal (Part 1 - SDK) (#5079)

* add model file for Montreal Options Exchange

* mypy fixes

* define attributes under __init__

* type error fix

* another pylint fix

* adds tests for tmx_model

* black

* mypy

* adds expirations test and re-records

* black

* capture error message in test

* mypy

* add __docformat__ line

* improves get_all_ticker_symbols

* removes python magic command for new cell

* adds TMX as source for SDK chains

* starts on a new method for loading options data returning a standardized object

* add load_options as SDK endpoint

* intrinio response - not complete

* adds tradier to load_options

* add source attribute to options object

* restore legacy nasdaq last price function

* yFinance underlying_price fixes

* yFinance model fix

* adds cboe to sdk options load

* table fix

* creates options_chains_model.py and updates SDK map

* docstrings added for the class.

* updates tmx_model tests

* fix options_controller test

* adds cboe_model tests

* spelling in docstring

* ruff - unused import

* mypy fixes

* more mypy fixes

* pylint

* attempt to manually resolve merge conflict.

* nasdaq_model fix

* adds test coverage for options/nasdaq_model

* docstrings update for nasdaq_model

* mypy fix

* adds unit testing for options_chains_model

* adds additional tests for intrinio_model

* unused import fix

* fix for .TO symbol and TMX EOD chains

* make CBOE Pydantic

* cboe update

* adds switch for pydantic output from all sources

* black

* index options error handling for Intrinio

* add warning message for index options from Intrinio

* tmx_model enhancements

* cleans up get_ticker_iv() in cboe_model

* fix ticker info for index symbols from cboe

* typo in comments

* adds test for tradier_model.load_options

* cboe optionType as lower case

* add function for calculating chains stats

* black

* trailmap for calculate_chains_stats

* adds test for calculate_stats()

* more details to nasdaq.underlying_price

* typo in docstrings

* mypy - options_chains_model.py

* black - options_chains_model.py

* pylint options_chains_model.py

* standardize response from intrinio underlying price

* add function to validate input of function

* missed type hint

* additional error handling for stats

* adds DTE as column for all sources

* adds strategies function and input validation

* add yFinance test for load_options()

* add Nasdaq test for load_options()

* tests for new functions in options_chains_model

* update sdk trailmap

* rewrite tests

* fixes for tests

* fix tmx_model test

* more pytest

* pytest..

* add vertical call spread function

* some cleanup

* update nasdaq tests

* more cleanup

* black

* pylint

* black

* ruff

* black

* pylint

* black

* pylint..

* tests rewrite

* more pytest

* recapture tests

* Different tests were collected between gw1 and gw0

* adds vertical spreads

* vertical_put_spread

* improve calculate_stats

* mypy

* edge cases

* black

* update tmx,yfinance tests

* new cboe tests

* new tmx_model tests

* fix nasdaq test

* test updates

* fix nasdaq tests

* add test_options_chains_model

* refactor data sources

* black

* pylint

* fixing stuff

* forgot a file..

* codespell

* linting

* mypy...

* refactor OptionsChains class

* pylint

* reconfigure SDK entry point

* fix error handling when data request fails

* ruff

* pylint

* pylint

* Add inheritance and a repr string

* add method for skew

* add method for skew

* fix nasdaq test

* add skew to tests

---------

Co-authored-by: James Maslek <jmaslek11@gmail.com>
This commit is contained in:
Danglewood
2023-06-19 06:11:16 -07:00
committed by GitHub
parent 27bf7207ee
commit a7edda330d
74 changed files with 232518 additions and 19 deletions

View File

@@ -47,6 +47,8 @@ class StocksController(model.StocksRoot):
`mentions`: Get interest over time from google api [Source: google].\n
`mentions_chart`: Plots weekly bars of stock's interest over time. other users watchlist. [Source: Google].\n
`messages`: Get last messages for a given ticker [Source: stocktwits].\n
`ns`: Getting Onclusive Data. [Source: Invisage Platform]\n
`ns_chart`: Display Onclusive Data. [Source: Invisage Plotform]\n
`popular`: Get popular tickers from list of subreddits [Source: reddit].\n
`queries`: Get related queries from google api [Source: google].\n
`redditsent`: Find posts related to a specific search term in Reddit.\n
@@ -262,6 +264,7 @@ class StocksController(model.StocksRoot):
`eodchain`: Get full EOD option date across all expirations\n
`expirations`: Get Option Chain Expirations\n
`generate_data`: Gets x values, and y values before and after premiums\n
`get_strategies`: Gets options strategies for all, or a list of, DTE(s).\n
`greeks`: Gets the greeks for a given option\n
`grhist`: Get historical EOD option prices, with Greeks, for a given OCC chain label.\n
`grhist_chart`: Plots historical greeks for a given option.\n
@@ -269,6 +272,7 @@ class StocksController(model.StocksRoot):
`info`: Scrape barchart for options info\n
`info_chart`: Scrapes Barchart.com for the options information\n
`last_price`: Makes api request for last price\n
`load_options_chains`: Loads all options chains from a specific source, fields returned to each attribute will vary.\n
`oi`: Plot open interest\n
`pcr`: Gets put call ratio over last time window [Source: AlphaQuery.com]\n
`pcr_chart`: Display put call ratio [Source: AlphaQuery.com]\n

View File

@@ -47,6 +47,8 @@ class StocksBehavioralAnalysis(Category):
`mentions`: Get interest over time from google api [Source: google].\n
`mentions_chart`: Plots weekly bars of stock's interest over time. other users watchlist. [Source: Google].\n
`messages`: Get last messages for a given ticker [Source: stocktwits].\n
`ns`: Getting Onclusive Data. [Source: Invisage Platform]\n
`ns_chart`: Display Onclusive Data. [Source: Invisage Plotform]\n
`popular`: Get popular tickers from list of subreddits [Source: reddit].\n
`queries`: Get related queries from google api [Source: google].\n
`redditsent`: Find posts related to a specific search term in Reddit.\n
@@ -78,6 +80,8 @@ class StocksBehavioralAnalysis(Category):
self.mentions = lib.stocks_ba_google_model.get_mentions
self.mentions_chart = lib.stocks_ba_google_view.display_mentions
self.messages = lib.stocks_ba_stocktwits_model.get_messages
self.ns = lib.stocks_ba_news_sentiment_model.get_data
self.ns_chart = lib.stocks_ba_news_sentiment_view.display_articles_data
self.popular = lib.stocks_ba_reddit_model.get_popular_tickers
self.queries = lib.stocks_ba_google_model.get_queries
self.redditsent = lib.stocks_ba_reddit_model.get_posts_about
@@ -452,6 +456,7 @@ class StocksOptions(Category):
`eodchain`: Get full EOD option date across all expirations\n
`expirations`: Get Option Chain Expirations\n
`generate_data`: Gets x values, and y values before and after premiums\n
`get_strategies`: Gets options strategies for all, or a list of, DTE(s).\n
`greeks`: Gets the greeks for a given option\n
`grhist`: Get historical EOD option prices, with Greeks, for a given OCC chain label.\n
`grhist_chart`: Plots historical greeks for a given option.\n
@@ -459,6 +464,7 @@ class StocksOptions(Category):
`info`: Scrape barchart for options info\n
`info_chart`: Scrapes Barchart.com for the options information\n
`last_price`: Makes api request for last price\n
`load_options_chains`: Loads all options chains from a specific source, fields returned to each attribute will vary.\n
`oi`: Plot open interest\n
`pcr`: Gets put call ratio over last time window [Source: AlphaQuery.com]\n
`pcr_chart`: Display put call ratio [Source: AlphaQuery.com]\n
@@ -480,6 +486,7 @@ class StocksOptions(Category):
self.eodchain = lib.stocks_options_intrinio_model.get_full_chain_eod
self.expirations = lib.stocks_options_sdk_helper.get_option_expirations
self.generate_data = lib.stocks_options_yfinance_model.generate_data
self.get_strategies = lib.stocks_options_options_chains_model.get_strategies
self.greeks = lib.stocks_options_sdk_helper.get_greeks
self.grhist = lib.stocks_options_intrinio_model.get_historical_options
self.grhist_chart = lib.stocks_options_intrinio_view.view_historical_greeks
@@ -487,6 +494,7 @@ class StocksOptions(Category):
self.info = lib.stocks_options_barchart_model.get_options_info
self.info_chart = lib.stocks_options_barchart_view.print_options_data
self.last_price = lib.stocks_options_tradier_model.get_last_price
self.load_options_chains = lib.stocks_options_sdk_helper.load_options_chains
self.oi = lib.stocks_options_view.plot_oi
self.pcr = lib.stocks_options_alphaquery_model.get_put_call_ratio
self.pcr_chart = lib.stocks_options_alphaquery_view.display_put_call_ratio

View File

@@ -521,6 +521,7 @@ from openbb_terminal.stocks.options import (
alphaquery_view as stocks_options_alphaquery_view,
barchart_model as stocks_options_barchart_model,
barchart_view as stocks_options_barchart_view,
cboe_model as stocks_options_cboe_model,
chartexchange_model as stocks_options_chartexchange_model,
chartexchange_view as stocks_options_chartexchange_view,
fdscanner_model as stocks_options_fdscanner_model,
@@ -529,6 +530,7 @@ from openbb_terminal.stocks.options import (
intrinio_view as stocks_options_intrinio_view,
nasdaq_model as stocks_options_nasdaq_model,
op_helpers as stocks_options_helpers,
options_chains_model as stocks_options_options_chains_model,
options_sdk_helper as stocks_options_sdk_helper,
options_view as stocks_options_view,
tradier_model as stocks_options_tradier_model,

View File

@@ -392,6 +392,7 @@ stocks.ba.headlines,stocks_ba_finbrain_model.get_sentiment,stocks_ba_finbrain_vi
stocks.ba.infer,stocks_ba_twitter_model.load_analyze_tweets,stocks_ba_twitter_view.display_inference
stocks.ba.mentions,stocks_ba_google_model.get_mentions,stocks_ba_google_view.display_mentions
stocks.ba.messages,stocks_ba_stocktwits_model.get_messages,
stocks.ba.ns,stocks_ba_news_sentiment_model.get_data,stocks_ba_news_sentiment_view.display_articles_data
stocks.ba.popular,stocks_ba_reddit_model.get_popular_tickers,
stocks.ba.queries,stocks_ba_google_model.get_queries,
stocks.ba.redditsent,stocks_ba_reddit_model.get_posts_about,
@@ -403,7 +404,6 @@ stocks.ba.spacc,stocks_ba_reddit_model.get_spac_community,
stocks.ba.stalker,stocks_ba_stocktwits_model.get_stalker,
stocks.ba.text_sent,stocks_ba_reddit_model.get_sentiment,
stocks.ba.trending,stocks_ba_stocktwits_model.get_trending,
stocks.ba.ns,stocks_ba_news_sentiment_model.get_data,stocks_ba_news_sentiment_view.display_articles_data
stocks.ba.wsb,stocks_ba_reddit_model.get_wsb_community,
stocks.ca.balance,stocks_ca_marketwatch_model.get_balance_comparison,
stocks.ca.cashflow,stocks_ca_marketwatch_model.get_cashflow_comparison,
@@ -516,11 +516,13 @@ stocks.options.dte,stocks_options_helpers.get_dte,
stocks.options.eodchain,stocks_options_intrinio_model.get_full_chain_eod,
stocks.options.expirations,stocks_options_sdk_helper.get_option_expirations,
stocks.options.generate_data,stocks_options_yfinance_model.generate_data,
stocks.options.get_strategies,stocks_options_options_chains_model.get_strategies,
stocks.options.greeks,stocks_options_sdk_helper.get_greeks,
stocks.options.grhist,stocks_options_intrinio_model.get_historical_options,stocks_options_intrinio_view.view_historical_greeks
stocks.options.hist,stocks_options_sdk_helper.hist,
stocks.options.info,stocks_options_barchart_model.get_options_info,stocks_options_barchart_view.print_options_data
stocks.options.last_price,stocks_options_tradier_model.get_last_price,
stocks.options.load_options_chains,stocks_options_sdk_helper.load_options_chains,
stocks.options.oi,stocks_options_view.plot_oi,
stocks.options.pcr,stocks_options_alphaquery_model.get_put_call_ratio,stocks_options_alphaquery_view.display_put_call_ratio
stocks.options.price,stocks_options_sdk_helper.get_option_current_price,
1 trail model view
392 stocks.ba.infer stocks_ba_twitter_model.load_analyze_tweets stocks_ba_twitter_view.display_inference
393 stocks.ba.mentions stocks_ba_google_model.get_mentions stocks_ba_google_view.display_mentions
394 stocks.ba.messages stocks_ba_stocktwits_model.get_messages
395 stocks.ba.ns stocks_ba_news_sentiment_model.get_data stocks_ba_news_sentiment_view.display_articles_data
396 stocks.ba.popular stocks_ba_reddit_model.get_popular_tickers
397 stocks.ba.queries stocks_ba_google_model.get_queries
398 stocks.ba.redditsent stocks_ba_reddit_model.get_posts_about
404 stocks.ba.stalker stocks_ba_stocktwits_model.get_stalker
405 stocks.ba.text_sent stocks_ba_reddit_model.get_sentiment
406 stocks.ba.trending stocks_ba_stocktwits_model.get_trending
stocks.ba.ns stocks_ba_news_sentiment_model.get_data stocks_ba_news_sentiment_view.display_articles_data
407 stocks.ba.wsb stocks_ba_reddit_model.get_wsb_community
408 stocks.ca.balance stocks_ca_marketwatch_model.get_balance_comparison
409 stocks.ca.cashflow stocks_ca_marketwatch_model.get_cashflow_comparison
516 stocks.options.eodchain stocks_options_intrinio_model.get_full_chain_eod
517 stocks.options.expirations stocks_options_sdk_helper.get_option_expirations
518 stocks.options.generate_data stocks_options_yfinance_model.generate_data
519 stocks.options.get_strategies stocks_options_options_chains_model.get_strategies
520 stocks.options.greeks stocks_options_sdk_helper.get_greeks
521 stocks.options.grhist stocks_options_intrinio_model.get_historical_options stocks_options_intrinio_view.view_historical_greeks
522 stocks.options.hist stocks_options_sdk_helper.hist
523 stocks.options.info stocks_options_barchart_model.get_options_info stocks_options_barchart_view.print_options_data
524 stocks.options.last_price stocks_options_tradier_model.get_last_price
525 stocks.options.load_options_chains stocks_options_sdk_helper.load_options_chains
526 stocks.options.oi stocks_options_view.plot_oi
527 stocks.options.pcr stocks_options_alphaquery_model.get_put_call_ratio stocks_options_alphaquery_view.display_put_call_ratio
528 stocks.options.price stocks_options_sdk_helper.get_option_current_price

View File

@@ -0,0 +1,574 @@
# mypy: disable-error-code=attr-defined
"""Model for retrieving public options data from the CBOE."""
from datetime import datetime
from typing import Tuple
import pandas as pd
from requests.exceptions import HTTPError
from openbb_terminal.helper_funcs import request
from openbb_terminal.stocks.options.op_helpers import Options, PydanticOptions
__docformat__ = "numpy"
TICKER_EXCEPTIONS: list[str] = ["NDX", "RUT"]
def get_cboe_directory() -> pd.DataFrame:
"""Gets the US Listings Directory for the CBOE.
Returns
-------
pd.DataFrame: CBOE_DIRECTORY
DataFrame of the CBOE listings directory
Examples
-------
>>> from openbb_terminal.stocks.options import cboe_model
>>> CBOE_DIRECTORY = cboe_model.get_cboe_directory()
"""
CBOE_DIRECTORY: pd.DataFrame = pd.read_csv(
"https://www.cboe.com/us/options/symboldir/equity_index_options/?download=csv"
)
CBOE_DIRECTORY = CBOE_DIRECTORY.rename(
columns={
" Stock Symbol": "Symbol",
" DPM Name": "DPM Name",
" Post/Station": "Post/Station",
}
).set_index("Symbol")
return CBOE_DIRECTORY
def get_cboe_index_directory() -> pd.DataFrame:
"""Gets the US Listings Directory for the CBOE
Returns
-------
pd.DataFrame: CBOE_INDEXES
Examples
-------
>>> from openb_terminal.stocks.options import cboe_model
>>> CBOE_INDEXES = cboe_model.get_cboe_index_directory()
"""
CBOE_INDEXES: pd.DataFrame = pd.DataFrame(
pd.read_json(
"https://cdn.cboe.com/api/global/us_indices/definitions/all_indices.json"
)
)
CBOE_INDEXES = CBOE_INDEXES.rename(
columns={
"calc_end_time": "Close Time",
"calc_start_time": "Open Time",
"currency": "Currency",
"description": "Description",
"display": "Display",
"featured": "Featured",
"featured_order": "Featured Order",
"index_symbol": "Ticker",
"mkt_data_delay": "Data Delay",
"name": "Name",
"tick_days": "Tick Days",
"tick_frequency": "Frequency",
"tick_period": "Period",
"time_zone": "Time Zone",
},
)
indices_order: list[str] = [
"Ticker",
"Name",
"Description",
"Currency",
"Tick Days",
"Frequency",
"Period",
"Time Zone",
]
CBOE_INDEXES = pd.DataFrame(CBOE_INDEXES, columns=indices_order).set_index("Ticker")
return CBOE_INDEXES
# Gets the list of indexes for parsing the ticker symbol properly.
INDEXES = get_cboe_index_directory().index.tolist()
SYMBOLS = get_cboe_directory()
def get_ticker_info(symbol: str) -> Tuple[pd.DataFrame, list[str]]:
"""Gets basic info for the symbol and expiration dates
Parameters
----------
symbol: str
The ticker to lookup
Returns
-------
Tuple: [pd.DataFrame, pd.Series]
ticker_details
ticker_expirations
Examples
--------
>>> from openbb_terminal.stocks.options import cboe_model
>>> ticker_details,ticker_expirations = cboe_model.get_ticker_info('AAPL')
>>> vix_details,vix_expirations = cboe_model.get_ticker_info('VIX')
"""
stock = "stock"
index = "index"
symbol = symbol.upper()
new_ticker: str = ""
ticker_details = pd.DataFrame()
ticker_expirations: list = []
try:
if symbol in TICKER_EXCEPTIONS:
new_ticker = "^" + symbol
else:
if symbol not in INDEXES:
new_ticker = symbol
elif symbol in INDEXES:
new_ticker = "^" + symbol
# Gets the data to return, and if none returns empty Tuple #
symbol_info_url = (
"https://www.cboe.com/education/tools/trade-optimizer/symbol-info/?symbol="
f"{new_ticker}"
)
symbol_info = request(symbol_info_url)
symbol_info_json = symbol_info.json()
symbol_info_json = pd.Series(symbol_info.json())
if symbol_info_json.success is False:
ticker_details = pd.DataFrame()
ticker_expirations = []
print("No data found for the symbol: " f"{symbol}" "")
else:
symbol_details = pd.Series(symbol_info_json["details"])
symbol_details = pd.DataFrame(symbol_details).transpose()
symbol_details = symbol_details.reset_index()
ticker_expirations = symbol_info_json["expirations"]
# Cleans columns depending on if the security type is a stock or an index
type_ = symbol_details.security_type
if stock[0] in type_[0]:
stock_details = symbol_details
ticker_details = pd.DataFrame(stock_details).rename(
columns={
"current_price": "price",
"bid_size": "bidSize",
"ask_size": "askSize",
"iv30": "ivThirty",
"prev_day_close": "previousClose",
"price_change": "change",
"price_change_percent": "changePercent",
"iv30_change": "ivThirtyChange",
"iv30_percent_change": "ivThirtyChangePercent",
"last_trade_time": "lastTradeTimestamp",
"exchange_id": "exchangeID",
"tick": "tick",
"security_type": "type",
}
)
details_columns = [
"symbol",
"type",
"tick",
"bid",
"bidSize",
"askSize",
"ask",
"price",
"open",
"high",
"low",
"close",
"volume",
"previousClose",
"change",
"changePercent",
"ivThirty",
"ivThirtyChange",
"ivThirtyChangePercent",
"lastTradeTimestamp",
]
ticker_details = (
pd.DataFrame(ticker_details, columns=details_columns)
.set_index(keys="symbol")
.dropna(axis=1)
.transpose()
)
if index[0] in type_[0]:
index_details = symbol_details
ticker_details = pd.DataFrame(index_details).rename(
columns={
"symbol": "symbol",
"security_type": "type",
"current_price": "price",
"price_change": "change",
"price_change_percent": "changePercent",
"prev_day_close": "previousClose",
"iv30": "ivThirty",
"iv30_change": "ivThirtyChange",
"iv30_change_percent": "ivThirtyChangePercent",
"last_trade_time": "lastTradeTimestamp",
}
)
index_columns = [
"symbol",
"type",
"tick",
"price",
"open",
"high",
"low",
"close",
"previousClose",
"change",
"changePercent",
"ivThirty",
"ivThirtyChange",
"ivThirtyChangePercent",
"lastTradeTimestamp",
]
ticker_details = (
pd.DataFrame(ticker_details, columns=index_columns)
.set_index(keys="symbol")
.dropna(axis=1)
.transpose()
).rename(columns={f"{new_ticker}": f"{symbol}"})
except HTTPError:
print("There was an error with the request'\n")
ticker_details = pd.DataFrame()
ticker_expirations = list()
return ticker_details, ticker_expirations
return ticker_details, ticker_expirations
def get_ticker_iv(symbol: str) -> pd.DataFrame:
"""Gets annualized high/low historical and implied volatility over 30/60/90 day windows.
Parameters
----------
symbol: str
The loaded ticker
Returns
-------
pd.DataFrame: ticker_iv
Examples
--------
>>> from openbb_terminal.stocks.options import cboe_model
>>> ticker_iv = cboe_model.get_ticker_iv('AAPL')
>>> ndx_iv = cboe_model.get_ticker_iv('NDX')
"""
# Checks ticker to determine if ticker is an index or an exception that requires modifying the request's URLs
try:
if symbol in TICKER_EXCEPTIONS:
quotes_iv_url = (
"https://cdn.cboe.com/api/global/delayed_quotes/historical_data/_"
f"{symbol}"
".json"
)
else:
if symbol not in INDEXES:
quotes_iv_url = (
"https://cdn.cboe.com/api/global/delayed_quotes/historical_data/"
f"{symbol}"
".json"
)
elif symbol in INDEXES:
quotes_iv_url = (
"https://cdn.cboe.com/api/global/delayed_quotes/historical_data/_"
f"{symbol}"
".json"
)
h_iv = request(quotes_iv_url)
if h_iv.status_code != 200:
print("No data found for the symbol: " f"{symbol}" "")
return pd.DataFrame()
data = h_iv.json()
h_data = pd.DataFrame(data)[2:-1]["data"].rename(f"{symbol}")
h_data.rename(
{
"hv30_annual_high": "hvThirtyOneYearHigh",
"hv30_annual_low": "hvThirtyOneYearLow",
"hv60_annual_high": "hvSixtyOneYearHigh",
"hv60_annual_low": "hvsixtyOneYearLow",
"hv90_annual_high": "hvNinetyOneYearHigh",
"hv90_annual_low": "hvNinetyOneYearLow",
"iv30_annual_high": "ivThirtyOneYearHigh",
"iv30_annual_low": "ivThirtyOneYearLow",
"iv60_annual_high": "ivSixtyOneYearHigh",
"iv60_annual_low": "ivSixtyOneYearLow",
"iv90_annual_high": "ivNinetyOneYearHigh",
"iv90_annual_low": "ivNinetyOneYearLow",
},
inplace=True,
)
iv_order = [
"ivThirtyOneYearHigh",
"hvThirtyOneYearHigh",
"ivThirtyOneYearLow",
"hvThirtyOneYearLow",
"ivSixtyOneYearHigh",
"hvSixtyOneYearHigh",
"ivSixtyOneYearLow",
"hvsixtyOneYearLow",
"ivNinetyOneYearHigh",
"hvNinetyOneYearHigh",
"ivNinetyOneYearLow",
"hvNinetyOneYearLow",
]
ticker_iv = pd.DataFrame(h_data).transpose()
except HTTPError:
print("There was an error with the request'\n")
return pd.DataFrame(ticker_iv, columns=iv_order).transpose()
def get_quotes(symbol: str) -> pd.DataFrame:
"""Gets the complete options chains for a ticker.
Parameters
----------
symbol: str
The ticker get options data for
Returns
-------
pd.DataFrame
DataFrame with all active options contracts for the underlying symbol.
Examples
--------
>>> from openbb_terminal.stocks.options import cboe_model
>>> xsp = cboe_model.OptionsChains().get_chains('XSP')
>>> xsp_chains = xsp.chains
"""
# Checks ticker to determine if ticker is an index or an exception that requires modifying the request's URLs.
try:
if symbol in TICKER_EXCEPTIONS:
quotes_url = (
"https://cdn.cboe.com/api/global/delayed_quotes/options/_"
f"{symbol}"
".json"
)
else:
if symbol not in INDEXES:
quotes_url = (
"https://cdn.cboe.com/api/global/delayed_quotes/options/"
f"{symbol}"
".json"
)
if symbol in INDEXES:
quotes_url = (
"https://cdn.cboe.com/api/global/delayed_quotes/options/_"
f"{symbol}"
".json"
)
r = request(quotes_url)
if r.status_code != 200:
print("No data found for the symbol: " f"{symbol}" "")
return pd.DataFrame()
r_json = r.json()
data = pd.DataFrame(r_json["data"])
options = pd.Series(data.options, index=data.index)
options_columns = list(options[0])
options_data = list(options[:])
options_df = pd.DataFrame(options_data, columns=options_columns)
options_df = options_df.rename(
columns={
"option": "contractSymbol",
"bid_size": "bidSize",
"ask_size": "askSize",
"iv": "impliedVolatility",
"open_interest": "openInterest",
"theo": "theoretical",
"last_trade_price": "lastTradePrice",
"last_trade_time": "lastTradeTimestamp",
"percent_change": "changePercent",
"prev_day_close": "previousClose",
}
)
# Pareses the option symbols into columns for expiration, strike, and optionType
option_df_index = options_df["contractSymbol"].str.extractall(
r"^(?P<Ticker>\D*)(?P<expiration>\d*)(?P<optionType>\D*)(?P<strike>\d*)"
)
option_df_index = option_df_index.reset_index().drop(
columns=["match", "level_0"]
)
option_df_index.optionType = option_df_index.optionType.str.replace(
"C", "call"
).str.replace("P", "put")
option_df_index.strike = [ele.lstrip("0") for ele in option_df_index.strike]
option_df_index.strike = pd.Series(option_df_index.strike).astype(float)
option_df_index.strike = option_df_index.strike * (1 / 1000)
option_df_index.strike = option_df_index.strike.to_list()
option_df_index.expiration = [
ele.lstrip("1") for ele in option_df_index.expiration
]
option_df_index.expiration = pd.DatetimeIndex(
option_df_index.expiration, yearfirst=True
).astype(str)
option_df_index = option_df_index.drop(columns=["Ticker"])
# Joins the parsed symbol into the dataframe.
quotes = option_df_index.join(options_df)
now = datetime.now()
temp = pd.DatetimeIndex(quotes.expiration)
temp_ = (temp - now).days + 1
quotes["dte"] = temp_
quotes = quotes.set_index(
keys=["expiration", "strike", "optionType"]
).sort_index()
quotes["openInterest"] = quotes["openInterest"].astype(int)
quotes["volume"] = quotes["volume"].astype(int)
quotes["bidSize"] = quotes["bidSize"].astype(int)
quotes["askSize"] = quotes["askSize"].astype(int)
quotes["previousClose"] = round(quotes["previousClose"], 2)
quotes["changePercent"] = round(quotes["changePercent"], 2)
except HTTPError:
print("There was an error with the request'\n")
return pd.DataFrame()
return quotes.reset_index()
def load_options(symbol: str, pydantic: bool = False) -> object:
"""OptionsChains data object for CBOE.
Parameters
----------
symbol: str
The ticker symbol to load.
pydantic: bool
Whether to return the object as a Pydantic Model or a subscriptable Pandas Object. Default is False.
Returns
-------
object: OptionsChains
chains: dict
The complete options chain for the ticker. Returns as a Pandas DataFrame if pydantic is False.
expirations: list[str]
List of unique expiration dates. (YYYY-MM-DD)
strikes: list[float]
List of unique strike prices.
last_price: float
The last price of the underlying asset.
underlying_name: str
The name of the underlying asset.
underlying_price: dict
The price and recent performance of the underlying asset. Returns as a Pandas Series if pydantic is False.
hasIV: bool
Returns implied volatility.
hasGreeks: bool
Returns greeks data.
symbol: str
The symbol entered by the user.
source: str
The source of the data, "CBOE".
SYMBOLS: dict
The CBOE symbol directory. Returns as a Pandas DataFrame if pydantic is False.
Examples
--------
Get current options chains for AAPL.
>>> from openbb_terminal.stocks.options.cboe_model import load_options
>>> data = load_options("AAPL")
>>> chains = data.chains
Return the object as a Pydantic Model.
>>> from openbb_terminal.stocks.options.cboe_model import load_options
>>> data = load_options("AAPL", pydantic=True)
"""
OptionsChains = Options()
symbol = symbol.upper()
OptionsChains.SYMBOLS = SYMBOLS
OptionsChains.source = "CBOE"
OptionsChains.symbol = symbol
if OptionsChains.symbol not in OptionsChains.SYMBOLS.index:
print("The symbol, " f"{symbol}" ", was not found in the CBOE directory.")
return OptionsChains
info, _ = get_ticker_info(OptionsChains.symbol)
if not info.empty:
iv = get_ticker_iv(OptionsChains.symbol)
info = pd.concat([info, iv])
info = pd.Series(info[f"{OptionsChains.symbol}"])
underlying_name = (
OptionsChains.SYMBOLS.reset_index()
.query("`Symbol` == @symbol")["Company Name"]
.iloc[0]
)
OptionsChains.underlying_name = underlying_name
OptionsChains.underlying_price = info
OptionsChains.last_price = round(info.loc["price"], 2)
OptionsChains.chains = get_quotes(OptionsChains.symbol)
if not OptionsChains.chains.empty:
OptionsChains.expirations = (
OptionsChains.chains["expiration"].astype(str).unique().tolist()
)
OptionsChains.strikes = (
OptionsChains.chains["strike"].sort_values().unique().tolist()
)
OptionsChains.hasIV = "impliedVolatility" in OptionsChains.chains.columns
OptionsChains.hasGreeks = "gamma" in OptionsChains.chains.columns
if not pydantic:
return OptionsChains
OptionsChainsPydantic = PydanticOptions(
chains=OptionsChains.chains.to_dict(),
expirations=OptionsChains.expirations,
strikes=OptionsChains.strikes,
last_price=OptionsChains.last_price,
underlying_name=OptionsChains.underlying_name,
underlying_price=OptionsChains.underlying_price.to_dict(),
hasIV=OptionsChains.hasIV,
hasGreeks=OptionsChains.hasGreeks,
symbol=OptionsChains.symbol,
source=OptionsChains.source,
SYMBOLS=OptionsChains.SYMBOLS.to_dict(),
)
return OptionsChainsPydantic
return OptionsChains
return None

View File

@@ -1,3 +1,5 @@
# mypy: disable-error-code=attr-defined
"""Intrinio model"""
__docformat__ = "numpy"
import logging
@@ -11,10 +13,12 @@ import pandas as pd
from openbb_terminal.core.session.current_user import get_current_user
from openbb_terminal.decorators import check_api_key, log_start_end
from openbb_terminal.rich_config import console, optional_rich_track
from openbb_terminal.stocks.options.op_helpers import Options, PydanticOptions
logger = logging.getLogger(__name__)
intrinio.ApiClient().set_api_key(get_current_user().credentials.API_INTRINIO_KEY)
intrinio.ApiClient().set_api_key(key=get_current_user().credentials.API_INTRINIO_KEY) # type: ignore[attr-defined]
api = intrinio.OptionsApi()
eod_columns_to_drop = [
"open_ask",
"open_bid",
@@ -38,6 +42,21 @@ columns_to_drop = [
"implied_volatility_change",
]
# These tickers are equity indexes that trade options and return data, but require modifying the API call.
TICKER_EXCEPTIONS = [
"SPX",
"XSP",
"XEO",
"NDX",
"XND",
"VIX",
"RUT",
"MRUT",
"DJX",
"XAU",
"OEX",
]
def calculate_dte(chain_df: pd.DataFrame) -> pd.DataFrame:
"""Adds a column calculating the difference between expiration and the date data is from
@@ -371,3 +390,365 @@ def get_historical_options(symbol: str) -> pd.DataFrame:
.fillna(0)
)
return historical
@check_api_key(["API_INTRINIO_KEY"])
def get_all_ticker_symbols() -> list[str]:
"""Gets a list of all options tickers supported by Intrinio.
Returns
-------
list: str
List of all ticker symbols supported.
"""
return api.get_all_options_tickers().tickers
@check_api_key(["API_INTRINIO_KEY"])
def get_ticker_info(symbol: str) -> pd.Series:
"""Gets basic meta data for the ticker.
Parameters
----------
symbol: str
The ticker symbol to lookup.
Returns
-------
pd.Series
Pandas Series object with meta data for the symbol.
"""
symbol = symbol.upper()
try:
info = intrinio.SecurityApi().get_security_by_id(symbol).to_dict()
except Exception:
print("Security not found")
return {}
info = pd.Series(info).rename(
{
"company_id": "companyID",
"share_class": "shareClass",
"round_lot_size": "roundLotSize",
"exchange_ticker": "exchangeTicker",
"composite_ticker": "compositeTicker",
"alternate_tickers": "alternateTickers",
"composite_figi": "compositeFIGI",
"share_class_figi": "shareClassFIGI",
"figi_uniqueid": "figiUniqueID",
"primary_listing": "primaryListing",
"first_stock_price": "firstStockPrice",
"last_stock_price": "lastStockPrice",
"last_stock_price_adjustment": "lastStockPriceAdjustment",
"last_corporate_action": "lastCorporateAction",
"previous_tickers": "previousTickers",
"listing_exchange_mic": "listingExchangeMIC",
}
)
return info.rename(info["ticker"])
@check_api_key(["API_INTRINIO_KEY"])
def get_underlying_price(symbol: str) -> pd.Series:
"""Gets the real time bid/ask and last price for the symbol.
Parameters
----------
symbol: str
The ticker symbol to lookup.
Returns
-------
pd.Series
Pandas Series object with real time bid/ask and last price for the symbol.
Example
-------
>>> from openbb_terminal.stocks.options.intrinio_model import get_underlying_price
>>> underlying = get_underlying_price("AAPL")
"""
data = intrinio.SecurityApi().get_security_realtime_price(symbol).to_dict()
underlying_price = pd.Series(data).rename(
{
"last_price": "lastPrice",
"last_time": "timestamp",
"last_size": "lastSize",
"bid_price": "bidPrice",
"bid_size": "bidSize",
"ask_price": "askPrice",
"ask_size": "askSize",
"open_price": "open",
"close_price": "close",
"high_price": "high",
"low_price": "low",
"exchange_volume": "volume",
"market_volume": "marketVolume",
"updated_on": "lastUpdated",
}
)
return underlying_price.rename(underlying_price["security"]["ticker"])
def get_eod_chains(symbol: str, date: str) -> object:
"""Internal function for loading historical EOD option prices. This function is called from `load_options()`.
Parameters
----------
symbol : str
The ticker symbol to lookup.
date: str
The date for the EOD chains data. Format: YYYY-MM-DD
object: OptionsChains
chains: pd.DataFrame
The complete options chain for the ticker.
expirations: list[str]
List of unique expiration dates. (YYYY-MM-DD)
strikes: list[float]
List of unique strike prices.
last_price: float
The last price of the underlying asset.
underlying_name: str
The name of the underlying asset.
underlying_price: pd.Series
The price and recent performance of the underlying asset.
hasIV: bool
Returns implied volatility.
hasGreeks: bool
Returns greeks data.
symbol: str
The symbol entered by the user.
source: str
The source of the data, "Intrinio".
SYMBOLS: list
The list of valid Intrinio symbols.
"""
OptionsChains = Options()
OptionsChains.source = "Intrinio"
OptionsChains.date = date
symbol = symbol.upper()
OptionsChains.SYMBOLS = get_all_ticker_symbols()
if symbol not in OptionsChains.SYMBOLS:
print(f"{symbol}", "is not supported by Intrinio.")
return OptionsChains
OptionsChains.symbol = symbol
if symbol not in TICKER_EXCEPTIONS:
underlying = (
intrinio.SecurityApi()
.get_security_stock_prices(
symbol, start_date=date, end_date=date, frequency="daily"
)
.to_dict()
)
OptionsChains.underlying_name = underlying["security"]["name"]
underlying = pd.Series(underlying["stock_prices"][0])
underlying = underlying.rename(
{
"adj_close": "adjClose",
"adj_high": "adjHigh",
"adj_low": "adjLow",
"adj_open": "adjOpen",
"adj_volume": "adjVolume",
"split_ratio": "splitRatio",
"percent_change": "changePercent",
"fifty_two_week_high": "fiftyTwoWeekHigh",
"fifty_two_week_low": "fiftyTwoWeekLow",
}
)
OptionsChains.underlying_price = underlying.rename(f"{OptionsChains.symbol}")
OptionsChains.last_price = underlying["adjClose"]
# If the ticker is an index, it will not return underlying data.
else:
print("Warning: Index options do not currently return underlying data.")
OptionsChains.underlying_name = OptionsChains.symbol
OptionsChains.underlying_price = pd.Series(dtype=object)
OptionsChains.last_price = 0
# If the symbol is an index, it needs to be preceded with, $.
if OptionsChains.symbol in TICKER_EXCEPTIONS:
OptionsChains.symbol = "$" + OptionsChains.symbol
chains = get_full_chain_eod(OptionsChains.symbol, date)
chains.rename(
columns={"code": "optionSymbol", "close_bid": "bid", "close_ask": "ask"},
inplace=True,
)
chains = chains.set_index(["expiration", "strike", "optionType"]).sort_index()
chains.reset_index(inplace=True)
OptionsChains.chains = chains.drop(columns=["ticker"])
if not OptionsChains.chains.empty:
OptionsChains.expirations = OptionsChains.chains["expiration"].unique().tolist()
OptionsChains.strikes = (
OptionsChains.chains["strike"].sort_values().unique().tolist()
)
OptionsChains.hasIV = (
"impliedVolatility" in OptionsChains.chains.columns
and OptionsChains.chains.impliedVolatility.sum() > 0
)
OptionsChains.hasGreeks = (
"gamma" in OptionsChains.chains.columns and OptionsChains.chains.gamma.sum() > 0
)
return OptionsChains
@check_api_key(["API_INTRINIO_KEY"])
def load_options(symbol: str, date: str = "", pydantic=False) -> object:
"""OptionsChains data object for Intrinio.
Parameters
----------
symbol : str
The ticker symbol to load.
date: Optional[str]
The date for EOD chains data.
pydantic: bool
Whether to return the object as a Pydantic Model or a subscriptable Pandas Object. Default is False.
Returns
-------
object: OptionsChains
chains: dict
The complete options chain for the ticker. Returns as a Pandas DataFrame if pydantic is False.
expirations: list[str]
List of unique expiration dates. (YYYY-MM-DD)
strikes: list[float]
List of unique strike prices.
last_price: float
The last price of the underlying asset.
underlying_name: str
The name of the underlying asset.
underlying_price: dict
The price and recent performance of the underlying asset. Returns as a Pandas Series if pydantic is False.
hasIV: bool
Returns implied volatility.
hasGreeks: bool
Returns greeks data.
symbol: str
The symbol entered by the user.
source: str
The source of the data, "Intrinio".
date: str
The date, if applicable, for the EOD chains data. (YYYY-MM-DD)
SYMBOLS: list
The list of valid Intrinio symbols.
Examples
--------
Get current options chains for AAPL.
>>> from openbb_terminal.stocks.options.intrinio_model import load_options
>>> data = load_options("AAPL")
>>> chains = data.chains
Get options chains for AAPL for a specific date.
>>> from openbb_terminal.stocks.options.intrinio_model import load_options
>>> data = load_options("AAPL", "2022-01-03")
>>> chains = data.chains
Return the object as a Pydantic Model.
>>> from openbb_terminal.stocks.options.intrinio_model import load_options
>>> data = load_options("AAPL", pydantic=True)
"""
OptionsChains = Options()
OptionsChains.source = "Intrinio"
symbol = symbol.upper()
OptionsChains.SYMBOLS = get_all_ticker_symbols()
if symbol not in OptionsChains.SYMBOLS:
print(f"{symbol}", "is not supported by Intrinio.")
return OptionsChains
OptionsChains.symbol = symbol
if date and date != "":
options = get_eod_chains(OptionsChains.symbol, date)
if not pydantic:
return options
if not options.chains.empty:
options.SYMBOLS = None
OptionsChainsPydantic = PydanticOptions(
chains=options.chains.to_dict(),
expirations=options.expirations,
strikes=options.strikes,
last_price=options.last_price,
underlying_name=options.underlying_name,
underlying_price=options.underlying_price.to_dict(),
hasIV=options.hasIV,
hasGreeks=options.hasGreeks,
symbol=options.symbol,
source=options.source,
date=options.date,
SYMBOLS=options.SYMBOLS,
)
return OptionsChainsPydantic
return OptionsChains
if symbol not in TICKER_EXCEPTIONS:
OptionsChains.underlying_price = get_underlying_price(OptionsChains.symbol)
OptionsChains.last_price = OptionsChains.underlying_price["lastPrice"]
OptionsChains.underlying_name = get_ticker_info(OptionsChains.symbol)["name"]
# If the ticker is an index, it will not return underlying data.
else:
print("Warning: Index options do not currently return underlying data.")
OptionsChains.underlying_name = OptionsChains.symbol
OptionsChains.underlying_price = pd.Series(dtype=object)
OptionsChains.last_price = 0
# If the symbol is an index, it needs to be preceded with, $.
if OptionsChains.symbol in TICKER_EXCEPTIONS:
OptionsChains.symbol = "$" + OptionsChains.symbol
chains = get_full_option_chain(OptionsChains.symbol)
chains.rename(columns={"code": "optionSymbol"}, inplace=True)
now = datetime.now()
temp = pd.DatetimeIndex(chains.expiration)
temp_ = (temp - now).days + 1
chains["dte"] = temp_
chains["close"] = round(chains["close"], 2)
chains = chains.set_index(["expiration", "strike", "optionType"]).sort_index()
OptionsChains.chains = chains.reset_index()
if not OptionsChains.chains.empty:
OptionsChains.expirations = OptionsChains.chains["expiration"].unique().tolist()
OptionsChains.strikes = (
OptionsChains.chains["strike"].sort_values().unique().tolist()
)
OptionsChains.hasIV = "impliedVolatility" in OptionsChains.chains.columns
OptionsChains.hasGreeks = "gamma" in OptionsChains.chains.columns
if pydantic is True:
OptionsChains.SYMBOLS = None
OptionsChainsPydantic = PydanticOptions(
chains=OptionsChains.chains.to_dict(),
expirations=OptionsChains.expirations,
strikes=OptionsChains.strikes,
last_price=OptionsChains.last_price,
underlying_name=OptionsChains.underlying_name,
underlying_price=OptionsChains.underlying_price.to_dict(),
hasIV=OptionsChains.hasIV,
hasGreeks=OptionsChains.hasGreeks,
symbol=OptionsChains.symbol,
source=OptionsChains.source,
SYMBOLS=OptionsChains.SYMBOLS,
)
return OptionsChainsPydantic
return OptionsChains
return None

View File

@@ -1,3 +1,5 @@
# mypy: disable-error-code=attr-defined
"""Nasdaq Model"""
__docformat__ = "numpy"
@@ -7,14 +9,17 @@ from typing import List
import numpy as np
import pandas as pd
import pandas_datareader
from openbb_terminal.decorators import log_start_end
from openbb_terminal.helper_funcs import request
from openbb_terminal.rich_config import console
from openbb_terminal.stocks.options.op_helpers import Options, PydanticOptions
logger = logging.getLogger(__name__)
# pylint: disable=unsupported-assignment-operation
call_cols = [
"c_Last",
"c_Bid",
@@ -216,6 +221,55 @@ def get_last_price(symbol: str) -> float:
return np.nan
@log_start_end(log=logger)
def get_underlying_price(symbol: str) -> pd.Series:
"""Get the last price from nasdaq
Parameters
----------
symbol: str
Symbol to get quote for
Returns
-------
float
Last price
"""
df = pd.Series(dtype=object)
for asset in ["stocks", "index", "etf"]:
url = f"https://api.nasdaq.com/api/quote/{symbol}/info?assetclass={asset}"
response_json = request(
url,
headers={
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)"
" AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.6 Safari/605.1.15"
},
).json()
if response_json["status"]["rCode"] == 200:
data = response_json["data"]
data = pd.Series(data)
df["companyName"] = data["companyName"]
df["price"] = float(
data["primaryData"]["lastSalePrice"].strip("$").replace(",", "")
)
df["change"] = float(data["primaryData"]["netChange"])
df["changePercent"] = float(
data["primaryData"]["percentageChange"].replace("%", "")
)
df["volume"] = data["primaryData"]["volume"].replace(",", "")
df["date"] = pd.to_datetime(
data["primaryData"]["lastTradeTimestamp"]
.replace("ET - PRE-MARKET", "")
.replace(" - AFTER HOURS", "")
.replace("ET", ""),
yearfirst=True,
).strftime("%Y-%m-%d")
return df.rename(symbol)
console.print(f"[red]Last price for {symbol} not found[/red]\n")
return pd.Series()
# Ugh this doesn't get the full chain
# TODO: apply CRR binomial tree to backtrack IV for greeks
@log_start_end(log=logger)
@@ -250,3 +304,196 @@ def get_option_greeks(symbol: str, expiration: str) -> pd.DataFrame:
console.print(f"[red]Greeks not found for {symbol} on {expiration}[/red].")
return pd.DataFrame()
def get_available_greeks(OptionsChains, expiration: str = "") -> pd.DataFrame:
"""Get available greeks for a specific expiration.
This function will return data for strike prices near the money only.
Parameters
----------
expiration: str
The expiration date to return the data. Default is the first available date. (YYYY-MM-DD)
Returns
-------
pd.DataFrame
Dataframe with option greeks and strike prices.
Examples
--------
Near-the-Money Greeks for the closest expiration date.
>>> greeks = self.get_available_greeks()
Get the last expiration date.
>>> greeks = self.get_available_greeks(self.expirations[-1])
"""
if expiration == "":
expiration = OptionsChains.expirations[0]
if expiration not in OptionsChains.expirations:
print(
f"{expiration}",
" is not a valid expiration. Choose from, ",
OptionsChains.expirations,
sep="",
)
return pd.DataFrame()
greeks = get_option_greeks(OptionsChains.symbol, expiration)
return greeks
@log_start_end(log=logger)
def load_options(symbol: str, pydantic: bool = False) -> object:
"""OptionsChains data object for Nasdaq.
Parameters
----------
symbol: str
The ticker symbol to load.
pydantic: bool
Whether to return the object as a Pydantic Model or a subscriptable Pandas Object. Default is False.
Returns
-------
object: Options
chains: dict
The complete options chain for the ticker. Returns as a Pandas DataFrame if pydantic is False.
expirations: list[str]
List of unique expiration dates. (YYYY-MM-DD)
strikes: list[float]
List of unique strike prices.
last_price: float
The last price of the underlying asset.
underlying_name: str
The name of the underlying asset.
underlying_price: dict
The price and recent performance of the underlying asset. Returns as a Pandas Series if pydantic is False.
hasIV: bool
Returns implied volatility.
hasGreeks: bool
Returns greeks data.
symbol: str
The symbol entered by the user.
source: str
The source of the data, "Nasdaq".
SYMBOLS: dict
The Nasdaq symbol directory. Returns as a Pandas DataFrame if pydantic is False.
Examples
--------
Get current options chains for AAPL.
>>> from openbb_terminal.stocks.options.nasdaq_model import load_options
>>> data = load_options("AAPL")
>>> chains = data.chains
Return the object as a Pydantic Model.
>>> from openbb_terminal.stocks.options.nasdaq_model import load_options
>>> data = load_options("AAPL", pydantic=True)
"""
symbol = symbol.upper()
OptionsChains = Options()
OptionsChains.source = "Nasdaq"
OptionsChains.SYMBOLS = pandas_datareader.nasdaq_trader.get_nasdaq_symbols()
OptionsChains.symbol = symbol
if (
OptionsChains.symbol not in OptionsChains.SYMBOLS.index
and OptionsChains.symbol != "NDX"
):
print(OptionsChains.symbol, "was not found in the Nasdaq directory")
return OptionsChains
OptionsChains.symbol = symbol
try:
OptionsChains.chains = get_full_option_chain(OptionsChains.symbol)
now = datetime.now()
temp = pd.DatetimeIndex(OptionsChains.chains.expiration)
temp_ = (temp - now).days + 1
OptionsChains.chains["dte"] = temp_
except Exception:
return OptionsChains
if not OptionsChains.chains.empty:
OptionsChains.expirations = option_expirations(OptionsChains.symbol)
OptionsChains.strikes = (
pd.Series(OptionsChains.chains["strike"]).sort_values().unique().tolist()
)
OptionsChains.underlying_price = get_underlying_price(OptionsChains.symbol)
OptionsChains.last_price = OptionsChains.underlying_price["price"]
OptionsChains.underlying_name = OptionsChains.underlying_price["companyName"]
OptionsChains.hasIV = "impliedVolatility" in OptionsChains.chains.columns
OptionsChains.hasGreeks = "gamma" in OptionsChains.chains.columns
def get_greeks(expiration: str = ""):
"""Get available greeks for a specific expiration.
This function will return data for strike prices near the money only.
Parameters
----------
expiration: str
The expiration date to return the data. Default is the first available date. (YYYY-MM-DD)
Returns
-------
pd.DataFrame
Dataframe with option greeks and strike prices.
Examples
--------
Near-the-Money Greeks for the closest expiration date.
>>> greeks = self.get_available_greeks()
Get the last expiration date.
>>> greeks = self.get_available_greeks(self.expirations[-1])
"""
if expiration == "":
expiration = OptionsChains.expirations[0]
if expiration not in OptionsChains.expirations:
print(
f"{expiration}",
" is not a valid expiration. Choose from, ",
OptionsChains.expirations,
sep="",
)
return pd.DataFrame()
return get_option_greeks(OptionsChains.symbol, expiration)
if not OptionsChains.chains.empty:
if OptionsChains.last_price is None:
OptionsChains.last_price = 0
print("No last price for " + OptionsChains.symbol)
if not pydantic:
setattr(OptionsChains, "get_available_greeks", get_greeks)
return OptionsChains
OptionsChainsPydantic = PydanticOptions(
chains=OptionsChains.chains.to_dict(),
expirations=OptionsChains.expirations,
strikes=OptionsChains.strikes,
last_price=OptionsChains.last_price,
underlying_name=OptionsChains.underlying_name,
underlying_price=OptionsChains.underlying_price.to_dict(),
hasIV=OptionsChains.hasIV,
hasGreeks=OptionsChains.hasGreeks,
symbol=OptionsChains.symbol,
source=OptionsChains.source,
SYMBOLS=OptionsChains.SYMBOLS.to_dict(),
)
setattr(OptionsChainsPydantic, "get_available_greeks", get_greeks)
return OptionsChainsPydantic
return None

View File

@@ -8,6 +8,7 @@ from typing import Optional, Tuple, Union
import numpy as np
import pandas as pd
from pydantic import BaseModel, Extra, Field
from scipy.stats import norm
from openbb_terminal.decorators import log_start_end
@@ -608,3 +609,98 @@ def get_dte(chain: pd.DataFrame) -> pd.DataFrame:
chain["dte"] = temp_
return chain
class Options: # pylint: disable=too-few-public-methods,too-many-instance-attributes
"""The Options data object.
Returns
-------
object: Options
chains: pd.DataFrame
The complete options chain for the ticker.
expirations: list[str]
List of unique expiration dates. (YYYY-MM-DD)
strikes: list[float]
List of unique strike prices.
last_price: float
The last price of the underlying asset.
underlying_name: str
The name of the underlying asset.
underlying_price: pd.Series
The price and recent performance of the underlying asset.
hasIV: bool
Returns implied volatility.
hasGreeks: bool
Returns greeks data.
symbol: str
The symbol entered by the user.
source: str
The source of the data.
date: str
The date, when the chains data is historical EOD.
SYMBOLS: pd.DataFrame
The symbol directory for the source, when available.
"""
chains = pd.DataFrame
expirations: list
strikes: list
last_price: float
underlying_name: str
underlying_price: pd.Series
hasIV: bool
hasGreeks: bool
symbol: str
source: str
date: str
SYMBOLS: pd.DataFrame
class PydanticOptions( # type: ignore [call-arg]
BaseModel, extra=Extra.allow
): # pylint: disable=too-few-public-methods
"""Pydantic model for the Options data object.
Returns
-------
Pydantic: Options
chains: dict
The complete options chain for the ticker.
expirations: list[str]
List of unique expiration dates. (YYYY-MM-DD)
strikes: list[float]
List of unique strike prices.
last_price: float
The last price of the underlying asset.
underlying_name: str
The name of the underlying asset.
underlying_price: dict
The price and recent performance of the underlying asset.
hasIV: bool
Returns implied volatility.
hasGreeks: bool
Returns greeks data.
symbol: str
The symbol entered by the user.
source: str
The source of the data.
date: str
The date, when the chains data is historical EOD.
SYMBOLS: dict
The symbol directory for the source, when available.
"""
chains: dict = Field(default=None)
expirations: list = Field(default=None)
strikes: list = Field(default=None)
last_price: float = Field(default=None)
underlying_name: str = Field(default=None)
underlying_price: dict = Field(default=None)
hasIV: bool = Field(default=False)
hasGreeks: bool = Field(default=False)
symbol: str = Field(default=None)
source: str = Field(default=None)
date: str = Field(default=None)
SYMBOLS: dict = Field(default=None)

File diff suppressed because it is too large Load Diff

View File

@@ -199,7 +199,9 @@ class OptionsController(BaseController):
last_price = tradier_model.get_last_price(self.ticker)
self.current_price = last_price or 0.0
elif self.source == "Nasdaq":
self.current_price = nasdaq_model.get_last_price(self.ticker)
self.current_price = nasdaq_model.get_underlying_price(self.ticker)[
"lastPrice"
]
elif self.source == "Intrinio":
self.current_price = intrinio_model.get_last_price(self.ticker)
else:

View File

@@ -19,6 +19,7 @@ from openbb_terminal.stocks.options import (
yfinance_model,
)
from openbb_terminal.stocks.options.op_helpers import Option
from openbb_terminal.stocks.options.options_chains_model import OptionsChains
logger = logging.getLogger(__name__)
@@ -36,7 +37,7 @@ def get_full_option_chain(
symbol : str
Symbol to get chain for
source : str, optional
Source to get data from, by default "Nasdaq". Can be YahooFinance, Tradier, Nasdaq, or Intrinio
Source to get data from, by default "Nasdaq". Can be YahooFinance, Tradier, Nasdaq, Intrinio, or TMX.
expiration : Union[str, None], optional
Date to get chain for. By default returns all dates
@@ -63,12 +64,12 @@ def get_full_option_chain(
elif source == "nasdaq":
df = nasdaq_model.get_full_option_chain(symbol)
elif source == "yahoofinance":
df = yfinance_model.get_full_option_chain(symbol)
elif source == "intrinio":
df = intrinio_model.get_full_option_chain(symbol)
else:
df = yfinance_model.get_full_option_chain(symbol)
if not isinstance(df, pd.DataFrame) or df.empty:
logger.info("Invalid Source or Symbol")
console.print("Invalid Source or Symbol")
@@ -312,3 +313,98 @@ def get_greeks(
df = pd.DataFrame(strikes, columns=columns)
return df
def load_options_chains(
symbol: str, source: str = "CBOE", date: str = "", pydantic: bool = False
) -> object:
"""Loads all options chains from a specific source, fields returned to each attribute will vary.
Parameters
----------
symbol: str
The ticker symbol to load the data for.
source: str
The source for the data. Defaults to "CBOE". ["CBOE", "Intrinio", "Nasdaq", "TMX", "Tradier", "YahooFinance"]
date: str
The date for EOD chains data. Only available for "Intrinio" and "TMX".
pydantic: bool
Whether to return as a Pydantic Model or as a Pandas object. Defaults to False.
Returns
-------
Object: Options
chains: pd.DataFrame
The complete options chain for the ticker.
expirations: list[str]
List of unique expiration dates. (YYYY-MM-DD)
strikes: list[float]
List of unique strike prices.
last_price: float
The last price of the underlying asset.
underlying_name: str
The name of the underlying asset.
underlying_price: pd.Series
The price and recent performance of the underlying asset.
hasIV: bool
Returns implied volatility.
hasGreeks: bool
Returns greeks data.
symbol: str
The symbol entered by the user.
source: str
The source of the data.
date: str
The date, when the chains data is historical EOD.
SYMBOLS: pd.DataFrame
The symbol directory for the source, when available.
Methods
-------
get_stats: Callable
Function to return a table of summary statistics, by strike or by expiration.
get_straddle: Callable
Function to calculate straddles and the payoff profile.
get_strangle: Callable
Function to calculate strangles and the payoff profile.
get_vertical_call_spread: Callable
Function to calculate vertical call spreads.
get_vertical_put_spreads: Callable
Function to calculate vertical put spreads.
get_strategies: Callable
Function for calculating multiple straddles and strangles at different expirations and moneyness.
Examples
--------
Loads SPY data from CBOE, returns as a Pydantic Model, and displays the longest-dated expiration chain.
>>> from openbb_terminal.sdk import openbb
>>> import pandas as pd
>>> data = openbb.stocks.options.load_options_chains("SPY", pydantic = True)
>>> chains = pd.DataFrame(data.chains)
>>> chains[chains["expiration"] == data.expirations[-1]]
Loads QQQ data from Tradier as a Pydantic Model.
>>> from openbb_terminal.sdk import openbb
>>> data = openbb.stocks.options.load_options_chains("QQQ", source = "Tradier", pydantic = True)
Loads VIX data from YahooFinance as a Pandas object.
>>> from openbb_terminal.sdk import openbb
>>> data = openbb.stocks.options.load_options_chains("^VIX", source = "YahooFinance")
Loads XIU data from TMX and displays the 25 highest open interest options.
>>> from openbb_terminal.sdk import openbb
>>> data = openbb.stocks.options.load_options_chains("XIU", "TMX")
>>> data.chains.sort_values("openInterest", ascending=False).head(25)
Loads the EOD chains data for XIU.TO from March 15, 2020, sorted by number of transactions.
>>> from openbb_terminal.sdk import openbb
>>> data = openbb.stocks.options.load_options_chains("XIU.TO", "TMX", "2020-03-15")
>>> data.chains.sort_values("transactions", ascending=False).head(25)
"""
return OptionsChains(symbol, source, date, pydantic)

View File

@@ -0,0 +1,591 @@
# mypy: disable-error-code=attr-defined
"""Model for retrieving public options data from the Montreal OptionsChains Exchange."""
from datetime import datetime, timedelta
import pandas as pd
import pandas_market_calendars as mcal
from pandas.tseries.holiday import next_workday
from openbb_terminal.helper_funcs import request
from openbb_terminal.stocks.options.op_helpers import Options, PydanticOptions
__docformat__ = "numpy"
cal = mcal.get_calendar(name="TSX")
holidays = list(cal.regular_holidays.holidays().strftime("%Y-%m-%d"))
def check_weekday(date) -> str:
"""Helper function to check if the input date is a weekday, and if not, returns the next weekday.
Parameters
----------
date: str
The date to check in YYYY-MM-DD format.
Returns
-------
str
Date in YYYY-MM-DD format. If the date is a weekend, returns the date of the next weekday.
Examples
--------
>>> from openbb_terminal.stocks.options import tmx_model
>>> tmx_model.check_weekday("2023-05-20")
>>> tmx_model.check_weekday("2023-05-22")
"""
if pd.to_datetime(date).weekday() not in range(0, 5):
date_ = next_workday(pd.to_datetime(date)).strftime("%Y-%m-%d")
date = date_
return date
def get_all_ticker_symbols() -> pd.DataFrame:
"""Returns a DataFrame with all valid ticker symbols."""
options_listings = pd.read_html("https://www.m-x.ca/en/trading/data/options-list")
listings = pd.concat(options_listings)
listings = listings.set_index("Option Symbol").drop_duplicates().sort_index()
symbols = listings[:-1]
symbols = symbols.fillna(value="")
symbols["Underlying Symbol"] = (
symbols["Underlying Symbol"].str.replace(" u", ".UN").str.replace("––", "")
)
return symbols
SYMBOLS = get_all_ticker_symbols()
def get_underlying_price(symbol: str) -> pd.Series:
"""Gets the current price and performance of the underlying asset from the Canadian Securities Exchange.
Note: Volume is CSE only and is not a consolidated value.
Parameters
----------
symbol: str
The ticker symbol of the underlying asset.
Returns
-------
pd.Series
Series of the current price and performance of the underlying asset.
"""
data = pd.Series(dtype=object)
symbol = symbol.upper()
URL = f"https://webapi.thecse.com/trading/other/securities/{symbol}.json"
response = request(URL)
if response.status_code != 200:
print("No price data found for the underlying security, " f"{symbol}")
return data
data = response.json()["ticker"]
data = (
pd.Series(data)
.rename(f"{symbol}")
.drop(["Composite Index Contribution", "CSE25 Index Contribution"])
)
data.rename(
{
"Previous Closing Price": "previousClose",
"Trade Count": "transactions",
"Trading Volume": "volume",
"Trading Value": "value",
"Trading Value (CAD)": "valueCAD",
"Opening Price": "open",
"Last Price": "price",
"Net Change": "change",
"Net Change Percentage": "changePercent",
"Days Low Price": "low",
"Days High Price": "high",
"Days VWAP": "vwap",
"Last Tick": "tick",
"52 Week High": "fiftyTwoWeekHigh",
"52 Week Low": "fiftyTwoWeekLow",
"Time": "time",
},
inplace=True,
)
return data
def check_symbol(symbol: str) -> bool:
"""Checks if the symbol is valid. This function is used as an internal helper.
Parameters
----------
symbol: str
The ticker symbol to check.
Returns
-------
bool: True if the symbol is valid, False otherwise.
Examples
--------
>>> from openbb_terminal.stocks.options import tmx_model
>>> tmx_model.check_symbol("AC")
>>> tmx_model.check_symbol("SPX")
"""
symbol = symbol.upper()
return len(SYMBOLS.query("`Underlying Symbol` == @symbol")) == 1
def get_chains(symbol: str = "") -> object:
"""Gets the current quotes for the complete options chain.
No implied volatility is returned from this method.
Use `get_eodchains()` to get the implied volatility.
Parameters
----------
symbol: str
The ticker symbol of the underlying asset.
Returns
-------
object: OptionsChains
chains: pd.DataFrame
The complete options chain for the ticker.
expirations: list[str]
List of unique expiration dates. (YYYY-MM-DD)
strikes: list[float]
List of unique strike prices.
last_price: float
The last price of the underlying asset.
underlying_name: str
The name of the underlying asset.
underlying_price: pd.Series
The price and recent performance of the underlying asset.
hasIV: bool
Returns implied volatility.
hasGreeks: bool
Returns greeks data.
symbol: str
The symbol entered by the user.
source: str
The source of the data, "TMX".
SYMBOLS: pd.DataFrame
TMX symbol directory.
Example
-------
>>> from openbb_terminal.stocks.options import tmx_model
>>> ticker = tmx_model.get_quotes("AC")
>>> chains = ticker.chains
"""
OptionsChains = Options()
OptionsChains.SYMBOLS = SYMBOLS
OptionsChains.source = "TMX"
if symbol == "":
print("Please enter a symbol.")
return OptionsChains
symbol = symbol.upper()
if ".TO" in symbol:
symbol = symbol.replace(".TO", "")
if check_symbol(symbol):
symbol = list(SYMBOLS.query("`Underlying Symbol` == @symbol").index.values)[0]
if symbol not in OptionsChains.SYMBOLS.index:
print(
"The symbol, " f"{symbol}" ", is not a valid TMX listing.",
sep=None,
)
return OptionsChains
OptionsChains.symbol = symbol
QUOTES_URL = (
"https://www.m-x.ca/en/trading/data/quotes?symbol="
f"{OptionsChains.symbol}"
"*"
)
cols = [
"expiration",
"strike",
"bid",
"ask",
"lastPrice",
"change",
"openInterest",
"volume",
"optionType",
]
data = pd.DataFrame()
data = pd.read_html(QUOTES_URL)[0]
data = data.iloc[:-1]
expirations = (
data["Unnamed: 0_level_0"]["Expiry date"].astype(str).rename("expiration")
)
expirations = expirations.str.strip("(Weekly)")
OptionsChains.expirations = list(
pd.DatetimeIndex(expirations.unique()).astype(str).sort_values()
)
strikes = (data["Unnamed: 7_level_0"].dropna().sort_values("Strike")).rename(
columns={"Strike": "strike"}
)
OptionsChains.strikes = list(strikes["strike"].unique())
calls = pd.concat([expirations, strikes, data["Calls"]], axis=1)
calls["expiration"] = pd.DatetimeIndex(calls["expiration"]).astype(str)
calls["optionType"] = "call"
calls.columns = cols
calls = calls.set_index(["expiration", "strike", "optionType"])
puts = pd.concat([expirations, strikes, data["Puts"]], axis=1)
puts["expiration"] = pd.DatetimeIndex(puts["expiration"]).astype(str)
puts["optionType"] = "put"
puts.columns = cols
puts = puts.set_index(["expiration", "strike", "optionType"])
chains = pd.concat([calls, puts])
chains["openInterest"] = chains["openInterest"].astype(int)
chains["volume"] = chains["volume"].astype(int)
chains["change"] = chains["change"].astype(float)
chains["lastPrice"] = chains["lastPrice"].astype(float)
chains["bid"] = chains["bid"].astype(float)
chains["ask"] = chains["ask"].astype(float)
chains = chains.sort_index()
chains = chains.reset_index()
now = datetime.now()
temp = pd.DatetimeIndex(chains.expiration)
temp_ = (temp - now).days + 1
chains["dte"] = temp_
OptionsChains.chains = chains
OptionsChains.underlying_name = OptionsChains.SYMBOLS.loc[OptionsChains.symbol][
"Name of Underlying Instrument"
]
try:
OptionsChains.underlying_price = get_underlying_price(OptionsChains.symbol)
OptionsChains.last_price = OptionsChains.underlying_price["price"]
except TypeError:
OptionsChains.last_price = 0
OptionsChains.underlying_price = 0
OptionsChains.hasIV = "impliedVolatility" in OptionsChains.chains.columns
OptionsChains.hasGreeks = "gamma" in OptionsChains.chains.columns
return OptionsChains
def get_eodchains(symbol: str = "", date: str = "") -> object:
"""Gets the complete options chain for the EOD on a specific date.
Open Interest values are from the previous day.
Parameters
----------
symbol: str
The ticker symbol of the underlying asset.
date: str
The date to get the EOD chain for. Formatted as YYYY-MM-DD.
Returns
-------
object: Options
chains: pd.DataFrame
The complete options chain for the ticker.
expirations: list[str]
List of unique expiration dates. (YYYY-MM-DD)
strikes: list[float]
List of unique strike prices.
last_price: float
The last price of the underlying asset.
underlying_name: str
The name of the underlying asset.
underlying_price: pd.Series
The price and recent performance of the underlying asset.
hasIV: bool
Returns implied volatility.
hasGreeks: bool
Returns greeks data.
symbol: str
The symbol entered by the user.
source: str
The source of the data, "TMX".
date: str
The date, if applicable, for the EOD chains data. (YYYY-MM-DD)
SYMBOLS: pd.DataFrame
TMX symbol directory.
Examples
--------
>>> from openbb_terminal.stocks.options import tmx_model
>>> xiu = tmx_model.get_eodchains("XIU", "2009-01-01")
>>> chains = xiu.chains
"""
OptionsChains = Options()
OptionsChains.SYMBOLS = SYMBOLS
OptionsChains.source = "TMX"
symbol = symbol.upper()
BASE_URL = "https://www.m-x.ca/en/trading/data/historical?symbol="
if symbol == "":
print("Please enter a symbol.")
return OptionsChains
if ".TO" in symbol:
symbol = symbol.replace(".TO", "")
if symbol not in OptionsChains.SYMBOLS.index:
print(
"The symbol, " f"{symbol}" ", was not found in the TMX listings.",
sep=None,
)
return OptionsChains
OptionsChains.symbol = symbol.upper()
if date == "":
EOD_URL = BASE_URL + f"{OptionsChains.symbol}" "&dnld=1#quotes"
if date != "":
if pd.to_datetime(date) < pd.to_datetime("2009-01-01"):
print("Historical options data begins on 2009-01-02.")
date = check_weekday(date)
if date in holidays:
date = (pd.to_datetime(date) + timedelta(days=1)).strftime("%Y-%m-%d")
date = check_weekday(date)
if date in holidays:
date = (pd.to_datetime(date) + timedelta(days=1)).strftime("%Y-%m-%d")
EOD_URL = (
BASE_URL + f"{OptionsChains.symbol}"
"&from="
f"{date}"
"&to="
f"{date}"
"&dnld=1#quotes"
)
data = pd.read_csv(EOD_URL)
if data.empty:
print(
"No data found. Check the date to ensure the ticker was listed before that date."
)
return OptionsChains
OptionsChains.date = str(date)
contractSymbol = []
for i in data.index:
contractSymbol.append(data["Symbol"].iloc[i].replace(" ", ""))
data["contractSymbol"] = contractSymbol
data["optionType"] = data["Call/Put"].replace(0, "call").replace(1, "put")
data = data.drop(
columns=[
"Symbol",
"Class Symbol",
"Root Symbol",
"Underlying Symbol",
"Ins. Type",
"Call/Put",
]
)
cols = [
"date",
"strike",
"expiration",
"bid",
"ask",
"bidSize",
"askSize",
"lastPrice",
"volume",
"previousClose",
"change",
"open",
"high",
"low",
"totalValue",
"transactions",
"settlementPrice",
"openInterest",
"impliedVolatility",
"contractSymbol",
"optionType",
]
data.columns = cols
OptionsChains.expirations = list(
pd.DatetimeIndex(data["expiration"].iloc[1:].unique()).astype(str)
)
OptionsChains.strikes = list(data["strike"].iloc[1:].unique())
data["expiration"] = pd.to_datetime(data["expiration"], format="%Y-%m-%d")
data["date"] = pd.to_datetime(data["date"], format="%Y-%m-%d")
data["impliedVolatility"] = 0.01 * data["impliedVolatility"]
date_ = pd.to_datetime(date, format="%Y-%m-%d")
temp = pd.DatetimeIndex(data.expiration)
temp_ = pd.Series((temp - date_).days)
data["dte"] = pd.to_numeric(temp_)
data = data.set_index(["expiration", "strike", "optionType"])
data = data.sort_index()
data["date"] = data["date"].astype(str)
OptionsChains.underlying_name = OptionsChains.SYMBOLS.loc[OptionsChains.symbol][
"Name of Underlying Instrument"
]
OptionsChains.chains = data.reset_index()
underlying_price = (
OptionsChains.chains.iloc[-1].drop(
index=[
"impliedVolatility",
"strike",
"optionType",
"settlementPrice",
"openInterest",
"expiration",
"dte",
]
)
).rename(f"{OptionsChains.underlying_name}")
underlying_price.rename(
{
"lastPrice": "price",
"totalValue": "valueCAD",
"transactions": "transactions",
"contractSymbol": "symbol",
},
inplace=True,
)
OptionsChains.underlying_price = underlying_price
OptionsChains.last_price = underlying_price["price"]
OptionsChains.chains = OptionsChains.chains.iloc[:-1]
OptionsChains.chains.dte = OptionsChains.chains.dte.astype(int)
OptionsChains.hasIV = "impliedVolatility" in OptionsChains.chains.columns
OptionsChains.hasGreeks = "gamma" in OptionsChains.chains.columns
return OptionsChains
def load_options(symbol: str, date: str = "", pydantic: bool = False) -> object:
"""Options data object for TMX.
Parameters
----------
symbol : str
The ticker symbol to load.
date: Optional[str]
The date for EOD chains data.
pydantic: bool
Whether to return the object as a Pydantic Model or a subscriptable Pandas Object. Default is False.
Returns
-------
object: Options
chains: pd.DataFrame
The complete options chain for the ticker. Returns a dictionary if pydantic is True.
expirations: list[str]
List of unique expiration dates. (YYYY-MM-DD)
strikes: list[float]
List of unique strike prices.
last_price: float
The last price of the underlying asset.
underlying_name: str
The name of the underlying asset.
underlying_price: pd.Series
The price and recent performance of the underlying asset. Returns a dictionary if pydantic is True.
hasIV: bool
Returns implied volatility.
hasGreeks: bool
Returns greeks data.
symbol: str
The symbol entered by the user.
source: str
The source of the data, "TMX".
date: str
The date, if applicable, for the EOD chains data. (YYYY-MM-DD)
SYMBOLS: pd.DataFrame
TMX symbol directory. Returns a dictionary if pydantic is True.
Examples
--------
Get current options chains for RY.
>>> from openbb_terminal.stocks.options.tmx_model import load_options
>>> data = load_options("RY")
>>> chains = data.chains
Get options chains for RY for a specific date.
>>> from openbb_terminal.stocks.options.tmx_model import load_options
>>> data = load_options("RY", "2022-01-03")
>>> chains = data.chains
Return the object as a Pydantic Model.
>>> from openbb_terminal.stocks.options.tmx_model import load_options
>>> data = load_options("RY", pydantic=True)
"""
if date != "":
OptionsChainsEOD = get_eodchains(symbol, date)
if not pydantic:
return OptionsChainsEOD
if not OptionsChainsEOD.chains.empty:
OptionsChainsPydantic = PydanticOptions(
chains=OptionsChainsEOD.chains.to_dict(),
expirations=OptionsChainsEOD.expirations,
strikes=OptionsChainsEOD.strikes,
last_price=OptionsChainsEOD.last_price,
underlying_name=OptionsChainsEOD.underlying_name,
underlying_price=OptionsChainsEOD.underlying_price.to_dict(),
hasIV=OptionsChainsEOD.hasIV,
hasGreeks=OptionsChainsEOD.hasGreeks,
symbol=OptionsChainsEOD.symbol,
source=OptionsChainsEOD.source,
date=OptionsChainsEOD.date,
SYMBOLS=OptionsChainsEOD.SYMBOLS.to_dict(),
)
return OptionsChainsPydantic
return None
OptionsChainsChains = get_chains(symbol)
if not pydantic:
return OptionsChainsChains
if not OptionsChainsChains.chains.empty:
OptionsChainsPydantic = PydanticOptions(
chains=OptionsChainsChains.chains.to_dict(),
expirations=OptionsChainsChains.expirations,
strikes=OptionsChainsChains.strikes,
last_price=OptionsChainsChains.last_price,
underlying_name=OptionsChainsChains.underlying_name,
underlying_price=OptionsChainsChains.underlying_price.to_dict(),
hasIV=OptionsChainsChains.hasIV,
hasGreeks=OptionsChainsChains.hasGreeks,
symbol=OptionsChainsChains.symbol,
source=OptionsChainsChains.source,
SYMBOLS=OptionsChainsChains.SYMBOLS.to_dict(),
)
return OptionsChainsPydantic
return None

View File

@@ -1,7 +1,10 @@
# mypy: disable-error-code=attr-defined
"""Tradier options model"""
__docformat__ = "numpy"
import logging
from datetime import datetime
from typing import List, Optional
import pandas as pd
@@ -11,6 +14,7 @@ from openbb_terminal.core.session.current_user import get_current_user
from openbb_terminal.decorators import check_api_key, log_start_end
from openbb_terminal.helper_funcs import request
from openbb_terminal.rich_config import console, optional_rich_track
from openbb_terminal.stocks.options.op_helpers import Options, PydanticOptions
logger = logging.getLogger(__name__)
@@ -57,6 +61,19 @@ sorted_chain_columns = [
]
@check_api_key(["API_TRADIER_TOKEN"])
def lookup_company(symbol: str):
response = request(
"https://sandbox.tradier.com/v1/markets/lookup",
params={"q": f"{symbol}"},
headers={
"Authorization": f"Bearer {get_current_user().credentials.API_TRADIER_TOKEN }", # type: ignore[attr-defined]
"Accept": "application/json",
},
)
return response.json()
@log_start_end(log=logger)
@check_api_key(["API_TRADIER_TOKEN"])
def get_historical_options(
@@ -173,12 +190,17 @@ def get_full_option_chain(symbol: str, quiet: bool = False) -> pd.DataFrame:
chain = pd.concat(options_dfs)
chain = chain[sorted_chain_columns].rename(
columns={
"mid_iv": "iv",
"mid_iv": "impliedVolatility",
"open_interest": "openInterest",
"option_type": "optionType",
"symbol": "optionSymbol",
}
)
return chain
chain["openInterest"] = chain["openInterest"].astype(int)
chain["volume"] = chain["volume"].astype(int)
chain = chain.set_index(["expiration", "strike", "optionType"]).sort_index()
return chain.reset_index()
@log_start_end(log=logger)
@@ -200,7 +222,7 @@ def option_expirations(symbol: str) -> List[str]:
"https://sandbox.tradier.com/v1/markets/options/expirations",
params={"symbol": symbol, "includeAllRoots": "true", "strikes": "false"},
headers={
"Authorization": f"Bearer {get_current_user().credentials.API_TRADIER_TOKEN}",
"Authorization": f"Bearer {get_current_user().credentials.API_TRADIER_TOKEN}", # type: ignore[attr-defined]
"Accept": "application/json",
},
)
@@ -237,7 +259,7 @@ def get_option_chain(symbol: str, expiry: str) -> pd.DataFrame:
params = {"symbol": symbol, "expiration": expiry, "greeks": "true"}
headers = {
"Authorization": f"Bearer {get_current_user().credentials.API_TRADIER_TOKEN}",
"Authorization": f"Bearer {get_current_user().credentials.API_TRADIER_TOKEN}", # type: ignore[attr-defined]
"Accept": "application/json",
}
@@ -311,7 +333,7 @@ def get_last_price(symbol: str):
"https://sandbox.tradier.com/v1/markets/quotes",
params={"symbols": symbol, "includeAllRoots": "true", "strikes": "false"},
headers={
"Authorization": f"Bearer {get_current_user().credentials.API_TRADIER_TOKEN}",
"Authorization": f"Bearer {get_current_user().credentials.API_TRADIER_TOKEN}", # type: ignore[attr-defined]
"Accept": "application/json",
},
)
@@ -323,3 +345,224 @@ def get_last_price(symbol: str):
else:
console.print("Error getting last price")
return None
@check_api_key(["API_TRADIER_TOKEN"])
def get_underlying_price(symbol: str) -> pd.Series:
"""Gets the current price and performance of the underlying asset.
Parameters
----------
symbol: str
Ticker symbol
Returns
-------
pd.Series:
Series of current price and performance of the underlying asset.
"""
r = request(
"https://sandbox.tradier.com/v1/markets/quotes",
params={"symbols": symbol, "includeAllRoots": "true", "strikes": "false"},
headers={
"Authorization": f"Bearer {get_current_user().credentials.API_TRADIER_TOKEN}", # type: ignore[attr-defined]
"Accept": "application/json",
},
)
if r.status_code != 200:
console.print("Error getting last price")
return pd.DataFrame()
underlying_price = pd.Series(dtype=object)
underlying_price = pd.Series(r.json()["quotes"]["quote"])
underlying_price = underlying_price.rename(
index={
"description": "name",
"change_percentage": "changePercent",
"average_volume": "avgVolume",
"last_volume": "volume",
"trade_date": "lastTradeTimestamp",
"prevclose": "previousClose",
"week_52_high": "fiftyTwoWeekHigh",
"week_52_low": "fiftyTwoWeekLow",
"bidsize": "bidSize",
"bidexch": "bidExchange",
"bid_date": "bidDate",
"asksize": "askSize",
"askexch": "askExchange",
"ask_date": "askDate",
"root_symbols": "rootSymbols",
}
)
underlying_price[
"lastTradeTimestamp"
] = ( # pylint: disable=unsupported-assignment-operation
pd.to_datetime(underlying_price["lastTradeTimestamp"], unit="ms").tz_localize(
"EST"
)
).strftime(
"%Y-%m-%d"
)
underlying_price["bidDate"] = ( # pylint: disable=unsupported-assignment-operation
pd.to_datetime(underlying_price["bidDate"], unit="ms").tz_localize("EST")
).strftime("%Y-%m-%d")
underlying_price["askDate"] = ( # pylint: disable=unsupported-assignment-operation
pd.to_datetime(underlying_price["askDate"], unit="ms").tz_localize("EST")
).strftime("%Y-%m-%d")
return underlying_price
def get_chains(symbol: str) -> object:
"""OptionsChains data object for Tradier.
Parameters
----------
symbol : str
The ticker symbol to load.
Returns
-------
object: OptionsChains
chains: pd.DataFrame
The complete options chain for the ticker.
expirations: list[str]
List of unique expiration dates. (YYYY-MM-DD)
strikes: list[float]
List of unique strike prices.
last_price: float
The last price of the underlying asset.
underlying_name: str
The name of the underlying asset.
underlying_price: pd.Series
The price and recent performance of the underlying asset.
hasIV: bool
Returns implied volatility.
hasGreeks: bool
Returns greeks data.
symbol: str
The symbol entered by the user.
source: str
The source of the data, "Tradier".
SYMBOLS: pd.DataFrame
Tradier symbol directory.
Examples
--------
>>> from openbb_terminal.stocks.options import tradier_model
>>> data = tradier_model.load_options("AAPL")
>>> chains = tradier_model.chains
"""
OptionsChains = Options()
OptionsChains.source = "Tradier"
try:
OptionsChains.SYMBOLS = pd.DataFrame(
lookup_company("")["securities"]["security"]
)
except requests.exceptions.JSONDecodeError:
return OptionsChains
OptionsChains.symbol = symbol.upper()
if OptionsChains.symbol not in list(OptionsChains.SYMBOLS["symbol"]):
print(f"{OptionsChains.symbol} is not support by Tradier.")
return OptionsChains
OptionsChains.underlying_price = get_underlying_price(OptionsChains.symbol)
OptionsChains.underlying_name = OptionsChains.underlying_price["name"]
OptionsChains.last_price = OptionsChains.underlying_price["last"]
chains = get_full_option_chain(OptionsChains.symbol)
if not chains.empty:
OptionsChains.expirations = chains["expiration"].unique().tolist()
OptionsChains.strikes = chains["strike"].sort_values().unique().tolist()
now = datetime.now()
temp = pd.DatetimeIndex(chains.expiration)
temp_ = (temp - now).days + 1
chains["dte"] = temp_
OptionsChains.chains = chains
OptionsChains.hasIV = "impliedVolatility" in OptionsChains.chains.columns
OptionsChains.hasGreeks = "gamma" in OptionsChains.chains.columns
return OptionsChains
def load_options(symbol: str, pydantic: bool = False) -> object:
"""OptionsChains data object for Tradier.
Parameters
----------
symbol: str
The ticker symbol to load.
pydantic: bool
Whether to return the object as a Pydantic Model or a subscriptable Pandas Object. Default is False.
Returns
-------
object: Options
chains: pd.DataFrame
The complete options chain for the ticker. Returns as a dictionary if pydantic is True.
expirations: list[str]
List of unique expiration dates. (YYYY-MM-DD)
strikes: list[float]
List of unique strike prices.
last_price: float
The last price of the underlying asset.
underlying_name: str
The name of the underlying asset.
underlying_price: pd.Series
The price and recent performance of the underlying asset. Returns as a dictionary if pydantic is True.
hasIV: bool
Returns implied volatility.
hasGreeks: bool
Returns greeks data.
symbol: str
The symbol entered by the user.
source: str
The source of the data, "Tradier".
SYMBOLS: pd.DataFrame
Tradier symbol directory. Returns as a dictionary if pydantic is True.
Examples
--------
Get current options chains for AAPL.
>>> from openbb_terminal.stocks.options.tradier_model import load_options
>>> data = load_options("AAPL")
>>> chains = data.chains
Return the object as a Pydantic Model.
>>> from openbb_terminal.stocks.options.tradier_model import load_options
>>> data = load_options("AAPL", pydantic=True)
"""
options = get_chains(symbol)
if options.last_price is None:
options.last_price = 0
print("No last price for " + options.symbol)
if not pydantic:
return options
if not options.chains.empty:
OptionsChainsPydantic = PydanticOptions(
chains=options.chains.to_dict(),
expirations=options.expirations,
strikes=options.strikes,
last_price=options.last_price,
underlying_name=options.underlying_name,
underlying_price=options.underlying_price.to_dict(),
hasIV=options.hasIV,
hasGreeks=options.hasGreeks,
symbol=options.symbol,
source=options.source,
SYMBOLS=options.SYMBOLS.to_dict(),
)
return OptionsChainsPydantic
return None

View File

@@ -1,3 +1,5 @@
# mypy: disable-error-code=attr-defined
"""Yfinance options model"""
__docformat__ = "numpy"
@@ -10,6 +12,7 @@ import yfinance as yf
from openbb_terminal.decorators import log_start_end
from openbb_terminal.rich_config import console, optional_rich_track
from openbb_terminal.stocks.options.op_helpers import Options, PydanticOptions
logger = logging.getLogger(__name__)
@@ -82,8 +85,8 @@ def get_option_chain(symbol: str, expiry: str):
Returns
-------
chains: yf.ticker.Options
Options chain
chains: yf.ticker.OptionsChains
OptionsChains chain
"""
yf_ticker = yf.Ticker(symbol)
@@ -286,8 +289,8 @@ def get_iv_surface(symbol: str) -> pd.DataFrame:
@log_start_end(log=logger)
def get_last_price(symbol: str) -> float:
"""Get the last price from nasdaq
def get_last_price(symbol: str) -> pd.Series:
"""Get the price and performance of the underlying asset.
Parameters
----------
@@ -296,7 +299,141 @@ def get_last_price(symbol: str) -> float:
Returns
-------
float
Last price
pd.Series
Pandas Series with the price and performance of the underlying asset.
"""
return float(yf.Ticker(symbol).fast_info.last_price)
ticker = yf.Ticker(symbol).fast_info
df = pd.Series(dtype=object)
df["lastPrice"] = round(ticker["lastPrice"], 2)
df["previousClose"] = round(ticker["previousClose"], 2)
df["open"] = round(ticker["open"], 2)
df["high"] = round(ticker["dayHigh"], 2)
df["low"] = round(ticker["dayLow"], 2)
df["yearHigh"] = round(ticker["yearHigh"], 2)
df["yearLow"] = round(ticker["yearLow"], 2)
df["fiftyDayMA"] = round(ticker["fiftyDayAverage"], 2)
df["twoHundredDayMA"] = round(ticker["twoHundredDayAverage"], 2)
return df.loc["lastPrice"]
@log_start_end(log=logger)
def get_underlying_price(symbol: str) -> pd.Series:
"""Get the price and performance of the underlying asset.
Parameters
----------
symbol: str
Symbol to get quote for
Returns
-------
pd.Series
Pandas Series with the price and performance of the underlying asset.
"""
ticker = yf.Ticker(symbol).fast_info
df = pd.Series(dtype=object)
df["lastPrice"] = round(ticker["lastPrice"], 2)
df["previousClose"] = round(ticker["previousClose"], 2)
df["open"] = round(ticker["open"], 2)
df["high"] = round(ticker["dayHigh"], 2)
df["low"] = round(ticker["dayLow"], 2)
df["yearHigh"] = round(ticker["yearHigh"], 2)
df["yearLow"] = round(ticker["yearLow"], 2)
df["fiftyDayMA"] = round(ticker["fiftyDayAverage"], 2)
df["twoHundredDayMA"] = round(ticker["twoHundredDayAverage"], 2)
return df.rename(f"{symbol}")
def load_options(symbol: str, pydantic: bool = False) -> object:
"""OptionsChains data object for YahooFinance.
Parameters
----------
symbol: str
The ticker symbol to load.
pydantic: bool
Whether to return the object as a Pydantic Model or a subscriptable Pandas Object. Default is False.
Returns
-------
object: OptionsChains
chains: pd.DataFrame
The complete options chain for the ticker. Returns as a dictionary if pydantic is True.
expirations: list[str]
List of unique expiration dates. (YYYY-MM-DD)
strikes: list[float]
List of unique strike prices.
last_price: float
The last price of the underlying asset.
underlying_name: str
The name of the underlying asset.
underlying_price: pd.Series
The price and recent performance of the underlying asset. Returns as a dictionary if pydantic is True.
hasIV: bool
Returns implied volatility.
hasGreeks: bool
Does not return greeks data.
symbol: str
The symbol entered by the user.
source: str
The source of the data, "YahooFinance".
Examples
--------
Get current options chains for AAPL.
>>> from openbb_terminal.stocks.options.yfinance_model import load_options
>>> data = load_options("AAPL")
>>> chains = data.chains
Return the object as a Pydantic Model.
>>> from openbb_terminal.stocks.options.yfinance_model import load_options
>>> data = load_options("AAPL", pydantic=True)
"""
OptionsChains = Options()
OptionsChains.source = "YahooFinance"
OptionsChains.symbol = symbol.upper()
chains = get_full_option_chain(OptionsChains.symbol)
if not chains.empty:
OptionsChains.expirations = option_expirations(OptionsChains.symbol)
OptionsChains.strikes = (
pd.Series(chains["strike"]).sort_values().unique().tolist()
)
OptionsChains.underlying_price = get_underlying_price(OptionsChains.symbol)
OptionsChains.underlying_name = OptionsChains.symbol
OptionsChains.last_price = OptionsChains.underlying_price["lastPrice"]
now = datetime.now()
temp = pd.DatetimeIndex(chains.expiration)
temp_ = (temp - now).days + 1
chains["dte"] = temp_
OptionsChains.chains = chains
OptionsChains.hasIV = "impliedVolatility" in OptionsChains.chains.columns
OptionsChains.hasGreeks = "gamma" in OptionsChains.chains.columns
if not chains.empty and OptionsChains.last_price is None:
OptionsChains.last_price = 0
print("No last price for " + OptionsChains.symbol)
if not pydantic:
return OptionsChains
OptionsChainsPydantic = PydanticOptions(
chains=OptionsChains.chains.to_dict(),
expirations=OptionsChains.expirations,
strikes=OptionsChains.strikes,
last_price=OptionsChains.last_price,
underlying_name=OptionsChains.underlying_name,
underlying_price=OptionsChains.underlying_price.to_dict(),
hasIV=OptionsChains.hasIV,
hasGreeks=OptionsChains.hasGreeks,
symbol=OptionsChains.symbol,
source=OptionsChains.source,
)
return OptionsChainsPydantic

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,796 @@
interactions:
- request:
body: null
headers:
Connection:
- close
Host:
- www.m-x.ca
User-Agent:
- Python-urllib/3.10
method: GET
uri: https://www.m-x.ca/en/trading/data/historical?dnld=1&from=2018-12-27&symbol=SU&to=2018-12-27
response:
body:
string: "\"Date\",\"Symbol\",\"Class Symbol\",\"Root Symbol\",\"Underlying Symbol\",\"Strike
Price\",\"Expiry Date\",\"Call/Put\",\"Ins. Type\",\"Bid Price\",\"Ask Price\",\"Bid
Size\",\"Ask Size\",\"Last Price\",\"Volume\",\"Last Close Price\",\"Net Change\",\"Open
Price\",\"High Price\",\"Low Price\",\"Total Value\",\"Nb. Trades\",\"Settlement
Price\",\"Open Interest\",\"Implied Volatility\"\r\n\"2018-12-27\",\"SU\",\"\",\"\",\"\",0,\"\",0,3,37.57,37.59,1,5,37.57,4606558,35.53,2.04,36.68,37.57,36.62,170600530,22548,0,0,0\r\n\"2018-12-27\",\"SU
\ 181228C34.00\",\"SU\",\"SU\",\"SU\",34,\"2018-12-28\",0,0,3.5,3.6,52,20,3.6,10,0,3.25,3.25,3.25,3.25,32,1,3.6,0,0\r\n\"2018-12-27\",\"SU
\ 181228C34.50\",\"SU\",\"SU\",\"SU\",34.5,\"2018-12-28\",0,0,3,3.15,43,43,3.15,0,1.38,0,0,0,0,0,0,3.15,0,74.768\r\n\"2018-12-27\",\"SU
\ 181228C35.00\",\"SU\",\"SU\",\"SU\",35,\"2018-12-28\",0,0,2.52,2.63,10,10,2.63,0,0.99,0,0,0,0,0,0,2.63,0,63.705\r\n\"2018-12-27\",\"SU
\ 181228C35.50\",\"SU\",\"SU\",\"SU\",35.5,\"2018-12-28\",0,0,2.03,2.13,10,10,2.13,0,0.65,0,0,0,0,0,0,2.13,20,57.151\r\n\"2018-12-27\",\"SU
\ 181228C36.00\",\"SU\",\"SU\",\"SU\",36,\"2018-12-28\",0,0,1.54,1.65,151,10,1.65,22,0.42,0.38,1.33,1.33,0.8,22,2,1.65,20,52.916\r\n\"2018-12-27\",\"SU
\ 181228C36.50\",\"SU\",\"SU\",\"SU\",36.5,\"2018-12-28\",0,0,1.09,1.17,151,20,1.17,0,0.24,0,0,0,0,0,0,1.17,10,49.059\r\n\"2018-12-27\",\"SU
\ 181228C37.00\",\"SU\",\"SU\",\"SU\",37,\"2018-12-28\",0,0,0.67,0.74,151,10,0.74,120,0.15,0.51,0.36,0.66,0.22,41,10,0.74,30,45.013\r\n\"2018-12-27\",\"SU
\ 181228C37.50\",\"SU\",\"SU\",\"SU\",37.5,\"2018-12-28\",0,0,0.33,0.38,151,20,0.38,83,0.1,0.1,0.18,0.32,0.18,16,5,0.38,330,40.831\r\n\"2018-12-27\",\"SU
\ 181228C38.00\",\"SU\",\"SU\",\"SU\",38,\"2018-12-28\",0,0,0.13,0.18,151,10,0.18,20,0.09,-0.01,0.08,0.08,0.08,1,1,0.18,50,41.402\r\n\"2018-12-27\",\"SU
\ 181228C38.50\",\"SU\",\"SU\",\"SU\",38.5,\"2018-12-28\",0,0,0.03,0.1,151,60,0.1,0,0.1,0,0,0,0,0,0,0.1,0,44.125\r\n\"2018-12-27\",\"SU
\ 181228C39.00\",\"SU\",\"SU\",\"SU\",39,\"2018-12-28\",0,0,0,0.1,0,76,0.1,0,0.1,0,0,0,0,0,0,0.1,80,54.953\r\n\"2018-12-27\",\"SU
\ 181228C39.50\",\"SU\",\"SU\",\"SU\",39.5,\"2018-12-28\",0,0,0,0.1,0,78,0.1,0,0.1,0,0,0,0,0,0,0.1,47,68.259\r\n\"2018-12-27\",\"SU
\ 181228C40.00\",\"SU\",\"SU\",\"SU\",40,\"2018-12-28\",0,0,0,0.05,0,63,0.05,0,0.1,0,0,0,0,0,0,0.05,83,62.792\r\n\"2018-12-27\",\"SU
\ 181228C40.50\",\"SU\",\"SU\",\"SU\",40.5,\"2018-12-28\",0,0,0,0.11,0,78,0.11,0,0.1,0,0,0,0,0,0,0.11,274,0\r\n\"2018-12-27\",\"SU
\ 181228C41.00\",\"SU\",\"SU\",\"SU\",41,\"2018-12-28\",0,0,0,0.11,0,78,0.11,0,0.1,0,0,0,0,0,0,0.11,110,0\r\n\"2018-12-27\",\"SU
\ 181228C41.50\",\"SU\",\"SU\",\"SU\",41.5,\"2018-12-28\",0,0,0,0.11,0,78,0.11,0,0.1,0,0,0,0,0,0,0.11,110,0\r\n\"2018-12-27\",\"SU
\ 181228C42.00\",\"SU\",\"SU\",\"SU\",42,\"2018-12-28\",0,0,0,0.11,0,78,0.11,0,0.1,0,0,0,0,0,0,0.11,41,0\r\n\"2018-12-27\",\"SU
\ 181228C42.50\",\"SU\",\"SU\",\"SU\",42.5,\"2018-12-28\",0,0,0,0.18,0,189,0.18,0,0.1,0,0,0,0,0,0,0.18,1,0\r\n\"2018-12-27\",\"SU
\ 181228C43.00\",\"SU\",\"SU\",\"SU\",43,\"2018-12-28\",0,0,0,0.18,0,189,0.18,0,0.1,0,0,0,0,0,0,0.18,91,0\r\n\"2018-12-27\",\"SU
\ 181228C43.50\",\"SU\",\"SU\",\"SU\",43.5,\"2018-12-28\",0,0,0,0.18,0,189,0.18,0,0.1,0,0,0,0,0,0,0.18,35,0\r\n\"2018-12-27\",\"SU
\ 181228C44.00\",\"SU\",\"SU\",\"SU\",44,\"2018-12-28\",0,0,0,0.17,0,78,0.17,0,0.1,0,0,0,0,0,0,0.17,18,0\r\n\"2018-12-27\",\"SU
\ 181228C44.50\",\"SU\",\"SU\",\"SU\",44.5,\"2018-12-28\",0,0,0,0.18,0,189,0.18,0,0.1,0,0,0,0,0,0,0.18,25,0\r\n\"2018-12-27\",\"SU
\ 181228C45.00\",\"SU\",\"SU\",\"SU\",45,\"2018-12-28\",0,0,0,0.17,0,78,0.17,0,0.1,0,0,0,0,0,0,0.17,3,0\r\n\"2018-12-27\",\"SU
\ 181228C45.50\",\"SU\",\"SU\",\"SU\",45.5,\"2018-12-28\",0,0,0,0.17,0,78,0.17,0,0.1,0,0,0,0,0,0,0.17,31,0\r\n\"2018-12-27\",\"SU
\ 181228C46.00\",\"SU\",\"SU\",\"SU\",46,\"2018-12-28\",0,0,0,0.17,0,78,0.17,0,0.1,0,0,0,0,0,0,0.17,20,0\r\n\"2018-12-27\",\"SU
\ 190104C34.00\",\"SU\",\"SU\",\"SU\",34,\"2019-01-04\",0,0,3.6,3.8,104,10,3.8,0,0,0,0,0,0,0,0,3.8,0,54.288\r\n\"2018-12-27\",\"SU
\ 190104C34.50\",\"SU\",\"SU\",\"SU\",34.5,\"2019-01-04\",0,0,3.1,3.25,104,44,3.25,0,1.66,0,0,0,0,0,0,3.25,0,45.892\r\n\"2018-12-27\",\"SU
\ 190104C35.00\",\"SU\",\"SU\",\"SU\",35,\"2019-01-04\",0,0,2.69,2.76,10,20,2.76,0,1.28,0,0,0,0,0,0,2.76,0,44.477\r\n\"2018-12-27\",\"SU
\ 190104C35.50\",\"SU\",\"SU\",\"SU\",35.5,\"2019-01-04\",0,0,2.24,2.31,20,20,2.31,0,0.99,0,0,0,0,0,0,2.31,0,41.829\r\n\"2018-12-27\",\"SU
\ 190104C36.00\",\"SU\",\"SU\",\"SU\",36,\"2019-01-04\",0,0,1.82,1.94,30,20,1.94,0,0.72,0,0,0,0,0,0,1.94,0,41.437\r\n\"2018-12-27\",\"SU
\ 190104C36.50\",\"SU\",\"SU\",\"SU\",36.5,\"2019-01-04\",0,0,1.44,1.48,150,20,1.48,60,0.52,0.4,0.92,0.92,0.92,51,7,1.48,25,37.999\r\n\"2018-12-27\",\"SU
\ 190104C37.00\",\"SU\",\"SU\",\"SU\",37,\"2019-01-04\",0,0,1.09,1.13,150,20,1.13,0,0.37,0,0,0,0,0,0,1.13,0,36.548\r\n\"2018-12-27\",\"SU
\ 190104C37.50\",\"SU\",\"SU\",\"SU\",37.5,\"2019-01-04\",0,0,0.79,0.84,140,20,0.84,110,0.25,0.54,0.56,0.8,0.46,64,7,0.84,0,35.606\r\n\"2018-12-27\",\"SU
\ 190104C38.00\",\"SU\",\"SU\",\"SU\",38,\"2019-01-04\",0,0,0.56,0.59,150,20,0.59,10,0.18,0.16,0.34,0.34,0.34,3,1,0.59,0,34.912\r\n\"2018-12-27\",\"SU
\ 190104C38.50\",\"SU\",\"SU\",\"SU\",38.5,\"2019-01-04\",0,0,0.38,0.39,150,20,0.39,20,0.13,0.11,0.24,0.24,0.24,4,1,0.39,0,34.196\r\n\"2018-12-27\",\"SU
\ 190104C39.00\",\"SU\",\"SU\",\"SU\",39,\"2019-01-04\",0,0,0.24,0.27,150,43,0.27,20,0.1,0.07,0.17,0.17,0.17,3,1,0.27,25,34.188\r\n\"2018-12-27\",\"SU
\ 190104C39.50\",\"SU\",\"SU\",\"SU\",39.5,\"2019-01-04\",0,0,0.15,0.18,150,56,0.18,0,0.1,0,0,0,0,0,0,0.18,23,34.367\r\n\"2018-12-27\",\"SU
\ 190104C40.00\",\"SU\",\"SU\",\"SU\",40,\"2019-01-04\",0,0,0.09,0.13,150,59,0.13,0,0.09,0,0,0,0,0,0,0.13,20,35.151\r\n\"2018-12-27\",\"SU
\ 190104C40.50\",\"SU\",\"SU\",\"SU\",40.5,\"2019-01-04\",0,0,0.05,0.1,170,63,0.1,0,0.1,0,0,0,0,0,0,0.1,39,36.209\r\n\"2018-12-27\",\"SU
\ 190104C41.00\",\"SU\",\"SU\",\"SU\",41,\"2019-01-04\",0,0,0.03,0.17,170,69,0.17,0,0.1,0,0,0,0,0,0,0.17,100,43.479\r\n\"2018-12-27\",\"SU
\ 190104C41.50\",\"SU\",\"SU\",\"SU\",41.5,\"2019-01-04\",0,0,0.01,0.17,226,72,0.17,0,0.09,0,0,0,0,0,0,0.17,20,46.658\r\n\"2018-12-27\",\"SU
\ 190104C42.00\",\"SU\",\"SU\",\"SU\",42,\"2019-01-04\",0,0,0.01,0.17,130,76,0.17,0,0.1,0,0,0,0,0,0,0.17,116,50.823\r\n\"2018-12-27\",\"SU
\ 190104C42.50\",\"SU\",\"SU\",\"SU\",42.5,\"2019-01-04\",0,0,0,0.17,0,77,0.17,0,0.1,0,0,0,0,0,0,0.17,25,54.191\r\n\"2018-12-27\",\"SU
\ 190104C43.00\",\"SU\",\"SU\",\"SU\",43,\"2019-01-04\",0,0,0,0.17,0,77,0.17,0,0.1,0,0,0,0,0,0,0.17,0,58.079\r\n\"2018-12-27\",\"SU
\ 190104C43.50\",\"SU\",\"SU\",\"SU\",43.5,\"2019-01-04\",0,0,0,0.17,0,77,0.17,0,0.1,0,0,0,0,0,0,0.17,15,61.895\r\n\"2018-12-27\",\"SU
\ 190104C44.00\",\"SU\",\"SU\",\"SU\",44,\"2019-01-04\",0,0,0,0.17,0,78,0.17,0,0.1,0,0,0,0,0,0,0.17,25,68.567\r\n\"2018-12-27\",\"SU
\ 190104C44.50\",\"SU\",\"SU\",\"SU\",44.5,\"2019-01-04\",0,0,0,0.17,0,78,0.17,0,0.1,0,0,0,0,0,0,0.17,20,74.817\r\n\"2018-12-27\",\"SU
\ 190104C45.00\",\"SU\",\"SU\",\"SU\",45,\"2019-01-04\",0,0,0,0.17,0,78,0.17,0,0.1,0,0,0,0,0,0,0.17,0,80.356\r\n\"2018-12-27\",\"SU
\ 190104C45.50\",\"SU\",\"SU\",\"SU\",45.5,\"2019-01-04\",0,0,0,0.17,0,78,0.17,0,0.1,0,0,0,0,0,0,0.17,0,70.128\r\n\"2018-12-27\",\"SU
\ 190104C46.00\",\"SU\",\"SU\",\"SU\",46,\"2019-01-04\",0,0,0,0.17,0,78,0.17,0,0.1,0,0,0,0,0,0,0.17,0,72.815\r\n\"2018-12-27\",\"SU
\ 190111C34.00\",\"SU\",\"SU\",\"SU\",34,\"2019-01-11\",0,0,3.75,3.85,10,43,3.85,0,0,0,0,0,0,0,0,3.85,0,47.195\r\n\"2018-12-27\",\"SU
\ 190111C34.50\",\"SU\",\"SU\",\"SU\",34.5,\"2019-01-11\",0,0,3.3,3.4,103,53,3.4,0,1.91,0,0,0,0,0,0,3.4,0,45.069\r\n\"2018-12-27\",\"SU
\ 190111C35.00\",\"SU\",\"SU\",\"SU\",35,\"2019-01-11\",0,0,2.88,3.05,10,10,3.05,2,1.53,0.94,2.4,2.47,2.4,4,2,3.05,0,45.456\r\n\"2018-12-27\",\"SU
\ 190111C35.50\",\"SU\",\"SU\",\"SU\",35.5,\"2019-01-11\",0,0,2.47,2.53,30,52,2.53,0,1.24,0,0,0,0,0,0,2.53,0,41.452\r\n\"2018-12-27\",\"SU
\ 190111C36.00\",\"SU\",\"SU\",\"SU\",36,\"2019-01-11\",0,0,2.08,2.14,168,51,2.14,20,0.99,0.66,1.65,1.65,1.65,33,1,2.14,0,39.999\r\n\"2018-12-27\",\"SU
\ 190111C36.50\",\"SU\",\"SU\",\"SU\",36.5,\"2019-01-11\",0,0,1.72,1.78,148,50,1.78,0,0.78,0,0,0,0,0,0,1.78,10,38.77\r\n\"2018-12-27\",\"SU
\ 190111C37.00\",\"SU\",\"SU\",\"SU\",37,\"2019-01-11\",0,0,1.38,1.54,148,108,1.54,0,0.61,0,0,0,0,0,0,1.54,0,38.947\r\n\"2018-12-27\",\"SU
\ 190111C37.50\",\"SU\",\"SU\",\"SU\",37.5,\"2019-01-11\",0,0,1.09,1.26,148,108,1.26,69,0.46,0.41,0.75,0.99,0.75,59,4,1.26,18,38.163\r\n\"2018-12-27\",\"SU
\ 190111C38.00\",\"SU\",\"SU\",\"SU\",38,\"2019-01-11\",0,0,0.85,0.91,148,10,0.91,1,0.34,0.26,0.6,0.6,0.6,0,1,0.91,2,35.923\r\n\"2018-12-27\",\"SU
\ 190111C38.50\",\"SU\",\"SU\",\"SU\",38.5,\"2019-01-11\",0,0,0.65,0.8,148,108,0.8,0,0.26,0,0,0,0,0,0,0.8,0,37.198\r\n\"2018-12-27\",\"SU
\ 190111C39.00\",\"SU\",\"SU\",\"SU\",39,\"2019-01-11\",0,0,0.49,0.52,148,51,0.52,0,0.21,0,0,0,0,0,0,0.52,20,35.025\r\n\"2018-12-27\",\"SU
\ 190111C39.50\",\"SU\",\"SU\",\"SU\",39.5,\"2019-01-11\",0,0,0.36,0.39,148,53,0.39,9,0.17,0.13,0.3,0.3,0.3,2,1,0.39,25,34.887\r\n\"2018-12-27\",\"SU
\ 190111C40.00\",\"SU\",\"SU\",\"SU\",40,\"2019-01-11\",0,0,0.26,0.3,148,54,0.3,0,0.14,0,0,0,0,0,0,0.3,800,35.105\r\n\"2018-12-27\",\"SU
\ 190111C40.50\",\"SU\",\"SU\",\"SU\",40.5,\"2019-01-11\",0,0,0.18,0.22,209,37,0.22,0,0.13,0,0,0,0,0,0,0.22,0,34.962\r\n\"2018-12-27\",\"SU
\ 190111C41.00\",\"SU\",\"SU\",\"SU\",41,\"2019-01-11\",0,0,0.13,0.18,168,39,0.18,0,0.1,0,0,0,0,0,0,0.18,40,35.848\r\n\"2018-12-27\",\"SU
\ 190111C41.50\",\"SU\",\"SU\",\"SU\",41.5,\"2019-01-11\",0,0,0.1,0.15,168,62,0.15,0,0.1,0,0,0,0,0,0,0.15,21,37.08\r\n\"2018-12-27\",\"SU
\ 190111C42.00\",\"SU\",\"SU\",\"SU\",42,\"2019-01-11\",0,0,0.07,0.13,168,65,0.13,0,0.1,0,0,0,0,0,0,0.13,29,38.148\r\n\"2018-12-27\",\"SU
\ 190111C42.50\",\"SU\",\"SU\",\"SU\",42.5,\"2019-01-11\",0,0,0.06,0.18,60,68,0.18,0,0.1,0,0,0,0,0,0,0.18,97,42.938\r\n\"2018-12-27\",\"SU
\ 190111C43.00\",\"SU\",\"SU\",\"SU\",43,\"2019-01-11\",0,0,0.04,0.18,222,70,0.18,0,0.1,0,0,0,0,0,0,0.18,168,45.023\r\n\"2018-12-27\",\"SU
\ 190111C43.50\",\"SU\",\"SU\",\"SU\",43.5,\"2019-01-11\",0,0,0.04,0.18,60,73,0.18,0,0.1,0,0,0,0,0,0,0.18,84,47.892\r\n\"2018-12-27\",\"SU
\ 190118C30.00\",\"SU\",\"SU\",\"SU\",30,\"2019-01-18\",0,0,7.6,7.75,134,54,7.75,0,5.9,0,0,0,0,0,0,7.75,0,62.201\r\n\"2018-12-27\",\"SU
\ 190118C32.00\",\"SU\",\"SU\",\"SU\",32,\"2019-01-18\",0,0,5.7,5.8,157,44,5.8,12,4.05,1.1,5.15,5.15,5.15,61,1,5.8,123,52.658\r\n\"2018-12-27\",\"SU
\ 190118C34.00\",\"SU\",\"SU\",\"SU\",34,\"2019-01-18\",0,0,3.85,3.95,133,53,3.95,0,2.41,0,0,0,0,0,0,3.95,40,44.215\r\n\"2018-12-27\",\"SU
\ 190118C36.00\",\"SU\",\"SU\",\"SU\",36,\"2019-01-18\",0,0,2.27,2.35,147,31,2.35,5,1.19,1.01,1.8,2.2,1.71,8,3,2.35,97,39.601\r\n\"2018-12-27\",\"SU
\ 190118C38.00\",\"SU\",\"SU\",\"SU\",38,\"2019-01-18\",0,0,1.07,1.22,147,20,1.22,62,0.51,0.54,0.85,1.05,0.74,51,9,1.22,62,37.13\r\n\"2018-12-27\",\"SU
\ 190118C40.00\",\"SU\",\"SU\",\"SU\",40,\"2019-01-18\",0,0,0.41,0.44,137,53,0.44,172,0.22,0.18,0.32,0.4,0.3,60,8,0.44,148,34.479\r\n\"2018-12-27\",\"SU
\ 190118C42.00\",\"SU\",\"SU\",\"SU\",42,\"2019-01-18\",0,0,0.15,0.16,147,40,0.16,0,0.11,0,0,0,0,0,0,0.16,248,35.244\r\n\"2018-12-27\",\"SU
\ 190118C44.00\",\"SU\",\"SU\",\"SU\",44,\"2019-01-18\",0,0,0.06,0.14,147,70,0.14,0,0.1,0,0,0,0,0,0,0.14,301,41.108\r\n\"2018-12-27\",\"SU
\ 190118C46.00\",\"SU\",\"SU\",\"SU\",46,\"2019-01-18\",0,0,0.02,0.14,197,76,0.14,0,0.1,0,0,0,0,0,0,0.14,4935,54.967\r\n\"2018-12-27\",\"SU
\ 190118C48.00\",\"SU\",\"SU\",\"SU\",48,\"2019-01-18\",0,0,0.01,0.14,197,78,0.14,0,0.1,0,0,0,0,0,0,0.14,3327,65.787\r\n\"2018-12-27\",\"SU
\ 190118C50.00\",\"SU\",\"SU\",\"SU\",50,\"2019-01-18\",0,0,0.01,0.14,90,78,0.14,0,0.1,0,0,0,0,0,0,0.14,440,55.4\r\n\"2018-12-27\",\"SU
\ 190118C52.00\",\"SU\",\"SU\",\"SU\",52,\"2019-01-18\",0,0,0.01,0.11,90,79,0.11,0,0.1,0,0,0,0,0,0,0.11,382,59.049\r\n\"2018-12-27\",\"SU
\ 190118C54.00\",\"SU\",\"SU\",\"SU\",54,\"2019-01-18\",0,0,0.01,0.11,90,79,0.11,0,0.1,0,0,0,0,0,0,0.11,345,91.807\r\n\"2018-12-27\",\"SU
\ 190118C56.00\",\"SU\",\"SU\",\"SU\",56,\"2019-01-18\",0,0,0,0.12,0,186,0.12,0,0.1,0,0,0,0,0,0,0.12,523,0\r\n\"2018-12-27\",\"SU
\ 190118C58.00\",\"SU\",\"SU\",\"SU\",58,\"2019-01-18\",0,0,0,0.12,0,186,0.12,0,0.1,0,0,0,0,0,0,0.12,378,0\r\n\"2018-12-27\",\"SU
\ 190118C60.00\",\"SU\",\"SU\",\"SU\",60,\"2019-01-18\",0,0,0,0.12,0,186,0.12,0,0.1,0,0,0,0,0,0,0.12,314,0\r\n\"2018-12-27\",\"SU
\ 190215C30.00\",\"SU\",\"SU\",\"SU\",30,\"2019-02-15\",0,0,7.85,7.95,112,20,7.95,12,6.15,1.25,7.3,7.4,7.3,88,2,7.95,0,54.453\r\n\"2018-12-27\",\"SU
\ 190215C32.00\",\"SU\",\"SU\",\"SU\",32,\"2019-02-15\",0,0,6,6.1,10,53,6.1,10,4.45,1.35,5.8,5.8,5.8,58,1,6.1,10,47.261\r\n\"2018-12-27\",\"SU
\ 190215C34.00\",\"SU\",\"SU\",\"SU\",34,\"2019-02-15\",0,0,4.3,4.4,112,52,4.4,20,2.92,1.18,3.85,4.1,3.85,79,2,4.4,30,42.068\r\n\"2018-12-27\",\"SU
\ 190215C36.00\",\"SU\",\"SU\",\"SU\",36,\"2019-02-15\",0,0,2.83,2.9,152,10,2.9,22,1.74,0.96,2.47,2.7,2.31,58,3,2.9,73,38.05\r\n\"2018-12-27\",\"SU
\ 190215C38.00\",\"SU\",\"SU\",\"SU\",38,\"2019-02-15\",0,0,1.66,1.71,182,20,1.71,9,0.96,0.34,1.31,1.31,1.3,10,3,1.71,95,34.998\r\n\"2018-12-27\",\"SU
\ 190215C40.00\",\"SU\",\"SU\",\"SU\",40,\"2019-02-15\",0,0,0.9,0.95,152,10,0.95,63,0.49,0.24,0.66,0.75,0.66,42,6,0.95,214,33.944\r\n\"2018-12-27\",\"SU
\ 190215C42.00\",\"SU\",\"SU\",\"SU\",42,\"2019-02-15\",0,0,0.46,0.51,152,10,0.51,5,0.29,0.16,0.45,0.45,0.45,1,2,0.51,19,33.852\r\n\"2018-12-27\",\"SU
\ 190215C44.00\",\"SU\",\"SU\",\"SU\",44,\"2019-02-15\",0,0,0.25,0.28,152,60,0.28,20,0.19,0.03,0.22,0.22,0.22,4,1,0.28,16,34.852\r\n\"2018-12-27\",\"SU
\ 190215C46.00\",\"SU\",\"SU\",\"SU\",46,\"2019-02-15\",0,0,0.14,0.18,152,66,0.18,0,0.13,0,0,0,0,0,0,0.18,0,36.704\r\n\"2018-12-27\",\"SU
\ 190315C30.00\",\"SU\",\"SU\",\"SU\",30,\"2019-03-15\",0,0,7.95,8.05,10,10,8.05,10,6.3,1.4,7.7,7.7,7.7,77,1,8.05,0,48.224\r\n\"2018-12-27\",\"SU
\ 190315C32.00\",\"SU\",\"SU\",\"SU\",32,\"2019-03-15\",0,0,6.15,6.25,10,52,6.25,10,4.65,1.3,5.95,5.95,5.95,59,1,6.25,0,42.552\r\n\"2018-12-27\",\"SU
\ 190315C34.00\",\"SU\",\"SU\",\"SU\",34,\"2019-03-15\",0,0,4.5,4.6,91,51,4.6,8,3.2,1.1,4.1,4.3,4.1,32,2,4.6,15,38.24\r\n\"2018-12-27\",\"SU
\ 190315C36.00\",\"SU\",\"SU\",\"SU\",36,\"2019-03-15\",0,0,3.1,3.2,150,50,3.2,20,2.02,1.13,2.74,3.15,2.74,57,3,3.2,26,35.5\r\n\"2018-12-27\",\"SU
\ 190315C38.00\",\"SU\",\"SU\",\"SU\",38,\"2019-03-15\",0,0,1.96,2.03,90,20,2.03,159,1.23,0.59,1.65,1.82,1.65,266,11,2.03,172,33.001\r\n\"2018-12-27\",\"SU
\ 190315C40.00\",\"SU\",\"SU\",\"SU\",40,\"2019-03-15\",0,0,1.17,1.24,91,51,1.24,196,0.73,0.37,0.98,1.1,0.98,198,15,1.24,338,31.974\r\n\"2018-12-27\",\"SU
\ 190315C42.00\",\"SU\",\"SU\",\"SU\",42,\"2019-03-15\",0,0,0.68,0.73,95,53,0.73,61,0.44,0.23,0.57,0.67,0.56,34,8,0.73,309,31.725\r\n\"2018-12-27\",\"SU
\ 190315C44.00\",\"SU\",\"SU\",\"SU\",44,\"2019-03-15\",0,0,0.41,0.46,150,57,0.46,0,0.28,0,0,0,0,0,0,0.46,417,32.611\r\n\"2018-12-27\",\"SU
\ 190315C46.00\",\"SU\",\"SU\",\"SU\",46,\"2019-03-15\",0,0,0.25,0.3,170,62,0.3,0,0.2,0,0,0,0,0,0,0.3,595,33.712\r\n\"2018-12-27\",\"SU
\ 190315C48.00\",\"SU\",\"SU\",\"SU\",48,\"2019-03-15\",0,0,0.16,0.19,150,47,0.19,0,0.14,0,0,0,0,0,0,0.19,79,34.751\r\n\"2018-12-27\",\"SU
\ 190315C50.00\",\"SU\",\"SU\",\"SU\",50,\"2019-03-15\",0,0,0.11,0.18,150,71,0.18,0,0.12,0,0,0,0,0,0,0.18,401,35.967\r\n\"2018-12-27\",\"SU
\ 190315C52.00\",\"SU\",\"SU\",\"SU\",52,\"2019-03-15\",0,0,0.08,0.16,150,74,0.16,0,0.1,0,0,0,0,0,0,0.16,195,45.951\r\n\"2018-12-27\",\"SU
\ 190315C54.00\",\"SU\",\"SU\",\"SU\",54,\"2019-03-15\",0,0,0.06,0.08,110,13,0.08,0,0.1,0,0,0,0,0,0,0.08,164,35.506\r\n\"2018-12-27\",\"SU
\ 190315C56.00\",\"SU\",\"SU\",\"SU\",56,\"2019-03-15\",0,0,0.04,0.14,60,77,0.14,0,0.1,0,0,0,0,0,0,0.14,38,54.758\r\n\"2018-12-27\",\"SU
\ 190315C58.00\",\"SU\",\"SU\",\"SU\",58,\"2019-03-15\",0,0,0.03,0.14,60,78,0.14,0,0.1,0,0,0,0,0,0,0.14,52,58.645\r\n\"2018-12-27\",\"SU
\ 190315C60.00\",\"SU\",\"SU\",\"SU\",60,\"2019-03-15\",0,0,0.02,0.14,170,78,0.14,0,0.1,0,0,0,0,0,0,0.14,17,44.653\r\n\"2018-12-27\",\"SU
\ 190315C62.00\",\"SU\",\"SU\",\"SU\",62,\"2019-03-15\",0,0,0.02,0.14,170,79,0.14,0,0.1,0,0,0,0,0,0,0.14,1,65.866\r\n\"2018-12-27\",\"SU
\ 190315C64.00\",\"SU\",\"SU\",\"SU\",64,\"2019-03-15\",0,0,0.01,0.14,200,79,0.14,0,0.1,0,0,0,0,0,0,0.14,0,49.16\r\n\"2018-12-27\",\"SU
\ 190315C66.00\",\"SU\",\"SU\",\"SU\",66,\"2019-03-15\",0,0,0.01,0.11,200,79,0.11,0,0.1,0,0,0,0,0,0,0.11,60,70.987\r\n\"2018-12-27\",\"SU
\ 190621C30.00\",\"SU\",\"SU\",\"SU\",30,\"2019-06-21\",0,0,8.2,8.35,52,20,8.35,16,6.75,1.15,7.9,7.9,7.9,126,1,8.35,0,39.967\r\n\"2018-12-27\",\"SU
\ 190621C32.00\",\"SU\",\"SU\",\"SU\",32,\"2019-06-21\",0,0,6.5,6.7,131,20,6.7,0,5.25,0,0,0,0,0,0,6.7,0,36.314\r\n\"2018-12-27\",\"SU
\ 190621C34.00\",\"SU\",\"SU\",\"SU\",34,\"2019-06-21\",0,0,5.05,5.25,91,20,5.25,0,3.95,0,0,0,0,0,0,5.25,97,34.231\r\n\"2018-12-27\",\"SU
\ 190621C36.00\",\"SU\",\"SU\",\"SU\",36,\"2019-06-21\",0,0,3.75,4,90,20,4,0,2.83,0,0,0,0,0,0,4,47,32.452\r\n\"2018-12-27\",\"SU
\ 190621C38.00\",\"SU\",\"SU\",\"SU\",38,\"2019-06-21\",0,0,2.72,2.8,90,5,2.8,11,2.02,0.45,2.4,2.48,2.4,26,3,2.8,61,30.549\r\n\"2018-12-27\",\"SU
\ 190621C40.00\",\"SU\",\"SU\",\"SU\",40,\"2019-06-21\",0,0,1.89,2.03,91,20,2.03,0,1.38,0,0,0,0,0,0,2.03,97,29.899\r\n\"2018-12-27\",\"SU
\ 190621C42.00\",\"SU\",\"SU\",\"SU\",42,\"2019-06-21\",0,0,1.31,1.5,92,30,1.5,46,0.96,0.39,1.32,1.35,1.17,52,7,1.5,114,29.977\r\n\"2018-12-27\",\"SU
\ 190621C44.00\",\"SU\",\"SU\",\"SU\",44,\"2019-06-21\",0,0,0.89,0.98,95,20,0.98,0,0.67,0,0,0,0,0,0,0.98,203,29.345\r\n\"2018-12-27\",\"SU
\ 190621C46.00\",\"SU\",\"SU\",\"SU\",46,\"2019-06-21\",0,0,0.59,0.68,98,56,0.68,0,0.49,0,0,0,0,0,0,0.68,80,29.311\r\n\"2018-12-27\",\"SU
\ 190621C48.00\",\"SU\",\"SU\",\"SU\",48,\"2019-06-21\",0,0,0.39,0.53,82,40,0.53,0,0.37,0,0,0,0,0,0,0.53,52,29.955\r\n\"2018-12-27\",\"SU
\ 190621C50.00\",\"SU\",\"SU\",\"SU\",50,\"2019-06-21\",0,0,0.29,0.37,106,63,0.37,0,0.29,0,0,0,0,0,0,0.37,42,30.46\r\n\"2018-12-27\",\"SU
\ 190621C52.00\",\"SU\",\"SU\",\"SU\",52,\"2019-06-21\",0,0,0.21,0.3,60,66,0.3,0,0.23,0,0,0,0,0,0,0.3,40,31.426\r\n\"2018-12-27\",\"SU
\ 190621C54.00\",\"SU\",\"SU\",\"SU\",54,\"2019-06-21\",0,0,0.14,0.25,112,69,0.25,0,0.2,0,0,0,0,0,0,0.25,21,32.201\r\n\"2018-12-27\",\"SU
\ 190621C56.00\",\"SU\",\"SU\",\"SU\",56,\"2019-06-21\",0,0,0.11,0.19,60,72,0.19,0,0.16,0,0,0,0,0,0,0.19,46,30.204\r\n\"2018-12-27\",\"SU
\ 190621C58.00\",\"SU\",\"SU\",\"SU\",58,\"2019-06-21\",0,0,0.09,0.17,60,74,0.17,0,0.16,0,0,0,0,0,0,0.17,20,31.013\r\n\"2018-12-27\",\"SU
\ 200117C32.00\",\"SU\",\"SU\",\"SU\",32,\"2020-01-17\",0,0,7.4,7.65,51,20,7.65,0,6.3,0,0,0,0,0,0,7.65,0,34.937\r\n\"2018-12-27\",\"SU
\ 200117C34.00\",\"SU\",\"SU\",\"SU\",34,\"2020-01-17\",0,0,5.55,6.4,90,30,6.4,0,5.15,0,0,0,0,0,0,6.4,338,31.474\r\n\"2018-12-27\",\"SU
\ 200117C36.00\",\"SU\",\"SU\",\"SU\",36,\"2020-01-17\",0,0,4.5,5.95,90,90,5.95,10,4.15,0.85,5,5,5,50,2,5.95,37,33.044\r\n\"2018-12-27\",\"SU
\ 200117C38.00\",\"SU\",\"SU\",\"SU\",38,\"2020-01-17\",0,0,4,4.25,90,50,4.25,0,3.3,0,0,0,0,0,0,4.25,129,31.262\r\n\"2018-12-27\",\"SU
\ 200117C40.00\",\"SU\",\"SU\",\"SU\",40,\"2020-01-17\",0,0,2.94,3.4,90,30,3.4,3,2.59,0.66,3.25,3.25,3.25,9,1,3.4,68,29.664\r\n\"2018-12-27\",\"SU
\ 200117C42.00\",\"SU\",\"SU\",\"SU\",42,\"2020-01-17\",0,0,2.48,2.69,91,20,2.69,0,2.04,0,0,0,0,0,0,2.69,270,29.781\r\n\"2018-12-27\",\"SU
\ 200117C44.00\",\"SU\",\"SU\",\"SU\",44,\"2020-01-17\",0,0,2.01,2.13,52,31,2.13,3,1.62,0.31,1.89,1.93,1.89,4,2,2.13,85,29.668\r\n\"2018-12-27\",\"SU
\ 200117C46.00\",\"SU\",\"SU\",\"SU\",46,\"2020-01-17\",0,0,1.54,1.69,93,53,1.69,0,1.28,0,0,0,0,0,0,1.69,128,29.307\r\n\"2018-12-27\",\"SU
\ 200117C48.00\",\"SU\",\"SU\",\"SU\",48,\"2020-01-17\",0,0,1.06,1.42,95,20,1.42,0,1.02,0,0,0,0,0,0,1.42,72,28.913\r\n\"2018-12-27\",\"SU
\ 200117C50.00\",\"SU\",\"SU\",\"SU\",50,\"2020-01-17\",0,0,0.94,1.05,97,36,1.05,0,0.82,0,0,0,0,0,0,1.05,141,29.082\r\n\"2018-12-27\",\"SU
\ 200117C52.00\",\"SU\",\"SU\",\"SU\",52,\"2020-01-17\",0,0,0.66,0.88,99,58,0.88,0,0.69,0,0,0,0,0,0,0.88,361,28.93\r\n\"2018-12-27\",\"SU
\ 200117C54.00\",\"SU\",\"SU\",\"SU\",54,\"2020-01-17\",0,0,0.59,0.74,102,60,0.74,0,0.58,0,0,0,0,0,0,0.74,36,29.709\r\n\"2018-12-27\",\"SU
\ 200117C56.00\",\"SU\",\"SU\",\"SU\",56,\"2020-01-17\",0,0,0.02,0.64,134,20,0.64,2,0.49,-0.01,0.48,0.48,0.48,0,1,0.64,555,26.627\r\n\"2018-12-27\",\"SU
\ 200117C58.00\",\"SU\",\"SU\",\"SU\",58,\"2020-01-17\",0,0,0.38,0.52,60,65,0.52,0,0.4,0,0,0,0,0,0,0.52,138,30.293\r\n\"2018-12-27\",\"SU
\ 200117C60.00\",\"SU\",\"SU\",\"SU\",60,\"2020-01-17\",0,0,0.27,0.44,109,67,0.44,0,0.37,0,0,0,0,0,0,0.44,60,30.262\r\n\"2018-12-27\",\"SU
\ 210115C32.00\",\"SU\",\"SU\",\"SU\",32,\"2021-01-15\",0,0,7.6,8.6,90,50,8.6,0,7.2,0,0,0,0,0,0,8.6,0,31.86\r\n\"2018-12-27\",\"SU
\ 210115C34.00\",\"SU\",\"SU\",\"SU\",34,\"2021-01-15\",0,0,7.1,10.45,90,20,10.45,30,6.15,0.75,6.8,6.9,6.8,206,2,10.45,21,40.583\r\n\"2018-12-27\",\"SU
\ 210115C36.00\",\"SU\",\"SU\",\"SU\",36,\"2021-01-15\",0,0,5.6,8.3,90,60,8.3,0,5.3,0,0,0,0,0,0,8.3,26,35.123\r\n\"2018-12-27\",\"SU
\ 210115C38.00\",\"SU\",\"SU\",\"SU\",38,\"2021-01-15\",0,0,5.15,5.45,90,30,5.45,0,4.45,0,0,0,0,0,0,5.45,47,30.48\r\n\"2018-12-27\",\"SU
\ 210115C40.00\",\"SU\",\"SU\",\"SU\",40,\"2021-01-15\",0,0,3.95,4.65,90,30,4.65,0,3.8,0,0,0,0,0,0,4.65,20,28.803\r\n\"2018-12-27\",\"SU
\ 210115C42.00\",\"SU\",\"SU\",\"SU\",42,\"2021-01-15\",0,0,3.65,3.95,90,30,3.95,0,3.15,0,0,0,0,0,0,3.95,69,29.235\r\n\"2018-12-27\",\"SU
\ 210115C44.00\",\"SU\",\"SU\",\"SU\",44,\"2021-01-15\",0,0,2.8,3.35,91,31,3.35,0,2.71,0,0,0,0,0,0,3.35,44,28.119\r\n\"2018-12-27\",\"SU
\ 210115C46.00\",\"SU\",\"SU\",\"SU\",46,\"2021-01-15\",0,0,2.57,2.87,92,51,2.87,0,2.28,0,0,0,0,0,0,2.87,0,28.57\r\n\"2018-12-27\",\"SU
\ 210115C48.00\",\"SU\",\"SU\",\"SU\",48,\"2021-01-15\",0,0,2.15,2.43,52,52,2.43,0,1.93,0,0,0,0,0,0,2.43,0,28.296\r\n\"2018-12-27\",\"SU
\ 210115C50.00\",\"SU\",\"SU\",\"SU\",50,\"2021-01-15\",0,0,1.8,2.08,54,20,2.08,3,1.64,-0.03,1.61,1.61,1.61,4,1,2.08,197,28.157\r\n\"2018-12-27\",\"SU
\ 210115C52.00\",\"SU\",\"SU\",\"SU\",52,\"2021-01-15\",0,0,1.34,1.76,95,54,1.76,0,1.39,0,0,0,0,0,0,1.76,54,27.441\r\n\"2018-12-27\",\"SU
\ 210115C54.00\",\"SU\",\"SU\",\"SU\",54,\"2021-01-15\",0,0,1.27,1.49,96,56,1.49,0,1.19,0,0,0,0,0,0,1.49,6,27.879\r\n\"2018-12-27\",\"SU
\ 210115C56.00\",\"SU\",\"SU\",\"SU\",56,\"2021-01-15\",0,0,1.07,1.27,98,57,1.27,0,1.01,0,0,0,0,0,0,1.27,14,27.824\r\n\"2018-12-27\",\"SU
\ 210115C58.00\",\"SU\",\"SU\",\"SU\",58,\"2021-01-15\",0,0,0.89,1.09,100,59,1.09,0,0.96,0,0,0,0,0,0,1.09,11,27.763\r\n\"2018-12-27\",\"SU
\ 181228P34.00\",\"SU\",\"SU\",\"SU\",34,\"2018-12-28\",1,0,0,0.1,0,72,0.1,0,0,0,0,0,0,0,0,0.1,0,118.26\r\n\"2018-12-27\",\"SU
\ 181228P34.50\",\"SU\",\"SU\",\"SU\",34.5,\"2018-12-28\",1,0,0,0.1,0,70,0.1,0,0.23,0,0,0,0,0,0,0.1,0,104.233\r\n\"2018-12-27\",\"SU
\ 181228P35.00\",\"SU\",\"SU\",\"SU\",35,\"2018-12-28\",1,0,0,0.1,0,66,0.1,0,0.35,0,0,0,0,0,0,0.1,0,90.096\r\n\"2018-12-27\",\"SU
\ 181228P35.50\",\"SU\",\"SU\",\"SU\",35.5,\"2018-12-28\",1,0,0,0.09,0,20,0.09,0,0.52,0,0,0,0,0,0,0.09,140,73.904\r\n\"2018-12-27\",\"SU
\ 181228P36.00\",\"SU\",\"SU\",\"SU\",36,\"2018-12-28\",1,0,0.01,0.1,97,62,0.1,71,0.79,-0.6,0.19,0.19,0.19,12,3,0.1,0,62.666\r\n\"2018-12-27\",\"SU
\ 181228P36.50\",\"SU\",\"SU\",\"SU\",36.5,\"2018-12-28\",1,0,0.05,0.1,79,20,0.1,50,1.13,-0.93,0.34,0.34,0.2,12,3,0.1,30,52.017\r\n\"2018-12-27\",\"SU
\ 181228P37.00\",\"SU\",\"SU\",\"SU\",37,\"2018-12-28\",1,0,0.03,0.17,151,20,0.17,2,1.53,-1.07,0.46,0.46,0.46,0,1,0.17,45,38.916\r\n\"2018-12-27\",\"SU
\ 181228P37.50\",\"SU\",\"SU\",\"SU\",37.5,\"2018-12-28\",1,0,0.27,0.33,70,111,0.33,0,2,0,0,0,0,0,0,0.33,20,42.461\r\n\"2018-12-27\",\"SU
\ 181228P38.00\",\"SU\",\"SU\",\"SU\",38,\"2018-12-28\",1,0,0.5,0.64,151,111,0.64,0,2.46,0,0,0,0,0,0,0.64,25,38.866\r\n\"2018-12-27\",\"SU
\ 181228P38.50\",\"SU\",\"SU\",\"SU\",38.5,\"2018-12-28\",1,0,0.92,1.05,10,111,1.05,40,2.98,-1.57,1.46,1.46,1.41,56,3,1.05,45,41.319\r\n\"2018-12-27\",\"SU
\ 181228P39.00\",\"SU\",\"SU\",\"SU\",39,\"2018-12-28\",1,0,1.33,1.51,151,111,1.51,10,3.45,-1.25,2.2,2.2,2.2,22,1,1.51,48,0\r\n\"2018-12-27\",\"SU
\ 181228P39.50\",\"SU\",\"SU\",\"SU\",39.5,\"2018-12-28\",1,0,1.88,2.01,10,111,2.01,0,3.95,0,0,0,0,0,0,2.01,45,45.421\r\n\"2018-12-27\",\"SU
\ 181228P40.00\",\"SU\",\"SU\",\"SU\",40,\"2018-12-28\",1,0,2.34,2.49,10,10,2.49,0,4.45,0,0,0,0,0,0,2.49,45,0\r\n\"2018-12-27\",\"SU
\ 181228P40.50\",\"SU\",\"SU\",\"SU\",40.5,\"2018-12-28\",1,0,2.83,2.99,10,10,2.99,0,4.95,0,0,0,0,0,0,2.99,0,0\r\n\"2018-12-27\",\"SU
\ 181228P41.00\",\"SU\",\"SU\",\"SU\",41,\"2018-12-28\",1,0,3.35,3.5,10,10,3.5,0,5.45,0,0,0,0,0,0,3.5,1,0\r\n\"2018-12-27\",\"SU
\ 181228P41.50\",\"SU\",\"SU\",\"SU\",41.5,\"2018-12-28\",1,0,3.85,4,10,10,4,0,5.95,0,0,0,0,0,0,4,20,0\r\n\"2018-12-27\",\"SU
\ 181228P42.00\",\"SU\",\"SU\",\"SU\",42,\"2018-12-28\",1,0,4.35,4.5,10,10,4.5,0,6.45,0,0,0,0,0,0,4.5,10,0\r\n\"2018-12-27\",\"SU
\ 181228P42.50\",\"SU\",\"SU\",\"SU\",42.5,\"2018-12-28\",1,0,4.85,5,10,10,5,0,6.95,0,0,0,0,0,0,5,10,0\r\n\"2018-12-27\",\"SU
\ 181228P43.00\",\"SU\",\"SU\",\"SU\",43,\"2018-12-28\",1,0,5.35,5.5,10,10,5.5,8,7.45,-1.45,6.15,6.15,6,48,2,5.5,30,0\r\n\"2018-12-27\",\"SU
\ 181228P43.50\",\"SU\",\"SU\",\"SU\",43.5,\"2018-12-28\",1,0,5.85,6,10,10,6,0,7.95,0,0,0,0,0,0,6,40,0\r\n\"2018-12-27\",\"SU
\ 181228P44.00\",\"SU\",\"SU\",\"SU\",44,\"2018-12-28\",1,0,6.3,6.5,10,10,6.5,0,8.45,0,0,0,0,0,0,6.5,30,0\r\n\"2018-12-27\",\"SU
\ 181228P44.50\",\"SU\",\"SU\",\"SU\",44.5,\"2018-12-28\",1,0,6.8,7,10,10,7,0,8.95,0,0,0,0,0,0,7,0,0\r\n\"2018-12-27\",\"SU
\ 181228P45.00\",\"SU\",\"SU\",\"SU\",45,\"2018-12-28\",1,0,7.3,7.5,10,10,7.5,0,9.45,0,0,0,0,0,0,7.5,10,0\r\n\"2018-12-27\",\"SU
\ 181228P45.50\",\"SU\",\"SU\",\"SU\",45.5,\"2018-12-28\",1,0,7.85,8,80,50,8,0,9.95,0,0,0,0,0,0,8,30,0\r\n\"2018-12-27\",\"SU
\ 181228P46.00\",\"SU\",\"SU\",\"SU\",46,\"2018-12-28\",1,0,8.35,8.5,80,50,8.5,0,10.45,0,0,0,0,0,0,8.5,62,0\r\n\"2018-12-27\",\"SU
\ 190104P34.00\",\"SU\",\"SU\",\"SU\",34,\"2019-01-04\",1,0,0.07,0.17,68,63,0.17,0,0,0,0,0,0,0,0,0.17,0,51.152\r\n\"2018-12-27\",\"SU
\ 190104P34.50\",\"SU\",\"SU\",\"SU\",34.5,\"2019-01-04\",1,0,0.1,0.15,44,59,0.15,0,0.49,0,0,0,0,0,0,0.15,0,45.974\r\n\"2018-12-27\",\"SU
\ 190104P35.00\",\"SU\",\"SU\",\"SU\",35,\"2019-01-04\",1,0,0.14,0.18,81,167,0.18,0,0.65,0,0,0,0,0,0,0.18,0,43.299\r\n\"2018-12-27\",\"SU
\ 190104P35.50\",\"SU\",\"SU\",\"SU\",35.5,\"2019-01-04\",1,0,0.18,0.24,170,54,0.24,0,0.85,0,0,0,0,0,0,0.24,0,40.849\r\n\"2018-12-27\",\"SU
\ 190104P36.00\",\"SU\",\"SU\",\"SU\",36,\"2019-01-04\",1,0,0.27,0.32,74,52,0.32,0,1.1,0,0,0,0,0,0,0.32,0,39.448\r\n\"2018-12-27\",\"SU
\ 190104P36.50\",\"SU\",\"SU\",\"SU\",36.5,\"2019-01-04\",1,0,0.35,0.42,20,20,0.42,20,1.41,-0.73,0.68,0.68,0.68,13,1,0.42,20,36.773\r\n\"2018-12-27\",\"SU
\ 190104P37.00\",\"SU\",\"SU\",\"SU\",37,\"2019-01-04\",1,0,0.5,0.58,200,50,0.58,2,1.76,-0.91,0.85,0.85,0.85,1,1,0.58,0,35.684\r\n\"2018-12-27\",\"SU
\ 190104P37.50\",\"SU\",\"SU\",\"SU\",37.5,\"2019-01-04\",1,0,0.67,0.79,150,50,0.79,0,2.14,0,0,0,0,0,0,0.79,0,34.11\r\n\"2018-12-27\",\"SU
\ 190104P38.00\",\"SU\",\"SU\",\"SU\",38,\"2019-01-04\",1,0,0.96,1.03,70,20,1.03,0,2.57,0,0,0,0,0,0,1.03,40,33.624\r\n\"2018-12-27\",\"SU
\ 190104P38.50\",\"SU\",\"SU\",\"SU\",38.5,\"2019-01-04\",1,0,1.15,1.36,150,51,1.36,0,3.05,0,0,0,0,0,0,1.36,0,30.22\r\n\"2018-12-27\",\"SU
\ 190104P39.00\",\"SU\",\"SU\",\"SU\",39,\"2019-01-04\",1,0,1.59,1.73,10,52,1.73,0,3.5,0,0,0,0,0,0,1.73,20,31.639\r\n\"2018-12-27\",\"SU
\ 190104P39.50\",\"SU\",\"SU\",\"SU\",39.5,\"2019-01-04\",1,0,2.01,2.13,10,10,2.13,0,4,0,0,0,0,0,0,2.13,42,31.15\r\n\"2018-12-27\",\"SU
\ 190104P40.00\",\"SU\",\"SU\",\"SU\",40,\"2019-01-04\",1,0,2.3,2.58,10,10,2.58,0,4.5,0,0,0,0,0,0,2.58,29,0\r\n\"2018-12-27\",\"SU
\ 190104P40.50\",\"SU\",\"SU\",\"SU\",40.5,\"2019-01-04\",1,0,2.95,3.05,10,10,3.05,10,5,-1.4,3.6,3.6,3.6,36,1,3.05,20,33.397\r\n\"2018-12-27\",\"SU
\ 190104P41.00\",\"SU\",\"SU\",\"SU\",41,\"2019-01-04\",1,0,3.4,3.55,60,54,3.55,0,5.45,0,0,0,0,0,0,3.55,0,29.451\r\n\"2018-12-27\",\"SU
\ 190104P41.50\",\"SU\",\"SU\",\"SU\",41.5,\"2019-01-04\",1,0,3.9,4,93,10,4,0,5.95,0,0,0,0,0,0,4,0,42.286\r\n\"2018-12-27\",\"SU
\ 190104P42.00\",\"SU\",\"SU\",\"SU\",42,\"2019-01-04\",1,0,4.4,4.5,83,43,4.5,10,6.45,-1.35,5.1,5.1,5.1,51,1,4.5,40,34.326\r\n\"2018-12-27\",\"SU
\ 190104P42.50\",\"SU\",\"SU\",\"SU\",42.5,\"2019-01-04\",1,0,4.9,5,83,10,5,0,6.95,0,0,0,0,0,0,5,20,31.459\r\n\"2018-12-27\",\"SU
\ 190104P43.00\",\"SU\",\"SU\",\"SU\",43,\"2019-01-04\",1,0,5.4,5.5,82,10,5.5,0,7.45,0,0,0,0,0,0,5.5,15,34.415\r\n\"2018-12-27\",\"SU
\ 190104P43.50\",\"SU\",\"SU\",\"SU\",43.5,\"2019-01-04\",1,0,5.9,6,82,42,6,0,7.95,0,0,0,0,0,0,6,10,55.422\r\n\"2018-12-27\",\"SU
\ 190104P44.00\",\"SU\",\"SU\",\"SU\",44,\"2019-01-04\",1,0,6.4,6.5,82,42,6.5,0,8.45,0,0,0,0,0,0,6.5,20,39.591\r\n\"2018-12-27\",\"SU
\ 190104P44.50\",\"SU\",\"SU\",\"SU\",44.5,\"2019-01-04\",1,0,6.9,7,81,41,7,0,8.95,0,0,0,0,0,0,7,0,40.07\r\n\"2018-12-27\",\"SU
\ 190104P45.00\",\"SU\",\"SU\",\"SU\",45,\"2019-01-04\",1,0,7.4,7.5,81,41,7.5,0,9.45,0,0,0,0,0,0,7.5,15,44.809\r\n\"2018-12-27\",\"SU
\ 190104P45.50\",\"SU\",\"SU\",\"SU\",45.5,\"2019-01-04\",1,0,7.85,8,10,41,8,0,9.95,0,0,0,0,0,0,8,42,0\r\n\"2018-12-27\",\"SU
\ 190104P46.00\",\"SU\",\"SU\",\"SU\",46,\"2019-01-04\",1,0,8.35,8.5,10,41,8.5,0,10.45,0,0,0,0,0,0,8.5,0,0\r\n\"2018-12-27\",\"SU
\ 190111P34.00\",\"SU\",\"SU\",\"SU\",34,\"2019-01-11\",1,0,0.19,0.23,51,57,0.23,0,0,0,0,0,0,0,0,0.23,0,43.718\r\n\"2018-12-27\",\"SU
\ 190111P34.50\",\"SU\",\"SU\",\"SU\",34.5,\"2019-01-11\",1,0,0.24,0.28,99,35,0.28,0,0.72,0,0,0,0,0,0,0.28,0,42.027\r\n\"2018-12-27\",\"SU
\ 190111P35.00\",\"SU\",\"SU\",\"SU\",35,\"2019-01-11\",1,0,0.31,0.36,96,53,0.36,0,0.89,0,0,0,0,0,0,0.36,0,40.957\r\n\"2018-12-27\",\"SU
\ 190111P35.50\",\"SU\",\"SU\",\"SU\",35.5,\"2019-01-11\",1,0,0.39,0.45,94,52,0.45,0,1.1,0,0,0,0,0,0,0.45,0,39.515\r\n\"2018-12-27\",\"SU
\ 190111P36.00\",\"SU\",\"SU\",\"SU\",36,\"2019-01-11\",1,0,0.5,0.55,60,51,0.55,0,1.35,0,0,0,0,0,0,0.55,2,38.063\r\n\"2018-12-27\",\"SU
\ 190111P36.50\",\"SU\",\"SU\",\"SU\",36.5,\"2019-01-11\",1,0,0.63,0.69,91,51,0.69,0,1.64,0,0,0,0,0,0,0.69,5,36.816\r\n\"2018-12-27\",\"SU
\ 190111P37.00\",\"SU\",\"SU\",\"SU\",37,\"2019-01-11\",1,0,0.8,0.86,60,50,0.86,0,1.97,0,0,0,0,0,0,0.86,36,35.756\r\n\"2018-12-27\",\"SU
\ 190111P37.50\",\"SU\",\"SU\",\"SU\",37.5,\"2019-01-11\",1,0,1.01,1.08,60,50,1.08,0,2.33,0,0,0,0,0,0,1.08,20,35.062\r\n\"2018-12-27\",\"SU
\ 190111P38.00\",\"SU\",\"SU\",\"SU\",38,\"2019-01-11\",1,0,1.24,1.32,10,20,1.32,20,2.72,-1.01,1.71,1.71,1.71,34,1,1.32,15,33.805\r\n\"2018-12-27\",\"SU
\ 190111P38.50\",\"SU\",\"SU\",\"SU\",38.5,\"2019-01-11\",1,0,1.52,1.62,148,50,1.62,0,3.15,0,0,0,0,0,0,1.62,20,33.092\r\n\"2018-12-27\",\"SU
\ 190111P39.00\",\"SU\",\"SU\",\"SU\",39,\"2019-01-11\",1,0,1.88,1.96,20,51,1.96,0,3.6,0,0,0,0,0,0,1.96,0,33.216\r\n\"2018-12-27\",\"SU
\ 190111P39.50\",\"SU\",\"SU\",\"SU\",39.5,\"2019-01-11\",1,0,2.21,2.33,10,52,2.33,0,4.05,0,0,0,0,0,0,2.33,0,32.001\r\n\"2018-12-27\",\"SU
\ 190111P40.00\",\"SU\",\"SU\",\"SU\",40,\"2019-01-11\",1,0,2.62,2.74,34,33,2.74,0,4.55,0,0,0,0,0,0,2.74,10,32.021\r\n\"2018-12-27\",\"SU
\ 190111P40.50\",\"SU\",\"SU\",\"SU\",40.5,\"2019-01-11\",1,0,3.05,3.15,84,10,3.15,0,5,0,0,0,0,0,0,3.15,10,31.22\r\n\"2018-12-27\",\"SU
\ 190111P41.00\",\"SU\",\"SU\",\"SU\",41,\"2019-01-11\",1,0,3.5,3.6,84,10,3.6,0,5.5,0,0,0,0,0,0,3.6,0,30.909\r\n\"2018-12-27\",\"SU
\ 190111P41.50\",\"SU\",\"SU\",\"SU\",41.5,\"2019-01-11\",1,0,3.75,4.1,10,54,4.1,0,6,0,0,0,0,0,0,4.1,0,0\r\n\"2018-12-27\",\"SU
\ 190111P42.00\",\"SU\",\"SU\",\"SU\",42,\"2019-01-11\",1,0,4.45,4.55,84,44,4.55,0,6.5,0,0,0,0,0,0,4.55,10,37.616\r\n\"2018-12-27\",\"SU
\ 190111P42.50\",\"SU\",\"SU\",\"SU\",42.5,\"2019-01-11\",1,0,4.95,5.05,54,34,5.05,0,7,0,0,0,0,0,0,5.05,30,30.331\r\n\"2018-12-27\",\"SU
\ 190111P43.00\",\"SU\",\"SU\",\"SU\",43,\"2019-01-11\",1,0,5.4,5.55,10,53,5.55,1,7.45,-1.35,6.1,6.1,6.1,6,1,5.55,2,41.844\r\n\"2018-12-27\",\"SU
\ 190111P43.50\",\"SU\",\"SU\",\"SU\",43.5,\"2019-01-11\",1,0,5.9,6,83,10,6,0,8,0,0,0,0,0,0,6,10,0\r\n\"2018-12-27\",\"SU
\ 190118P30.00\",\"SU\",\"SU\",\"SU\",30,\"2019-01-18\",1,0,0.07,0.18,93,69,0.18,1,0.18,-0.04,0.14,0.14,0.14,0,1,0.18,26,58.662\r\n\"2018-12-27\",\"SU
\ 190118P32.00\",\"SU\",\"SU\",\"SU\",32,\"2019-01-18\",1,0,0.14,0.18,117,62,0.18,61,0.34,-0.15,0.21,0.21,0.19,11,4,0.18,361,47.523\r\n\"2018-12-27\",\"SU
\ 190118P34.00\",\"SU\",\"SU\",\"SU\",34,\"2019-01-18\",1,0,0.31,0.34,78,20,0.34,0,0.73,0,0,0,0,0,0,0.34,319,41.631\r\n\"2018-12-27\",\"SU
\ 190118P36.00\",\"SU\",\"SU\",\"SU\",36,\"2019-01-18\",1,0,0.64,0.74,60,51,0.74,50,1.53,-0.63,0.96,0.96,0.9,46,3,0.74,159,36.491\r\n\"2018-12-27\",\"SU
\ 190118P38.00\",\"SU\",\"SU\",\"SU\",38,\"2019-01-18\",1,0,1.41,1.54,167,50,1.54,40,2.85,-1.14,1.76,1.76,1.71,68,3,1.54,505,33.04\r\n\"2018-12-27\",\"SU
\ 190118P40.00\",\"SU\",\"SU\",\"SU\",40,\"2019-01-18\",1,0,2.75,2.88,70,52,2.88,35,4.6,-1.2,3.3,3.4,3.3,118,3,2.88,1336,31.321\r\n\"2018-12-27\",\"SU
\ 190118P42.00\",\"SU\",\"SU\",\"SU\",42,\"2019-01-18\",1,0,4.5,4.65,114,54,4.65,5,6.5,-1.45,5.8,5.8,5.05,26,4,4.65,227,31.572\r\n\"2018-12-27\",\"SU
\ 190118P44.00\",\"SU\",\"SU\",\"SU\",44,\"2019-01-18\",1,0,6.4,6.55,70,10,6.55,0,8.5,0,0,0,0,0,0,6.55,1336,23.021\r\n\"2018-12-27\",\"SU
\ 190118P46.00\",\"SU\",\"SU\",\"SU\",46,\"2019-01-18\",1,0,8.4,8.5,112,107,8.5,6,10.45,-1.45,9,9,9,54,1,8.5,1318,0\r\n\"2018-12-27\",\"SU
\ 190118P48.00\",\"SU\",\"SU\",\"SU\",48,\"2019-01-18\",1,0,10.4,10.5,80,41,10.5,10,12.45,-1.05,11.4,11.4,11.4,114,1,10.5,113,0\r\n\"2018-12-27\",\"SU
\ 190118P50.00\",\"SU\",\"SU\",\"SU\",50,\"2019-01-18\",1,0,12.4,12.5,91,31,12.5,0,14.45,0,0,0,0,0,0,12.5,232,0\r\n\"2018-12-27\",\"SU
\ 190118P52.00\",\"SU\",\"SU\",\"SU\",52,\"2019-01-18\",1,0,14.4,14.5,80,40,14.5,0,16.45,0,0,0,0,0,0,14.5,30,0\r\n\"2018-12-27\",\"SU
\ 190118P54.00\",\"SU\",\"SU\",\"SU\",54,\"2019-01-18\",1,0,16.35,16.5,70,50,16.5,0,18.45,0,0,0,0,0,0,16.5,22,0\r\n\"2018-12-27\",\"SU
\ 190118P56.00\",\"SU\",\"SU\",\"SU\",56,\"2019-01-18\",1,0,18.35,18.5,70,50,18.5,0,20.45,0,0,0,0,0,0,18.5,0,0\r\n\"2018-12-27\",\"SU
\ 190118P58.00\",\"SU\",\"SU\",\"SU\",58,\"2019-01-18\",1,0,20.35,20.5,70,50,20.5,0,22.45,0,0,0,0,0,0,20.5,1,0\r\n\"2018-12-27\",\"SU
\ 190118P60.00\",\"SU\",\"SU\",\"SU\",60,\"2019-01-18\",1,0,22.35,22.5,70,50,22.5,0,24.45,0,0,0,0,0,0,22.5,0,0\r\n\"2018-12-27\",\"SU
\ 190215P30.00\",\"SU\",\"SU\",\"SU\",30,\"2019-02-15\",1,0,0.23,0.29,112,62,0.29,47,0.38,-0.11,0.28,0.28,0.27,12,2,0.29,0,46.169\r\n\"2018-12-27\",\"SU
\ 190215P32.00\",\"SU\",\"SU\",\"SU\",32,\"2019-02-15\",1,0,0.37,0.42,90,56,0.42,158,0.67,-0.2,0.44,0.47,0.44,69,7,0.42,0,40.643\r\n\"2018-12-27\",\"SU
\ 190215P34.00\",\"SU\",\"SU\",\"SU\",34,\"2019-02-15\",1,0,0.68,0.74,112,42,0.74,0,1.18,0,0,0,0,0,0,0.74,50,37.551\r\n\"2018-12-27\",\"SU
\ 190215P36.00\",\"SU\",\"SU\",\"SU\",36,\"2019-02-15\",1,0,1.18,1.24,71,50,1.24,0,2.03,0,0,0,0,0,0,1.24,425,34.152\r\n\"2018-12-27\",\"SU
\ 190215P38.00\",\"SU\",\"SU\",\"SU\",38,\"2019-02-15\",1,0,2,2.07,50,20,2.07,20,3.25,-0.97,2.28,2.28,2.28,45,1,2.07,115,31.516\r\n\"2018-12-27\",\"SU
\ 190215P40.00\",\"SU\",\"SU\",\"SU\",40,\"2019-02-15\",1,0,3.2,3.35,91,81,3.35,10,4.85,-1.4,3.45,3.45,3.45,34,1,3.35,0,30.104\r\n\"2018-12-27\",\"SU
\ 190215P42.00\",\"SU\",\"SU\",\"SU\",42,\"2019-02-15\",1,0,4.65,4.9,10,63,4.9,0,6.65,0,0,0,0,0,0,4.9,0,26.816\r\n\"2018-12-27\",\"SU
\ 190215P44.00\",\"SU\",\"SU\",\"SU\",44,\"2019-02-15\",1,0,6.55,6.65,44,34,6.65,10,8.55,-1.55,7,7,7,70,1,6.65,37,28.918\r\n\"2018-12-27\",\"SU
\ 190215P46.00\",\"SU\",\"SU\",\"SU\",46,\"2019-02-15\",1,0,8.45,8.6,43,53,8.6,0,10.5,0,0,0,0,0,0,8.6,20,18.4\r\n\"2018-12-27\",\"SU
\ 190315P30.00\",\"SU\",\"SU\",\"SU\",30,\"2019-03-15\",1,0,0.38,0.46,152,58,0.46,70,0.61,-0.17,0.44,0.45,0.44,30,3,0.46,0,42.198\r\n\"2018-12-27\",\"SU
\ 190315P32.00\",\"SU\",\"SU\",\"SU\",32,\"2019-03-15\",1,0,0.62,0.68,186,54,0.68,0,1,0,0,0,0,0,0,0.68,131,38.664\r\n\"2018-12-27\",\"SU
\ 190315P34.00\",\"SU\",\"SU\",\"SU\",34,\"2019-03-15\",1,0,1.01,1.08,92,51,1.08,0,1.62,0,0,0,0,0,0,1.08,46,36.056\r\n\"2018-12-27\",\"SU
\ 190315P36.00\",\"SU\",\"SU\",\"SU\",36,\"2019-03-15\",1,0,1.5,1.7,150,50,1.7,1,2.53,-0.48,2.05,2.05,2.05,2,1,1.7,214,33.046\r\n\"2018-12-27\",\"SU
\ 190315P38.00\",\"SU\",\"SU\",\"SU\",38,\"2019-03-15\",1,0,2.53,2.59,70,110,2.59,2,3.8,-0.95,2.85,2.85,2.85,5,1,2.59,181,32.443\r\n\"2018-12-27\",\"SU
\ 190315P40.00\",\"SU\",\"SU\",\"SU\",40,\"2019-03-15\",1,0,3.75,3.85,91,110,3.85,0,5.3,0,0,0,0,0,0,3.85,125,31.954\r\n\"2018-12-27\",\"SU
\ 190315P42.00\",\"SU\",\"SU\",\"SU\",42,\"2019-03-15\",1,0,5.25,5.35,93,32,5.35,1,7,-1.15,5.85,5.85,5.85,5,1,5.35,425,31.832\r\n\"2018-12-27\",\"SU
\ 190315P44.00\",\"SU\",\"SU\",\"SU\",44,\"2019-03-15\",1,0,6.95,7.1,60,53,7.1,5,8.9,-1.2,7.7,7.7,7.7,38,1,7.1,740,32.796\r\n\"2018-12-27\",\"SU
\ 190315P46.00\",\"SU\",\"SU\",\"SU\",46,\"2019-03-15\",1,0,8.8,8.95,94,44,8.95,5,10.8,-1.25,9.55,9.55,9.55,47,1,8.95,156,34.48\r\n\"2018-12-27\",\"SU
\ 190315P48.00\",\"SU\",\"SU\",\"SU\",48,\"2019-03-15\",1,0,10.7,10.9,84,84,10.9,0,12.75,0,0,0,0,0,0,10.9,160,37.016\r\n\"2018-12-27\",\"SU
\ 190315P50.00\",\"SU\",\"SU\",\"SU\",50,\"2019-03-15\",1,0,12.65,12.75,83,20,12.75,0,14.7,0,0,0,0,0,0,12.75,68,39.917\r\n\"2018-12-27\",\"SU
\ 190315P52.00\",\"SU\",\"SU\",\"SU\",52,\"2019-03-15\",1,0,14.6,14.75,83,53,14.75,0,16.65,0,0,0,0,0,0,14.75,196,36.477\r\n\"2018-12-27\",\"SU
\ 190315P54.00\",\"SU\",\"SU\",\"SU\",54,\"2019-03-15\",1,0,16.6,16.7,43,53,16.7,0,18.65,0,0,0,0,0,0,16.7,30,50.68\r\n\"2018-12-27\",\"SU
\ 190315P56.00\",\"SU\",\"SU\",\"SU\",56,\"2019-03-15\",1,0,18.5,18.7,70,52,18.7,0,20.65,0,0,0,0,0,0,18.7,30,53.269\r\n\"2018-12-27\",\"SU
\ 190315P58.00\",\"SU\",\"SU\",\"SU\",58,\"2019-03-15\",1,0,20.55,20.7,82,52,20.7,0,22.65,0,0,0,0,0,0,20.7,0,58.913\r\n\"2018-12-27\",\"SU
\ 190315P60.00\",\"SU\",\"SU\",\"SU\",60,\"2019-03-15\",1,0,22.55,22.65,82,52,22.65,0,24.6,0,0,0,0,0,0,22.65,25,44.079\r\n\"2018-12-27\",\"SU
\ 190315P62.00\",\"SU\",\"SU\",\"SU\",62,\"2019-03-15\",1,0,24.5,24.65,10,52,24.65,0,26.6,0,0,0,0,0,0,24.65,2,44.777\r\n\"2018-12-27\",\"SU
\ 190315P64.00\",\"SU\",\"SU\",\"SU\",64,\"2019-03-15\",1,0,26.45,26.65,70,10,26.65,0,28.6,0,0,0,0,0,0,26.65,20,65.072\r\n\"2018-12-27\",\"SU
\ 190315P66.00\",\"SU\",\"SU\",\"SU\",66,\"2019-03-15\",1,0,28.5,28.65,81,41,28.65,0,30.6,0,0,0,0,0,0,28.65,40,71.857\r\n\"2018-12-27\",\"SU
\ 190621P30.00\",\"SU\",\"SU\",\"SU\",30,\"2019-06-21\",1,0,0.83,0.91,55,54,0.91,0,1.21,0,0,0,0,0,0,0.91,0,35.636\r\n\"2018-12-27\",\"SU
\ 190621P32.00\",\"SU\",\"SU\",\"SU\",32,\"2019-06-21\",1,0,1.23,1.29,33,20,1.29,50,1.75,-0.38,1.37,1.37,1.37,68,2,1.29,381,33.732\r\n\"2018-12-27\",\"SU
\ 190621P34.00\",\"SU\",\"SU\",\"SU\",34,\"2019-06-21\",1,0,1.76,1.86,91,51,1.86,20,2.49,-0.45,2.04,2.04,2.04,40,1,1.86,57,32.178\r\n\"2018-12-27\",\"SU
\ 190621P36.00\",\"SU\",\"SU\",\"SU\",36,\"2019-06-21\",1,0,2.48,2.57,60,50,2.57,1,3.45,-0.87,2.58,2.58,2.58,2,1,2.57,73,30.644\r\n\"2018-12-27\",\"SU
\ 190621P38.00\",\"SU\",\"SU\",\"SU\",38,\"2019-06-21\",1,0,3.4,3.6,90,40,3.6,20,4.6,-0.75,3.85,3.85,3.85,77,1,3.6,161,29.838\r\n\"2018-12-27\",\"SU
\ 190621P40.00\",\"SU\",\"SU\",\"SU\",40,\"2019-06-21\",1,0,4.55,4.7,30,50,4.7,20,6,-0.85,5.15,5.15,5.15,103,1,4.7,1573,28.566\r\n\"2018-12-27\",\"SU
\ 190621P42.00\",\"SU\",\"SU\",\"SU\",42,\"2019-06-21\",1,0,5.95,6.15,51,51,6.15,7,7.6,-1.25,6.35,6.35,6.35,44,1,6.15,213,28.473\r\n\"2018-12-27\",\"SU
\ 190621P44.00\",\"SU\",\"SU\",\"SU\",44,\"2019-06-21\",1,0,7.5,7.85,52,82,7.85,0,9.3,0,0,0,0,0,0,7.85,94,29.032\r\n\"2018-12-27\",\"SU
\ 190621P46.00\",\"SU\",\"SU\",\"SU\",46,\"2019-06-21\",1,0,9.2,9.35,53,53,9.35,0,11.1,0,0,0,0,0,0,9.35,521,27.595\r\n\"2018-12-27\",\"SU
\ 190621P48.00\",\"SU\",\"SU\",\"SU\",48,\"2019-06-21\",1,0,11,11.35,43,83,11.35,0,12.95,0,0,0,0,0,0,11.35,21,29.63\r\n\"2018-12-27\",\"SU
\ 190621P50.00\",\"SU\",\"SU\",\"SU\",50,\"2019-06-21\",1,0,12.85,13.15,43,83,13.15,0,14.85,0,0,0,0,0,0,13.15,34,29.368\r\n\"2018-12-27\",\"SU
\ 190621P52.00\",\"SU\",\"SU\",\"SU\",52,\"2019-06-21\",1,0,14.75,15.05,43,83,15.05,0,16.8,0,0,0,0,0,0,15.05,44,29.823\r\n\"2018-12-27\",\"SU
\ 190621P54.00\",\"SU\",\"SU\",\"SU\",54,\"2019-06-21\",1,0,16.7,17,20,83,17,0,18.75,0,0,0,0,0,0,17,126,33.782\r\n\"2018-12-27\",\"SU
\ 190621P56.00\",\"SU\",\"SU\",\"SU\",56,\"2019-06-21\",1,0,18.65,18.85,20,52,18.85,0,20.7,0,0,0,0,0,0,18.85,109,36.717\r\n\"2018-12-27\",\"SU
\ 190621P58.00\",\"SU\",\"SU\",\"SU\",58,\"2019-06-21\",1,0,20.6,20.8,20,52,20.8,0,22.65,0,0,0,0,0,0,20.8,70,37.802\r\n\"2018-12-27\",\"SU
\ 200117P32.00\",\"SU\",\"SU\",\"SU\",32,\"2020-01-17\",1,0,1.36,2.49,60,91,2.49,0,2.98,0,0,0,0,0,0,2.49,0,27.842\r\n\"2018-12-27\",\"SU
\ 200117P34.00\",\"SU\",\"SU\",\"SU\",34,\"2020-01-17\",1,0,2.97,3.15,30,90,3.15,0,3.8,0,0,0,0,0,0,3.15,250,30.351\r\n\"2018-12-27\",\"SU
\ 200117P36.00\",\"SU\",\"SU\",\"SU\",36,\"2020-01-17\",1,0,3.8,3.9,50,1,3.9,0,4.75,0,0,0,0,0,0,3.9,192,29.07\r\n\"2018-12-27\",\"SU
\ 200117P38.00\",\"SU\",\"SU\",\"SU\",38,\"2020-01-17\",1,0,4.75,5.4,40,90,5.4,0,5.95,0,0,0,0,0,0,5.4,379,29.858\r\n\"2018-12-27\",\"SU
\ 200117P40.00\",\"SU\",\"SU\",\"SU\",40,\"2020-01-17\",1,0,5.9,6.1,40,50,6.1,0,7.25,0,0,0,0,0,0,6.1,179,27.705\r\n\"2018-12-27\",\"SU
\ 200117P42.00\",\"SU\",\"SU\",\"SU\",42,\"2020-01-17\",1,0,7.15,7.5,51,80,7.5,0,8.7,0,0,0,0,0,0,7.5,230,27.398\r\n\"2018-12-27\",\"SU
\ 200117P44.00\",\"SU\",\"SU\",\"SU\",44,\"2020-01-17\",1,0,7.2,8.9,60,91,8.9,0,10.2,0,0,0,0,0,0,8.9,131,21.323\r\n\"2018-12-27\",\"SU
\ 200117P46.00\",\"SU\",\"SU\",\"SU\",46,\"2020-01-17\",1,0,10.1,11.05,52,91,11.05,0,11.9,0,0,0,0,0,0,11.05,264,29.012\r\n\"2018-12-27\",\"SU
\ 200117P48.00\",\"SU\",\"SU\",\"SU\",48,\"2020-01-17\",1,0,11.65,12.05,42,52,12.05,0,13.55,0,0,0,0,0,0,12.05,100,25.673\r\n\"2018-12-27\",\"SU
\ 200117P50.00\",\"SU\",\"SU\",\"SU\",50,\"2020-01-17\",1,0,13.4,13.65,52,52,13.65,8,15.3,-1.15,14.15,14.15,14.15,113,1,13.65,450,24.923\r\n\"2018-12-27\",\"SU
\ 200117P52.00\",\"SU\",\"SU\",\"SU\",52,\"2020-01-17\",1,0,15.2,15.5,20,52,15.5,0,17.15,0,0,0,0,0,0,15.5,229,25.261\r\n\"2018-12-27\",\"SU
\ 200117P54.00\",\"SU\",\"SU\",\"SU\",54,\"2020-01-17\",1,0,17,17.3,20,52,17.3,0,19,0,0,0,0,0,0,17.3,70,24.637\r\n\"2018-12-27\",\"SU
\ 200117P56.00\",\"SU\",\"SU\",\"SU\",56,\"2020-01-17\",1,0,18.85,19.25,20,92,19.25,0,20.9,0,0,0,0,0,0,19.25,20,25.181\r\n\"2018-12-27\",\"SU
\ 200117P58.00\",\"SU\",\"SU\",\"SU\",58,\"2020-01-17\",1,0,20.7,21.05,52,52,21.05,0,22.8,0,0,0,0,0,0,21.05,60,21.017\r\n\"2018-12-27\",\"SU
\ 200117P60.00\",\"SU\",\"SU\",\"SU\",60,\"2020-01-17\",1,0,22.6,22.9,52,52,22.9,0,24.7,0,0,0,0,0,0,22.9,56,26.889\r\n\"2018-12-27\",\"SU
\ 210115P32.00\",\"SU\",\"SU\",\"SU\",32,\"2021-01-15\",1,0,3.45,3.95,50,90,3.95,0,4.3,0,0,0,0,0,0,3.95,0,29.381\r\n\"2018-12-27\",\"SU
\ 210115P34.00\",\"SU\",\"SU\",\"SU\",34,\"2021-01-15\",1,0,4.25,4.55,50,50,4.55,0,5.2,0,0,0,0,0,0,4.55,3,27.999\r\n\"2018-12-27\",\"SU
\ 210115P36.00\",\"SU\",\"SU\",\"SU\",36,\"2021-01-15\",1,0,5.15,5.45,50,50,5.45,0,6.25,0,0,0,0,0,0,5.45,6,27.205\r\n\"2018-12-27\",\"SU
\ 210115P38.00\",\"SU\",\"SU\",\"SU\",38,\"2021-01-15\",1,0,6.1,6.45,50,50,6.45,0,7.35,0,0,0,0,0,0,6.45,48,26.295\r\n\"2018-12-27\",\"SU
\ 210115P40.00\",\"SU\",\"SU\",\"SU\",40,\"2021-01-15\",1,0,7.25,7.6,30,90,7.6,0,8.6,0,0,0,0,0,0,7.6,41,25.77\r\n\"2018-12-27\",\"SU
\ 210115P42.00\",\"SU\",\"SU\",\"SU\",42,\"2021-01-15\",1,0,8.4,9.8,50,90,9.8,0,9.9,0,0,0,0,0,0,9.8,105,27.454\r\n\"2018-12-27\",\"SU
\ 210115P44.00\",\"SU\",\"SU\",\"SU\",44,\"2021-01-15\",1,0,9.7,10.1,51,20,10.1,0,11.35,0,0,0,0,0,0,10.1,50,24.135\r\n\"2018-12-27\",\"SU
\ 210115P46.00\",\"SU\",\"SU\",\"SU\",46,\"2021-01-15\",1,0,11.1,11.5,51,20,11.5,0,12.85,0,0,0,0,0,0,11.5,0,23.441\r\n\"2018-12-27\",\"SU
\ 210115P48.00\",\"SU\",\"SU\",\"SU\",48,\"2021-01-15\",1,0,12.6,12.95,51,20,12.95,0,14.4,0,0,0,0,0,0,12.95,10,22.678\r\n\"2018-12-27\",\"SU
\ 210115P50.00\",\"SU\",\"SU\",\"SU\",50,\"2021-01-15\",1,0,14.15,14.55,52,91,14.55,0,16.05,0,0,0,0,0,0,14.55,24,22.05\r\n\"2018-12-27\",\"SU
\ 210115P52.00\",\"SU\",\"SU\",\"SU\",52,\"2021-01-15\",1,0,15.8,16.15,32,52,16.15,0,17.7,0,0,0,0,0,0,16.15,70,21.257\r\n\"2018-12-27\",\"SU
\ 210115P54.00\",\"SU\",\"SU\",\"SU\",54,\"2021-01-15\",1,0,17.5,17.8,32,20,17.8,0,19.45,0,0,0,0,0,0,17.8,20,20.272\r\n\"2018-12-27\",\"SU
\ 210115P56.00\",\"SU\",\"SU\",\"SU\",56,\"2021-01-15\",1,0,19.2,19.6,20,92,19.6,0,21.25,0,0,0,0,0,0,19.6,40,19.395\r\n\"2018-12-27\",\"SU
\ 210115P58.00\",\"SU\",\"SU\",\"SU\",58,\"2021-01-15\",1,0,21,21.35,32,92,21.35,0,23.05,0,0,0,0,0,0,21.35,32,16.389"
headers:
Cache-Control:
- max-age=0, no-cache, must-revalidate
Connection:
- close
Content-Disposition:
- attachment; filename="quote_SU_20181227.csv"
Content-Length:
- '40485'
Content-Type:
- text/csv;charset=UTF-8
Date:
- Sat, 10 Jun 2023 22:49:51 GMT
Expires:
- '0'
Pragma:
- no-cache
Server:
- Apache
Set-Cookie:
- PHPSESSID=9dje66jnp91sghmij5a5vg9j6j; expires=Sun, 11-Jun-2023 02:49:50 GMT;
Max-Age=14400; path=/
Vary:
- Accept-Encoding
Via:
- 1.1 446e26a256db1310ae719d818e420898.cloudfront.net (CloudFront)
X-Amz-Cf-Id:
- RuvcRVycTsaEj56tYDhf0DzrajiWTXfsIupKW6J7VncAhtBnUmaDKA==
X-Amz-Cf-Pop:
- SEA19-C3
X-Cache:
- Miss from cloudfront
status:
code: 200
message: OK
- request:
body: null
headers:
Connection:
- close
Host:
- www.m-x.ca
User-Agent:
- Python-urllib/3.10
method: GET
uri: https://www.m-x.ca/en/trading/data/historical?dnld=1&from=2020-07-02&symbol=SU&to=2020-07-02
response:
body:
string: "\"Date\",\"Symbol\",\"Class Symbol\",\"Root Symbol\",\"Underlying Symbol\",\"Strike
Price\",\"Expiry Date\",\"Call/Put\",\"Ins. Type\",\"Bid Price\",\"Ask Price\",\"Bid
Size\",\"Ask Size\",\"Last Price\",\"Volume\",\"Last Close Price\",\"Net Change\",\"Open
Price\",\"High Price\",\"Low Price\",\"Total Value\",\"Nb. Trades\",\"Settlement
Price\",\"Open Interest\",\"Implied Volatility\"\r\n\"2020-07-02\",\"SU\",\"\",\"\",\"\",0,\"\",0,3,22.72,22.79,5,1,22.74,5274139,22.89,-0.15,22.8,23.46,22.71,121126783,18560,0,0,0\r\n\"2020-07-02\",\"SU
\ 200703C20.50\",\"SU\",\"SU\",\"SU\",20.5,\"2020-07-03\",0,0,2.18,2.28,24,14,2.28,0,2.46,0,0,0,0,0,0,2.28,0,0\r\n\"2020-07-02\",\"SU
\ 200703C21.00\",\"SU\",\"SU\",\"SU\",21,\"2020-07-03\",0,0,1.69,1.78,24,14,1.78,0,1.96,0,0,0,0,0,0,1.78,0,0\r\n\"2020-07-02\",\"SU
\ 200703C21.50\",\"SU\",\"SU\",\"SU\",21.5,\"2020-07-03\",0,0,1.19,1.28,24,14,1.28,0,1.48,0,0,0,0,0,0,1.28,25,0\r\n\"2020-07-02\",\"SU
\ 200703C22.00\",\"SU\",\"SU\",\"SU\",22,\"2020-07-03\",0,0,0.71,0.79,14,14,0.79,11,1,-0.08,1.2,1.2,0.92,10,2,0.79,11,40.522\r\n\"2020-07-02\",\"SU
\ 200703C22.50\",\"SU\",\"SU\",\"SU\",22.5,\"2020-07-03\",0,0,0.29,0.37,55,14,0.37,0,0.6,0,0,0,0,0,0,0.37,45,39.727\r\n\"2020-07-02\",\"SU
\ 200703C23.00\",\"SU\",\"SU\",\"SU\",23,\"2020-07-03\",0,0,0.06,0.12,55,62,0.12,54,0.29,-0.17,0.26,0.44,0.12,11,10,0.12,117,40.52\r\n\"2020-07-02\",\"SU
\ 200703C23.50\",\"SU\",\"SU\",\"SU\",23.5,\"2020-07-03\",0,0,0,0.05,0,30,0.05,4,0.12,0.08,0.2,0.2,0.2,0,1,0.05,52,47.61\r\n\"2020-07-02\",\"SU
\ 200703C24.00\",\"SU\",\"SU\",\"SU\",24,\"2020-07-03\",0,0,0,0.04,0,30,0.04,0,0.07,0,0,0,0,0,0,0.04,189,65.677\r\n\"2020-07-02\",\"SU
\ 200703C24.50\",\"SU\",\"SU\",\"SU\",24.5,\"2020-07-03\",0,0,0,0.04,0,30,0.04,0,0.07,0,0,0,0,0,0,0.04,18,0\r\n\"2020-07-02\",\"SU
\ 200703C25.00\",\"SU\",\"SU\",\"SU\",25,\"2020-07-03\",0,0,0,0.04,0,30,0.04,2,0.06,-0.02,0.04,0.04,0.04,0,1,0.04,95,0\r\n\"2020-07-02\",\"SU
\ 200703C25.50\",\"SU\",\"SU\",\"SU\",25.5,\"2020-07-03\",0,0,0,0.04,0,30,0.04,0,0.06,0,0,0,0,0,0,0.04,18,0\r\n\"2020-07-02\",\"SU
\ 200703C26.00\",\"SU\",\"SU\",\"SU\",26,\"2020-07-03\",0,0,0,0.02,0,14,0.02,0,0.05,0,0,0,0,0,0,0.02,28,0\r\n\"2020-07-02\",\"SU
\ 200703C26.50\",\"SU\",\"SU\",\"SU\",26.5,\"2020-07-03\",0,0,0,0.04,0,30,0.04,0,0.05,0,0,0,0,0,0,0.04,131,0\r\n\"2020-07-02\",\"SU
\ 200703C27.00\",\"SU\",\"SU\",\"SU\",27,\"2020-07-03\",0,0,0,0.04,0,30,0.04,0,0.04,0,0,0,0,0,0,0.04,14,0\r\n\"2020-07-02\",\"SU
\ 200703C27.50\",\"SU\",\"SU\",\"SU\",27.5,\"2020-07-03\",0,0,0,0.04,0,30,0.04,0,0.04,0,0,0,0,0,0,0.04,21,0\r\n\"2020-07-02\",\"SU
\ 200703C28.00\",\"SU\",\"SU\",\"SU\",28,\"2020-07-03\",0,0,0,0.04,0,30,0.04,0,0.04,0,0,0,0,0,0,0.04,24,0\r\n\"2020-07-02\",\"SU
\ 200703C28.50\",\"SU\",\"SU\",\"SU\",28.5,\"2020-07-03\",0,0,0,0.04,0,30,0.04,0,0.04,0,0,0,0,0,0,0.04,30,0\r\n\"2020-07-02\",\"SU
\ 200703C29.00\",\"SU\",\"SU\",\"SU\",29,\"2020-07-03\",0,0,0,0.03,0,30,0.03,0,0.04,0,0,0,0,0,0,0.03,10,0\r\n\"2020-07-02\",\"SU
\ 200703C29.50\",\"SU\",\"SU\",\"SU\",29.5,\"2020-07-03\",0,0,0,0.03,0,30,0.03,0,0.04,0,0,0,0,0,0,0.03,22,0\r\n\"2020-07-02\",\"SU
\ 200703C30.00\",\"SU\",\"SU\",\"SU\",30,\"2020-07-03\",0,0,0,0.03,0,30,0.03,0,0.04,0,0,0,0,0,0,0.03,1,0\r\n\"2020-07-02\",\"SU
\ 200703C30.50\",\"SU\",\"SU\",\"SU\",30.5,\"2020-07-03\",0,0,0,0.03,0,30,0.03,0,0.04,0,0,0,0,0,0,0.03,10,0\r\n\"2020-07-02\",\"SU
\ 200710C20.50\",\"SU\",\"SU\",\"SU\",20.5,\"2020-07-10\",0,0,2.26,2.34,14,14,2.34,0,2.52,0,0,0,0,0,0,2.34,0,53.456\r\n\"2020-07-02\",\"SU
\ 200710C21.00\",\"SU\",\"SU\",\"SU\",21,\"2020-07-10\",0,0,1.79,1.88,47,30,1.88,0,2.06,0,0,0,0,0,0,1.88,8,49.154\r\n\"2020-07-02\",\"SU
\ 200710C21.50\",\"SU\",\"SU\",\"SU\",21.5,\"2020-07-10\",0,0,1.36,1.44,56,14,1.44,0,1.63,0,0,0,0,0,0,1.44,0,46.062\r\n\"2020-07-02\",\"SU
\ 200710C22.00\",\"SU\",\"SU\",\"SU\",22,\"2020-07-10\",0,0,0.97,1.04,24,14,1.04,0,1.23,0,0,0,0,0,0,1.04,150,43.385\r\n\"2020-07-02\",\"SU
\ 200710C22.50\",\"SU\",\"SU\",\"SU\",22.5,\"2020-07-10\",0,0,0.64,0.7,40,14,0.7,0,0.89,0,0,0,0,0,0,0.7,34,41.319\r\n\"2020-07-02\",\"SU
\ 200710C23.00\",\"SU\",\"SU\",\"SU\",23,\"2020-07-10\",0,0,0.38,0.45,40,44,0.45,5,0.6,0.02,0.62,0.62,0.62,3,1,0.45,90,40.188\r\n\"2020-07-02\",\"SU
\ 200710C23.50\",\"SU\",\"SU\",\"SU\",23.5,\"2020-07-10\",0,0,0.21,0.28,40,62,0.28,15,0.39,-0.01,0.45,0.45,0.38,5,2,0.28,187,40.179\r\n\"2020-07-02\",\"SU
\ 200710C24.00\",\"SU\",\"SU\",\"SU\",24,\"2020-07-10\",0,0,0.13,0.18,14,66,0.18,1,0.25,0.07,0.32,0.32,0.32,0,1,0.18,48,42.395\r\n\"2020-07-02\",\"SU
\ 200710C24.50\",\"SU\",\"SU\",\"SU\",24.5,\"2020-07-10\",0,0,0.06,0.11,40,56,0.11,35,0.17,-0.08,0.2,0.2,0.09,3,4,0.11,40,42.679\r\n\"2020-07-02\",\"SU
\ 200710C25.00\",\"SU\",\"SU\",\"SU\",25,\"2020-07-10\",0,0,0.04,0.09,14,14,0.09,0,0.12,0,0,0,0,0,0,0.09,178,47.083\r\n\"2020-07-02\",\"SU
\ 200710C25.50\",\"SU\",\"SU\",\"SU\",25.5,\"2020-07-10\",0,0,0.03,0.08,14,30,0.08,0,0.09,0,0,0,0,0,0,0.08,13,52.113\r\n\"2020-07-02\",\"SU
\ 200710C26.00\",\"SU\",\"SU\",\"SU\",26,\"2020-07-10\",0,0,0.03,0.07,14,30,0.07,0,0.09,0,0,0,0,0,0,0.07,32,57.481\r\n\"2020-07-02\",\"SU
\ 200710C26.50\",\"SU\",\"SU\",\"SU\",26.5,\"2020-07-10\",0,0,0.02,0.06,14,30,0.06,0,0.09,0,0,0,0,0,0,0.06,460,55.634\r\n\"2020-07-02\",\"SU
\ 200710C27.00\",\"SU\",\"SU\",\"SU\",27,\"2020-07-10\",0,0,0,0.06,0,30,0.06,0,0.09,0,0,0,0,0,0,0.06,16,56.408\r\n\"2020-07-02\",\"SU
\ 200710C27.50\",\"SU\",\"SU\",\"SU\",27.5,\"2020-07-10\",0,0,0,0.06,0,30,0.06,0,0.08,0,0,0,0,0,0,0.06,0,85.082\r\n\"2020-07-02\",\"SU
\ 200710C28.00\",\"SU\",\"SU\",\"SU\",28,\"2020-07-10\",0,0,0,0.06,0,30,0.06,0,0.08,0,0,0,0,0,0,0.06,10,92.307\r\n\"2020-07-02\",\"SU
\ 200710C28.50\",\"SU\",\"SU\",\"SU\",28.5,\"2020-07-10\",0,0,0,0.06,0,30,0.06,0,0.08,0,0,0,0,0,0,0.06,10,0\r\n\"2020-07-02\",\"SU
\ 200724C20.50\",\"SU\",\"SU\",\"SU\",20.5,\"2020-07-24\",0,0,2.54,2.63,30,16,2.63,0,2.82,0,0,0,0,0,0,2.63,0,55.848\r\n\"2020-07-02\",\"SU
\ 200724C21.00\",\"SU\",\"SU\",\"SU\",21,\"2020-07-24\",0,0,2.18,2.24,14,16,2.24,0,2.42,0,0,0,0,0,0,2.24,0,55.024\r\n\"2020-07-02\",\"SU
\ 200724C21.50\",\"SU\",\"SU\",\"SU\",21.5,\"2020-07-24\",0,0,1.8,1.86,14,15,1.86,3,2.04,-0.08,2.36,2.36,1.96,5,3,1.86,1,52.555\r\n\"2020-07-02\",\"SU
\ 200724C22.00\",\"SU\",\"SU\",\"SU\",22,\"2020-07-24\",0,0,1.45,1.52,14,16,1.52,0,1.69,0,0,0,0,0,0,1.52,0,50.526\r\n\"2020-07-02\",\"SU
\ 200724C22.50\",\"SU\",\"SU\",\"SU\",22.5,\"2020-07-24\",0,0,1.16,1.21,14,30,1.21,1,1.38,0.23,1.61,1.61,1.61,1,1,1.21,6,49.128\r\n\"2020-07-02\",\"SU
\ 200724C23.00\",\"SU\",\"SU\",\"SU\",23,\"2020-07-24\",0,0,0.88,0.95,30,30,0.95,0,1.11,0,0,0,0,0,0,0.95,2,47.496\r\n\"2020-07-02\",\"SU
\ 200724C23.50\",\"SU\",\"SU\",\"SU\",23.5,\"2020-07-24\",0,0,0.68,0.73,14,14,0.73,0,0.88,0,0,0,0,0,0,0.73,0,46.916\r\n\"2020-07-02\",\"SU
\ 200724C24.00\",\"SU\",\"SU\",\"SU\",24,\"2020-07-24\",0,0,0.52,0.56,14,14,0.56,1,0.69,0.08,0.77,0.77,0.77,0,1,0.56,4,46.802\r\n\"2020-07-02\",\"SU
\ 200724C24.50\",\"SU\",\"SU\",\"SU\",24.5,\"2020-07-24\",0,0,0.39,0.43,14,16,0.43,0,0.54,0,0,0,0,0,0,0.43,18,46.88\r\n\"2020-07-02\",\"SU
\ 200724C25.00\",\"SU\",\"SU\",\"SU\",25,\"2020-07-24\",0,0,0.29,0.33,14,16,0.33,22,0.42,-0.1,0.45,0.45,0.32,5,5,0.33,0,47.147\r\n\"2020-07-02\",\"SU
\ 200717C18.00\",\"SU\",\"SU\",\"SU\",18,\"2020-07-17\",0,0,4.7,4.85,76,14,4.85,0,5,0,0,0,0,0,0,4.85,0,71.652\r\n\"2020-07-02\",\"SU
\ 200717C19.00\",\"SU\",\"SU\",\"SU\",19,\"2020-07-17\",0,0,3.75,3.9,67,47,3.9,0,4.05,0,0,0,0,0,0,3.9,22,66.035\r\n\"2020-07-02\",\"SU
\ 200717C20.00\",\"SU\",\"SU\",\"SU\",20,\"2020-07-17\",0,0,2.84,2.93,14,14,2.93,14,3.1,0.15,3.25,3.25,3.25,45,1,2.93,3,57.933\r\n\"2020-07-02\",\"SU
\ 200717C21.00\",\"SU\",\"SU\",\"SU\",21,\"2020-07-17\",0,0,1.96,2.04,56,14,2.04,0,2.23,0,0,0,0,0,0,2.04,31,51.014\r\n\"2020-07-02\",\"SU
\ 200717C22.00\",\"SU\",\"SU\",\"SU\",22,\"2020-07-17\",0,0,1.21,1.29,45,26,1.29,0,1.47,0,0,0,0,0,0,1.29,93,47.051\r\n\"2020-07-02\",\"SU
\ 200717C23.00\",\"SU\",\"SU\",\"SU\",23,\"2020-07-17\",0,0,0.64,0.71,70,14,0.71,13,0.86,0.02,0.88,0.88,0.88,11,1,0.71,89,44.011\r\n\"2020-07-02\",\"SU
\ 200717C24.00\",\"SU\",\"SU\",\"SU\",24,\"2020-07-17\",0,0,0.33,0.38,14,62,0.38,5,0.49,0,0.49,0.49,0.49,2,1,0.38,301,45.008\r\n\"2020-07-02\",\"SU
\ 200717C25.00\",\"SU\",\"SU\",\"SU\",25,\"2020-07-17\",0,0,0.17,0.21,14,14,0.21,151,0.28,-0.06,0.3,0.3,0.22,36,7,0.21,714,47.387\r\n\"2020-07-02\",\"SU
\ 200717C26.00\",\"SU\",\"SU\",\"SU\",26,\"2020-07-17\",0,0,0.07,0.1,62,54,0.1,1,0.17,-0.07,0.1,0.1,0.1,0,1,0.1,3485,47.57\r\n\"2020-07-02\",\"SU
\ 200717C27.00\",\"SU\",\"SU\",\"SU\",27,\"2020-07-17\",0,0,0.04,0.09,52,24,0.09,0,0.1,0,0,0,0,0,0,0.09,1152,53.891\r\n\"2020-07-02\",\"SU
\ 200717C28.00\",\"SU\",\"SU\",\"SU\",28,\"2020-07-17\",0,0,0.03,0.09,16,14,0.09,40,0.1,-0.05,0.05,0.05,0.05,1,2,0.09,1379,57.286\r\n\"2020-07-02\",\"SU
\ 200717C29.00\",\"SU\",\"SU\",\"SU\",29,\"2020-07-17\",0,0,0.02,0.08,87,14,0.08,0,0.09,0,0,0,0,0,0,0.08,1587,79.282\r\n\"2020-07-02\",\"SU
\ 200717C30.00\",\"SU\",\"SU\",\"SU\",30,\"2020-07-17\",0,0,0.01,0.07,88,14,0.07,0,0.08,0,0,0,0,0,0,0.07,324,63.896\r\n\"2020-07-02\",\"SU
\ 200717C32.00\",\"SU\",\"SU\",\"SU\",32,\"2020-07-17\",0,0,0,0.07,0,30,0.07,0,0.07,0,0,0,0,0,0,0.07,20,0\r\n\"2020-07-02\",\"SU
\ 200717C34.00\",\"SU\",\"SU\",\"SU\",34,\"2020-07-17\",0,0,0,0.06,0,14,0.06,0,0.06,0,0,0,0,0,0,0.06,28,0\r\n\"2020-07-02\",\"SU
\ 200821C18.00\",\"SU\",\"SU\",\"SU\",18,\"2020-08-21\",0,0,5.1,5.25,62,62,5.25,0,5.4,0,0,0,0,0,0,5.25,16,70.37\r\n\"2020-07-02\",\"SU
\ 200821C19.00\",\"SU\",\"SU\",\"SU\",19,\"2020-08-21\",0,0,4.25,4.4,46,62,4.4,0,4.55,0,0,0,0,0,0,4.4,0,65.746\r\n\"2020-07-02\",\"SU
\ 200821C20.00\",\"SU\",\"SU\",\"SU\",20,\"2020-08-21\",0,0,3.45,3.55,61,30,3.55,0,3.75,0,0,0,0,0,0,3.55,0,60.683\r\n\"2020-07-02\",\"SU
\ 200821C21.00\",\"SU\",\"SU\",\"SU\",21,\"2020-08-21\",0,0,2.74,2.81,14,30,2.81,0,2.99,0,0,0,0,0,0,2.81,7,57.478\r\n\"2020-07-02\",\"SU
\ 200821C22.00\",\"SU\",\"SU\",\"SU\",22,\"2020-08-21\",0,0,2.09,2.15,14,14,2.15,10,2.34,-0.16,2.18,2.18,2.18,21,1,2.15,12,54.349\r\n\"2020-07-02\",\"SU
\ 200821C23.00\",\"SU\",\"SU\",\"SU\",23,\"2020-08-21\",0,0,1.54,1.61,30,30,1.61,5,1.78,0.19,1.97,1.97,1.97,9,1,1.61,94,52.148\r\n\"2020-07-02\",\"SU
\ 200821C24.00\",\"SU\",\"SU\",\"SU\",24,\"2020-08-21\",0,0,1.09,1.16,60,14,1.16,59,1.3,-0.07,1.23,1.23,1.23,72,2,1.16,28,50.171\r\n\"2020-07-02\",\"SU
\ 200821C25.00\",\"SU\",\"SU\",\"SU\",25,\"2020-08-21\",0,0,0.76,0.82,62,14,0.82,117,0.94,-0.07,1.05,1.05,0.87,102,10,0.82,78,49.073\r\n\"2020-07-02\",\"SU
\ 200821C26.00\",\"SU\",\"SU\",\"SU\",26,\"2020-08-21\",0,0,0.52,0.57,64,14,0.57,15,0.68,-0.05,0.63,0.63,0.63,9,2,0.57,813,48.42\r\n\"2020-07-02\",\"SU
\ 200821C27.00\",\"SU\",\"SU\",\"SU\",27,\"2020-08-21\",0,0,0.36,0.4,30,14,0.4,0,0.49,0,0,0,0,0,0,0.4,1713,48.482\r\n\"2020-07-02\",\"SU
\ 200821C28.00\",\"SU\",\"SU\",\"SU\",28,\"2020-08-21\",0,0,0.25,0.29,71,56,0.29,3,0.36,0,0.36,0.36,0.36,1,1,0.29,29,49.038\r\n\"2020-07-02\",\"SU
\ 200821C29.00\",\"SU\",\"SU\",\"SU\",29,\"2020-08-21\",0,0,0.18,0.21,16,14,0.21,0,0.27,0,0,0,0,0,0,0.21,15,49.844\r\n\"2020-07-02\",\"SU
\ 200821C30.00\",\"SU\",\"SU\",\"SU\",30,\"2020-08-21\",0,0,0.12,0.16,62,14,0.16,32,0.2,-0.05,0.17,0.17,0.15,3,3,0.16,152,50.537\r\n\"2020-07-02\",\"SU
\ 200918C12.00\",\"SU\",\"SU\",\"SU\",12,\"2020-09-18\",0,0,10.85,11.15,14,65,11.15,0,11.15,0,0,0,0,0,0,11.15,13,110.988\r\n\"2020-07-02\",\"SU
\ 200918C13.00\",\"SU\",\"SU\",\"SU\",13,\"2020-09-18\",0,0,9.9,10.05,14,46,10.05,0,10.2,0,0,0,0,0,0,10.05,10,97.757\r\n\"2020-07-02\",\"SU
\ 200918C14.00\",\"SU\",\"SU\",\"SU\",14,\"2020-09-18\",0,0,8.9,9.1,46,46,9.1,0,9.25,0,0,0,0,0,0,9.1,109,88.718\r\n\"2020-07-02\",\"SU
\ 200918C15.00\",\"SU\",\"SU\",\"SU\",15,\"2020-09-18\",0,0,8,8.15,14,46,8.15,0,8.3,0,0,0,0,0,0,8.15,139,82.754\r\n\"2020-07-02\",\"SU
\ 200918C16.00\",\"SU\",\"SU\",\"SU\",16,\"2020-09-18\",0,0,7.05,7.3,46,66,7.3,0,7.35,0,0,0,0,0,0,7.3,137,77.619\r\n\"2020-07-02\",\"SU
\ 200918C17.00\",\"SU\",\"SU\",\"SU\",17,\"2020-09-18\",0,0,6.2,6.35,14,46,6.35,0,6.5,0,0,0,0,0,0,6.35,19,71.939\r\n\"2020-07-02\",\"SU
\ 200918C18.00\",\"SU\",\"SU\",\"SU\",18,\"2020-09-18\",0,0,5.3,5.55,46,66,5.55,0,5.65,0,0,0,0,0,0,5.55,5,67.577\r\n\"2020-07-02\",\"SU
\ 200918C19.00\",\"SU\",\"SU\",\"SU\",19,\"2020-09-18\",0,0,4.5,4.75,45,65,4.75,0,4.85,0,0,0,0,0,0,4.75,42,63.973\r\n\"2020-07-02\",\"SU
\ 200918C20.00\",\"SU\",\"SU\",\"SU\",20,\"2020-09-18\",0,0,3.8,4,14,65,4,0,4.1,0,0,0,0,0,0,4,50,61.448\r\n\"2020-07-02\",\"SU
\ 200918C21.00\",\"SU\",\"SU\",\"SU\",21,\"2020-09-18\",0,0,3.05,3.25,44,64,3.25,0,3.4,0,0,0,0,0,0,3.25,70,56.962\r\n\"2020-07-02\",\"SU
\ 200918C22.00\",\"SU\",\"SU\",\"SU\",22,\"2020-09-18\",0,0,2.51,2.57,14,30,2.57,0,2.73,0,0,0,0,0,0,2.57,87,54.765\r\n\"2020-07-02\",\"SU
\ 200918C23.00\",\"SU\",\"SU\",\"SU\",23,\"2020-09-18\",0,0,1.96,2.03,14,14,2.03,5,2.19,0.01,2.2,2.2,2.2,11,1,2.03,67,52.588\r\n\"2020-07-02\",\"SU
\ 200918C24.00\",\"SU\",\"SU\",\"SU\",24,\"2020-09-18\",0,0,1.5,1.58,44,14,1.58,28,1.71,-0.03,1.67,1.76,1.65,42,11,1.58,2366,50.936\r\n\"2020-07-02\",\"SU
\ 200918C25.00\",\"SU\",\"SU\",\"SU\",25,\"2020-09-18\",0,0,1.14,1.22,45,45,1.22,74,1.33,-0.08,1.25,1.35,1.25,89,7,1.22,142,49.941\r\n\"2020-07-02\",\"SU
\ 200918C26.00\",\"SU\",\"SU\",\"SU\",26,\"2020-09-18\",0,0,0.86,0.92,33,14,0.92,0,1.02,0,0,0,0,0,0,0.92,203,49.121\r\n\"2020-07-02\",\"SU
\ 200918C27.00\",\"SU\",\"SU\",\"SU\",27,\"2020-09-18\",0,0,0.63,0.7,49,14,0.7,0,0.79,0,0,0,0,0,0,0.7,150,48.552\r\n\"2020-07-02\",\"SU
\ 200918C28.00\",\"SU\",\"SU\",\"SU\",28,\"2020-09-18\",0,0,0.47,0.53,52,14,0.53,2,0.6,-0.07,0.53,0.53,0.53,1,1,0.53,330,48.405\r\n\"2020-07-02\",\"SU
\ 200918C29.00\",\"SU\",\"SU\",\"SU\",29,\"2020-09-18\",0,0,0.37,0.41,40,14,0.41,0,0.46,0,0,0,0,0,0,0.41,234,48.976\r\n\"2020-07-02\",\"SU
\ 200918C30.00\",\"SU\",\"SU\",\"SU\",30,\"2020-09-18\",0,0,0.27,0.32,57,14,0.32,14,0.38,-0.05,0.33,0.33,0.33,4,2,0.32,399,49.1\r\n\"2020-07-02\",\"SU
\ 200918C32.00\",\"SU\",\"SU\",\"SU\",32,\"2020-09-18\",0,0,0.17,0.24,48,61,0.24,0,0.26,0,0,0,0,0,0,0.24,418,51.728\r\n\"2020-07-02\",\"SU
\ 200918C34.00\",\"SU\",\"SU\",\"SU\",34,\"2020-09-18\",0,0,0.11,0.14,66,54,0.14,0,0.17,0,0,0,0,0,0,0.14,177,52.443\r\n\"2020-07-02\",\"SU
\ 200918C36.00\",\"SU\",\"SU\",\"SU\",36,\"2020-09-18\",0,0,0.07,0.12,85,68,0.12,0,0.13,0,0,0,0,0,0,0.12,222,50.374\r\n\"2020-07-02\",\"SU
\ 200918C38.00\",\"SU\",\"SU\",\"SU\",38,\"2020-09-18\",0,0,0.05,0.09,70,14,0.09,0,0.1,0,0,0,0,0,0,0.09,90,69.132\r\n\"2020-07-02\",\"SU
\ 200918C40.00\",\"SU\",\"SU\",\"SU\",40,\"2020-09-18\",0,0,0.04,0.09,58,14,0.09,0,0.09,0,0,0,0,0,0,0.09,86,54.772\r\n\"2020-07-02\",\"SU
\ 200918C42.00\",\"SU\",\"SU\",\"SU\",42,\"2020-09-18\",0,0,0.02,0.08,88,14,0.08,0,0.09,0,0,0,0,0,0,0.08,134,56.247\r\n\"2020-07-02\",\"SU
\ 200918C44.00\",\"SU\",\"SU\",\"SU\",44,\"2020-09-18\",0,0,0.02,0.08,59,30,0.08,0,0.08,0,0,0,0,0,0,0.08,79,59.737\r\n\"2020-07-02\",\"SU
\ 200918C46.00\",\"SU\",\"SU\",\"SU\",46,\"2020-09-18\",0,0,0.02,0.09,16,30,0.09,0,0.07,0,0,0,0,0,0,0.09,253,88.392\r\n\"2020-07-02\",\"SU
\ 200918C48.00\",\"SU\",\"SU\",\"SU\",48,\"2020-09-18\",0,0,0,0.07,0,30,0.07,0,0.07,0,0,0,0,0,0,0.07,15,89.359\r\n\"2020-07-02\",\"SU
\ 200918C50.00\",\"SU\",\"SU\",\"SU\",50,\"2020-09-18\",0,0,0.02,0.07,10,30,0.07,0,0.06,0,0,0,0,0,0,0.07,54,0\r\n\"2020-07-02\",\"SU
\ 200918C52.00\",\"SU\",\"SU\",\"SU\",52,\"2020-09-18\",0,0,0,0.07,0,30,0.07,0,0.06,0,0,0,0,0,0,0.07,70,0\r\n\"2020-07-02\",\"SU
\ 200918C54.00\",\"SU\",\"SU\",\"SU\",54,\"2020-09-18\",0,0,0,0.07,0,30,0.07,0,0.06,0,0,0,0,0,0,0.07,60,0\r\n\"2020-07-02\",\"SU
\ 201218C16.00\",\"SU\",\"SU\",\"SU\",16,\"2020-12-18\",0,0,7.3,7.55,47,16,7.55,0,7.75,0,0,0,0,0,0,7.55,1,64.72\r\n\"2020-07-02\",\"SU
\ 201218C17.00\",\"SU\",\"SU\",\"SU\",17,\"2020-12-18\",0,0,6.5,6.75,31,16,6.75,0,6.9,0,0,0,0,0,0,6.75,0,61.891\r\n\"2020-07-02\",\"SU
\ 201218C18.00\",\"SU\",\"SU\",\"SU\",18,\"2020-12-18\",0,0,5.75,6,31,16,6,0,6.15,0,0,0,0,0,0,6,0,59.624\r\n\"2020-07-02\",\"SU
\ 201218C19.00\",\"SU\",\"SU\",\"SU\",19,\"2020-12-18\",0,0,5,5.25,31,16,5.25,0,5.4,0,0,0,0,0,0,5.25,0,56.731\r\n\"2020-07-02\",\"SU
\ 201218C20.00\",\"SU\",\"SU\",\"SU\",20,\"2020-12-18\",0,0,4.35,4.55,30,16,4.55,0,4.7,0,0,0,0,0,0,4.55,3,54.68\r\n\"2020-07-02\",\"SU
\ 201218C21.00\",\"SU\",\"SU\",\"SU\",21,\"2020-12-18\",0,0,3.75,3.95,30,16,3.95,0,4.1,0,0,0,0,0,0,3.95,0,53.263\r\n\"2020-07-02\",\"SU
\ 201218C22.00\",\"SU\",\"SU\",\"SU\",22,\"2020-12-18\",0,0,3.15,3.4,56,16,3.4,0,3.55,0,0,0,0,0,0,3.4,0,51.51\r\n\"2020-07-02\",\"SU
\ 201218C23.00\",\"SU\",\"SU\",\"SU\",23,\"2020-12-18\",0,0,2.76,2.85,14,30,2.85,0,2.99,0,0,0,0,0,0,2.85,21,50.749\r\n\"2020-07-02\",\"SU
\ 201218C24.00\",\"SU\",\"SU\",\"SU\",24,\"2020-12-18\",0,0,2.32,2.43,14,30,2.43,0,2.54,0,0,0,0,0,0,2.43,21,49.864\r\n\"2020-07-02\",\"SU
\ 201218C25.00\",\"SU\",\"SU\",\"SU\",25,\"2020-12-18\",0,0,1.93,2.02,14,30,2.02,0,2.15,0,0,0,0,0,0,2.02,3,48.71\r\n\"2020-07-02\",\"SU
\ 201218C26.00\",\"SU\",\"SU\",\"SU\",26,\"2020-12-18\",0,0,1.6,1.7,45,14,1.7,0,1.81,0,0,0,0,0,0,1.7,8,48.068\r\n\"2020-07-02\",\"SU
\ 201218C27.00\",\"SU\",\"SU\",\"SU\",27,\"2020-12-18\",0,0,1.33,1.42,14,30,1.42,2,1.52,-0.1,1.42,1.42,1.42,2,1,1.42,7,47.582\r\n\"2020-07-02\",\"SU
\ 201218C28.00\",\"SU\",\"SU\",\"SU\",28,\"2020-12-18\",0,0,1.11,1.19,14,63,1.19,0,1.28,0,0,0,0,0,0,1.19,13,47.338\r\n\"2020-07-02\",\"SU
\ 201218C29.00\",\"SU\",\"SU\",\"SU\",29,\"2020-12-18\",0,0,0.91,1,49,65,1,0,1.07,0,0,0,0,0,0,1,36,47.05\r\n\"2020-07-02\",\"SU
\ 201218C30.00\",\"SU\",\"SU\",\"SU\",30,\"2020-12-18\",0,0,0.77,0.84,14,67,0.84,2,0.9,0.04,0.94,0.94,0.94,1,1,0.84,132,47.118\r\n\"2020-07-02\",\"SU
\ 201218C32.00\",\"SU\",\"SU\",\"SU\",32,\"2020-12-18\",0,0,0.54,0.6,14,54,0.6,0,0.65,0,0,0,0,0,0,0.6,51,47.245\r\n\"2020-07-02\",\"SU
\ 201218C34.00\",\"SU\",\"SU\",\"SU\",34,\"2020-12-18\",0,0,0.39,0.48,58,73,0.48,0,0.48,0,0,0,0,0,0,0.48,19,48.375\r\n\"2020-07-02\",\"SU
\ 210115C13.00\",\"SU\",\"SU\",\"SU\",13,\"2021-01-15\",0,0,10,10.3,51,51,10.3,0,10.45,0,0,0,0,0,0,10.3,170,76.723\r\n\"2020-07-02\",\"SU
\ 210115C14.00\",\"SU\",\"SU\",\"SU\",14,\"2021-01-15\",0,0,9.15,9.4,31,51,9.4,0,9.6,0,0,0,0,0,0,9.4,13,72.492\r\n\"2020-07-02\",\"SU
\ 210115C15.00\",\"SU\",\"SU\",\"SU\",15,\"2021-01-15\",0,0,8.3,8.55,31,67,8.55,0,8.7,0,0,0,0,0,0,8.55,34,68.756\r\n\"2020-07-02\",\"SU
\ 210115C16.00\",\"SU\",\"SU\",\"SU\",16,\"2021-01-15\",0,0,7.4,7.65,51,20,7.65,0,7.85,0,0,0,0,0,0,7.65,33,63.569\r\n\"2020-07-02\",\"SU
\ 210115C17.00\",\"SU\",\"SU\",\"SU\",17,\"2021-01-15\",0,0,6.6,6.85,31,20,6.85,0,7,0,0,0,0,0,0,6.85,34,60.547\r\n\"2020-07-02\",\"SU
\ 210115C18.00\",\"SU\",\"SU\",\"SU\",18,\"2021-01-15\",0,0,5.95,6.2,31,51,6.2,0,6.35,0,0,0,0,0,0,6.2,105,60.084\r\n\"2020-07-02\",\"SU
\ 210115C19.00\",\"SU\",\"SU\",\"SU\",19,\"2021-01-15\",0,0,5.2,5.55,30,50,5.55,0,5.65,0,0,0,0,0,0,5.55,36,57.907\r\n\"2020-07-02\",\"SU
\ 210115C20.00\",\"SU\",\"SU\",\"SU\",20,\"2021-01-15\",0,0,4.5,4.8,30,66,4.8,1,4.95,0.1,5.05,5.05,5.05,5,1,4.8,63,54.76\r\n\"2020-07-02\",\"SU
\ 210115C21.00\",\"SU\",\"SU\",\"SU\",21,\"2021-01-15\",0,0,3.9,4.2,30,66,4.2,0,4.35,0,0,0,0,0,0,4.2,45,53.19\r\n\"2020-07-02\",\"SU
\ 210115C22.00\",\"SU\",\"SU\",\"SU\",22,\"2021-01-15\",0,0,3.35,3.6,30,20,3.6,5,3.75,-0.15,3.6,3.6,3.6,18,1,3.6,136,51.38\r\n\"2020-07-02\",\"SU
\ 210115C23.00\",\"SU\",\"SU\",\"SU\",23,\"2021-01-15\",0,0,2.81,3.1,30,50,3.1,3,3.25,0,3.25,3.25,3.25,9,1,3.1,86,49.786\r\n\"2020-07-02\",\"SU
\ 210115C24.00\",\"SU\",\"SU\",\"SU\",24,\"2021-01-15\",0,0,2.36,2.65,30,50,2.65,0,2.8,0,0,0,0,0,0,2.65,140,48.603\r\n\"2020-07-02\",\"SU
\ 210115C25.00\",\"SU\",\"SU\",\"SU\",25,\"2021-01-15\",0,0,1.96,2.25,30,50,2.25,3,2.39,-0.19,2.2,2.2,2.2,6,1,2.25,289,47.518\r\n\"2020-07-02\",\"SU
\ 210115C26.00\",\"SU\",\"SU\",\"SU\",26,\"2021-01-15\",0,0,1.61,1.9,31,31,1.9,0,2.04,0,0,0,0,0,0,1.9,203,46.547\r\n\"2020-07-02\",\"SU
\ 210115C27.00\",\"SU\",\"SU\",\"SU\",27,\"2021-01-15\",0,0,1.36,1.64,32,32,1.64,0,1.74,0,0,0,0,0,0,1.64,29,46.47\r\n\"2020-07-02\",\"SU
\ 210115C28.00\",\"SU\",\"SU\",\"SU\",28,\"2021-01-15\",0,0,1.11,1.39,33,33,1.39,0,1.47,0,0,0,0,0,0,1.39,114,45.897\r\n\"2020-07-02\",\"SU
\ 210115C29.00\",\"SU\",\"SU\",\"SU\",29,\"2021-01-15\",0,0,0.91,1.19,34,34,1.19,0,1.29,0,0,0,0,0,0,1.19,86,45.633\r\n\"2020-07-02\",\"SU
\ 210115C30.00\",\"SU\",\"SU\",\"SU\",30,\"2021-01-15\",0,0,0.76,0.99,36,36,0.99,0,1.04,0,0,0,0,0,0,0.99,235,45.31\r\n\"2020-07-02\",\"SU
\ 210115C32.00\",\"SU\",\"SU\",\"SU\",32,\"2021-01-15\",0,0,0.51,0.74,39,39,0.74,0,0.79,0,0,0,0,0,0,0.74,267,45.296\r\n\"2020-07-02\",\"SU
\ 210115C34.00\",\"SU\",\"SU\",\"SU\",34,\"2021-01-15\",0,0,0.36,0.6,42,20,0.6,0,0.6,0,0,0,0,0,0,0.6,291,46.267\r\n\"2020-07-02\",\"SU
\ 210115C36.00\",\"SU\",\"SU\",\"SU\",36,\"2021-01-15\",0,0,0.26,0.4,45,1,0.4,0,0.4,0,0,0,0,0,0,0.4,332,45.792\r\n\"2020-07-02\",\"SU
\ 210115C38.00\",\"SU\",\"SU\",\"SU\",38,\"2021-01-15\",0,0,0.16,0.39,58,48,0.39,0,0.39,0,0,0,0,0,0,0.39,356,47.391\r\n\"2020-07-02\",\"SU
\ 210115C40.00\",\"SU\",\"SU\",\"SU\",40,\"2021-01-15\",0,0,0.11,0.25,50,1,0.25,0,0.3,0,0,0,0,0,0,0.25,350,46.452\r\n\"2020-07-02\",\"SU
\ 210115C42.00\",\"SU\",\"SU\",\"SU\",42,\"2021-01-15\",0,0,0.1,0.25,52,1,0.25,0,0.25,0,0,0,0,0,0,0.25,7693,49.484\r\n\"2020-07-02\",\"SU
\ 210115C44.00\",\"SU\",\"SU\",\"SU\",44,\"2021-01-15\",0,0,0.07,0.2,74,1,0.2,0,0.2,0,0,0,0,0,0,0.2,1210,45.682\r\n\"2020-07-02\",\"SU
\ 210115C46.00\",\"SU\",\"SU\",\"SU\",46,\"2021-01-15\",0,0,0.05,0.2,75,71,0.2,0,0.23,0,0,0,0,0,0,0.2,313,58.856\r\n\"2020-07-02\",\"SU
\ 210115C48.00\",\"SU\",\"SU\",\"SU\",48,\"2021-01-15\",0,0,0.02,0.15,76,20,0.15,0,0.15,0,0,0,0,0,0,0.15,374,60.85\r\n\"2020-07-02\",\"SU
\ 210115C50.00\",\"SU\",\"SU\",\"SU\",50,\"2021-01-15\",0,0,0.02,0.15,57,20,0.15,0,0.15,0,0,0,0,0,0,0.15,273,63.515\r\n\"2020-07-02\",\"SU
\ 210115C52.00\",\"SU\",\"SU\",\"SU\",52,\"2021-01-15\",0,0,0,0.14,0,16,0.14,0,0.15,0,0,0,0,0,0,0.14,156,48.073\r\n\"2020-07-02\",\"SU
\ 210115C54.00\",\"SU\",\"SU\",\"SU\",54,\"2021-01-15\",0,0,0,0.14,0,16,0.14,0,0.15,0,0,0,0,0,0,0.14,166,67.555\r\n\"2020-07-02\",\"SU
\ 210115C56.00\",\"SU\",\"SU\",\"SU\",56,\"2021-01-15\",0,0,0,0.13,0,16,0.13,0,0.15,0,0,0,0,0,0,0.13,20,50.974\r\n\"2020-07-02\",\"SU
\ 210115C58.00\",\"SU\",\"SU\",\"SU\",58,\"2021-01-15\",0,0,0,0.12,0,16,0.12,0,0.14,0,0,0,0,0,0,0.12,7296,71.119\r\n\"2020-07-02\",\"SU
\ 210115C60.00\",\"SU\",\"SU\",\"SU\",60,\"2021-01-15\",0,0,0,0.1,0,20,0.1,0,0.1,0,0,0,0,0,0,0.1,3204,72.106\r\n\"2020-07-02\",\"SU
\ 220121C13.00\",\"SU\",\"SU\",\"SU\",13,\"2022-01-21\",0,0,6.2,15.45,30,30,15.45,0,15.55,0,0,0,0,0,0,15.45,8,68.185\r\n\"2020-07-02\",\"SU
\ 220121C14.00\",\"SU\",\"SU\",\"SU\",14,\"2022-01-21\",0,0,5.2,9.95,30,1,9.95,0,10,0,0,0,0,0,0,9.95,34,18.221\r\n\"2020-07-02\",\"SU
\ 220121C15.00\",\"SU\",\"SU\",\"SU\",15,\"2022-01-21\",0,0,4.45,9.15,30,1,9.15,0,9.2,0,0,0,0,0,0,9.15,14,23.345\r\n\"2020-07-02\",\"SU
\ 220121C16.00\",\"SU\",\"SU\",\"SU\",16,\"2022-01-21\",0,0,3.75,8.4,30,1,8.4,0,8.5,0,0,0,0,0,0,8.4,41,25.299\r\n\"2020-07-02\",\"SU
\ 220121C17.00\",\"SU\",\"SU\",\"SU\",17,\"2022-01-21\",0,0,3.05,7.7,30,1,7.7,0,7.8,0,0,0,0,0,0,7.7,45,26.024\r\n\"2020-07-02\",\"SU
\ 220121C18.00\",\"SU\",\"SU\",\"SU\",18,\"2022-01-21\",0,0,2.45,8.7,30,5,8.7,0,8.8,0,0,0,0,0,0,8.7,0,36.309\r\n\"2020-07-02\",\"SU
\ 220121C19.00\",\"SU\",\"SU\",\"SU\",19,\"2022-01-21\",0,0,5.05,8.1,20,5,8.1,0,8.2,0,0,0,0,0,0,8.1,5,52.733\r\n\"2020-07-02\",\"SU
\ 220121C20.00\",\"SU\",\"SU\",\"SU\",20,\"2022-01-21\",0,0,1.25,6.35,30,1,6.35,2,6.25,-0.05,6.2,6.2,6.2,12,2,6.35,87,28.874\r\n\"2020-07-02\",\"SU
\ 220121C21.00\",\"SU\",\"SU\",\"SU\",21,\"2022-01-21\",0,0,2.1,5.95,20,1,5.95,1,5.85,-0.05,5.8,5.8,5.8,5,1,5.95,40,35.734\r\n\"2020-07-02\",\"SU
\ 220121C22.00\",\"SU\",\"SU\",\"SU\",22,\"2022-01-21\",0,0,0.3,6.55,40,5,6.55,0,6.6,0,0,0,0,0,0,6.55,14,33.956\r\n\"2020-07-02\",\"SU
\ 220121C23.00\",\"SU\",\"SU\",\"SU\",23,\"2022-01-21\",0,0,4.1,6.1,20,5,6.1,0,6.15,0,0,0,0,0,0,6.1,6,53.398\r\n\"2020-07-02\",\"SU
\ 220121C24.00\",\"SU\",\"SU\",\"SU\",24,\"2022-01-21\",0,0,3.65,4.55,20,1,4.55,40,4.6,0.4,5,5,5,200,1,4.55,200,46.975\r\n\"2020-07-02\",\"SU
\ 220121C25.00\",\"SU\",\"SU\",\"SU\",25,\"2022-01-21\",0,0,3.3,5.3,20,5,5.3,0,5.35,0,0,0,0,0,0,5.3,14,51.698\r\n\"2020-07-02\",\"SU
\ 220121C26.00\",\"SU\",\"SU\",\"SU\",26,\"2022-01-21\",0,0,2.95,3.8,20,1,3.8,0,3.85,0,0,0,0,0,0,3.8,61,45.651\r\n\"2020-07-02\",\"SU
\ 220121C27.00\",\"SU\",\"SU\",\"SU\",27,\"2022-01-21\",0,0,2.65,4.65,20,5,4.65,0,4.7,0,0,0,0,0,0,4.65,0,50.653\r\n\"2020-07-02\",\"SU
\ 220121C28.00\",\"SU\",\"SU\",\"SU\",28,\"2022-01-21\",0,0,2.35,4.2,20,40,4.2,0,4.4,0,0,0,0,0,0,4.2,50,49.39\r\n\"2020-07-02\",\"SU
\ 220121C29.00\",\"SU\",\"SU\",\"SU\",29,\"2022-01-21\",0,0,2.1,4.1,20,5,4.1,0,4.15,0,0,0,0,0,0,4.1,0,49.841\r\n\"2020-07-02\",\"SU
\ 220121C30.00\",\"SU\",\"SU\",\"SU\",30,\"2022-01-21\",0,0,2.05,2.55,5,1,2.55,0,2.55,0,0,0,0,0,0,2.55,151,44.078\r\n\"2020-07-02\",\"SU
\ 220121C32.00\",\"SU\",\"SU\",\"SU\",32,\"2022-01-21\",0,0,1.5,1.95,20,1,1.95,0,1.95,0,0,0,0,0,0,1.95,153,41.713\r\n\"2020-07-02\",\"SU
\ 220121C34.00\",\"SU\",\"SU\",\"SU\",34,\"2022-01-21\",0,0,1.2,1.5,20,1,1.5,0,1.55,0,0,0,0,0,0,1.5,79,40.632\r\n\"2020-07-02\",\"SU
\ 220121C36.00\",\"SU\",\"SU\",\"SU\",36,\"2022-01-21\",0,0,0.95,2.95,20,5,2.95,0,2.95,0,0,0,0,0,0,2.95,75,50.053\r\n\"2020-07-02\",\"SU
\ 220121C38.00\",\"SU\",\"SU\",\"SU\",38,\"2022-01-21\",0,0,0.75,2.75,20,5,2.75,0,2.75,0,0,0,0,0,0,2.75,31,50.482\r\n\"2020-07-02\",\"SU
\ 220121C40.00\",\"SU\",\"SU\",\"SU\",40,\"2022-01-21\",0,0,0.7,0.75,23,1,0.75,0,0.75,0,0,0,0,0,0,0.75,3089,39.759\r\n\"2020-07-02\",\"SU
\ 220121C42.00\",\"SU\",\"SU\",\"SU\",42,\"2022-01-21\",0,0,0.45,2.45,20,5,2.45,0,2.45,0,0,0,0,0,0,2.45,23,51.576\r\n\"2020-07-02\",\"SU
\ 220121C44.00\",\"SU\",\"SU\",\"SU\",44,\"2022-01-21\",0,0,0.35,2.35,20,5,2.35,0,2.35,0,0,0,0,0,0,2.35,24,52.369\r\n\"2020-07-02\",\"SU
\ 220121C46.00\",\"SU\",\"SU\",\"SU\",46,\"2022-01-21\",0,0,0.4,0.45,2,1,0.45,0,0.45,0,0,0,0,0,0,0.45,1252,39.894\r\n\"2020-07-02\",\"SU
\ 220121C48.00\",\"SU\",\"SU\",\"SU\",48,\"2022-01-21\",0,0,0.25,0.35,30,1,0.35,0,0.35,0,0,0,0,0,0,0.35,29,38.527\r\n\"2020-07-02\",\"SU
\ 220121C50.00\",\"SU\",\"SU\",\"SU\",50,\"2022-01-21\",0,0,0.2,2.15,20,5,2.15,0,2.15,0,0,0,0,0,0,2.15,84,55.386\r\n\"2020-07-02\",\"SU
\ 220121C60.00\",\"SU\",\"SU\",\"SU\",60,\"2022-01-21\",0,0,0.35,0.4,20,1,0.4,0,0.4,0,0,0,0,0,0,0.4,3039,48.102\r\n\"2020-07-02\",\"SU
\ 200703P20.50\",\"SU\",\"SU\",\"SU\",20.5,\"2020-07-03\",1,0,0,0.04,0,30,0.04,0,0.05,0,0,0,0,0,0,0.04,0,112.369\r\n\"2020-07-02\",\"SU
\ 200703P21.00\",\"SU\",\"SU\",\"SU\",21,\"2020-07-03\",1,0,0,0.04,0,30,0.04,0,0.06,0,0,0,0,0,0,0.04,0,90.511\r\n\"2020-07-02\",\"SU
\ 200703P21.50\",\"SU\",\"SU\",\"SU\",21.5,\"2020-07-03\",1,0,0,0.04,0,30,0.04,0,0.05,0,0,0,0,0,0,0.04,27,68.341\r\n\"2020-07-02\",\"SU
\ 200703P22.00\",\"SU\",\"SU\",\"SU\",22,\"2020-07-03\",1,0,0,0.04,0,16,0.04,0,0.08,0,0,0,0,0,0,0.04,331,45.421\r\n\"2020-07-02\",\"SU
\ 200703P22.50\",\"SU\",\"SU\",\"SU\",22.5,\"2020-07-03\",1,0,0.08,0.14,56,30,0.14,10,0.19,-0.02,0.17,0.17,0.17,1,1,0.14,20,43.956\r\n\"2020-07-02\",\"SU
\ 200703P23.00\",\"SU\",\"SU\",\"SU\",23,\"2020-07-03\",1,0,0.32,0.4,24,30,0.4,3,0.4,-0.18,0.22,0.22,0.22,0,1,0.4,124,42.401\r\n\"2020-07-02\",\"SU
\ 200703P23.50\",\"SU\",\"SU\",\"SU\",23.5,\"2020-07-03\",1,0,0.76,0.84,14,14,0.84,0,0.74,0,0,0,0,0,0,0.84,70,53.397\r\n\"2020-07-02\",\"SU
\ 200703P24.00\",\"SU\",\"SU\",\"SU\",24,\"2020-07-03\",1,0,1.24,1.34,14,46,1.34,2,1.22,-0.22,1,1,1,2,1,1.34,11,70.764\r\n\"2020-07-02\",\"SU
\ 200703P24.50\",\"SU\",\"SU\",\"SU\",24.5,\"2020-07-03\",1,0,1.74,1.82,14,14,1.82,0,1.69,0,0,0,0,0,0,1.82,24,0\r\n\"2020-07-02\",\"SU
\ 200703P25.00\",\"SU\",\"SU\",\"SU\",25,\"2020-07-03\",1,0,2.23,2.33,24,14,2.33,0,2.19,0,0,0,0,0,0,2.33,31,0\r\n\"2020-07-02\",\"SU
\ 200703P25.50\",\"SU\",\"SU\",\"SU\",25.5,\"2020-07-03\",1,0,2.72,2.82,24,14,2.82,0,2.69,0,0,0,0,0,0,2.82,14,0\r\n\"2020-07-02\",\"SU
\ 200703P26.00\",\"SU\",\"SU\",\"SU\",26,\"2020-07-03\",1,0,3.15,3.35,54,44,3.35,0,3.2,0,0,0,0,0,0,3.35,16,0\r\n\"2020-07-02\",\"SU
\ 200703P26.50\",\"SU\",\"SU\",\"SU\",26.5,\"2020-07-03\",1,0,3.65,3.85,54,44,3.85,0,3.7,0,0,0,0,0,0,3.85,10,0\r\n\"2020-07-02\",\"SU
\ 200703P27.00\",\"SU\",\"SU\",\"SU\",27,\"2020-07-03\",1,0,4.15,4.35,54,44,4.35,0,4.2,0,0,0,0,0,0,4.35,2,0\r\n\"2020-07-02\",\"SU
\ 200703P27.50\",\"SU\",\"SU\",\"SU\",27.5,\"2020-07-03\",1,0,4.65,4.85,70,44,4.85,0,4.7,0,0,0,0,0,0,4.85,0,0\r\n\"2020-07-02\",\"SU
\ 200703P28.00\",\"SU\",\"SU\",\"SU\",28,\"2020-07-03\",1,0,5.15,5.35,70,44,5.35,0,5.2,0,0,0,0,0,0,5.35,0,0\r\n\"2020-07-02\",\"SU
\ 200703P28.50\",\"SU\",\"SU\",\"SU\",28.5,\"2020-07-03\",1,0,5.65,5.85,70,44,5.85,0,5.7,0,0,0,0,0,0,5.85,0,0\r\n\"2020-07-02\",\"SU
\ 200703P29.00\",\"SU\",\"SU\",\"SU\",29,\"2020-07-03\",1,0,6.15,6.35,70,44,6.35,0,6.2,0,0,0,0,0,0,6.35,0,0\r\n\"2020-07-02\",\"SU
\ 200703P29.50\",\"SU\",\"SU\",\"SU\",29.5,\"2020-07-03\",1,0,6.65,6.85,70,44,6.85,0,6.7,0,0,0,0,0,0,6.85,0,0\r\n\"2020-07-02\",\"SU
\ 200703P30.00\",\"SU\",\"SU\",\"SU\",30,\"2020-07-03\",1,0,7.15,7.35,70,44,7.35,0,7.2,0,0,0,0,0,0,7.35,0,0\r\n\"2020-07-02\",\"SU
\ 200703P30.50\",\"SU\",\"SU\",\"SU\",30.5,\"2020-07-03\",1,0,7.65,7.85,70,44,7.85,0,7.7,0,0,0,0,0,0,7.85,0,0\r\n\"2020-07-02\",\"SU
\ 200710P20.50\",\"SU\",\"SU\",\"SU\",20.5,\"2020-07-10\",1,0,0.03,0.09,88,30,0.09,0,0.1,0,0,0,0,0,0,0.09,50,50.035\r\n\"2020-07-02\",\"SU
\ 200710P21.00\",\"SU\",\"SU\",\"SU\",21,\"2020-07-10\",1,0,0.07,0.12,82,16,0.12,3,0.14,-0.03,0.11,0.11,0.11,0,1,0.12,103,46.613\r\n\"2020-07-02\",\"SU
\ 200710P21.50\",\"SU\",\"SU\",\"SU\",21.5,\"2020-07-10\",1,0,0.14,0.2,76,65,0.2,0,0.22,0,0,0,0,0,0,0.2,2,45.245\r\n\"2020-07-02\",\"SU
\ 200710P22.00\",\"SU\",\"SU\",\"SU\",22,\"2020-07-10\",1,0,0.25,0.3,40,24,0.3,0,0.32,0,0,0,0,0,0,0.3,19,42.73\r\n\"2020-07-02\",\"SU
\ 200710P22.50\",\"SU\",\"SU\",\"SU\",22.5,\"2020-07-10\",1,0,0.41,0.45,40,44,0.45,40,0.5,-0.1,0.4,0.4,0.4,11,7,0.45,60,39.983\r\n\"2020-07-02\",\"SU
\ 200710P23.00\",\"SU\",\"SU\",\"SU\",23,\"2020-07-10\",1,0,0.66,0.72,26,44,0.72,0,0.7,0,0,0,0,0,0,0.72,40,39.993\r\n\"2020-07-02\",\"SU
\ 200710P23.50\",\"SU\",\"SU\",\"SU\",23.5,\"2020-07-10\",1,0,0.98,1.05,40,45,1.05,0,1.01,0,0,0,0,0,0,1.05,33,39.527\r\n\"2020-07-02\",\"SU
\ 200710P24.00\",\"SU\",\"SU\",\"SU\",24,\"2020-07-10\",1,0,1.38,1.45,24,46,1.45,0,1.36,0,0,0,0,0,0,1.45,30,40.504\r\n\"2020-07-02\",\"SU
\ 200710P24.50\",\"SU\",\"SU\",\"SU\",24.5,\"2020-07-10\",1,0,1.8,1.9,24,47,1.9,0,1.79,0,0,0,0,0,0,1.9,20,40.796\r\n\"2020-07-02\",\"SU
\ 200710P25.00\",\"SU\",\"SU\",\"SU\",25,\"2020-07-10\",1,0,2.27,2.36,24,14,2.36,0,2.24,0,0,0,0,0,0,2.36,0,41.411\r\n\"2020-07-02\",\"SU
\ 200710P25.50\",\"SU\",\"SU\",\"SU\",25.5,\"2020-07-10\",1,0,2.76,2.85,14,14,2.85,0,2.72,0,0,0,0,0,0,2.85,7,52.77\r\n\"2020-07-02\",\"SU
\ 200710P26.00\",\"SU\",\"SU\",\"SU\",26,\"2020-07-10\",1,0,3.15,3.35,72,46,3.35,0,3.25,0,0,0,0,0,0,3.35,14,0\r\n\"2020-07-02\",\"SU
\ 200710P26.50\",\"SU\",\"SU\",\"SU\",26.5,\"2020-07-10\",1,0,3.7,3.85,56,46,3.85,0,3.7,0,0,0,0,0,0,3.85,14,0\r\n\"2020-07-02\",\"SU
\ 200710P27.00\",\"SU\",\"SU\",\"SU\",27,\"2020-07-10\",1,0,4.2,4.35,56,46,4.35,0,4.2,0,0,0,0,0,0,4.35,0,0\r\n\"2020-07-02\",\"SU
\ 200710P27.50\",\"SU\",\"SU\",\"SU\",27.5,\"2020-07-10\",1,0,4.7,4.85,55,45,4.85,0,4.7,0,0,0,0,0,0,4.85,0,0\r\n\"2020-07-02\",\"SU
\ 200710P28.00\",\"SU\",\"SU\",\"SU\",28,\"2020-07-10\",1,0,5.2,5.35,55,45,5.35,0,5.2,0,0,0,0,0,0,5.35,0,0\r\n\"2020-07-02\",\"SU
\ 200710P28.50\",\"SU\",\"SU\",\"SU\",28.5,\"2020-07-10\",1,0,5.7,5.85,55,45,5.85,0,5.7,0,0,0,0,0,0,5.85,14,0\r\n\"2020-07-02\",\"SU
\ 200724P20.50\",\"SU\",\"SU\",\"SU\",20.5,\"2020-07-24\",1,0,0.31,0.37,40,36,0.37,0,0.39,0,0,0,0,0,0,0.37,11,52.445\r\n\"2020-07-02\",\"SU
\ 200724P21.00\",\"SU\",\"SU\",\"SU\",21,\"2020-07-24\",1,0,0.41,0.47,30,16,0.47,0,0.5,0,0,0,0,0,0,0.47,1,50.624\r\n\"2020-07-02\",\"SU
\ 200724P21.50\",\"SU\",\"SU\",\"SU\",21.5,\"2020-07-24\",1,0,0.54,0.6,40,16,0.6,0,0.63,0,0,0,0,0,0,0.6,0,49.075\r\n\"2020-07-02\",\"SU
\ 200724P22.00\",\"SU\",\"SU\",\"SU\",22,\"2020-07-24\",1,0,0.7,0.76,40,30,0.76,0,0.78,0,0,0,0,0,0,0.76,4,47.527\r\n\"2020-07-02\",\"SU
\ 200724P22.50\",\"SU\",\"SU\",\"SU\",22.5,\"2020-07-24\",1,0,0.9,0.96,24,30,0.96,2,0.98,-0.18,0.8,0.8,0.8,1,1,0.96,1,46.253\r\n\"2020-07-02\",\"SU
\ 200724P23.00\",\"SU\",\"SU\",\"SU\",23,\"2020-07-24\",1,0,1.14,1.21,24,30,1.21,2,1.21,-0.18,1.03,1.03,1.03,2,1,1.21,0,45.318\r\n\"2020-07-02\",\"SU
\ 200724P23.50\",\"SU\",\"SU\",\"SU\",23.5,\"2020-07-24\",1,0,1.43,1.5,24,30,1.5,0,1.48,0,0,0,0,0,0,1.5,0,44.673\r\n\"2020-07-02\",\"SU
\ 200724P24.00\",\"SU\",\"SU\",\"SU\",24,\"2020-07-24\",1,0,1.76,1.83,14,30,1.83,0,1.79,0,0,0,0,0,0,1.83,0,44.157\r\n\"2020-07-02\",\"SU
\ 200724P24.50\",\"SU\",\"SU\",\"SU\",24.5,\"2020-07-24\",1,0,2.12,2.2,14,30,2.2,0,2.13,0,0,0,0,0,0,2.2,0,43.679\r\n\"2020-07-02\",\"SU
\ 200724P25.00\",\"SU\",\"SU\",\"SU\",25,\"2020-07-24\",1,0,2.53,2.6,14,30,2.6,0,2.53,0,0,0,0,0,0,2.6,0,43.822\r\n\"2020-07-02\",\"SU
\ 200717P18.00\",\"SU\",\"SU\",\"SU\",18,\"2020-07-17\",1,0,0.02,0.07,68,30,0.07,0,0.08,0,0,0,0,0,0,0.07,69,65.937\r\n\"2020-07-02\",\"SU
\ 200717P19.00\",\"SU\",\"SU\",\"SU\",19,\"2020-07-17\",1,0,0.06,0.09,2,14,0.09,0,0.1,0,0,0,0,0,0,0.09,53,59.11\r\n\"2020-07-02\",\"SU
\ 200717P20.00\",\"SU\",\"SU\",\"SU\",20,\"2020-07-17\",1,0,0.1,0.15,67,14,0.15,18,0.15,-0.02,0.15,0.15,0.13,1,3,0.15,27429,52.017\r\n\"2020-07-02\",\"SU
\ 200717P21.00\",\"SU\",\"SU\",\"SU\",21,\"2020-07-17\",1,0,0.23,0.28,75,14,0.28,8,0.31,-0.04,0.27,0.27,0.27,2,1,0.28,130,48.095\r\n\"2020-07-02\",\"SU
\ 200717P22.00\",\"SU\",\"SU\",\"SU\",22,\"2020-07-17\",1,0,0.47,0.5,71,10,0.5,24,0.54,-0.04,0.4,0.5,0.4,10,4,0.5,536,43.642\r\n\"2020-07-02\",\"SU
\ 200717P23.00\",\"SU\",\"SU\",\"SU\",23,\"2020-07-17\",1,0,0.9,0.95,30,14,0.95,68,0.96,-0.06,0.84,0.9,0.73,55,7,0.95,125,41.659\r\n\"2020-07-02\",\"SU
\ 200717P24.00\",\"SU\",\"SU\",\"SU\",24,\"2020-07-17\",1,0,1.58,1.64,14,45,1.64,0,1.6,0,0,0,0,0,0,1.64,82,42.568\r\n\"2020-07-02\",\"SU
\ 200717P25.00\",\"SU\",\"SU\",\"SU\",25,\"2020-07-17\",1,0,2.4,2.49,14,30,2.49,0,2.39,0,0,0,0,0,0,2.49,108,44.013\r\n\"2020-07-02\",\"SU
\ 200717P26.00\",\"SU\",\"SU\",\"SU\",26,\"2020-07-17\",1,0,3.25,3.4,57,47,3.4,0,3.3,0,0,0,0,0,0,3.4,84,34.875\r\n\"2020-07-02\",\"SU
\ 200717P27.00\",\"SU\",\"SU\",\"SU\",27,\"2020-07-17\",1,0,4.2,4.35,72,14,4.35,0,4.25,0,0,0,0,0,0,4.35,51,0\r\n\"2020-07-02\",\"SU
\ 200717P28.00\",\"SU\",\"SU\",\"SU\",28,\"2020-07-17\",1,0,5.2,5.35,56,14,5.35,0,5.25,0,0,0,0,0,0,5.35,80,0\r\n\"2020-07-02\",\"SU
\ 200717P29.00\",\"SU\",\"SU\",\"SU\",29,\"2020-07-17\",1,0,6.15,6.35,72,14,6.35,0,6.25,0,0,0,0,0,0,6.35,63,0\r\n\"2020-07-02\",\"SU
\ 200717P30.00\",\"SU\",\"SU\",\"SU\",30,\"2020-07-17\",1,0,7.15,7.35,71,45,7.35,0,7.25,0,0,0,0,0,0,7.35,15,0\r\n\"2020-07-02\",\"SU
\ 200717P32.00\",\"SU\",\"SU\",\"SU\",32,\"2020-07-17\",1,0,9.2,9.35,55,45,9.35,0,9.2,0,0,0,0,0,0,9.35,0,0\r\n\"2020-07-02\",\"SU
\ 200717P34.00\",\"SU\",\"SU\",\"SU\",34,\"2020-07-17\",1,0,11.2,11.35,54,44,11.35,0,11.2,0,0,0,0,0,0,11.35,0,0\r\n\"2020-07-02\",\"SU
\ 200821P18.00\",\"SU\",\"SU\",\"SU\",18,\"2020-08-21\",1,0,0.35,0.4,69,55,0.4,0,0.41,0,0,0,0,0,0,0.4,24,61.387\r\n\"2020-07-02\",\"SU
\ 200821P19.00\",\"SU\",\"SU\",\"SU\",19,\"2020-08-21\",1,0,0.5,0.54,49,36,0.54,0,0.56,0,0,0,0,0,0,0.54,14,58.016\r\n\"2020-07-02\",\"SU
\ 200821P20.00\",\"SU\",\"SU\",\"SU\",20,\"2020-08-21\",1,0,0.69,0.75,83,63,0.75,0,0.76,0,0,0,0,0,0,0.75,104,54.997\r\n\"2020-07-02\",\"SU
\ 200821P21.00\",\"SU\",\"SU\",\"SU\",21,\"2020-08-21\",1,0,0.96,1.02,45,30,1.02,2,1.03,-0.05,0.98,0.98,0.98,1,1,1.02,17,52.295\r\n\"2020-07-02\",\"SU
\ 200821P22.00\",\"SU\",\"SU\",\"SU\",22,\"2020-08-21\",1,0,1.31,1.37,64,30,1.37,47,1.38,-0.1,1.22,1.28,1.15,53,5,1.37,41,49.731\r\n\"2020-07-02\",\"SU
\ 200821P23.00\",\"SU\",\"SU\",\"SU\",23,\"2020-08-21\",1,0,1.76,1.82,24,30,1.82,0,1.82,0,0,0,0,0,0,1.82,26,47.52\r\n\"2020-07-02\",\"SU
\ 200821P24.00\",\"SU\",\"SU\",\"SU\",24,\"2020-08-21\",1,0,2.31,2.36,26,14,2.36,0,2.35,0,0,0,0,0,0,2.36,22,45.255\r\n\"2020-07-02\",\"SU
\ 200821P25.00\",\"SU\",\"SU\",\"SU\",25,\"2020-08-21\",1,0,2.98,3.05,16,14,3.05,0,2.99,0,0,0,0,0,0,3.05,35,44.203\r\n\"2020-07-02\",\"SU
\ 200821P26.00\",\"SU\",\"SU\",\"SU\",26,\"2020-08-21\",1,0,3.7,3.85,62,62,3.85,0,3.75,0,0,0,0,0,0,3.85,14,42.96\r\n\"2020-07-02\",\"SU
\ 200821P27.00\",\"SU\",\"SU\",\"SU\",27,\"2020-08-21\",1,0,4.55,4.65,63,14,4.65,0,4.6,0,0,0,0,0,0,4.65,37,41.271\r\n\"2020-07-02\",\"SU
\ 200821P28.00\",\"SU\",\"SU\",\"SU\",28,\"2020-08-21\",1,0,5.4,5.55,47,47,5.55,0,5.45,0,0,0,0,0,0,5.55,13,38.518\r\n\"2020-07-02\",\"SU
\ 200821P29.00\",\"SU\",\"SU\",\"SU\",29,\"2020-08-21\",1,0,6.35,6.5,47,47,6.5,0,6.35,0,0,0,0,0,0,6.5,0,43.951\r\n\"2020-07-02\",\"SU
\ 200821P30.00\",\"SU\",\"SU\",\"SU\",30,\"2020-08-21\",1,0,7.25,7.45,63,47,7.45,0,7.3,0,0,0,0,0,0,7.45,0,0\r\n\"2020-07-02\",\"SU
\ 200918P12.00\",\"SU\",\"SU\",\"SU\",12,\"2020-09-18\",1,0,0.13,0.16,34,68,0.16,6,0.17,-0.03,0.14,0.14,0.14,0,3,0.16,349,84.937\r\n\"2020-07-02\",\"SU
\ 200918P13.00\",\"SU\",\"SU\",\"SU\",13,\"2020-09-18\",1,0,0.17,0.2,14,65,0.2,0,0.22,0,0,0,0,0,0,0.2,132,79.818\r\n\"2020-07-02\",\"SU
\ 200918P14.00\",\"SU\",\"SU\",\"SU\",14,\"2020-09-18\",1,0,0.21,0.26,82,62,0.26,0,0.28,0,0,0,0,0,0,0.26,142,75.005\r\n\"2020-07-02\",\"SU
\ 200918P15.00\",\"SU\",\"SU\",\"SU\",15,\"2020-09-18\",1,0,0.26,0.32,59,75,0.32,0,0.32,0,0,0,0,0,0,0.32,247,69.954\r\n\"2020-07-02\",\"SU
\ 200918P16.00\",\"SU\",\"SU\",\"SU\",16,\"2020-09-18\",1,0,0.38,0.42,14,55,0.42,0,0.42,0,0,0,0,0,0,0.42,345,67.417\r\n\"2020-07-02\",\"SU
\ 200918P17.00\",\"SU\",\"SU\",\"SU\",17,\"2020-09-18\",1,0,0.48,0.54,52,68,0.54,0,0.54,0,0,0,0,0,0,0.54,147,63.595\r\n\"2020-07-02\",\"SU
\ 200918P18.00\",\"SU\",\"SU\",\"SU\",18,\"2020-09-18\",1,0,0.63,0.7,69,30,0.7,0,0.71,0,0,0,0,0,0,0.7,144,60.576\r\n\"2020-07-02\",\"SU
\ 200918P19.00\",\"SU\",\"SU\",\"SU\",19,\"2020-09-18\",1,0,0.82,0.9,97,16,0.9,0,0.92,0,0,0,0,0,0,0.9,215,57.694\r\n\"2020-07-02\",\"SU
\ 200918P20.00\",\"SU\",\"SU\",\"SU\",20,\"2020-09-18\",1,0,1.07,1.16,96,16,1.16,0,1.18,0,0,0,0,0,0,1.16,287,55.283\r\n\"2020-07-02\",\"SU
\ 200918P21.00\",\"SU\",\"SU\",\"SU\",21,\"2020-09-18\",1,0,1.44,1.51,65,14,1.51,0,1.52,0,0,0,0,0,0,1.51,76,54.193\r\n\"2020-07-02\",\"SU
\ 200918P22.00\",\"SU\",\"SU\",\"SU\",22,\"2020-09-18\",1,0,1.84,1.91,64,14,1.91,0,1.93,0,0,0,0,0,0,1.91,71,52.407\r\n\"2020-07-02\",\"SU
\ 200918P23.00\",\"SU\",\"SU\",\"SU\",23,\"2020-09-18\",1,0,2.32,2.39,24,30,2.39,0,2.37,0,0,0,0,0,0,2.39,76,50.898\r\n\"2020-07-02\",\"SU
\ 200918P24.00\",\"SU\",\"SU\",\"SU\",24,\"2020-09-18\",1,0,2.86,2.94,54,14,2.94,0,2.91,0,0,0,0,0,0,2.94,44,49.237\r\n\"2020-07-02\",\"SU
\ 200918P25.00\",\"SU\",\"SU\",\"SU\",25,\"2020-09-18\",1,0,3.5,3.65,14,61,3.65,0,3.55,0,0,0,0,0,0,3.65,150,49.064\r\n\"2020-07-02\",\"SU
\ 200918P26.00\",\"SU\",\"SU\",\"SU\",26,\"2020-09-18\",1,0,4.15,4.3,65,14,4.3,0,4.3,0,0,0,0,0,0,4.3,34,46.517\r\n\"2020-07-02\",\"SU
\ 200918P27.00\",\"SU\",\"SU\",\"SU\",27,\"2020-09-18\",1,0,4.95,5.1,66,14,5.1,0,5,0,0,0,0,0,0,5.1,43,46.43\r\n\"2020-07-02\",\"SU
\ 200918P28.00\",\"SU\",\"SU\",\"SU\",28,\"2020-09-18\",1,0,5.7,5.95,66,14,5.95,0,5.85,0,0,0,0,0,0,5.95,64,44.696\r\n\"2020-07-02\",\"SU
\ 200918P29.00\",\"SU\",\"SU\",\"SU\",29,\"2020-09-18\",1,0,6.6,6.8,67,14,6.8,0,6.75,0,0,0,0,0,0,6.8,39,44\r\n\"2020-07-02\",\"SU
\ 200918P30.00\",\"SU\",\"SU\",\"SU\",30,\"2020-09-18\",1,0,7.55,7.75,67,47,7.75,0,7.65,0,0,0,0,0,0,7.75,65,45.547\r\n\"2020-07-02\",\"SU
\ 200918P32.00\",\"SU\",\"SU\",\"SU\",32,\"2020-09-18\",1,0,9.45,9.65,67,47,9.65,0,9.55,0,0,0,0,0,0,9.65,67,46.252\r\n\"2020-07-02\",\"SU
\ 200918P34.00\",\"SU\",\"SU\",\"SU\",34,\"2020-09-18\",1,0,11.4,11.6,66,46,11.6,0,11.45,0,0,0,0,0,0,11.6,72,56.126\r\n\"2020-07-02\",\"SU
\ 200918P36.00\",\"SU\",\"SU\",\"SU\",36,\"2020-09-18\",1,0,13.4,13.55,66,46,13.55,0,13.4,0,0,0,0,0,0,13.55,1179,61.664\r\n\"2020-07-02\",\"SU
\ 200918P38.00\",\"SU\",\"SU\",\"SU\",38,\"2020-09-18\",1,0,15.35,15.5,66,14,15.5,0,15.35,0,0,0,0,0,0,15.5,200,32.081\r\n\"2020-07-02\",\"SU
\ 200918P40.00\",\"SU\",\"SU\",\"SU\",40,\"2020-09-18\",1,0,17.25,17.5,76,14,17.5,0,17.4,0,0,0,0,0,0,17.5,158,0\r\n\"2020-07-02\",\"SU
\ 200918P42.00\",\"SU\",\"SU\",\"SU\",42,\"2020-09-18\",1,0,19.35,19.5,66,14,19.5,0,19.35,0,0,0,0,0,0,19.5,78,43.522\r\n\"2020-07-02\",\"SU
\ 200918P44.00\",\"SU\",\"SU\",\"SU\",44,\"2020-09-18\",1,0,21.3,21.5,65,45,21.5,0,21.35,0,0,0,0,0,0,21.5,43,0\r\n\"2020-07-02\",\"SU
\ 200918P46.00\",\"SU\",\"SU\",\"SU\",46,\"2020-09-18\",1,0,23.25,23.5,75,45,23.5,0,23.35,0,0,0,0,0,0,23.5,0,0\r\n\"2020-07-02\",\"SU
\ 200918P48.00\",\"SU\",\"SU\",\"SU\",48,\"2020-09-18\",1,0,25.35,25.5,14,45,25.5,0,25.35,0,0,0,0,0,0,25.5,6,55.421\r\n\"2020-07-02\",\"SU
\ 200918P50.00\",\"SU\",\"SU\",\"SU\",50,\"2020-09-18\",1,0,27.3,27.5,65,45,27.5,0,27.35,0,0,0,0,0,0,27.5,53,0\r\n\"2020-07-02\",\"SU
\ 200918P52.00\",\"SU\",\"SU\",\"SU\",52,\"2020-09-18\",1,0,29.3,29.45,65,14,29.45,0,29.35,0,0,0,0,0,0,29.45,124,0\r\n\"2020-07-02\",\"SU
\ 200918P54.00\",\"SU\",\"SU\",\"SU\",54,\"2020-09-18\",1,0,31.3,31.45,65,14,31.45,0,31.35,0,0,0,0,0,0,31.45,238,0\r\n\"2020-07-02\",\"SU
\ 201218P16.00\",\"SU\",\"SU\",\"SU\",16,\"2020-12-18\",1,0,0.86,0.89,49,10,0.89,0,0.93,0,0,0,0,0,0,0.89,10,59.799\r\n\"2020-07-02\",\"SU
\ 201218P17.00\",\"SU\",\"SU\",\"SU\",17,\"2020-12-18\",1,0,1.06,1.12,48,14,1.12,0,1.12,0,0,0,0,0,0,1.12,2,57.905\r\n\"2020-07-02\",\"SU
\ 201218P18.00\",\"SU\",\"SU\",\"SU\",18,\"2020-12-18\",1,0,1.29,1.38,46,46,1.38,0,1.35,0,0,0,0,0,0,1.38,25,55.943\r\n\"2020-07-02\",\"SU
\ 201218P19.00\",\"SU\",\"SU\",\"SU\",19,\"2020-12-18\",1,0,1.59,1.65,45,14,1.65,0,1.64,0,0,0,0,0,0,1.65,7,54.078\r\n\"2020-07-02\",\"SU
\ 201218P20.00\",\"SU\",\"SU\",\"SU\",20,\"2020-12-18\",1,0,1.93,2,14,14,2,0,1.98,0,0,0,0,0,0,2,25,52.605\r\n\"2020-07-02\",\"SU
\ 201218P21.00\",\"SU\",\"SU\",\"SU\",21,\"2020-12-18\",1,0,2.3,2.41,54,44,2.41,0,2.38,0,0,0,0,0,0,2.41,0,51.142\r\n\"2020-07-02\",\"SU
\ 201218P22.00\",\"SU\",\"SU\",\"SU\",22,\"2020-12-18\",1,0,2.74,2.85,24,44,2.85,0,2.83,0,0,0,0,0,0,2.85,15,49.74\r\n\"2020-07-02\",\"SU
\ 201218P23.00\",\"SU\",\"SU\",\"SU\",23,\"2020-12-18\",1,0,3.25,3.4,14,60,3.4,0,3.35,0,0,0,0,0,0,3.4,1,49.03\r\n\"2020-07-02\",\"SU
\ 201218P24.00\",\"SU\",\"SU\",\"SU\",24,\"2020-12-18\",1,0,3.75,3.95,70,44,3.95,0,3.9,0,0,0,0,0,0,3.95,0,47.422\r\n\"2020-07-02\",\"SU
\ 201218P25.00\",\"SU\",\"SU\",\"SU\",25,\"2020-12-18\",1,0,4.4,4.55,24,44,4.55,0,4.55,0,0,0,0,0,0,4.55,15,46.666\r\n\"2020-07-02\",\"SU
\ 201218P26.00\",\"SU\",\"SU\",\"SU\",26,\"2020-12-18\",1,0,5.05,5.25,32,31,5.25,4,5.2,-0.25,4.95,4.95,4.95,19,1,5.25,7,45.973\r\n\"2020-07-02\",\"SU
\ 201218P27.00\",\"SU\",\"SU\",\"SU\",27,\"2020-12-18\",1,0,5.75,6,67,31,6,0,5.95,0,0,0,0,0,0,6,27,45.403\r\n\"2020-07-02\",\"SU
\ 201218P28.00\",\"SU\",\"SU\",\"SU\",28,\"2020-12-18\",1,0,6.55,6.8,20,31,6.8,0,6.7,0,0,0,0,0,0,6.8,11,45.529\r\n\"2020-07-02\",\"SU
\ 201218P29.00\",\"SU\",\"SU\",\"SU\",29,\"2020-12-18\",1,0,7.35,7.6,36,32,7.6,0,7.5,0,0,0,0,0,0,7.6,0,45.02\r\n\"2020-07-02\",\"SU
\ 201218P30.00\",\"SU\",\"SU\",\"SU\",30,\"2020-12-18\",1,0,8.2,8.45,36,32,8.45,0,8.35,0,0,0,0,0,0,8.45,17,44.941\r\n\"2020-07-02\",\"SU
\ 201218P32.00\",\"SU\",\"SU\",\"SU\",32,\"2020-12-18\",1,0,9.95,10.2,36,32,10.2,0,10.1,0,0,0,0,0,0,10.2,0,44.257\r\n\"2020-07-02\",\"SU
\ 201218P34.00\",\"SU\",\"SU\",\"SU\",34,\"2020-12-18\",1,0,11.75,12.1,68,32,12.1,0,12.05,0,0,0,0,0,0,12.1,0,44.335\r\n\"2020-07-02\",\"SU
\ 210115P13.00\",\"SU\",\"SU\",\"SU\",13,\"2021-01-15\",1,0,0.51,0.71,20,58,0.71,0,0.67,0,0,0,0,0,0,0.71,377,68.657\r\n\"2020-07-02\",\"SU
\ 210115P14.00\",\"SU\",\"SU\",\"SU\",14,\"2021-01-15\",1,0,0.64,0.84,20,59,0.84,0,0.84,0,0,0,0,0,0,0.84,66,65.602\r\n\"2020-07-02\",\"SU
\ 210115P15.00\",\"SU\",\"SU\",\"SU\",15,\"2021-01-15\",1,0,0.78,0.84,57,37,0.84,27,0.84,-0.08,0.76,0.76,0.76,18,3,0.84,57,60.435\r\n\"2020-07-02\",\"SU
\ 210115P16.00\",\"SU\",\"SU\",\"SU\",16,\"2021-01-15\",1,0,0.93,1.11,55,35,1.11,0,1.11,0,0,0,0,0,0,1.11,67,58.848\r\n\"2020-07-02\",\"SU
\ 210115P17.00\",\"SU\",\"SU\",\"SU\",17,\"2021-01-15\",1,0,1.13,1.33,53,53,1.33,0,1.34,0,0,0,0,0,0,1.33,35,56.548\r\n\"2020-07-02\",\"SU
\ 210115P18.00\",\"SU\",\"SU\",\"SU\",18,\"2021-01-15\",1,0,1.36,1.57,52,52,1.57,0,1.58,0,0,0,0,0,0,1.57,62,54.2\r\n\"2020-07-02\",\"SU
\ 210115P19.00\",\"SU\",\"SU\",\"SU\",19,\"2021-01-15\",1,0,1.64,1.85,51,31,1.85,0,1.86,0,0,0,0,0,0,1.85,31,52.135\r\n\"2020-07-02\",\"SU
\ 210115P20.00\",\"SU\",\"SU\",\"SU\",20,\"2021-01-15\",1,0,1.97,2.19,51,51,2.19,0,2.2,0,0,0,0,0,0,2.19,27,50.41\r\n\"2020-07-02\",\"SU
\ 210115P21.00\",\"SU\",\"SU\",\"SU\",21,\"2021-01-15\",1,0,2.35,2.58,70,50,2.58,0,2.59,0,0,0,0,0,0,2.58,140,48.839\r\n\"2020-07-02\",\"SU
\ 210115P22.00\",\"SU\",\"SU\",\"SU\",22,\"2021-01-15\",1,0,2.79,3.05,50,50,3.05,0,3,0,0,0,0,0,0,3.05,22,47.677\r\n\"2020-07-02\",\"SU
\ 210115P23.00\",\"SU\",\"SU\",\"SU\",23,\"2021-01-15\",1,0,3.25,3.55,76,50,3.55,0,3.5,0,0,0,0,0,0,3.55,32,46.176\r\n\"2020-07-02\",\"SU
\ 210115P24.00\",\"SU\",\"SU\",\"SU\",24,\"2021-01-15\",1,0,3.85,4.1,50,50,4.1,0,4.05,0,0,0,0,0,0,4.1,10,45.407\r\n\"2020-07-02\",\"SU
\ 210115P25.00\",\"SU\",\"SU\",\"SU\",25,\"2021-01-15\",1,0,4.45,4.75,50,50,4.75,0,4.65,0,0,0,0,0,0,4.75,74,44.688\r\n\"2020-07-02\",\"SU
\ 210115P26.00\",\"SU\",\"SU\",\"SU\",26,\"2021-01-15\",1,0,5.15,5.4,51,51,5.4,0,5.3,0,0,0,0,0,0,5.4,7,44.053\r\n\"2020-07-02\",\"SU
\ 210115P27.00\",\"SU\",\"SU\",\"SU\",27,\"2021-01-15\",1,0,5.85,6.1,51,51,6.1,0,6.05,0,0,0,0,0,0,6.1,3,43.136\r\n\"2020-07-02\",\"SU
\ 210115P28.00\",\"SU\",\"SU\",\"SU\",28,\"2021-01-15\",1,0,6.65,6.85,20,31,6.85,0,6.8,0,0,0,0,0,0,6.85,30,42.833\r\n\"2020-07-02\",\"SU
\ 210115P29.00\",\"SU\",\"SU\",\"SU\",29,\"2021-01-15\",1,0,7.4,7.65,52,32,7.65,0,7.55,0,0,0,0,0,0,7.65,4,41.89\r\n\"2020-07-02\",\"SU
\ 210115P30.00\",\"SU\",\"SU\",\"SU\",30,\"2021-01-15\",1,0,8.25,8.5,52,32,8.5,0,8.4,0,0,0,0,0,0,8.5,78,41.8\r\n\"2020-07-02\",\"SU
\ 210115P32.00\",\"SU\",\"SU\",\"SU\",32,\"2021-01-15\",1,0,10,10.25,20,33,10.25,0,10.15,0,0,0,0,0,0,10.25,423,41.134\r\n\"2020-07-02\",\"SU
\ 210115P34.00\",\"SU\",\"SU\",\"SU\",34,\"2021-01-15\",1,0,11.85,12.15,20,20,12.15,0,12.05,0,0,0,0,0,0,12.15,518,41.994\r\n\"2020-07-02\",\"SU
\ 210115P36.00\",\"SU\",\"SU\",\"SU\",36,\"2021-01-15\",1,0,13.7,13.95,52,32,13.95,0,13.85,0,0,0,0,0,0,13.95,427,39.118\r\n\"2020-07-02\",\"SU
\ 210115P38.00\",\"SU\",\"SU\",\"SU\",38,\"2021-01-15\",1,0,15.65,15.9,20,32,15.9,0,15.8,0,0,0,0,0,0,15.9,161,36.64\r\n\"2020-07-02\",\"SU
\ 210115P40.00\",\"SU\",\"SU\",\"SU\",40,\"2021-01-15\",1,0,17.6,17.85,20,32,17.85,0,17.75,0,0,0,0,0,0,17.85,178,47.778\r\n\"2020-07-02\",\"SU
\ 210115P42.00\",\"SU\",\"SU\",\"SU\",42,\"2021-01-15\",1,0,19.55,19.8,20,32,19.8,0,19.7,0,0,0,0,0,0,19.8,7768,49.127\r\n\"2020-07-02\",\"SU
\ 210115P44.00\",\"SU\",\"SU\",\"SU\",44,\"2021-01-15\",1,0,21.55,21.8,20,51,21.8,0,21.65,0,0,0,0,0,0,21.8,126,52.34\r\n\"2020-07-02\",\"SU
\ 210115P46.00\",\"SU\",\"SU\",\"SU\",46,\"2021-01-15\",1,0,23.3,23.7,61,20,23.7,0,23.55,0,0,0,0,0,0,23.7,38,0\r\n\"2020-07-02\",\"SU
\ 210115P48.00\",\"SU\",\"SU\",\"SU\",48,\"2021-01-15\",1,0,25.3,25.7,61,20,25.7,0,25.55,0,0,0,0,0,0,25.7,70,0\r\n\"2020-07-02\",\"SU
\ 210115P50.00\",\"SU\",\"SU\",\"SU\",50,\"2021-01-15\",1,0,27.35,27.7,61,51,27.7,0,27.55,0,0,0,0,0,0,27.7,50,0\r\n\"2020-07-02\",\"SU
\ 210115P52.00\",\"SU\",\"SU\",\"SU\",52,\"2021-01-15\",1,0,29.25,29.7,61,51,29.7,0,29.5,0,0,0,0,0,0,29.7,69,0\r\n\"2020-07-02\",\"SU
\ 210115P54.00\",\"SU\",\"SU\",\"SU\",54,\"2021-01-15\",1,0,31.25,31.65,61,20,31.65,0,31.5,0,0,0,0,0,0,31.65,5,0\r\n\"2020-07-02\",\"SU
\ 210115P56.00\",\"SU\",\"SU\",\"SU\",56,\"2021-01-15\",1,0,33.25,33.65,61,20,33.65,0,33.5,0,0,0,0,0,0,33.65,42,0\r\n\"2020-07-02\",\"SU
\ 210115P58.00\",\"SU\",\"SU\",\"SU\",58,\"2021-01-15\",1,0,35.3,35.65,61,51,35.65,0,35.5,0,0,0,0,0,0,35.65,7256,0\r\n\"2020-07-02\",\"SU
\ 210115P60.00\",\"SU\",\"SU\",\"SU\",60,\"2021-01-15\",1,0,37.3,37.65,61,51,37.65,0,37.5,0,0,0,0,0,0,37.65,3000,0\r\n\"2020-07-02\",\"SU
\ 220121P13.00\",\"SU\",\"SU\",\"SU\",13,\"2022-01-21\",1,0,1.34,2.83,20,5,2.83,0,2.81,0,0,0,0,0,0,2.83,53,64.822\r\n\"2020-07-02\",\"SU
\ 220121P14.00\",\"SU\",\"SU\",\"SU\",14,\"2022-01-21\",1,0,1.58,3.1,20,5,3.1,0,3.05,0,0,0,0,0,0,3.1,0,62.291\r\n\"2020-07-02\",\"SU
\ 220121P15.00\",\"SU\",\"SU\",\"SU\",15,\"2022-01-21\",1,0,1.85,3.35,20,5,3.35,0,3.35,0,0,0,0,0,0,3.35,10,59.732\r\n\"2020-07-02\",\"SU
\ 220121P16.00\",\"SU\",\"SU\",\"SU\",16,\"2022-01-21\",1,0,2.16,3.65,20,5,3.65,0,3.65,0,0,0,0,0,0,3.65,10,57.653\r\n\"2020-07-02\",\"SU
\ 220121P17.00\",\"SU\",\"SU\",\"SU\",17,\"2022-01-21\",1,0,2.5,4,20,5,4,0,4,0,0,0,0,0,0,4,27,55.899\r\n\"2020-07-02\",\"SU
\ 220121P18.00\",\"SU\",\"SU\",\"SU\",18,\"2022-01-21\",1,0,2.88,4.4,20,5,4.4,0,4.35,0,0,0,0,0,0,4.4,0,54.467\r\n\"2020-07-02\",\"SU
\ 220121P19.00\",\"SU\",\"SU\",\"SU\",19,\"2022-01-21\",1,0,3.25,4.8,20,5,4.8,0,4.75,0,0,0,0,0,0,4.8,0,52.772\r\n\"2020-07-02\",\"SU
\ 220121P20.00\",\"SU\",\"SU\",\"SU\",20,\"2022-01-21\",1,0,3.7,5.25,20,5,5.25,0,5.2,0,0,0,0,0,0,5.25,0,51.561\r\n\"2020-07-02\",\"SU
\ 220121P21.00\",\"SU\",\"SU\",\"SU\",21,\"2022-01-21\",1,0,0.06,5.75,40,5,5.75,0,5.7,0,0,0,0,0,0,5.75,26,30.32\r\n\"2020-07-02\",\"SU
\ 220121P22.00\",\"SU\",\"SU\",\"SU\",22,\"2022-01-21\",1,0,0.44,6.25,40,5,6.25,0,6.2,0,0,0,0,0,0,6.25,0,29.1\r\n\"2020-07-02\",\"SU
\ 220121P23.00\",\"SU\",\"SU\",\"SU\",23,\"2022-01-21\",1,0,0.99,6.25,40,1,6.25,0,6.5,0,0,0,0,0,0,6.25,1,25.922\r\n\"2020-07-02\",\"SU
\ 220121P24.00\",\"SU\",\"SU\",\"SU\",24,\"2022-01-21\",1,0,1.59,7.4,40,5,7.4,0,7.35,0,0,0,0,0,0,7.4,0,27.935\r\n\"2020-07-02\",\"SU
\ 220121P25.00\",\"SU\",\"SU\",\"SU\",25,\"2022-01-21\",1,0,2.21,8.05,40,5,8.05,0,7.95,0,0,0,0,0,0,8.05,0,27.284\r\n\"2020-07-02\",\"SU
\ 220121P26.00\",\"SU\",\"SU\",\"SU\",26,\"2022-01-21\",1,0,3.55,8.7,40,5,8.7,0,8.6,0,0,0,0,0,0,8.7,0,29.791\r\n\"2020-07-02\",\"SU
\ 220121P27.00\",\"SU\",\"SU\",\"SU\",27,\"2022-01-21\",1,0,3.55,9.35,30,5,9.35,0,9.3,0,0,0,0,0,0,9.35,5,25.133\r\n\"2020-07-02\",\"SU
\ 220121P28.00\",\"SU\",\"SU\",\"SU\",28,\"2022-01-21\",1,0,4.3,10.1,30,5,10.1,0,10,0,0,0,0,0,0,10.1,0,24.292\r\n\"2020-07-02\",\"SU
\ 220121P29.00\",\"SU\",\"SU\",\"SU\",29,\"2022-01-21\",1,0,5.05,10.85,30,5,10.85,0,10.75,0,0,0,0,0,0,10.85,0,22.881\r\n\"2020-07-02\",\"SU
\ 220121P30.00\",\"SU\",\"SU\",\"SU\",30,\"2022-01-21\",1,0,5.8,11.6,30,5,11.6,0,11.5,0,0,0,0,0,0,11.6,0,20.547\r\n\"2020-07-02\",\"SU
\ 220121P32.00\",\"SU\",\"SU\",\"SU\",32,\"2022-01-21\",1,0,7.4,13.2,30,5,13.2,0,13.1,0,0,0,0,0,0,13.2,153,0\r\n\"2020-07-02\",\"SU
\ 220121P34.00\",\"SU\",\"SU\",\"SU\",34,\"2022-01-21\",1,0,8.85,14.65,30,5,14.65,0,14.55,0,0,0,0,0,0,14.65,25,0\r\n\"2020-07-02\",\"SU
\ 220121P36.00\",\"SU\",\"SU\",\"SU\",36,\"2022-01-21\",1,0,10.6,16.4,30,5,16.4,0,16.3,0,0,0,0,0,0,16.4,49,0\r\n\"2020-07-02\",\"SU
\ 220121P38.00\",\"SU\",\"SU\",\"SU\",38,\"2022-01-21\",1,0,12.4,18.2,30,5,18.2,0,18.05,0,0,0,0,0,0,18.2,25,0\r\n\"2020-07-02\",\"SU
\ 220121P40.00\",\"SU\",\"SU\",\"SU\",40,\"2022-01-21\",1,0,14.2,20,30,5,20,0,19.9,0,0,0,0,0,0,20,3045,0\r\n\"2020-07-02\",\"SU
\ 220121P42.00\",\"SU\",\"SU\",\"SU\",42,\"2022-01-21\",1,0,16.05,25.1,30,20,25.1,0,25,0,0,0,0,0,0,25.1,75,31.912\r\n\"2020-07-02\",\"SU
\ 220121P44.00\",\"SU\",\"SU\",\"SU\",44,\"2022-01-21\",1,0,17.95,27,30,20,27,0,26.85,0,0,0,0,0,0,27,5,34.223\r\n\"2020-07-02\",\"SU
\ 220121P46.00\",\"SU\",\"SU\",\"SU\",46,\"2022-01-21\",1,0,19.9,28.9,30,20,28.9,0,28.75,0,0,0,0,0,0,28.9,20,26.076\r\n\"2020-07-02\",\"SU
\ 220121P48.00\",\"SU\",\"SU\",\"SU\",48,\"2022-01-21\",1,0,21.8,30.8,30,20,30.8,0,30.7,0,0,0,0,0,0,30.8,24,0\r\n\"2020-07-02\",\"SU
\ 220121P50.00\",\"SU\",\"SU\",\"SU\",50,\"2022-01-21\",1,0,23.7,32.75,30,20,32.75,0,32.6,0,0,0,0,0,0,32.75,94,0\r\n\"2020-07-02\",\"SU
\ 220121P60.00\",\"SU\",\"SU\",\"SU\",60,\"2022-01-21\",1,0,33.45,42.5,30,20,42.5,0,42.35,0,0,0,0,0,0,42.5,3053,0"
headers:
Cache-Control:
- max-age=0, no-cache, must-revalidate
Connection:
- close
Content-Disposition:
- attachment; filename="quote_SU_20200702.csv"
Content-Length:
- '46847'
Content-Type:
- text/csv;charset=UTF-8
Date:
- Sat, 10 Jun 2023 22:49:51 GMT
Expires:
- '0'
Pragma:
- no-cache
Server:
- Apache
Set-Cookie:
- PHPSESSID=hr32moe2emhs26eoo098blfiqt; expires=Sun, 11-Jun-2023 02:49:51 GMT;
Max-Age=14400; path=/
Vary:
- Accept-Encoding
Via:
- 1.1 28fdf6e146f70e7372911f118404fb20.cloudfront.net (CloudFront)
X-Amz-Cf-Id:
- Z2MbTY3sHWAXCrZivsgNjrnxYl-VZyqTae0epirYpgu-w6GosXkAmQ==
X-Amz-Cf-Pop:
- SEA19-C3
X-Cache:
- Miss from cloudfront
status:
code: 200
message: OK
version: 1

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,29 @@
,AAPL
id,sec_agjrgj
companyID,com_NX6GzO
name,Apple Inc
type,Ordinary Shares
code,EQS
shareClass,AAPL
currency,USD
roundLotSize,100.0
ticker,AAPL
exchangeTicker,AAPL:UW
compositeTicker,AAPL:US
alternateTickers,[]
figi,BBG000B9Y5X2
cik,0000320193
compositeFIGI,BBG000B9XRY4
shareClassFIGI,BBG001S5N8V8
figiUniqueID,EQ0010169500001000
active,True
etf,False
delisted,False
primaryListing,True
primary_security,True
firstStockPrice,1980-12-12
lastStockPrice,2023-05-19
lastStockPriceAdjustment,2023-05-12
lastCorporateAction,2023-05-11
previousTickers,[]
listingExchangeMIC,XNAS
1 AAPL
2 id sec_agjrgj
3 companyID com_NX6GzO
4 name Apple Inc
5 type Ordinary Shares
6 code EQS
7 shareClass AAPL
8 currency USD
9 roundLotSize 100.0
10 ticker AAPL
11 exchangeTicker AAPL:UW
12 compositeTicker AAPL:US
13 alternateTickers []
14 figi BBG000B9Y5X2
15 cik 0000320193
16 compositeFIGI BBG000B9XRY4
17 shareClassFIGI BBG001S5N8V8
18 figiUniqueID EQ0010169500001000
19 active True
20 etf False
21 delisted False
22 primaryListing True
23 primary_security True
24 firstStockPrice 1980-12-12
25 lastStockPrice 2023-05-19
26 lastStockPriceAdjustment 2023-05-12
27 lastCorporateAction 2023-05-11
28 previousTickers []
29 listingExchangeMIC XNAS

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
["expiration", "strike", "optionType", "optionSymbol", "date", "close", "bid", "ask", "volume", "open", "openInterest", "high", "low", "impliedVolatility", "delta", "gamma", "theta", "vega", "dte"]

View File

@@ -0,0 +1 @@
["Nasdaq Traded", "Security Name", "Listing Exchange", "Market Category", "ETF", "Round Lot Size", "Test Issue", "Financial Status", "CQS Symbol", "NASDAQ Symbol", "NextShares"]

View File

@@ -0,0 +1 @@
["optionType", "expiration", "strike", "lastPrice", "bid", "ask", "openInterest", "volume", "dte"]

View File

@@ -0,0 +1 @@
["companyName", "price", "change", "changePercent", "volume", "date"]

View File

@@ -0,0 +1 @@
["cDelta", "cGamma", "cRho", "cTheta", "cVega", "cIV", "strike", "pDelta", "pGamma", "pRho", "pTheta", "pVega", "pIV"]

View File

@@ -0,0 +1 @@
[["expiration", "strike", "optionType", "contractSymbol", "bid", "bidSize", "ask", "askSize", "impliedVolatility", "openInterest", "volume", "delta", "gamma", "theta", "rho", "vega", "theoretical", "change", "open", "high", "low", "tick", "lastTradePrice", "lastTradeTimestamp", "changePercent", "previousClose", "dte"], ["type", "tick", "bid", "bidSize", "askSize", "ask", "price", "open", "high", "low", "close", "volume", "previousClose", "change", "changePercent", "ivThirty", "ivThirtyChange", "lastTradeTimestamp", "ivThirtyOneYearHigh", "hvThirtyOneYearHigh", "ivThirtyOneYearLow", "hvThirtyOneYearLow", "ivSixtyOneYearHigh", "hvSixtyOneYearHigh", "ivSixtyOneYearLow", "hvsixtyOneYearLow", "ivNinetyOneYearHigh", "hvNinetyOneYearHigh", "ivNinetyOneYearLow", "hvNinetyOneYearLow"]]

View File

@@ -0,0 +1 @@
["APPLE INC COM", "AAPL"]

View File

@@ -0,0 +1 @@
["Call Strike", "Call IV", "Call ATM IV", "Call Skew", "Put Strike", "Put IV", "Put ATM IV", "Put Skew", "IV Skew"]

View File

@@ -0,0 +1 @@
["Puts OI", "Calls OI", "Total OI", "OI Ratio", "Puts OTM", "Calls OTM", "Puts ITM", "Calls ITM", "OTM Ratio", "ITM Percent", "Puts Volume", "Calls Volume", "Total Volume", "Volume Ratio", "Vol-OI Ratio"]

View File

@@ -0,0 +1 @@
["Puts OI", "Calls OI", "Total OI", "OI Ratio", "Puts Volume", "Calls Volume", "Total Volume", "Volume Ratio", "Vol-OI Ratio"]

View File

@@ -0,0 +1 @@
[["Symbol", "Underlying Price", "Expiration", "DTE", "Strike 1", "Strike 2", "Strike 1 Premium", "Strike 2 Premium", "Cost", "Cost Percent", "Breakeven Upper", "Breakeven Upper Percent", "Breakeven Lower", "Breakeven Lower Percent", "Max Profit", "Max Loss", "Payoff Ratio"], ["Long Straddle"]]

View File

@@ -0,0 +1 @@
[["Symbol", "Underlying Price", "Expiration", "DTE", "Strike 1", "Strike 2", "Strike 1 Premium", "Strike 2 Premium", "Cost", "Cost Percent", "Breakeven Upper", "Breakeven Upper Percent", "Breakeven Lower", "Breakeven Lower Percent", "Max Profit", "Max Loss", "Payoff Ratio"], ["Long Strangle"]]

View File

@@ -0,0 +1 @@
[["Symbol", "Underlying Price", "Expiration", "DTE", "Strike 1", "Strike 2", "Strike 1 Premium", "Strike 2 Premium", "Cost", "Cost Percent", "Breakeven Lower", "Breakeven Lower Percent", "Breakeven Upper", "Breakeven Upper Percent", "Max Profit", "Max Loss", "Payoff Ratio"], ["Bull Call Spread"]]

View File

@@ -0,0 +1 @@
[["Symbol", "Underlying Price", "Expiration", "DTE", "Strike 1", "Strike 2", "Strike 1 Premium", "Strike 2 Premium", "Cost", "Cost Percent", "Breakeven Lower", "Breakeven Lower Percent", "Breakeven Upper", "Breakeven Upper Percent", "Max Profit", "Max Loss", "Payoff Ratio"], ["Bear Put Spread"]]

View File

@@ -0,0 +1 @@
["Long Straddle", "Long Strangle", "Long Strangle", "Long Strangle", "Bull Call Spread", "Bear Put Spread", "Long Straddle", "Long Strangle", "Long Strangle", "Long Strangle", "Bull Call Spread", "Bear Put Spread", "Long Straddle", "Long Strangle", "Long Strangle", "Long Strangle", "Bull Call Spread", "Bear Put Spread", "Long Straddle", "Long Strangle", "Long Strangle", "Long Strangle", "Bull Call Spread", "Bear Put Spread"]

View File

@@ -0,0 +1 @@
["Expiration", "Strike", "Option Type", "IV", "Skew"]

View File

@@ -0,0 +1 @@
[["expiration", "strike", "optionType", "optionSymbol", "bid", "ask", "openInterest", "volume", "impliedVolatility", "delta", "gamma", "theta", "vega", "dte"], ["symbol", "name", "exch", "type", "last", "change", "volume", "open", "high", "low", "close", "bid", "ask", "changePercent", "avgVolume", "volume", "lastTradeTimestamp", "previousClose", "fiftyTwoWeekHigh", "fiftyTwoWeekLow", "bidSize", "bidExchange", "bidDate", "askSize", "askExchange", "askDate", "rootSymbols"], ["symbol", "exchange", "type", "description"], "Apple Inc", "Apple Inc"]

View File

@@ -0,0 +1 @@
["lastPrice", "previousClose", "open", "high", "low", "yearHigh", "yearLow", "fiftyDayMA", "twoHundredDayMA"]

View File

@@ -0,0 +1 @@
["contractSymbol", "optionType", "expiration", "strike", "lastPrice", "bid", "ask", "openInterest", "volume", "impliedVolatility", "dte"]

View File

@@ -0,0 +1,82 @@
# IMPORTATION STANDARD
# IMPORTATION THIRDPARTY
import pandas as pd
import pytest
# IMPORTATION INTERNAL
from openbb_terminal.stocks.options import cboe_model
@pytest.mark.vcr
def test_symbol_directory():
result_df = cboe_model.get_cboe_directory()
assert isinstance(result_df, pd.DataFrame)
assert not result_df.empty
@pytest.mark.vcr
def test_underlying_price():
result_df = cboe_model.load_options("QQQ")
hasattr(result_df, "underlying_price")
assert isinstance(result_df.underlying_price, pd.Series)
assert isinstance(result_df.underlying_price["price"], float)
@pytest.mark.vcr
@pytest.mark.record_stdout
def test_underlying_price_bad_symbol():
data = cboe_model.load_options("BAD_SYMBOL")
assert hasattr(data, "underlying_name") is False
@pytest.mark.vcr
def test_underlying_name():
ticker = cboe_model.load_options("SPX")
assert hasattr(ticker, "underlying_name")
assert isinstance(ticker.underlying_name, str)
assert ticker.underlying_name == "SPX"
@pytest.mark.vcr
def test_last_price():
ticker = cboe_model.load_options("AAPL")
assert hasattr(ticker, "last_price")
assert isinstance(ticker.last_price, float)
assert ticker.last_price == ticker.underlying_price["price"]
@pytest.mark.vcr
def test_chains():
ticker = cboe_model.load_options("JPM")
assert hasattr(ticker, "chains")
assert ticker.symbol == "JPM"
assert isinstance(ticker.chains, pd.DataFrame)
assert ticker.expirations[0] == ticker.chains["expiration"][0]
@pytest.mark.vcr
def test_strikes():
ticker = cboe_model.load_options("TSLA")
results_df = ticker
assert hasattr(results_df, "strikes")
assert isinstance(results_df.strikes, list)
assert isinstance(results_df.strikes[0], float)
assert len(results_df.strikes) > 1
@pytest.mark.vcr
def test_expirations():
ticker = cboe_model.load_options("OXY")
assert hasattr(ticker, "expirations")
assert isinstance(ticker.expirations, list)
assert isinstance(ticker.expirations[0], str)
assert ticker.expirations[0] == ticker.chains["expiration"].iloc[0]
@pytest.mark.vcr
def test_hasGreeks_hasIV():
ticker = cboe_model.load_options("TSLA")
assert ticker.underlying_name != "TSLA"
assert ticker.hasGreeks is True
assert ticker.hasIV is True

View File

@@ -79,3 +79,34 @@ def test_option_chain_bad_symbol(recorder):
)
recorder.capture(df2)
assert df2.empty
@pytest.mark.vcr
def test_get_ticker_info(recorder):
df = intrinio_model.get_ticker_info("AAPL")
recorder.capture(df)
assert df["ticker"] == "AAPL"
data = intrinio_model.load_options("AAPL")
assert df["name"] == data.underlying_name
assert data.symbol in data.SYMBOLS
@pytest.mark.vcr
def test_SYMBOLS(recorder):
results_df = intrinio_model.get_all_ticker_symbols()
assert isinstance(results_df, list)
recorder.capture(results_df[0])
@pytest.mark.vcr
def test_load_options(recorder):
data = intrinio_model.load_options("AAPL")
assert data.symbol == "AAPL"
assert data.hasIV is True
assert isinstance(data.underlying_price, pd.Series)
assert not data.chains.empty
assert isinstance(data.underlying_name, str)
data = intrinio_model.load_options("AAPL", date="2023-01-05", pydantic=True)
assert data.source == "Intrinio"
assert data.date == "2023-01-05"
recorder.capture(pd.DataFrame(data.chains).columns.to_list())

View File

@@ -0,0 +1,67 @@
# pylint: disable=no-member
# IMPORTATION STANDARD
# IMPORTATION THIRDPARTY
import pandas as pd
import pytest
import requests
# IMPORTATION INTERNAL
from openbb_terminal.stocks.options import nasdaq_model
@pytest.fixture(scope="module")
def vcr_config():
return {
"filter_headers": [("User-Agent", None)],
}
@pytest.mark.vcr
def test_SYMBOLS(recorder):
ticker = nasdaq_model.load_options("AAPL")
results_df = ticker.SYMBOLS
assert not results_df.empty
recorder.capture(results_df.columns.to_list())
@pytest.mark.vcr
def test_last_price():
result_df = nasdaq_model.load_options("QQQ")
assert isinstance(result_df.last_price, float)
assert result_df.last_price > 0
@pytest.mark.vcr(record_mode="none")
@pytest.mark.record_stdout
def test_load_options_bad_symbol(mocker):
mock_response = requests.Response()
mock_response.status_code = 400
mocker.patch(
target="openbb_terminal.helper_funcs.requests.get",
new=mocker.Mock(return_value=mock_response),
)
data = nasdaq_model.load_options("BAD_SYMBOL")
assert hasattr(data, "underlying_name") is False
@pytest.mark.vcr
def test_load_options(recorder):
data = nasdaq_model.load_options(symbol="OXY")
assert isinstance(data.chains, pd.DataFrame)
assert isinstance(data.last_price, float)
assert isinstance(data.underlying_price, pd.Series)
df1 = pd.DataFrame(data.chains)
data = nasdaq_model.load_options(symbol="OXY", pydantic=True)
assert isinstance(data.chains, dict)
assert isinstance(data.underlying_price, dict)
assert isinstance(data.expirations, list)
assert isinstance(data.strikes, list)
df2 = pd.DataFrame(data.chains)
assert df1.columns.equals(df2.columns)
df_greeks = data.get_available_greeks()
recorder.capture(df2.columns.to_list())
recorder.capture(list(data.underlying_price.keys()))
recorder.capture(data.underlying_name)
recorder.capture(data.symbol)
recorder.capture(df_greeks.columns.to_list())

View File

@@ -0,0 +1,48 @@
# pylint: disable=no-member
# IMPORTATION STANDARD
# IMPORTATION THIRDPARTY
import pandas as pd
import pytest
# IMPORTATION INTERNAL
from openbb_terminal.stocks.options import options_chains_model
@pytest.mark.vcr
def test_OptionsChains(recorder):
df1 = options_chains_model.OptionsChains("AAPL")
df2 = options_chains_model.OptionsChains("AAPL", "YahooFinance", pydantic=True)
assert hasattr(df1, "chains")
assert hasattr(df2, "underlying_price")
assert isinstance(df1.underlying_price, pd.Series)
assert isinstance(df2.chains, dict)
recorder.capture(
[df1.chains.columns.to_list(), df1.underlying_price.index.to_list()]
)
recorder.capture([df1.underlying_name, df2.underlying_name])
stats1 = df1.get_stats()
stats2 = df2.get_stats("strike")
recorder.capture(stats1.columns.to_list())
recorder.capture(stats2.columns.to_list())
straddle = df1.get_straddle()
recorder.capture([straddle.index.to_list(), straddle.columns.to_list()])
strangle = df1.get_strangle(days=90, moneyness=20)
recorder.capture([strangle.index.to_list(), strangle.columns.to_list()])
call_spread = df1.get_vertical_call_spread()
recorder.capture([call_spread.index.to_list(), call_spread.columns.to_list()])
put_spread = df1.get_vertical_put_spread()
recorder.capture([put_spread.index.to_list(), put_spread.columns.to_list()])
strategies = df1.get_strategies(
days=[30, 60, 90, 180],
straddle_strike=df1.last_price,
strangle_moneyness=[5, 10, 20],
vertical_calls=[200, 180],
vertical_puts=[150, 180],
)
recorder.capture(strategies["Strategy"].to_list())
vertical_skew = df1.get_skew()
recorder.capture(vertical_skew.columns.to_list())
horizontal_skew = df2.get_skew(moneyness=10)
recorder.capture(horizontal_skew.columns.to_list())

View File

@@ -0,0 +1,124 @@
# IMPORTATION STANDARD
# IMPORTATION THIRDPARTY
import pandas as pd
import pytest
# IMPORTATION INTERNAL
from openbb_terminal.stocks.options import tmx_model
# pylint: disable=no-member
@pytest.fixture(scope="module")
def vcr_config():
return {
"filter_headers": [("Authorization")],
"filter_query_parameters": [
("before", "MOCK_BEFORE"),
("after", "MOCK_AFTER"),
],
}
@pytest.mark.vcr
def test_underlying_price():
result_df = tmx_model.get_underlying_price("XIU")
assert isinstance(result_df, pd.Series)
assert "price" in result_df.index
result_df2 = tmx_model.load_options("XIU", pydantic=True)
assert result_df["price"] == result_df2.last_price
assert hasattr(result_df2, "underlying_price")
assert isinstance(result_df2.underlying_price, dict)
assert result_df2.underlying_price["price"] == result_df["price"]
@pytest.mark.record_stdout
def test_underlying_price_bad_symbol():
result_df = tmx_model.get_underlying_price("BAD_SYMBOL")
assert result_df.empty
@pytest.mark.vcr
def test_underlying_name():
ticker = tmx_model.get_chains("BAM")
assert hasattr(ticker, "underlying_name")
assert isinstance(ticker.underlying_name, str)
assert ticker.underlying_name != "BAM"
@pytest.mark.vcr
def test_check_symbol():
result_df = tmx_model.check_symbol("BAD_SYMBOL")
assert isinstance(result_df, bool)
result_df2 = tmx_model.check_symbol("CM")
assert result_df2 is True
@pytest.mark.vcr
def test_last_price():
ticker = tmx_model.load_options("AC")
assert hasattr(ticker, "last_price")
assert isinstance(ticker.last_price, float)
ticker2 = tmx_model.get_eodchains("AC", "2021-12-28")
assert hasattr(ticker2, "last_price")
assert isinstance(ticker2.last_price, float)
assert ticker.last_price != ticker2.last_price
@pytest.mark.vcr
def test_chains():
ticker = tmx_model.get_chains("BMO")
assert hasattr(ticker, "chains")
assert isinstance(ticker.chains, pd.DataFrame)
ticker = tmx_model.load_options("BMO", pydantic=True)
assert hasattr(ticker, "chains")
assert isinstance(ticker.chains, dict)
assert ticker.hasGreeks is False
@pytest.mark.vcr
def test_strikes():
ticker = tmx_model.get_chains("RY")
assert hasattr(ticker, "strikes")
assert isinstance(ticker.strikes, list)
assert isinstance(ticker.strikes[0], float)
assert ticker.strikes[-1] == max(ticker.chains["strike"])
@pytest.mark.vcr
def test_eodchains_holiday():
ticker = tmx_model.get_eodchains("SU", "2018-12-25")
assert not ticker.chains.empty
ticker1 = tmx_model.get_eodchains("SU", "2020-07-01")
assert hasattr(ticker1, "date")
assert ticker1.date != "2020-07-01"
@pytest.mark.vcr
def test_expirations():
ticker = tmx_model.load_options("VFV")
assert hasattr(ticker, "expirations")
results1 = ticker.expirations
assert isinstance(results1, list)
ticker2 = tmx_model.get_eodchains("VFV", "2021-12-28")
results_df2 = ticker2.expirations
assert isinstance(results_df2, list)
assert results1[1] != results_df2[1]
@pytest.mark.vcr
def test_SYMBOLS():
results_df = tmx_model.get_all_ticker_symbols()
assert not results_df.empty
assert "RY" in results_df.index
@pytest.mark.vcr
def test_hasGreeks_hasIV():
ac = tmx_model.load_options("AC")
assert ac.hasGreeks is False
assert ac.hasIV is False
ac2 = tmx_model.get_eodchains("AC", "2022-01-03")
assert ac2.hasIV
assert ac2.hasGreeks is False

View File

@@ -1,6 +1,7 @@
# IMPORTATION STANDARD
# IMPORTATION THIRDPARTY
import pandas as pd
import pytest
import requests
@@ -12,6 +13,10 @@ from openbb_terminal.stocks.options import tradier_model
def vcr_config():
return {
"filter_headers": [("Authorization", "MOCK_TOKEN")],
"filter_query_parameters": [
("before", "MOCK_BEFORE"),
("after", "MOCK_AFTER"),
],
}
@@ -149,3 +154,29 @@ def test_get_historical_greeks_invalid_status(mocker):
result = tradier_model.get_last_price(symbol="AAPL")
assert result is None
@pytest.mark.vcr
def test_load_options(recorder):
results = tradier_model.load_options(symbol="AAPL")
results1 = tradier_model.load_options(symbol="AAPL", pydantic=True)
assert hasattr(results, "chains")
assert hasattr(results1, "chains")
assert isinstance(results.chains, pd.DataFrame)
assert isinstance(results1.chains, dict)
assert isinstance(results.expirations, list)
assert isinstance(results1.expirations, list)
assert isinstance(results.underlying_price, pd.Series)
assert isinstance(results1.underlying_price, dict)
assert (
results.chains["volume"].sum() == pd.DataFrame(results1.chains)["volume"].sum()
)
recorder.capture(
[
results.chains.columns.to_list(),
results.underlying_price.index.to_list(),
results.SYMBOLS.columns.to_list(),
results.underlying_name,
results1.underlying_name,
]
)

View File

@@ -1,4 +1,5 @@
# IMPORTATION STANDARD
import pandas as pd
# IMPORTATION THIRDPARTY
import pytest
@@ -15,6 +16,8 @@ def vcr_config():
("period1", "MOCK_PERIOD_1"),
("period2", "MOCK_PERIOD_2"),
("date", "MOCK_DATE"),
("before", "MOCK_BEFORE"),
("after", "MOCK_AFTER"),
],
}
@@ -83,3 +86,23 @@ def test_call_func(func, mocker, recorder):
result = getattr(yfinance_model, func)(symbol="PM")
recorder.capture(result)
@pytest.mark.vcr
def test_load_options(recorder):
data = yfinance_model.load_options(symbol="OXY")
assert isinstance(data.chains, pd.DataFrame)
assert isinstance(data.last_price, float)
assert isinstance(data.underlying_price, pd.Series)
assert data.hasIV
df1 = data.chains
data2 = yfinance_model.load_options(symbol="OXY", pydantic=True)
assert isinstance(data2.chains, dict)
assert isinstance(data2.underlying_price, dict)
assert data2.hasIV
assert isinstance(data2.expirations, list)
assert isinstance(data2.strikes, list)
df2 = pd.DataFrame(data2.chains)
assert df1.equals(df2)
recorder.capture(data.underlying_price.index.to_list())
recorder.capture(df2.columns.to_list())

View File

@@ -0,0 +1 @@
The symbol, BAD_SYMBOL, was not found in the CBOE directory.

View File

@@ -0,0 +1 @@
1AAPL

View File

@@ -0,0 +1 @@
Occidental Petroleum Corporation Common Stock

View File

@@ -0,0 +1 @@
BAD_SYMBOL was not found in the Nasdaq directory

View File

@@ -0,0 +1 @@
No price data found for the underlying security, BAD_SYMBOL