Code Without Documentation BANNED (Contributors Outraged) (#1487)

* Adds working checker

* Removed unused import

* Added dupont docs

* Added arg parser

* Removed Directory

* Updated commands

* Added hook to actions

* Added handling for no args

* Added proper ignores to actions

* Fixed tests

* Added Oanda documentation

Co-authored-by: Theodore Aptekarev <aptekarev@gmail.com>
This commit is contained in:
Colin Delahunty
2022-03-16 15:21:28 -04:00
committed by GitHub
parent a5dd351433
commit 93dc34b59c
34 changed files with 370 additions and 157 deletions

View File

@@ -26,6 +26,7 @@ jobs:
key: ${{ runner.os }}-linting
restore-keys: ${{ runner.os }}-linting
- run: python custom_pre_commit/check_doc.py --ignore-files=settings_controller.py,keys_controller.py,degiro_controller.py,oanda_controller.py --ignore-commands=login,al_swe,info_swe,goodness,resources,yf,yolo
- run: pip install bandit black codespell flake8 mypy pyupgrade safety pylint==2.12.2
- run: pip install types-pytz types-requests types-termcolor types-tabulate types-PyYAML types-python-dateutil types-setuptools
- run: bandit -x ./tests -r . || true

View File

@@ -1,4 +1,13 @@
repos:
- repo: local
hooks:
- id: check-docs
name: Check Command Documentation
description: Ensures that all of the commands in the terminal are included in Hugo.
language: python
pass_filenames: false
args: ["--ignore-files=settings_controller.py,keys_controller.py,degiro_controller.py,", "--ignore-commands=login,al_swe,info_swe,goodness,resources,yf,yolo"]
entry: python custom_pre_commit/check_doc.py
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.1.0
hooks:

View File

@@ -0,0 +1,109 @@
import argparse
import os
import sys
from typing import List, Optional
def clean_input(text: str) -> List[str]:
text = text.replace(" str ", "")
text = text.strip()
text = text.replace("CHOICES_COMMANDS", "")
text = text.replace("=", "")
text = text.replace("[", "")
text = text.replace("]", "")
text = text.replace("[str]", "")
text = text.replace("List", "")
text = text.replace(":", "")
text = text.replace("str ", "")
text = text.replace('"', "")
text = text.replace("'", "")
text_list = text.split(",")
return [x.strip() for x in text_list if x]
def main(ignore_files: Optional[str], ignore_commands: Optional[str]):
"""Checks commands in the repository to ensure they are documented
Parameters
----------
ignore_files : Optional[str]
Files that should not be checked
ignore_commands : Optional[str]
Commands that should not be checked
"""
if ignore_files:
ignore_file_list = ignore_files.split(",")
else:
ignore_file_list = []
if ignore_commands:
ignore_cmds_list = ignore_commands.split(",")
else:
ignore_cmds_list = []
path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
gst_path = os.path.join(path, "gamestonk_terminal/")
main_yaml_filename = os.path.join(path, "website/data/menu/main.yml")
files = []
commands = []
for r, _, f in os.walk(gst_path):
for file in f:
if file.endswith("_controller.py") and file not in ignore_file_list:
files.append(os.path.join(r, file))
record = 0
for item in files:
with open(item) as controller:
for line in controller:
if "CHOICES_COMMANDS" in line or record == 1:
commands += clean_input(line)
record = 1
if "]" in line.replace("str]", ""):
record = 0
break
clean_commands = {
x for x in commands if x and "#" not in x and x not in ignore_cmds_list
}
with open(main_yaml_filename) as yaml:
lines = yaml.read()
undocumented = []
for command in clean_commands:
if command not in lines:
undocumented.append(command)
if not undocumented:
sys.exit(0)
else:
print("The following commands do not have documentation:")
undocumented = list(undocumented)
undocumented.sort()
for item in undocumented:
print(item)
sys.exit(1)
if __name__ == "__main__":
parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="check_doc",
description="checks for proper documentation in gst",
)
parser.add_argument(
"--ignore-files",
dest="files",
help="The files to not check.",
type=str,
)
parser.add_argument(
"--ignore-commands",
dest="commands",
help="The commands to not check.",
type=str,
)
ns_parser = parser.parse_args()
main(ns_parser.files, ns_parser.commands)

View File

@@ -369,7 +369,7 @@ class OandaController(BaseController):
+ "defaults to all units. ",
)
if other_args:
if "-i" not in other_args[0]:
if "-i" not in other_args[0] and "-h" not in other_args[0]:
other_args.insert(0, "-i")
ns_parser = parse_known_args_and_warn(parser, other_args)
if ns_parser:

View File

@@ -26,7 +26,7 @@ class DashboardsController(BaseController):
"""Dashboards Controller class"""
CHOICES_COMMANDS = ["stocks", "correlation", "vsurf", "chains", "shortdata"]
PATH = "/jupyter/dashboard/"
PATH = "/jupyter/dashboards/"
def __init__(self, queue: List[str] = None):
"""Constructor"""

View File

@@ -30,7 +30,7 @@ possible_paths = [
]
class PortfolioAnalysis(BaseController):
class PortfolioAnalysisController(BaseController):
"""Portfolio Controller"""
CHOICES_COMMANDS = [

View File

@@ -143,7 +143,7 @@ Loaded:[/info] {self.portfolio_name or None}
+ self.portfolio._crypto_tickers
)
self.queue = self.load_class(
po_controller.PortfolioOptimization, tickers, self.queue
po_controller.PortfolioOptimizationController, tickers, self.queue
)
# BUG: The commands in pa menu throw errors. First one says that it's related to
@@ -155,7 +155,7 @@ Loaded:[/info] {self.portfolio_name or None}
# from gamestonk_terminal.portfolio.portfolio_analysis import pa_controller
#
# self.queue = self.queue = self.load_class(
# pa_controller.PortfolioAnalysis, self.queue
# pa_controller.PortfolioAnalysisController, self.queue
# )
@log_start_end(log=logger)

View File

@@ -28,7 +28,7 @@ from gamestonk_terminal.rich_config import console
logger = logging.getLogger(__name__)
class PortfolioOptimization(BaseController):
class PortfolioOptimizationController(BaseController):
"""Portfolio Optimization Controller class"""
CHOICES_COMMANDS = [

View File

@@ -1,95 +0,0 @@
"""Resource Collection Controller Module"""
__docformat__ = "numpy"
import logging
import webbrowser
from typing import List
from prompt_toolkit.completion import NestedCompleter
from gamestonk_terminal import feature_flags as gtff
from gamestonk_terminal.decorators import log_start_end
from gamestonk_terminal.menu import session
from gamestonk_terminal.parent_classes import BaseController
from gamestonk_terminal.rich_config import console
logger = logging.getLogger(__name__)
class ResourceCollectionController(BaseController):
"""Resources Controller class"""
CHOICES_COMMANDS = [
"hfletters",
"arxiv",
"finra",
"edgar",
"fred",
"learn",
"econiverse",
]
PATH = "/resources/"
def __init__(self, queue: List[str] = None):
"""Constructor"""
super().__init__(queue)
if session and gtff.USE_PROMPT_TOOLKIT:
choices: dict = {c: {} for c in self.controller_choices}
self.completer = NestedCompleter.from_nested_dict(choices)
def print_help(self):
"""Print help"""
help_text = """
[info]Resource Collection:[/info][cmds]
hfletters hedge fund letters or reports
arxiv open-access archive for academic articles
finra self-regulatory organization
edgar online public database from SEC
fred economic research data
learn trading analysis, tips and resources
econiverse compilation of free knowledge and educational resources[/cmds]
"""
console.print(text=help_text, menu="Resources")
@log_start_end(log=logger)
def call_hfletters(self, _):
"""Process hfletters command"""
webbrowser.open("https://miltonfmr.com/hedge-fund-letters/")
console.print("")
@log_start_end(log=logger)
def call_arxiv(self, _):
"""Process arxiv command"""
webbrowser.open("https://arxiv.org")
console.print("")
@log_start_end(log=logger)
def call_finra(self, _):
"""Process finra command"""
webbrowser.open("https://www.finra.org/#/")
console.print("")
@log_start_end(log=logger)
def call_edgar(self, _):
"""Process edgar command"""
webbrowser.open("https://www.sec.gov/edgar.shtml")
console.print("")
@log_start_end(log=logger)
def call_fred(self, _):
"""Process fred command"""
webbrowser.open("https://fred.stlouisfed.org")
console.print("")
@log_start_end(log=logger)
def call_learn(self, _):
"""Process learn command"""
webbrowser.open("https://moongangcapital.com/free-stock-market-resources/")
console.print("")
@log_start_end(log=logger)
def call_econiverse(self, _):
"""Process econiverse command"""
webbrowser.open("https://econiverse.github.io")
console.print("")

View File

@@ -976,7 +976,7 @@ class ComparisonAnalysisController(BaseController):
def call_po(self, _):
"""Call the portfolio optimization menu with selected tickers"""
if self.similar and len(self.similar) > 1:
self.queue = po_controller.PortfolioOptimization(
self.queue = po_controller.PortfolioOptimizationController(
self.similar, self.queue
).menu(custom_path_menu_above="/portfolio/")
else:

View File

@@ -181,9 +181,9 @@ class ScreenerController(BaseController):
def call_po(self, _):
"""Call the portfolio optimization menu with selected tickers"""
if self.screen_tickers:
self.queue = po_controller.PortfolioOptimization(self.screen_tickers).menu(
custom_path_menu_above="/portfolio/"
)
self.queue = po_controller.PortfolioOptimizationController(
self.screen_tickers
).menu(custom_path_menu_above="/portfolio/")
else:
console.print(
"Some tickers must be screened first through one of the presets!\n"

View File

@@ -743,9 +743,9 @@ class ScreenerController(BaseController):
def call_po(self, _):
"""Call the portfolio optimization menu with selected tickers"""
if self.screen_tickers:
self.queue = po_controller.PortfolioOptimization(self.screen_tickers).menu(
custom_path_menu_above="/portfolio/"
)
self.queue = po_controller.PortfolioOptimizationController(
self.screen_tickers
).menu(custom_path_menu_above="/portfolio/")
else:
console.print(
"Some tickers must be screened first through one of the presets!\n"

View File

@@ -2,41 +2,41 @@
"""Main Terminal Module"""
__docformat__ = "numpy"
import sys
import os
import argparse
import difflib
import logging
import argparse
import os
import platform
import sys
from typing import List
from pathlib import Path
import pytz
import dotenv
from prompt_toolkit.completion import NestedCompleter
from gamestonk_terminal.rich_config import console
from gamestonk_terminal.parent_classes import BaseController
from gamestonk_terminal import feature_flags as gtff
from gamestonk_terminal.helper_funcs import (
check_path,
get_flair,
get_user_timezone_or_invalid,
replace_user_timezone,
check_path,
parse_known_args_and_warn,
replace_user_timezone,
set_export_folder,
)
from gamestonk_terminal.loggers import setup_logging, upload_archive_logs_s3
from gamestonk_terminal.menu import session
from gamestonk_terminal.parent_classes import BaseController
from gamestonk_terminal.rich_config import console
from gamestonk_terminal.terminal_helper import (
about_us,
bootup,
welcome_message,
is_reset,
print_goodbye,
reset,
update_terminal,
suppress_stdout,
is_reset,
update_terminal,
welcome_message,
)
# pylint: disable=too-many-public-methods,import-outside-toplevel

View File

@@ -80,7 +80,7 @@ def test_print_help():
("h", []),
(
"r",
["quit", "quit", "reset", "jupyter", "dashboard"],
["quit", "quit", "reset", "jupyter", "dashboards"],
),
],
)
@@ -119,7 +119,7 @@ def test_call_cls(mocker):
(
"call_reset",
[],
["quit", "quit", "reset", "jupyter", "dashboard"],
["quit", "quit", "reset", "jupyter", "dashboards"],
),
(
"call_reset",
@@ -129,7 +129,7 @@ def test_call_cls(mocker):
"quit",
"reset",
"jupyter",
"dashboard",
"dashboards",
"help",
],
),

View File

@@ -25,10 +25,10 @@ def test_menu_with_queue(expected, mocker, queue):
# MOCK SWITCH
mocker.patch(
target=f"{path_controller}.PortfolioAnalysis.switch",
target=f"{path_controller}.PortfolioAnalysisController.switch",
return_value=["quit"],
)
result_menu = pa_controller.PortfolioAnalysis(queue=queue).menu()
result_menu = pa_controller.PortfolioAnalysisController(queue=queue).menu()
assert result_menu == expected
@@ -64,7 +64,7 @@ def test_menu_without_queue_completion(mocker):
return_value="quit",
)
result_menu = pa_controller.PortfolioAnalysis(queue=None).menu()
result_menu = pa_controller.PortfolioAnalysisController(queue=None).menu()
assert result_menu == []
@@ -104,11 +104,11 @@ def test_menu_without_queue_sys_exit(mock_input, mocker):
mock_switch = mocker.Mock(side_effect=SystemExitSideEffect())
mocker.patch(
target=f"{path_controller}.PortfolioAnalysis.switch",
target=f"{path_controller}.PortfolioAnalysisController.switch",
new=mock_switch,
)
result_menu = pa_controller.PortfolioAnalysis(queue=None).menu()
result_menu = pa_controller.PortfolioAnalysisController(queue=None).menu()
assert result_menu == []
@@ -116,7 +116,7 @@ def test_menu_without_queue_sys_exit(mock_input, mocker):
@pytest.mark.vcr(record_mode="none")
@pytest.mark.record_stdout
def test_print_help():
controller = pa_controller.PortfolioAnalysis(queue=None)
controller = pa_controller.PortfolioAnalysisController(queue=None)
controller.print_help()
@@ -136,7 +136,7 @@ def test_print_help():
],
)
def test_switch(an_input, expected_queue):
controller = pa_controller.PortfolioAnalysis(queue=None)
controller = pa_controller.PortfolioAnalysisController(queue=None)
queue = controller.switch(an_input=an_input)
assert queue == expected_queue
@@ -146,7 +146,7 @@ def test_switch(an_input, expected_queue):
def test_call_cls(mocker):
mocker.patch("os.system")
controller = pa_controller.PortfolioAnalysis(queue=None)
controller = pa_controller.PortfolioAnalysisController(queue=None)
controller.call_cls([])
assert controller.queue == []
@@ -180,7 +180,7 @@ def test_call_cls(mocker):
],
)
def test_call_func_expect_queue(expected_queue, func, queue):
controller = pa_controller.PortfolioAnalysis(queue=queue)
controller = pa_controller.PortfolioAnalysisController(queue=queue)
result = getattr(controller, func)([])
assert result is None
@@ -219,7 +219,7 @@ def test_call_func(
new=mock,
)
controller = pa_controller.PortfolioAnalysis(queue=None)
controller = pa_controller.PortfolioAnalysisController(queue=None)
getattr(controller, tested_func)(other_args)
@@ -228,6 +228,6 @@ def test_call_func(
else:
mock.assert_called_once()
else:
controller = pa_controller.PortfolioAnalysis(queue=None)
controller = pa_controller.PortfolioAnalysisController(queue=None)
getattr(controller, tested_func)(other_args)

View File

@@ -27,10 +27,10 @@ def test_menu_with_queue(expected, mocker, queue):
# MOCK SWITCH
mocker.patch(
target=f"{path_controller}.PortfolioOptimization.switch",
target=f"{path_controller}.PortfolioOptimizationController.switch",
return_value=["quit"],
)
result_menu = po_controller.PortfolioOptimization(queue=queue).menu()
result_menu = po_controller.PortfolioOptimizationController(queue=queue).menu()
assert result_menu == expected
@@ -68,7 +68,7 @@ def test_menu_without_queue_completion(mocker):
return_value="quit",
)
result_menu = po_controller.PortfolioOptimization(queue=None).menu()
result_menu = po_controller.PortfolioOptimizationController(queue=None).menu()
assert result_menu == []
@@ -110,11 +110,11 @@ def test_menu_without_queue_sys_exit(mock_input, mocker):
mock_switch = mocker.Mock(side_effect=SystemExitSideEffect())
mocker.patch(
target=f"{path_controller}.PortfolioOptimization.switch",
target=f"{path_controller}.PortfolioOptimizationController.switch",
new=mock_switch,
)
result_menu = po_controller.PortfolioOptimization(queue=None).menu()
result_menu = po_controller.PortfolioOptimizationController(queue=None).menu()
assert result_menu == []
@@ -122,7 +122,7 @@ def test_menu_without_queue_sys_exit(mock_input, mocker):
@pytest.mark.vcr(record_mode="none")
@pytest.mark.record_stdout
def test_print_help():
controller = po_controller.PortfolioOptimization(queue=None)
controller = po_controller.PortfolioOptimizationController(queue=None)
controller.print_help()
@@ -142,7 +142,7 @@ def test_print_help():
],
)
def test_switch(an_input, expected_queue):
controller = po_controller.PortfolioOptimization(queue=None)
controller = po_controller.PortfolioOptimizationController(queue=None)
queue = controller.switch(an_input=an_input)
assert queue == expected_queue
@@ -152,7 +152,7 @@ def test_switch(an_input, expected_queue):
def test_call_cls(mocker):
mocker.patch("os.system")
controller = po_controller.PortfolioOptimization(queue=None)
controller = po_controller.PortfolioOptimizationController(queue=None)
controller.call_cls([])
assert controller.queue == []
@@ -186,7 +186,7 @@ def test_call_cls(mocker):
],
)
def test_call_func_expect_queue(expected_queue, func, queue):
controller = po_controller.PortfolioOptimization(queue=queue)
controller = po_controller.PortfolioOptimizationController(queue=queue)
result = getattr(controller, func)([])
assert result is None
@@ -200,21 +200,21 @@ def test_call_func_expect_queue(expected_queue, func, queue):
(
"call_select",
[],
"PortfolioOptimization.add_stocks",
"PortfolioOptimizationController.add_stocks",
[],
dict(),
),
(
"call_add",
[],
"PortfolioOptimization.add_stocks",
"PortfolioOptimizationController.add_stocks",
[],
dict(),
),
(
"call_rmv",
[],
"PortfolioOptimization.rmv_stocks",
"PortfolioOptimizationController.rmv_stocks",
[],
dict(),
),
@@ -325,7 +325,7 @@ def test_call_func(
new=mock,
)
controller = po_controller.PortfolioOptimization(queue=None)
controller = po_controller.PortfolioOptimizationController(queue=None)
controller.tickers = ["AAPL", "MSFT"]
getattr(controller, tested_func)(other_args)
@@ -335,6 +335,6 @@ def test_call_func(
else:
mock.assert_called_once()
else:
controller = po_controller.PortfolioOptimization(queue=None)
controller = po_controller.PortfolioOptimizationController(queue=None)
getattr(controller, tested_func)(other_args)

View File

@@ -532,7 +532,7 @@ def test_func_calling_get_similar_companies(
def test_call_po(mocker):
similar = ["MOCK_SIMILAR_1", "MOCK_SIMILAR_2"]
mock = mocker.Mock(return_value=["MOCK_SIMILAR", "MOCK_USER"])
target = "gamestonk_terminal.portfolio.portfolio_optimization.po_controller.PortfolioOptimization.menu"
target = "gamestonk_terminal.portfolio.portfolio_optimization.po_controller.PortfolioOptimizationController.menu"
mocker.patch(target=target, new=mock)
controller = ca_controller.ComparisonAnalysisController(similar=similar)

View File

@@ -256,7 +256,7 @@ def test_call_func_expect_queue(expected_queue, func, queue):
(
"call_po",
[],
"po_controller.PortfolioOptimization.menu",
"po_controller.PortfolioOptimizationController.menu",
[],
dict(),
),

View File

@@ -381,7 +381,7 @@ def test_call_func_expect_queue(expected_queue, func, queue):
(
"call_po",
[],
"po_controller.PortfolioOptimization.menu",
"po_controller.PortfolioOptimizationController.menu",
[],
dict(),
),

View File

@@ -0,0 +1,13 @@
```
usage: jcdr [-i] [-h] [--export {csv,json,xlsx}]
```
Show daily cramer recommendation
```
optional arguments:
-i, --inverse Show inverse recommendation (default: False)
-h, --help Show this help message (default: False)
--export {csv,json,xlsx}
Export raw data into csv, json, xlsx (default: )
```

View File

@@ -0,0 +1,12 @@
```
usage: jctr [-h] [--export {csv,json,xlsx,png,jpg,pdf,svg}] [--raw]
```
Show cramer recommendation for loaded ticker
```
optional arguments:
-h, --help Show this help message (default: False)
--export {csv,json,xlsx,png,jpg,pdf,svg}
Export raw data into csv, json, xlsx and figure into png, jpg, pdf, svg (default: )
--raw Flag to display raw data (default: False)

View File

@@ -0,0 +1,11 @@
```
usage: to [-n FROM_SYMBOL] [-h]
```
Select the "from" currency symbol in a forex pair
```
optional arguments:
-n FROM_SYMBOL, --name FROM_SYMBOL
From currency (default: None)
-h, --help show this help message (default: False)

View File

@@ -0,0 +1,7 @@
---
geekdocCollapseSection: true
---
## TODO: Update after refactoring
{{< toc-tree >}}

View File

@@ -0,0 +1,11 @@
```
usage: calendar [-d DAYS] [-h]
```
Show Calendar Data
```
optional arguments:
-d DAYS, --days DAYS The number of days to search for, up to 30 forward or backward use negative numbers to search back.
-h, --help show this help message
```

View File

@@ -0,0 +1,12 @@
```
usage: cancel [-i ORDERID] [-h]
```
Cancel a Pending Order.
```
optional arguments:
-i ORDERID, --id ORDERID
The pending order ID to cancel.
-h, --help Show this help message
```

View File

@@ -0,0 +1,22 @@
```
usage: candles [-g GRANULARITY] [-l CANDLECOUNT] [-a] [-b] [-c] [-e] [-o] [-r] [-s] [-v] [-h]
```
Display Candle Data
```
optional arguments:
-g GRANULARITY, --granularity GRANULARITY
The timeframe to get for the candle chart (Seconds: S5, S10, S15, S30 Minutes: M1, M2, M4, M5, M10, M15, M30 Hours: H1, H2, H3, H4, H6, H8, H12 Day (default): D, Week: W Month: M
-l CANDLECOUNT, --limit CANDLECOUNT
The number of candles to retrieve. Default:180
-a, --ad Adds ad (Accumulation/Distribution Indicator) to the chart
-b, --bbands Adds Bollinger Bands to the chart
-c, --cci Adds cci (Commodity Channel Index) to the chart
-e, --ema Adds ema (Exponential Moving Average) to the chart
-o, --obv Adds obv (On Balance Volume) to the chart
-r, --rsi Adds rsi (Relative Strength Index) to the chart
-s, --sma Adds sma (Simple Moving Average) to the chart
-v, --vwap Adds vwap (Volume Weighted Average Price) to the chart
-h, --help show this help message
```

View File

@@ -0,0 +1,14 @@
```
usage: closetrade [-i ORDERID] [-u UNITS] [-h]
```
Close a trade by id.
```
optional arguments:
-i ORDERID, --id ORDERID
The Trade ID to close.
-u UNITS, --units UNITS
The number of units on the trade to close. If not set it defaults to all units.
-h, --help Show this help message
```

View File

@@ -0,0 +1,10 @@
```
usage: orderbook [-h]
```
Plot an orderbook for an instrument if Oanda provides one.
```
optional arguments:
-h, --help show this help message
```

View File

@@ -0,0 +1,10 @@
```
usage: pending [-h]
```
Get information about pending orders.
```
optional arguments:
-h, --help show this help message
```

View File

@@ -0,0 +1,10 @@
```
usage: positionbook [-h]
```
Plot a position book for an instrument if Oanda provides one.
```
optional arguments:
-h, --help show this help message
```

View File

@@ -0,0 +1,10 @@
```
usage: positions [-h]
```
Get information about open positions.
```
optional arguments:
-h, --help show this help message
```

View File

@@ -0,0 +1,11 @@
```
usage: period [-n {Annual,Quarterly,Trailing,annual,quarterly,trailing}] [-h]
```
Set period between annual, quarterly and trailing
```
optional arguments:
-n {Annual,Quarterly,Trailing,annual,quarterly,trailing}, --name {Annual,Quarterly,Trailing,annual,quarterly,trailing}
period to select (default: None)
-h, --help show this help message (default: False)

View File

@@ -94,6 +94,8 @@ main:
ref: "/terminal/stocks/sia/metric"
- name: vis
ref: "/terminal/stocks/sia/vis"
- name: period
ref: "/terminal/stocks/sia/period"
- name: dark pool shorts
ref: "/terminal/stocks/dark_pool_shorts"
sub:
@@ -239,8 +241,7 @@ main:
ref: "/terminal/stocks/fundamental_analysis/cal"
- name: splits
ref: "/terminal/stocks/fundamental_analysis/splits"
- name: web
ref: "/terminal/stocks/fundamental_analysis/web"
- name: fundamental_analysis/web"
- name: hq
ref: "/terminal/stocks/fundamental_analysis/hq"
- name: divs
@@ -261,6 +262,8 @@ main:
ref: "/terminal/stocks/fundamental_analysis/earnings"
- name: fraud
ref: "/terminal/stocks/fundamental_analysis/fraud"
- name: dupont
ref: "/terminal/stocks/fundamental_analysis/dupont"
- name: financial modeling prep
ref: "/terminal/stocks/fundamental_analysis/fmp"
sub:
@@ -440,6 +443,8 @@ main:
sub:
- name: add
ref: "/terminal/stocks/options/payoff/add"
- name: sop
ref: "/terminal/stocks/options/payoff/sop"
- name: pick
ref: "/terminal/stocks/options/payoff/pick"
- name: plot
@@ -557,6 +562,10 @@ main:
ref: "/terminal/common/behavioural_analysis/hist"
- name: trend
ref: "/terminal/common/behavioural_analysis/trend"
- name: jcdr
ref: "terminal/common/behavioural_analysis/jcdr"
- name: jctr
ref: "/terminal/common/behavioural_analysis/jctr"
- name: quantitative analysis
ref: "/terminal/common/quantitative_analysis"
sub:
@@ -598,6 +607,8 @@ main:
ref: "/terminal/common/quantitative_analysis/capm"
- name: line
ref: "/terminal/common/quantitative_analysis/line"
- name: raw
ref: "/terminal/common/quantitative_analysis/raw"
- name: prediction techniques
ref: "/terminal/common/prediction_techniques"
sub:
@@ -619,8 +630,8 @@ main:
ref: "/terminal/common/prediction_techniques/conv1d"
- name: mc
ref: "/terminal/common/prediction_techniques/mc"
- name: cryptocurrency
ref: "/terminal/cryptocurrency"
- name: Cryptocurrency
Ref: "/terminal/cryptocurrency"
sub:
- name: load
ref: "/terminal/cryptocurrency/load"
@@ -764,7 +775,9 @@ main:
- name: stats
ref: "/terminal/cryptocurrency/due_diligence/stats"
- name: stats
ref: "/cryptocurrency/due_diligence/mcapdom"
ref: "/terminal/cryptocurrency/due_diligence/mcapdom"
- name: nonzero
ref: "/terminal/cryptocurrency/due_diligence/nonzero"
- name: onchain
ref: "/terminal/cryptocurrency/onchain"
sub:
@@ -1058,6 +1071,8 @@ main:
ref: "/terminal/funds/plot"
- name: sector
ref: "/terminal/funds/sector"
- name: equity
ref: "/terminal/funds/equity"
- name: portfolio
ref: "/terminal/portfolio"
sub:
@@ -1144,6 +1159,8 @@ main:
ref: "/terminal/portfolio/init"
- name: rolling
ref: "/terminal/portfolio/rolling"
- name: var
ref: "/terminal/portfolio/var"
- name: forex
ref: "/terminal/forex"
sub:
@@ -1153,8 +1170,27 @@ main:
ref: "/terminal/forex/load"
- name: candle
ref: "/terminal/forex/candle"
- name: resources
ref: "/terminal/resources"
- name: from
ref: "/terminal/forex/from"
- name: oanda
ref: "/terminal/forex/oanda"
sub:
- name: calendar
ref: "/terminal/forex/oanda/calendar"
- name: cancel
ref: "/terminal/forex/oanda/cancel"
- name: candles
ref: "/terminal/forex/oanda/candles"
- name: closetrade
ref: "/terminal/forex/oanda/closetrade"
- name: orderbook
ref: "/terminal/forex/oanda/orderbook"
- name: pending
ref: "/terminal/forex/oanda/pending"
- name: positionbook
ref: "/terminal/forex/oanda/positionbook"
- name: positions
ref: "/terminal/forex/oanda/positions"
- name: alternative
ref: "/terminal/alternative"
sub: