Merge branch 'develop' into feature/volume-inchart

This commit is contained in:
teh_coderer
2023-03-16 23:16:50 -04:00
178 changed files with 12917 additions and 4755 deletions

View File

@@ -49,7 +49,7 @@ jobs:
pip install types-pytz types-requests types-termcolor types-tabulate types-PyYAML types-python-dateutil types-setuptools types-six
- run: bandit -x ./tests -r . || true
- run: black --diff --check .
- run: codespell --ignore-words-list=commun,statics,ro,zar,zlot,jewl,ba,buil,coo,ether,hist,hsi,mape,navagation,operatio,pres,ser,yeld,shold,ist,varian,datas,ake,creat,vie,hel,ket,toke,certi,buidl,ot,te,buda,shs,welp --quiet-level=2 --skip=./tests,.git,*.css,*.csv,*.html,*.ini,*.ipynb,*.js,*.json,*.lock,*.scss,*.txt,*.yaml,./build/pyinstaller,./website/config.toml
- run: codespell --ignore-words-list=gard,commun,statics,ro,zar,zlot,jewl,ba,buil,coo,ether,hist,hsi,mape,navagation,operatio,pres,ser,yeld,shold,ist,varian,datas,ake,creat,vie,hel,ket,toke,certi,buidl,ot,te,buda,shs,welp --quiet-level=2 --skip=./tests,.git,*.css,*.csv,*.html,*.ini,*.ipynb,*.js,*.json,*.lock,*.scss,*.txt,*.yaml,./build/pyinstaller,./website/config.toml
- run: ruff .
- run: mypy --ignore-missing-imports openbb_terminal
- run: pylint terminal.py openbb_terminal tests

View File

@@ -24,7 +24,7 @@ repos:
entry: codespell
args:
[
"--ignore-words-list=te,commun,ro,zar,vie,hel,jewl,zlot,ba,buil,coo,ether,hist,hsi,mape,navagation,operatio,pres,ser,yeld,shold,ist,varian,datas,ake,creat,statics,ket,toke,certi,buidl,ot",
"--ignore-words-list=gard,te,commun,ro,zar,vie,hel,jewl,zlot,ba,buil,coo,ether,hist,hsi,mape,navagation,operatio,pres,ser,yeld,shold,ist,varian,datas,ake,creat,statics,ket,toke,certi,buidl,ot",
"--quiet-level=2",
"--skip=./tests,.git,*.css,*.csv,*.html,*.ini,*.ipynb,*.js,*.json,*.lock,*.scss,*.txt,*.yaml,build/pyinstaller/*,./website/config.toml",
]

View File

@@ -5,17 +5,20 @@ import os
from pathlib import Path
from typing import Dict, List, Optional
from openbb_terminal import (
keys_model,
from openbb_terminal.account.account_model import (
get_diff,
get_routines_info,
)
from openbb_terminal.account.account_model import get_diff, get_routines_info
from openbb_terminal.account.account_view import display_routines_list
from openbb_terminal.core.session import (
hub_model as Hub,
local_model as Local,
)
from openbb_terminal.core.session.current_user import get_current_user, is_local
from openbb_terminal.core.session.preferences_handler import set_preference
from openbb_terminal.core.session.current_user import (
get_current_user,
is_local,
set_preference,
)
from openbb_terminal.core.session.session_model import logout
from openbb_terminal.custom_prompt_toolkit import NestedCompleter
from openbb_terminal.decorators import log_start_end
@@ -156,16 +159,23 @@ class AccountController(BaseController):
ns_parser = self.parse_known_args_and_warn(parser, other_args)
if ns_parser:
current_user = get_current_user()
if ns_parser.sync is None:
sync = "ON" if current_user.preferences.SYNC_ENABLED is True else "OFF"
sync = (
"ON"
if get_current_user().preferences.SYNC_ENABLED is True
else "OFF"
)
console.print(f"sync is {sync}, use --on or --off to change.")
else:
set_preference(
name="SYNC_ENABLED",
value=ns_parser.sync,
)
sync = "ON" if current_user.preferences.SYNC_ENABLED is True else "OFF"
sync = (
"ON"
if get_current_user().preferences.SYNC_ENABLED is True
else "OFF"
)
console.print(f"[info]sync:[/info] {sync}")
@log_start_end(log=logger)
@@ -489,17 +499,6 @@ class AccountController(BaseController):
if token:
console.print(f"\n[info]Token:[/info] {token}\n")
save_to_keys = False
if not ns_parser.save:
save_to_keys = console.input(
"Would you like to save the token to the keys? (y/n): "
).lower() in ["y", "yes"]
if save_to_keys or ns_parser.save:
keys_model.set_openbb_personal_access_token(
key=token, persist=True, show_output=True
)
@log_start_end(log=logger)
def call_show(self, other_args: List[str]) -> None:
"""Process show command."""

View File

@@ -64,9 +64,6 @@ class CredentialsModel:
API_COINBASE_SECRET: str = "REPLACE_ME"
API_COINBASE_PASS_PHRASE: str = "REPLACE_ME"
# Others
OPENBB_PERSONAL_ACCESS_TOKEN: str = "REPLACE_ME"
def __repr__(self) -> str:
"""Return string representation of model."""
dataclass_repr = ""

View File

@@ -40,14 +40,13 @@ class PreferencesModel:
RETRY_WITH_LOAD: bool = False
USE_TABULATE_DF: bool = True
# Use interactive window to display dataframes with options to sort, filter, etc.
USE_INTERACTIVE_DF = True
USE_INTERACTIVE_DF: bool = True
USE_CLEAR_AFTER_CMD: bool = False
USE_COLOR: bool = True
USE_DATETIME: bool = True
# Enable interactive matplotlib mode: change variable name to be more descriptive and delete comment
USE_ION: bool = True
USE_WATERMARK: bool = True
# Enable command and source in the figures: change variable name to be more descriptive and delete comment
USE_CMD_LOCATION_FIGURE: bool = True
USE_PROMPT_TOOLKIT: bool = True
USE_PLOT_AUTOSCALING: bool = False

View File

@@ -30,7 +30,6 @@ class KeysRoot(Category):
`mykeys`: Get currently set API keys.\n
`news`: Set News key\n
`oanda`: Set Oanda key\n
`openbb`: Set OpenBB Personal Access Token.\n
`polygon`: Set Polygon key\n
`quandl`: Set Quandl key\n
`reddit`: Set Reddit key\n
@@ -71,7 +70,6 @@ class KeysRoot(Category):
self.mykeys = lib.keys_model.get_keys
self.news = lib.keys_model.set_news_key
self.oanda = lib.keys_model.set_oanda_key
self.openbb = lib.keys_model.set_openbb_personal_access_token
self.polygon = lib.keys_model.set_polygon_key
self.quandl = lib.keys_model.set_quandl_key
self.reddit = lib.keys_model.set_reddit_key

View File

@@ -1,73 +0,0 @@
# IMPORTS STANDARD
import dataclasses
# IMPORTS THIRDPARTY
from dotenv import set_key
# IMPORTS INTERNAL
from openbb_terminal.core.config.paths import SETTINGS_ENV_FILE
from openbb_terminal.core.session.current_user import (
get_current_user,
is_local,
set_current_user,
)
from openbb_terminal.core.session.hub_model import patch_user_configs
LOCAL_KEYS = [
"RH_USERNAME",
"RH_PASSWORD",
"DG_USERNAME",
"DG_PASSWORD",
"DG_TOTP_SECRET",
"OANDA_ACCOUNT_TYPE",
"OANDA_ACCOUNT",
"OANDA_TOKEN",
"API_BINANCE_KEY",
"API_BINANCE_SECRET",
"API_COINBASE_KEY",
"API_COINBASE_SECRET",
"API_COINBASE_PASS_PHRASE",
]
def set_credential(
name: str,
value: str,
persist: bool = False,
login: bool = False,
):
"""Set credential
Parameters
----------
name : str
Credential name
value : str
Credential value
persist : bool
Force saving to .env file
login : bool
If preference set during login
"""
current_user = get_current_user()
sync_enabled = current_user.preferences.SYNC_ENABLED
local_user = is_local()
# Set credential in current user
updated_credentials = dataclasses.replace(current_user.credentials, **{name: value})
updated_user = dataclasses.replace(current_user, credentials=updated_credentials)
set_current_user(updated_user)
# Set credential in local env file
if persist and local_user:
set_key(str(SETTINGS_ENV_FILE), "OPENBB_" + name, str(value))
# Send credential to cloud
if not local_user and sync_enabled and name not in LOCAL_KEYS and not login:
patch_user_configs(
key=name,
value=str(value),
type_="keys",
auth_header=current_user.profile.get_auth_header(),
)

View File

@@ -1,6 +1,8 @@
# IMPORTS STANDARD
import dataclasses
from copy import deepcopy
from typing import Optional
from pathlib import Path
from typing import Optional, Union
# IMPORTS INTERNAL
from openbb_terminal.core.models import (
@@ -9,7 +11,10 @@ from openbb_terminal.core.models import (
ProfileModel,
UserModel,
)
from openbb_terminal.core.session.env_handler import load_env_to_model, reading_env
from openbb_terminal.core.session.env_handler import (
load_env_to_model,
reading_env,
)
__env_dict = reading_env()
__credentials = load_env_to_model(__env_dict, CredentialsModel)
@@ -36,6 +41,21 @@ def set_current_user(user: UserModel):
__current_user = user
def get_local_user() -> UserModel:
"""Get local user."""
return deepcopy(__local_user)
def get_env_dict() -> dict:
"""Get env dict."""
return deepcopy(__env_dict)
def get_local_preferences() -> PreferencesModel:
"""Get preferences."""
return deepcopy(__preferences) # type: ignore
def is_local() -> bool:
"""Check if user is guest.
@@ -65,3 +85,38 @@ def copy_user(
)
return user_copy
def set_preference(
name: str,
value: Union[bool, Path, str],
):
"""Set preference
Parameters
----------
name : str
Preference name
value : Union[bool, Path, str]
Preference value
"""
current_user = get_current_user()
updated_preferences = dataclasses.replace(current_user.preferences, **{name: value})
updated_user = dataclasses.replace(current_user, preferences=updated_preferences)
set_current_user(updated_user)
def set_credential(name: str, value: str):
"""Set credential
Parameters
----------
name : str
Credential name
value : str
Credential value
"""
current_user = get_current_user()
updated_credentials = dataclasses.replace(current_user.credentials, **{name: value})
updated_user = dataclasses.replace(current_user, credentials=updated_credentials)
set_current_user(updated_user)

View File

@@ -2,7 +2,7 @@
from typing import Any, Dict, Optional, Type, Union
# IMPORTS THIRDPARTY
from dotenv import dotenv_values
from dotenv import dotenv_values, set_key
from pydantic import ValidationError
# IMPORTS INTERNAL
@@ -53,10 +53,10 @@ def load_env_to_model(
Union[Type[CredentialsModel], Type[PreferencesModel]]
Model with environment variables.
"""
model_name = model.__name__.strip("Model").lower()
try:
return model(**env_dict) # type: ignore
except ValidationError as error:
model_name = model.__name__.strip("Model").lower()
print(f"Error loading {model_name}:")
for err in error.errors():
loc = err.get("loc", None)
@@ -69,3 +69,19 @@ def load_env_to_model(
print(f" {var_name}: {msg}, using default -> {default}")
return model(**env_dict) # type: ignore
except Exception:
print(f"Error loading {model_name}, using defaults.")
return model() # type: ignore
def write_to_dotenv(name: str, value: str) -> None:
"""Write to .env file.
Parameters
----------
name : str
Name of the variable.
value : str
Value of the variable.
"""
set_key(str(SETTINGS_ENV_FILE), name, str(value))

View File

@@ -232,7 +232,7 @@ def fetch_user_configs(
return None
def patch_user_configs(
def upload_config(
key: str,
value: str,
type_: str,
@@ -565,7 +565,7 @@ def generate_personal_access_token(
Optional[requests.Response]
"""
url = f"{base_url}/sdk/token"
url = f"{base_url}sdk/token"
payload = json.dumps({"days": days})
headers = {
@@ -612,7 +612,7 @@ def get_personal_access_token(
Optional[requests.Response]
"""
url = f"{base_url}/sdk/token"
url = f"{base_url}sdk/token"
headers = {"Authorization": auth_header}
@@ -655,7 +655,7 @@ def revoke_personal_access_token(
Optional[requests.Response]
"""
url = f"{base_url}/sdk/token"
url = f"{base_url}sdk/token"
headers = {"Authorization": auth_header}

View File

@@ -7,9 +7,11 @@ from openbb_terminal.core.config.paths import (
HIST_FILE_PATH,
SETTINGS_DIRECTORY,
)
from openbb_terminal.core.session.credentials_handler import set_credential
from openbb_terminal.core.session.current_user import get_current_user
from openbb_terminal.core.session.preferences_handler import set_preference
from openbb_terminal.core.session.current_user import (
get_current_user,
get_local_user,
set_credential,
)
from openbb_terminal.rich_config import console
SESSION_FILE_PATH = SETTINGS_DIRECTORY / "session.json"
@@ -110,38 +112,12 @@ def apply_configs(configs: dict):
configs : dict
The configurations.
"""
if configs:
settings = configs.get("features_settings", {})
sync = update_sync_flag(settings)
if sync:
if settings:
for k, v in settings.items():
set_preference(k, v, login=True)
if configs and get_local_user().preferences.SYNC_ENABLED:
credentials = configs.get("features_keys", {}) or {}
for k, v in credentials.items():
set_credential(k, v)
keys = configs.get("features_keys", {})
if keys:
for k, v in keys.items():
set_credential(k, v, login=True)
def update_sync_flag(settings: dict) -> bool:
"""Update the sync flag.
Parameters
----------
settings : dict
The settings.
Returns
-------
bool
The sync flag.
"""
sync = not (settings and settings.get("SYNC_ENABLED", "true").lower() == "false")
set_preference("SYNC_ENABLED", sync, login=True)
return sync
# TODO: apply other configs here
def get_routine(file_name: str, folder: Optional[Path] = None) -> Optional[str]:

View File

@@ -1,56 +0,0 @@
# IMPORTS STANDARD
import dataclasses
from pathlib import Path
from typing import Union
# IMPORTS THIRDPARTY
from dotenv import set_key
# IMPORTS INTERNAL
from openbb_terminal.core.config.paths import SETTINGS_ENV_FILE
from openbb_terminal.core.session.current_user import (
get_current_user,
is_local,
set_current_user,
)
from openbb_terminal.core.session.hub_model import patch_user_configs
def set_preference(
name: str,
value: Union[bool, Path, str],
login: bool = False,
):
"""Set preference
Parameters
----------
name : str
Preference name
value : Union[bool, Path, str]
Preference value
login : bool
If the preference is set during login
"""
current_user = get_current_user()
sync_enabled = current_user.preferences.SYNC_ENABLED
local_user = is_local()
# Set preference in current user
updated_preferences = dataclasses.replace(current_user.preferences, **{name: value})
updated_user = dataclasses.replace(current_user, preferences=updated_preferences)
set_current_user(updated_user)
# Set preference in local env file
if local_user:
set_key(str(SETTINGS_ENV_FILE), "OPENBB_" + name, str(value))
# Send preference to cloud
if not login and not local_user and (sync_enabled or name == "SYNC_ENABLED"):
patch_user_configs(
key=name,
value=str(value),
type_="settings",
auth_header=current_user.profile.get_auth_header(),
)

View File

@@ -11,14 +11,15 @@ from openbb_terminal.base_helpers import (
)
from openbb_terminal.core.models.user_model import (
CredentialsModel,
PreferencesModel,
ProfileModel,
UserModel,
)
from openbb_terminal.core.session.current_user import (
get_env_dict,
get_local_preferences,
set_current_user,
set_preference,
)
from openbb_terminal.core.session.preferences_handler import set_preference
from openbb_terminal.helper_funcs import system_clear
from openbb_terminal.rich_config import console
@@ -76,26 +77,24 @@ def login(session: dict) -> LoginStatus:
session : dict
The session info.
"""
# create a new user
hub_user = UserModel( # type: ignore
credentials=CredentialsModel(),
profile=ProfileModel(),
preferences=PreferencesModel(),
preferences=get_local_preferences(),
)
response = Hub.fetch_user_configs(session)
if response is not None:
if response.status_code == 200:
configs = json.loads(response.content)
email = configs.get("email", "")
feature_settings = configs.get("features_settings", {}) or {}
hub_user.profile.load_user_info(session, email)
set_current_user(hub_user)
Local.apply_configs(configs=configs)
if feature_settings.get("FLAIR", None) is None:
if "FLAIR" not in get_env_dict():
MAX_FLAIR_LEN = 20
flair = "[" + hub_user.profile.username[:MAX_FLAIR_LEN] + "]" + " 🦋"
set_preference("FLAIR", flair, login=True)
set_preference("FLAIR", flair)
return LoginStatus.SUCCESS
if response.status_code == 401:
return LoginStatus.UNAUTHORIZED

View File

@@ -3,13 +3,17 @@ __docformat__ = "numpy"
# IMPORTATION STANDARD
import logging
from typing import List, Optional
from pathlib import Path
from typing import List, Optional, Union
# IMPORTATION THIRDPARTY
from openbb_terminal.core.session.current_user import get_current_user
from openbb_terminal.core.session.current_user import (
get_current_user,
set_preference,
)
from openbb_terminal.core.session.env_handler import write_to_dotenv
# IMPORTATION INTERNAL
from openbb_terminal.core.session.preferences_handler import set_preference
from openbb_terminal.custom_prompt_toolkit import NestedCompleter
from openbb_terminal.decorators import log_start_end
from openbb_terminal.menu import session
@@ -22,12 +26,27 @@ from openbb_terminal.rich_config import MenuText, console
logger = logging.getLogger(__name__)
def set_and_save_preference(name: str, value: Union[bool, Path, str]):
"""Set preference and write to .env
Parameters
----------
name : str
Preference name
value : Union[bool, Path, str]
Preference value
"""
set_preference(name, value)
write_to_dotenv("OPENBB_" + name, str(value))
class FeatureFlagsController(BaseController):
"""Feature Flags Controller class"""
CHOICES_COMMANDS: List[str] = [
"retryload",
"tab",
"interactive",
"cls",
"color",
"ion",
@@ -63,6 +82,7 @@ class FeatureFlagsController(BaseController):
mt.add_raw("\n")
mt.add_setting("retryload", current_user.preferences.RETRY_WITH_LOAD)
mt.add_setting("tab", current_user.preferences.USE_TABULATE_DF)
mt.add_setting("interactive", current_user.preferences.USE_INTERACTIVE_DF)
mt.add_setting("cls", current_user.preferences.USE_CLEAR_AFTER_CMD)
mt.add_setting("color", current_user.preferences.USE_COLOR)
mt.add_setting("promptkit", current_user.preferences.USE_PROMPT_TOOLKIT)
@@ -83,7 +103,7 @@ class FeatureFlagsController(BaseController):
def call_overwrite(self, _):
"""Process overwrite command"""
set_preference(
set_and_save_preference(
"FILE_OVERWITE", not get_current_user().preferences.FILE_OVERWRITE
)
@@ -93,21 +113,28 @@ class FeatureFlagsController(BaseController):
def call_retryload(self, _):
"""Process retryload command"""
set_preference(
set_and_save_preference(
"RETRY_WITH_LOAD", not get_current_user().preferences.RETRY_WITH_LOAD
)
@log_start_end(log=logger)
def call_tab(self, _):
"""Process tab command"""
set_preference(
set_and_save_preference(
"USE_TABULATE_DF", not get_current_user().preferences.USE_TABULATE_DF
)
@log_start_end(log=logger)
def call_interactive(self, _):
"""Process interactive command"""
set_and_save_preference(
"USE_INTERACTIVE_DF", not get_current_user().preferences.USE_INTERACTIVE_DF
)
@log_start_end(log=logger)
def call_cls(self, _):
"""Process cls command"""
set_preference(
set_and_save_preference(
"USE_CLEAR_AFTER_CMD",
not get_current_user().preferences.USE_CLEAR_AFTER_CMD,
)
@@ -115,12 +142,14 @@ class FeatureFlagsController(BaseController):
@log_start_end(log=logger)
def call_color(self, _):
"""Process color command"""
set_preference("USE_COLOR", not get_current_user().preferences.USE_COLOR)
set_and_save_preference(
"USE_COLOR", not get_current_user().preferences.USE_COLOR
)
@log_start_end(log=logger)
def call_promptkit(self, _):
"""Process promptkit command"""
set_preference(
set_and_save_preference(
"USE_PROMPT_TOOLKIT",
not get_current_user().preferences.USE_PROMPT_TOOLKIT,
)
@@ -128,7 +157,7 @@ class FeatureFlagsController(BaseController):
@log_start_end(log=logger)
def call_thoughts(self, _):
"""Process thoughts command"""
set_preference(
set_and_save_preference(
"ENABLE_THOUGHTS_DAY",
not get_current_user().preferences.ENABLE_THOUGHTS_DAY,
)
@@ -136,7 +165,7 @@ class FeatureFlagsController(BaseController):
@log_start_end(log=logger)
def call_reporthtml(self, _):
"""Process reporthtml command"""
set_preference(
set_and_save_preference(
"OPEN_REPORT_AS_HTML",
not get_current_user().preferences.OPEN_REPORT_AS_HTML,
)
@@ -144,7 +173,7 @@ class FeatureFlagsController(BaseController):
@log_start_end(log=logger)
def call_exithelp(self, _):
"""Process exithelp command"""
set_preference(
set_and_save_preference(
"ENABLE_EXIT_AUTO_HELP",
not get_current_user().preferences.ENABLE_EXIT_AUTO_HELP,
)
@@ -152,7 +181,7 @@ class FeatureFlagsController(BaseController):
@log_start_end(log=logger)
def call_rcontext(self, _):
"""Process rcontext command"""
set_preference(
set_and_save_preference(
"REMEMBER_CONTEXTS",
not get_current_user().preferences.REMEMBER_CONTEXTS,
)
@@ -160,17 +189,21 @@ class FeatureFlagsController(BaseController):
@log_start_end(log=logger)
def call_dt(self, _):
"""Process dt command"""
set_preference("USE_DATETIME", not get_current_user().preferences.USE_DATETIME)
set_and_save_preference(
"USE_DATETIME", not get_current_user().preferences.USE_DATETIME
)
@log_start_end(log=logger)
def call_rich(self, _):
"""Process rich command"""
set_preference("ENABLE_RICH", not get_current_user().preferences.ENABLE_RICH)
set_and_save_preference(
"ENABLE_RICH", not get_current_user().preferences.ENABLE_RICH
)
@log_start_end(log=logger)
def call_richpanel(self, _):
"""Process richpanel command"""
set_preference(
set_and_save_preference(
"ENABLE_RICH_PANEL",
not get_current_user().preferences.ENABLE_RICH_PANEL,
)
@@ -178,19 +211,19 @@ class FeatureFlagsController(BaseController):
@log_start_end(log=logger)
def call_ion(self, _):
"""Process ion command"""
set_preference("USE_ION", not get_current_user().preferences.USE_ION)
set_and_save_preference("USE_ION", not get_current_user().preferences.USE_ION)
@log_start_end(log=logger)
def call_watermark(self, _):
"""Process watermark command"""
set_preference(
set_and_save_preference(
"USE_WATERMARK", not get_current_user().preferences.USE_WATERMARK
)
@log_start_end(log=logger)
def call_cmdloc(self, _):
"""Process cmdloc command"""
set_preference(
set_and_save_preference(
"USE_CMD_LOCATION_FIGURE",
not get_current_user().preferences.USE_CMD_LOCATION_FIGURE,
)
@@ -200,4 +233,6 @@ class FeatureFlagsController(BaseController):
"""Process tbhint command"""
if get_current_user().preferences.TOOLBAR_HINT:
console.print("Will take effect when running terminal next.")
set_preference("TOOLBAR_HINT", not get_current_user().preferences.TOOLBAR_HINT)
set_and_save_preference(
"TOOLBAR_HINT", not get_current_user().preferences.TOOLBAR_HINT
)

View File

@@ -1214,26 +1214,29 @@ def str_to_bool(value) -> bool:
def get_screeninfo():
"""Get screeninfo."""
screens = get_monitors() # Get all available monitors
current_user = get_current_user()
if (
len(screens) - 1 < current_user.preferences.MONITOR
): # Check to see if chosen monitor is detected
monitor = 0
console.print(
f"Could not locate monitor {current_user.preferences.MONITOR}, using primary monitor."
)
else:
monitor = current_user.preferences.MONITOR
main_screen = screens[monitor] # Choose what monitor to get
if screens:
current_user = get_current_user()
if (
len(screens) - 1 < current_user.preferences.MONITOR
): # Check to see if chosen monitor is detected
monitor = 0
console.print(
f"Could not locate monitor {current_user.preferences.MONITOR}, using primary monitor."
)
else:
monitor = current_user.preferences.MONITOR
main_screen = screens[monitor] # Choose what monitor to get
return (main_screen.width, main_screen.height)
return (main_screen.width, main_screen.height)
return None
def plot_autoscale():
"""Autoscale plot."""
current_user = get_current_user()
if current_user.preferences.USE_PLOT_AUTOSCALING:
x, y = get_screeninfo() # Get screen size
screen_info = get_screeninfo()
if current_user.preferences.USE_PLOT_AUTOSCALING and screen_info:
x, y = screen_info # Get screen size
# account for ultrawide monitors
if x / y > 1.5:
x = x * 0.4

View File

@@ -53,14 +53,7 @@ class KeysController(BaseController): # pylint: disable=too-many-public-methods
def check_keys_status(self) -> None:
"""Check keys status"""
for api in optional_rich_track(self.API_LIST, desc="Checking keys status"):
if api == "openbb":
self.status_dict[api] = getattr(
keys_model, "check_" + str(api) + "_personal_access_token"
)()
else:
self.status_dict[api] = getattr(
keys_model, "check_" + str(api) + "_key"
)()
self.status_dict[api] = getattr(keys_model, "check_" + str(api) + "_key")()
def print_help(self):
"""Print help"""
@@ -1167,31 +1160,3 @@ class KeysController(BaseController): # pylint: disable=too-many-public-methods
self.status_dict["databento"] = keys_model.set_databento_key(
key=ns_parser.key, persist=True, show_output=True
)
@log_start_end(log=logger)
def call_openbb(self, other_args: List[str]):
"""Process openbb command"""
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="openbb",
description="Set OpenBB Personal Access Token. ",
)
parser.add_argument(
"-k",
"--key",
type=str,
dest="key",
help="key",
)
if not other_args:
console.print("For your Personal Access Token, visit: https://openbb.co/")
return
if other_args and "-" not in other_args[0][0]:
other_args.insert(0, "-k")
ns_parser = self.parse_simple_args(parser, other_args)
if ns_parser:
self.status_dict["openbb"] = keys_model.set_openbb_personal_access_token(
key=ns_parser.key, persist=True, show_output=True
)

View File

@@ -5,9 +5,7 @@ __docformat__ = "numpy"
import contextlib
import io
import json
import logging
import os
import sys
from enum import Enum
from typing import Dict, List, Union
@@ -25,10 +23,13 @@ from oandapyV20 import API as oanda_API
from prawcore.exceptions import ResponseException
from tokenterminal import TokenTerminal
from openbb_terminal.core.session.credentials_handler import set_credential
from openbb_terminal.core.session.current_user import get_current_user
from openbb_terminal.core.session.hub_model import BASE_URL
from openbb_terminal.core.session.local_model import SESSION_FILE_PATH
from openbb_terminal.core.session.current_user import (
get_current_user,
is_local,
set_credential,
)
from openbb_terminal.core.session.env_handler import write_to_dotenv
from openbb_terminal.core.session.hub_model import upload_config
from openbb_terminal.cryptocurrency.coinbase_helpers import (
CoinbaseApiException,
CoinbaseProAuth,
@@ -67,7 +68,6 @@ API_DICT: Dict = {
"rh": "ROBINHOOD",
"degiro": "DEGIRO",
"oanda": "OANDA",
"openbb": "OPENBB",
"binance": "BINANCE",
"bitquery": "BITQUERY",
"coinbase": "COINBASE",
@@ -89,6 +89,22 @@ API_DICT: Dict = {
# sorting api key section by name
API_DICT = dict(sorted(API_DICT.items()))
LOCAL_KEYS = [
"RH_USERNAME",
"RH_PASSWORD",
"DG_USERNAME",
"DG_PASSWORD",
"DG_TOTP_SECRET",
"OANDA_ACCOUNT_TYPE",
"OANDA_ACCOUNT",
"OANDA_TOKEN",
"API_BINANCE_KEY",
"API_BINANCE_SECRET",
"API_COINBASE_KEY",
"API_COINBASE_SECRET",
"API_COINBASE_PASS_PHRASE",
]
class KeyStatus(str, Enum):
"""Class to handle status messages and colors"""
@@ -230,7 +246,7 @@ def get_keys(show: bool = False) -> pd.DataFrame:
for k, _ in current_user.credentials.get_fields().items():
field_value = current_user.credentials.get_field_value(field=k)
if field_value != "REPLACE_ME":
if field_value and field_value != "REPLACE_ME":
current_keys[k] = field_value
if current_keys:
@@ -245,6 +261,35 @@ def get_keys(show: bool = False) -> pd.DataFrame:
return pd.DataFrame()
def handle_credential(name: str, value: str, persist: bool = False):
"""Handle credential
Parameters
----------
name: str
Name of credential
value: str
Value of credential
persist: bool, optional
Write to .env file. By default, False.
"""
current_user = get_current_user()
sync_enabled = current_user.preferences.SYNC_ENABLED
local_user = is_local()
set_credential(name, value)
if local_user and persist:
write_to_dotenv("OPENBB_" + name, value)
elif not local_user and sync_enabled and name not in LOCAL_KEYS:
upload_config(
key=name,
value=str(value),
type_="keys",
auth_header=current_user.profile.get_auth_header(),
)
def set_av_key(key: str, persist: bool = False, show_output: bool = False) -> str:
"""Set Alpha Vantage key
@@ -270,7 +315,7 @@ def set_av_key(key: str, persist: bool = False, show_output: bool = False) -> st
>>> openbb.keys.av(key="example_key")
"""
set_credential("API_KEY_ALPHAVANTAGE", key, persist)
handle_credential("API_KEY_ALPHAVANTAGE", key, persist)
return check_av_key(show_output)
@@ -337,7 +382,7 @@ def set_fmp_key(key: str, persist: bool = False, show_output: bool = False) -> s
>>> openbb.keys.fmp(key="example_key")
"""
set_credential("API_KEY_FINANCIALMODELINGPREP", key, persist)
handle_credential("API_KEY_FINANCIALMODELINGPREP", key, persist)
return check_fmp_key(show_output)
@@ -408,7 +453,7 @@ def set_quandl_key(key: str, persist: bool = False, show_output: bool = False) -
>>> openbb.keys.quandl(key="example_key")
"""
set_credential("API_KEY_QUANDL", key, persist)
handle_credential("API_KEY_QUANDL", key, persist)
return check_quandl_key(show_output)
@@ -474,7 +519,7 @@ def set_polygon_key(key: str, persist: bool = False, show_output: bool = False)
>>> openbb.keys.polygon(key="example_key")
"""
set_credential("API_POLYGON_KEY", key, persist)
handle_credential("API_POLYGON_KEY", key, persist)
return check_polygon_key(show_output)
@@ -543,7 +588,7 @@ def set_fred_key(key: str, persist: bool = False, show_output: bool = False) ->
>>> openbb.keys.fred(key="example_key")
"""
set_credential("API_FRED_KEY", key, persist)
handle_credential("API_FRED_KEY", key, persist)
return check_fred_key(show_output)
@@ -611,7 +656,7 @@ def set_news_key(key: str, persist: bool = False, show_output: bool = False) ->
>>> openbb.keys.news(key="example_key")
"""
set_credential("API_NEWS_TOKEN", key, persist)
handle_credential("API_NEWS_TOKEN", key, persist)
return check_news_key(show_output)
@@ -679,7 +724,7 @@ def set_tradier_key(key: str, persist: bool = False, show_output: bool = False)
>>> openbb.keys.tradier(key="example_key")
"""
set_credential("API_TRADIER_TOKEN", key, persist)
handle_credential("API_TRADIER_TOKEN", key, persist)
return check_tradier_key(show_output)
@@ -752,7 +797,7 @@ def set_cmc_key(key: str, persist: bool = False, show_output: bool = False) -> s
>>> openbb.keys.cmc(key="example_key")
"""
set_credential("API_CMC_KEY", key, persist)
handle_credential("API_CMC_KEY", key, persist)
return check_cmc_key(show_output)
@@ -816,7 +861,7 @@ def set_finnhub_key(key: str, persist: bool = False, show_output: bool = False)
>>> openbb.keys.finnhub(key="example_key")
"""
set_credential("API_FINNHUB_KEY", key, persist)
handle_credential("API_FINNHUB_KEY", key, persist)
return check_finnhub_key(show_output)
@@ -906,11 +951,11 @@ def set_reddit_key(
)
"""
set_credential("API_REDDIT_CLIENT_ID", client_id, persist)
set_credential("API_REDDIT_CLIENT_SECRET", client_secret, persist)
set_credential("API_REDDIT_PASSWORD", password, persist)
set_credential("API_REDDIT_USERNAME", username, persist)
set_credential("API_REDDIT_USER_AGENT", useragent, persist)
handle_credential("API_REDDIT_CLIENT_ID", client_id, persist)
handle_credential("API_REDDIT_CLIENT_SECRET", client_secret, persist)
handle_credential("API_REDDIT_PASSWORD", password, persist)
handle_credential("API_REDDIT_USERNAME", username, persist)
handle_credential("API_REDDIT_USER_AGENT", useragent, persist)
return check_reddit_key(show_output)
@@ -1002,7 +1047,7 @@ def set_bitquery_key(key: str, persist: bool = False, show_output: bool = False)
>>> openbb.keys.bitquery(key="example_key")
"""
set_credential("API_BITQUERY_KEY", key, persist)
handle_credential("API_BITQUERY_KEY", key, persist)
return check_bitquery_key(show_output)
@@ -1092,7 +1137,7 @@ def set_twitter_key(
)
"""
set_credential("API_TWITTER_BEARER_TOKEN", access_token, persist)
handle_credential("API_TWITTER_BEARER_TOKEN", access_token, persist)
return check_twitter_key(show_output)
@@ -1180,8 +1225,8 @@ def set_rh_key(
)
"""
set_credential("RH_USERNAME", username, persist)
set_credential("RH_PASSWORD", password, persist)
handle_credential("RH_USERNAME", username, persist)
handle_credential("RH_PASSWORD", password, persist)
return check_rh_key(show_output)
@@ -1257,9 +1302,9 @@ def set_degiro_key(
)
"""
set_credential("DG_USERNAME", username, persist)
set_credential("DG_PASSWORD", password, persist)
set_credential("DG_TOTP_SECRET", secret, persist)
handle_credential("DG_USERNAME", username, persist)
handle_credential("DG_PASSWORD", password, persist)
handle_credential("DG_TOTP_SECRET", secret, persist)
return check_degiro_key(show_output)
@@ -1355,9 +1400,9 @@ def set_oanda_key(
)
"""
set_credential("OANDA_ACCOUNT", account, persist)
set_credential("OANDA_TOKEN", access_token, persist)
set_credential("OANDA_ACCOUNT_TYPE", account_type, persist)
handle_credential("OANDA_ACCOUNT", account, persist)
handle_credential("OANDA_TOKEN", access_token, persist)
handle_credential("OANDA_ACCOUNT_TYPE", account_type, persist)
return check_oanda_key(show_output)
@@ -1442,8 +1487,8 @@ def set_binance_key(
)
"""
set_credential("API_BINANCE_KEY", key, persist)
set_credential("API_BINANCE_SECRET", secret, persist)
handle_credential("API_BINANCE_KEY", key, persist)
handle_credential("API_BINANCE_SECRET", secret, persist)
return check_binance_key(show_output)
@@ -1529,9 +1574,9 @@ def set_coinbase_key(
)
"""
set_credential("API_COINBASE_KEY", key, persist)
set_credential("API_COINBASE_SECRET", secret, persist)
set_credential("API_COINBASE_PASS_PHRASE", passphrase, persist)
handle_credential("API_COINBASE_KEY", key, persist)
handle_credential("API_COINBASE_SECRET", secret, persist)
handle_credential("API_COINBASE_PASS_PHRASE", passphrase, persist)
return check_coinbase_key(show_output)
@@ -1606,7 +1651,7 @@ def set_walert_key(key: str, persist: bool = False, show_output: bool = False) -
>>> openbb.keys.walert(key="example_key")
"""
set_credential("API_WHALE_ALERT_KEY", key, persist)
handle_credential("API_WHALE_ALERT_KEY", key, persist)
return check_walert_key(show_output)
@@ -1679,7 +1724,7 @@ def set_glassnode_key(
>>> openbb.keys.glassnode(key="example_key")
"""
set_credential("API_GLASSNODE_KEY", key, persist)
handle_credential("API_GLASSNODE_KEY", key, persist)
return check_glassnode_key(show_output)
@@ -1754,7 +1799,7 @@ def set_coinglass_key(
>>> openbb.keys.coinglass(key="example_key")
"""
set_credential("API_COINGLASS_KEY", key, persist)
handle_credential("API_COINGLASS_KEY", key, persist)
return check_coinglass_key(show_output)
@@ -1825,7 +1870,7 @@ def set_cpanic_key(key: str, persist: bool = False, show_output: bool = False) -
>>> openbb.keys.cpanic(key="example_key")
"""
set_credential("API_CRYPTO_PANIC_KEY", key, persist)
handle_credential("API_CRYPTO_PANIC_KEY", key, persist)
return check_cpanic_key(show_output)
@@ -1895,7 +1940,7 @@ def set_ethplorer_key(
>>> openbb.keys.ethplorer(key="example_key")
"""
set_credential("API_ETHPLORER_KEY", key, persist)
handle_credential("API_ETHPLORER_KEY", key, persist)
return check_ethplorer_key(show_output)
@@ -1972,8 +2017,8 @@ def set_smartstake_key(
)
"""
set_credential("API_SMARTSTAKE_KEY", key, persist)
set_credential("API_SMARTSTAKE_TOKEN", access_token, persist)
handle_credential("API_SMARTSTAKE_KEY", key, persist)
handle_credential("API_SMARTSTAKE_TOKEN", access_token, persist)
return check_smartstake_key(show_output)
@@ -2058,7 +2103,7 @@ def set_github_key(key: str, persist: bool = False, show_output: bool = False) -
>>> openbb.keys.github(key="example_key")
"""
set_credential("API_GITHUB_KEY", key, persist)
handle_credential("API_GITHUB_KEY", key, persist)
return check_github_key(show_output)
@@ -2119,7 +2164,7 @@ def set_messari_key(key: str, persist: bool = False, show_output: bool = False)
>>> openbb.keys.messari(key="example_key")
"""
set_credential("API_MESSARI_KEY", key, persist)
handle_credential("API_MESSARI_KEY", key, persist)
return check_messari_key(show_output)
@@ -2189,7 +2234,7 @@ def set_eodhd_key(key: str, persist: bool = False, show_output: bool = False) ->
>>> openbb.keys.eodhd(key="example_key")
"""
set_credential("API_EODHD_KEY", key, persist)
handle_credential("API_EODHD_KEY", key, persist)
return check_eodhd_key(show_output)
@@ -2258,7 +2303,7 @@ def set_santiment_key(
>>> openbb.keys.santiment(key="example_key")
"""
set_credential("API_SANTIMENT_KEY", key, persist)
handle_credential("API_SANTIMENT_KEY", key, persist)
return check_santiment_key(show_output)
@@ -2338,7 +2383,7 @@ def set_shroom_key(key: str, persist: bool = False, show_output: bool = False) -
>>> openbb.keys.shroom(key="example_key")
"""
set_credential("API_SHROOM_KEY", key, persist)
handle_credential("API_SHROOM_KEY", key, persist)
return check_shroom_key(show_output)
@@ -2413,7 +2458,7 @@ def set_tokenterminal_key(
>>> from openbb_terminal.sdk import openbb
>>> openbb.keys.tokenterminal(key="example_key")
"""
set_credential("API_TOKEN_TERMINAL_KEY", key, persist)
handle_credential("API_TOKEN_TERMINAL_KEY", key, persist)
return check_tokenterminal_key(show_output)
@@ -2478,7 +2523,7 @@ def set_stocksera_key(key: str, persist: bool = False, show_output: bool = False
>>> from openbb_terminal.sdk import openbb
>>> openbb.keys.stocksera(key="example_key")
"""
set_credential("API_STOCKSERA_KEY", key, persist)
handle_credential("API_STOCKSERA_KEY", key, persist)
return check_stocksera_key(show_output)
@@ -2517,89 +2562,6 @@ def check_stocksera_key(show_output: bool = False):
return str(status)
def set_openbb_personal_access_token(
key: str, persist: bool = False, show_output: bool = False
):
"""Set OpenBB Personal Access Token.
Parameters
----------
key: str
Personal Access Token
persist: bool, optional
If False, api key change will be contained to where it was changed. For example, a Jupyter notebook session.
If True, api key change will be global, i.e. it will affect terminal environment variables.
By default, False.
show_output: bool, optional
Display status string or not. By default, False.
Returns
-------
str
Status of key set
Examples
--------
>>> from openbb_terminal.sdk import openbb
>>> openbb.keys.openbb(key="example_key")
"""
set_credential("OPENBB_PERSONAL_ACCESS_TOKEN", key, persist)
return check_openbb_personal_access_token(show_output)
def check_openbb_personal_access_token(show_output: bool = False):
"""Check OpenBB Personal Access Token
Returns
-------
str
Status of key set
"""
current_user = get_current_user()
if current_user.credentials.OPENBB_PERSONAL_ACCESS_TOKEN == "REPLACE_ME":
logger.info("OpenBB Personal Access Token not defined")
status = KeyStatus.NOT_DEFINED
else:
try:
access_token = ""
# TODO: is there a better way to test the key?
# This requires a valid session file
if os.path.isfile(SESSION_FILE_PATH):
with open(SESSION_FILE_PATH) as f:
access_token = json.load(f).get("access_token")
headers = {
"Authorization": f"Bearer {access_token}",
"Content-Type": "application/json",
}
response = request(
url=f"{BASE_URL}sdk/token", method="GET", headers=headers
)
token = response.json().get("token")
if (
response.status_code == 200
and token == current_user.credentials.OPENBB_PERSONAL_ACCESS_TOKEN
):
logger.info("OpenBB Personal Access Token defined, test passed")
status = KeyStatus.DEFINED_TEST_PASSED
else:
logger.warning("OpenBB Personal Access Token. defined, test failed")
status = KeyStatus.DEFINED_TEST_FAILED
except requests.exceptions.RequestException:
logger.warning("OpenBB Personal Access Token. defined, test failed")
status = KeyStatus.DEFINED_TEST_FAILED
if show_output:
console.print(status.colorize())
return str(status)
def set_intrinio_key(key: str, persist: bool = False, show_output: bool = False) -> str:
"""Set Intrinio key
@@ -2625,7 +2587,7 @@ def set_intrinio_key(key: str, persist: bool = False, show_output: bool = False)
>>> openbb.keys.intrinio(key="example_key")
"""
set_credential("API_INTRINIO_KEY", key, persist)
handle_credential("API_INTRINIO_KEY", key, persist)
return check_intrinio_key(show_output)
@@ -2695,7 +2657,7 @@ def set_databento_key(
>>> openbb.keys.databento(key="example_key")
"""
set_credential("API_DATABENTO_KEY", key, persist)
handle_credential("API_DATABENTO_KEY", key, persist)
return check_databento_key(show_output)

View File

@@ -47,6 +47,7 @@ en:
featflags/_info_: Feature flags through environment variables
featflags/retryload: retry misspelled commands with load first
featflags/tab: use tabulate to print dataframes
featflags/interactive: open dataframes in interactive window
featflags/cls: clear console after each command
featflags/color: use coloring features
featflags/promptkit: enable prompt toolkit (autocomplete and history)
@@ -155,8 +156,6 @@ en:
stocks/options/vsurf: show 3D volatility surface
stocks/options/grhist: plot option greek history
stocks/options/plot: plot variables provided by the user
stocks/options/parity: shows whether options are above or below expected price
stocks/options/binom: shows the value of an option using binomial options pricing
stocks/options/greeks: shows the greeks for a given option
stocks/options/eodchain: gets option chain at a specific date
stocks/options/pricing: shows options pricing and risk neutral valuation
@@ -167,12 +166,6 @@ en:
stocks/options/screen/scr: screen data from this preset
stocks/options/screen/_screened_tickers: Last screened tickers
stocks/options/screen/ca: take these to comparison analysis menu
stocks/options/pricing/_ticker: Ticker
stocks/options/pricing/_expiry: Expiry
stocks/options/pricing/add: add an expected price to the list
stocks/options/pricing/rmv: remove an expected price from the list
stocks/options/pricing/show: show the listed of expected prices
stocks/options/pricing/rnval: risk neutral valuation for an option
stocks/options/hedge/_ticker: Ticker
stocks/options/hedge/_expiry: Expiry
stocks/options/hedge/pick: pick the underlying asset position
@@ -1000,7 +993,6 @@ en:
portfolio/var: display value at risk
portfolio/es: display expected shortfall
portfolio/om: display omega ratio
portfolio/bro/ally: Ally Invest Menu
portfolio/bro/degiro: Degiro Menu
portfolio/bro/rh: Robinhood Menu
portfolio/bro/cb: Coinbase Pro Menu

View File

@@ -1,191 +0,0 @@
"""Ally Controller"""
__docformat__ = "numpy"
import argparse
import logging
from typing import List, Optional
from openbb_terminal.core.session.current_user import get_current_user
from openbb_terminal.custom_prompt_toolkit import NestedCompleter
from openbb_terminal.decorators import log_start_end
from openbb_terminal.helper_funcs import EXPORT_ONLY_RAW_DATA_ALLOWED
from openbb_terminal.menu import session
from openbb_terminal.parent_classes import BaseController
from openbb_terminal.portfolio.brokers.ally import ally_view
from openbb_terminal.rich_config import MenuText, console
logger = logging.getLogger(__name__)
class AllyController(BaseController):
"""Ally Controller class"""
CHOICES_COMMANDS = ["holdings", "history", "balances", "quote", "movers"]
list_choices = [
"toplosers",
"toppctlosers",
"topvolume",
"topactive",
"topgainers",
"toppctgainers",
]
list_exchanges = ["A", "N", "Q", "U", "V"]
PATH = "/portfolio/bro/ally/"
CHOICES_GENERATION = True
def __init__(self, queue: Optional[List[str]] = None):
"""Constructor"""
super().__init__(queue)
if session and get_current_user().preferences.USE_PROMPT_TOOLKIT:
choices: dict = self.choices_default
self.choices = choices
self.completer = NestedCompleter.from_nested_dict(choices)
def print_help(self):
"""Print help"""
mt = MenuText("portfolio/bro/ally/")
mt.add_cmd("holdings")
mt.add_cmd("history")
mt.add_cmd("balances")
mt.add_raw("\n")
mt.add_info("_info_")
mt.add_cmd("quote")
mt.add_cmd("movers")
console.print(text=mt.menu_text, menu="Portfolio - Brokers - Ally")
@log_start_end(log=logger)
def call_holdings(self, other_args: List[str]):
"""Process holdings command"""
parser = argparse.ArgumentParser(
prog="holdings",
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
description="Display info about your trading accounts on Ally",
)
ns_parser = self.parse_known_args_and_warn(
parser, other_args, export_allowed=EXPORT_ONLY_RAW_DATA_ALLOWED
)
if ns_parser:
ally_view.display_holdings(
export=ns_parser.export,
sheet_name=" ".join(ns_parser.sheet_name)
if ns_parser.sheet_name
else None,
)
@log_start_end(log=logger)
def call_history(self, other_args: List[str]):
"""Process history command"""
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="history",
description="""Account transaction history""",
)
parser.add_argument(
"-l",
"--limit",
dest="limit",
default=15,
type=int,
help="Number of recent transactions to show",
)
ns_parser = self.parse_known_args_and_warn(
parser, other_args, export_allowed=EXPORT_ONLY_RAW_DATA_ALLOWED
)
if ns_parser:
ally_view.display_history(
n_to_show=ns_parser.limit, export=ns_parser.export
)
@log_start_end(log=logger)
def call_balances(self, other_args: List[str]):
"""Process balances command"""
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="balances",
description="""Account balance details""",
)
ns_parser = self.parse_known_args_and_warn(
parser, other_args, export_allowed=EXPORT_ONLY_RAW_DATA_ALLOWED
)
if ns_parser:
ally_view.display_balances(
export=ns_parser.export,
sheet_name=" ".join(ns_parser.sheet_name)
if ns_parser.sheet_name
else None,
)
@log_start_end(log=logger)
def call_quote(self, other_args: List[str]):
"""Process balances command"""
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="quote",
description="""Get stock quote""",
)
if other_args and "-" not in other_args[0][0]:
other_args.insert(0, "-t")
parser.add_argument(
"-t",
"--ticker",
help="Ticker to get quote for. Can be in form of 'tick1,tick2...'",
type=str,
dest="ticker",
)
ns_parser = self.parse_known_args_and_warn(parser, other_args)
if ns_parser:
ally_view.display_stock_quote(ns_parser.ticker)
@log_start_end(log=logger)
def call_movers(self, other_args: List[str]):
"""Process movers command"""
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="movers",
description="""Get stock movers""",
)
parser.add_argument(
"-t",
"--type",
help="List to get movers of",
choices=self.list_choices,
default="topactive",
dest="list_type",
)
parser.add_argument(
"-e",
"--exchange",
help="""Exchange to look at. Can be
A:American Stock Exchange.
N:New York Stock Exchange.
Q:NASDAQ
U:NASDAQ Bulletin Board
V:NASDAQ OTC Other""",
choices=self.list_exchanges,
default="N",
dest="exchange",
)
parser.add_argument(
"-l", "--limit", help="Number to show", type=int, default=15, dest="limit"
)
ns_parser = self.parse_known_args_and_warn(
parser, other_args, export_allowed=EXPORT_ONLY_RAW_DATA_ALLOWED
)
if ns_parser:
ally_view.display_top_lists(
list_type=ns_parser.list_type,
exchange=ns_parser.exchange,
num_to_show=ns_parser.limit,
export=ns_parser.export,
sheet_name=" ".join(ns_parser.sheet_name)
if ns_parser.sheet_name
else None,
)

View File

@@ -1,132 +0,0 @@
"""Ally Model"""
__docformat__ = "numpy"
import logging
import ally
import pandas as pd
from openbb_terminal.decorators import log_start_end
logger = logging.getLogger(__name__)
@log_start_end(log=logger)
def get_holdings() -> pd.DataFrame:
"""Get holdings from Ally account in pandas df
Returns
-------
pd.DataFrame
Dataframe of positions
"""
a = ally.Ally()
return ally_positions_to_df(a.holdings(dataframe=True))
@log_start_end(log=logger)
def ally_positions_to_df(df: pd.DataFrame) -> pd.DataFrame:
"""Clean up ally holdings dataframe
Parameters
----------
df : pd.DataFrame
Input dataframe of holdings
Returns
-------
pd.DataFrame
Processed holdings
"""
names = {
"costbasis": "CostBasis",
"marketvalue": "MarketValue",
"sym": "Symbol",
"qty": "Quantity",
}
df = df.loc[:, ["qty", "costbasis", "marketvalue", "sym"]]
df[["qty", "costbasis", "marketvalue"]] = df[
["qty", "costbasis", "marketvalue"]
].astype(float)
df = df.rename(columns=names)
df["PnL"] = df["MarketValue"] - df["CostBasis"]
return df
@log_start_end(log=logger)
def get_history(limit: int = 50) -> pd.DataFrame:
"""Gets transaction history for the account."
Parameters
----------
limit : pd.DataFrame
Number of entries to return
Returns
-------
pd.DataFrame
Dataframe of transaction history
"""
a = ally.Ally()
df = a.history(dataframe=True)
return df.tail(limit)
@log_start_end(log=logger)
def get_balances() -> pd.DataFrame:
"""Gets balance details for the account."
Returns
-------
pd.DataFrame
Dataframe of transaction history
"""
a = ally.Ally()
return a.balances(dataframe=True)
@log_start_end(log=logger)
def get_stock_quote(symbol: str) -> pd.DataFrame:
"""Gets quote for stock ticker
Parameters
----------
symbol : str
Ticker to get. Can be in form of 'tick1,tick2...'
Returns
-------
pd.DataFrame
Dataframe of ticker quote
"""
a = ally.Ally()
return a.quote(
symbol,
fields=["last", "bid", "ask", "opn", "dollar_value", "chg", "vl"],
dataframe=True,
)
@log_start_end(log=logger)
def get_top_movers(
list_type: str = "", exchange: str = "", limit: int = 50
) -> pd.DataFrame:
"""
Gets top lists from ally Invest API. Documentation for parameters below:
https://www.ally.com/api/invest/documentation/market-toplists-get/
Parameters
----------
list_type : str
Which list to get data for
exchange : str
Which exchange to look at
limit: int
Number of top rows to return
Returns
-------
pd.DataFrame
DataFrame of top movers
"""
a = ally.Ally()
df = a.toplists(list_type, exchange, dataframe=True)
return df.tail(limit)

View File

@@ -1,156 +0,0 @@
"""Ally View"""
__docformat__ = "numpy"
import logging
import os
from typing import Optional
from openbb_terminal.decorators import log_start_end
from openbb_terminal.helper_funcs import export_data, print_rich_table
from openbb_terminal.portfolio.brokers.ally import ally_model
logger = logging.getLogger(__name__)
@log_start_end(log=logger)
def display_history(
limit: int = 15, export: str = "", sheet_name: Optional[str] = None
) -> None:
history = ally_model.get_history(limit)
show_history = history[["amount", "date", "symbol", "transactiontype", "quantity"]]
print_rich_table(
show_history,
headers=list(show_history.columns),
show_index=False,
title="Ally History",
export=bool(export),
)
export_data(
export,
os.path.dirname(os.path.abspath(__file__)),
"ally_history",
history,
sheet_name,
)
@log_start_end(log=logger)
def display_holdings(export: str = "", sheet_name: Optional[str] = None) -> None:
"""Display holdings from ally account
Parameters
----------
export : str, optional
Format to export data, by default ""
"""
holdings = ally_model.get_holdings()
holdings = holdings.set_index("Symbol")
print_rich_table(
holdings,
headers=list(holdings.columns),
show_index=True,
title="Ally Holdings",
export=bool(export),
)
export_data(
export,
os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))),
"ally_holdings",
holdings,
sheet_name,
)
@log_start_end(log=logger)
def display_balances(export: str = "", sheet_name: Optional[str] = None) -> None:
"""Display balances from ally account
Parameters
----------
export : str, optional
Format to export data, by default ""
"""
balances = ally_model.get_balances()
# Export data here before picking out certain columns
export_data(
export,
os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))),
"ally_balances",
balances,
sheet_name,
)
# Pick which balances to show
balances = balances[
[
"accountvalue",
"buyingpower.stock",
"money.cash",
"securities.stocks",
"securities.total",
]
]
print_rich_table(
balances,
headers=list(balances.columns),
show_index=False,
title="Ally Balances",
export=bool(export),
)
@log_start_end(log=logger)
def display_stock_quote(symbol: str) -> None:
"""Displays stock quote for ticker/tickers
Parameters
----------
ticker : str
Ticker to get. Can be in form of 'tick1,tick2...'
"""
quote = ally_model.get_stock_quote(symbol)
print_rich_table(
quote, headers=list(quote.columns), show_index=True, title="Stock Quote"
)
@log_start_end(log=logger)
def display_top_lists(
list_type: str = "",
exchange: str = "",
limit: int = 20,
export: str = "",
sheet_name: Optional[str] = None,
):
"""
Display top lists from ally Invest API. Documentation for parameters below:
https://www.ally.com/api/invest/documentation/market-toplists-get/
Parameters
----------
list_type : str
Which list to get data for
exchange : str
Which exchange to look at
limit : int, optional
Number of top rows to show, by default 20
export : str, optional
Format to export data, by default ""
"""
movers = ally_model.get_top_movers(list_type, exchange, limit)
print_rich_table(
movers,
headers=list(movers.columns),
show_index=True,
title="Ally Top Lists",
export=bool(export),
)
export_data(
export,
os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))),
"ally_movers",
movers,
sheet_name,
)

View File

@@ -10,7 +10,6 @@ from openbb_terminal.custom_prompt_toolkit import NestedCompleter
from openbb_terminal.decorators import log_start_end
from openbb_terminal.menu import session
from openbb_terminal.parent_classes import BaseController
from openbb_terminal.portfolio.brokers.ally import ally_controller
from openbb_terminal.portfolio.brokers.coinbase import coinbase_controller
from openbb_terminal.portfolio.brokers.degiro import degiro_controller
from openbb_terminal.portfolio.brokers.robinhood import robinhood_controller
@@ -42,7 +41,6 @@ class BrokersController(BaseController):
def print_help(self):
"""Print help"""
mt = MenuText("portfolio/bro/")
mt.add_menu("ally")
mt.add_menu("degiro")
mt.add_menu("rh")
mt.add_menu("cb")
@@ -53,11 +51,6 @@ class BrokersController(BaseController):
"""Process degiro command."""
self.queue = self.load_class(degiro_controller.DegiroController, self.queue)
@log_start_end(log=logger)
def call_ally(self, _):
"""Process ally command."""
self.queue = self.load_class(ally_controller.AllyController, self.queue)
@log_start_end(log=logger)
def call_rh(self, _):
"""Process rh command."""

View File

@@ -19,8 +19,8 @@
"import numpy as np\n",
"import datetime\n",
"\n",
"from IPython.display import HTML \n",
" \n",
"from IPython.display import HTML\n",
"\n",
"import openbb_terminal.config_terminal as cfg\n",
"from openbb_terminal.reports import widget_helpers as widgets\n",
"from openbb_terminal.sdk import openbb\n",

View File

@@ -351,7 +351,6 @@ class OpenBBSDK:
`mykeys`: Get currently set API keys.\n
`news`: Set News key\n
`oanda`: Set Oanda key\n
`openbb`: Set OpenBB Personal Access Token.\n
`polygon`: Set Polygon key\n
`quandl`: Set Quandl key\n
`reddit`: Set Reddit key\n

View File

@@ -7,7 +7,7 @@ import logging
import os
import os.path
from pathlib import Path
from typing import List, Optional
from typing import List, Optional, Union
# IMPORTATION THIRDPARTY
import pytz
@@ -19,8 +19,11 @@ from openbb_terminal.core.config.paths import (
SETTINGS_ENV_FILE,
USER_DATA_SOURCES_DEFAULT_FILE,
)
from openbb_terminal.core.session.current_user import get_current_user
from openbb_terminal.core.session.preferences_handler import set_preference
from openbb_terminal.core.session.current_user import (
get_current_user,
set_preference,
)
from openbb_terminal.core.session.env_handler import write_to_dotenv
from openbb_terminal.custom_prompt_toolkit import NestedCompleter
from openbb_terminal.decorators import log_start_end
from openbb_terminal.helper_funcs import (
@@ -193,6 +196,20 @@ class SettingsController(BaseController):
mt.add_param("_tk", current_user.preferences.TOOLBAR_TWEET_NEWS_KEYWORDS)
console.print(text=mt.menu_text, menu="Settings")
@staticmethod
def set_and_save_preference(name: str, value: Union[bool, Path, str]):
"""Set preference and write to .env
Parameters
----------
name : str
Preference name
value : Union[bool, Path, str]
Preference value
"""
set_preference(name, value)
write_to_dotenv("OPENBB_" + name, str(value))
@log_start_end(log=logger)
def call_colors(self, other_args: List[str]):
"""Process colors command"""
@@ -227,7 +244,7 @@ class SettingsController(BaseController):
)
ns_parser = self.parse_simple_args(parser, other_args)
if ns_parser:
set_preference(
self.set_and_save_preference(
"USE_DATETIME", not get_current_user().preferences.USE_DATETIME
)
@@ -253,7 +270,9 @@ class SettingsController(BaseController):
ns_parser = self.parse_simple_args(parser, other_args)
if ns_parser:
if os.path.exists(ns_parser.file):
set_preference("PREFERRED_DATA_SOURCE_FILE", ns_parser.file)
self.set_and_save_preference(
"PREFERRED_DATA_SOURCE_FILE", ns_parser.file
)
console.print("[green]Sources file changed successfully![/green]")
else:
console.print("[red]Couldn't find the sources file![/red]")
@@ -269,7 +288,7 @@ class SettingsController(BaseController):
)
ns_parser = self.parse_simple_args(parser, other_args)
if ns_parser:
set_preference(
self.set_and_save_preference(
"USE_PLOT_AUTOSCALING",
not get_current_user().preferences.USE_PLOT_AUTOSCALING,
)
@@ -295,7 +314,7 @@ class SettingsController(BaseController):
other_args.insert(0, "-v")
ns_parser = self.parse_simple_args(parser, other_args)
if ns_parser and ns_parser.value:
set_preference("PLOT_DPI", ns_parser.value)
self.set_and_save_preference("PLOT_DPI", ns_parser.value)
@log_start_end(log=logger)
def call_height(self, other_args: List[str]):
@@ -318,7 +337,7 @@ class SettingsController(BaseController):
other_args.insert(0, "-v")
ns_parser = self.parse_simple_args(parser, other_args)
if ns_parser:
set_preference("PLOT_HEIGHT", ns_parser.value)
self.set_and_save_preference("PLOT_HEIGHT", ns_parser.value)
@log_start_end(log=logger)
def call_width(self, other_args: List[str]):
@@ -341,7 +360,7 @@ class SettingsController(BaseController):
other_args.insert(0, "-v")
ns_parser = self.parse_simple_args(parser, other_args)
if ns_parser:
set_preference("PLOT_WIDTH", ns_parser.value)
self.set_and_save_preference("PLOT_WIDTH", ns_parser.value)
@log_start_end(log=logger)
def call_pheight(self, other_args: List[str]):
@@ -363,7 +382,7 @@ class SettingsController(BaseController):
other_args.insert(0, "-v")
ns_parser = self.parse_simple_args(parser, other_args)
if ns_parser:
set_preference("PLOT_HEIGHT_PERCENTAGE", ns_parser.value)
self.set_and_save_preference("PLOT_HEIGHT_PERCENTAGE", ns_parser.value)
@log_start_end(log=logger)
def call_pwidth(self, other_args: List[str]):
@@ -385,7 +404,7 @@ class SettingsController(BaseController):
other_args.insert(0, "-v")
ns_parser = self.parse_simple_args(parser, other_args)
if ns_parser:
set_preference("PLOT_WIDTH_PERCENTAGE", ns_parser.value)
self.set_and_save_preference("PLOT_WIDTH_PERCENTAGE", ns_parser.value)
@log_start_end(log=logger)
def call_monitor(self, other_args: List[str]):
@@ -407,7 +426,7 @@ class SettingsController(BaseController):
other_args.insert(0, "-v")
ns_parser = self.parse_simple_args(parser, other_args)
if ns_parser:
set_preference("MONITOR", ns_parser.value)
self.set_and_save_preference("MONITOR", ns_parser.value)
@log_start_end(log=logger)
def call_backend(self, other_args: List[str]):
@@ -429,7 +448,7 @@ class SettingsController(BaseController):
other_args.insert(0, "-v")
ns_parser = self.parse_simple_args(parser, other_args)
if ns_parser:
set_preference("BACKEND", ns_parser.value)
self.set_and_save_preference("BACKEND", ns_parser.value)
@log_start_end(log=logger)
def call_lang(self, other_args: List[str]):
@@ -454,7 +473,7 @@ class SettingsController(BaseController):
ns_parser = self.parse_simple_args(parser, other_args)
if ns_parser:
if ns_parser.value:
set_preference("USE_LANGUAGE", ns_parser.value)
self.set_and_save_preference("USE_LANGUAGE", ns_parser.value)
else:
console.print(
f"Languages available: {', '.join(self.languages_available)}"
@@ -484,7 +503,7 @@ class SettingsController(BaseController):
ns_parser = self.parse_simple_args(parser, other_args)
if ns_parser and ns_parser.timezone:
set_preference("TIMEZONE", ns_parser.timezone)
self.set_and_save_preference("TIMEZONE", ns_parser.timezone)
@log_start_end(log=logger)
def call_flair(self, other_args: List[str]):
@@ -512,7 +531,7 @@ class SettingsController(BaseController):
else:
ns_parser.emoji = " ".join(ns_parser.emoji)
set_preference("FLAIR", ns_parser.emoji)
self.set_and_save_preference("FLAIR", ns_parser.emoji)
@log_start_end(log=logger)
def call_userdata(self, other_args: List[str]):
@@ -550,7 +569,7 @@ class SettingsController(BaseController):
console.print(
f"User data to be saved in the default folder: '{default_path}'"
)
set_preference("USER_DATA_DIRECTORY", default_path)
self.set_and_save_preference("USER_DATA_DIRECTORY", default_path)
success_userdata = True
else:
# If the path selected does not start from the user root, give relative location from root
@@ -564,7 +583,9 @@ class SettingsController(BaseController):
console.print(
f"User data to be saved in the selected folder: '{userdata_path}'"
)
set_preference("USER_DATA_DIRECTORY", userdata_path)
self.set_and_save_preference(
"USER_DATA_DIRECTORY", userdata_path
)
success_userdata = True
else:
console.print(
@@ -581,7 +602,9 @@ class SettingsController(BaseController):
console.print(
f"[green]Folder '{userdata_path}' successfully created.[/green]"
)
set_preference("USER_DATA_DIRECTORY", userdata_path)
self.set_and_save_preference(
"USER_DATA_DIRECTORY", userdata_path
)
else:
# Do not update userdata_folder path since we will keep the same as before
console.print(
@@ -607,7 +630,7 @@ class SettingsController(BaseController):
current_user = get_current_user()
if current_user.preferences.TOOLBAR_TWEET_NEWS:
console.print("Will take effect when running terminal next.")
set_preference(
self.set_and_save_preference(
"TOOLBAR_TWEET_NEWS",
not get_current_user().preferences.TOOLBAR_TWEET_NEWS,
)
@@ -659,25 +682,25 @@ class SettingsController(BaseController):
ns_parser = self.parse_known_args_and_warn(parser, other_args)
if ns_parser:
if ns_parser.time:
set_preference(
self.set_and_save_preference(
"TOOLBAR_TWEET_NEWS_SECONDS_BETWEEN_UPDATES",
str(ns_parser.time),
)
if ns_parser.number:
set_preference(
self.set_and_save_preference(
"TOOLBAR_TWEET_NEWS_NUM_LAST_TWEETS_TO_READ",
str(ns_parser.number),
)
if ns_parser.accounts:
set_preference(
self.set_and_save_preference(
"TOOLBAR_TWEET_NEWS_ACCOUNTS_TO_TRACK",
str(ns_parser.accounts),
)
if ns_parser.keywords:
set_preference(
self.set_and_save_preference(
"TOOLBAR_TWEET_NEWS_KEYWORDS",
str(" ".join(ns_parser.keywords)),
)

View File

@@ -28,7 +28,7 @@ from openbb_terminal.helper_funcs import (
from openbb_terminal.menu import session
from openbb_terminal.parent_classes import StockBaseController
from openbb_terminal.rich_config import MenuText, console
from openbb_terminal.stocks.behavioural_analysis import cramer_view, finnhub_view
from openbb_terminal.stocks.behavioural_analysis import finnhub_view
# pylint:disable=R0904,C0302
@@ -827,57 +827,3 @@ class BehaviouralAnalysisController(StockBaseController):
)
else:
console.print("No ticker loaded. Please load using 'load <ticker>'\n")
def call_jcdr(self, other_args: List[str]):
"""Process jcdr command."""
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="jcdr",
description="""
Show daily cramer recommendation
""",
)
parser.add_argument(
"-i",
"--inverse",
default=False,
action="store_true",
help="Show inverse recommendation",
dest="inverse",
)
ns_parser = self.parse_known_args_and_warn(
parser, other_args, export_allowed=EXPORT_ONLY_RAW_DATA_ALLOWED
)
if ns_parser:
cramer_view.display_cramer_daily(inverse=ns_parser.inverse)
@log_start_end(log=logger)
def call_jctr(self, other_args: List[str]):
"""Process jctr command."""
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="jctr",
description="""
Show cramer recommendation for loaded ticker
""",
)
ns_parser = self.parse_known_args_and_warn(
parser,
other_args,
export_allowed=EXPORT_BOTH_RAW_DATA_AND_FIGURES,
raw=True,
)
if ns_parser:
if self.ticker:
cramer_view.display_cramer_ticker(
symbol=self.ticker, raw=ns_parser.raw, export=ns_parser.export
)
else:
console.print(
"[red]No ticker loaded. Please use load <ticker> first.\n[/red]"
)

View File

@@ -1,119 +0,0 @@
"""Cramer Model"""
__docformat__ = "numpy"
import logging
import os
import re
import certifi
import numpy as np
import pandas as pd
import yfinance as yf
from bs4 import BeautifulSoup
from openbb_terminal.decorators import log_start_end
from openbb_terminal.helper_funcs import request
logger = logging.getLogger(__name__)
# Necessary only for installer to identify where SSL certs are
os.environ["REQUESTS_CA_BUNDLE"] = certifi.where()
os.environ["SSL_CERT_FILE"] = certifi.where()
@log_start_end(log=logger)
def get_cramer_daily(inverse: bool = True) -> pd.DataFrame:
"""Scrape the daily recommendations of Jim Cramer
Parameters
----------
inverse: bool
Whether to include inverse
Returns
-------
pd.DataFrame
Datafreme of daily Cramer recommendations
"""
link = (
"https://madmoney.thestreet.com/screener/index.cfm?showview=stocks&showrows=500"
)
r = request(
link,
method="POST",
headers={
"Content-Type": "application/x-www-form-urlencoded",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) "
"AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.3 Safari/605.1.15",
},
)
if r.status_code != 200:
return pd.DataFrame()
soup = BeautifulSoup(r.text, "html.parser")
table = soup.find_all("table")[0]
trs = table.find_all("tr")
recs = {
"1": "Sell",
"2": "Sell",
"3": "Hold",
"4": "Buy",
"5": "Buy",
}
rec = [recs[tr.find_all("td")[3].find("img")["src"][-5]] for tr in trs[1:]]
df = pd.read_html(r.text)[0]
df["Symbol"] = df.Company.apply(lambda x: re.findall(r"[\w]+", x)[-1])
last_price = [
round(
yf.download(ticker, period="1d", interval="1h", progress=False)["Close"][
-1
],
2,
)
for ticker in df.Symbol
]
df["LastPrice"] = last_price
df["Price"] = df.Price.apply(lambda x: float(x.strip("$")))
df = df.drop(columns=["Segment", "Call", "Portfolio"])
df["Change (%)"] = 100 * np.round((df["LastPrice"] - df["Price"]) / df.LastPrice, 4)
df["Recommendation"] = rec
df["Company"] = df.apply(lambda x: x.Company.replace(f"({x.Symbol})", ""), axis=1)
cols = [
"Date",
"Company",
"Symbol",
"Price",
"LastPrice",
"Change (%)",
"Recommendation",
]
if inverse:
df["InverseCramer"] = df["Recommendation"].apply(
lambda x: ["Buy", "Sell"][x == "Buy"]
)
cols.append("InverseCramer")
return df[cols]
@log_start_end(log=logger)
def get_cramer_ticker(symbol: str) -> pd.DataFrame:
"""Get cramer recommendations from beginning of year for given ticker
Parameters
----------
symbol: str
Ticker to get recommendations for
Returns
-------
pd.DataFrame
Dataframe with dates and recommendations
"""
link = "https://raw.githubusercontent.com/jmaslek/InverseCramer/main/AllRecommendations.csv"
df = pd.read_csv(link, index_col=0)
df["Date"] = pd.to_datetime(df["Date"].apply(lambda x: x + "/2022"))
return df[df.Symbol == symbol].reset_index(drop=True)

View File

@@ -1,136 +0,0 @@
"""Cramer View"""
__docformat__ = "numpy"
import logging
import os
from datetime import datetime
from typing import Optional, Union
import yfinance
from openbb_terminal import OpenBBFigure, theme
from openbb_terminal.decorators import log_start_end
from openbb_terminal.helper_funcs import export_data, print_rich_table
from openbb_terminal.rich_config import console
from openbb_terminal.stocks.behavioural_analysis import cramer_model
logger = logging.getLogger(__name__)
@log_start_end(log=logger)
def display_cramer_daily(
inverse: bool = True, export: str = "", sheet_name: Optional[str] = None
):
"""Display Jim Cramer daily recommendations
Parameters
----------
inverse: bool
Include inverse recommendation
sheet_name: str
Optionally specify the name of the sheet the data is exported to.
export: str
Format to export data
"""
recs = cramer_model.get_cramer_daily(inverse)
if recs.empty:
console.print("[red]Error getting request.\n[/red]")
return
date = recs.Date[0]
recs = recs.drop(columns=["Date"])
if datetime.today().strftime("%m-%d") != datetime.strptime(
date.replace("/", "-"), "%m-%d"
):
console.print(
"""
\n[yellow]Warning[/yellow]: We noticed Jim Crammer recommendation data has not been updated for a while, \
and we're investigating on finding a replacement.
""",
)
print_rich_table(
recs, title=f"Jim Cramer Recommendations for {date}", export=bool(export)
)
export_data(
export,
os.path.dirname(os.path.abspath(__file__)),
"cramer",
recs,
sheet_name,
)
@log_start_end(log=logger)
def display_cramer_ticker(
symbol: str,
raw: bool = False,
export: str = "",
sheet_name: Optional[str] = None,
external_axes: bool = False,
) -> Union[None, OpenBBFigure]:
"""Display ticker close with Cramer recommendations
Parameters
----------
symbol: str
Stock ticker
raw: bool
Display raw data
sheet_name: str
Optionally specify the name of the sheet the data is exported to.
export: str
Format to export data
external_axes : bool, optional
Whether to return the figure object or not, by default False
"""
df = cramer_model.get_cramer_ticker(symbol)
if df.empty:
return console.print(f"No recommendations found for {symbol}.\n")
fig = OpenBBFigure(xaxis_title="Date", yaxis_title="Price")
fig.set_title(f"{symbol.upper()} Close With Cramer Recommendations")
close_prices = yfinance.download(symbol, start="2022-01-01", progress=False)[
"Adj Close"
]
fig.add_scatter(
x=close_prices.index,
y=close_prices,
mode="lines",
name="Close",
showlegend=False,
line=dict(color=theme.line_color),
)
color_map = {"Buy": theme.up_color, "Sell": theme.down_color}
for name, group in df.groupby("Recommendation"):
fig.add_scatter(
x=group.Date,
y=group.Price,
mode="markers",
name=name,
marker=dict(color=color_map[name], size=10),
)
if raw:
df["Date"] = df["Date"].apply(lambda x: x.strftime("%Y-%m-%d"))
print_rich_table(
df, title=f"Jim Cramer Recommendations for {symbol}", export=bool(export)
)
export_data(
export,
os.path.dirname(os.path.abspath(__file__)),
"jctr",
df,
sheet_name,
fig,
)
fig.update_layout(legend=dict(yanchor="top", y=1, xanchor="right", x=1))
return fig.show(external=external_axes)

View File

@@ -43,7 +43,6 @@ from openbb_terminal.stocks.options.options_view import (
plot_voi,
plot_vol,
)
from openbb_terminal.stocks.options.pricing import pricing_controller
from openbb_terminal.stocks.options.screen import (
screener_controller,
syncretism_model,
@@ -80,8 +79,6 @@ class OptionsController(BaseController):
"grhist",
"unu",
"plot",
"parity",
"binom",
"vsurf",
"greeks",
"eodchain",
@@ -232,8 +229,6 @@ class OptionsController(BaseController):
self.choices["grhist"]["-s"] = "--strike"
self.choices["grhist"]["--strike"] = {str(c): {} for c in strike}
self.choices["grhist"]["-s"] = "--strike"
self.choices["binom"]["--strike"] = {str(c): {} for c in strike}
self.choices["binom"]["-s"] = "--strike"
self.choices["chains"]["--display"] = {
str(c): {} for c in self.chain.columns
@@ -284,12 +279,9 @@ class OptionsController(BaseController):
mt.add_cmd("vsurf", self.ticker and self.selected_date)
mt.add_cmd("grhist", self.ticker and self.selected_date)
mt.add_cmd("plot", self.ticker and self.selected_date)
mt.add_cmd("parity", self.ticker and self.selected_date)
mt.add_cmd("binom", self.ticker and self.selected_date)
mt.add_cmd("greeks", self.ticker and self.selected_date)
mt.add_cmd("eodchain", self.ticker and self.selected_date)
mt.add_raw("\n")
mt.add_menu("pricing", self.ticker and self.selected_date)
mt.add_menu("hedge", self.ticker and self.selected_date)
console.print(text=mt.menu_text, menu="Stocks - Options")
@@ -1415,162 +1407,6 @@ class OptionsController(BaseController):
show_all=ns_parser.all,
)
@log_start_end(log=logger)
def call_parity(self, other_args: List[str]):
"""Process parity command"""
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="parity",
description="Shows whether options are over or under valued",
)
parser.add_argument(
"-p",
"--put",
action="store_true",
default=False,
dest="put",
help="Shows puts instead of calls",
)
parser.add_argument(
"-a",
"--ask",
action="store_true",
default=False,
dest="ask",
help="Use ask price instead of lastPrice",
)
parser.add_argument(
"-m",
"--min",
type=float,
default=None,
dest="mini",
help="Minimum strike price shown",
)
parser.add_argument(
"-M",
"--max",
type=float,
default=None,
dest="maxi",
help="Maximum strike price shown",
)
ns_parser = self.parse_known_args_and_warn(
parser, other_args, EXPORT_ONLY_RAW_DATA_ALLOWED
)
if ns_parser:
if self.ticker:
if self.selected_date:
yfinance_view.show_parity(
self.ticker,
self.selected_date,
ns_parser.put,
ns_parser.ask,
ns_parser.mini,
ns_parser.maxi,
ns_parser.export,
)
else:
console.print("No expiry loaded. First use `exp {expiry date}`")
else:
console.print("No ticker loaded. First use `load <ticker>`")
@log_start_end(log=logger)
def call_binom(self, other_args: List[str]):
"""Process binom command"""
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="binom",
description="Gives the option value using binomial option valuation",
)
parser.add_argument(
"-s",
"--strike",
type=float,
default=0,
dest="strike",
help="Strike price for option shown",
)
parser.add_argument(
"-p",
"--put",
action="store_true",
default=False,
dest="put",
help="Value a put instead of a call",
)
parser.add_argument(
"-e",
"--european",
action="store_true",
default=False,
dest="europe",
help="Value a European option instead of an American one",
)
parser.add_argument(
"-x",
"--xlsx",
action="store_true",
default=False,
dest="export",
help="Export an excel spreadsheet with binomial pricing data",
)
parser.add_argument(
"--plot",
action="store_true",
default=False,
dest="plot",
help="Plot expected ending values",
)
parser.add_argument(
"-v",
"--volatility",
type=float,
default=None,
dest="volatility",
help="Underlying asset annualized volatility. Historical volatility used if not supplied.",
)
if other_args and "-" not in other_args[0][0]:
other_args.insert(0, "-s")
ns_parser = self.parse_known_args_and_warn(parser, other_args)
if ns_parser:
if self.ticker:
if self.selected_date:
yfinance_view.show_binom(
self.ticker,
self.selected_date,
ns_parser.strike,
ns_parser.put,
ns_parser.europe,
ns_parser.export,
ns_parser.plot,
ns_parser.volatility,
)
else:
console.print("No expiry loaded. First use `exp {expiry date}`")
else:
console.print("No ticker loaded. First use `load <ticker>`")
@log_start_end(log=logger)
def call_pricing(self, _):
"""Process pricing command"""
if self.ticker:
if self.selected_date:
self.queue = self.load_class(
pricing_controller.PricingController,
self.ticker,
self.selected_date,
self.prices,
self.queue,
)
else:
console.print("No expiry loaded. First use `exp {expiry date}`")
else:
console.print("No ticker loaded. First use `load <ticker>`")
@log_start_end(log=logger)
def call_hedge(self, _):
"""Process hedge command"""

View File

@@ -1,228 +0,0 @@
""" Pricing Controller Module """
__docformat__ = "numpy"
import argparse
import logging
from typing import List, Optional
import pandas as pd
from openbb_terminal.core.session.current_user import get_current_user
from openbb_terminal.custom_prompt_toolkit import NestedCompleter
from openbb_terminal.decorators import log_start_end
from openbb_terminal.helper_funcs import print_rich_table
from openbb_terminal.menu import session
from openbb_terminal.parent_classes import BaseController
from openbb_terminal.rich_config import MenuText, console
from openbb_terminal.stocks.options import yfinance_view
logger = logging.getLogger(__name__)
class PricingController(BaseController):
"""Pricing Controller class"""
CHOICES_COMMANDS = [
"add",
"rmv",
"show",
"rnval",
]
PATH = "/stocks/options/pricing/"
CHOICES_GENERATION = True
def __init__(
self,
ticker: str,
selected_date: str,
prices: pd.DataFrame,
queue: Optional[List[str]] = None,
):
"""Constructor"""
super().__init__(queue)
self.ticker = ticker
self.selected_date = selected_date
self.prices = prices
if session and get_current_user().preferences.USE_PROMPT_TOOLKIT:
choices: dict = self.choices_default
self.completer = NestedCompleter.from_nested_dict(choices)
def print_help(self):
"""Print help"""
mt = MenuText("stocks/options/pricing/")
mt.add_param("_ticker", self.ticker or "")
mt.add_param("_expiry", self.selected_date or "")
mt.add_raw("\n")
mt.add_cmd("add")
mt.add_cmd("rmv")
mt.add_raw("\n")
mt.add_cmd("show")
mt.add_cmd("rnval")
console.print(text=mt.menu_text, menu="Stocks - Options - Pricing")
def custom_reset(self):
"""Class specific component of reset command"""
if self.ticker:
if self.selected_date:
return [
"stocks",
f"load {self.ticker}",
"options",
f"exp -d {self.selected_date}",
"pricing",
]
return ["stocks", f"load {self.ticker}", "options", "payoff"]
return []
@log_start_end(log=logger)
def call_add(self, other_args: List[str]):
"""Process add command"""
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="add",
description="Adds a price to the list",
)
parser.add_argument(
"-p",
"--price",
type=float,
required="-h" not in other_args,
dest="price",
help="Projected price of the stock at the expiration date",
)
parser.add_argument(
"-c",
"--chance",
type=float,
required="-h" not in other_args,
dest="chance",
help="Chance that the stock is at a given projected price",
)
if other_args and "-" not in other_args[0][0]:
other_args.insert(0, "-p")
ns_parser = self.parse_known_args_and_warn(parser, other_args)
if ns_parser:
if ns_parser.price in self.prices["Price"].to_list():
df = self.prices[(self.prices["Price"] != ns_parser.price)]
else:
df = self.prices
new = {"Price": ns_parser.price, "Chance": ns_parser.chance}
df = df.append(new, ignore_index=True)
self.prices = df.sort_values("Price")
@log_start_end(log=logger)
def call_rmv(self, other_args: List[str]):
"""Process rmv command"""
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="rmv",
description="Removes a price from the list",
)
parser.add_argument(
"-p",
"--price",
type=float,
required="-h" not in other_args and "-a" not in other_args,
dest="price",
help="Price you want to remove from the list",
)
parser.add_argument(
"-a",
"--all",
action="store_true",
default=False,
dest="all",
help="Remove all prices from the list",
)
if other_args and "-" not in other_args[0][0]:
other_args.insert(0, "-p")
ns_parser = self.parse_known_args_and_warn(parser, other_args)
if ns_parser:
if ns_parser.all:
self.prices = pd.DataFrame(columns=["Price", "Chance"])
else:
self.prices = self.prices[(self.prices["Price"] != ns_parser.price)]
@log_start_end(log=logger)
def call_show(self, other_args):
"""Process show command"""
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="show",
description="Display prices",
)
ns_parser = self.parse_known_args_and_warn(parser, other_args)
if ns_parser:
print_rich_table(
self.prices,
headers=list(self.prices.columns),
show_index=False,
title=f"Estimated price(s) of {self.ticker} at {self.selected_date}",
)
@log_start_end(log=logger)
def call_rnval(self, other_args: List[str]):
"""Process rnval command"""
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="rnval",
description="The risk neutral value of the options",
)
parser.add_argument(
"-p",
"--put",
action="store_true",
default=False,
help="Show puts instead of calls",
)
parser.add_argument(
"-m",
"--min",
type=float,
default=None,
dest="mini",
help="Minimum strike price shown",
)
parser.add_argument(
"-M",
"--max",
type=float,
default=None,
dest="maxi",
help="Maximum strike price shown",
)
parser.add_argument(
"-r",
"--risk",
type=float,
default=None,
dest="risk",
help="The risk-free rate to use",
)
ns_parser = self.parse_known_args_and_warn(parser, other_args)
if ns_parser:
if self.ticker:
if self.selected_date:
if sum(self.prices["Chance"]) == 1:
yfinance_view.risk_neutral_vals(
self.ticker,
self.selected_date,
self.prices,
ns_parser.put,
ns_parser.mini,
ns_parser.maxi,
ns_parser.risk,
)
else:
console.print("Total chances must equal one\n")
else:
console.print("No expiry loaded. First use `exp {expiry date}`\n")
else:
console.print("No ticker loaded. First use `load <ticker>`\n")

View File

@@ -2,15 +2,13 @@
__docformat__ = "numpy"
import logging
import math
from datetime import date, datetime, timedelta
from typing import Any, Dict, List, Optional, Tuple
from datetime import datetime
from typing import Any, Dict, List, Tuple
import pandas as pd
import yfinance as yf
from openbb_terminal.decorators import log_start_end
from openbb_terminal.helper_funcs import get_rf
from openbb_terminal.rich_config import console, optional_rich_track
logger = logging.getLogger(__name__)
@@ -288,102 +286,6 @@ def get_iv_surface(symbol: str) -> pd.DataFrame:
return vol_df
@log_start_end(log=logger)
def get_binom(
symbol: str,
expiry: str,
strike: float = 0,
put: bool = False,
europe: bool = False,
vol: Optional[float] = None,
):
"""Gets binomial pricing for options
Parameters
----------
symbol : str
The ticker symbol of the option's underlying asset
expiry : str
The expiration for the option
strike : float
The strike price for the option
put : bool
Value a put instead of a call
europe : bool
Value a European option instead of an American option
vol : float
The annualized volatility for the underlying asset
"""
# Base variables to calculate values
info = get_info(symbol)
price = yf.Ticker(symbol).fast_info.last_price
if vol is None:
closings = get_closing(symbol)
vol = (closings / closings.shift()).std() * (252**0.5)
div_yield = (
info["trailingAnnualDividendYield"]
if info["trailingAnnualDividendYield"] is not None
else 0
)
delta_t = 1 / 252
rf = get_rf()
exp_date = datetime.strptime(expiry, "%Y-%m-%d").date()
today = date.today()
days = (exp_date - today).days
# Binomial pricing specific variables
up = math.exp(vol * (delta_t**0.5))
down = 1 / up
prob_up = (math.exp((rf - div_yield) * delta_t) - down) / (up - down)
prob_down = 1 - prob_up
discount = math.exp(delta_t * rf)
und_vals: List[List[float]] = [[price]]
# Binomial tree for underlying values
for i in range(days):
cur_date = today + timedelta(days=i + 1)
if cur_date.weekday() < 5:
last = und_vals[-1]
new = [x * up for x in last]
new.append(last[-1] * down)
und_vals.append(new)
# Binomial tree for option values
opt_vals = (
[[max(strike - x, 0) for x in und_vals[-1]]]
if put
else [[max(x - strike, 0) for x in und_vals[-1]]]
)
j = 2
while len(opt_vals[0]) > 1:
new_vals = []
for i in range(len(opt_vals[0]) - 1):
if europe:
value = (
opt_vals[0][i] * prob_up + opt_vals[0][i + 1] * prob_down
) / discount
else:
if put:
value = max(
(opt_vals[0][i] * prob_up + opt_vals[0][i + 1] * prob_down)
/ discount,
strike - und_vals[-j][i],
)
else:
value = max(
(opt_vals[0][i] * prob_up + opt_vals[0][i + 1] * prob_down)
/ discount,
und_vals[-j][i] - strike,
)
new_vals.append(value)
opt_vals.insert(0, new_vals)
j += 1
return up, prob_up, discount, und_vals, opt_vals, days
@log_start_end(log=logger)
def get_last_price(symbol: str) -> float:
"""Get the last price from nasdaq

View File

@@ -4,17 +4,13 @@ __docformat__ = "numpy"
import logging
import os
import re
from datetime import date, datetime, timedelta
from typing import Any, Dict, List, Optional, Union
import numpy as np
import pandas as pd
from openpyxl import Workbook
from scipy.spatial import Delaunay
from scipy.stats import binom
from openbb_terminal import OpenBBFigure
from openbb_terminal.core.config.paths import MISCELLANEOUS_DIRECTORY
from openbb_terminal.core.plots.config.openbb_styles import (
PLT_3DMESH_COLORSCALE,
PLT_3DMESH_HOVERLABEL,
@@ -22,9 +18,7 @@ from openbb_terminal.core.plots.config.openbb_styles import (
)
from openbb_terminal.decorators import log_start_end
from openbb_terminal.helper_funcs import (
excel_columns,
export_data,
get_rf,
print_rich_table,
)
from openbb_terminal.rich_config import console
@@ -188,189 +182,6 @@ def plot_payoff(
return plot.show(external=external_axes)
@log_start_end(log=logger)
def show_parity(
symbol: str,
expiry: str,
put: bool = False,
ask: bool = False,
mini: Optional[float] = None,
maxi: Optional[float] = None,
export: str = "",
sheet_name: Optional[str] = None,
) -> None:
"""Prints options and whether they are under or over priced [Source: Yahoo Finance]
Parameters
----------
symbol : str
Ticker symbol to get expirations for
expiration : str
Expiration to use for options
put : bool
Whether to use puts or calls
ask : bool
Whether to use ask or lastPrice
mini : float
Minimum strike price to show
maxi : float
Maximum strike price to show
export : str
Export data
"""
r_date = datetime.strptime(expiry, "%Y-%m-%d").date()
delta = (r_date - date.today()).days
rate = ((1 + get_rf()) ** (delta / 365)) - 1
stock = get_price(symbol)
div_info = yfinance_model.get_dividend(symbol)
div_dts = div_info.index.values.tolist()
if div_dts:
last_div = pd.to_datetime(div_dts[-1])
avg_div = (
np.mean(div_info.to_list()[-4:])
if len(div_dts) > 3
else np.mean(div_info.to_list())
)
next_div = last_div + timedelta(days=91)
dividends = []
while next_div < datetime.strptime(expiry, "%Y-%m-%d"):
day_dif = (next_div - datetime.now()).days
dividends.append((avg_div, day_dif))
next_div += timedelta(days=91)
div_pvs = [x[0] / ((1 + get_rf()) ** (x[1] / 365)) for x in dividends]
pv_dividend = sum(div_pvs)
else:
pv_dividend = 0
chain = get_option_chain(symbol, expiry)
name = "ask" if ask else "lastPrice"
o_type = "put" if put else "call"
calls = chain.calls[["strike", name]].copy()
calls = calls.rename(columns={name: "callPrice"})
puts = chain.puts[["strike", name]].copy()
puts = puts.rename(columns={name: "putPrice"})
opts = pd.merge(calls, puts, on="strike")
opts = opts.dropna()
opts = opts.loc[opts["callPrice"] * opts["putPrice"] != 0]
opts["callParity"] = (
opts["putPrice"] + stock - (opts["strike"] / (1 + rate)) - pv_dividend
)
opts["putParity"] = (
(opts["strike"] / (1 + rate)) + opts["callPrice"] - stock + pv_dividend
)
diff = o_type + " Difference"
opts[diff] = opts[o_type + "Price"] - opts[o_type + "Parity"]
opts["distance"] = abs(stock - opts["strike"])
filtered = opts.copy()
if mini is None:
mini = filtered.strike.quantile(0.25)
if maxi is None:
maxi = filtered.strike.quantile(0.75)
filtered = filtered.loc[filtered["strike"] >= mini]
filtered = filtered.loc[filtered["strike"] <= maxi]
show = filtered[["strike", diff]].copy()
if ask:
console.print("Warning: Options with no current ask price not shown.\n")
print_rich_table(
show,
headers=[x.title() for x in show.columns],
show_index=False,
title=f"{symbol} Parity",
export=bool(export),
)
console.print(
"[yellow]Warning: Low volume options may be difficult to trade.[/yellow]"
)
export_data(
export,
os.path.dirname(os.path.abspath(__file__)),
"parity",
show,
sheet_name,
)
@log_start_end(log=logger)
def risk_neutral_vals(
symbol: str,
expiry: str,
data: pd.DataFrame,
put: bool = False,
mini: Optional[float] = None,
maxi: Optional[float] = None,
risk: Optional[float] = None,
) -> None:
"""Prints current options prices and risk neutral values [Source: Yahoo Finance]
Parameters
----------
symbol: str
Ticker symbol to get expirations for
expiry: str
Expiration to use for options
put: bool
Whether to use puts or calls
data: pd.DataFrame
Estimates for stocks prices and probabilities
mini: float
Minimum strike price to show
maxi: float
Maximum strike price to show
risk: float
The risk-free rate for the asset
"""
chain = (
get_option_chain(symbol, expiry).puts
if put
else get_option_chain(symbol, expiry).calls
)
r_date = datetime.strptime(expiry, "%Y-%m-%d").date()
delta = (r_date - date.today()).days
vals = []
if risk is None:
risk = get_rf()
for _, row in chain.iterrows():
vals.append(
[
row["strike"],
row["lastPrice"],
op_helpers.rn_payoff(row["strike"], data, put, delta, risk),
]
)
new_df = pd.DataFrame(vals, columns=["Strike", "Last Price", "Value"], dtype=float)
new_df["Difference"] = new_df["Last Price"] - new_df["Value"]
if mini is None:
mini = new_df.Strike.quantile(0.25)
if maxi is None:
maxi = new_df.Strike.quantile(0.75)
new_df = new_df[new_df["Strike"] >= mini]
new_df = new_df[new_df["Strike"] <= maxi]
print_rich_table(
new_df,
headers=[x.title() for x in new_df.columns],
show_index=False,
title="Risk Neutral Values",
)
@log_start_end(log=logger)
def plot_expected_prices(
und_vals: List[List[float]],
@@ -418,129 +229,6 @@ def plot_expected_prices(
return fig.show(external=external_axes)
@log_start_end(log=logger)
def export_binomial_calcs(
up: float,
prob_up: float,
discount: float,
und_vals: List[List[float]],
opt_vals: List[List[float]],
days: int,
symbol: str,
) -> None:
"""Create an excel spreadsheet with binomial tables for underlying asset value and option value
Parameters
----------
up : float
The stock's increase on an upward move
prob_up : float
The probability of an upward move
discount : float
The daily discount rate
und_vals : List[List[float]]
The underlying asset values at each step
opt_vals : List[List[float]]
The values for the option at each step
days : int
The number of days until the option expires
symbol : str
The ticker symbol for the company
"""
opts = excel_columns()
wb = Workbook()
ws = wb.active
ws["A1"] = "Up Move"
ws["B1"] = up
ws["A2"] = "Down Move"
ws["B2"] = 1 / up
ws["D1"] = "Prob Up"
ws["E1"] = prob_up
ws["D2"] = "Prob Down"
ws["E2"] = 1 - prob_up
ws["D3"] = "Discount"
ws["E3"] = discount
ws["A4"] = "Binomial Tree for Underlying Values"
for i, _ in enumerate(und_vals):
for j, _ in enumerate(und_vals[i]):
ws[f"{opts[i]}{j+5}"] = und_vals[i][j]
ws[f"A{days+7}"] = "Binomial Tree for Option Values"
for i, _ in enumerate(opt_vals):
for j, _ in enumerate(opt_vals[i]):
ws[f"{opts[i]}{j+8+days}"] = opt_vals[i][j]
trypath = str(
MISCELLANEOUS_DIRECTORY
/ "exports"
/ "stocks"
/ "options"
/ f"{symbol} {datetime.now()}.xlsx"
)
wb.save(trypath)
console.print(
f"Analysis ran for {symbol}\nPlease look in {trypath} for the file.\n"
)
@log_start_end(log=logger)
def show_binom(
symbol: str,
expiry: str,
strike: float = 0,
put: bool = False,
europe: bool = False,
export: str = "",
plot: bool = False,
vol: Optional[float] = None,
) -> None:
"""Get binomial pricing for option
Parameters
----------
symbol : str
The ticker symbol of the option's underlying asset
expiry : str
The expiration for the option
strike : float
The strike price for the option
put : bool
Value a put instead of a call
europe : bool
Value a European option instead of an American option
export : str
Export the options data to an excel spreadsheet
plot : bool
Show a graph of expected ending prices
vol : float
The annualized volatility for the underlying asset
"""
fig = OpenBBFigure()
up, prob_up, discount, und_vals, opt_vals, days = yfinance_model.get_binom(
symbol, expiry, strike, put, europe, vol
)
if plot or fig.is_image_export(export):
fig = plot_expected_prices(und_vals, prob_up, symbol, expiry, True)
export_data(
export,
os.path.dirname(os.path.abspath(__file__)),
"binomial",
figure=fig,
)
if export:
export_binomial_calcs(up, prob_up, discount, und_vals, opt_vals, days, symbol)
option = "put" if put else "call"
console.print(
f"{symbol} {option} at ${strike:.2f} expiring on {expiry} is worth ${opt_vals[0][0]:.2f}\n"
)
@log_start_end(log=logger)
def display_vol_surface(
symbol: str,

View File

@@ -90,8 +90,6 @@ class StocksController(StockBaseController):
if session and get_current_user().preferences.USE_PROMPT_TOOLKIT:
choices: dict = self.choices_default
choices["load"]["--file"] = {c: None for c in self.USER_IMPORT_FILES}
choices["load"]["-f"] = "--file"
self.completer = NestedCompleter.from_nested_dict(choices)
def print_help(self):

View File

@@ -28,15 +28,15 @@ def display_quote(symbol: str, export: str = "", sheet_name: Optional[str] = Non
quote = stocks_model.get_quote(symbol)
if quote.empty:
console.print("[red]Data not found[/red]\n")
else:
print_rich_table(
quote,
headers=["Value"],
title=f"{symbol.upper()} Quote",
index_name="Info",
show_index=True,
export=bool(export),
)
return
print_rich_table(
quote,
headers=["Value"],
title=f"{symbol.upper()} Quote",
index_name="Info",
show_index=True,
export=bool(export),
)
export_data(
export,

View File

@@ -137,7 +137,6 @@ class TechnicalAnalysisController(StockBaseController):
mt.add_raw("\n")
mt.add_cmd("recom")
mt.add_cmd("summary")
mt.add_cmd("tv")
mt.add_cmd("view")
mt.add_raw("\n")
mt.add_info("_overlap_")

View File

@@ -6,6 +6,7 @@ import logging
import os
import subprocess # nosec
import sys
import webbrowser
# IMPORTATION STANDARD
from contextlib import contextmanager
@@ -24,8 +25,11 @@ from openbb_terminal.config_terminal import LOGGING_COMMIT_HASH, VERSION
# IMPORTATION INTERNAL
from openbb_terminal.core.config.paths import SETTINGS_ENV_FILE
from openbb_terminal.core.plots.backend import plots_backend
from openbb_terminal.core.session.current_user import get_current_user
from openbb_terminal.core.session.preferences_handler import set_preference
from openbb_terminal.core.session.current_user import (
get_current_user,
set_preference,
)
from openbb_terminal.core.session.env_handler import write_to_dotenv
from openbb_terminal.helper_funcs import request
from openbb_terminal.rich_config import console
@@ -125,60 +129,60 @@ def update_terminal():
def open_openbb_documentation(
path, url="https://docs.openbb.co/terminal", command=None, arg_type=""
path, url="http://localhost/app/terminal", command=None, arg_type=""
):
"""Opens the documentation page based on your current location within the terminal. Make exceptions for menus
that are considered 'common' by adjusting the path accordingly."""
if path == "/" and command is None:
path = "/"
path = "/how-to"
command = ""
elif "keys" in path:
path = "/quickstart/api-keys"
path = "/guides?full=1&path=/quickstart/api-keys"
command = ""
elif "settings" in path:
path = "/usage/guides/customizing-the-terminal"
path = "/guides?path=/advanced/customizing-the-terminal"
command = ""
elif "featflags" in path:
path = "/usage/guides/customizing-the-terminal"
path = "/guides?path=/advanced/customizing-the-terminal"
command = ""
elif "sources" in path:
path = "/usage/guides/changing-sources"
path = "/guides?path=/advanced/changing-sources"
command = ""
elif "params" in path:
path = "/usage/intros/portfolio/po"
path = "/guides?path=/intros/portfolio/po"
command = ""
else:
if arg_type == "command": # user passed a command name
path = f"/reference/{path}"
path = f"/reference?path={path}"
elif arg_type == "menu": # user passed a menu name
if command in ["ta", "ba", "qa"]:
menu = path.split("/")[-2]
path = f"/usage/intros/common/{menu}"
path = f"/guides?path=/intros/common/{menu}"
elif command == "forecast":
command = ""
path = "/usage/intros/forecast"
path = "/guides?path=/intros/forecast"
else:
path = f"/usage/intros/{path}"
path = f"/guides?path=/intros/{path}"
else: # user didn't pass argument and is in a menu
menu = path.split("/")[-2]
path = (
f"/usage/intros/common/{menu}"
f"/guides?path=/intros/common/{menu}"
if menu in ["ta", "ba", "qa"]
else f"/usage/intros/{path}"
else f"/guides?path=/intros/{path}"
)
if command:
if command == "keys":
path = "/quickstart/api-keys"
path = "/guides?full=1&path=/quickstart/api-keys"
command = ""
elif "settings" in path or "featflags" in path:
path = "/usage/guides/customizing-the-terminal"
path = "/guides?path=/advanced/customizing-the-terminal"
command = ""
elif "sources" in path:
path = "/usage/guides/changing-sources"
path = "/guides?path=/advanced/changing-sources"
command = ""
elif command in ["record", "stop", "exe"]:
path = "/usage/guides/scripts-and-routines"
path = "/guides?path=/advanced/scripts-and-routines"
command = ""
elif command in [
"intro",
@@ -192,7 +196,7 @@ def open_openbb_documentation(
path = ""
command = ""
elif command in ["ta", "ba", "qa"]:
path = f"/usage/intros/common/{command}"
path = f"/guides?path=/intros/common/{command}"
command = ""
path += command
@@ -202,7 +206,7 @@ def open_openbb_documentation(
if full_url[-1] == "/":
full_url = full_url[:-1]
plots_backend().send_url(full_url)
webbrowser.open(full_url)
def hide_splashscreen():
@@ -412,5 +416,6 @@ def first_time_user() -> bool:
"""
if SETTINGS_ENV_FILE.stat().st_size == 0:
set_preference("PREVIOUS_USE", True)
write_to_dotenv("OPENBB_PREVIOUS_USE", "True")
return True
return False

1281
poetry.lock generated vendored

File diff suppressed because it is too large Load Diff

1
pyproject.toml vendored
View File

@@ -39,7 +39,6 @@ seaborn = "^0.11.0"
fredapi = "^0.4.3"
screeninfo = "^0.6.7"
robin-stocks = "^2.0.3"
pyally = "^1.1.2"
pycoingecko = "^3.1.0"
detecta = "^0.0.5"
tradingview-ta = "^3.2.3"

109
requirements-full.txt vendored
View File

@@ -28,7 +28,7 @@ babel==2.12.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and p
backcall==0.2.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
backoff==2.2.1 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
backports-zoneinfo==0.2.1 ; python_version >= "3.8" and python_version < "3.9"
bandit==1.7.4 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
bandit==1.7.5 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
base58==2.1.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
beautifulsoup4==4.11.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
black==23.1.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
@@ -40,23 +40,23 @@ bs4==0.0.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and pyth
bt==0.2.9 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
cachetools==5.3.0 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
catboost==1.1.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
ccxt==2.8.78 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
ccxt==2.9.16 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
certifi==2022.12.7 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
cffi==1.15.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
cfgv==3.3.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
charset-normalizer==3.0.1 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
charset-normalizer==3.1.0 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
click==8.1.3 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
cloudpickle==2.2.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
cmdstanpy==1.1.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
codespell==2.2.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
codespell==2.2.4 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
colorama==0.4.6 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
comm==0.1.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
commonmark==0.9.1 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
contourpy==1.0.7 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
convertdate==2.4.0 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
coverage==7.2.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
coverage[toml]==7.2.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
cryptography==39.0.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
coverage==7.2.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
coverage[toml]==7.2.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
cryptography==39.0.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
cssselect2==0.7.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
cssselect==1.2.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
cvxpy==1.2.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
@@ -65,9 +65,9 @@ cython==0.29.33 ; python_version >= "3.8" and python_full_version != "3.9.7" and
dash-core-components==2.0.0 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
dash-html-components==2.0.0 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
dash-table==5.0.0 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
dash==2.8.1 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
dash==2.9.0 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
dateparser==1.1.7 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
datetime==5.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
datetime==5.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
debugpy==1.6.6 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
decorator==5.1.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
defusedxml==0.7.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
@@ -88,22 +88,21 @@ fastjsonschema==2.16.3 ; python_version >= "3.8" and python_full_version != "3.9
feedparser==6.0.10 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
ffmpeg-python==0.2.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
ffn==0.3.6 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
filelock==3.9.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
filelock==3.10.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
financedatabase==2.0.9 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
finnhub-python==2.4.16 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
finviz==1.4.4 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
finvizfinance==0.14.5 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
flake8==5.0.4 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
flask-cors==3.0.10 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
flask==2.2.3 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
fonttools==4.38.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
fonttools==4.39.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
formulaic==0.3.4 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
fred==3.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
fredapi==0.4.3 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
frozendict==2.3.5 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
frozenlist==1.3.3 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
fs==2.4.16 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
fsspec[http]==2023.1.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
fsspec[http]==2023.3.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
fugue-sql-antlr==0.1.5 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
fugue==0.8.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
fundamentalanalysis==0.2.14 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
@@ -111,24 +110,25 @@ future==0.18.3 ; python_version >= "3.8" and python_full_version != "3.9.7" and
gitdb==4.0.10 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
gitpython==3.1.31 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
google-auth-oauthlib==0.4.6 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
google-auth==2.16.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
google-auth==2.16.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
graphviz==0.20.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
greenlet==2.0.2 ; python_version >= "3.8" and platform_machine == "aarch64" and python_full_version != "3.9.7" and python_version < "3.11" or python_version >= "3.8" and platform_machine == "ppc64le" and python_full_version != "3.9.7" and python_version < "3.11" or python_version >= "3.8" and platform_machine == "x86_64" and python_full_version != "3.9.7" and python_version < "3.11" or python_version >= "3.8" and platform_machine == "amd64" and python_full_version != "3.9.7" and python_version < "3.11" or python_version >= "3.8" and platform_machine == "AMD64" and python_full_version != "3.9.7" and python_version < "3.11" or python_version >= "3.8" and platform_machine == "win32" and python_full_version != "3.9.7" and python_version < "3.11" or python_version >= "3.8" and platform_machine == "WIN32" and python_full_version != "3.9.7" and python_version < "3.11"
greenlet==2.0.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11" and platform_machine == "aarch64" or python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11" and platform_machine == "ppc64le" or python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11" and platform_machine == "x86_64" or python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11" and platform_machine == "amd64" or python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11" and platform_machine == "AMD64" or python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11" and platform_machine == "win32" or python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11" and platform_machine == "WIN32"
grpcio==1.51.3 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
hijri-converter==2.2.4 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
holidays==0.14.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
html5lib==1.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
huggingface-hub==0.12.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
identify==2.5.18 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
huggingface-hub==0.13.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
identify==2.5.21 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
idna==3.4 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
imagesize==1.4.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
importlib-metadata==6.0.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
importlib-resources==5.12.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.10"
importlib-metadata==6.0.0 ; python_full_version != "3.9.7" and python_version < "3.11" and python_version >= "3.8"
importlib-resources==5.12.0 ; python_full_version != "3.9.7" and python_version < "3.10" and python_version >= "3.8"
inflection==0.5.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
iniconfig==2.0.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
interface-meta==1.3.0 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
intrinio-sdk==6.22.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
ipykernel==6.21.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
ipyflex==0.2.6 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
ipykernel==6.21.3 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
ipympl==0.8.4 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
ipython-genutils==0.2.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
ipython==8.11.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
@@ -143,11 +143,11 @@ joblib==1.2.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and p
json5==0.9.11 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
jsonschema==4.17.3 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
jupyter-client==7.4.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
jupyter-core==5.2.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
jupyter-core==5.3.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
jupyter-dash==0.4.2 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
jupyter-server==1.23.6 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
jupyterlab-pygments==0.2.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
jupyterlab-server==2.19.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
jupyterlab-server==2.20.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
jupyterlab-widgets==3.0.5 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
jupyterlab==3.5.3 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
kiwisolver==1.4.4 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
@@ -164,7 +164,7 @@ markdown-it-py==1.1.0 ; python_version >= "3.8" and python_version < "3.11" and
markdown==3.4.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
markupsafe==2.1.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
matplotlib-inline==0.1.6 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
matplotlib==3.7.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
matplotlib==3.7.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
mccabe==0.7.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
mdit-py-plugins==0.2.8 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
mistune==2.0.5 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
@@ -176,11 +176,11 @@ multidict==6.0.4 ; python_version >= "3.8" and python_full_version != "3.9.7" an
multitasking==0.0.11 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
mutagen==1.46.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
mypy-extensions==1.0.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
mypy==1.0.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
mypy==1.1.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
myst-parser==0.15.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
nbclassic==0.5.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
nbclassic==0.5.3 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
nbclient==0.6.8 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
nbconvert==7.2.9 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
nbconvert==7.2.10 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
nbformat==5.7.3 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
nbmake==1.4.1 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
nest-asyncio==1.5.6 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
@@ -188,14 +188,14 @@ networkx==3.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and p
nfoursid==1.0.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
nodeenv==1.7.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
notebook-shim==0.2.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
notebook==6.5.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
notebook==6.5.3 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
numba==0.56.4 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
numpy==1.23.4 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
oandapyv20==0.6.3 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
oauthlib==3.2.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
onetimepass==1.0.1 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
openai-whisper==20230124 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
openpyxl==3.1.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
openpyxl==3.1.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
orjson==3.8.7 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
osqp==0.6.2.post8 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
packaging==23.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
@@ -206,7 +206,7 @@ pandas==1.5.3 ; python_version >= "3.8" and python_full_version != "3.9.7" and p
pandocfilters==1.5.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
papermill==2.4.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
parso==0.8.3 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pathspec==0.11.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pathspec==0.11.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
patsy==0.5.3 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pbr==5.11.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pefile==2023.2.7 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7" and sys_platform == "win32"
@@ -214,12 +214,12 @@ pexpect==4.8.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and
pickleshare==0.7.5 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pillow==9.4.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pkgutil-resolve-name==1.3.10 ; python_version >= "3.8" and python_version < "3.9"
platformdirs==3.0.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
plotly-resampler==0.8.1 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
platformdirs==3.1.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
plotly-resampler==0.8.3.2 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
plotly==5.13.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pluggy==1.0.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pmaw==3.0.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pmdarima==2.0.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pmdarima==2.0.3 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
praw==7.7.0 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
prawcore==2.3.0 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
pre-commit==2.21.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
@@ -232,7 +232,6 @@ psutil==5.9.3 ; python_version >= "3.8" and python_full_version != "3.9.7" and p
ptyprocess==0.7.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11" and sys_platform != "win32" or python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11" and os_name != "nt"
pure-eval==0.2.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
py==1.11.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pyally==1.1.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pyarrow==11.0.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pyasn1-modules==0.2.8 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pyasn1==0.4.8 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
@@ -242,7 +241,7 @@ pycoingecko==3.1.0 ; python_version >= "3.8" and python_full_version != "3.9.7"
pycparser==2.21 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pycryptodome==3.17 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pycryptodomex==3.17 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pydantic==1.10.5 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pydantic==1.10.6 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pydeck==0.8.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pydeprecate==0.3.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pydocstyle==6.3.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
@@ -258,7 +257,7 @@ pymeeus==0.5.12 ; python_version >= "3.8" and python_version < "3.11" and python
pympler==1.0.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pyobjc-core==9.0.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11" and sys_platform == "darwin"
pyobjc-framework-cocoa==9.0.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11" and sys_platform == "darwin"
pyod==1.0.7 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pyod==1.0.8 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pyotp==2.8.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pyparsing==3.0.9 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pyprind==2.11.3 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
@@ -267,7 +266,7 @@ pytest-cov==3.0.0 ; python_version >= "3.8" and python_full_version != "3.9.7" a
pytest-mock==3.10.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pytest-recording==0.12.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pytest-timeout==2.1.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pytest-xdist==3.2.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pytest-xdist==3.2.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pytest==6.2.5 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pythclient==0.1.4 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
python-binance==1.0.17 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
@@ -278,13 +277,13 @@ python-i18n==0.3.9 ; python_version >= "3.8" and python_full_version != "3.9.7"
pytorch-lightning==1.6.5 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pytrends==4.9.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pytz-deprecation-shim==0.1.0.post0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pytz==2022.7.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pytz==2022.7.1 ; python_full_version != "3.9.7" and python_version < "3.11" and python_version >= "3.8"
pywin32-ctypes==0.2.0 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7" and sys_platform == "win32"
pywin32==305 ; sys_platform == "win32" and platform_python_implementation != "PyPy" and python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pywinpty==2.0.10 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11" and os_name == "nt"
pywry==0.3.6 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pyyaml==6.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pyzmq==25.0.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pyzmq==25.0.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
qdldl==0.1.5.post3 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
qpd==0.4.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
quandl==3.7.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
@@ -303,7 +302,7 @@ rsa==4.9 ; python_version >= "3.8" and python_version < "3.11" and python_full_v
ruamel-yaml-clib==0.2.7 ; platform_python_implementation == "CPython" and python_version < "3.11" and python_version >= "3.8" and python_full_version != "3.9.7"
ruamel-yaml==0.17.21 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
ruff==0.0.247 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
scikit-learn==1.2.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
scikit-learn==1.2.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
scipy==1.10.1 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
screeninfo==0.6.7 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
scs==3.2.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
@@ -330,15 +329,15 @@ sphinxcontrib-htmlhelp==2.0.1 ; python_version >= "3.8" and python_full_version
sphinxcontrib-jsmath==1.0.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
sphinxcontrib-qthelp==1.0.3 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
sphinxcontrib-serializinghtml==1.1.5 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
sqlalchemy==2.0.4 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
sqlglot==11.2.3 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
sqlalchemy==2.0.6 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
sqlglot==11.3.7 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
squarify==0.4.3 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
stack-data==0.6.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
statsforecast==1.5.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
statsmodels==0.13.5 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
stevedore==5.0.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
stocksera==0.1.21 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
streamlit==1.19.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
streamlit==1.20.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
svglib==1.5.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
tabulate==0.9.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
tbats==1.1.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
@@ -358,35 +357,35 @@ tomli==2.0.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and py
tomlkit==0.11.6 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
toolz==0.12.0 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
torch==1.11.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
torchmetrics==0.11.3 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
torchmetrics==0.11.4 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
tornado==6.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
tqdm==4.64.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
tqdm==4.65.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
trace-updater==0.0.9 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
tradingview-ta==3.3.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
traitlets==5.9.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
transformers==4.26.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
triad==0.8.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
tweepy==4.12.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
transformers==4.27.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
triad==0.8.3 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
tweepy==4.13.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
types-python-dateutil==2.8.19.10 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
types-pytz==2021.3.8 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
types-pyyaml==6.0.12.8 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
types-requests==2.28.11.15 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
types-setuptools==57.4.18 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
types-six==1.16.21.6 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
types-six==1.16.21.7 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
types-urllib3==1.26.25.8 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
typing-extensions==4.5.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
typing-extensions==4.5.0 ; python_full_version != "3.9.7" and python_version < "3.11" and python_version >= "3.8"
tzdata==2022.7 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
tzlocal==4.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
u8darts[torch]==0.23.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
ujson==5.7.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
update-checker==0.18.0 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
urllib3==1.26.14 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
urllib3==1.26.15 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
user-agent==0.1.10 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
vadersentiment==3.3.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
validators==0.20.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
valinvest==0.0.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
vcrpy==4.2.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
virtualenv==20.20.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
virtualenv==20.21.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
voila==0.4.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
watchdog==2.3.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
wcwidth==0.2.6 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
@@ -394,17 +393,17 @@ webencodings==0.5.1 ; python_version >= "3.8" and python_full_version != "3.9.7"
websocket-client==1.5.1 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
websockets==10.4 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
werkzeug==2.2.3 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
wheel==0.38.4 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
wheel==0.40.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
widgetsnbextension==4.0.5 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
win32-setctime==1.1.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11" and sys_platform == "win32"
wrapt==1.15.0 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
xarray==2023.1.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
xgboost==1.7.4 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
xlsxwriter==3.0.8 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
xlsxwriter==3.0.9 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
y-py==0.6.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
yahooquery==2.3.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
yarl==1.8.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
yfinance==0.2.12 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
yt-dlp==2023.2.17 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
zipp==3.15.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
yt-dlp==2023.3.4 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
zipp==3.15.0 ; python_full_version != "3.9.7" and python_version < "3.11" and python_version >= "3.8"
zope-interface==5.5.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"

52
requirements.txt vendored
View File

@@ -25,23 +25,23 @@ blinker==1.5 ; python_version >= "3.8" and python_full_version != "3.9.7" and py
bs4==0.0.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
bt==0.2.9 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
cachetools==5.3.0 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
ccxt==2.8.78 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
ccxt==2.9.16 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
certifi==2022.12.7 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
cffi==1.15.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
charset-normalizer==3.0.1 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
charset-normalizer==3.1.0 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
click==8.1.3 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
colorama==0.4.6 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
comm==0.1.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
commonmark==0.9.1 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
contourpy==1.0.7 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
convertdate==2.4.0 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
cryptography==39.0.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
cryptography==39.0.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
cssselect2==0.7.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
cssselect==1.2.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
cycler==0.11.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
cython==0.29.33 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
dateparser==1.1.7 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
datetime==5.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
datetime==5.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
debugpy==1.6.6 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
decorator==5.1.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
defusedxml==0.7.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
@@ -60,7 +60,7 @@ finnhub-python==2.4.16 ; python_version >= "3.8" and python_full_version != "3.9
finviz==1.4.4 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
finvizfinance==0.14.5 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
flake8==5.0.4 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
fonttools==4.38.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
fonttools==4.39.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
formulaic==0.3.4 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
fred==3.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
fredapi==0.4.3 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
@@ -76,11 +76,12 @@ holidays==0.14.2 ; python_version >= "3.8" and python_full_version != "3.9.7" an
html5lib==1.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
idna==3.4 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
importlib-metadata==6.0.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
importlib-resources==5.12.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.10"
importlib-resources==5.12.0 ; python_full_version != "3.9.7" and python_version < "3.10" and python_version >= "3.8"
inflection==0.5.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
interface-meta==1.3.0 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
intrinio-sdk==6.22.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
ipykernel==6.21.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
ipyflex==0.2.6 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
ipykernel==6.21.3 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
ipympl==0.8.4 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
ipython-genutils==0.2.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
ipython==8.11.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
@@ -93,10 +94,10 @@ joblib==1.2.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and p
json5==0.9.11 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
jsonschema==4.17.3 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
jupyter-client==7.4.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
jupyter-core==5.2.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
jupyter-core==5.3.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
jupyter-server==1.23.6 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
jupyterlab-pygments==0.2.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
jupyterlab-server==2.19.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
jupyterlab-server==2.20.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
jupyterlab-widgets==3.0.5 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
jupyterlab==3.5.3 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
kiwisolver==1.4.4 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
@@ -106,7 +107,7 @@ loguru==0.6.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and p
lxml==4.9.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
markupsafe==2.1.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
matplotlib-inline==0.1.6 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
matplotlib==3.7.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
matplotlib==3.7.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
mccabe==0.7.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
mistune==2.0.5 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
more-itertools==9.1.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
@@ -115,18 +116,18 @@ mstarpy==0.0.4 ; python_version >= "3.8" and python_full_version != "3.9.7" and
multidict==6.0.4 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
multitasking==0.0.11 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
mypy-extensions==1.0.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
nbclassic==0.5.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
nbclassic==0.5.3 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
nbclient==0.6.8 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
nbconvert==7.2.9 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
nbconvert==7.2.10 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
nbformat==5.7.3 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
nest-asyncio==1.5.6 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
notebook-shim==0.2.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
notebook==6.5.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
notebook==6.5.3 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
numpy==1.23.4 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
oandapyv20==0.6.3 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
oauthlib==3.2.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
onetimepass==1.0.1 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
openpyxl==3.1.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
openpyxl==3.1.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
packaging==23.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pandas-datareader==0.10.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pandas-market-calendars==3.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
@@ -140,7 +141,7 @@ pexpect==4.8.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and
pickleshare==0.7.5 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pillow==9.4.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pkgutil-resolve-name==1.3.10 ; python_version >= "3.8" and python_version < "3.9"
platformdirs==3.0.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
platformdirs==3.1.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
plotly==5.13.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pmaw==3.0.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
praw==7.7.0 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
@@ -152,14 +153,13 @@ protobuf==3.20.1 ; python_version >= "3.8" and python_full_version != "3.9.7" an
psutil==5.9.3 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
ptyprocess==0.7.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11" and sys_platform != "win32" or python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11" and os_name != "nt"
pure-eval==0.2.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pyally==1.1.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pyarrow==11.0.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pycares==4.3.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pycodestyle==2.9.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pycoingecko==3.1.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pycparser==2.21 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pycryptodome==3.17 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pydantic==1.10.5 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pydantic==1.10.6 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pydeck==0.8.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pyflakes==2.5.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pygments==2.14.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
@@ -181,12 +181,12 @@ python-dotenv==0.19.2 ; python_version >= "3.8" and python_full_version != "3.9.
python-i18n==0.3.9 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pytrends==4.9.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pytz-deprecation-shim==0.1.0.post0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pytz==2022.7.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pytz==2022.7.1 ; python_full_version != "3.9.7" and python_version < "3.11" and python_version >= "3.8"
pywin32==305 ; sys_platform == "win32" and platform_python_implementation != "PyPy" and python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pywinpty==2.0.10 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11" and os_name == "nt"
pywry==0.3.6 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pyyaml==6.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pyzmq==25.0.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
pyzmq==25.0.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
quandl==3.7.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
rapidfuzz==2.13.7 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
rdflib==6.2.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
@@ -200,7 +200,7 @@ rich==12.6.0 ; python_version >= "3.8" and python_version < "3.11" and python_fu
robin-stocks==2.1.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
ruamel-yaml-clib==0.2.7 ; platform_python_implementation == "CPython" and python_version < "3.11" and python_version >= "3.8" and python_full_version != "3.9.7"
ruamel-yaml==0.17.21 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
scikit-learn==1.2.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
scikit-learn==1.2.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
scipy==1.10.1 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
screeninfo==0.6.7 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
seaborn==0.11.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
@@ -218,7 +218,7 @@ squarify==0.4.3 ; python_version >= "3.8" and python_full_version != "3.9.7" and
stack-data==0.6.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
statsmodels==0.13.5 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
stocksera==0.1.21 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
streamlit==1.19.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
streamlit==1.20.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
svglib==1.5.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
tabulate==0.9.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
tenacity==7.0.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
@@ -232,16 +232,16 @@ toml==0.10.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and py
tomli==2.0.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
toolz==0.12.0 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
tornado==6.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
tqdm==4.64.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
tqdm==4.65.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
tradingview-ta==3.3.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
traitlets==5.9.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
tweepy==4.12.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
typing-extensions==4.5.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
tweepy==4.13.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
typing-extensions==4.5.0 ; python_full_version != "3.9.7" and python_version < "3.11" and python_version >= "3.8"
tzdata==2022.7 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
tzlocal==4.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
ujson==5.7.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
update-checker==0.18.0 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
urllib3==1.26.14 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
urllib3==1.26.15 ; python_version >= "3.8" and python_version < "3.11" and python_full_version != "3.9.7"
user-agent==0.1.10 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
vadersentiment==3.3.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
validators==0.20.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
@@ -259,5 +259,5 @@ y-py==0.6.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and pyt
yahooquery==2.3.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
yarl==1.8.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
yfinance==0.2.12 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
zipp==3.15.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"
zipp==3.15.0 ; python_full_version != "3.9.7" and python_version < "3.11" and python_version >= "3.8"
zope-interface==5.5.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"

View File

@@ -352,7 +352,9 @@ def test_call_sync(mocker, other_args, sync):
target="openbb_terminal.core.session.current_user.__current_user",
new=mock_current_user,
)
mocker.patch(
target="openbb_terminal.account.account_controller.set_preference",
)
controller.call_sync(other_args=other_args)
assert controller.queue == []
@@ -619,12 +621,6 @@ def test_call_generate(mocker, monkeypatch, test_user):
mock_input = "y"
monkeypatch.setattr(f"{path_controller}.console.input", lambda _: mock_input)
# mock save to keys
mocker.patch(
target=f"{path_controller}.keys_model.set_openbb_personal_access_token",
return_value=True,
)
controller.call_generate(other_args=["--save", "--days", "30"])
mock_generate.assert_called_once_with(

View File

@@ -360,7 +360,7 @@ def test_fetch_user_configs_exception():
("key", "value", "settings", "auth_header"),
],
)
def test_patch_user_configs_success(key, value, type_, auth_header):
def test_upload_config_success(key, value, type_, auth_header):
mock_response = MagicMock(spec=requests.Response)
mock_response.status_code = 200
@@ -368,7 +368,7 @@ def test_patch_user_configs_success(key, value, type_, auth_header):
"openbb_terminal.core.session.hub_model.requests.patch",
return_value=mock_response,
) as requests_patch_mock:
result = hub_model.patch_user_configs(key, value, type_, auth_header)
result = hub_model.upload_config(key, value, type_, auth_header)
assert result.status_code == mock_response.status_code
requests_patch_mock.assert_called_once()
@@ -379,7 +379,7 @@ def test_patch_user_configs_success(key, value, type_, auth_header):
assert kwargs["timeout"] == hub_model.TIMEOUT
def test_patch_user_configs_failure():
def test_upload_config_failure():
mock_response = MagicMock(spec=requests.Response)
mock_response.status_code = 400
@@ -387,7 +387,7 @@ def test_patch_user_configs_failure():
"openbb_terminal.core.session.hub_model.requests.patch",
return_value=mock_response,
) as requests_patch_mock:
result = hub_model.patch_user_configs("key", "value", "keys", "auth_header")
result = hub_model.upload_config("key", "value", "keys", "auth_header")
assert result.status_code == mock_response.status_code
requests_patch_mock.assert_called_once()
@@ -398,13 +398,13 @@ def test_patch_user_configs_failure():
assert kwargs["timeout"] == hub_model.TIMEOUT
def test_patch_user_configs_connection_error():
def test_upload_config_connection_error():
with patch(
"openbb_terminal.core.session.hub_model.requests.patch"
) as requests_patch_mock:
requests_patch_mock.side_effect = requests.exceptions.ConnectionError()
result = hub_model.patch_user_configs("key", "value", "keys", "auth_header")
result = hub_model.upload_config("key", "value", "keys", "auth_header")
assert result is None
requests_patch_mock.assert_called_once()
@@ -415,13 +415,13 @@ def test_patch_user_configs_connection_error():
assert kwargs["timeout"] == hub_model.TIMEOUT
def test_patch_user_configs_timeout():
def test_upload_config_timeout():
with patch(
"openbb_terminal.core.session.hub_model.requests.patch"
) as requests_patch_mock:
requests_patch_mock.side_effect = requests.exceptions.Timeout()
result = hub_model.patch_user_configs("key", "value", "keys", "auth_header")
result = hub_model.upload_config("key", "value", "keys", "auth_header")
assert result is None
requests_patch_mock.assert_called_once()
@@ -432,13 +432,13 @@ def test_patch_user_configs_timeout():
assert kwargs["timeout"] == hub_model.TIMEOUT
def test_patch_user_configs_exception():
def test_upload_config_exception():
with patch(
"openbb_terminal.core.session.hub_model.requests.patch"
) as requests_patch_mock:
requests_patch_mock.side_effect = Exception()
result = hub_model.patch_user_configs("key", "value", "keys", "auth_header")
result = hub_model.upload_config("key", "value", "keys", "auth_header")
assert result is None
requests_patch_mock.assert_called_once()
@@ -750,7 +750,7 @@ def test_generate_personal_access_token(
assert result.status_code == mock_response.status_code
requests_put_mock.assert_called_once()
_, kwargs = requests_put_mock.call_args
assert kwargs["url"] == base_url + "/sdk/token"
assert kwargs["url"] == base_url + "sdk/token"
assert kwargs["headers"] == {
"Authorization": auth_header,
"Content-Type": "application/json",
@@ -798,7 +798,7 @@ def test_get_personal_access_token(auth_header, base_url, timeout, status_code):
assert result.status_code == mock_response.status_code
requests_get_mock.assert_called_once()
_, kwargs = requests_get_mock.call_args
assert kwargs["url"] == base_url + "/sdk/token"
assert kwargs["url"] == base_url + "sdk/token"
assert kwargs["headers"] == {"Authorization": auth_header}
assert kwargs["timeout"] == timeout
@@ -842,7 +842,7 @@ def test_revoke_personal_access_token(auth_header, base_url, timeout, status_cod
assert result.status_code == mock_response.status_code
requests_get_mock.assert_called_once()
_, kwargs = requests_get_mock.call_args
assert kwargs["url"] == base_url + "/sdk/token"
assert kwargs["url"] == base_url + "sdk/token"
assert kwargs["headers"] == {"Authorization": auth_header}
assert kwargs["timeout"] == timeout

View File

@@ -1,28 +0,0 @@
# IMPORTATION THIRDPARTY
import pytest
# IMPORTATION INTERNAL
from openbb_terminal.stocks.behavioural_analysis import cramer_model
@pytest.fixture(scope="module")
def vcr_config():
return {
"filter_headers": [("User-Agent", None)],
}
@pytest.mark.vcr()
@pytest.mark.parametrize(
"inverse",
[True, False],
)
def test_get_orders(recorder, inverse):
recommendations = cramer_model.get_cramer_daily(inverse=inverse)
recorder.capture(recommendations)
@pytest.mark.vcr()
def test_get_cramer_ticker(recorder):
data = cramer_model.get_cramer_ticker("AAPL")
recorder.capture(data)

View File

@@ -1,96 +0,0 @@
# IMPORTATION THIRDPARTY
from io import StringIO
import pandas as pd
import pytest
# IMPORTATION INTERNAL
from openbb_terminal.stocks.behavioural_analysis import cramer_view
closes = pd.read_csv(
StringIO(
"""
Date,Adj Close
2022-01-03, 181.7783966064453
2022-01-04, 179.47134399414062
2022-01-05, 174.69741821289062
2022-01-06, 171.78114318847656
2022-01-07, 171.950927734375
2022-01-10, 171.9709014892578
2022-01-11, 174.8572235107422
2022-01-12, 175.306640625
2022-01-13, 171.9709014892578
2022-01-14, 172.84979248046875
2022-01-18, 169.5839385986328
2022-01-19, 166.0184783935547
2022-01-20, 164.3006591796875
2022-01-21, 162.20335388183594
2022-01-24, 161.41433715820312
2022-01-25, 159.57669067382812
2022-01-26, 159.48680114746094
2022-01-27, 159.0174102783203
2022-01-28, 170.11326599121094
2022-01-31, 174.55760192871094
2022-02-01, 174.3878173828125
2022-02-02, 175.6162567138672
2022-02-03, 172.67999267578125
2022-02-04, 172.38999938964844
2022-02-07, 171.66000366210938
2022-02-08, 174.8300018310547
2022-02-09, 176.27999877929688
2022-02-10, 172.1199951171875
2022-02-11, 168.63999938964844
2022-02-14, 168.8800048828125
2022-02-15, 172.7899932861328
2022-02-16, 172.5500030517578
2022-02-17, 168.8800048828125
2022-02-18, 167.3000030517578
2022-02-22, 164.32000732421875
2022-02-23, 160.07000732421875
2022-02-24, 162.74000549316406
2022-02-25, 164.85000610351562
2022-02-28, 165.1199951171875
2022-03-01, 163.1999969482422
2022-03-02, 166.55999755859375
2022-03-03, 166.22999572753906
2022-03-04, 163.1699981689453
2022-03-07, 159.3000030517578
2022-03-09, 162.01499938964844
"""
)
).set_index("Date")
closes.index = pd.to_datetime(closes.index)
@pytest.fixture(scope="module")
def vcr_config():
return {
"filter_headers": [("User-Agent", None)],
}
@pytest.mark.vcr()
@pytest.mark.record_stdout
@pytest.mark.parametrize(
"inverse",
[True, False],
)
def test_get_orders(inverse):
cramer_view.display_cramer_daily(inverse=inverse)
@pytest.mark.vcr()
@pytest.mark.record_stdout
@pytest.mark.parametrize("raw", [True, False])
def test_cramer_ticker(mocker, raw):
# MOCK EXPORT_DATA
mocker.patch(
target="openbb_terminal.stocks.behavioural_analysis.cramer_view.export_data"
)
mocker.patch(
target="openbb_terminal.stocks.behavioural_analysis.cramer_view.yfinance.download",
new=mocker.Mock(return_value=closes.copy()),
)
cramer_view.display_cramer_ticker("AAPL", raw=raw)

View File

@@ -843,51 +843,6 @@ def test_call_func_expect_queue(expected_queue, func, mocker, queue):
],
dict(),
),
(
"call_parity",
[
"--put",
"--ask",
"--min=1",
"--max=2",
"--export=csv",
],
"yfinance_view.show_parity",
[
"MOCK_TICKER",
"2022-01-07",
True,
True,
1,
2,
"csv",
],
dict(),
),
(
"call_binom",
[
"1",
"--put",
"--european",
"--xlsx",
"--plot",
"--volatility=2",
"--export=csv",
],
"yfinance_view.show_binom",
[
"MOCK_TICKER",
"2022-01-07",
1.0,
True,
True,
True,
True,
2.0,
],
dict(),
),
(
"call_pricing",
[],
@@ -965,9 +920,6 @@ def test_call_func(
"call_chains",
"call_grhist",
"call_plot",
"call_parity",
"call_binom",
"call_pricing",
],
)
def test_call_func_no_ticker(func, mocker):
@@ -994,9 +946,6 @@ def test_call_func_no_ticker(func, mocker):
"call_oi",
"call_vol",
"call_plot",
"call_parity",
"call_binom",
"call_pricing",
],
)
def test_call_func_no_selected_date(func, mocker):

View File

@@ -1,441 +0,0 @@
# IMPORTATION STANDARD
import os
# IMPORTATION THIRDPARTY
import pandas as pd
import pytest
# IMPORTATION INTERNAL
from openbb_terminal.core.session.current_user import (
PreferencesModel,
copy_user,
)
from openbb_terminal.stocks.options.pricing import pricing_controller
# pylint: disable=E1101
# pylint: disable=W0603
# pylint: disable=E1111
PRICES = pd.DataFrame(data={"Price": [11.0, 12.0], "Chance": [0.2, 0.8]})
@pytest.mark.vcr(record_mode="none")
@pytest.mark.parametrize(
"queue, expected",
[
(["load", "help"], ["help"]),
(["quit", "help"], ["help"]),
],
)
def test_menu_with_queue(expected, mocker, queue):
path_controller = "openbb_terminal.stocks.options.pricing.pricing_controller"
# MOCK SWITCH
mocker.patch(
target=f"{path_controller}.PricingController.switch",
return_value=["quit"],
)
result_menu = pricing_controller.PricingController(
ticker="MOCK_TICKER",
selected_date="2022-01-07",
prices=PRICES,
queue=queue,
).menu()
assert result_menu == expected
@pytest.mark.vcr(record_mode="none")
def test_menu_without_queue_completion(mocker):
path_controller = "openbb_terminal.stocks.options.pricing.pricing_controller"
# ENABLE AUTO-COMPLETION : HELPER_FUNCS.MENU
preferences = PreferencesModel(USE_PROMPT_TOOLKIT=True)
mock_current_user = copy_user(preferences=preferences)
mocker.patch(
target="openbb_terminal.core.session.current_user.__current_user",
new=mock_current_user,
)
mocker.patch(
target="openbb_terminal.parent_classes.session",
)
mocker.patch(
target="openbb_terminal.parent_classes.session.prompt",
return_value="quit",
)
# ENABLE AUTO-COMPLETION : CONTROLLER.COMPLETER
preferences = PreferencesModel(USE_PROMPT_TOOLKIT=True)
mock_current_user = copy_user(preferences=preferences)
mocker.patch(
target="openbb_terminal.core.session.current_user.__current_user",
new=mock_current_user,
)
mocker.patch(
target=f"{path_controller}.session",
)
mocker.patch(
target=f"{path_controller}.session.prompt",
return_value="quit",
)
result_menu = pricing_controller.PricingController(
ticker="MOCK_TICKER",
selected_date="2022-01-07",
prices=PRICES,
queue=None,
).menu()
assert result_menu == ["help"]
@pytest.mark.vcr(record_mode="none")
@pytest.mark.parametrize(
"mock_input",
["help", "homee help", "home help", "mock"],
)
def test_menu_without_queue_sys_exit(mock_input, mocker):
path_controller = "openbb_terminal.stocks.options.pricing.pricing_controller"
# DISABLE AUTO-COMPLETION
preferences = PreferencesModel(USE_PROMPT_TOOLKIT=True)
mock_current_user = copy_user(preferences=preferences)
mocker.patch(
target="openbb_terminal.core.session.current_user.__current_user",
new=mock_current_user,
)
mocker.patch(
target=f"{path_controller}.session",
return_value=None,
)
# MOCK USER INPUT
mocker.patch("builtins.input", return_value=mock_input)
# MOCK SWITCH
class SystemExitSideEffect:
def __init__(self):
self.first_call = True
def __call__(self, *args, **kwargs):
if self.first_call:
self.first_call = False
raise SystemExit()
return ["quit"]
mock_switch = mocker.Mock(side_effect=SystemExitSideEffect())
mocker.patch(
target=f"{path_controller}.PricingController.switch",
new=mock_switch,
)
result_menu = pricing_controller.PricingController(
ticker="MOCK_TICKER",
selected_date="2022-01-07",
prices=PRICES,
queue=None,
).menu()
assert result_menu == ["help"]
@pytest.mark.vcr(record_mode="none")
@pytest.mark.record_stdout
def test_print_help():
controller = pricing_controller.PricingController(
ticker="MOCK_TICKER",
selected_date="2022-01-07",
prices=PRICES,
queue=None,
)
controller.print_help()
@pytest.mark.vcr(record_mode="none")
@pytest.mark.parametrize(
"an_input, expected_queue",
[
("", []),
("/help", ["home", "help"]),
("help/help", ["help", "help"]),
("q", ["quit"]),
("h", []),
(
"r",
[
"quit",
"quit",
"quit",
"reset",
"stocks",
"load MOCK_TICKER",
"options",
"exp -d 2022-01-07",
"pricing",
],
),
],
)
def test_switch(an_input, expected_queue):
controller = pricing_controller.PricingController(
ticker="MOCK_TICKER",
selected_date="2022-01-07",
prices=PRICES,
queue=None,
)
queue = controller.switch(an_input=an_input)
assert queue == expected_queue
@pytest.mark.vcr(record_mode="none")
def test_call_cls(mocker):
mocker.patch("os.system")
controller = pricing_controller.PricingController(
ticker="MOCK_TICKER",
selected_date="2022-01-07",
prices=PRICES,
queue=None,
)
controller.call_cls([])
assert controller.queue == []
os.system.assert_called_once_with("cls||clear")
@pytest.mark.vcr(record_mode="none")
@pytest.mark.parametrize(
"func, queue, expected_queue",
[
(
"call_exit",
[],
["quit", "quit", "quit", "quit"],
),
("call_exit", ["help"], ["quit", "quit", "quit", "quit", "help"]),
("call_home", [], ["quit", "quit", "quit"]),
("call_help", [], []),
("call_quit", [], ["quit"]),
("call_quit", ["help"], ["quit", "help"]),
(
"call_reset",
[],
[
"quit",
"quit",
"quit",
"reset",
"stocks",
"load MOCK_TICKER",
"options",
"exp -d 2022-01-07",
"pricing",
],
),
(
"call_reset",
["help"],
[
"quit",
"quit",
"quit",
"reset",
"stocks",
"load MOCK_TICKER",
"options",
"exp -d 2022-01-07",
"pricing",
"help",
],
),
],
)
def test_call_func_expect_queue(expected_queue, func, queue):
controller = pricing_controller.PricingController(
ticker="MOCK_TICKER",
selected_date="2022-01-07",
prices=PRICES,
queue=queue,
)
result = getattr(controller, func)([])
assert result is None
assert controller.queue == expected_queue
@pytest.mark.vcr(record_mode="none")
@pytest.mark.parametrize(
"tested_func, other_args, mocked_func, called_args, called_kwargs",
[
(
"call_add",
[
"1",
"--chance=2",
],
"",
[],
dict(),
),
(
"call_add",
[
"11",
"--chance=2",
],
"",
[],
dict(),
),
(
"call_rmv",
[
"11",
],
"",
[],
dict(),
),
(
"call_show",
[],
"print_rich_table",
[
PRICES,
],
dict(
headers=list(PRICES.columns),
show_index=False,
title="Estimated price(s) of MOCK_TICKER at 2022-01-07",
),
),
(
"call_rnval",
[
"--put",
"--min=1.0",
"--max=2.0",
"--risk=3.0",
],
"yfinance_view.risk_neutral_vals",
[
"MOCK_TICKER",
"2022-01-07",
PRICES,
True,
1.0,
2.0,
3.0,
],
dict(),
),
],
)
def test_call_func_test(
tested_func, mocked_func, other_args, called_args, called_kwargs, mocker
):
path_controller = "openbb_terminal.stocks.options.pricing.pricing_controller"
if mocked_func:
mock = mocker.Mock()
mocker.patch(
target=f"{path_controller}.{mocked_func}",
new=mock,
)
controller = pricing_controller.PricingController(
ticker="MOCK_TICKER",
selected_date="2022-01-07",
prices=PRICES,
queue=None,
)
getattr(controller, tested_func)(other_args)
if called_args or called_kwargs:
mock.assert_called_once_with(*called_args, **called_kwargs)
else:
mock.assert_called_once()
else:
controller = pricing_controller.PricingController(
ticker="MOCK_TICKER",
selected_date="2022-01-07",
prices=PRICES,
queue=None,
)
getattr(controller, tested_func)(other_args)
@pytest.mark.vcr(record_mode="none")
@pytest.mark.parametrize(
"func",
[
"call_rnval",
],
)
def test_call_func_no_ticker(func, mocker):
mocker.patch(
"openbb_terminal.stocks.options.pricing.pricing_controller.PricingController.parse_known_args_and_warn",
return_value=True,
)
controller = pricing_controller.PricingController(
ticker=None,
selected_date="2022-01-07",
prices=PRICES,
queue=None,
)
func_result = getattr(controller, func)(list())
assert func_result is None
assert controller.queue == []
@pytest.mark.vcr(record_mode="none")
@pytest.mark.parametrize(
"func",
[
"call_rnval",
],
)
def test_call_func_no_selected_date(func, mocker):
# MOCK PARSE_KNOWN_ARGS_AND_WARN
mocker.patch(
"openbb_terminal.stocks.options.pricing.pricing_controller.PricingController.parse_known_args_and_warn",
return_value=True,
)
controller = pricing_controller.PricingController(
ticker="MOCK_TICKER",
selected_date=None,
prices=PRICES,
queue=None,
)
func_result = getattr(controller, func)(list())
assert func_result is None
assert controller.selected_date is None
@pytest.mark.vcr(record_mode="none")
@pytest.mark.parametrize(
"ticker, expected",
[
(None, []),
(
"MOCK_TICKER",
["stocks", "load MOCK_TICKER", "options", "exp -d 2022-01-07", "pricing"],
),
],
)
def test_custom_reset(expected, ticker):
controller = pricing_controller.PricingController(
ticker=None,
selected_date="2022-01-07",
prices=PRICES,
queue=None,
)
controller.ticker = ticker
result = controller.custom_reset()
assert result == expected

View File

@@ -1,7 +1,6 @@
# IMPORTATION STANDARD
# IMPORTATION THIRDPARTY
import pandas as pd
import pytest
# IMPORTATION INTERNAL
@@ -48,62 +47,6 @@ def test_plot_payoff(mocker):
)
@pytest.mark.default_cassette("test_show_parity")
@pytest.mark.vcr
def test_show_parity(mocker):
# MOCK EXPORT_DATA
mocker.patch(target="openbb_terminal.stocks.options.yfinance_view.export_data")
yfinance_view.show_parity(
symbol="AAPL",
expiry="2023-07-21",
put=True,
ask=True,
mini=0.0,
maxi=100.0,
export="csv",
sheet_name=None,
)
@pytest.mark.default_cassette("test_risk_neutral_vals")
@pytest.mark.vcr
def test_risk_neutral_vals(mocker):
# MOCK EXPORT_DATA
mocker.patch(target="openbb_terminal.stocks.options.yfinance_view.export_data")
yfinance_view.risk_neutral_vals(
symbol="AAPL",
expiry="2023-07-21",
put=True,
data=pd.DataFrame(columns=["Price", "Chance"]),
mini=None,
maxi=None,
risk=None,
)
@pytest.mark.default_cassette("test_show_binom")
@pytest.mark.vcr
def test_show_binom(mocker):
# MOCK EXPORT_DATA
mocker.patch(target="openbb_terminal.stocks.options.yfinance_view.export_data")
# MOCK EXPORT_BINOMIAL_CALCS
mocker.patch(target="openbb_terminal.stocks.options.yfinance_view.Workbook.save")
yfinance_view.show_binom(
symbol="AAPL",
expiry="2023-07-21",
strike=90.0,
put=True,
europe=False,
export=False,
plot=True,
vol=None,
)
@pytest.mark.default_cassette("test_show_greeks")
@pytest.mark.vcr
def test_show_greeks():

View File

@@ -19,11 +19,8 @@ Expiry:
[unvl] vsurf show 3D volatility surface[/unvl] [YahooFinance]
[unvl] grhist plot option greek history[/unvl] [Syncretism, Intrinio]
[unvl] plot plot variables provided by the user[/unvl] [YahooFinance]
[unvl] parity shows whether options are above or below expected price[/unvl] [YahooFinance]
[unvl] binom shows the value of an option using binomial options pricing[/unvl] [YahooFinance]
[unvl] greeks shows the greeks for a given option[/unvl] [YahooFinance]
[unvl] eodchain gets option chain at a specific date[/unvl] [Intrinio]
[unvl]> pricing shows options pricing and risk neutral valuation[/unvl]
[unvl]> hedge shows portfolio weights in order to neutralise delta[/unvl]

View File

@@ -24,12 +24,9 @@ def controller(mocker):
)
mocker.patch(
target="openbb_terminal.featflags_controller.set_preference",
target="openbb_terminal.featflags_controller.set_and_save_preference",
)
mocker.patch(
target="openbb_terminal.core.session.preferences_handler.set_preference"
)
return FeatureFlagsController()

View File

@@ -252,20 +252,3 @@ def test_call_tokenterminal(other):
@pytest.mark.parametrize("other", [[], ["-k", "1234", "-t", "456"]])
def test_call_shroom(other):
controller.call_shroom(other)
@pytest.mark.vcr
@pytest.mark.parametrize("other", [[], ["-k", "1234", "-t", "456"]])
def test_call_openbb(mocker, other):
# MOCK GET
attrs = {
"status_code": 200,
"json.return_value": {"token": "MOCK_TOKEN"},
}
mock_response = mocker.Mock(**attrs)
mocker.patch(
target="openbb_terminal.keys_model.request",
new=mocker.Mock(return_value=mock_response),
)
controller.call_openbb(other)

View File

@@ -1456,53 +1456,6 @@ def test_set_shroom_key(
)
@pytest.mark.vcr
@pytest.mark.record_stdout
@pytest.mark.parametrize(
"args, persist, show_output, __expected",
[
(
["test_key"],
False,
True,
keys_model.KeyStatus.DEFINED_TEST_FAILED,
),
(
["test_key"],
False,
False,
keys_model.KeyStatus.DEFINED_TEST_FAILED,
),
(
["test_key"],
True,
True,
keys_model.KeyStatus.DEFINED_TEST_FAILED,
),
(
["REPLACE_ME"],
False,
True,
keys_model.KeyStatus.NOT_DEFINED,
),
],
)
def test_set_openbb_key(
args: List[str], persist: bool, show_output: bool, __expected: str
):
var_name_list = [
"OPENBB_OPENBB_PERSONAL_ACCESS_TOKEN",
]
set_naive_environment(var_name_list)
keys_model.set_openbb_personal_access_token(
key=args[0],
persist=persist,
show_output=show_output,
)
def delete_tmp_files():
tmp_files = TEST_PATH.glob(f"*{proc_id}.tmp")
for file in tmp_files:

74
website/README.md vendored
View File

@@ -2,16 +2,16 @@
This repository contains the source code for the OpenBB Documentation Website.
The website was built using [Docusaurus](https://docusaurus.io/), a modern static website generator and [TailwindCSS](https://tailwindcss.com) as styling solution.
The website was built using [Docusaurus](https://docusaurus.io/), a modern static website generator and [TailwindCSS](https://tailwindcss.com) as styling solution. It uses algolia search for the search bar.
The final website can be found at [https://docs.openbb.co](https://docs.openbb.co).
## Folder Structure
```bash
website
├── content # Markdown files
| ├── sdk # SDK markdown files
| ├── bot # bot markdown files
| └── terminal # Terminal markdown files
├── old_content # previous terminal documentation; required to get the examples for terminal reference
├── src # react stuff for website
@@ -24,13 +24,72 @@ website
The markdown files are used to generate the website. The markdown files are located in the `content` folder. The markdown files are generated using the `generate_sdk_markdown.py` and `generate_terminal_markdown.py` scripts. The markdown files are generated from the docstrings in the SDK and Terminal code. Files inside `content/sdk/reference` and `content/terminal/reference` should not be changed manually because they are generated automatically on every commit.
### Syntax sugar
#### Code blocks
Code blocks are generated using the default markdown syntax:
```python
print("Hello World")
```
To generate a dynamic date for a certain code block (useful for options examples that need to have a valid date), you can use `2022-07-29` as a placeholder. The script will replace it with the third friday of the next month.
```
/op oichart ticker:AMD expiry:2022-07-29
```
#### Available options
This is great for huge lists. It opens a popup that contains the list and the search bar, so you can easily find what you are looking for. Everything is virtualized, so it's always fast no matter how many items you have.
Check [crypto page](https://docs.openbb.co/bot/discord/crypto) for a demo of this component.
```md
import AvailableOptions from "@site/src/components/General/AvailableOptions";
<AvailableOptions
label="Exchanges"
allOptions={[
"aax",
"ascendex",
"bequant",
"bibox",
"bigone",
"binance",
"binancecoinm",
"binanceus",
"binanceusdm",
"bit2c",
"bitbank",
"bitbay",
"bitcoincom",
"bitfinex",
"bitfinex2",
"bitflyer",
"bitforex",
"bitget",
"bithumb",
"bitmart",
"bitmex",
"bitopro",
"bitpanda",
"bitrue",
"bitso",
"bitstamp",
"bitstamp1",
"bittrex",
"bitvavo",
]}
/>
```
## Run locally
### Prerequisites
- [Node.js](https://nodejs.org/en/) >= 16.13.0
To check if you have Node.js installed, run this command in your terminal:
To check if you have Node.js installed, run this command in your terminal:
```bash
node --version # should be v16.13.0 or higher
@@ -58,8 +117,6 @@ npm run build
This command generates static content into the `build` directory and can be served using any static contents hosting service. We use Github Pages to host our website. It's deployed in the `gh-pages` branch.
## Run tests
```bash
@@ -70,11 +127,18 @@ pytest tests/website --autodoc
> To install necessary dependencies for tests, run `poetry install -E doc` in the root directory of the repository.
## Notes
### iFrame
We are detecting whether the website is loaded inside an iframe. If it is, we are hiding the header and footer. This is done to have a better integration with out [hub website](https://my.openbb.co).
## Contributing
We welcome contributions to the OpenBB Documentation Website.
---
<details><summary>DEPRECATED - OLD README</summary>
<p>

4
website/content/bot/_category_.json vendored Normal file
View File

@@ -0,0 +1,4 @@
{
"label": "OpenBB Bot",
"position": 3
}

View File

@@ -0,0 +1,4 @@
{
"label": "Changelog",
"position": 5
}

View File

@@ -0,0 +1,33 @@
---
title: Version 1.0.0
version: "1.0.0"
date: 2022-08-03
description: Version 1.0.0
---
## Added
- Supports Discord
- Charts menu including: chart, c3m, c5m, c15m, cd, cw, cm
- Discovery menu including: contracts, senate, splits, fgindex, holidays, ipolist, fidelity, house
- Due diligence menu including: ah, nexter, bio, pm, analyst, pt, est, sec, supplier, customer, instholdings, insiders, arktrades, splits, ermove, earnings
- ETF menu including: tops, holdings
- Economy menu including: calendar, glbonds, indices, commodiities, usbonds, currencies, revrepo, fedrates
- General menu including: futures, ta, news, quote
- Government menu including: contracts, senate, house
- Information menu including: serverid, stats, support, about, help
- Shorts menu including: borrowed, shortvol, topshortvol, hsi, shortrate
- Screener menu including: ah, pm, all, technical
- Premium Crypto menu including: prints, bigprints
- Premium Darkpool menu including: allblocks, alldp, allprints, bigprints, levels. topsum, sectors, summary
- Premium Flow menu including: sumexp, opening, unu, weekly, bigflow, prem, day, sumweek, sumtop, sectors, summary, sumday
- Premium Stock Options including: equitypc, chains, oichart, indexpc, maxpain, stats, gamma, oi, topoichange, smile, info, unu, vol, topoi, vsurf, topvoletf, topstrikevol, topvol, itm, uoastock, hist, highiv
- OpenBB Alerts including: list, create, update, delete
## Changed
- First release, no changes.
## Fixed
- First release, no fixes.

View File

@@ -0,0 +1,20 @@
---
title: Version 1.0.1
version: "1.0.1"
date: 2022-08-04
description: Version 1.0.1
---
## Added
- Charts : new layout on charts "classic" theme - made this default
- Discovery menu including: heatmap
## Changed
- Charts menu including: "classic" theme on charts
## Fixed
- Due diligence menu including : added ah and pm to ! commands
- Premium Flow menu including : added weekly and opening to ! commands

View File

@@ -0,0 +1,18 @@
---
title: Version 1.0.2
version: "1.0.2"
date: 2022-08-05
description: Version 1.0.2
---
## Added
- No changes
## Changed
- All Blue should now be Green - :)
## Fixed
- Futures Caching issue

View File

@@ -0,0 +1,31 @@
---
title: Version 1.0.3
version: "1.0.3"
date: 2022-08-12
description: Version 1.0.3
---
## Added
Commands:
- /chartfib
- /disc wsb
- /disc trendingst
- /dd financials
You can run /help to see these.
## Changed
Chart Changes:
- More Chart Style Settings changes - Should be almost done here
- Sizing of chart is smaller now
- Adjusted indicator opacity
- Added AH change to chart
- Made PM/AH/Price LARGER
- Adjusted Candle Color to not be so bright on Green
- Added Yest Close Line and fixed scaling
## Fixed
- PM Screener not getting correct data

View File

@@ -0,0 +1,28 @@
---
title: Version 1.0.4
version: "1.0.4"
date: 2022-08-16
description: Version 1.0.4
---
## Added
Commands:
- /dd divinfo
- /dd ytd
- /econ yieldcurve
- /chartsr
- /heatmap
You can run /help to see these.
## Changed
Changes:
- old /heatmap is now /heatchart (makes more sense)
- changed positioning of numbers on chartfib + expanding line
- Added small candle border to Daily/Monthly/Weekly charts
## Fixed
- PM Screener not getting correct data - again...

View File

@@ -0,0 +1,31 @@
---
title: Version 1.0.5
version: "1.0.5"
date: 2022-08-30
description: Version 1.0.5
---
## Added
Commands:
- /pop 1d
- /pop 1h
- /watchlist - (Each user gets 3 stocks for free signup)
- /heatmap crypto
- /cc (for the quick c5m)
- /fun urban
- /fun flip
- /fun 8ball
You can run /help to see these.
## Changed
Changes:
- /alerts - Alerts have been refactored to include Stocks and Forex now
- For most Flow and Darkpool commands you should now see much more data - Added Pages
- Changed a few commands to be more mobile friendly - (TA - PM/AH Next update)
## Fixed
- Chart bug with no PM data
- "Change" column on one of the screeners

View File

@@ -0,0 +1,26 @@
---
title: Version 1.0.6
version: "1.0.6"
date: 2022-09-12
description: Version 1.0.6
---
## Added
Commands:
No changes
## Changed
### Charts
- Candles should be easier to see now
- Reduced gaps on candles
- Charts should look more "zoomed"
- Increased size of text in some areas
### Tables
- All text should be larger and easier to read for Mobile and Desktop
- Tables will now use the same settings as your chart settings
- Branding on charts is now consistent
## Fixed
No changes

View File

@@ -0,0 +1,40 @@
---
title: Version 1.0.7
version: "1.0.7"
date: 2022-09-12
description: Version 1.0.7
---
## Added
Commands:
### Stocks:
- /markets - Provides a nice overview of the market with adv / decliners relative to change and 50d/200d MA
- /scr pm_all - Displays all available pre-market screeners
- /scr ah_all - Displays all available after-hours screeners
### Crypto:
- /crypto tvl - Get protocols historical TVL.
- /crypto defi table - Get top DeFi protocols
- /crypto defi chart - Chart of top 20 defi protocols by TVL
- /crypto top - Get top cryptos and info
- /crypto bio - Get fundamental information about a crypto.
- /crypto fees - Fees on a certain date of top crypto protocols
- /crypto compfees - Get protocol fees over time.
- /crypto ir - Returns a table of issuance rate of top crypto protocols.
### NFT:
- /nft top - Get Top NFT Collections from Ethereum Chain
- /nft collection - Get NFT collection data from Ethereum network for the specified slug.
- /nft chart - Returns NFT chart for floor price and sales on the specified slug.
- REMOVE:
- /fidelity - They made this so you have to be logged in now :(
## Changed
No changes
## Fixed
- Fixed small bug when saving watchlist
- Adjusted some tickers sizing on charts

View File

@@ -0,0 +1,17 @@
---
title: Version 1.0.8
version: "1.0.8"
date: 2022-10-13
description: Version 1.0.8
---
## Added
### Stocks
- /scr technical - Added "Overbought" and "Oversold" to Screener - Calcs are based on RSI 14
## Changed
- /flow day - Added ability to filter on - Expiration Date | Strike | Option Type - ex. "/flow day ticker:AMD expiry:2023-01-20 strike:75 opt_type:Calls"
## Fixed
- No Changes

View File

@@ -0,0 +1,30 @@
---
title: Current - Version 2.0.0
version: "2.0.0"
date: 2022-10-26
description: Version 2.0.0
sidebar_position: 0
---
## Added
### Telegram Support
- OpenBB Bot is now available on telegram - you can add it <a href="https://openbb.co/bot-telegram" rel="noopener noreferrer" target="_blank" className="_hyper-link">here</a>
### Billboard Messages
- With a premium server account you can now edit the billboard messages users see in your server. You can edit this on the [my.openbb.co](https://my.openbb.co) dash.
Commands:
- /autopost add - Added Auto Posting to bot! (Finally :D ) You can now schedule autoposts for your server with a free server plan or premium plan
## Changed
### Pricing
- You can read more about the pricing change <a href="https://openbb.co/blog/openbb-bot-price-change" rel="noopener noreferrer" target="_blank" className="_hyper-link">here</a> - TLDR - It's cheaper now :)
## Fixed
No Changes

View File

@@ -0,0 +1,4 @@
{
"label": "FAQs",
"position": 4
}

91
website/content/bot/faqs/generic.md vendored Normal file
View File

@@ -0,0 +1,91 @@
---
title: Generic
sidebar_position: 1
description: TBD
keywords:
[
installation,
installer,
install,
guide,
mac,
windows,
linux,
python,
github,
macos,
how to,
explanation,
openbb terminal,
]
---
## Generic
<details><summary>How Do I Link My OpenBB Bot Account?</summary>
After you signup for an OpenBB Bot plan you can link your accounts from <a href="https://my.openbb.co/app/bot" class="_hyper-link">here</a>
</details>
<details><summary>Can I try an OpenBB Bot plan?</summary>
You can try a preview of any plan by just running commands on a server that has OpenBB Bot, like <a href='https://my.openbb.co/discord' class='_hyper-link'>OpenBB Discord</a>. We offer a limited amount of daily commands.
</details>
<details><summary>Will my OpenBB Bot plan renew at the end of the billing cycle?</summary>
Yes, plans renew automatically at the end of the monthly and yearly billing cycles. You can cancel your plan at any time, before the end of the billing cycle, and it will not auto-renew anymore.
</details>
<details><summary>Can I get a refund on my OpenBB Bot?</summary>
Since we offer a free command tier to try commands we don't offer refunds as you have had ample time to try the service and make a decision.
</details>
<details><summary>If I sign up for OpenBB Bot do I get access on all platforms?</summary>
Yes! You will have access on Discord, and other platforms as we add support.
</details>
<details><summary>If I cancel OpenBB Bot subscription do I still have access?</summary>
No, you will lose your access but you get a credit on your account of the prorated amount until the end of your current billing cycle.
</details>
<details><summary>What's the difference in an individual plan and server plan on OpenBB Bot?</summary>
An individual plan gives your account access to OpenBB Bot while a server plan gives the whole server access. An individual plan carries more perks with it than a server plan, which you can find by clicking on the plan.
</details>
<details><summary>I added the bot but still don't see slash commands, what do I do?</summary>
<img class="mb-8" src="https://assets-global.website-files.com/5f9072399b2640f14d6a2bf4/625ddbedd330d37960463537_Untitled.png" />
Just head to <b>Server Settings → Integrations</b> and then <b>click ‘Manage’ next to an app</b>, where you will behold a new, shiny, and dare we say <i>dazzling</i>, new surface.
<ul class="list-disc my-4 ml-4">
<li>Use toggles to modify which members can use commands</li>
<li>Use toggles to modify which channels allow commands</li>
</ul>
There’s also a command-specific list, where you can make customized permissions for each command.
<ul class="list-disc my-4 ml-4">
<li>By default, these are all synced to the command permission at the top.</li>
<li>You can unsync an individual command to make further customizations.</li>
</ul>
For more information click <a rel="noreferrer noopener" target="_blank" href="https://discord.com/blog/slash-commands-permissions-discord-apps-bots" class="_hyper-link">here</a>.
</details>

23
website/content/bot/faqs/individual.md vendored Normal file
View File

@@ -0,0 +1,23 @@
---
title: Individual
sidebar_position: 2
description: TBD
keywords:
[
installation,
installer,
install,
guide,
mac,
windows,
linux,
python,
github,
macos,
how to,
explanation,
openbb terminal,
]
---
## Individual

23
website/content/bot/faqs/server.md vendored Normal file
View File

@@ -0,0 +1,23 @@
---
title: Server
sidebar_position: 3
description: TBD
keywords:
[
installation,
installer,
install,
guide,
mac,
windows,
linux,
python,
github,
macos,
how to,
explanation,
openbb terminal,
]
---
## Server

10
website/content/bot/guides.md vendored Normal file
View File

@@ -0,0 +1,10 @@
---
title: Guides
sidebar_position: 2
description: TBD
keywords: [installation, installer, install, guide, mac, windows, linux, python, github, macos, how to, explanation, openbb, sdk, api, pip, pypi,]
---
## Guides
TBD

56
website/content/bot/index.md vendored Normal file
View File

@@ -0,0 +1,56 @@
---
sidebar_position: 1
keywords:
[
getting started,
openbb,
discord,
telegram,
beginner guide,
how to use openbb bot,
introduction,
intro,
how-to,
how to,
openbb bot,
]
description: OpenBB Bot is a chatting bot for investment research that provides access to high quality financial data for both individual investors and online communities.
---
import Card from "@site/src/components/General/Card";
# OpenBB Bot
OpenBB Bot is a chatting bot for Discord and Telegram which provides access to high quality financial data for both individual investors and online communities.
With OpenBB Bot, we offer free access to hundreds of commands ranging from stock data, options, screeners, darkpool info, crypto, nft, short data, and more!
OpenBB Bot was created to give individual users access to high quality financial data. We know our users love to invest and they also want to be part of a community and share ideas with their friends quickly and easily. Our Bot allows quick access to actionable market data to make you and your community better informed investors.
---
<Card
type="bot"
title="What is OpenBB Bot?"
description="OpenBB Bot is a chatting bot for investment research that provides access to high quality financial data for both individual investors and online communities."
/>
<Card
type="bot"
title="How can I add OpenBB Bot to my community?"
description="Instructions to add OpenBB Bot to your community can be found under the installation section."
/>
---
### Getting Started
To know more about OpenBB Bot, you can start by reading the [Installation Guide](/bot/installation).
### Using OpenBB Bot
To learn how to use OpenBB Bot, you can start by reading the [Basics Guide](/bot/guides).
### Bot Reference
The Reference section is a complete list of all functions available for OpenBB Bot. It can be found [here](/bot/reference/).

53
website/content/bot/installation.md vendored Normal file
View File

@@ -0,0 +1,53 @@
---
title: Installation
sidebar_position: 1
description: How to get started with OpenBB Bot
keywords: [installation, install, install openbb bot, guide, how to, explanation, openbb bot, openbb, discord, telegram,]
---
import AddBotDialog from "@site/src/components/General/AddBot";
## Adding Bot to your Server
To add the bot to your server click on one of the links for your respective platform and then follow the instructions below.
<AddBotDialog
/>
---
# Discord - First Time Setup
A pop-up window will open, asking you to log in to your Discord account and allow the bot access.
<img src="https://openbb-assets.s3.amazonaws.com/docs/bot_docs/discord_step_1.png" alt="discord bot setup step 1" width="40%" height="40%" />
Once you log in, you’ll see a window asking for permission to access your account. Locate the “Add to Server” drop-down menu and click on it.
<img src="https://openbb-assets.s3.amazonaws.com/docs/bot_docs/discord_step_2.png" alt="discord bot setup step 2" width="40%" height="40%" />
This will open a list of Discord servers where you can add a bot. Select your server and press “Continue”.
Review permissions that the bot requests on your server. Select and deselect based on your needs, we recommend all the default settings in order to experience everything the bot has to offer. Click on “Authorize” when you’re ready.
<img src="https://openbb-assets.s3.amazonaws.com/docs/bot_docs/discord_step_3.png" alt="discord bot setup step 3" width="40%" height="40%" />
Congratulations! You’ve successfully added a bot to your Discord server.
---
# Telegram - First Time Setup
After clicking on the Add to Telegram button it should open a chat with our OpenBB Bot.
<img src="https://openbb-assets.s3.amazonaws.com/docs/bot_docs/telegram_step_1.png" alt="telegram bot setup step 1" width="40%" height="40%" />
Go to your Telegram chat and click/tap on the Top Bar of the OpenBB Bot chat window.
<img src="https://openbb-assets.s3.amazonaws.com/docs/bot_docs/telegram_step_2.png" alt="telegram bot setup step 2" width="40%" height="40%" />
Then, you need to click on “More” and select "Add to Group or Channel" or just click "Add to Group or Channel" and select the Telegram group you want to add the chatbot to:
<img src="https://openbb-assets.s3.amazonaws.com/docs/bot_docs/telegram_step_3.png" alt="telegram bot setup step 3" width="40%" height="40%" />
Now you can verify it has the permissions required, we recommend the ones already selected, and you are ready to go!
<img src="https://openbb-assets.s3.amazonaws.com/docs/bot_docs/telegram_step_4.png" alt="telegram bot setup step 4" width="40%" height="40%" />

View File

@@ -0,0 +1,4 @@
{
"label": "Reference",
"position": 3
}

View File

@@ -0,0 +1,4 @@
{
"label": "Discord",
"position": 2
}

View File

@@ -0,0 +1,100 @@
---
title: Alerts
description: create, list, update, delete
premium: false
commands:
- "/alerts create"
- "/alerts list"
- "/alerts update"
- "/alerts delete"
---
# Alerts
## create
> Create an alert with conditions for a symbol
```format
/alerts create <ticker> <condition> <price>
```
**ticker**
- The symbol/ticker/coin of the stock/coin you want to set the alert for
**condition**
- Condition to set alert for - (Equal or Above or Equal or Below)
**price**
- Price to set the alert for
**Examples**
```
/alerts create ticker:BTCUSD condition:Equal or Above price:1000
```
```
/alerts create ticker:SPY condition:Equal or Below price:400
```
---
## list
> List all of your active alerts
```format
/alerts list
```
---
## update
> Update a condition on an active alert
```format
/alerts update <alerts> <condition> <price>
```
**alerts**
- The alert you want to update
**condition**
- Change condition here if needed
**price**
- To update the price send a new price
**Examples**
```
/alerts update alerts: condition: price:
```
---
## delete
> Delete an active alert you have set
```format
/alerts delete <alert>
```
**alert**
- The alert you want to remove/delete
**Examples**
```
/alerts delete alert:
```

View File

@@ -0,0 +1,214 @@
---
title: Charting
description: c3m, c5m, c15m, cd, cw...
premium: false
commands:
- "/chart"
- "/c3m"
- "/c5m"
- "/c15m"
- "/cd"
- "/cw"
- "/cm"
- "/chartfib"
- "/chartsr"
---
# Charting
## chart
> Shows the candlestick chart for the ticker/interval provided
```format
/chart <ticker> <interval> [<past_days>]
```
**ticker**
- The symbol/ticker/coin of the stock you want the chart of
**interval**
- The interval you want to chart - Current valid options are : Daily, Weekly, Monthly, 1-5-10-15-30 Minute, 1 hour, or 4 hour.
**[past_days]** - _optional_
- Amount of days to show for the Interval
**Examples**
```
/chart ticker:AMD interval:5 minute past_days:0
```
```
/chart ticker:AMD interval:Daily
```
---
## c3m
> Shows an intraday 3m candlestick chart for the ticker provided
```format
/c3m <ticker>
```
**ticker**
- The symbol/ticker/coin of the stock you want the chart of
**Examples**
```
/c3m ticker:AMD
```
---
## c5m
> Shows an intraday 5m candlestick chart for the ticker/coin provided
```format
/c5m <ticker>
```
**ticker**
- The symbol/ticker/coin of the ticker/coin you want the chart of
**Examples**
```
/c5m ticker:AMD
```
---
## c15m
> Shows an intraday 15m candlestick chart for the ticker provided
```format
/c15m <ticker>
```
**ticker**
- The symbol/ticker/coin of the stock you want the chart of
**Examples**
```
/c15m ticker:AMD
```
---
## cd
> Shows a daily candlestick chart for the ticker/coin provided
```format
/cd <ticker>
```
**ticker**
- The symbol/ticker/coin of the stock you want the chart of
**Examples**
```
/cd ticker:AMD
```
---
## cw
> Shows a weekly candlestick chart for the ticker/coin provided
```format
/cw <ticker>
```
**ticker**
- The symbol/ticker/coin of the stock you want the chart of
**Examples**
```
/cw ticker:AMD
```
---
## cm
> Shows a monthly candlestick chart for the ticker/coin provided
```format
/cm <ticker>
```
**ticker**
- The symbol/ticker/coin of the stock you want the chart of
**Examples**
```
/cm ticker:AMD
```
---
## chartfib
> Plots the Fibonacci levels for the ticker provided
```format
/chartfib <ticker>
```
**ticker**
- The symbol/ticker/coin of the stock you want the chartfib of
**Examples**
```
/chartfib ticker:AMD
```
---
## chartsr
> Displays Support and Resistance Levels for the ticker provided
```format
/chartsr <ticker> **[interval]**
```
**ticker**
- The symbol/ticker/coin of the stock you want the chartfib of
**[interval]** - _optional_
- interval in minutes for the chart. Defaults to Daily with no selection
**Examples**
```
/chartsr ticker:AMC
```
```
/chartsr ticker:AMC interval:5 minute
```

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,158 @@
---
title: Darkpool
description: topsum, sectors, summary, allprints...
premium: true
commands:
- "/dp topsum"
- "/dp sectors"
- "/dp summary"
- "/dp allprints"
- "/dp allblocks"
- "/dp bigprints"
---
# darkpool
## topsum
> Top Total Block & Dark Pool data.
```format
/dp topsum
```
**Examples**
```
/dp topsum
```
---
## levels
> Biggest Levels for All Prints over last X days.
```format
/dp levels <ticker> <days>
```
**ticker**
- The ticker to query for
**days**
- The number of days to return
**Examples**
```
/dp levels ticker:TSLA days:10
```
---
## sectors
> Summary of all prints by % of MarketCap by Sector
```format
/dp sectors <days> <sector>
```
**days**
- The number of days to return
**sector**
- The sector to select for the query
```format
/dp sectors days:5 sector:Basic Materials
```
---
## summary
> Summary of all prints by % of MarketCap
```format
/dp summary <days> <sort>
```
**days**
- The number of days to return
**sort**
- Sort by market cap, float, total or short percentage
**Examples**
```
/dp summary days:10 sort:MarketCap
```
---
## allprints
> Last 15 Combination of Dark Pool and Blocks.
```format
/dp allprints <ticker>
```
**ticker**
- The symbol/ticker of the stock you want to lookup
**Examples**
```
/dp allprints ticker:AMD
```
---
## allblocks
> Last 15 Combination of Block Trades only
```format
/dp allblocks <ticker>
```
**ticker**
- The symbol/ticker of the stock you want to lookup
**Examples**
```
/dp allblocks ticker:AMD
```
---
## bigprints
> Combination of Dark Pool and Blocks - Largest over x amount of days
```format
/dp bigprints <days>
```
**days**
- The number of days to return
**Examples**
```
/dp bigprints days:6
```

View File

@@ -0,0 +1,116 @@
---
title: Discovery
description: splits, senate, house, fgindex, ipolist...
premium: false
commands:
- "/disc splits"
- "/disc senate"
- "/disc house"
- "/disc fgindex"
- "/disc ipolist"
- "/disc contracts"
- "/disc holidays"
- "/disc wsb"
- "/disc trendingst"
---
# Discovery
## splits
> List of recent Stock splits for all tickers.
```format
/disc splits
```
---
## senate
> Displays recent senate trades for all tickers.
```format
/disc senate
```
---
## house
> Displays recent House trades for all tickers
```format
/disc house
```
---
## fgindex
> Displays Fear & Greed Index - Investor Sentiment - CNNMoney
```format
/disc fgindex
```
---
## ipolist
> Displays 10 Upcoming and Recent IPO's.
```format
/disc ipolist
```
---
## contracts
> Displays Top 15 Government contracts by amount for all tickers.
```format
/disc contracts
```
---
## holidays
> Displays Upcoming Market Holidays.
```format
/disc holidays
```
---
## arktrades
> Displays trades made by ARK ETF
```format
/disc arktrades
```
---
## wsb
> Display Top 15 Trending Stocks - WSB (WallStreetBets)
```format
/disc wsb
```
---
## trendingst
> Display top 15 Trending Stocks - StockTwits
```format
/disc trendingst
```

View File

@@ -0,0 +1,387 @@
---
title: Due Diligence
description: ph, ah, shortrate, news, earnings, bio, ermove...
premium: false
commands:
- "/dd pm"
- "/dd ah"
- "/dd splits"
- "/dd earnings"
- "/dd nexter"
- "/dd bio"
- "/dd ermove"
- "/dd analyst"
- "/dd pt"
- "/dd est"
- "/dd supplier"
- "/dd customer"
- "/dd sec"
- "/dd insiders"
- "/dd arktrades"
- "/dd instholdings"
- "/dd financials"
- "/dd divinfo"
- "/dd ytd"
---
# Due Diligence
## pm
> Displays premarket data for a given stock ticker
```format
/dd pm <ticker>
```
**ticker**
- The symbol/ticker of the stock you want the premarket info for
**Examples**
```
/dd pm ticker:AMD
```
---
## ah
> Displays afterhours data for a given stock ticker
```format
/dd ah <ticker>
```
**ticker**
- The symbol/ticker of the stock you want the afterhours info for
**Examples**
```
/dd ah ticker:AMD
```
---
## splits
> List of recent Stock splits for a ticker
**Command**
```format
/dd splits <ticker>
```
**ticker**
- The symbol/ticker of the stock you want the splits for
**Examples**
```
/dd splits ticker:AMD
```
---
## earnings
> Display Earnings that are expected to occur in the next business days. (Sorted by market cap)
```format
/dd earnings <day>
```
**day**
- The Date you want to see the earnings for. Format: YYYY-MM-DD
**Examples**
```
/dd earnings day:2022-07-29
```
---
## nexter
> Returns next Earnings Date for a stock.
```format
/dd nexter <ticker>
```
**ticker**
- The symbol/ticker of the stock you want the next earnings date for
**Examples**
```
/dd nexter ticker:AMD
```
---
## bio
> Displays a Stock's dd Info and other information.
```format
/dd bio <ticker>
```
**ticker**
- The symbol/ticker of the stock you want the bio of
**Examples**
```
/dd bio ticker:AMD
```
---
## ermove
> Display implied move for a stock based on option prices.
```format
/dd ermove <ticker>
```
**ticker**
- The symbol/ticker of the stock you want the earnings move of
**Examples**
```
/dd ermove ticker:AMD
```
---
## analyst
> Displays analyst recommendations.
```format
/dd analyst <ticker>
```
**ticker**
- The symbol/ticker of the stock you want the analyst ratings for
**Examples**
```
/dd analyst ticker:AMD
```
---
## pt
> Displays chart with price targets.
```format
/dd pt <ticker>
```
**ticker**
- The symbol/ticker of the stock you want to query
**Examples**
```
/dd pt ticker:AMD
```
---
## est
> Displays earning estimates.
```format
/dd est <ticker>
```
**ticker**
- The symbol/ticker of the stock you want to query
**Examples**
```
/dd est ticker:MMM
```
---
## supplier
> Retrieve list of suppliers for specified company
```format
/dd supplier <ticker>
```
**ticker**
- The symbol/ticker of the stock you want to query
**Examples**
```
/dd supplier ticker:AMD
```
---
## customer
> Retrieve list of customers for specified company
```format
/dd customer <ticker>
```
**ticker**
- The symbol/ticker of the stock you want to query
**Examples**
```
/dd customer ticker:AMD
```
---
## sec
> Displays recent SEC filings.
```
/dd sec <ticker>
```
**ticker**
- The symbol/ticker of the stock you want to query
**Examples**
```
/dd sec ticker:AMD
```
---
## insiders
Displays 15 latest insider transactions for given stock
```format
/dd insiders <ticker>
```
**ticker**
- The symbol/ticker of the stock you want to query
**Examples**
```
/dd insiders ticker:AMD
```
---
## instholdings
> Displays top 15 Institutional Holdings for given stock
```format
/dd instholdings <ticker>
```
**ticker**
- The symbol/ticker of the stock you want to query
**Examples**
```
/dd instholdings ticker:AMD
```
---
## financials
> Gives Total Assets, Cash, Debt, Liabilities, Rev for Company
```format
/dd financials <ticker>
```
**ticker**
- The symbol/ticker of the stock you want to query
**Examples**
```
/dd financials ticker:AMD
```
---
## divinfo
> Display dividend information for a stock.
```format
/dd divinfo <ticker>
```
**ticker**
- The symbol/ticker of the stock you want to query
**Examples**
```
/dd divinfo ticker:AAPL
```
---
## ytd
> Displays Period Performance for a stock
```format
/dd ytd <ticker>
```
**ticker**
- The symbol/ticker of the stock you want to query
**Examples**
```
/dd ytd ticker:AAPL
```

View File

@@ -0,0 +1,119 @@
---
title: Economy
description: calendar, currencies, indices, commodities...
premium: false
commands:
- "/econ calendar"
- "/econ currencies"
- "/econ indices"
- "/econ commodities"
- "/econ usbonds"
- "/econ glbonds"
- "/econ revrepo"
- "/econ fedrates"
- "/econ yieldcurve"
---
# Economy
## calendar
> Displays Economic Calendar of events
```format
/econ calendar
```
---
## currencies
> Create an alert with conditions for a symbol
```format
/econ currencies
```
---
## indices
> US indices overview
```format
/econ indices
```
---
## commodities
> Futures and commodities overview.
```format
/econ commodities
```
---
## usbonds
> US bonds overview.
```format
/econ usbonds
```
---
## glbonds
> Global bonds overview.
```format
/econ glbonds
```
---
## revrepo
> Displays Reverse Repo.
```format
/econ revrepo [<days>]
```
**[days]** - _optional_
- The number of days to display. Default : 50
**Examples**
```
/econ revrepo days:35
```
```
/econ revrepo
```
---
## fedrates
> Upcoming Federal Rate decision dates and chances
```format
/econ fedrates
```
---
## yieldcurve
> Displays US Bonds yield curve
```format
/econ yieldcurve
```

View File

@@ -0,0 +1,53 @@
---
title: ETFs
description: tops, holdings
premium: false
commands:
- "/etf tops"
- "/etf holdings"
---
# ETFs
## tops
> Displays ETF's Top Gainers/Decliners, Most Active.
```format
/etf tops <sort>
```
**sort**
- Sort by Top Gainers, Top Decliners, or Most Active
**Examples**
```
/etf tops sort:Top Gainers
```
---
## holdings
> Displays ETF's Holdings.
```format
/etf holdings <etf> [<num>]
```
**etf**
- ETF Symbol
**[num]** - _optional_
- Amount of holdings to display. Default 15
**Examples**
```
/etf holdings etf:SPY
```
```
/etf holdings etf:SPY num:25
```

View File

@@ -0,0 +1,278 @@
---
title: Flow
description: opening, day, bigflow, prem, weekly, summary...
premium: true
commands:
- "/flow unu"
- "/flow opening"
- "/flow day"
- "/flow bigflow"
- "/flow prem"
- "/flow weekly"
- "/flow summary"
- "/flow sectors"
- "/flow sumexp"
- "/flow sumweek"
- "/flow sumday"
- "/flow sumtop"
---
# Flow
## unu
> Unusual Options Trades over 100k Prem. - Vol > OI
```format
/flow unu
```
---
## opening
> Top 20 flow by Premium for a stock with opening condition - Vol > OI
```format
/flow opening <ticker>
```
**ticker**
- Ticker symbol you want to lookup
Examples
```
/flow opening ticker:AMD
```
---
## day
> Returns the most recent flow for a stock
```format
/flow day <ticker> [expiry] [strike] [opt_type]
```
**ticker**
- Ticker symbol you want to lookup
**[expiry]** - _optional_
- Filter last flow for the provided expiration date that happened today - YYYY-MM-DD format
**[strike]** - _optional_
- Filter on the strike for flow -
**[opt_type]** - _optional_
- Filter on option type - Can be "C" - Calls or "P" - Puts
Examples
```
/flow day ticker:AMD
```
```
/flow day ticker:AMD expiry:2022-07-29 strike:60 opt_type:Puts
```
```
/flow day ticker:AMD expiry:2022-07-29 strike:60
```
---
## bigflow
> Returns the top 20 largest flow by premium for a stock
```format
/flow bigflow <ticker>
```
**ticker**
- Ticker symbol you want to lookup
Examples
```
/flow bigflow ticker:AMD
```
---
## weekly
> Top 20 flow by Premium for a stock with weekly expiration
```format
/flow weekly <ticker>
```
**ticker**
- Ticker symbol you want to lookup
Examples
```
/flow weekly ticker:AMD
```
---
## prem
> Returns a chart with sum of premium per day by call/put
```format
/flow prem <ticker>
```
**ticker**
- Ticker symbol you want to lookup
Examples
```
/flow prem ticker:AMD
```
---
## summary
> Summary of all flow by % of MarketCap
```format
/flow summary <days> <sort>
```
**days**
- The number of days to look back
**sort**
- Field to sort by - Can be : MarketCap, Float, Total, Short Percentage
Examples
```
/flow summary days:5 sort:Float
```
```
/flow summary days:5 sort:Short Percentage
```
---
## sectors
> Summary of all flow by % of MarketCap by Sector
```
/flow sectors <days> <sector>
```
**days**
- The number of days to look back
**sector**
- Sector to filter by - Basic Materials | Energy | Communication Services | Consumer Cyclical | Consumer Defensive | Financial | Healthcare | Industrials | Real Estate | Technology | Utilities
Examples
```
/flow sectors days:5 sector:Energy
```
```
/flow sectors days:2 sector:Communication Services
```
---
## sumday
> Graph Today's Total Premium of a stock.
```format
/flow sumday <ticker>
```
**ticker**
- The ticker/symbol to look up
Examples
```
/flow sumday ticker:AMD
```
---
## sumweek
> Graph Total Premium weekly summary of a stock.
```format
/flow sumweek <ticker>
```
**ticker**
- The ticker/symbol to look up
Examples
```
/flow sumweek ticker:AMD
```
---
## sumexp
> Flow summary by expiration date
```format
/flow sumexp <ticker> <expiry>
```
**ticker**
- The ticker/symbol to look up
**expiry**
- The expiration date to lookup
Examples
```
/flow sumexp ticker:AMD expiry:2022-07-29
```
---
## sumtop
> Top flow for the day Calls vs Puts by ticker
```format
/flow sumtop
```

View File

@@ -0,0 +1,62 @@
---
title: Fun
description: 8ball, flip, urban
premium: false
commands:
- "/fun 8ball"
- "/fun flip"
- "/fun urban"
---
# Fun
## 8ball
> Ask 8ball a question
```format
/fun 8ball <question>
```
**question**
- Make sure its in the form of a question
**Examples**
```
/fun 8ball question:Will I make money today?
```
---
## flip
> Flip a coin for your Witcher!
```format
/fun flip
```
**Examples**
```
/fun flip
```
---
## Urban
> Look up a word in the urban dictionary - be careful
```format
/fun urban <word>
```
**word**
- enjoy the lookup
**Examples**
```
/fun urban word:Shill
```
---

View File

@@ -0,0 +1,213 @@
---
title: General
description: autopost, watchlist, markets, news, quote, futures, ta, pop
premium: false
commands:
- "/autopost"
- "/watchlist"
- "/news"
- "/markets"
- "/quote"
- "/futures"
- "/ta"
- "/heatmap"
- "/heatchart"
- "/pop"
---
# General
## autopost
> Set up Autoposting for your server - (Server Only)
```format
/autopost add
```
**add** - _optional_
- If you want to add autoposts to your server
**list** - _optional_
- If you want to list all current autoposts
**remove** - _optional_
- If you want to remove an autopost from your server channel
**Examples**
```
/autopost add
```
```
/autopost list
```
```
/autopost remove
```
## watchlist
> Display the tickers in your watchlist - Registered users get 3 for free!
```format
/watchlist [<add>] [<edit>]
```
**add** - _optional_
- How to add more tickers to your watchlist
**edit** - _optional_
- If you want to remove symbols you can run add this optional parameter
**Examples**
```
/watchlist
```
```
/watchlist add:AMD
```
```
/watchlist add:AMD,GOOG,TSLA
```
```
/watchlist edit:Remove
```
## news
> Display the most recent news for ticker
```format
/news <ticker>
```
**ticker**
- The symbol/ticker/coin of the stock/coin you want to query
**Examples**
```
/news ticker:AMD
```
---
## markets
> Displays an overview of the market with adv / decliners relative to change and 50d/200d MA
```format
/markets
```
**Examples**
```
/markets
```
---
## quote
> Displays ticker quote info.
```format
/quote <ticker>
```
**ticker**
- The symbol/ticker/coin of the stock/coin you want to query
**Examples**
```
/quote ticker:AMD
```
---
## futures
> Displays Futures.
```format
/futures
```
---
## ta
> Displays a given stocks Technical Analysis summary.
```format
/ta <ticker>
```
**ticker**
- The symbol/ticker/coin of the stock/coin you want to query
**Examples**
```
/ta ticker:AMD
```
---
## heatmap
> Daily Heat Maps by Market. Sector is optional.
```format
/heatmap <market> <sector>
```
**market**
- Market to filter by.
**sector**
- Sector to filter by. If not specified, all sectors are returned.
**Examples**
```
/heatmap market:S&P 500
/heatmap market:S&P 500 sector:Services
```
---
## heatchart
> Daily Market Heat Chart - 15m Delayed
```format
/heatchart
```
**Examples**
```
/heatchart
```
## pop
> Display the most popular tickers over the last hour or day run on the bot
```format
/pop <timeframe>
```
**Examples**
```
/pop 1hr
```
```
/pop 1d
```

View File

@@ -0,0 +1,66 @@
---
title: Government
description: contracts, house, senate
premium: false
commands:
- "/gov contracts"
- "/gov house"
- "/gov senate"
---
# Government
## contracts
> Displays Top 15 Government contracts by amount for all tickers or for a specific ticker.
```format
/gov contracts <ticker>
```
**ticker**
- The symbol of the stock you want to query
**Examples**
```
/gov contracts ticker:GE
```
---
## house
> Displays recent house trades for all tickers or a specific ticker.
```format
/gov house <ticker>
```
**ticker**
- The symbol of the stock you want to query
**Examples**
```
/gov house ticker:GE
```
----
## senate
> Displays recent senate trades for all tickers or for a specific ticker
```format
/gov senate <ticker>
```
**ticker**
- The symbol of the stock you want to query
**Examples**
```
/gov senate ticker:GE
```

View File

@@ -0,0 +1,61 @@
---
title: Info
description: help, stats, about, serverid, support
premium: false
commands:
- "/help"
- "/info stats"
- "/info about"
- "/info serverid"
- "/info support"
---
# Info
## help
> Get started with OpenBB Bot.
```format
/help
```
---
## stats
> Bot Stats
```format
/info stats
```
---
## about
> About OpenBB Terminal
```format
/info about
```
---
## serverid
> Responds with your Server ID
```format
/info serverid
```
---
## support
> Send support ticket!
```format
/info support
```

View File

@@ -0,0 +1,921 @@
---
title: NFT
description: top, collection...
premium: false
commands:
- "/nft top"
- "/nft collection"
- "/nft chart"
---
import AvailableOptions from "@site/src/components/General/AvailableOptions";
# NFT
## top
> Get Top NFT Collections from Ethereum
```format
/nft top [sortby] [interval] [reverse]
```
**[sortby]** - _optional_
- Column to sort by (default: Market Cap) - can be one of : Market Cap/ Floor Price Change / Volume / Sales
**[interval]** - _optional_
- Time interval to display Sales/Volume/Floor Price (default: 1d) - can be one of : 1d / 7d / 30d / 90d
**[reverse]** - _optional_
- Reverse the sort order (default: No) - Yes/No
**Examples**
```
/nft top
```
```
/nft top sortby: Market Cap reverse: Yes
```
---
## collection
> Get NFT collection data from Ethereum network for the specified slug. Returns ranking, price info, supply, and much more.
```format
/nft collection <slug>
```
**slug**
- The nft you want the collection info for
<AvailableOptions
label="Collections"
allOptions={[
"bored-ape-yacht-club",
"cryptopunks",
"mutant-ape-yacht-club",
"the_sandbox",
"otherdeed",
"Decentraland",
"autoglyphs",
"clonex",
"chromie-squiggle-art-blocks-curated",
"proof-moonbirds",
"fidenza-art-blocks-curated",
"azuki",
"doodles",
"bored-ape-kennel-club",
"meebits",
"ringers-art-blocks-curated",
"veefriends",
"proof-collective",
"damien-hirst-the-currency",
"space-doodles",
"cool-cats",
"pudgy-penguins",
"nouns",
"digidaigaku",
"world-of-women",
"renga-black-box",
"rtfkt-mnlth",
"squiggly",
"fluf-world",
"exosama-expect-chaos",
"bored_ape_chemistry_club",
"gutter-cat-gang",
"adidas-originals-into-the-metaverse-phase-1-and-2",
"beanz-official",
"the-eternal-pump",
"gazers",
"cryptodickbutts",
"invisible-friends",
"deafbeef",
"v1-cryptopunks-wrapped",
"asm-aifa-genesis",
"archetype-art-blocks-curated",
"creepz-genesis",
"veefriends-series-2",
"the-potatoz",
"beeple-everydays",
"cryptoadz",
"moonbirds-oddities",
"cyberkongz-vx",
"goblintownwtf",
"murakami-flowers",
"joyworld-joys",
"mfers",
"dodgers-mlb-crypto",
"neo-tokyo-identities",
"forgotten-runes-wizards-cult",
"grifters-by-xcopy",
"dooplicator",
"cyberbrokers",
"etheria",
"renga",
"deadfellaz",
"wolf-game",
"sappy-seals",
"loot",
"10ktf",
"meridian-art-blocks-playground",
"beeple-genesis-collection",
"ikb-cachet-de-garantie",
"elevated-deconstructions-art-blocks-curated",
"nft-worlds",
"curio-cards",
"treeverse",
"chimpers-nft",
"the-shiboshis",
"hashmasks",
"jrny-nft-club",
"anticyclone-art-blocks-curated",
"where-my-vans-go",
"collectvox",
"beeple-spring-summer-collection",
"asm-brains",
"subscapes-art-blocks-curated",
"akutars",
"collectvoxmirandus",
"world-of-women-galaxy",
"0xMons",
"loomlocknft",
"onchainmonkey",
"metahero-universe-generative",
"blitmap",
"psychedelics-anonymous-genesis",
"nftrees",
"neo-tokyo-part-4-land-deeds",
"hapeprime",
"mooncats",
"adam-bomb-squad",
"io-imaginary-ones",
"rareapepeyachtclub",
"realms-for-adventurers",
"adidas-originals-capsule-collection",
"mutant-garden-seeder",
"genesis-art-blocks-curated",
"max-pain-and-frens-by-xcopy",
"cryptoskulls",
"rumble-kong-league",
"rug-radio-genesis-nft",
"lobsterdao",
"cryptovoxels",
"memories-of-qilin-art-blocks-curated",
"impostors-genesis-aliens",
"rektguy",
"gutter-dogs",
"singularity-art-blocks-curated",
"unigrids-art-blocks-curated",
"worldwide-webb-land",
"gutter-rats",
"gutter-pigeons",
"construction-token-art-blocks-curated",
"phantabear",
"premint-collector-pass",
"lazy-lions",
"beeple-5000-days-collection",
"cool-pets-nft",
"milady",
"portal-art-blocks-playground",
"boss-beauties",
"timeless-characters",
"fluf-world-thingies",
"anonymice",
"screens-art-blocks-curated",
"ledger-market-pass-genesis-edition",
"fragments-of-an-infinite-field-art-blocks-curated",
"vaynersports-pass-vsp",
"mcgoblinwtf",
"colorglyphs",
"merge",
"cryptocubes",
"byopills",
"prime-ape-planet-pap",
"zombieclub-token",
"capsule-house",
"720-minutes-art-blocks-curated",
"0n1-force",
"neo-tokyo-part-2-vault-cards",
"official-moar-by-joan-cornella",
"1111-by-kevin-abosch",
"kaiju-kingz",
"supducks",
"cyberkongz-genesis",
"creature-world",
"jadu-jetpack",
"alienfrensnft",
"eulerbeats-genesis-original",
"sail-o-bots-art-blocks-factory",
"pigments-art-blocks-curated",
"nina-s-super-cool-world",
"cryptoon-goonz",
"neo-tokyo-outer-identities",
"tubby-cats",
"the-blocks-of-art-art-blocks-curated",
"angry-ape-army",
"the-blitnauts",
"metahero-universe-core-identities",
"desperate-ape-wives",
"robotos",
"habbo-avatars",
"edifice",
"supernormalbyzipcy",
"century-art-blocks-curated",
"gambling-apes",
"mekaverse",
"cryptocoven",
"mlb-champions",
"cosmic-reef-art-blocks-curated",
"the-doge-pound",
"galaxy-fight-club",
"chain-runners",
"decentraland_names",
"mutant-cats",
"fomo-dog-club",
"bastard-gan-punks-v2",
"avastars",
"dino-pals-art-blocks-factory",
"3landers",
"solvency",
"tom-sachs-rockets",
"phase-art-blocks-curated",
"crypto-bull-society",
"the-art-of-seasons",
"frammenti-art-blocks-curated",
"pegz",
"arcade-land",
"dynamic-slices-art-blocks-curated",
"cryptoarte",
"uwucrew",
"lil-heroes-by-edgar-plans",
"crypto-chicks",
"fewocious-x-rtfkt",
"eightbitme",
"slotie-nft",
"the-saudis-nft",
"sorare",
"hyperhash-art-blocks-curated",
"crypto-stamp",
"karafuru",
"adidas-wagmi-united",
"the-sevens",
"genesis-braindrops",
"purrnelopes-country-club",
"the-humanoids",
"color-study-art-blocks-playground",
"chimera-art-blocks-curated",
"ecumenopolis-art-blocks-playground",
"quantum-key",
"everai-heroes-duo",
"sneaky-vampire-syndicate",
"shitbeast",
"los-muertos-world",
"avidlines",
"galaxy-eggs",
"bapetaverse-official",
"meta-legends",
"paper-armada-art-blocks-playground",
"sidus-nft-heroes",
"foxfam",
"neo-tokyo-part-3-item-caches",
"8liens",
"inft-personality-pod-by-alethea-ai",
"playboy-rabbitars-official",
"impact-theory-founders-key",
"apparitions-art-blocks-curated",
"the-alien-boy",
"ether-orcs",
"ack-unique-editions",
"bent",
"killergf",
"animetas",
"sipherian-surge",
"ragnarok-meta",
"isekai-meta",
"podgans-braindrops",
"stepn-shoeboxes",
"skulptuur-art-blocks-curated",
"waifusion",
"bears-deluxe",
"spectron-art-blocks-curated",
"boonji-project",
"dreams-art-blocks-curated",
"nimbuds-art-blocks-curated",
"kleee02",
"kiwami-genesis",
"cryptomories",
"the-littles-nft",
"deez-nuts",
"smilesssvrs",
"og-crystals",
"algorhythms-art-blocks-curated",
"factura-by-mathias-isaksen",
"corruption-s",
"888-inner-circle",
"stoner-cats",
"chumbi-valley",
"revenants-by-alethea-ai",
"wicked-craniums",
"mr-crypto-by-racksmafia",
"shinsei-galverse",
"nifty-league-degens",
"akumu-dragonz",
"boki-nft",
"geometry-runners-art-blocks-curated",
"swampverse",
"spooky-boys-country-club",
"aerial-view-art-blocks-curated",
"jungle-freaks-by-trosley",
"gevols",
"fomoverse",
"apostles-genesis",
"ignition-art-blocks-curated",
"fvck-crystal",
"elementals-art-blocks-curated",
"furballs",
"bubble-blobby-art-blocks-curated",
"chainfaces",
"crypto-cannabis-club",
"dourdarcels",
"decentraland_wearables",
"rinascita",
"coolmans-universe",
"goatz",
"tiny-dinos",
"ether-cards-founder",
"rhythm-art-blocks-playground",
"cryptobatz-by-ozzy-osbourne",
"framergence",
"deadheads",
"time-pieces-build-a-better-future",
"party-degenerates",
"algobots-art-blocks-curated",
"dystopunks",
"alien-clock-art-blocks-playground",
"koin-games-dev-squad",
"cupcats-official",
"creepz-reptile-armoury",
"metroverse-genesis",
"vortex",
"ape-gang",
"scribbled-boundaries-art-blocks-curated",
"wonderpals",
"plasma-bears",
"hausphases",
"the-wanderers",
"muri-haus",
"gener8tive-k-compositions",
"glitch-crystal-monsters-art-blocks-curated",
"satoshibles",
"the-cryptodads",
"lives-of-asuna",
"gen-art-membership",
"we-are-all-going-to-die",
"watercolor-dreams-art-blocks-curated",
"the-n-project",
"entretiempos-art-blocks-curated",
"rituals",
"cryptoblots-art-blocks-curated",
"ghostsproject",
"trossets-art-blocks-curated",
"salt-v4",
"pulsquares",
"metabillionaire",
"punks-comic",
"bubblegum-kids",
"generativemasks",
"phototaxis-art-blocks-playground",
"heaven-computer",
"doge-pound-puppies",
"wavelength",
"dapper-dinos-nft",
"smallbros",
"cryptotrunks",
"jiometory-no-compute-art-blocks-curated",
"bulls-on-the-block",
"dotdotdots",
"crypto-pills-by-micha-klein",
"space-punks-club",
"asemica",
"poap",
"akuma-origins",
"synapses-art-blocks-curated",
"fusion-by-hideki-tsukamoto",
"peaceful-groupies",
"the-association-nft",
"gh0stly-gh0sts",
"the-vogu-collective",
"endless-nameless-art-blocks-curated",
"koala-intelligence-agency",
"divine-anarchy",
"royal-society-of-players",
"derace-horses",
"inspirals-art-blocks-curated",
"ancient-courses-of-fictional-rivers-art-blocks-curated",
"thorguards",
"27-bit-digital-art-blocks-curated",
"superlative-secret-society",
"crypto-unicorns",
"first-first-nfts",
"the-official-surreals",
"headdao",
"anonymice-breeding",
"bored-mummy-waking-up",
"ainightbirds",
"colorspace-art-blocks-curated",
"fang-gang",
"uninterested-unicorns",
"song-a-day",
"the-yakuza-cats-society",
"shinsekaicorp",
"para-bellum-art-blocks-curated",
"metasaurs",
"obits",
"autology",
"voxies",
"wicked-ape-bone-club",
"party-ape-billionaire-club",
"lonely-alien-space-club",
"animonkeys",
"alien-insects-art-blocks-playground",
"apes-in-space",
"goop-troop",
"defy-genesis-masks",
"galacticapes",
"the-alien-secret-society",
"ape-kids-club",
"flux-art-blocks-curated",
"ens-domains",
"polygonpunks",
"monaco-planet-yacht",
"solos",
"yolo-holiday",
"winter-bears",
"letswalk",
"incognito",
"al-cabones",
"adidas-for-prada",
"haki-nft",
"monkey-bet-dao",
"fast-food-punks",
"chill-frogs",
"lostsamurise",
"wizards-dragons-game",
"creepz-shapeshifterz",
"raidparty-fighters",
]}
/>
**Examples**
```
/nft collection slug: bent
```
---
## chart
> Returns NFT chart for floor price and sales on the specified slug.
```format
/nft chart <slug>
```
**slug**
- The nft you want the chart for
<AvailableOptions
label="Collections"
allOptions={[
"bored-ape-yacht-club",
"cryptopunks",
"mutant-ape-yacht-club",
"the_sandbox",
"otherdeed",
"Decentraland",
"autoglyphs",
"clonex",
"chromie-squiggle-art-blocks-curated",
"proof-moonbirds",
"fidenza-art-blocks-curated",
"azuki",
"doodles",
"bored-ape-kennel-club",
"meebits",
"ringers-art-blocks-curated",
"veefriends",
"proof-collective",
"damien-hirst-the-currency",
"space-doodles",
"cool-cats",
"pudgy-penguins",
"nouns",
"digidaigaku",
"world-of-women",
"renga-black-box",
"rtfkt-mnlth",
"squiggly",
"fluf-world",
"exosama-expect-chaos",
"bored_ape_chemistry_club",
"gutter-cat-gang",
"adidas-originals-into-the-metaverse-phase-1-and-2",
"beanz-official",
"the-eternal-pump",
"gazers",
"cryptodickbutts",
"invisible-friends",
"deafbeef",
"v1-cryptopunks-wrapped",
"asm-aifa-genesis",
"archetype-art-blocks-curated",
"creepz-genesis",
"veefriends-series-2",
"the-potatoz",
"beeple-everydays",
"cryptoadz",
"moonbirds-oddities",
"cyberkongz-vx",
"goblintownwtf",
"murakami-flowers",
"joyworld-joys",
"mfers",
"dodgers-mlb-crypto",
"neo-tokyo-identities",
"forgotten-runes-wizards-cult",
"grifters-by-xcopy",
"dooplicator",
"cyberbrokers",
"etheria",
"renga",
"deadfellaz",
"wolf-game",
"sappy-seals",
"loot",
"10ktf",
"meridian-art-blocks-playground",
"beeple-genesis-collection",
"ikb-cachet-de-garantie",
"elevated-deconstructions-art-blocks-curated",
"nft-worlds",
"curio-cards",
"treeverse",
"chimpers-nft",
"the-shiboshis",
"hashmasks",
"jrny-nft-club",
"anticyclone-art-blocks-curated",
"where-my-vans-go",
"collectvox",
"beeple-spring-summer-collection",
"asm-brains",
"subscapes-art-blocks-curated",
"akutars",
"collectvoxmirandus",
"world-of-women-galaxy",
"0xMons",
"loomlocknft",
"onchainmonkey",
"metahero-universe-generative",
"blitmap",
"psychedelics-anonymous-genesis",
"nftrees",
"neo-tokyo-part-4-land-deeds",
"hapeprime",
"mooncats",
"adam-bomb-squad",
"io-imaginary-ones",
"rareapepeyachtclub",
"realms-for-adventurers",
"adidas-originals-capsule-collection",
"mutant-garden-seeder",
"genesis-art-blocks-curated",
"max-pain-and-frens-by-xcopy",
"cryptoskulls",
"rumble-kong-league",
"rug-radio-genesis-nft",
"lobsterdao",
"cryptovoxels",
"memories-of-qilin-art-blocks-curated",
"impostors-genesis-aliens",
"rektguy",
"gutter-dogs",
"singularity-art-blocks-curated",
"unigrids-art-blocks-curated",
"worldwide-webb-land",
"gutter-rats",
"gutter-pigeons",
"construction-token-art-blocks-curated",
"phantabear",
"premint-collector-pass",
"lazy-lions",
"beeple-5000-days-collection",
"cool-pets-nft",
"milady",
"portal-art-blocks-playground",
"boss-beauties",
"timeless-characters",
"fluf-world-thingies",
"anonymice",
"screens-art-blocks-curated",
"ledger-market-pass-genesis-edition",
"fragments-of-an-infinite-field-art-blocks-curated",
"vaynersports-pass-vsp",
"mcgoblinwtf",
"colorglyphs",
"merge",
"cryptocubes",
"byopills",
"prime-ape-planet-pap",
"zombieclub-token",
"capsule-house",
"720-minutes-art-blocks-curated",
"0n1-force",
"neo-tokyo-part-2-vault-cards",
"official-moar-by-joan-cornella",
"1111-by-kevin-abosch",
"kaiju-kingz",
"supducks",
"cyberkongz-genesis",
"creature-world",
"jadu-jetpack",
"alienfrensnft",
"eulerbeats-genesis-original",
"sail-o-bots-art-blocks-factory",
"pigments-art-blocks-curated",
"nina-s-super-cool-world",
"cryptoon-goonz",
"neo-tokyo-outer-identities",
"tubby-cats",
"the-blocks-of-art-art-blocks-curated",
"angry-ape-army",
"the-blitnauts",
"metahero-universe-core-identities",
"desperate-ape-wives",
"robotos",
"habbo-avatars",
"edifice",
"supernormalbyzipcy",
"century-art-blocks-curated",
"gambling-apes",
"mekaverse",
"cryptocoven",
"mlb-champions",
"cosmic-reef-art-blocks-curated",
"the-doge-pound",
"galaxy-fight-club",
"chain-runners",
"decentraland_names",
"mutant-cats",
"fomo-dog-club",
"bastard-gan-punks-v2",
"avastars",
"dino-pals-art-blocks-factory",
"3landers",
"solvency",
"tom-sachs-rockets",
"phase-art-blocks-curated",
"crypto-bull-society",
"the-art-of-seasons",
"frammenti-art-blocks-curated",
"pegz",
"arcade-land",
"dynamic-slices-art-blocks-curated",
"cryptoarte",
"uwucrew",
"lil-heroes-by-edgar-plans",
"crypto-chicks",
"fewocious-x-rtfkt",
"eightbitme",
"slotie-nft",
"the-saudis-nft",
"sorare",
"hyperhash-art-blocks-curated",
"crypto-stamp",
"karafuru",
"adidas-wagmi-united",
"the-sevens",
"genesis-braindrops",
"purrnelopes-country-club",
"the-humanoids",
"color-study-art-blocks-playground",
"chimera-art-blocks-curated",
"ecumenopolis-art-blocks-playground",
"quantum-key",
"everai-heroes-duo",
"sneaky-vampire-syndicate",
"shitbeast",
"los-muertos-world",
"avidlines",
"galaxy-eggs",
"bapetaverse-official",
"meta-legends",
"paper-armada-art-blocks-playground",
"sidus-nft-heroes",
"foxfam",
"neo-tokyo-part-3-item-caches",
"8liens",
"inft-personality-pod-by-alethea-ai",
"playboy-rabbitars-official",
"impact-theory-founders-key",
"apparitions-art-blocks-curated",
"the-alien-boy",
"ether-orcs",
"ack-unique-editions",
"bent",
"killergf",
"animetas",
"sipherian-surge",
"ragnarok-meta",
"isekai-meta",
"podgans-braindrops",
"stepn-shoeboxes",
"skulptuur-art-blocks-curated",
"waifusion",
"bears-deluxe",
"spectron-art-blocks-curated",
"boonji-project",
"dreams-art-blocks-curated",
"nimbuds-art-blocks-curated",
"kleee02",
"kiwami-genesis",
"cryptomories",
"the-littles-nft",
"deez-nuts",
"smilesssvrs",
"og-crystals",
"algorhythms-art-blocks-curated",
"factura-by-mathias-isaksen",
"corruption-s",
"888-inner-circle",
"stoner-cats",
"chumbi-valley",
"revenants-by-alethea-ai",
"wicked-craniums",
"mr-crypto-by-racksmafia",
"shinsei-galverse",
"nifty-league-degens",
"akumu-dragonz",
"boki-nft",
"geometry-runners-art-blocks-curated",
"swampverse",
"spooky-boys-country-club",
"aerial-view-art-blocks-curated",
"jungle-freaks-by-trosley",
"gevols",
"fomoverse",
"apostles-genesis",
"ignition-art-blocks-curated",
"fvck-crystal",
"elementals-art-blocks-curated",
"furballs",
"bubble-blobby-art-blocks-curated",
"chainfaces",
"crypto-cannabis-club",
"dourdarcels",
"decentraland_wearables",
"rinascita",
"coolmans-universe",
"goatz",
"tiny-dinos",
"ether-cards-founder",
"rhythm-art-blocks-playground",
"cryptobatz-by-ozzy-osbourne",
"framergence",
"deadheads",
"time-pieces-build-a-better-future",
"party-degenerates",
"algobots-art-blocks-curated",
"dystopunks",
"alien-clock-art-blocks-playground",
"koin-games-dev-squad",
"cupcats-official",
"creepz-reptile-armoury",
"metroverse-genesis",
"vortex",
"ape-gang",
"scribbled-boundaries-art-blocks-curated",
"wonderpals",
"plasma-bears",
"hausphases",
"the-wanderers",
"muri-haus",
"gener8tive-k-compositions",
"glitch-crystal-monsters-art-blocks-curated",
"satoshibles",
"the-cryptodads",
"lives-of-asuna",
"gen-art-membership",
"we-are-all-going-to-die",
"watercolor-dreams-art-blocks-curated",
"the-n-project",
"entretiempos-art-blocks-curated",
"rituals",
"cryptoblots-art-blocks-curated",
"ghostsproject",
"trossets-art-blocks-curated",
"salt-v4",
"pulsquares",
"metabillionaire",
"punks-comic",
"bubblegum-kids",
"generativemasks",
"phototaxis-art-blocks-playground",
"heaven-computer",
"doge-pound-puppies",
"wavelength",
"dapper-dinos-nft",
"smallbros",
"cryptotrunks",
"jiometory-no-compute-art-blocks-curated",
"bulls-on-the-block",
"dotdotdots",
"crypto-pills-by-micha-klein",
"space-punks-club",
"asemica",
"poap",
"akuma-origins",
"synapses-art-blocks-curated",
"fusion-by-hideki-tsukamoto",
"peaceful-groupies",
"the-association-nft",
"gh0stly-gh0sts",
"the-vogu-collective",
"endless-nameless-art-blocks-curated",
"koala-intelligence-agency",
"divine-anarchy",
"royal-society-of-players",
"derace-horses",
"inspirals-art-blocks-curated",
"ancient-courses-of-fictional-rivers-art-blocks-curated",
"thorguards",
"27-bit-digital-art-blocks-curated",
"superlative-secret-society",
"crypto-unicorns",
"first-first-nfts",
"the-official-surreals",
"headdao",
"anonymice-breeding",
"bored-mummy-waking-up",
"ainightbirds",
"colorspace-art-blocks-curated",
"fang-gang",
"uninterested-unicorns",
"song-a-day",
"the-yakuza-cats-society",
"shinsekaicorp",
"para-bellum-art-blocks-curated",
"metasaurs",
"obits",
"autology",
"voxies",
"wicked-ape-bone-club",
"party-ape-billionaire-club",
"lonely-alien-space-club",
"animonkeys",
"alien-insects-art-blocks-playground",
"apes-in-space",
"goop-troop",
"defy-genesis-masks",
"galacticapes",
"the-alien-secret-society",
"ape-kids-club",
"flux-art-blocks-curated",
"ens-domains",
"polygonpunks",
"monaco-planet-yacht",
"solos",
"yolo-holiday",
"winter-bears",
"letswalk",
"incognito",
"al-cabones",
"adidas-for-prada",
"haki-nft",
"monkey-bet-dao",
"fast-food-punks",
"chill-frogs",
"lostsamurise",
"wizards-dragons-game",
"creepz-shapeshifterz",
"raidparty-fighters",
]}
/>
**Examples**
```
/nft chart slug: bent
```
```
/nft chart slug: bored-ape-yacht-club
```

View File

@@ -0,0 +1,471 @@
---
title: Options
description: gamma, info, topoi, unu, vol, hist, oi, mp...
premium: true
commands:
- "/op gamma"
- "/op info"
- "/op topoi"
- "/op unu"
- "/op vol"
- "/op hist"
- "/op uoastock"
- "/op highiv"
- "/op topvol"
- "/op topvoletf"
- "/op topoichange"
- "/op oi"
- "/op stats"
- "/op mp"
- "/op smile"
- "/op vsurf"
- "/op chains"
---
# Options
## itm
> Displays In-The-Money (ITM) options by expiry for a stock.
```format
/op itm <ticker>
```
**ticker**
- The ticker/symbol to look up
Examples
```
/op itm ticker:AMD
```
---
## equitypc
> Displays the Equity Put/Call Volume Ratio - from market-harmonics.com
```format
/op equitypc
```
---
## indexpc
> Displays the Index Put/Call Ratio for the market - from market-harmonics.com
```format
/op indexpc
```
---
## oichart
> Charts Total Open Interest by Strike Price.
```format
/op oichart <ticker> [<expiry>]
```
**ticker**
- The ticker/symbol to look up
**[expiry]** - _optional_
- The ticker/symbol to look up
Examples
```
/op oichart ticker:AMD
```
```
/op oichart ticker:AMD expiry:2022-07-29
```
---
## gamma
> Displays Options Gamma Levels for a Stock.
```format
/op gamma <ticker> [<expiry>]
```
**ticker**
- The ticker/symbol to look up
**[expiry]** - _optional_
- Gamma from now to expiration
Examples
```
/op gamma ticker:AMD
```
```
/op gamma ticker:AMD expiry:2022-07-29
```
---
## info
> Displays option information (volatility, IV rank etc).
```format
/op info <ticker>
```
**ticker**
- The ticker/symbol to look up
Examples
```
/op info ticker:AMD
```
---
## topoi
> Displays Top Open Interest
```format
/op topoi
```
---
## unu
> Shows Unusual Options
```format
/op unu
```
---
## vol
> Displays Options Strike Volume can add EXP date for bigger breakdown
```format
/op vol <ticker> [<expiry>]
```
**ticker**
- The ticker/symbol to look up
**expiry** - _optional_
- Expiration to query
Examples
```
/op vol ticker:AMD
```
```
/op vol ticker:AMD expiry:2022-07-29
```
---
## hist
> Displays Options Price History in a chart.
```
/op hist <ticker> <expiry> <strike> <opt_type> <interval> [<past_days>]
```
**ticker**
- The ticker/symbol to look up
**expiry**
- Expiration to query
**strike**
- Option Strike Price
**opt_type**
- Calls or Puts Calls | Puts
**interval**
- Chart Minute Interval | 1440 for Daily 15 | 30
**[past_days]** - _optional_
- Past Days to Display. Default: 5
Examples
```
/op hist ticker:AMD expiry:2022-07-29 strike:80 opt_type:Calls interval:15 past_days:5
```
```
/op hist ticker:AMD expiry:2022-07-29 strike:80 opt_type:Calls interval:15
```
---
## uoastock
> Display Top 20day Average Options Volume by ticker.
```format
/op uoastock [<price>]
```
**[price]** - _optional_
- Filter by stocks over a certain price
Examples
```
/op uoastock
```
```
/op uoastock price:50
```
---
## highiv
> Top 15 Highest IV30 Equity stocks.
```format
/op highiv
```
---
## topvol
> Top 15 Highest options volume.
```format
/op topvol
```
---
## topvoletf
> Top 15 Highest options volume ETF.
```
/op topvoletf
```
---
## topoichange
> Displays Top 15 stocks with highest OI Change.
```format
/op topoichange
```
---
## oi
> Displays OI and call/put ratio for given stock - can add EXP date too for bigger breakdown
```format
/op oi <ticker> [<expiry>]
```
**ticker**
- The ticker/symbol to look up
**[expiry]** - _optional_
- Expiration to query
Examples
```
/op oi ticker:AMC
```
```
/op oi ticker:AMC expiry:2022-07-29
```
---
## stats
> Displays Options Statistics for a stock.
```format
/op stats <ticker>
```
**ticker**
- The ticker/symbol to look up
Examples
```
/op stats ticker:AMC
```
---
## maxpain
> Displays the Max Pain on expiration date for a given stock.
```format
/op maxpain <ticker> <expiry>
```
**ticker**
- The ticker/symbol to look up
**expiry**
- Expiration to query
Examples
```
/op maxpain ticker:AMC expiry:2022-07-29
```
---
## chains
> Displays Options Chain by Expiry
```format
/op chains <ticker> <expiry> <opt_type> [<min_sp>] [<max_sp>]
```
**ticker**
- The ticker/symbol to look up
**expiry**
- Expiration to query
**opt_type**
- Calls or Puts
**[min_sp]** - _optional_
- Minimum Strike Price
**[max_sp]** - _optional_
- Maximum Strike Price
Examples
```
/op chains ticker:AMD expiry:2022-07-29 opt_type:Calls
```
```
/op chains ticker:AMD expiry:2022-07-29 opt_type:Calls min_sp:10 max_sp:100
```
---
## vsurf
> Displays Options Volatility Surface
```format
/op vsurf <ticker> <z>
```
**ticker**
- The ticker/symbol to look up
**z**
- Variable for the Z axis (Volatility, Open Interest, Last Price)
Examples
```
/op vsurf ticker:AMD z:Volatility
```
```
/op vsurf ticker:AMD z:Open Interest
```
---
## smile
> Displays Options Volatility Smile
```format
/op smile <ticker> <expiry> [<min_sp>] [<max_sp>]
```
**ticker**
- The ticker/symbol to look up
**expiry**
- Expiration to query
**[min_sp]** - _optional_
- Minimum Strike price
**[max_sp]** - _optional_
- Maximum Strike Price
Examples
```
/op smile ticker:AMD expiry:2022-07-29
```
```
/op smile ticker:AMD expiry:2022-07-29 min_sp:10 max_sp:100
```

View File

@@ -0,0 +1,80 @@
---
title: Screeners
description: technical, all, pm, ah
premium: false
commands:
- "/scr technical"
- "/scr all"
- "/scr pm"
- "/scr ah"
---
# Screeners
## technical
> Displays stock screener results according to chosen signal.
```format
/scr technical <signal>
```
**signal**
- Screener presets - Top Gainers | Top Losers | Most Active | Most Volatile | Relative Volatility | Golden Cross | Death Cross | New 52week High | New 52week Low | Unusual Volume | Overbought (RSI > 70) | Oversold (RSI < 14)
**Examples**
```
/scr technical signal:Top Gainers
```
```
/scr technical signal:Death Cross
```
---
## all
> Displays all available screeners
```format
/scr all
```
---
## pm
> Displays Pre-Market stocks according to chosen screener.
```format
/scr pm <signal>
```
**signal**
- Screener preset - Pre-Market Top Gainers | Pre-Market Top Losers | Pre-Market Most Active
**Examples**
```
/scr pm signal:Pre-Market Top Gainers
```
---
## ah
> Displays After-Hours stocks according to chosen screener.
```format
/scr ah <signal>
```
**signal**
- Screener preset - After-Hours Top Gainers | After-Hours Top Losers | After-Hours Most Active
**Examples**
```
/scr ah signal:After-Hours Top Gainers
```

View File

@@ -0,0 +1,101 @@
---
title: Shorts
description: shotvol, shortint, topshortvol, hsi...
premium: false
commands:
- "/sh shortvol"
- "/sh shortint"
- "/sh topshortvol"
- "/sh hsi"
- "/sh shortrate"
- "/sh borrowed"
---
# Shorts
## sh
> Graph of 30 day history of short volume vs vol.
```format
/sh shortvol <ticker>
```
**ticker**
- The symbol/ticker of the stock you want the short interest for
**Examples**
```
/sh shortvol ticker:AMD
```
---
## borrowed
> Displays history of borrowed shares available and fee.
```format
/sh borrowed <ticker>
```
**ticker**
- The symbol/ticker of the stock you want the short interest for
**Examples**
```
/sh borrowed ticker:AMD
```
---
## shortrate
> Display Short shares spot borrow rate sourced from Interactive Brokers.
```format
/sh shortrate <ticker>
```
**ticker**
- The symbol/ticker of the stock you want the short interest for
**Examples**
```
/sh shortrate ticker:AMD
```
---
## topshortvol
> Top 15 Short Interest Stocks per Finra
```format
/sh topshortvol
```
---
## hsi
> Show top high short interest stocks of over 20% ratio
```
/sh hsi [<num>]
```
**[num]** - _optional_
- The number of stocks to print
Examples
```
/sh hsi
```
```
/sh hsi num:4
```

View File

@@ -0,0 +1,4 @@
{
"label": "Telegram",
"position": 3
}

View File

@@ -0,0 +1,231 @@
---
title: Charting
description: c3m, c5m, c15m, cd, cw...
premium: false
commands:
- "/chart"
- "/c3m"
- "/c5m"
- "/c15m"
- "/cd"
- "/cw"
- "/cm"
- "/chartfib"
- "/chartsr"
---
# Charting
## chart
> Shows the candlestick chart for the ticker/interval provided
```format
/chart <ticker> <interval> [<past_days>]
```
**ticker**
- The symbol/ticker/coin of the stock you want the chart of
**interval**
- The interval you want to chart - Current valid options are : 1m, 5m, 10m, 15m, 30m, 60m, 1d, 1wk, 1mo
**[past_days]** - _optional_
- Amount of days to show for the Interval
**Examples**
```
/chart AMD 1d 10
```
```
/chart AMD 1d
```
---
## c3m
> Shows an intraday 3m candlestick chart for the ticker provided
```format
/c3m <ticker>
```
**ticker**
- The symbol/ticker/coin of the stock you want the chart of
**[extendedhours]** - _optional_
- Show the full extended hours chart from 4am to 8pm
**Examples**
```
/c3m AMD
```
```
/c3m AMD true
```
---
## c5m
> Shows an intraday 5m candlestick chart for the ticker/coin provided
```format
/c5m <ticker>
```
**ticker**
- The symbol/ticker/coin of the ticker/coin you want the chart of
**[extendedhours]** - _optional_
- Show the full extended hours chart from 4am to 8pm
**Examples**
```
/c5m AMD
```
```
/c5m AMD true
```
---
## c15m
> Shows an intraday 15m candlestick chart for the ticker provided
```format
/c15m <ticker>
```
**ticker**
- The symbol/ticker/coin of the stock you want the chart of
**Examples**
```
/c15m AMD
```
---
## cd
> Shows a daily candlestick chart for the ticker/coin provided
```format
/cd <ticker>
```
**ticker**
- The symbol/ticker/coin of the stock you want the chart of
**Examples**
```
/cd AMD
```
---
## cw
> Shows a weekly candlestick chart for the ticker/coin provided
```format
/cw <ticker>
```
**ticker**
- The symbol/ticker/coin of the stock you want the chart of
**Examples**
```
/cw AMD
```
---
## cm
> Shows a monthly candlestick chart for the ticker/coin provided
```format
/cm <ticker>
```
**ticker**
- The symbol/ticker/coin of the stock you want the chart of
**Examples**
```
/cm AMD
```
---
## chartfib
> Plots the Fibonacci levels for the ticker provided
```format
/chartfib <ticker>
```
**ticker**
- The symbol/ticker/coin of the stock you want the chartfib of
**Examples**
```
/chartfib AMD
```
---
## chartsr
> Displays Support and Resistance Levels for the ticker provided
```format
/chartsr <ticker> **[interval]**
```
**ticker**
- The symbol/ticker/coin of the stock you want the chartfib of
**[interval]** - _optional_
- interval in minutes for the chart. Defaults to Daily with no selection
**Examples**
```
/chartsr AMC
```
```
/chartsr AMC 1d
```

View File

@@ -0,0 +1,268 @@
---
title: Crypto
description: c, prints, bigprints, bio, defi, fees, ir...
premium: false
commands:
- "/c"
- "/prints"
- "/bigprints"
- "/tvl"
- "/defi chart"
- "/defi"
- "/bio"
- "/fees"
- "/compfees"
- "/ir"
---
# Crypto
## chart
```format
/c <symbol>
```
> Shows the candlestick chart for the ticker/interval provided
**symbol**
- The Crypto Symbol want to chart
**currency** - _optional_
- Crypto Currency. Default: USDT
**exchange** - _optional_
- Crypto Exchange. Default: binanceus
**interval** - _optional_
- Chart Interval. Default: 15m
**srlines** - _optional_
- Show Support/Resistance Lines. Default: False
**fibs** - _optional_
- Show Fibonacci Retracement Levels. Default: False
```format
/c doge
```
---
## prints
> Last 15 Crypto Prints over last 24hrs.
```format
/prints <coin>
```
**coin**
- The coin you want the prints of
**Examples**
```
/prints ada
```
---
## bigprints
> Last 15 Large Crypto Prints.
```format
/bigprints <coin>
```
**coin**
- The coin you want the large prints of
**Examples**
```
/bigprints ada
```
---
## tvl
> Get protocols historical TVL.
```format
/crypto tvl <protocols>
```
**protocols**
- comma separated list of protocols (e.g., curve,makerdao)
**Examples**
```
/tvl
```
```
/tvl curve
```
---
## defi table
> Get top DeFi protocols
```format
/defi [sortby] [chain] [reverse]
```
**[sortby]** - _optional_
- Column to sort data by (default="TVL") (e.g., Total Value Locked)
**[chain]** - _optional_
- Chain to filter by (default="all") (e.g., ethereum)
**[reverse]** - _optional_
- Reverse the sort order (default: No) - Yes/No
**Examples**
```
/defi
```
```
/defi 1hr Bitcoin
```
---
## defi chart
> Chart of top 20 defi protocols by TVL
```format
/defi chart
```
**Examples**
```
/defi chart
```
---
## top
> Get top cryptos and info
```format
/crypto top [sortby] [category] [reverse]
```
**[sortby]** - _optional_
- Column to sort data by (default="mc") (e.g., Market Cap)
**[category]** - _optional_
- Category to filter by (default="all") (e.g., stablecoins)
**[reverse]** - _optional_
- Reverse the sort order (default: No) - Yes/No
**Examples**
```
/top
```
```
/top mc marketing
```
---
## bio
> Get fundamental information about a crypto.
```format
/bio <symbol>
```
**symbol**
- Crypto symbol to check information (e.g., BTC)
**Examples**
```
/bio btc
```
---
## fees
> Fees on a certain date of top crypto protocols
```format
/fees <date>
```
**date**
- Date to get fees for (e.g., 2022-01-01)
**Examples**
```
/fees date: 2023-04-19
```
---
## compfees
> Get protocol fees over time.
```format
/compfees <project>
```
**project**
- Comma separated list of protocols (e.g., btc,eth)
**Examples**
```
/compfees doge
```
```
/compfees projects: btc,eth
```
---
## ir
> Returns a table of issuance rate of top crypto protocols.
```format
/ir
```
**Examples**
```
/ir
```

View File

@@ -0,0 +1,170 @@
---
title: Darkpool
description: topsum, sectors, summary, allprints...
premium: true
commands:
- "/topsum"
- "/sectors"
- "/summary"
- "/allprints"
- "/allblocks"
- "/alldp"
- "/bigprintsdp"
- "/levels"
---
# darkpool
## topsum
> Top Total Block & Dark Pool data.
```format
/topsum
```
**Examples**
```
/topsum
```
---
## levels
> Biggest Levels for All Prints over last X days.
```format
/levels <ticker> <days>
```
**ticker**
- The ticker to query for
**days**
- The number of days to return
**Examples**
```
/levels TSLA 10
```
---
## sectors
> Summary of all prints by % of MarketCap by Sector
```format
/sectors <days> <sector>
```
**days**
- The number of days to return
**sector**
- The sector to select for the query
```format
/sectors 5 bm
```
---
## summary
> Summary of all prints by % of MarketCap
```format
/summary <days> <sort>
```
**days**
- The number of days to return
**sort**
- Sort by market cap, float, total or short percentage
**Examples**
```
/summary 10 mc
```
---
## allprints
> Last 10 Combination of Dark Pool and Blocks.
```format
/allprints <ticker>
```
**ticker**
- The symbol/ticker of the stock you want to lookup
**Examples**
```
/allprints AMD
```
---
## alldp
> Last 15 Dark Pool Trades.
```format
/alldp <ticker>
```
**ticker**
- The symbol/ticker of the stock you want to lookup
**Examples**
```
/alldp AMD
```
---
## allblocks
> Last 15 Combination of Block Trades only
```format
/allblocks <ticker>
```
**ticker**
- The symbol/ticker of the stock you want to lookup
**Examples**
```
/allblocks AMD
```
---
## bigprints
> Combination of Dark Pool and Blocks - Largest over x amount of days
```format
/bigprintsdp <days>
```
**days**
- The number of days to return
**Examples**
```
/bigprintsdp 6
```

View File

@@ -0,0 +1,114 @@
---
title: Discovery
description: splits, senate, house, fgindex, ipolist...
premium: false
commands:
- "/splits"
- "/senate"
- "/house"
- "/fgindex"
- "/ipolist"
- "/contracts"
- "/holidays"
- "/wsb"
- "/trendingst"
---
# Discovery
## splits
> List of recent Stock splits for all tickers.
```format
/splits
```
---
## senate
> Displays recent senate trades for all tickers.
```format
/senate
```
---
## house
> Displays recent House trades for all tickers
```format
/house
```
---
## fgindex
> Displays Fear & Greed Index - Investor Sentiment - CNNMoney
```format
/fgindex
```
---
## ipolist
> Displays 10 Upcoming and Recent IPO's.
```format
/ipolist
```
---
## contracts
> Displays Top 15 Government contracts by amount for all tickers.
```format
/contracts
```
---
## holidays
> Displays Upcoming Market Holidays.
```format
/holidays
```
---
## arktrades
> Displays trades made by ARK ETF
```format
/arktrades
```
---
## wsb
> Display Top 15 Trending Stocks - WSB (WallStreetBets)
```format
/wsb
```
---
## trendingst
> Display top 15 Trending Stocks - StockTwits
```format
/trendingst
```

View File

@@ -0,0 +1,349 @@
---
title: Due Diligence
description: ph, ah, shortrate, news, earnings, bio, ermove...
premium: false
commands:
- "/pm"
- "/ah"
- "/splits"
- "/earnings"
- "/nexter"
- "/bio"
- "/ermove"
- "/analyst"
- "/pt"
- "/supplier"
- "/customer"
- "/insiders"
- "/arktrades"
- "/instholdings"
- "/financials"
- "/divinfo"
- "/ytd"
---
# Due Diligence
## pm
> Displays premarket data for a given stock ticker
```format
/pm <ticker>
```
**ticker**
- The symbol/ticker of the stock you want the premarket info for
**Examples**
```
/pm AMD
```
---
## ah
> Displays afterhours data for a given stock ticker
```format
/ah <ticker>
```
**ticker**
- The symbol/ticker of the stock you want the afterhours info for
**Examples**
```
/ah AMD
```
---
## splits
> List of recent Stock splits for a ticker
### Command
```format
/splits <ticker>
```
**ticker**
- The symbol/ticker of the stock you want the splits for
**Examples**
```
/splits AMD
```
---
## earnings
> Display Earnings that are expected to occur in the next business days. (Sorted by market cap)
```format
/earnings <day>
```
**day**
- The Date you want to see the earnings for. Format: YYYY-MM-DD
**Examples**
```
/earnings 2022-07-29
```
---
## nexter
> Returns next Earnings Date for a stock.
```format
/nexter <ticker>
```
**ticker**
- The symbol/ticker of the stock you want the next earnings date for
**Examples**
```
/nexter AMD
```
---
## bio
> Displays a Crpyto's Info and other information or you can use bio_stocks to get Stock bio
```format
/bio <ticker>
```
**ticker**
- The symbol/ticker of the stock you want the bio of
**Examples**
```
/bio BTC
```
```
/bio_stocks AMD
```
---
## ermove
> Display implied move for a stock based on option prices.
```format
/ermove <ticker>
```
**ticker**
- The symbol/ticker of the stock you want the earnings move of
**Examples**
```
/ermove AMD
```
---
## analyst
> Displays analyst recommendations.
```format
/analyst <ticker>
```
**ticker**
- The symbol/ticker of the stock you want the analyst ratings for
**Examples**
```
/analyst AMD
```
---
## pt
> Displays chart with price targets.
```format
/pt <ticker>
```
**ticker**
- The symbol/ticker of the stock you want to query
**Examples**
```
/pt AMD
```
---
## supplier
> Retrieve list of suppliers for specified company
```format
/supplier <ticker>
```
**ticker**
- The symbol/ticker of the stock you want to query
**Examples**
```
/supplier AMD
```
---
## customer
> Retrieve list of customers for specified company
```format
/customer <ticker>
```
**ticker**
- The symbol/ticker of the stock you want to query
**Examples**
```
/customer AMD
```
---
## insiders
Displays 15 latest insider transactions for given stock
```format
/insiders <ticker>
```
**ticker**
- The symbol/ticker of the stock you want to query
**Examples**
```
/insiders AMD
```
---
## instholdings
> Displays top 15 Institutional Holdings for given stock
```format
/instholdings <ticker>
```
**ticker**
- The symbol/ticker of the stock you want to query
**Examples**
```
/instholdings AMD
```
---
## financials
> Gives Total Assets, Cash, Debt, Liabilities, Rev for Company
```format
/financials <ticker>
```
**ticker**
- The symbol/ticker of the stock you want to query
**Examples**
```
/financials AMD
```
---
## divinfo
> Display dividend information for a stock.
```format
/divinfo <ticker>
```
**ticker**
- The symbol/ticker of the stock you want to query
**Examples**
```
/divinfo AAPL
```
---
## ytd
> Displays Period Performance for a stock
```format
/ytd <ticker>
```
**ticker**
- The symbol/ticker of the stock you want to query
**Examples**
```
/ytd AAPL
```

View File

@@ -0,0 +1,119 @@
---
title: Economy
description: calendar, currencies, indices, commodities...
premium: false
commands:
- "/calendar"
- "/currencies"
- "/indices"
- "/commodities"
- "/bonds"
- "/fedrates"
- "/yieldcurve"
---
# Economy
## calendar
> Displays Economic Calendar of events
```format
/calendar
```
---
## currencies
> Create an alert with conditions for a symbol
```format
/currencies
```
---
## indices
> US indices overview
```format
/indices
```
---
## commodities
> Futures and commodities overview.
```format
/commodities
```
---
## bonds
> Global bonds overview.
```format
/bonds <market>
```
**market** -
- The market to get bonds for - us (US bonds) or gl (Global)
**Examples**
```
/bonds us
```
```
/bonds gl
```
---
## revrepo
> Displays Reverse Repo.
```format
/revrepo [<days>]
```
**[days]** - _optional_
- The number of days to display. Default : 50
**Examples**
```
/revrepo days:35
```
```
/revrepo
```
---
## fedrates
> Upcoming Federal Rate decision dates and chances
```format
/fedrates
```
---
## yieldcurve
> Displays US Bonds yield curve
```format
/yieldcurve
```

View File

@@ -0,0 +1,34 @@
---
title: ETFs
description: top etfs, etf holdings
premium: false
commands:
- "/etf"
---
# ETFs
## tops/holdings
> Displays ETF's Top Gainers/Decliners, Most Active or get holdings data for an ETF.
```format
/etf tops <sort>
/etf holdings <ticker>
```
**sort**
- Sort by Top Gainers, Top Decliners, or Most Active
**ticker**
- Ticker to get holdings data for
**Examples**
```
/etf holdings SPY
```
```
/etf tops
```

View File

@@ -0,0 +1,184 @@
---
title: Flow
description: flow, unusual, bigflow, summary...
premium: true
commands:
- "/flow"
- "/unu"
- "/bigflow"
- "/summary"
- "/sectors"
- "/sumexp"
- "/sumweek"
- "/sumday"
- "/sumtop"
---
# Flow
## flow
> Returns the most recent for a stock
```format
/flow [subcmd] <ticker> [expiry] [strike] [opt_type]
```
**[subcmd]** - _optional_
- Possible subcommands to run. If not provided, defaults to daily flow
- wk: Weekly flow by Premium for a stock with weekly expiration
- open: Flow by Premium for a stock with opening condition - Vol > OI
- unu: Unusual Options Trades over 100k Prem. - Vol > OI
- prem: Chart with sum of premium per day by call/put
**ticker**
- Ticker symbol you want to lookup
**[expiry]** - _optional_
- Filter last flow for the provided expiration date that happened today - YYYY-MM-DD format
**[strike]** - _optional_
- Filter on the strike for flow -
**[opt_type]** - _optional_
- Filter on option type - Can be "C" - Calls or "P" - Puts
Examples
```
/flow AMD
```
```
/flow wk AMD
```
```
/flow prem AMD
```
---
## unu
> Unusual Options Trades over 100k Prem. - Vol > OI
```format
/unu
```
---
## bigflow
> Returns the top 20 largest by premium for a stock
```format
/bigflow <ticker>
```
**ticker**
- Ticker symbol you want to lookup
Examples
```
/bigflow AMD
```
---
## summary
> Summary of all by % of MarketCap
```format
/summaryflow <days> <sort>
```
**days**
- The number of days to look back
**sort**
- Field to sort by - Can be : MarketCap, Float, Total, Short Percentage
Examples
```
/summaryflow 1 float
```
```
/summaryflow 1 sum
```
---
## sectorsflow
> Summary of all by % of MarketCap by Sector
```
/sectorsflow <days> <sector>
```
**days**
- The number of days to look back
**sector**
- Sector to filter by - Basic Materials (bm) | Energy (e) | Communication Services (cs) | Consumer Cyclical (cs) | Consumer Defensive (cd) | Financial (f) | Healthcare (h) | Industrials (i) | Real Estate (re) | Technology (t) | Utilities (u)
Examples
```
/sectorsflow 5 cs
```
```
/sectorsflow 5 bm
```
---
## flowsum
> Graph Today's Total Premium of a stock.
```format
/flowsum [subcmd] <ticker>
```
**[subcmd]** - _optional_
- Possible subcommands, if not provided, defaults to daily sum
wk: Weekly flow by Premium for a stock with weekly expiration
exp: Flow summary by expiration date
top: Top flow for the day Calls vs Puts by stock
**ticker**
- The ticker/symbol to look up
**expiry**
- Expiration date - Only available/required for exp
Examples
```
/flowsum AMD
```
```
/flowsum wk AMD
```
```
/flowsum top AMD
```
```
/flowsum exp AMD 2022-07-29
```

View File

@@ -0,0 +1,62 @@
---
title: Fun
description: 8ball, flip, urban
premium: false
commands:
- "/8ball"
- "/flip"
- "/urban"
---
# Fun
## 8ball
> Ask 8ball a question
```format
/8ball <question>
```
**question**
- Make sure its in the form of a question
**Examples**
```
/8ball Will I make money today?
```
---
## flip
> Flip a coin for your Witcher!
```format
/flip
```
**Examples**
```
/flip
```
---
## Urban
> Look up a word in the urban dictionary - be careful
```format
/urban <word>
```
**word**
- enjoy the lookup
**Examples**
```
/urban Shill
```
---

Some files were not shown because too many files have changed in this diff Show More