mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-11-01 23:12:21 +00:00
* include plotly.js in reports html, implement new plotly multi-legends feature * use `ensure_backend` to `check_backend`, improve charts in reports * requirements files * fix files with `CRLF` line endings * Update widget_helpers.py * Update widget_helpers.py * handle unsupported plotly multiple legends version error
1167 lines
32 KiB
Plaintext
Vendored
1167 lines
32 KiB
Plaintext
Vendored
{
|
|
"cells": [
|
|
{
|
|
"attachments": {},
|
|
"cell_type": "markdown",
|
|
"id": "70ba2c8a",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Notebook setup"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "driven-billion",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"import os\n",
|
|
"import io\n",
|
|
"import warnings\n",
|
|
"import datetime\n",
|
|
"import numpy as np\n",
|
|
"import base64\n",
|
|
"import pandas as pd\n",
|
|
"from typing import List\n",
|
|
"\n",
|
|
"from IPython.display import HTML\n",
|
|
"\n",
|
|
"import openbb_terminal.config_terminal as cfg\n",
|
|
"from openbb_terminal.helper_classes import TerminalStyle\n",
|
|
"from openbb_terminal import OpenBBFigure, theme\n",
|
|
"\n",
|
|
"\n",
|
|
"warnings.filterwarnings(\"ignore\")\n",
|
|
"\n",
|
|
"pd.set_option(\"display.float_format\", lambda x: \"%.5f\" % x)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "24ed42f0",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Suppressing sdk logs\n",
|
|
"from openbb_terminal.core.session.current_system import set_system_variable\n",
|
|
"\n",
|
|
"set_system_variable(\"LOGGING_SUPPRESS\", True)\n",
|
|
"\n",
|
|
"# Import the OpenBB SDK\n",
|
|
"from openbb_terminal.sdk import openbb, widgets"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "c3fe7db5-ec6a-42cf-9e66-52dc1de22370",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"from openbb_terminal.core.session.current_user import get_current_user\n",
|
|
"\n",
|
|
"user = get_current_user()\n",
|
|
"\n",
|
|
"cfg.theme = TerminalStyle(\n",
|
|
" user.preferences.MPL_STYLE,\n",
|
|
" user.preferences.PMF_STYLE,\n",
|
|
" user.preferences.RICH_STYLE,\n",
|
|
")\n",
|
|
"theme.apply_style(\"light\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "c52f83e1",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"stylesheet = widgets.html_report_stylesheet()"
|
|
]
|
|
},
|
|
{
|
|
"attachments": {},
|
|
"cell_type": "markdown",
|
|
"id": "807fda4e",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Select Ticker"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "intended-sherman",
|
|
"metadata": {
|
|
"tags": [
|
|
"parameters"
|
|
]
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Parameters that will be replaced when calling this notebook\n",
|
|
"# Do not leave parameters blank as notebook will not run otherwise\n",
|
|
"symbol = \"BTC\"\n",
|
|
"report_name = f\"Crypto Report for {symbol}\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "2c46efb8",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"ticker = symbol"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "d4897334",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"author = \"\"\n",
|
|
"report_title = f\"INVESTMENT RESEARCH REPORT ON {ticker.upper()}\"\n",
|
|
"report_date = datetime.datetime.now().strftime(\"%d %B, %Y\")\n",
|
|
"report_time = datetime.datetime.now().strftime(\"%H:%M\")\n",
|
|
"report_timezone = datetime.datetime.now(datetime.timezone.utc).astimezone().tzinfo\n",
|
|
"report_title, report_date, report_time, report_timezone"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "35d9a943",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# basic info\n",
|
|
"\n",
|
|
"basic_info = openbb.crypto.dd.basic(ticker)\n",
|
|
"if not basic_info.empty:\n",
|
|
" basic_info[\"Metric\"] = basic_info[\"Metric\"].str.title()\n",
|
|
" basic_info[\"Metric\"] = basic_info[\"Metric\"].str.replace(\"_\", \" \")\n",
|
|
" basic_info = basic_info.set_index(\"Metric\")\n",
|
|
" basic_info"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "091d305e",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"news = openbb.crypto.dd.news(symbol=ticker).head(10)\n",
|
|
"\n",
|
|
"if (isinstance(news, pd.DataFrame) and not news.empty) or (\n",
|
|
" not isinstance(news, pd.DataFrame) and news\n",
|
|
"):\n",
|
|
" news = news.set_index(\"published_at\")\n",
|
|
" news.sort_index()\n",
|
|
" news[\"link\"] = news[\"link\"].apply(lambda x: f'<a href=\"{x}\">{x}</a>')\n",
|
|
" news\n",
|
|
"else:\n",
|
|
" news = pd.DataFrame()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "bd281ab8",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"links = openbb.crypto.dd.links(ticker)\n",
|
|
"\n",
|
|
"if (isinstance(links, pd.DataFrame) and not links.empty) or (\n",
|
|
" not isinstance(links, pd.DataFrame) and links\n",
|
|
"):\n",
|
|
" links[\"Link\"] = links[\"Link\"].apply(lambda x: f'<a href=\"{x}\">{x}</a>')\n",
|
|
" links\n",
|
|
"else:\n",
|
|
" links = pd.DataFrame()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "07d09ce8",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"five_year = datetime.datetime.now() - datetime.timedelta(days=1825)\n",
|
|
"three_year = datetime.datetime.now() - datetime.timedelta(days=1095)\n",
|
|
"one_year = datetime.datetime.now() - datetime.timedelta(days=365)\n",
|
|
"three_months = datetime.datetime.now() - datetime.timedelta(days=90)\n",
|
|
"\n",
|
|
"dates = {\n",
|
|
" \"three_months\": three_months,\n",
|
|
" \"one_year\": one_year,\n",
|
|
" \"three_year\": three_year,\n",
|
|
" \"five_year\": five_year,\n",
|
|
"}"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "e6d6d43d",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"from tkinter.filedialog import Open\n",
|
|
"\n",
|
|
"\n",
|
|
"def get_historical_data(ticker, dict_of_dates, is_plot=True) -> List[pd.DataFrame]:\n",
|
|
" list_of_historical_data = []\n",
|
|
"\n",
|
|
" for date in dict_of_dates:\n",
|
|
" data = openbb.crypto.load(\n",
|
|
" symbol=ticker,\n",
|
|
" to_symbol=\"usd\",\n",
|
|
" start_date=dict_of_dates[date],\n",
|
|
" source=\"YahooFinance\",\n",
|
|
" )\n",
|
|
"\n",
|
|
" if data.empty:\n",
|
|
" continue\n",
|
|
"\n",
|
|
" # we'll be using the adjusted close price as same as close price\n",
|
|
" data[\"Adj Close\"] = data[\"Close\"]\n",
|
|
"\n",
|
|
" if is_plot:\n",
|
|
" fig = OpenBBFigure(yaxis_title=\"USDT\").set_title(\n",
|
|
" f\"{date} historical data for {ticker.upper()}\"\n",
|
|
" )\n",
|
|
" fig.add_scatter(x=data.index, y=data[\"Adj Close\"], name=\"Close\")\n",
|
|
"\n",
|
|
" plot_data = fig.to_html()\n",
|
|
"\n",
|
|
" list_of_historical_data.append(plot_data)\n",
|
|
" else:\n",
|
|
" list_of_historical_data.append(data)\n",
|
|
"\n",
|
|
" return list_of_historical_data"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "ed19a708",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"try:\n",
|
|
" historical_data = get_historical_data(ticker, dates)\n",
|
|
"except Exception as e:\n",
|
|
" raise KeyboardInterrupt"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "8f815dbc",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"historical_data_one_year = get_historical_data(ticker, {\"one_year\": one_year}, False)[0]\n",
|
|
"historical_data_one_year"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "081a4bb3",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"from openbb_terminal.cryptocurrency.cryptocurrency_helpers import show_quick_performance\n",
|
|
"\n",
|
|
"show_quick_performance(\n",
|
|
" crypto_df=historical_data_one_year,\n",
|
|
" symbol=ticker,\n",
|
|
" current_currency=\"USDT\",\n",
|
|
" source=\"YahooFinance\",\n",
|
|
" exchange=\"binance\",\n",
|
|
" interval=\"1440\",\n",
|
|
")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "88af0fbe",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"headlines = openbb.crypto.dd.headlines_chart(ticker, external_axes=True)\n",
|
|
"\n",
|
|
"if headlines:\n",
|
|
" headlines = headlines.to_html()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "e4509c6e",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"candle_one_year = openbb.crypto.chart(\n",
|
|
" historical_data_one_year,\n",
|
|
" to_symbol=ticker,\n",
|
|
" from_symbol=\"USDT\",\n",
|
|
" source=\"YahooFinance\",\n",
|
|
" exchange=\"binance\",\n",
|
|
" interval=\"1440\",\n",
|
|
" external_axes=True,\n",
|
|
")\n",
|
|
"\n",
|
|
"if candle_one_year:\n",
|
|
" candle_one_year = candle_one_year.to_html()"
|
|
]
|
|
},
|
|
{
|
|
"attachments": {},
|
|
"cell_type": "markdown",
|
|
"id": "7f83daae",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Due Diligence"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "93d66cf1",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# market cap dominance\n",
|
|
"mcapdom_df = openbb.crypto.dd.mcapdom(symbol=ticker)\n",
|
|
"\n",
|
|
"if (isinstance(mcapdom_df, pd.DataFrame) and not mcapdom_df.empty) or (\n",
|
|
" not isinstance(mcapdom_df, pd.DataFrame) and mcapdom_df\n",
|
|
"):\n",
|
|
" mcapdom = openbb.crypto.dd.mcapdom_chart(symbol=ticker, external_axes=True)\n",
|
|
"\n",
|
|
" if mcapdom:\n",
|
|
" mcapdom = mcapdom.to_html()\n",
|
|
"else:\n",
|
|
" mcapdom_df = pd.DataFrame()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "284b0586",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# roadmap\n",
|
|
"roadmap_model = openbb.crypto.dd.rm(symbol=ticker)\n",
|
|
"\n",
|
|
"if (isinstance(roadmap_model, pd.DataFrame) and not roadmap_model.empty) or (\n",
|
|
" not isinstance(roadmap_model, pd.DataFrame) and roadmap_model\n",
|
|
"):\n",
|
|
" roadmap_model = roadmap_model.set_index(\"Date\")\n",
|
|
" roadmap_model.sort_index()\n",
|
|
"\n",
|
|
" roadmap_view = openbb.crypto.dd.rm_chart(symbol=ticker, external_axes=True)\n",
|
|
" if roadmap_view:\n",
|
|
" roadmap_view = roadmap_view.to_html()\n",
|
|
"\n",
|
|
"else:\n",
|
|
" roadmap_model = pd.DataFrame()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "9ddbc654",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"tokenomics_model = openbb.crypto.dd.rm(symbol=ticker)\n",
|
|
"\n",
|
|
"if (isinstance(tokenomics_model, pd.DataFrame) and not tokenomics_model.empty) or (\n",
|
|
" not isinstance(tokenomics_model, pd.DataFrame) and tokenomics_model\n",
|
|
"):\n",
|
|
" tokenomics_model = tokenomics_model.set_index(\"Date\")\n",
|
|
" tokenomics_model.sort_index()\n",
|
|
"\n",
|
|
" tokenomics_view = openbb.crypto.dd.tk_chart(symbol=ticker, external_axes=True)\n",
|
|
" if tokenomics_view:\n",
|
|
" tokenomics_view = tokenomics_view.to_html()\n",
|
|
"\n",
|
|
"else:\n",
|
|
" tokenomics_model = pd.DataFrame()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "7d02fcc4",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# fundraise\n",
|
|
"fundraise = openbb.crypto.dd.fr(symbol=ticker) # this returns a tuple\n",
|
|
"\n",
|
|
"if fundraise:\n",
|
|
" fundraise_info = fundraise[0]\n",
|
|
" fundraise_df = fundraise[1]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "5e625a2e",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"trading_pair_info = openbb.crypto.dd.trading_pair_info(f\"{ticker}-USDT\")\n",
|
|
"if (isinstance(trading_pair_info, pd.DataFrame) and not trading_pair_info.empty) or (\n",
|
|
" not isinstance(trading_pair_info, pd.DataFrame) and trading_pair_info\n",
|
|
"):\n",
|
|
" trading_pair_info[\"Metric\"] = trading_pair_info[\"Metric\"].str.title()\n",
|
|
" trading_pair_info[\"Metric\"] = trading_pair_info[\"Metric\"].str.replace(\"_\", \" \")\n",
|
|
" trading_pair_info = trading_pair_info.set_index(\"Metric\")\n",
|
|
" trading_pair_info\n",
|
|
"else:\n",
|
|
" trading_pair_info = pd.DataFrame()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "8f33b4d8",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"import openbb_terminal.cryptocurrency.due_diligence.pycoingecko_model as gecko\n",
|
|
"from openbb_terminal.cryptocurrency.cryptocurrency_helpers import get_coingecko_id\n",
|
|
"\n",
|
|
"ath = pd.DataFrame()\n",
|
|
"try:\n",
|
|
" cg_id = get_coingecko_id(symbol=ticker)\n",
|
|
" coin = gecko.Coin(ticker)\n",
|
|
" ath = coin.get_all_time_high(currency=cg_id)\n",
|
|
"\n",
|
|
"except Exception as e:\n",
|
|
" print(\"Reached coingecko API limit\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "2a82e990",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"import openbb_terminal.cryptocurrency.due_diligence.pycoingecko_model as gecko\n",
|
|
"from openbb_terminal.cryptocurrency.cryptocurrency_helpers import get_coingecko_id\n",
|
|
"\n",
|
|
"atl = pd.DataFrame()\n",
|
|
"try:\n",
|
|
" cg_id = get_coingecko_id(symbol=ticker)\n",
|
|
" coin = gecko.Coin(ticker)\n",
|
|
" atl = coin.get_all_time_low(currency=cg_id)\n",
|
|
"\n",
|
|
"except Exception as e:\n",
|
|
" print(\"Reached coingecko API limit\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "e9e512e9",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# market stats about loaded coin\n",
|
|
"\n",
|
|
"market = openbb.crypto.dd.mkt(ticker)\n",
|
|
"\n",
|
|
"if (isinstance(market, pd.DataFrame) and not market.empty) or (\n",
|
|
" not isinstance(market, pd.DataFrame) and market\n",
|
|
"):\n",
|
|
" market = market.set_index(\"exchange\")\n",
|
|
"\n",
|
|
" market[\"market_url\"] = market[\"market_url\"].apply(\n",
|
|
" lambda x: f'<a href=\"{x}\">{x}</a>'\n",
|
|
" )\n",
|
|
" market\n",
|
|
"else:\n",
|
|
" market = pd.DataFrame()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "1d6e76cb",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# all exchanges where loaded coin is listed\n",
|
|
"ex = openbb.crypto.dd.ex(ticker)\n",
|
|
"\n",
|
|
"if (isinstance(ex, pd.DataFrame) and not ex.empty) or (\n",
|
|
" not isinstance(ex, pd.DataFrame) and ex\n",
|
|
"):\n",
|
|
" ex = ex.set_index(\"id\")\n",
|
|
" ex\n",
|
|
"else:\n",
|
|
" ex = pd.DataFrame()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "1fcdbc67",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# last trades\n",
|
|
"trades = openbb.crypto.dd.trades(symbol=ticker, exchange_id=\"gemini\", to_symbol=\"USD\")\n",
|
|
"if (isinstance(trades, pd.DataFrame) and not trades.empty) or (\n",
|
|
" not isinstance(trades, pd.DataFrame) and trades\n",
|
|
"):\n",
|
|
" trades = trades.set_index(\"Date\")\n",
|
|
" trades\n",
|
|
"else:\n",
|
|
" trades = pd.DataFrame()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "262d190a",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# order book\n",
|
|
"order_book_raw = openbb.crypto.dd.ob(\n",
|
|
" symbol=ticker, exchange=\"gemini\", to_symbol=\"USD\"\n",
|
|
") # this returns a dict\n",
|
|
"\n",
|
|
"if order_book_raw:\n",
|
|
" order_book = openbb.crypto.dd.ob_chart(\n",
|
|
" symbol=ticker, exchange=\"gemini\", to_symbol=\"USD\", external_axes=True\n",
|
|
" )\n",
|
|
" if order_book:\n",
|
|
" order_book = order_book.to_html()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "679d0d79",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# price and supply related metrics for loaded coin\n",
|
|
"\n",
|
|
"ps = openbb.crypto.dd.ps(ticker)\n",
|
|
"if (isinstance(ps, pd.DataFrame) and not ps.empty) or (\n",
|
|
" not isinstance(ps, pd.DataFrame) and ps\n",
|
|
"):\n",
|
|
" ps = ps.set_index(\"Metric\")\n",
|
|
" ps\n",
|
|
"else:\n",
|
|
" ps = pd.DataFrame()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "92e76d79",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# events\n",
|
|
"\n",
|
|
"events = openbb.crypto.dd.events(ticker)\n",
|
|
"\n",
|
|
"if (isinstance(events, pd.DataFrame) and not events.empty) or (\n",
|
|
" not isinstance(events, pd.DataFrame) and events\n",
|
|
"):\n",
|
|
" events = events.set_index(\"date\")\n",
|
|
" events[\"link\"] = events[\"link\"].apply(lambda x: f'<a href=\"{x}\">{x}</a>')\n",
|
|
"else:\n",
|
|
" events = pd.DataFrame()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "a14130db",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# social media\n",
|
|
"\n",
|
|
"from openbb_terminal.cryptocurrency.due_diligence.pycoingecko_view import display_social\n",
|
|
"\n",
|
|
"display_social(ticker)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "8f89627f",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# tweets for loaded coin\n",
|
|
"\n",
|
|
"tweets = openbb.crypto.dd.twitter(ticker)\n",
|
|
"tweets"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "9bb75443",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# github activity over time\n",
|
|
"\n",
|
|
"gh_data = openbb.crypto.dd.gh(symbol=ticker)\n",
|
|
"\n",
|
|
"if (isinstance(gh_data, pd.DataFrame) and not gh_data.empty) or (\n",
|
|
" not isinstance(gh_data, pd.DataFrame) and gh_data\n",
|
|
"):\n",
|
|
" gh = openbb.crypto.dd.gh_chart(symbol=ticker, external_axes=True)\n",
|
|
" if gh:\n",
|
|
" gh = gh.to_html()\n",
|
|
"else:\n",
|
|
" gh_data = pd.DataFrame()"
|
|
]
|
|
},
|
|
{
|
|
"attachments": {},
|
|
"cell_type": "markdown",
|
|
"id": "fcaa973d",
|
|
"metadata": {},
|
|
"source": [
|
|
"## TA\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "477317b4",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"ticker_data = historical_data_one_year.copy()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "7af3695c",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# simple moving average\n",
|
|
"ticker_data.index.names = [\"date\"]\n",
|
|
"\n",
|
|
"sma = openbb.ta.ma_chart(\n",
|
|
" data=ticker_data,\n",
|
|
" ma_type=\"SMA\",\n",
|
|
" symbol=ticker,\n",
|
|
" external_axes=True,\n",
|
|
")\n",
|
|
"\n",
|
|
"if sma:\n",
|
|
" sma = sma.to_html()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "5d5089fa",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# exponential moving average\n",
|
|
"ema = openbb.ta.ma_chart(\n",
|
|
" data=ticker_data,\n",
|
|
" ma_type=\"EMA\",\n",
|
|
" symbol=ticker,\n",
|
|
" external_axes=True,\n",
|
|
")\n",
|
|
"\n",
|
|
"if ema:\n",
|
|
" ema = ema.to_html()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "5facfbf4",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# zero lag exponential moving average\n",
|
|
"\n",
|
|
"zlma = openbb.ta.ma_chart(\n",
|
|
" data=ticker_data,\n",
|
|
" ma_type=\"ZLMA\",\n",
|
|
" symbol=ticker,\n",
|
|
" external_axes=True,\n",
|
|
")\n",
|
|
"\n",
|
|
"if zlma:\n",
|
|
" zlma = zlma.to_html()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "df54f7ad",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# commodity channel index\n",
|
|
"\n",
|
|
"cci = openbb.ta.cci_chart(\n",
|
|
" data=ticker_data,\n",
|
|
" symbol=ticker,\n",
|
|
" external_axes=True,\n",
|
|
")\n",
|
|
"\n",
|
|
"if cci:\n",
|
|
" cci = cci.to_html()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "f53469eb",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# moving average convergence/divergence\n",
|
|
"\n",
|
|
"macd = openbb.ta.macd_chart(\n",
|
|
" data=ticker_data,\n",
|
|
" symbol=ticker,\n",
|
|
" external_axes=True,\n",
|
|
")\n",
|
|
"\n",
|
|
"if macd:\n",
|
|
" macd = macd.to_html()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "dd79e6b6",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# fisher transform\n",
|
|
"\n",
|
|
"fisher = openbb.ta.fisher_chart(\n",
|
|
" data=ticker_data,\n",
|
|
" symbol=ticker,\n",
|
|
" external_axes=True,\n",
|
|
")\n",
|
|
"\n",
|
|
"if fisher:\n",
|
|
" fisher = fisher.to_html()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "b699e61f",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# aroon indicator\n",
|
|
"\n",
|
|
"aroon = openbb.ta.aroon_chart(\n",
|
|
" data=ticker_data,\n",
|
|
" symbol=ticker,\n",
|
|
" external_axes=True,\n",
|
|
")\n",
|
|
"\n",
|
|
"if aroon:\n",
|
|
" aroon = aroon.to_html()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "79401027",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# bollinger bands\n",
|
|
"\n",
|
|
"bbands = openbb.ta.bbands_chart(\n",
|
|
" data=ticker_data,\n",
|
|
" symbol=ticker,\n",
|
|
" external_axes=True,\n",
|
|
")\n",
|
|
"\n",
|
|
"if bbands:\n",
|
|
" bbands = bbands.to_html()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "0b5e2949",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# fibonacci retracement\n",
|
|
"\n",
|
|
"fib = openbb.ta.fib_chart(\n",
|
|
" data=ticker_data,\n",
|
|
" symbol=ticker,\n",
|
|
" external_axes=True,\n",
|
|
")\n",
|
|
"\n",
|
|
"if fib:\n",
|
|
" fib = fib.to_html()"
|
|
]
|
|
},
|
|
{
|
|
"attachments": {},
|
|
"cell_type": "markdown",
|
|
"id": "48847a7f",
|
|
"metadata": {},
|
|
"source": [
|
|
"## QA"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "e77b373b",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# summary\n",
|
|
"\n",
|
|
"summary = openbb.qa.summary(data=ticker_data)\n",
|
|
"summary"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "3ecfc93e",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# normality statistics and tests\n",
|
|
"\n",
|
|
"# openbb.qa.normality_chart(\n",
|
|
"# data=ticker_data,\n",
|
|
"# target=\"Close\",\n",
|
|
"# )\n",
|
|
"\n",
|
|
"normality = openbb.qa.normality(\n",
|
|
" data=ticker_data[\"Close\"],\n",
|
|
")\n",
|
|
"normality"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "8abe96b0",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# box and whisker plot\n",
|
|
"\n",
|
|
"bw = openbb.qa.bw(\n",
|
|
" symbol=ticker,\n",
|
|
" data=ticker_data,\n",
|
|
" target=\"Close\",\n",
|
|
" yearly=False,\n",
|
|
" external_axes=True,\n",
|
|
")\n",
|
|
"\n",
|
|
"if bw:\n",
|
|
" bw = bw.to_html()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "66a7dccc",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# rolling mean and std deviation of prices\n",
|
|
"\n",
|
|
"rolling = openbb.qa.rolling_chart(\n",
|
|
" symbol=ticker,\n",
|
|
" data=ticker_data,\n",
|
|
" target=\"Close\",\n",
|
|
" external_axes=True,\n",
|
|
")\n",
|
|
"\n",
|
|
"if rolling:\n",
|
|
" rolling.update_layout(\n",
|
|
" legend=dict(\n",
|
|
" x=0.01,\n",
|
|
" y=0.99,\n",
|
|
" xanchor=\"left\",\n",
|
|
" yanchor=\"top\",\n",
|
|
" xref=\"paper\",\n",
|
|
" yref=\"paper\",\n",
|
|
" bgcolor=\"rgba(0, 0, 0, 0)\",\n",
|
|
" ),\n",
|
|
" legend2=dict(bgcolor=\"rgba(0, 0, 0, 0)\"),\n",
|
|
" )\n",
|
|
" rolling = rolling.to_html()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "d6b43dd7",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# rolling kurtosis of distribution of prices\n",
|
|
"\n",
|
|
"kurtosis = openbb.qa.kurtosis_chart(\n",
|
|
" symbol=ticker,\n",
|
|
" data=ticker_data,\n",
|
|
" target=\"Close\",\n",
|
|
" external_axes=True,\n",
|
|
")\n",
|
|
"\n",
|
|
"if kurtosis:\n",
|
|
" kurtosis = kurtosis.to_html()"
|
|
]
|
|
},
|
|
{
|
|
"attachments": {},
|
|
"cell_type": "markdown",
|
|
"id": "ac501a32-124d-4d21-aae1-a8d147bb1071",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Render the report template to a file"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "abfe37e4-ea38-42c3-8fb5-7cceb233fb12",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"body = \"\"\n",
|
|
"\n",
|
|
"\n",
|
|
"body += widgets.header(\n",
|
|
" author,\n",
|
|
" report_date,\n",
|
|
" report_time,\n",
|
|
" report_timezone,\n",
|
|
" f\"<b>INVESTMENT RESEARCH REPORT:</b> {ticker}\",\n",
|
|
" plotly_js=True,\n",
|
|
")\n",
|
|
"\n",
|
|
"body += widgets.tablinks(\n",
|
|
" [\n",
|
|
" \"SUMMARY\",\n",
|
|
" \"Due Diligence\",\n",
|
|
" \"Technical Analysis\",\n",
|
|
" \"Quantitative Analysis\",\n",
|
|
" ]\n",
|
|
")\n",
|
|
"\n",
|
|
"comment = \"\"\n",
|
|
"\n",
|
|
"# Summary tab\n",
|
|
"htmlcode = \"\"\n",
|
|
"htmlcode += widgets.row(\n",
|
|
" [widgets.h(3, \"Basic information about loaded coin\") + basic_info.to_html()]\n",
|
|
")\n",
|
|
"if not links.empty:\n",
|
|
" htmlcode += widgets.row([widgets.h(3, \"Links\") + links.to_html(escape=False)])\n",
|
|
"\n",
|
|
"if not news.empty:\n",
|
|
" htmlcode += widgets.row(\n",
|
|
" [widgets.h(3, \"Published news\") + news.to_html(escape=False)]\n",
|
|
" )\n",
|
|
"\n",
|
|
"htmlcode += widgets.row([widgets.h(3, \"Historical data\")])\n",
|
|
"for data in historical_data:\n",
|
|
" htmlcode += widgets.row([data])\n",
|
|
"\n",
|
|
"htmlcode += widgets.row([widgets.h(3, \"1-year historical data candlestick chart\")])\n",
|
|
"htmlcode += widgets.row([candle_one_year])\n",
|
|
"htmlcode += widgets.row([widgets.h(3, \"Sentiment analysis\")])\n",
|
|
"htmlcode += widgets.row([headlines])\n",
|
|
"# TODO: print rich table\n",
|
|
"# htmlcode += widgets.row([widgets.h(3, \"Quick performance\")])\n",
|
|
"# htmlcode += widgets.row([quick_performance])\n",
|
|
"body += widgets.add_tab(\"SUMMARY\", htmlcode)\n",
|
|
"\n",
|
|
"# # Due diligence tab\n",
|
|
"htmlcode = \"\"\n",
|
|
"if not trading_pair_info.empty:\n",
|
|
" htmlcode += widgets.row(\n",
|
|
" [widgets.h(3, f\"Trading pair info {ticker}/USDT\") + trading_pair_info.to_html()]\n",
|
|
" )\n",
|
|
"if not mcapdom_df.empty:\n",
|
|
" htmlcode += widgets.row([widgets.h(3, \"Market cap dominance\")])\n",
|
|
" htmlcode += widgets.row([mcapdom])\n",
|
|
"\n",
|
|
"if not roadmap_model.empty:\n",
|
|
" htmlcode += widgets.row([widgets.h(3, \"Roadmap\") + roadmap_model.to_html()])\n",
|
|
" htmlcode += widgets.row([roadmap_view])\n",
|
|
"\n",
|
|
"if not tokenomics_model.empty:\n",
|
|
" htmlcode += widgets.row([widgets.h(3, \"Tokenomics\") + tokenomics_model.to_html()])\n",
|
|
" htmlcode += widgets.row([tokenomics_view])\n",
|
|
"\n",
|
|
"if fundraise:\n",
|
|
" htmlcode += widgets.row([widgets.h(3, \"Fundraising Details\")])\n",
|
|
" htmlcode += widgets.row([widgets.p(fundraise_info)])\n",
|
|
" htmlcode += widgets.row([fundraise_df.to_html()])\n",
|
|
"\n",
|
|
"if not ath.empty:\n",
|
|
" htmlcode += widgets.row([widgets.h(3, \"All time high\")])\n",
|
|
" htmlcode += widgets.row([ath.to_html()])\n",
|
|
"\n",
|
|
"if not atl.empty:\n",
|
|
" htmlcode += widgets.row([widgets.h(3, \"All time low\")])\n",
|
|
" htmlcode += widgets.row([atl.to_html()])\n",
|
|
"\n",
|
|
"if not market.empty:\n",
|
|
" htmlcode += widgets.row([widgets.h(3, \"All markets\")])\n",
|
|
" htmlcode += widgets.row([market.sample(n=20).sort_index().to_html(escape=False)])\n",
|
|
"\n",
|
|
"if not ex.empty:\n",
|
|
" htmlcode += widgets.row([widgets.h(3, \"Exchanges where loaded coin is listed\")])\n",
|
|
" htmlcode += widgets.row([ex.sample(n=20).sort_index().to_html()])\n",
|
|
"\n",
|
|
"if not trades.empty:\n",
|
|
" htmlcode += widgets.row([widgets.h(3, \"Last trades\")])\n",
|
|
" htmlcode += widgets.row([trades.tail(20).to_html()])\n",
|
|
"\n",
|
|
"if order_book_raw:\n",
|
|
" htmlcode += widgets.row([widgets.h(3, \"Order book\")])\n",
|
|
" htmlcode += widgets.row([order_book])\n",
|
|
"\n",
|
|
"if not ps.empty:\n",
|
|
" htmlcode += widgets.row(\n",
|
|
" [widgets.h(3, \"Price and supply related metrics for loaded coin\")]\n",
|
|
" )\n",
|
|
" htmlcode += widgets.row([ps.to_html()])\n",
|
|
"\n",
|
|
"if not events.empty:\n",
|
|
" htmlcode += widgets.row([widgets.h(3, \"Events\")])\n",
|
|
" htmlcode += widgets.row([events.to_html(escape=False)])\n",
|
|
"\n",
|
|
"# TODO: print rich table\n",
|
|
"# htmlcode += widgets.row([widgets.h(3, \"Tweets for loaded coin\")])\n",
|
|
"# htmlcode += widgets.row([tweets])\n",
|
|
"# htmlcode += widgets.row([widgets.h(3, \"Social media\")])\n",
|
|
"# htmlcode += widgets.row([social.to_html()])\n",
|
|
"\n",
|
|
"if not gh_data.empty:\n",
|
|
" htmlcode += widgets.row([widgets.h(3, \"Github activity over time\")])\n",
|
|
" htmlcode += widgets.row([gh])\n",
|
|
"else:\n",
|
|
" htmlcode += widgets.row([widgets.h(3, \"Github activity over time\")])\n",
|
|
" htmlcode += widgets.row([widgets.p(\"No data available.\")])\n",
|
|
"\n",
|
|
"body += widgets.add_tab(\"Due Diligence\", htmlcode)\n",
|
|
"\n",
|
|
"# Technical Analysis tab\n",
|
|
"htmlcode = \"\"\n",
|
|
"htmlcode = widgets.row([widgets.h(3, \"Simple moving average\")])\n",
|
|
"htmlcode += widgets.row([sma])\n",
|
|
"htmlcode += widgets.row([widgets.h(3, \"Exponential moving average\")])\n",
|
|
"htmlcode += widgets.row([ema])\n",
|
|
"htmlcode += widgets.row([widgets.h(3, \"Zero lag exponential moving average\")])\n",
|
|
"htmlcode += widgets.row([zlma])\n",
|
|
"htmlcode += widgets.row([widgets.h(3, \"Commodity channel index\")])\n",
|
|
"htmlcode += widgets.row([cci])\n",
|
|
"htmlcode += widgets.row([widgets.h(3, \"Moving average convergence/divergence\")])\n",
|
|
"htmlcode += widgets.row([macd])\n",
|
|
"htmlcode += widgets.row([widgets.h(3, \"Fisher transform\")])\n",
|
|
"htmlcode += widgets.row([fisher])\n",
|
|
"htmlcode += widgets.row([widgets.h(3, \"Aroon indicator\")])\n",
|
|
"htmlcode += widgets.row([aroon])\n",
|
|
"htmlcode += widgets.row([widgets.h(3, \"Bollinger bands\")])\n",
|
|
"htmlcode += widgets.row([bbands])\n",
|
|
"htmlcode += widgets.row([widgets.h(3, \"Fibonacci retracement\")])\n",
|
|
"htmlcode += widgets.row([fib])\n",
|
|
"body += widgets.add_tab(\"Technical Analysis\", htmlcode)\n",
|
|
"\n",
|
|
"# Quantitative Analysis tab\n",
|
|
"htmlcode = \"\"\n",
|
|
"htmlcode = widgets.row([widgets.h(3, \"Summary\") + summary.to_html()])\n",
|
|
"htmlcode += widgets.row(\n",
|
|
" [widgets.h(3, \"Normality statistics and tests\") + normality.to_html()]\n",
|
|
")\n",
|
|
"htmlcode += widgets.row([widgets.h(3, \"Box and whisker plot\")])\n",
|
|
"htmlcode += widgets.row([bw])\n",
|
|
"htmlcode += widgets.row([widgets.h(3, \"Rolling mean and std deviation of prices\")])\n",
|
|
"htmlcode += widgets.row([rolling])\n",
|
|
"htmlcode += widgets.row([widgets.h(3, \"Rolling kurtosis of distribution of prices\")])\n",
|
|
"htmlcode += widgets.row([kurtosis])\n",
|
|
"body += widgets.add_tab(\"Quantitative Analysis\", htmlcode)\n",
|
|
"\n",
|
|
"body += widgets.tab_clickable_and_save_evt()\n",
|
|
"report = widgets.html_report(title=report_name, stylesheet=stylesheet, body=body)\n",
|
|
"\n",
|
|
"# # to save the results\n",
|
|
"with open(report_name + \".html\", \"w\", encoding=\"utf-8\") as fh:\n",
|
|
" fh.write(report)"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"celltoolbar": "Tags",
|
|
"kernelspec": {
|
|
"display_name": "venv",
|
|
"language": "python",
|
|
"name": "python3"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": {
|
|
"name": "ipython",
|
|
"version": 3
|
|
},
|
|
"file_extension": ".py",
|
|
"mimetype": "text/x-python",
|
|
"name": "python",
|
|
"nbconvert_exporter": "python",
|
|
"pygments_lexer": "ipython3",
|
|
"version": "3.9.6"
|
|
},
|
|
"vscode": {
|
|
"interpreter": {
|
|
"hash": "381a209f752e9104bff95ec5e80679ea2e476866b80e4326f1ee6b7658af6049"
|
|
}
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 5
|
|
}
|