mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-11-03 16:02:04 +00:00
@@ -224,10 +224,11 @@ These are the ones where a key is necessary:
|
||||
* News API: https://newsapi.org
|
||||
* Tradier: https://developer.tradier.com/getting_started
|
||||
* Oanda API: https://developer.oanda.com
|
||||
* CoinMarketCap API: https://coinmarketcap.com/api/
|
||||
|
||||
When these are obtained, don't forget to update [config_terminal.py](/gamestonk_terminal/config_terminal.py).
|
||||
|
||||
Alternatively, you can also set them to the following environment variables: GT_API_KEY_ALPHAVANTAGE, GT_API_KEY_FINANCIALMODELINGPREP, GT_API_KEY_QUANDL, GT_API_REDDIT_CLIENT_ID, GT_API_REDDIT_CLIENT_SECRET, GT_API_REDDIT_USERNAME, GT_API_REDDIT_USER_AGENT, GT_API_REDDIT_PASSWORD, GT_API_TWITTER_KEY, GT_API_TWITTER_SECRET_KEY, GT_API_TWITTER_BEARER_TOKEN, GT_API_POLYGON_KEY, GT_FRED_API_KEY, GT_API_NEWS_TOKEN, GT_OANDA_TOKEN, GT_OANDA_ACCOUNT, GT_TRADIER_TOKEN.
|
||||
Alternatively, you can also set them to the following environment variables: GT_API_KEY_ALPHAVANTAGE, GT_API_KEY_FINANCIALMODELINGPREP, GT_API_KEY_QUANDL, GT_API_REDDIT_CLIENT_ID, GT_API_REDDIT_CLIENT_SECRET, GT_API_REDDIT_USERNAME, GT_API_REDDIT_USER_AGENT, GT_API_REDDIT_PASSWORD, GT_API_TWITTER_KEY, GT_API_TWITTER_SECRET_KEY, GT_API_TWITTER_BEARER_TOKEN, GT_API_POLYGON_KEY, GT_FRED_API_KEY, GT_API_NEWS_TOKEN, GT_OANDA_TOKEN, GT_OANDA_ACCOUNT, GT_TRADIER_TOKEN, GT_CMC_API_KEY.
|
||||
|
||||
Example:
|
||||
```
|
||||
@@ -334,10 +335,7 @@ Distributed under the MIT License. See [LICENSE](https://github.com/DidierRLopes
|
||||
|
||||
[James Maslek](https://www.linkedin.com/in/james-maslek-b6810186/) - jmaslek11@gmail.com
|
||||
|
||||
Feel free to share loss porn, memes or any questions:
|
||||
|
||||

|
||||
|
||||
Feel free to share loss porn, memes or any questions: https://discord.gg/Up2QGbMKHY
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
* [Cryptocurrencies](#Cryptocurrencies)
|
||||
* [Screener](#Screener)
|
||||
* [Forex](#Forex)
|
||||
* [Backtesting](#Backtesting)
|
||||
|
||||
## Additional
|
||||
|
||||
@@ -217,6 +218,11 @@ ___
|
||||
|
||||
**NEXT**
|
||||
|
||||
## Backtesting
|
||||
* [x] Add simple backtest menu with simple strategies and benchmarks (@jmaslek) [PR #415](https://github.com/DidierRLopes/GamestonkTerminal/pull/415)
|
||||
|
||||
**NEXT**
|
||||
|
||||
---
|
||||
|
||||
## Backend
|
||||
|
||||
59
gamestonk_terminal/backtesting/README.md
Normal file
59
gamestonk_terminal/backtesting/README.md
Normal file
@@ -0,0 +1,59 @@
|
||||
# Backtesting
|
||||
The goal of this menu is to allow super simple research into potential strategies.
|
||||
|
||||
We currently provides a couple basic options for starting with backtesting strategies. Note that this is currently just a
|
||||
simple logic (i.e price comparisons). Obviously these strategies should not be used immediately and should be researched,
|
||||
improved and further tested on your own.
|
||||
|
||||
The current implementation uses the [bt](#http://pmorissette.github.io/bt/index.html) library.
|
||||
|
||||
Current strategies are:
|
||||
* [Simple EMA](#SimpleEMA)
|
||||
* Buys the stock when `price > EMA(l)`
|
||||
|
||||
* [EMA Cross](#EMA Cross)
|
||||
* Buys when EMA(short) > EMA(long) and sells when the opposite is true
|
||||
|
||||
* [RSI](#RSI)
|
||||
* Momentum strategy that longs when RSI < threshold (oversold) and shorts when
|
||||
|
||||
### SimpleEMA <a name="SimpleEMA"></a>
|
||||
This strategy buys when price > EMA(l)
|
||||
````
|
||||
usage: ema [-l] [--spy] [--no_bench]
|
||||
````
|
||||
* -l: Period of EMA to use. Default = 20.
|
||||
* [--spy]: Flag that overlays the results if you buy and hold SPY
|
||||
* [--no_bench]: Flag that removes the benchmark comparison of just buy and hold the stock.
|
||||
|
||||
im:
|
||||
|
||||
### EMA Cross <a name="EMA Cross"></a>
|
||||
This strategy goes long when EMA(short) > EMA(long) and goes short when
|
||||
EMA(short) < EMA(long). I provide the option to go long only through the --no_short flag
|
||||
|
||||
````
|
||||
usage: ema_cross [-l] [-s] [--spy] [--no_bench] [--no_short]
|
||||
````
|
||||
* -l/--long: Long period of EMA to use. Default = 50.
|
||||
* -s/--short: Short period of EMA to use. Default = 20.
|
||||
* [--spy]: Flag that overlays the results if you buy and hold SPY
|
||||
* [--no_bench]: Flag that removes the benchmark comparison of just buy and hold the stock.
|
||||
* [--no_short]: Flag that removes the shortable option. Will just be long positions when short > long EMAs.
|
||||
|
||||
im
|
||||
### RSI <a name="RSI"></a>
|
||||
This strategy goes long when the RSI is "oversold" - defined as the low parameter. It goes short when
|
||||
the RSI is "overbought" - defined as the high (upper) parameter
|
||||
````
|
||||
usage: rsi [-u] [-l] [-p] [--spy] [--no_bench] [--no_short]
|
||||
````
|
||||
* -u/--high: High (upper) value to consider overbought. Default = 70
|
||||
* -s/--short: Short period of EMA to use. Default = 30
|
||||
* -p/--periods: Periods to use for RSI calculation. Default = 14.
|
||||
* [--spy]: Flag that overlays the results if you buy and hold SPY
|
||||
* [--no_bench]: Flag that removes the benchmark comparison of just buy and hold the stock.
|
||||
* [--no_short]: Flag that removes the shortable option. Will just be long positions when short > long EMAs.
|
||||
|
||||
|
||||
|
||||
0
gamestonk_terminal/backtesting/__init__.py
Normal file
0
gamestonk_terminal/backtesting/__init__.py
Normal file
125
gamestonk_terminal/backtesting/bt_controller.py
Normal file
125
gamestonk_terminal/backtesting/bt_controller.py
Normal file
@@ -0,0 +1,125 @@
|
||||
"""Backtesting Controller Module"""
|
||||
__docformat__ = "numpy"
|
||||
|
||||
import argparse
|
||||
from typing import List, Union
|
||||
from datetime import datetime
|
||||
import matplotlib as mpl
|
||||
import matplotlib.pyplot as plt
|
||||
from prompt_toolkit.completion import NestedCompleter
|
||||
from gamestonk_terminal import feature_flags as gtff
|
||||
from gamestonk_terminal.helper_funcs import get_flair
|
||||
from gamestonk_terminal.menu import session
|
||||
|
||||
# This code below aims to fix an issue with the fnn module, used by bt module
|
||||
# which forces matplotlib backend to be 'agg' which doesn't allow to plot
|
||||
# Save current matplotlib backend
|
||||
default_backend = mpl.get_backend()
|
||||
# pylint: disable=wrong-import-position
|
||||
from gamestonk_terminal.backtesting import bt_view # noqa: E402
|
||||
|
||||
# Restore backend matplotlib used
|
||||
mpl.use(default_backend)
|
||||
|
||||
|
||||
class BacktestingController:
|
||||
"""Backtesting Class"""
|
||||
|
||||
CHOICES = ["help", "q", "quit", "ema", "ema_cross", "rsi"]
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
ticker: str,
|
||||
start: Union[datetime, str],
|
||||
):
|
||||
self.ticker = ticker
|
||||
self.start = start
|
||||
self.bt_parser = argparse.ArgumentParser(add_help=False, prog="bt")
|
||||
self.bt_parser.add_argument(
|
||||
"cmd",
|
||||
choices=self.CHOICES,
|
||||
)
|
||||
|
||||
def print_help(self):
|
||||
"""Print help"""
|
||||
|
||||
print("Back Testing Menu\n")
|
||||
print(" help show this backtesting menu again")
|
||||
print(" q quit this menu, and shows back to main menu")
|
||||
print(" quit quit to abandon program")
|
||||
print("")
|
||||
print(" ema buy when price exceeds EMA(l)")
|
||||
print(" ema_cross buy when EMA(short) > EMA(long) ")
|
||||
print(" rsi buy when RSI < low and sell when RSI > high")
|
||||
print("")
|
||||
|
||||
def switch(self, an_input: str):
|
||||
"""Process and dispatch input
|
||||
|
||||
Returns
|
||||
-------
|
||||
True, False or None
|
||||
False - quit the menu
|
||||
True - quit the program
|
||||
None - continue in the menu
|
||||
"""
|
||||
|
||||
(known_args, other_args) = self.bt_parser.parse_known_args(an_input.split())
|
||||
|
||||
return getattr(
|
||||
self, "call_" + known_args.cmd, lambda: "Command not recognized!"
|
||||
)(other_args)
|
||||
|
||||
def call_help(self, _):
|
||||
"""Process Help command"""
|
||||
self.print_help()
|
||||
|
||||
def call_q(self, _):
|
||||
"""Process Q command - quit the menu"""
|
||||
return False
|
||||
|
||||
def call_quit(self, _):
|
||||
"""Process Quit command - quit the program"""
|
||||
return True
|
||||
|
||||
def call_ema(self, other_args: List[str]):
|
||||
"""Call EMA strategy"""
|
||||
bt_view.simple_ema(self.ticker, self.start, other_args)
|
||||
|
||||
def call_ema_cross(self, other_args: List[str]):
|
||||
"""Call EMA Cross strategy"""
|
||||
bt_view.ema_cross(self.ticker, self.start, other_args)
|
||||
|
||||
def call_rsi(self, other_args: List[str]):
|
||||
"""Call RSI Strategy"""
|
||||
bt_view.rsi_strat(self.ticker, self.start, other_args)
|
||||
|
||||
|
||||
def menu(ticker: str, start: Union[str, datetime]):
|
||||
"""Backtesting Menu"""
|
||||
plt.close("all")
|
||||
bt_controller = BacktestingController(ticker, start)
|
||||
bt_controller.call_help(None)
|
||||
|
||||
while True:
|
||||
# Get input command from user
|
||||
if session and gtff.USE_PROMPT_TOOLKIT:
|
||||
completer = NestedCompleter.from_nested_dict(
|
||||
{c: None for c in bt_controller.CHOICES}
|
||||
)
|
||||
an_input = session.prompt(
|
||||
f"{get_flair()} (bt)> ",
|
||||
completer=completer,
|
||||
)
|
||||
else:
|
||||
an_input = input(f"{get_flair()} (bt)> ")
|
||||
|
||||
try:
|
||||
plt.close("all")
|
||||
process_input = bt_controller.switch(an_input)
|
||||
if process_input is not None:
|
||||
return process_input
|
||||
|
||||
except SystemExit:
|
||||
print("The command selected doesn't exist\n")
|
||||
continue
|
||||
65
gamestonk_terminal/backtesting/bt_helper.py
Normal file
65
gamestonk_terminal/backtesting/bt_helper.py
Normal file
@@ -0,0 +1,65 @@
|
||||
"""Helper functions for backtesting"""
|
||||
__docformat__ = "numpy"
|
||||
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Union
|
||||
from matplotlib import pyplot as plt
|
||||
from pandas.plotting import register_matplotlib_converters
|
||||
import bt
|
||||
from gamestonk_terminal.helper_funcs import plot_autoscale
|
||||
from gamestonk_terminal.config_plot import PLOT_DPI
|
||||
from gamestonk_terminal import feature_flags as gtff
|
||||
|
||||
register_matplotlib_converters()
|
||||
|
||||
|
||||
def buy_and_hold(ticker: str, start: Union[str, datetime], name: str):
|
||||
"""
|
||||
Generates a backtest object for the given ticker
|
||||
Parameters
|
||||
----------
|
||||
ticker: str
|
||||
Stock to test
|
||||
start: Union[str, datetime]
|
||||
Backtest start date. Can be either string or datetime
|
||||
name:
|
||||
Name of the backtest (for labeling purposes)
|
||||
|
||||
Returns
|
||||
-------
|
||||
bt.Backtest object for buy and hold strategy
|
||||
"""
|
||||
prices = bt.get(ticker, start=start)
|
||||
bt_strategy = bt.Strategy(
|
||||
name,
|
||||
[
|
||||
bt.algos.RunOnce(),
|
||||
bt.algos.SelectAll(),
|
||||
bt.algos.WeighEqually(),
|
||||
bt.algos.Rebalance(),
|
||||
],
|
||||
)
|
||||
return bt.Backtest(bt_strategy, prices)
|
||||
|
||||
|
||||
def plot_bt(res: bt.backtest.Result, plot_title: str):
|
||||
"""
|
||||
Plot the bt result
|
||||
Parameters
|
||||
----------
|
||||
res: bt.backtest.Result
|
||||
Result after a bt backtest is run
|
||||
plot_title: str
|
||||
Title of plot
|
||||
|
||||
"""
|
||||
_, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)
|
||||
res.plot(title=plot_title, ax=ax)
|
||||
plt.grid(b=True, which="major", color="#666666", linestyle="-")
|
||||
plt.minorticks_on()
|
||||
plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2)
|
||||
|
||||
if gtff.USE_ION:
|
||||
plt.ion()
|
||||
plt.show()
|
||||
299
gamestonk_terminal/backtesting/bt_view.py
Normal file
299
gamestonk_terminal/backtesting/bt_view.py
Normal file
@@ -0,0 +1,299 @@
|
||||
"""bt view module"""
|
||||
__docformat__ = "numpy"
|
||||
import argparse
|
||||
from typing import List, Union
|
||||
from datetime import datetime
|
||||
import pandas as pd
|
||||
import bt
|
||||
import pandas_ta as ta
|
||||
from gamestonk_terminal.helper_funcs import parse_known_args_and_warn
|
||||
from gamestonk_terminal.backtesting.bt_helper import buy_and_hold, plot_bt
|
||||
|
||||
|
||||
def simple_ema(ticker: str, start_date: Union[str, datetime], other_args: List[str]):
|
||||
"""
|
||||
Strategy where stock is bought when Price > EMA(l)
|
||||
Parameters
|
||||
----------
|
||||
ticker: str
|
||||
Stock to test
|
||||
start: Union[str, datetime]
|
||||
Backtest start date. Can be either string or datetime
|
||||
other_args: List[str]
|
||||
List of argparse arguments
|
||||
|
||||
Returns
|
||||
-------
|
||||
Plot and a printout of backtest
|
||||
"""
|
||||
parser = argparse.ArgumentParser(add_help=False, prog="ema")
|
||||
parser.add_argument(
|
||||
"-l", default=20, dest="length", type=int, help="EMA period to consider"
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--spy",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help="Flag to add spy hold comparison",
|
||||
dest="spy",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--no_bench",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help="Flag to not show buy and hold comparison",
|
||||
dest="no_bench",
|
||||
)
|
||||
|
||||
try:
|
||||
ns_parser = parse_known_args_and_warn(parser, other_args)
|
||||
if not ns_parser:
|
||||
return
|
||||
ticker = ticker.lower()
|
||||
ema = pd.DataFrame()
|
||||
prices = bt.get(ticker, start=start_date)
|
||||
ema[ticker] = ta.ema(prices[ticker], ns_parser.length)
|
||||
bt_strategy = bt.Strategy(
|
||||
"AboveEMA",
|
||||
[
|
||||
bt.algos.SelectWhere(prices >= ema),
|
||||
bt.algos.WeighEqually(),
|
||||
bt.algos.Rebalance(),
|
||||
],
|
||||
)
|
||||
bt_backtest = bt.Backtest(bt_strategy, prices)
|
||||
|
||||
if ns_parser.spy:
|
||||
spy_bt = buy_and_hold("spy", start_date, "SPY Hold")
|
||||
if ns_parser.no_bench:
|
||||
res = bt.run(bt_backtest, spy_bt)
|
||||
else:
|
||||
stock_bt = buy_and_hold(ticker, start_date, ticker.upper() + " Hold")
|
||||
res = bt.run(bt_backtest, spy_bt, stock_bt)
|
||||
else:
|
||||
if ns_parser.no_bench:
|
||||
res = bt.run(bt_backtest)
|
||||
else:
|
||||
stock_bt = buy_and_hold(ticker, start_date, ticker.upper() + " Hold")
|
||||
res = bt.run(bt_backtest, stock_bt)
|
||||
|
||||
plot_bt(res, f"Equity for EMA({ns_parser.length})")
|
||||
|
||||
print(res.display())
|
||||
print("")
|
||||
|
||||
except Exception as e:
|
||||
print(e)
|
||||
print("")
|
||||
return
|
||||
|
||||
|
||||
def ema_cross(ticker: str, start_date: Union[str, datetime], other_args: List[str]):
|
||||
"""
|
||||
Strategy where we go long/short when EMA(short) is greater than/less than EMA(short)
|
||||
Parameters
|
||||
----------
|
||||
ticker: str
|
||||
Stock to test
|
||||
start: Union[str, datetime]
|
||||
Backtest start date. Can be either string or datetime
|
||||
other_args: List[str]
|
||||
List of argparse arguments
|
||||
|
||||
Returns
|
||||
-------
|
||||
Plot and a printout of backtest
|
||||
"""
|
||||
parser = argparse.ArgumentParser(add_help=False, prog="ema_cross")
|
||||
parser.add_argument(
|
||||
"-l", "--long", default=50, dest="long", type=int, help="Long EMA period"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-s", "--short", default=20, dest="short", type=int, help="Short EMA period"
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--spy",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help="Flag to add spy hold comparison",
|
||||
dest="spy",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--no_bench",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help="Flag to not show buy and hold comparison",
|
||||
dest="no_bench",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--no_short",
|
||||
action="store_false",
|
||||
default=True,
|
||||
dest="shortable",
|
||||
help="Flag that disables the short sell",
|
||||
)
|
||||
try:
|
||||
ns_parser = parse_known_args_and_warn(parser, other_args)
|
||||
if not ns_parser:
|
||||
return
|
||||
if ns_parser.long < ns_parser.short:
|
||||
print("Short EMA period is longer than Long EMA period\n")
|
||||
return
|
||||
ticker = ticker.lower()
|
||||
prices = bt.get(ticker, start=start_date)
|
||||
short_ema = pd.DataFrame(ta.ema(prices[ticker], ns_parser.short))
|
||||
short_ema.columns = [ticker]
|
||||
long_ema = pd.DataFrame(ta.ema(prices[ticker], ns_parser.long))
|
||||
long_ema.columns = [ticker]
|
||||
|
||||
# signals
|
||||
signals = long_ema.copy()
|
||||
signals[short_ema > long_ema] = 1.0
|
||||
signals[short_ema <= long_ema] = -1.0 * ns_parser.shortable
|
||||
signals[long_ema.isnull()] = 0.0
|
||||
|
||||
combined_data = bt.merge(signals, prices, short_ema, long_ema)
|
||||
combined_data.columns = ["signal", "price", "ema_short", "ema_long"]
|
||||
bt_strategy = bt.Strategy(
|
||||
"EMA_Cross",
|
||||
[
|
||||
bt.algos.WeighTarget(signals),
|
||||
bt.algos.Rebalance(),
|
||||
],
|
||||
)
|
||||
bt_backtest = bt.Backtest(bt_strategy, prices)
|
||||
|
||||
if ns_parser.spy:
|
||||
spy_bt = buy_and_hold("spy", start_date, "SPY Hold")
|
||||
if ns_parser.no_bench:
|
||||
res = bt.run(bt_backtest, spy_bt)
|
||||
else:
|
||||
stock_bt = buy_and_hold(ticker, start_date, ticker.upper() + " Hold")
|
||||
res = bt.run(bt_backtest, spy_bt, stock_bt)
|
||||
else:
|
||||
if ns_parser.no_bench:
|
||||
res = bt.run(bt_backtest)
|
||||
else:
|
||||
stock_bt = buy_and_hold(ticker, start_date, ticker.upper() + " Hold")
|
||||
res = bt.run(bt_backtest, stock_bt)
|
||||
|
||||
plot_bt(res, f"EMA Cross for EMA({ns_parser.short})/EMA({ns_parser.long})")
|
||||
print(res.display())
|
||||
print("")
|
||||
|
||||
except Exception as e:
|
||||
print(e)
|
||||
print("")
|
||||
return
|
||||
|
||||
|
||||
def rsi_strat(ticker: str, start_date: Union[datetime, str], other_args: List[str]):
|
||||
"""
|
||||
Strategy that buys when the stock is less than a threshold and shorts when it exceeds a threshold.
|
||||
Parameters
|
||||
----------
|
||||
ticker: str
|
||||
Stock to test
|
||||
start: Union[str, datetime]
|
||||
Backtest start date. Can be either string or datetime
|
||||
other_args: List[str]
|
||||
List of argparse arguments
|
||||
|
||||
Returns
|
||||
-------
|
||||
Plot and a printout of backtest
|
||||
"""
|
||||
parser = argparse.ArgumentParser(add_help=False, prog="rsi_strat")
|
||||
parser.add_argument(
|
||||
"-p",
|
||||
"--periods",
|
||||
dest="periods",
|
||||
help="Number of periods for RSI calculation",
|
||||
type=int,
|
||||
default=14,
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"-u", "--high", default=70, dest="high", type=int, help="High (upper) RSI Level"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-l", "--low", default=30, dest="low", type=int, help="Low RSI Level"
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--spy",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help="Flag to add spy hold comparison",
|
||||
dest="spy",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--no_bench",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help="Flag to not show buy and hold comparison",
|
||||
dest="no_bench",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--no_short",
|
||||
action="store_false",
|
||||
default=True,
|
||||
dest="shortable",
|
||||
help="Flag that disables the short sell",
|
||||
)
|
||||
|
||||
try:
|
||||
ns_parser = parse_known_args_and_warn(parser, other_args)
|
||||
if not ns_parser:
|
||||
return
|
||||
if ns_parser.high < ns_parser.low:
|
||||
print("Low RSI value is higher than Low RSI value\n")
|
||||
return
|
||||
ticker = ticker.lower()
|
||||
prices = bt.get(ticker, start=start_date)
|
||||
|
||||
rsi = pd.DataFrame(ta.rsi(prices[ticker], ns_parser.periods))
|
||||
rsi.columns = [ticker]
|
||||
|
||||
signal = 0 * rsi.copy()
|
||||
signal[rsi > ns_parser.high] = -1
|
||||
signal[rsi < ns_parser.low] = 1
|
||||
signal[rsi.isnull()] = 0
|
||||
|
||||
merged_data = bt.merge(signal, prices)
|
||||
merged_data.columns = ["signal", "price"]
|
||||
|
||||
bt_strategy = bt.Strategy(
|
||||
"RSI Reversion", [bt.algos.WeighTarget(signal), bt.algos.Rebalance()]
|
||||
)
|
||||
bt_backtest = bt.Backtest(bt_strategy, prices)
|
||||
|
||||
if ns_parser.spy:
|
||||
spy_bt = buy_and_hold("spy", start_date, "SPY Hold")
|
||||
if ns_parser.no_bench:
|
||||
res = bt.run(bt_backtest, spy_bt)
|
||||
else:
|
||||
stock_bt = buy_and_hold(ticker, start_date, ticker.upper() + " Hold")
|
||||
res = bt.run(bt_backtest, spy_bt, stock_bt)
|
||||
else:
|
||||
if ns_parser.no_bench:
|
||||
res = bt.run(bt_backtest)
|
||||
else:
|
||||
stock_bt = buy_and_hold(ticker, start_date, ticker.upper() + " Hold")
|
||||
res = bt.run(bt_backtest, stock_bt)
|
||||
|
||||
plot_bt(res, f"RSI Strategy between ({ns_parser.low}, {ns_parser.high})")
|
||||
print(res.display())
|
||||
print("")
|
||||
|
||||
except Exception as e:
|
||||
print(e)
|
||||
print("")
|
||||
return
|
||||
@@ -1,5 +1,14 @@
|
||||
PLOT_DPI = 100
|
||||
|
||||
# Backend to use for plotting
|
||||
BACKEND = None
|
||||
# Examples:
|
||||
# "tkAgg" - This uses the tkinter library. If unsure, set to this
|
||||
# "module://backend_interagg" - This is what pycharm defaults to in Scientific Mode
|
||||
# "MacOSX" - Mac default. Does not work with backtesting
|
||||
# "Qt5Agg" - This requires the PyQt5 package is installed
|
||||
# See more: https://matplotlib.org/stable/tutorials/introductory/usage.html#the-builtin-backends
|
||||
|
||||
# Used when USE_PLOT_AUTOSCALING is set to False
|
||||
PLOT_HEIGHT = 500
|
||||
PLOT_WIDTH = 800
|
||||
|
||||
@@ -6,6 +6,7 @@ import re
|
||||
import sys
|
||||
from pytz import timezone
|
||||
import iso8601
|
||||
import matplotlib
|
||||
import matplotlib.pyplot as plt
|
||||
from holidays import US as holidaysUS
|
||||
from colorama import Fore, Style
|
||||
@@ -17,6 +18,8 @@ from gamestonk_terminal import feature_flags as gtff
|
||||
from gamestonk_terminal import config_plot as cfgPlot
|
||||
|
||||
register_matplotlib_converters()
|
||||
if cfgPlot.BACKEND is not None:
|
||||
matplotlib.use(cfgPlot.BACKEND)
|
||||
|
||||
|
||||
def check_non_negative(value) -> int:
|
||||
|
||||
@@ -79,6 +79,9 @@ def print_help(s_ticker, s_start, s_interval, b_is_market_open):
|
||||
print(
|
||||
" ta technical analysis, \t e.g.: ema, macd, rsi, adx, bbands, obv"
|
||||
)
|
||||
print(
|
||||
" bt strategy backtester, \t e.g.: simple ema, ema cross, rsi strategies"
|
||||
)
|
||||
print(
|
||||
" dd in-depth due-diligence, \t e.g.: news, analyst, shorts, insider, sec"
|
||||
)
|
||||
|
||||
231
poetry.lock
generated
231
poetry.lock
generated
@@ -104,11 +104,11 @@ tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pytest"]
|
||||
|
||||
[[package]]
|
||||
name = "astroid"
|
||||
version = "2.5.3"
|
||||
version = "2.5.6"
|
||||
description = "An abstract syntax tree for Python with inference support."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
python-versions = "~=3.6"
|
||||
|
||||
[package.dependencies]
|
||||
lazy-object-proxy = ">=1.4.0"
|
||||
@@ -249,9 +249,24 @@ python-versions = "*"
|
||||
[package.dependencies]
|
||||
beautifulsoup4 = "*"
|
||||
|
||||
[[package]]
|
||||
name = "bt"
|
||||
version = "0.2.9"
|
||||
description = "A flexible backtesting framework for Python"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*"
|
||||
|
||||
[package.dependencies]
|
||||
ffn = ">=0.3.5"
|
||||
pyprind = ">=2.11"
|
||||
|
||||
[package.extras]
|
||||
dev = ["black (>=20.8b1)", "codecov", "coverage", "cython (>=0.25)", "flake8", "flake8-black", "future", "mock", "nose", "numpy (>=1)", "pandas (>=0.19)", "matplotlib (>=2)", "ffn (>=0.3.5)", "pyprind (>=2.11)"]
|
||||
|
||||
[[package]]
|
||||
name = "cachetools"
|
||||
version = "4.2.1"
|
||||
version = "4.2.2"
|
||||
description = "Extensible memoizing collections and decorators"
|
||||
category = "main"
|
||||
optional = true
|
||||
@@ -435,11 +450,11 @@ pytz = "*"
|
||||
|
||||
[[package]]
|
||||
name = "decorator"
|
||||
version = "4.4.2"
|
||||
version = "5.0.7"
|
||||
description = "Decorators for Humans"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.6, !=3.0.*, !=3.1.*"
|
||||
python-versions = ">=3.5"
|
||||
|
||||
[[package]]
|
||||
name = "defusedxml"
|
||||
@@ -528,6 +543,28 @@ pystan = ">=2.14"
|
||||
python-dateutil = ">=2.8.0"
|
||||
setuptools-git = ">=1.2"
|
||||
|
||||
[[package]]
|
||||
name = "ffn"
|
||||
version = "0.3.6"
|
||||
description = "Financial functions for Python"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[package.dependencies]
|
||||
decorator = ">=4"
|
||||
future = ">=0.15"
|
||||
matplotlib = ">=1"
|
||||
numpy = ">=1.5"
|
||||
pandas = ">=0.19"
|
||||
pandas-datareader = ">=0.2"
|
||||
scikit-learn = ">=0.15"
|
||||
scipy = ">=0.15"
|
||||
tabulate = ">=0.7.5"
|
||||
|
||||
[package.extras]
|
||||
dev = ["black (>=20.8b1)", "codecov", "coverage", "flake8", "flake8-black", "future", "mock", "nose"]
|
||||
|
||||
[[package]]
|
||||
name = "filelock"
|
||||
version = "3.0.12"
|
||||
@@ -557,7 +594,7 @@ user_agent = "*"
|
||||
|
||||
[[package]]
|
||||
name = "finvizfinance"
|
||||
version = "0.9.6"
|
||||
version = "0.9.7"
|
||||
description = "Finviz Finance. Information downloader."
|
||||
category = "main"
|
||||
optional = false
|
||||
@@ -662,7 +699,7 @@ name = "future"
|
||||
version = "0.18.2"
|
||||
description = "Clean single-source support for Python 3 and 2"
|
||||
category = "main"
|
||||
optional = true
|
||||
optional = false
|
||||
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||
|
||||
[[package]]
|
||||
@@ -710,7 +747,7 @@ test-win = ["pytest", "pytest-rerunfailures", "mock", "cython", "nmslib", "pyemd
|
||||
|
||||
[[package]]
|
||||
name = "google-auth"
|
||||
version = "1.29.0"
|
||||
version = "1.30.0"
|
||||
description = "Google Authentication Library"
|
||||
category = "main"
|
||||
optional = true
|
||||
@@ -1448,14 +1485,14 @@ python-versions = ">=3.5"
|
||||
|
||||
[[package]]
|
||||
name = "networkx"
|
||||
version = "2.5.1"
|
||||
version = "2.5"
|
||||
description = "Python package for creating and manipulating graphs and networks"
|
||||
category = "main"
|
||||
optional = true
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[package.dependencies]
|
||||
decorator = ">=4.3,<5"
|
||||
decorator = ">=4.3.0"
|
||||
|
||||
[package.extras]
|
||||
all = ["numpy", "scipy", "pandas", "matplotlib", "pygraphviz", "pydot", "pyyaml", "lxml", "pytest"]
|
||||
@@ -1591,6 +1628,19 @@ pytz = ">=2017.2"
|
||||
[package.extras]
|
||||
test = ["pytest (>=4.0.2)", "pytest-xdist", "hypothesis (>=3.58)"]
|
||||
|
||||
[[package]]
|
||||
name = "pandas-datareader"
|
||||
version = "0.9.0"
|
||||
description = "Data readers extracted from the pandas codebase,should be compatible with recent pandas versions"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[package.dependencies]
|
||||
lxml = "*"
|
||||
pandas = ">=0.23"
|
||||
requests = ">=2.19.0"
|
||||
|
||||
[[package]]
|
||||
name = "pandas-ta"
|
||||
version = "0.2.45b"
|
||||
@@ -1936,22 +1986,19 @@ python-versions = ">=3.5"
|
||||
|
||||
[[package]]
|
||||
name = "pylint"
|
||||
version = "2.7.4"
|
||||
version = "2.8.2"
|
||||
description = "python code static checker"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "~=3.6"
|
||||
|
||||
[package.dependencies]
|
||||
astroid = ">=2.5.2,<2.7"
|
||||
astroid = ">=2.5.6,<2.7"
|
||||
colorama = {version = "*", markers = "sys_platform == \"win32\""}
|
||||
isort = ">=4.2.5,<6"
|
||||
mccabe = ">=0.6,<0.7"
|
||||
toml = ">=0.7.1"
|
||||
|
||||
[package.extras]
|
||||
docs = ["sphinx (==3.5.1)", "python-docs-theme (==2020.12)"]
|
||||
|
||||
[[package]]
|
||||
name = "pymeeus"
|
||||
version = "0.5.11"
|
||||
@@ -2012,6 +2059,14 @@ scipy = ">=1.3,<2.0"
|
||||
[package.extras]
|
||||
optionals = ["cvxopt (>=1.2,!=1.2.5.post1,<2.0)", "scikit-learn (>=0.24.1,<0.25.0)", "matplotlib (>=3.2.0,<4.0.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "pyprind"
|
||||
version = "2.11.3"
|
||||
description = "Python Progress Bar and Percent Indicator Utility"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "pyrsistent"
|
||||
version = "0.14.11"
|
||||
@@ -2086,7 +2141,7 @@ six = ">=1.5"
|
||||
|
||||
[[package]]
|
||||
name = "python-dotenv"
|
||||
version = "0.17.0"
|
||||
version = "0.17.1"
|
||||
description = "Read key-value pairs from a .env file and set them as environment variables"
|
||||
category = "main"
|
||||
optional = false
|
||||
@@ -2137,8 +2192,8 @@ python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "pywinpty"
|
||||
version = "0.5.7"
|
||||
description = "Python bindings for the winpty library"
|
||||
version = "1.0.1"
|
||||
description = "Pseudo terminal support for Windows from Python."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
@@ -2325,7 +2380,7 @@ tqdm = "*"
|
||||
|
||||
[[package]]
|
||||
name = "scikit-learn"
|
||||
version = "0.24.1"
|
||||
version = "0.24.2"
|
||||
description = "A set of python modules for machine learning and data mining"
|
||||
category = "main"
|
||||
optional = false
|
||||
@@ -2981,7 +3036,7 @@ prediction = ["fbprophet", "tensorflow", "pmdarima", "transformers", "flair", "t
|
||||
[metadata]
|
||||
lock-version = "1.1"
|
||||
python-versions = "^3.6.8"
|
||||
content-hash = "24dd5a8aac56488e2fa9b754a5b71e6cbcf51006166910e4e683bc09533a1d21"
|
||||
content-hash = "51e9191a579c58d229a6a32b419f3f8d891d2e7ce12decb6f74a283fb46a851a"
|
||||
|
||||
[metadata.files]
|
||||
absl-py = [
|
||||
@@ -3068,8 +3123,8 @@ argon2-cffi = [
|
||||
{file = "argon2_cffi-20.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:8a84934bd818e14a17943de8099d41160da4a336bcc699bb4c394bbb9b94bd32"},
|
||||
]
|
||||
astroid = [
|
||||
{file = "astroid-2.5.3-py3-none-any.whl", hash = "sha256:bea3f32799fbb8581f58431c12591bc20ce11cbc90ad82e2ea5717d94f2080d5"},
|
||||
{file = "astroid-2.5.3.tar.gz", hash = "sha256:ad63b8552c70939568966811a088ef0bc880f99a24a00834abd0e3681b514f91"},
|
||||
{file = "astroid-2.5.6-py3-none-any.whl", hash = "sha256:4db03ab5fc3340cf619dbc25e42c2cc3755154ce6009469766d7143d1fc2ee4e"},
|
||||
{file = "astroid-2.5.6.tar.gz", hash = "sha256:8a398dfce302c13f14bab13e2b14fe385d32b73f4e4853b9bdfb64598baa1975"},
|
||||
]
|
||||
astunparse = [
|
||||
{file = "astunparse-1.6.3-py2.py3-none-any.whl", hash = "sha256:c2652417f2c8b5bb325c885ae329bdf3f86424075c4fd1a128674bc6fba4b8e8"},
|
||||
@@ -3114,9 +3169,20 @@ bpemb = [
|
||||
bs4 = [
|
||||
{file = "bs4-0.0.1.tar.gz", hash = "sha256:36ecea1fd7cc5c0c6e4a1ff075df26d50da647b75376626cc186e2212886dd3a"},
|
||||
]
|
||||
bt = [
|
||||
{file = "bt-0.2.9-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:5654e5639ffd0778714d567ae14fb06d485e43becb720a0dc5a38b405251485e"},
|
||||
{file = "bt-0.2.9-cp36-cp36m-win_amd64.whl", hash = "sha256:5d6dd92fd6aa1efbade3efee980add709fc591a8b007643016f2e0cbf7372daf"},
|
||||
{file = "bt-0.2.9-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:637fd917f57d0302b17968025650be7d8b2b6da32c2c7daea9ae48f6a66cbb8c"},
|
||||
{file = "bt-0.2.9-cp37-cp37m-win_amd64.whl", hash = "sha256:55a9cf1ca3aa2c425a48fc1e8d324cd5959d4d189e221f7744c1c6e30149c61b"},
|
||||
{file = "bt-0.2.9-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:5dbf1ced108a6f2086b927dcf17ecd1deff7d98266d7f52ab3ff43be4a349ec3"},
|
||||
{file = "bt-0.2.9-cp38-cp38-win_amd64.whl", hash = "sha256:e77a56adc7bcac285df2c70e714b8724fc92fa1beb8de4b1fd991ab3862f84b0"},
|
||||
{file = "bt-0.2.9-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:a1aed6e0ee3fa3b6f5bcef1f26d29e2a96c8329ea54894362014e20012de053b"},
|
||||
{file = "bt-0.2.9-cp39-cp39-win_amd64.whl", hash = "sha256:399bedbf48026899e85536ea8cbd21459461346638ae20f439a09bc75fa131e9"},
|
||||
{file = "bt-0.2.9.tar.gz", hash = "sha256:d162d71aaaaf7265a848d1fc0040f503add32dac2f9f3127bece0d74c22efb9b"},
|
||||
]
|
||||
cachetools = [
|
||||
{file = "cachetools-4.2.1-py3-none-any.whl", hash = "sha256:1d9d5f567be80f7c07d765e21b814326d78c61eb0c3a637dffc0e5d1796cb2e2"},
|
||||
{file = "cachetools-4.2.1.tar.gz", hash = "sha256:f469e29e7aa4cff64d8de4aad95ce76de8ea1125a16c68e0d93f65c3c3dc92e9"},
|
||||
{file = "cachetools-4.2.2-py3-none-any.whl", hash = "sha256:2cc0b89715337ab6dbba85b5b50effe2b0c74e035d83ee8ed637cf52f12ae001"},
|
||||
{file = "cachetools-4.2.2.tar.gz", hash = "sha256:61b5ed1e22a0924aed1d23b478f37e8d52549ff8a961de2909c69bf950020cff"},
|
||||
]
|
||||
certifi = [
|
||||
{file = "certifi-2020.12.5-py2.py3-none-any.whl", hash = "sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830"},
|
||||
@@ -3268,8 +3334,8 @@ datetime = [
|
||||
{file = "DateTime-4.3.tar.gz", hash = "sha256:5cef605bab8259ff61281762cdf3290e459fbf0b4719951d5fab967d5f2ea0ea"},
|
||||
]
|
||||
decorator = [
|
||||
{file = "decorator-4.4.2-py2.py3-none-any.whl", hash = "sha256:41fa54c2a0cc4ba648be4fd43cff00aedf5b9465c9bf18d64325bc225f08f760"},
|
||||
{file = "decorator-4.4.2.tar.gz", hash = "sha256:e3a62f0520172440ca0dcc823749319382e377f37f140a0b99ef45fecb84bfe7"},
|
||||
{file = "decorator-5.0.7-py3-none-any.whl", hash = "sha256:945d84890bb20cc4a2f4a31fc4311c0c473af65ea318617f13a7257c9a58bc98"},
|
||||
{file = "decorator-5.0.7.tar.gz", hash = "sha256:6f201a6c4dac3d187352661f508b9364ec8091217442c9478f1f83c003a0f060"},
|
||||
]
|
||||
defusedxml = [
|
||||
{file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"},
|
||||
@@ -3346,6 +3412,10 @@ ephem = [
|
||||
fbprophet = [
|
||||
{file = "fbprophet-0.6.tar.gz", hash = "sha256:de7eaa16500e4dba69a0706906775cbe96668a6fe48354ee2fff820d9e6a899b"},
|
||||
]
|
||||
ffn = [
|
||||
{file = "ffn-0.3.6-py2.py3-none-any.whl", hash = "sha256:1e55e8caf6b63dce2f164cc4d3b8a02b678be7ed12990cafb2006b818a9a09e7"},
|
||||
{file = "ffn-0.3.6.tar.gz", hash = "sha256:4a79e72e06ff328e333ffe97010b1ce110bcd694fcd03be7351bf5065cd273e8"},
|
||||
]
|
||||
filelock = [
|
||||
{file = "filelock-3.0.12-py3-none-any.whl", hash = "sha256:929b7d63ec5b7d6b71b0fa5ac14e030b3f70b75747cef1b10da9b879fef15836"},
|
||||
{file = "filelock-3.0.12.tar.gz", hash = "sha256:18d82244ee114f543149c66a6e0c14e9c4f8a1044b5cdaadd0f82159d6a6ff59"},
|
||||
@@ -3354,8 +3424,8 @@ finviz = [
|
||||
{file = "finviz-1.4.1.tar.gz", hash = "sha256:7b1a2a730ce8e09dfe64aad30b499a3adaf0fdf2d52cba6dd3ef9813248182be"},
|
||||
]
|
||||
finvizfinance = [
|
||||
{file = "finvizfinance-0.9.6-py3-none-any.whl", hash = "sha256:18db3403bac6c3e6dae9d2c8d555df10d228e34daf02e4d50bb69c46e578cb7d"},
|
||||
{file = "finvizfinance-0.9.6.tar.gz", hash = "sha256:9a5f5a1a1e67e810e4f6819cda0e3966f95313ff27d06466ae8a91e5a0e0cdbe"},
|
||||
{file = "finvizfinance-0.9.7-py3-none-any.whl", hash = "sha256:f4e944ba28bb715d31dbe4c738572a6f7fad8feddbd5223a693d81eb31dd5365"},
|
||||
{file = "finvizfinance-0.9.7.tar.gz", hash = "sha256:92e6454686ed736164e0252137bb491b77f0dd6a32ea82677082de880afc6bfb"},
|
||||
]
|
||||
flair = [
|
||||
{file = "flair-0.7-py3-none-any.whl", hash = "sha256:42c7e8074f67eeac722d68f4d5a9ad602377a76f5c4a2a190b916645b9be6ff2"},
|
||||
@@ -3421,8 +3491,8 @@ gensim = [
|
||||
{file = "gensim-3.8.3.tar.gz", hash = "sha256:786adb0571f75114e9c5f7a31dd2e6eb39a9791f22c8757621545e2ded3ea367"},
|
||||
]
|
||||
google-auth = [
|
||||
{file = "google-auth-1.29.0.tar.gz", hash = "sha256:010f011c4e27d3d5eb01106fba6aac39d164842dfcd8709955c4638f5b11ccf8"},
|
||||
{file = "google_auth-1.29.0-py2.py3-none-any.whl", hash = "sha256:f30a672a64d91cc2e3137765d088c5deec26416246f7a9e956eaf69a8d7ed49c"},
|
||||
{file = "google-auth-1.30.0.tar.gz", hash = "sha256:9ad25fba07f46a628ad4d0ca09f38dcb262830df2ac95b217f9b0129c9e42206"},
|
||||
{file = "google_auth-1.30.0-py2.py3-none-any.whl", hash = "sha256:588bdb03a41ecb4978472b847881e5518b5d9ec6153d3d679aa127a55e13b39f"},
|
||||
]
|
||||
google-auth-oauthlib = [
|
||||
{file = "google-auth-oauthlib-0.4.4.tar.gz", hash = "sha256:09832c6e75032f93818edf1affe4746121d640c625a5bef9b5c96af676e98eee"},
|
||||
@@ -3948,8 +4018,8 @@ nest-asyncio = [
|
||||
{file = "nest_asyncio-1.5.1.tar.gz", hash = "sha256:afc5a1c515210a23c461932765691ad39e8eba6551c055ac8d5546e69250d0aa"},
|
||||
]
|
||||
networkx = [
|
||||
{file = "networkx-2.5.1-py3-none-any.whl", hash = "sha256:0635858ed7e989f4c574c2328380b452df892ae85084144c73d8cd819f0c4e06"},
|
||||
{file = "networkx-2.5.1.tar.gz", hash = "sha256:109cd585cac41297f71103c3c42ac6ef7379f29788eb54cb751be5a663bb235a"},
|
||||
{file = "networkx-2.5-py3-none-any.whl", hash = "sha256:8c5812e9f798d37c50570d15c4a69d5710a18d77bafc903ee9c5fba7454c616c"},
|
||||
{file = "networkx-2.5.tar.gz", hash = "sha256:7978955423fbc9639c10498878be59caf99b44dc304c2286162fd24b458c1602"},
|
||||
]
|
||||
notebook = [
|
||||
{file = "notebook-6.3.0-py3-none-any.whl", hash = "sha256:cb271af1e8134e3d6fc6d458bdc79c40cbfc84c1eb036a493f216d58f0880e92"},
|
||||
@@ -4058,6 +4128,10 @@ pandas = [
|
||||
{file = "pandas-1.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:edda9bacc3843dfbeebaf7a701763e68e741b08fccb889c003b0a52f0ee95782"},
|
||||
{file = "pandas-1.1.5.tar.gz", hash = "sha256:f10fc41ee3c75a474d3bdf68d396f10782d013d7f67db99c0efbfd0acb99701b"},
|
||||
]
|
||||
pandas-datareader = [
|
||||
{file = "pandas-datareader-0.9.0.tar.gz", hash = "sha256:b2cbc1e16a6ab9ff1ed167ae2ea92839beab9a20823bd00bdfb78155fa04f891"},
|
||||
{file = "pandas_datareader-0.9.0-py3-none-any.whl", hash = "sha256:fd9ce1238114dd199c32662a9d788271032580960bcf029e64b814d33d17477c"},
|
||||
]
|
||||
pandas-ta = [
|
||||
{file = "pandas_ta-0.2.45b.tar.gz", hash = "sha256:2adde7d3ecec5d96b032b6d80491fb2c9b7952626a3c2cf01fe7ca78f35ebe38"},
|
||||
]
|
||||
@@ -4254,8 +4328,8 @@ pygments = [
|
||||
{file = "Pygments-2.8.1.tar.gz", hash = "sha256:2656e1a6edcdabf4275f9a3640db59fd5de107d88e8663c5d4e9a0fa62f77f94"},
|
||||
]
|
||||
pylint = [
|
||||
{file = "pylint-2.7.4-py3-none-any.whl", hash = "sha256:209d712ec870a0182df034ae19f347e725c1e615b2269519ab58a35b3fcbbe7a"},
|
||||
{file = "pylint-2.7.4.tar.gz", hash = "sha256:bd38914c7731cdc518634a8d3c5585951302b6e2b6de60fbb3f7a0220e21eeee"},
|
||||
{file = "pylint-2.8.2-py3-none-any.whl", hash = "sha256:f7e2072654a6b6afdf5e2fb38147d3e2d2d43c89f648637baab63e026481279b"},
|
||||
{file = "pylint-2.8.2.tar.gz", hash = "sha256:586d8fa9b1891f4b725f587ef267abe2a1bad89d6b184520c7f07a253dd6e217"},
|
||||
]
|
||||
pymeeus = [
|
||||
{file = "PyMeeus-0.5.11.tar.gz", hash = "sha256:bb9d670818d8b0594317b48a7dadea02a0594e5344263bf2054e1a011c8fed55"},
|
||||
@@ -4288,6 +4362,10 @@ pyportfolioopt = [
|
||||
{file = "PyPortfolioOpt-1.4.1-py3-none-any.whl", hash = "sha256:73f0b4ac2a5d879879a7a91af038b4d7ff82e9998fb2cad7c249302294e8c09e"},
|
||||
{file = "PyPortfolioOpt-1.4.1.tar.gz", hash = "sha256:e6c8e983db92cd13caf41d87fb4dcd945d37053f28b75dd19b5be699b6b1d19e"},
|
||||
]
|
||||
pyprind = [
|
||||
{file = "PyPrind-2.11.3-py2.py3-none-any.whl", hash = "sha256:cc8edb66aabb18f25f7a3cce65312b3bc64b49992ddc93ba4cf511e5e25c1be3"},
|
||||
{file = "PyPrind-2.11.3.tar.gz", hash = "sha256:e37dcab6e1a9c8e0a7f0fce65fde7a79e2deda1c75aa015910a49e2137b54cbf"},
|
||||
]
|
||||
pyrsistent = [
|
||||
{file = "pyrsistent-0.14.11.tar.gz", hash = "sha256:3ca82748918eb65e2d89f222b702277099aca77e34843c5eb9d52451173970e2"},
|
||||
]
|
||||
@@ -4332,8 +4410,8 @@ python-dateutil = [
|
||||
{file = "python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"},
|
||||
]
|
||||
python-dotenv = [
|
||||
{file = "python-dotenv-0.17.0.tar.gz", hash = "sha256:471b782da0af10da1a80341e8438fca5fadeba2881c54360d5fd8d03d03a4f4a"},
|
||||
{file = "python_dotenv-0.17.0-py2.py3-none-any.whl", hash = "sha256:49782a97c9d641e8a09ae1d9af0856cc587c8d2474919342d5104d85be9890b2"},
|
||||
{file = "python-dotenv-0.17.1.tar.gz", hash = "sha256:b1ae5e9643d5ed987fc57cc2583021e38db531946518130777734f9589b3141f"},
|
||||
{file = "python_dotenv-0.17.1-py2.py3-none-any.whl", hash = "sha256:00aa34e92d992e9f8383730816359647f358f4a3be1ba45e5a5cefd27ee91544"},
|
||||
]
|
||||
pytrends = [
|
||||
{file = "pytrends-4.7.3-py3-none-any.whl", hash = "sha256:88d92e398b9408c79fd92946ddc2b03fa622301233bc49f16804042eb2897328"},
|
||||
@@ -4360,16 +4438,11 @@ pywin32 = [
|
||||
{file = "pywin32-300-cp39-cp39-win_amd64.whl", hash = "sha256:b1609ce9bd5c411b81f941b246d683d6508992093203d4eb7f278f4ed1085c3f"},
|
||||
]
|
||||
pywinpty = [
|
||||
{file = "pywinpty-0.5.7-cp27-cp27m-win32.whl", hash = "sha256:b358cb552c0f6baf790de375fab96524a0498c9df83489b8c23f7f08795e966b"},
|
||||
{file = "pywinpty-0.5.7-cp27-cp27m-win_amd64.whl", hash = "sha256:1e525a4de05e72016a7af27836d512db67d06a015aeaf2fa0180f8e6a039b3c2"},
|
||||
{file = "pywinpty-0.5.7-cp35-cp35m-win32.whl", hash = "sha256:2740eeeb59297593a0d3f762269b01d0285c1b829d6827445fcd348fb47f7e70"},
|
||||
{file = "pywinpty-0.5.7-cp35-cp35m-win_amd64.whl", hash = "sha256:33df97f79843b2b8b8bc5c7aaf54adec08cc1bae94ee99dfb1a93c7a67704d95"},
|
||||
{file = "pywinpty-0.5.7-cp36-cp36m-win32.whl", hash = "sha256:e854211df55d107f0edfda8a80b39dfc87015bef52a8fe6594eb379240d81df2"},
|
||||
{file = "pywinpty-0.5.7-cp36-cp36m-win_amd64.whl", hash = "sha256:dbd838de92de1d4ebf0dce9d4d5e4fc38d0b7b1de837947a18b57a882f219139"},
|
||||
{file = "pywinpty-0.5.7-cp37-cp37m-win32.whl", hash = "sha256:5fb2c6c6819491b216f78acc2c521b9df21e0f53b9a399d58a5c151a3c4e2a2d"},
|
||||
{file = "pywinpty-0.5.7-cp37-cp37m-win_amd64.whl", hash = "sha256:dd22c8efacf600730abe4a46c1388355ce0d4ab75dc79b15d23a7bd87bf05b48"},
|
||||
{file = "pywinpty-0.5.7-cp38-cp38-win_amd64.whl", hash = "sha256:8fc5019ff3efb4f13708bd3b5ad327589c1a554cb516d792527361525a7cb78c"},
|
||||
{file = "pywinpty-0.5.7.tar.gz", hash = "sha256:2d7e9c881638a72ffdca3f5417dd1563b60f603e1b43e5895674c2a1b01f95a0"},
|
||||
{file = "pywinpty-1.0.1-cp36-none-win_amd64.whl", hash = "sha256:739094e8d0d685a64c92ff91424cf43da9296110349036161ab294268e444d05"},
|
||||
{file = "pywinpty-1.0.1-cp37-none-win_amd64.whl", hash = "sha256:5447b8c158e5807237f80ea4e14262f0c05ff7c4d39f1c4b697ea6e8920786b2"},
|
||||
{file = "pywinpty-1.0.1-cp38-none-win_amd64.whl", hash = "sha256:aa3e4178503ff6be3e8a1d9ae4ce77de9058308562dbf26b505a51583be9f02d"},
|
||||
{file = "pywinpty-1.0.1-cp39-none-win_amd64.whl", hash = "sha256:58e23d59891e624d478ec7bcc42ced0ecfbf0a4e7cb0217de714f785f71c2461"},
|
||||
{file = "pywinpty-1.0.1.tar.gz", hash = "sha256:b3512d4a964a0abae1b77b6908917c62ea0ad7d8178696e4e973877fe9e820f9"},
|
||||
]
|
||||
pyyaml = [
|
||||
{file = "PyYAML-5.4.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922"},
|
||||
@@ -4596,39 +4669,39 @@ sacremoses = [
|
||||
{file = "sacremoses-0.0.45.tar.gz", hash = "sha256:58176cc28391830789b763641d0f458819bebe88681dac72b41a19c0aedc07e9"},
|
||||
]
|
||||
scikit-learn = [
|
||||
{file = "scikit-learn-0.24.1.tar.gz", hash = "sha256:a0334a1802e64d656022c3bfab56a73fbd6bf4b1298343f3688af2151810bbdf"},
|
||||
{file = "scikit_learn-0.24.1-cp36-cp36m-macosx_10_13_x86_64.whl", hash = "sha256:9bed8a1ef133c8e2f13966a542cb8125eac7f4b67dcd234197c827ba9c7dd3e0"},
|
||||
{file = "scikit_learn-0.24.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:a36e159a0521e13bbe15ca8c8d038b3a1dd4c7dad18d276d76992e03b92cf643"},
|
||||
{file = "scikit_learn-0.24.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:c658432d8a20e95398f6bb95ff9731ce9dfa343fdf21eea7ec6a7edfacd4b4d9"},
|
||||
{file = "scikit_learn-0.24.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:9dfa564ef27e8e674aa1cc74378416d580ac4ede1136c13dd555a87996e13422"},
|
||||
{file = "scikit_learn-0.24.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:9c6097b6a9b2bafc5e0f31f659e6ab5e131383209c30c9e978c5b8abdac5ed2a"},
|
||||
{file = "scikit_learn-0.24.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:5580eba7345a4d3b097be2f067cc71a306c44bab19e8717a30361f279c929bea"},
|
||||
{file = "scikit_learn-0.24.1-cp36-cp36m-win32.whl", hash = "sha256:7b04691eb2f41d2c68dbda8d1bd3cb4ef421bdc43aaa56aeb6c762224552dfb6"},
|
||||
{file = "scikit_learn-0.24.1-cp36-cp36m-win_amd64.whl", hash = "sha256:1adf483e91007a87171d7ce58c34b058eb5dab01b5fee6052f15841778a8ecd8"},
|
||||
{file = "scikit_learn-0.24.1-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:ddb52d088889f5596bc4d1de981f2eca106b58243b6679e4782f3ba5096fd645"},
|
||||
{file = "scikit_learn-0.24.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:a29460499c1e62b7a830bb57ca42e615375a6ab1bcad053cd25b493588348ea8"},
|
||||
{file = "scikit_learn-0.24.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:0567a2d29ad08af98653300c623bd8477b448fe66ced7198bef4ed195925f082"},
|
||||
{file = "scikit_learn-0.24.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:99349d77f54e11f962d608d94dfda08f0c9e5720d97132233ebdf35be2858b2d"},
|
||||
{file = "scikit_learn-0.24.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:83b21ff053b1ff1c018a2d24db6dd3ea339b1acfbaa4d9c881731f43748d8b3b"},
|
||||
{file = "scikit_learn-0.24.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:abe835a851610f87201819cb315f8d554e1a3e8128912783a31e87264ba5ffb7"},
|
||||
{file = "scikit_learn-0.24.1-cp37-cp37m-win32.whl", hash = "sha256:c3deb3b19dd9806acf00cf0d400e84562c227723013c33abefbbc3cf906596e9"},
|
||||
{file = "scikit_learn-0.24.1-cp37-cp37m-win_amd64.whl", hash = "sha256:d54dbaadeb1425b7d6a66bf44bee2bb2b899fe3e8850b8e94cfb9c904dcb46d0"},
|
||||
{file = "scikit_learn-0.24.1-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:3c4f07f47c04e81b134424d53c3f5e16dfd7f494e44fd7584ba9ce9de2c5e6c1"},
|
||||
{file = "scikit_learn-0.24.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:c13ebac42236b1c46397162471ea1c46af68413000e28b9309f8c05722c65a09"},
|
||||
{file = "scikit_learn-0.24.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:4ddd2b6f7449a5d539ff754fa92d75da22de261fd8fdcfb3596799fadf255101"},
|
||||
{file = "scikit_learn-0.24.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:826b92bf45b8ad80444814e5f4ac032156dd481e48d7da33d611f8fe96d5f08b"},
|
||||
{file = "scikit_learn-0.24.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:259ec35201e82e2db1ae2496f229e63f46d7f1695ae68eef9350b00dc74ba52f"},
|
||||
{file = "scikit_learn-0.24.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:9599a3f3bf33f73fed0fe06d1dfa4e6081365a58c1c807acb07271be0dce9733"},
|
||||
{file = "scikit_learn-0.24.1-cp38-cp38-win32.whl", hash = "sha256:8772b99d683be8f67fcc04789032f1b949022a0e6880ee7b75a7ec97dbbb5d0b"},
|
||||
{file = "scikit_learn-0.24.1-cp38-cp38-win_amd64.whl", hash = "sha256:ed9d65594948678827f4ff0e7ae23344e2f2b4cabbca057ccaed3118fdc392ca"},
|
||||
{file = "scikit_learn-0.24.1-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:8aa1b3ac46b80eaa552b637eeadbbce3be5931e4b5002b964698e33a1b589e1e"},
|
||||
{file = "scikit_learn-0.24.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:c7f4eb77504ac586d8ac1bde1b0c04b504487210f95297235311a0ab7edd7e38"},
|
||||
{file = "scikit_learn-0.24.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:087dfede39efb06ab30618f9ab55a0397f29c38d63cd0ab88d12b500b7d65fd7"},
|
||||
{file = "scikit_learn-0.24.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:895dbf2030aa7337649e36a83a007df3c9811396b4e2fa672a851160f36ce90c"},
|
||||
{file = "scikit_learn-0.24.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:9a24d1ccec2a34d4cd3f2a1f86409f3f5954cc23d4d2270ba0d03cf018aa4780"},
|
||||
{file = "scikit_learn-0.24.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:54be0a60a5a35005ad69c75902e0f5c9f699db4547ead427e97ef881c3242e6f"},
|
||||
{file = "scikit_learn-0.24.1-cp39-cp39-win32.whl", hash = "sha256:fab31f48282ebf54dd69f6663cd2d9800096bad1bb67bbc9c9ac84eb77b41972"},
|
||||
{file = "scikit_learn-0.24.1-cp39-cp39-win_amd64.whl", hash = "sha256:4562dcf4793e61c5d0f89836d07bc37521c3a1889da8f651e2c326463c4bd697"},
|
||||
{file = "scikit-learn-0.24.2.tar.gz", hash = "sha256:d14701a12417930392cd3898e9646cf5670c190b933625ebe7511b1f7d7b8736"},
|
||||
{file = "scikit_learn-0.24.2-cp36-cp36m-macosx_10_13_x86_64.whl", hash = "sha256:d5bf9c863ba4717b3917b5227463ee06860fc43931dc9026747de416c0a10fee"},
|
||||
{file = "scikit_learn-0.24.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:5beaeb091071625e83f5905192d8aecde65ba2f26f8b6719845bbf586f7a04a1"},
|
||||
{file = "scikit_learn-0.24.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:06ffdcaaf81e2a3b1b50c3ac6842cfb13df2d8b737d61f64643ed61da7389cde"},
|
||||
{file = "scikit_learn-0.24.2-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:fec42690a2eb646b384eafb021c425fab48991587edb412d4db77acc358b27ce"},
|
||||
{file = "scikit_learn-0.24.2-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:5ff3e4e4cf7592d36541edec434e09fb8ab9ba6b47608c4ffe30c9038d301897"},
|
||||
{file = "scikit_learn-0.24.2-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:3cbd734e1aefc7c5080e6b6973fe062f97c26a1cdf1a991037ca196ce1c8f427"},
|
||||
{file = "scikit_learn-0.24.2-cp36-cp36m-win32.whl", hash = "sha256:f74429a07fedb36a03c159332b914e6de757176064f9fed94b5f79ebac07d913"},
|
||||
{file = "scikit_learn-0.24.2-cp36-cp36m-win_amd64.whl", hash = "sha256:dd968a174aa82f3341a615a033fa6a8169e9320cbb46130686562db132d7f1f0"},
|
||||
{file = "scikit_learn-0.24.2-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:49ec0b1361da328da9bb7f1a162836028e72556356adeb53342f8fae6b450d47"},
|
||||
{file = "scikit_learn-0.24.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:f18c3ed484eeeaa43a0d45dc2efb4d00fc6542ccdcfa2c45d7b635096a2ae534"},
|
||||
{file = "scikit_learn-0.24.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:cdf24c1b9bbeb4936456b42ac5bd32c60bb194a344951acb6bfb0cddee5439a4"},
|
||||
{file = "scikit_learn-0.24.2-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:d177fe1ff47cc235942d628d41ee5b1c6930d8f009f1a451c39b5411e8d0d4cf"},
|
||||
{file = "scikit_learn-0.24.2-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:f3ec00f023d84526381ad0c0f2cff982852d035c921bbf8ceb994f4886c00c64"},
|
||||
{file = "scikit_learn-0.24.2-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:ae19ac105cf7ce8c205a46166992fdec88081d6e783ab6e38ecfbe45729f3c39"},
|
||||
{file = "scikit_learn-0.24.2-cp37-cp37m-win32.whl", hash = "sha256:f0ed4483c258fb23150e31b91ea7d25ff8495dba108aea0b0d4206a777705350"},
|
||||
{file = "scikit_learn-0.24.2-cp37-cp37m-win_amd64.whl", hash = "sha256:39b7e3b71bcb1fe46397185d6c1a5db1c441e71c23c91a31e7ad8cc3f7305f9a"},
|
||||
{file = "scikit_learn-0.24.2-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:90a297330f608adeb4d2e9786c6fda395d3150739deb3d42a86d9a4c2d15bc1d"},
|
||||
{file = "scikit_learn-0.24.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:f1d2108e770907540b5248977e4cff9ffaf0f73d0d13445ee938df06ca7579c6"},
|
||||
{file = "scikit_learn-0.24.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:1eec963fe9ffc827442c2e9333227c4d49749a44e592f305398c1db5c1563393"},
|
||||
{file = "scikit_learn-0.24.2-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:2db429090b98045d71218a9ba913cc9b3fe78e0ba0b6b647d8748bc6d5a44080"},
|
||||
{file = "scikit_learn-0.24.2-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:62214d2954377fcf3f31ec867dd4e436df80121e7a32947a0b3244f58f45e455"},
|
||||
{file = "scikit_learn-0.24.2-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:8fac72b9688176922f9f54fda1ba5f7ffd28cbeb9aad282760186e8ceba9139a"},
|
||||
{file = "scikit_learn-0.24.2-cp38-cp38-win32.whl", hash = "sha256:ae426e3a52842c6b6d77d00f906b6031c8c2cfdfabd6af7511bb4bc9a68d720e"},
|
||||
{file = "scikit_learn-0.24.2-cp38-cp38-win_amd64.whl", hash = "sha256:038f4e9d6ef10e1f3fe82addc3a14735c299866eb10f2c77c090410904828312"},
|
||||
{file = "scikit_learn-0.24.2-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:48f273836e19901ba2beecd919f7b352f09310ce67c762f6e53bc6b81cacf1f0"},
|
||||
{file = "scikit_learn-0.24.2-cp39-cp39-manylinux1_i686.whl", hash = "sha256:a2a47449093dcf70babc930beba2ca0423cb7df2fa5fd76be5260703d67fa574"},
|
||||
{file = "scikit_learn-0.24.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:0e71ce9c7cbc20f6f8b860107ce15114da26e8675238b4b82b7e7cd37ca0c087"},
|
||||
{file = "scikit_learn-0.24.2-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:2754c85b2287333f9719db7f23fb7e357f436deed512db3417a02bf6f2830aa5"},
|
||||
{file = "scikit_learn-0.24.2-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:7be1b88c23cfac46e06404582215a917017cd2edaa2e4d40abe6aaff5458f24b"},
|
||||
{file = "scikit_learn-0.24.2-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:4e6198675a6f9d333774671bd536668680eea78e2e81c0b19e57224f58d17f37"},
|
||||
{file = "scikit_learn-0.24.2-cp39-cp39-win32.whl", hash = "sha256:cbdb0b3db99dd1d5f69d31b4234367d55475add31df4d84a3bd690ef017b55e2"},
|
||||
{file = "scikit_learn-0.24.2-cp39-cp39-win_amd64.whl", hash = "sha256:40556bea1ef26ef54bc678d00cf138a63069144a0b5f3a436eecd8f3468b903e"},
|
||||
]
|
||||
scipy = [
|
||||
{file = "scipy-1.5.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:4f12d13ffbc16e988fa40809cbbd7a8b45bc05ff6ea0ba8e3e41f6f4db3a9e47"},
|
||||
|
||||
@@ -62,6 +62,7 @@ python-coinmarketcap = "^0.2"
|
||||
oandapyV20 = "^0.6.3"
|
||||
degiroapi = "^0.9.5"
|
||||
valinvest = "^0.0.2"
|
||||
bt = "^0.2.9"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
pytest = "^6.2.2"
|
||||
|
||||
@@ -16,6 +16,7 @@ black==20.8b1; python_version >= "3.6"
|
||||
bleach==3.3.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6"
|
||||
bpemb==0.3.3; python_version >= "3.6"
|
||||
bs4==0.0.1
|
||||
bt==0.2.9
|
||||
cachetools==4.2.1; python_version >= "3.5" and python_version < "4.0" and (python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0")
|
||||
certifi==2020.12.5; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0"
|
||||
cffi==1.14.5; implementation_name == "pypy" and python_version >= "3.6"
|
||||
|
||||
@@ -9,6 +9,7 @@ beautifulsoup4==4.9.3
|
||||
black==20.8b1; python_version >= "3.6"
|
||||
bpemb==0.3.2; python_version >= "3.6"
|
||||
bs4==0.0.1
|
||||
bt==0.2.9
|
||||
cachetools==4.2.1; python_version >= "3.5" and python_version < "4.0" and (python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0")
|
||||
certifi==2020.12.5; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0"
|
||||
chardet==3.0.4; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6"
|
||||
|
||||
@@ -9,6 +9,7 @@ beautifulsoup4==4.9.3
|
||||
black==20.8b1; python_version >= "3.6"
|
||||
bpemb==0.3.2; python_version >= "3.6"
|
||||
bs4==0.0.1
|
||||
bt==0.2.9
|
||||
cachetools==4.2.1; python_version >= "3.5" and python_version < "4.0" and (python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0")
|
||||
certifi==2020.12.5; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0"
|
||||
chardet==3.0.4; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6"
|
||||
|
||||
@@ -13,6 +13,7 @@ beautifulsoup4==4.9.3; python_version >= "3.5"
|
||||
black==20.8b1; python_version >= "3.6"
|
||||
bleach==3.3.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6"
|
||||
bs4==0.0.1
|
||||
bt==0.2.9
|
||||
certifi==2020.12.5; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0"
|
||||
cffi==1.14.5; implementation_name == "pypy" and python_version >= "3.6"
|
||||
chardet==4.0.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6"
|
||||
|
||||
@@ -33,6 +33,7 @@ from gamestonk_terminal.cryptocurrency import crypto_controller
|
||||
from gamestonk_terminal.screener import screener_controller
|
||||
from gamestonk_terminal.portfolio_optimization import po_controller
|
||||
from gamestonk_terminal.forex import fx_controller
|
||||
from gamestonk_terminal.backtesting import bt_controller
|
||||
|
||||
|
||||
# pylint: disable=too-many-statements,too-many-branches
|
||||
@@ -76,6 +77,7 @@ def main():
|
||||
"res",
|
||||
"fa",
|
||||
"ta",
|
||||
"bt",
|
||||
"dd",
|
||||
"eda",
|
||||
"pred",
|
||||
@@ -358,6 +360,11 @@ def main():
|
||||
elif ns_known_args.opt == "scr":
|
||||
b_quit = screener_controller.menu()
|
||||
|
||||
elif ns_known_args.opt == "bt":
|
||||
b_quit = bt_controller.menu(
|
||||
s_ticker.split(".")[0] if "." in s_ticker else s_ticker, s_start
|
||||
)
|
||||
|
||||
else:
|
||||
print("Shouldn't see this command!")
|
||||
continue
|
||||
|
||||
Reference in New Issue
Block a user