mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-27 12:40:35 +00:00
Add cboe top of book (#2830)
* Add cboe top of book * test + merge 1 print table * unit test + add stocks int test
This commit is contained in:
1
data_sources_default.json
vendored
1
data_sources_default.json
vendored
@@ -2,6 +2,7 @@
|
||||
"stocks": {
|
||||
"search": ["FinanceDatabase"],
|
||||
"quote": ["YahooFinance"],
|
||||
"tob": ["CBOE"],
|
||||
"candle": [],
|
||||
"codes": ["Polygon"],
|
||||
"news": ["Feedparser", "NewsApi"],
|
||||
|
||||
@@ -1889,6 +1889,7 @@ functions = {
|
||||
},
|
||||
"stocks.search": {"model": "openbb_terminal.stocks.stocks_helper.search"},
|
||||
"stocks.quote": {"model": "openbb_terminal.stocks.stocks_helper.quote"},
|
||||
"stocks.tob": {"model": "openbb_terminal.stocks.cboe_model.get_top_of_book"},
|
||||
"stocks.candle": {"model": "openbb_terminal.stocks.stocks_helper.display_candle"},
|
||||
"crypto.load": {
|
||||
"model": "openbb_terminal.cryptocurrency.cryptocurrency_helpers.load"
|
||||
|
||||
1
openbb_terminal/miscellaneous/i18n/en.yml
vendored
1
openbb_terminal/miscellaneous/i18n/en.yml
vendored
@@ -94,6 +94,7 @@ en:
|
||||
stocks/load: load a specific stock ticker and additional info for analysis
|
||||
stocks/_ticker: Stock
|
||||
stocks/quote: view the current price for a specific stock ticker
|
||||
stocks/tob: view top of book for loaded ticker (US exchanges only)
|
||||
stocks/QUOTE: Current quote for stock ticker
|
||||
stocks/QUOTE_ticker: Stock ticker
|
||||
stocks/candle: view a candle chart for a specific stock ticker
|
||||
|
||||
59
openbb_terminal/stocks/cboe_model.py
Normal file
59
openbb_terminal/stocks/cboe_model.py
Normal file
@@ -0,0 +1,59 @@
|
||||
"""CBOE Model Functions"""
|
||||
__docformat__ = "numpy"
|
||||
|
||||
from typing import Tuple
|
||||
|
||||
import pandas as pd
|
||||
import requests
|
||||
|
||||
from openbb_terminal.rich_config import console
|
||||
|
||||
|
||||
def get_top_of_book(
|
||||
symbol: str, exchange: str = "BZX"
|
||||
) -> Tuple[pd.DataFrame, pd.DataFrame]:
|
||||
"""Get top of book bid and ask for ticker on exchange [CBOE.com]
|
||||
|
||||
Parameters
|
||||
----------
|
||||
symbol: str
|
||||
Ticker to get
|
||||
exchange: str
|
||||
Exchange to look at. Can be `BZX`,`EDGX`, `BYX`, `EDGA`
|
||||
|
||||
Returns
|
||||
-------
|
||||
pd.DatatFrame
|
||||
Dataframe of Bids
|
||||
pd.DataFrame
|
||||
Dataframe of asks
|
||||
|
||||
"""
|
||||
if exchange not in ["BZX", "EDGX", "BYX", "EDGA"]:
|
||||
console.print(f"[red]Exchange not valid: {exchange}[/red]")
|
||||
return pd.DataFrame(), pd.DataFrame()
|
||||
# exchange need to be lower case. Not sure why
|
||||
url = f"https://www.cboe.com/json/{exchange.lower()}/book/{symbol}"
|
||||
|
||||
r = requests.get(
|
||||
url,
|
||||
headers={
|
||||
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko)"
|
||||
" Chrome/106.0.0.0 Safari/537.36",
|
||||
"referer": "https://www.cboe.com/us/equities/market_statistics/book_viewer/",
|
||||
},
|
||||
)
|
||||
if r.status_code != 200:
|
||||
console.print(f"[red]Request failed with code {r.status_code}[/red]")
|
||||
return pd.DataFrame(), pd.DataFrame()
|
||||
r_json = r.json()
|
||||
if r_json["data"]["company"] == "unknown symbol":
|
||||
console.print(f"[red]Unknown symbol: {symbol}[/red]")
|
||||
return pd.DataFrame(), pd.DataFrame()
|
||||
bids = pd.DataFrame(r_json["data"]["bids"], columns=["Size", "Price"])
|
||||
asks = pd.DataFrame(r_json["data"]["asks"], columns=["Size", "Price"])
|
||||
if bids.empty or asks.empty:
|
||||
console.print(
|
||||
"[red]No bid/ask data. Note this is real time so there is no data after market close.[/red]"
|
||||
)
|
||||
return bids, asks
|
||||
34
openbb_terminal/stocks/cboe_view.py
Normal file
34
openbb_terminal/stocks/cboe_view.py
Normal file
@@ -0,0 +1,34 @@
|
||||
"""CBOE View"""
|
||||
__docformat__ = "numpy"
|
||||
|
||||
import pandas as pd
|
||||
from openbb_terminal.stocks import cboe_model
|
||||
from openbb_terminal.helper_funcs import print_rich_table
|
||||
from openbb_terminal.rich_config import console
|
||||
|
||||
|
||||
def display_top_of_book(symbol: str, exchange: str = "BZX"):
|
||||
"""Display top of book data [CBOE]
|
||||
|
||||
Parameters
|
||||
----------
|
||||
symbol: str
|
||||
Symbol to get data for
|
||||
exchange: str
|
||||
Exchange to get data for
|
||||
"""
|
||||
bids, asks = cboe_model.get_top_of_book(symbol, exchange)
|
||||
|
||||
if not bids.empty and not asks.empty:
|
||||
asks = asks[["Price", "Size"]]
|
||||
bids.columns = ["Bid " + col for col in bids.columns]
|
||||
asks.columns = ["Ask " + col for col in asks.columns]
|
||||
merged = pd.concat([bids, asks], axis=1)
|
||||
print_rich_table(
|
||||
merged,
|
||||
title=f"{symbol} Top of Book",
|
||||
show_index=False,
|
||||
headers=merged.columns,
|
||||
)
|
||||
|
||||
console.print()
|
||||
@@ -16,6 +16,7 @@ from openbb_terminal import feature_flags as obbff
|
||||
from openbb_terminal.common import feedparser_view, newsapi_view
|
||||
from openbb_terminal.common.quantitative_analysis import qa_view
|
||||
from openbb_terminal.decorators import log_start_end
|
||||
from openbb_terminal.stocks import cboe_view
|
||||
|
||||
from openbb_terminal.helper_funcs import (
|
||||
EXPORT_ONLY_RAW_DATA_ALLOWED,
|
||||
@@ -46,6 +47,7 @@ class StocksController(StockBaseController):
|
||||
"search",
|
||||
"load",
|
||||
"quote",
|
||||
"tob",
|
||||
"candle",
|
||||
"news",
|
||||
"resources",
|
||||
@@ -77,6 +79,7 @@ class StocksController(StockBaseController):
|
||||
country = financedatabase.show_options("equities", "countries")
|
||||
sector = financedatabase.show_options("equities", "sectors")
|
||||
industry = financedatabase.show_options("equities", "industries")
|
||||
TOB_EXCHANGES = ["BZX", "EDGX", "BYX", "EDGA"]
|
||||
|
||||
def __init__(self, queue: List[str] = None):
|
||||
"""Constructor"""
|
||||
@@ -114,6 +117,10 @@ class StocksController(StockBaseController):
|
||||
"--ticker": None,
|
||||
"-t": "--ticker",
|
||||
}
|
||||
choices["tob"] = {
|
||||
"--exchange": {c: {} for c in self.TOB_EXCHANGES},
|
||||
"-e": "--exchange",
|
||||
}
|
||||
choices["search"] = {
|
||||
"--query": None,
|
||||
"-q": "--query",
|
||||
@@ -179,6 +186,7 @@ class StocksController(StockBaseController):
|
||||
mt.add_raw(self.add_info)
|
||||
mt.add_raw("\n")
|
||||
mt.add_cmd("quote", self.ticker)
|
||||
mt.add_cmd("tob", self.ticker)
|
||||
mt.add_cmd("candle", self.ticker)
|
||||
mt.add_cmd("codes", self.ticker)
|
||||
mt.add_cmd("news", self.ticker)
|
||||
@@ -286,6 +294,41 @@ class StocksController(StockBaseController):
|
||||
export=ns_parser.export,
|
||||
)
|
||||
|
||||
@log_start_end(log=logger)
|
||||
def call_tob(self, other_args: List[str]):
|
||||
"""Process quote command"""
|
||||
parser = argparse.ArgumentParser(
|
||||
add_help=False,
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
||||
prog="quote",
|
||||
description="Get top of book for loaded ticker from selected exchange",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-t",
|
||||
"--ticker",
|
||||
action="store",
|
||||
dest="s_ticker",
|
||||
required="-h" not in other_args and not self.ticker,
|
||||
help="Ticker to get data for",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-e",
|
||||
"--exchange",
|
||||
default="BZX",
|
||||
choices=self.TOB_EXCHANGES,
|
||||
type=str,
|
||||
dest="exchange",
|
||||
)
|
||||
|
||||
if not self.ticker:
|
||||
if other_args and "-" not in other_args[0][0]:
|
||||
other_args.insert(0, "-t")
|
||||
ns_parser = self.parse_known_args_and_warn(parser, other_args)
|
||||
|
||||
if ns_parser:
|
||||
ticker = ns_parser.s_ticker if ns_parser.s_ticker else self.ticker
|
||||
cboe_view.display_top_of_book(ticker, ns_parser.exchange)
|
||||
|
||||
@log_start_end(log=logger)
|
||||
def call_quote(self, other_args: List[str]):
|
||||
"""Process quote command"""
|
||||
|
||||
9
scripts/test_stocks.openbb
vendored
Normal file
9
scripts/test_stocks.openbb
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
stocks
|
||||
search apple
|
||||
load aapl -s 2022-10-01
|
||||
tob
|
||||
tob -e EDGX
|
||||
candle
|
||||
codes
|
||||
news
|
||||
exit
|
||||
58
tests/openbb_terminal/stocks/cassettes/test_cboe_model/test_top_of_book.yaml
vendored
Normal file
58
tests/openbb_terminal/stocks/cassettes/test_cboe_model/test_top_of_book.yaml
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
interactions:
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept:
|
||||
- '*/*'
|
||||
Accept-Encoding:
|
||||
- gzip, deflate
|
||||
Connection:
|
||||
- keep-alive
|
||||
User-Agent:
|
||||
- Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML,
|
||||
like Gecko) Chrome/106.0.0.0 Safari/537.36
|
||||
referer:
|
||||
- https://www.cboe.com/us/equities/market_statistics/book_viewer/
|
||||
method: GET
|
||||
uri: https://www.cboe.com/json/bzx/book/AAPL
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
H4sIAAAAAAAAA72TT2uDMBiHv0p5zy4kMf5JbqXsMOjWHnaTMlLNWqlWMbajjH33vbFatPQ22EHI
|
||||
k/fJL6+JfoM9pamxFlTbnIwHjSkqnYEKKKUeZLrVoL7BXsptVYCC+Xy9BA/0KW3z6gjqUxcWV6VV
|
||||
WevjxQnr9fJ59vK2mC1Wr2jWjTmDYoITKV1iVZujY58w5nif7/aOBQlCx0X1hehLEvAOtW1dmRK/
|
||||
ayjd6+POgHriJOzyzlVxKnGCB8KXMccNmsw0dtW8Nzoz1q1lEqOxZ3tATBKX2wWKjZeIAYIxhAg3
|
||||
LRpDvNl4sM2zLunmc1SCARiCHADHfj/m0oHgV+iC2r7HJAHGFI8Uo3hkzD39G7thXyEx5W4GU/7N
|
||||
vkrO96c+DeKpT+XE53Lk0+ttPvIHPZ7qwn+s3/zozuf37URTPxj7EYkl/6MfYlkMdji2QxKLazfu
|
||||
hvPS2FaXNf4a/eG5ndo8PXy0lxo/XICfn1+23IgKhgMAAA==
|
||||
headers:
|
||||
Accept-Ranges:
|
||||
- bytes
|
||||
CF-Cache-Status:
|
||||
- EXPIRED
|
||||
CF-RAY:
|
||||
- 75a156ac88625716-IAD
|
||||
Cache-Control:
|
||||
- no-cache=False, must-revalidate=False, max-age=5
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Encoding:
|
||||
- gzip
|
||||
Content-Length:
|
||||
- '376'
|
||||
Content-Type:
|
||||
- application/json
|
||||
Date:
|
||||
- Fri, 14 Oct 2022 15:27:21 GMT
|
||||
Last-Modified:
|
||||
- Fri, 14 Oct 2022 15:27:18 GMT
|
||||
Link:
|
||||
- <https://(null)(null)>; rel="canonical"
|
||||
Server:
|
||||
- cloudflare
|
||||
Vary:
|
||||
- Host,Accept-Encoding
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
version: 1
|
||||
58
tests/openbb_terminal/stocks/cassettes/test_cboe_view/test_top_of_book.yaml
vendored
Normal file
58
tests/openbb_terminal/stocks/cassettes/test_cboe_view/test_top_of_book.yaml
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
interactions:
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept:
|
||||
- '*/*'
|
||||
Accept-Encoding:
|
||||
- gzip, deflate
|
||||
Connection:
|
||||
- keep-alive
|
||||
User-Agent:
|
||||
- Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML,
|
||||
like Gecko) Chrome/106.0.0.0 Safari/537.36
|
||||
referer:
|
||||
- https://www.cboe.com/us/equities/market_statistics/book_viewer/
|
||||
method: GET
|
||||
uri: https://www.cboe.com/json/bzx/book/AAPL
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
H4sIAAAAAAAAA5WTTWuDQBCG/0qYsxV3dVfdWwg9FNImh94klK1uE4lfuJoSQv57ZzcKJoSCF/GZ
|
||||
eXxnXJML6D5NldYgurZXDrSqqGUGgnme50AmOwniAvpcftcFCFgut2twQPZpl9cViB9ZaHwqrctG
|
||||
VmcjbLfr18Xbx2qx2ryj2bTqBIIE1I1jk1g3qjLsu4QYPuT7g+HAZdxwUf8i+rHLqEWpO9P2XN8u
|
||||
lB5ktVcgXqjLbd6pLvoSC5Rx5tEAB7SZavWm/WxlprQdRSgjuLM+IiaJybWBZOckfASKQDwe3shH
|
||||
CsZWMAW22znwnWc2KhyqNEYlGiFC8EcIJ0MoRxjHU5vUDVsmCRAiaCy8CA8NT8Zch7c2t0PPjZmt
|
||||
YM5zn4b3fsT5E58Fs/SAz9LnbjPx+b3POXvww3/8EM80muWT8HGfuT6/99nU5y73ifXNh85LpTtZ
|
||||
NvgfufUJBVNOj1/ducFfMMD1+gcFcAyvjwMAAA==
|
||||
headers:
|
||||
Accept-Ranges:
|
||||
- bytes
|
||||
CF-Cache-Status:
|
||||
- EXPIRED
|
||||
CF-RAY:
|
||||
- 75a1596f3f605830-IAD
|
||||
Cache-Control:
|
||||
- no-cache=False, must-revalidate=False, max-age=5
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Encoding:
|
||||
- gzip
|
||||
Content-Length:
|
||||
- '370'
|
||||
Content-Type:
|
||||
- application/json
|
||||
Date:
|
||||
- Fri, 14 Oct 2022 15:29:14 GMT
|
||||
Last-Modified:
|
||||
- Fri, 14 Oct 2022 15:29:13 GMT
|
||||
Link:
|
||||
- <https://(null)(null)>; rel="canonical"
|
||||
Server:
|
||||
- cloudflare
|
||||
Vary:
|
||||
- Host,Accept-Encoding
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
version: 1
|
||||
55
tests/openbb_terminal/stocks/cassettes/test_cboe_view/test_top_of_book_bad_ticker.yaml
vendored
Normal file
55
tests/openbb_terminal/stocks/cassettes/test_cboe_view/test_top_of_book_bad_ticker.yaml
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
interactions:
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept:
|
||||
- '*/*'
|
||||
Accept-Encoding:
|
||||
- gzip, deflate
|
||||
Connection:
|
||||
- keep-alive
|
||||
User-Agent:
|
||||
- Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML,
|
||||
like Gecko) Chrome/106.0.0.0 Safari/537.36
|
||||
referer:
|
||||
- https://www.cboe.com/us/equities/market_statistics/book_viewer/
|
||||
method: GET
|
||||
uri: https://www.cboe.com/json/bzx/book/JBEUCEBFY
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
H4sIAAAAAAAAA0yNzQrCMBCEX6XsOWC1txyVevCqHkSkrMmCpU1Sko1aiu9u+oN4m5nd+WYAT61D
|
||||
DTIXoJER5AChN3fXgoTDtjzvyu3+AgK4NhQYTZfy9VoWG1kU2fm4KjEweZs+lDMd2j7do22se9ls
|
||||
AQl4ujYamkac1+TDJDE0SVxvAu61XhTXqqm479IzjKseNS2nh7dolnysVspFyxNp7P/ZufULPgJC
|
||||
VIpCArGPlCwjx3CiN8+42e+cHvGbPP9Fs5UZfL4AAAD//wMAf/v13SoBAAA=
|
||||
headers:
|
||||
CF-Cache-Status:
|
||||
- MISS
|
||||
CF-RAY:
|
||||
- 75a15e4c5aa35e17-IAD
|
||||
Cache-Control:
|
||||
- must-revalidate=False, no-cache=False, max-age=5
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Encoding:
|
||||
- gzip
|
||||
Content-Type:
|
||||
- application/json
|
||||
Date:
|
||||
- Fri, 14 Oct 2022 15:32:33 GMT
|
||||
Last-Modified:
|
||||
- Fri, 14 Oct 2022 15:32:33 GMT
|
||||
Link:
|
||||
- <https://www.cboe.com/json/bzx/book/JBEUCEBFY>; rel="canonical"
|
||||
Server:
|
||||
- cloudflare
|
||||
Transfer-Encoding:
|
||||
- chunked
|
||||
Vary:
|
||||
- Host,Accept-Encoding
|
||||
X-Frame-Options:
|
||||
- SAMEORIGIN
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
version: 1
|
||||
7
tests/openbb_terminal/stocks/test_cboe_model.py
Normal file
7
tests/openbb_terminal/stocks/test_cboe_model.py
Normal file
@@ -0,0 +1,7 @@
|
||||
import pytest
|
||||
from openbb_terminal.stocks import cboe_model
|
||||
|
||||
|
||||
@pytest.mark.vcr
|
||||
def test_top_of_book():
|
||||
cboe_model.get_top_of_book("AAPL")
|
||||
14
tests/openbb_terminal/stocks/test_cboe_view.py
Normal file
14
tests/openbb_terminal/stocks/test_cboe_view.py
Normal file
@@ -0,0 +1,14 @@
|
||||
import pytest
|
||||
from openbb_terminal.stocks import cboe_view
|
||||
|
||||
|
||||
@pytest.mark.vcr
|
||||
@pytest.mark.record_stdout
|
||||
def test_top_of_book():
|
||||
cboe_view.display_top_of_book("AAPL")
|
||||
|
||||
|
||||
@pytest.mark.vcr
|
||||
@pytest.mark.record_stdout
|
||||
def test_top_of_book_bad_ticker():
|
||||
cboe_view.display_top_of_book("JBEUCEBFY")
|
||||
@@ -271,6 +271,13 @@ def test_call_func_expect_queue(expected_queue, func, queue):
|
||||
[],
|
||||
dict(),
|
||||
),
|
||||
(
|
||||
"call_tob",
|
||||
["--ticker=AAPL"],
|
||||
"cboe_view.display_top_of_book",
|
||||
[],
|
||||
dict(),
|
||||
),
|
||||
(
|
||||
"call_candle",
|
||||
[
|
||||
|
||||
7
tests/openbb_terminal/stocks/txt/test_cboe_view/test_top_of_book.txt
vendored
Normal file
7
tests/openbb_terminal/stocks/txt/test_cboe_view/test_top_of_book.txt
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
Bid Size Bid Price Ask Price Ask Size
|
||||
0 700 140.29 140.31 200
|
||||
1 800 140.28 140.32 600
|
||||
2 300 140.27 140.33 1067
|
||||
3 600 140.26 140.34 400
|
||||
4 200 140.25 140.35 400
|
||||
|
||||
2
tests/openbb_terminal/stocks/txt/test_cboe_view/test_top_of_book_bad_ticker.txt
vendored
Normal file
2
tests/openbb_terminal/stocks/txt/test_cboe_view/test_top_of_book_bad_ticker.txt
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
[red]Unknown symbol: JBEUCEBFY[/red]
|
||||
|
||||
@@ -8,6 +8,7 @@ Exchange:
|
||||
Currency:
|
||||
|
||||
[unvl] quote view the current price for a specific stock ticker[/unvl] [YahooFinance]
|
||||
[unvl] tob view top of book for loaded ticker (US exchanges only)[/unvl] [CBOE]
|
||||
[unvl] candle view a candle chart for a specific stock ticker[/unvl]
|
||||
[unvl] codes FIGI, SIK and SIC codes codes[/unvl] [Polygon]
|
||||
[unvl] news latest news of the company[/unvl] [Feedparser, NewsApi]
|
||||
|
||||
12
website/content/terminal/stocks/tob/_index.md
vendored
Normal file
12
website/content/terminal/stocks/tob/_index.md
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
```
|
||||
usage: quote [-t S_TICKER] [-e {BZX,EDGX,BYX,EDGA}] [-h]
|
||||
```
|
||||
Get top of book for loaded ticker from selected exchange
|
||||
```
|
||||
optional arguments:
|
||||
-t S_TICKER, --ticker S_TICKER
|
||||
Ticker to get data for (default: None)
|
||||
-e {BZX,EDGX,BYX,EDGA}, --exchange {BZX,EDGX,BYX,EDGA}
|
||||
-h, --help show this help message (default: False)
|
||||
```
|
||||
For more information and examples, use 'about quote' to access the related guide.
|
||||
2
website/data/menu/main.yml
vendored
2
website/data/menu/main.yml
vendored
@@ -1507,6 +1507,8 @@ main:
|
||||
ref: /terminal/common/qa/unitroot
|
||||
- name: quote
|
||||
ref: /terminal/stocks/quote
|
||||
- name: tob
|
||||
ref: /terminal/stocks/tob
|
||||
- name: research
|
||||
ref: /terminal/stocks/res
|
||||
sub:
|
||||
|
||||
Reference in New Issue
Block a user