Merge branch 'main' into prediction_updates

This commit is contained in:
Jamie
2021-05-07 19:20:27 -04:00
17 changed files with 986 additions and 109 deletions

View File

@@ -54,6 +54,7 @@
<summary><h2 style="display: inline-block">Table of Contents</h2></summary>
<ol>
<li> <a href="#about-the-project">About The Project</a> </li>
<li><a href="#donation">Donation</a></li>
<li>
<a href="#getting-started">Getting Started</a>
<ul>
@@ -84,11 +85,21 @@ Gamestonk Terminal provides a modern Python-based integrated environment for inv
As a modern Python-based environment, GamestonkTerminal opens access to numerous Python data libraries in Data Science (Pandas, Numpy, Scipy, Jupyter), Machine Learning (Pytorch, Tensorflow, Sklearn, Flair), and Data Acquisition (Beautiful Soup, and numerous third-party APIs).
## Donation
GST is a completely free open-source terminal. My personal goal has always been to keep this terminal available for everyone to use at zero cost.
Lately, some developers have been helping me in this endeavour. As you can probably tell from the git history, the terminal has been increasing in features/robustness at a really fast pace. Since none of us are getting paid to do so, and we all have 9-5 jobs, it's hard to onbard people to work towards the cause. On a personal level, I stopped investing since the repository was made public, since I spend all my spare time working on it, and don't have time left for DD.
There are many ways to help support GST. If technical development or support are one of your strengths, join our [discord](https://discord.gg/Up2QGbMKHY). Otherwise, you could certainly help us by providing a donation to our coinbase crypto wallet: **3Pfx7NwGgmZsk7hQJxzHdp5rGBftUHVTiM**.
Sharing the terminal with friends and family would also go a long way. Thanks in advance ape.
## Getting Started
### Install
If you'd like to see a video recording of the installation process, @JohnnyDankseed has made one available [here](https://www.twitch.tv/videos/1008414642).
If you'd like to see a video recording of the installation process, @JohnnyDankseed has made one available [here](https://www.twitch.tv/videos/1013768299).
This project was originally written and tested with Python 3.6.8. It should now support Python 3.6, 3.7, and 3.8.
@@ -321,9 +332,6 @@ If red is your favourite color, and you never sell for a loss.
Welcome to the club, and feel free to support the developers behind this amazing open-source project.
<a href="https://www.buymeacoffee.com/didierlopes" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-yellow.png" alt="Buy Me A Coffee" height="41" width="174"></a>
OR, if you prefer a coinbase crypto wallet: **3Pfx7NwGgmZsk7hQJxzHdp5rGBftUHVTiM**
## License
@@ -347,6 +355,14 @@ Feel free to share loss porn, memes or any questions at:
* Discord: https://discord.gg/Up2QGbMKHY
* Twitter: [@gamestonkt](https://twitter.com/gamestonkt)
#### Shoutout to:
* **alokan** : Responsible by developing `Forex` menu
* **pll_llq** and **hinxx** : Working towards a GUI using Qt.
* Get in touch in our [#gui](https://discord.gg/gQ3VxXEj) discord channel.
* **1lluz10n**, **crspy**, and **martiaaz** : Working on our landing page https://gamestonkterminal.vercel.app.
* Get in touch in our [#landing-page](https://discord.gg/wkyB4xcb) discord channel.
## Acknowledgments
* [VICE article - Gamestonk Terminal Is a DIY, Meme Stock Version of Bloomberg Terminal](https://www.vice.com/en/article/qjp9vp/gamestonk-terminal-is-a-diy-meme-stock-version-of-bloomberg-terminal)

View File

@@ -23,6 +23,7 @@
* [Forex](#Forex)
* [Backtesting](#Backtesting)
* [Resource Collection](#Resource-Collection)
* [Government](#Government)
## Additional
@@ -233,6 +234,7 @@ ___
## Resource Collection
* [x] Add hfletters and learn commands to resource collection (@didier) - [PR #427](https://github.com/DidierRLopes/GamestonkTerminal/pull/427)
* [x] Add arxiv, finra, edgar, fred (@didier) - [PR #438](https://github.com/DidierRLopes/GamestonkTerminal/pull/438)
**NEXT**
@@ -246,6 +248,13 @@ ___
---
## Government
* [x] Add congress data (@didier) [PR #438](https://github.com/DidierRLopes/GamestonkTerminal/pull/438)
**NEXT**
---
## Backend
**NEXT**

View File

@@ -1,6 +1,7 @@
# Features 📈
### Table of contents
* [Discover Stocks](#Discover-Stocks-)
* [Behavioural Analysis](#Behavioural-Analysis-)
* [Research](#Research-)
@@ -20,52 +21,59 @@
* [Forex](#Forex-)
* [Backtesting](#Backtesting-)
* [Resource Collection](#Resource-Collection-)
* [Government](#Government-)
## Main
The main menu allows the following commands:
```
load -t S_TICKER [-s S_START_DATE] [-i {1,5,15,30,60}]
```
* Load stock ticker to perform analysis on. When the data source is 'yf', an Indian ticker can be loaded by using '.NS' at the end, e.g. 'SBIN.NS'. See available market in https://help.yahoo.com/kb/exchanges-data-providers-yahoo-finance-sln2310.html.
* -s : The starting date (format YYYY-MM-DD) of the stock
* -i : Intraday stock minutes
* --source : Source of historical data. 'yf' and 'av' available. Default 'yf'
* -p : Pre/After market hours. Only works for 'yf' source, and intraday data
* Load stock ticker to perform analysis on. When the data source is 'yf', an Indian ticker can be loaded by using '.NS' at the end, e.g. 'SBIN.NS'. See available market in <https://help.yahoo.com/kb/exchanges-data-providers-yahoo-finance-sln2310.html>.
* -s : The starting date (format YYYY-MM-DD) of the stock
* -i : Intraday stock minutes
* --source : Source of historical data. 'yf' and 'av' available. Default 'yf'
* -p : Pre/After market hours. Only works for 'yf' source, and intraday data
**Note:** Until a ticker is loaded, the menu will only show *disc* and *sen* menu, as the others require a ticker being provided.
```
clear
```
* Clear previously loaded stock ticker.
* Clear previously loaded stock ticker.
```
view -t S_TICKER [-s S_START_DATE] [-i {1,5,15,30,60}] [--type N_TYPE]
```
* Visualise historical data of a stock. An alpha_vantage key is necessary.
* -s : The starting date (format YYYY-MM-DD) of the stock
* -i : Intraday stock minutes
* --type : 1234 corresponds to types: 1. open; 2. high; 3.low; 4. close; while 14 corresponds to types: 1.open; 4. close
* Visualise historical data of a stock. An alpha_vantage key is necessary.
* -s : The starting date (format YYYY-MM-DD) of the stock
* -i : Intraday stock minutes
* --type : 1234 corresponds to types: 1. open; 2. high; 3.low; 4. close; while 14 corresponds to types: 1.open; 4. close
![GNUS](https://user-images.githubusercontent.com/25267873/108925137-f2920e80-7633-11eb-8274-6e3bb6a19592.png)
```
candle
```
* Visualize candles historical data from the past 6 months, with support and resistance bars, and moving averages of 20 and 50
* Visualize candles historical data from the past 6 months, with support and resistance bars, and moving averages of 20 and 50
![nio](https://user-images.githubusercontent.com/25267873/111053397-4d609e00-845b-11eb-9c94-89b8892a8e81.png)
```
export -f GNUS_data -F csv
```
* Exports the historical data from this ticker to a file or stdout.
* -f : Name of file to save the historical data exported (stdout if unspecified). Default: stdout.
* -F : Export historical data into following formats: csv, json, excel, clipboard. Default: csv.
* Exports the historical data from this ticker to a file or stdout.
* -f : Name of file to save the historical data exported (stdout if unspecified). Default: stdout.
* -F : Export historical data into following formats: csv, json, excel, clipboard. Default: csv.
## Discover Stocks [»](discovery/README.md)
Command|Description|Source
---|---|---
`ipo` |past and future IPOs |[Finnhub](https://finnhub.io)
@@ -86,12 +94,13 @@ Command|Description|Source
`spectrum` |spectrum of sectors, industry, country |[Finviz](https://finviz.com)
`latest` |latest news |[Seeking Alpha](https://seekingalpha.com/)
`trending` |trending news |[Seeking Alpha](https://seekingalpha.com/)
`ratings ` |top ratings updates |[MarketBeat](https://marketbeat.com)
`ratings` |top ratings updates |[MarketBeat](https://marketbeat.com)
`darkpool` |dark pool tickers with growing activity |[FINRA](https://www.finra.org)
&nbsp;
## Behavioural Analysis [»](behavioural_analysis/README.md)
Command|Description
----|----
[FinBrain](https://finbrain.tech)|
@@ -120,26 +129,27 @@ Command|Description
&nbsp;
## Research [»](research/README.md)
Command|Website
----|----
`macroaxis` |www.macroaxis.com
`yahoo` |www.finance.yahoo.com
`finviz` |www.finviz.com
`marketwatch` |www.marketwatch.com
`fool` |www.fool.com
`businessinsider` |www.markets.businessinsider.com
`fmp` |www.financialmodelingprep.com
`fidelity` |www.eresearch.fidelity.com
`tradingview` |www.tradingview.com
`marketchameleon` |www.marketchameleon.com
`stockrow` |www.stockrow.com
`barchart` |www.barchart.com
`grufity` |www.grufity.com
`fintel` |www.fintel.com
`zacks` |www.zacks.com
`macrotrends` |www.macrotrends.net
`newsfilter` |www.newsfilter.io
`stockanalysis` |www.stockanalysis.com
`macroaxis` |<https://www.macroaxis.com>
`yahoo` |<https://www.finance.yahoo.com>
`finviz` |<https://www.finviz.com>
`marketwatch` |<https://www.marketwatch.com>
`fool` |<https://www.fool.com>
`businessinsider` |<https://www.markets.businessinsider.com>
`fmp` |<https://www.financialmodelingprep.com>
`fidelity` |<https://www.eresearch.fidelity.com>
`tradingview` |<https://www.tradingview.com>
`marketchameleon` |<https://www.marketchameleon.com>
`stockrow` |<https://www.stockrow.com>
`barchart` |<https://www.barchart.com>
`grufity` |<https://www.grufity.com>
`fintel` |<https://www.fintel.com>
`zacks` |<https://www.zacks.com>
`macrotrends` |<https://www.macrotrends.net>
`newsfilter` |<https://www.newsfilter.io>
`stockanalysis` |<https://www.stockanalysis.com>
&nbsp;
@@ -180,6 +190,7 @@ Command|Description
&nbsp;
## Technical Analysis [»](technical_analysis/README.md)
Command | Description | Sources
------ | ------ | ------
`view` | view historical data and trendlines| [Finviz](https://finviz.com/quote.ashx?t=tsla)
@@ -207,6 +218,7 @@ Command | Description | Sources
&nbsp;
## Due Diligence [»](due_diligence/README.md)
Command|Description|Source
------ | --------|----
`news` |latest news of the company |[Finviz](https://finviz.com/)
@@ -227,6 +239,7 @@ Command|Description|Source
&nbsp;
## Prediction Techniques [»](prediction_techniques/README.md)
Command|Technique|Sources
------ | ------------|---
`sma` |simple moving average | [Wikipedia](https://en.wikipedia.org/wiki/Moving_average#Simple_moving_average), [Investopedia](https://www.investopedia.com/terms/s/sma.asp)
@@ -279,9 +292,9 @@ Command|Description
Command|Description
------ | ------------
[coingecko](#https://www.coingecko.com/en)|
`load`| load cryptocurrency data
`view`| view loaded cryptocurrency data
`trend`| view top 7 coins
`load`| load cryptocurrency data
`view`| view loaded cryptocurrency data
`trend`| view top 7 coins
[coinmarketcap](#http://coinmarketcap.com)|
`top` | view top coins from coinmarketcap
[binance](#http://binance.us)|
@@ -293,6 +306,7 @@ Command|Description
&nbsp;
## Comparison Analysis [»](comparison_analysis/README.md)
Command|Description|Source
------ | --------|----
`get` |get similar companies |[Polygon](https://polygon.io)
@@ -308,6 +322,7 @@ Command|Description|Source
&nbsp;
## Exploratory Data Analysis [»](exploratory_data_analysis/README.md)
Command|Description|Source
------ | --------|----
`get` |get similar companies |[Polygon](https://polygon.io)
@@ -322,7 +337,8 @@ Command|Description|Source
&nbsp;
## Residual Analysis [»](residual_analysis/README.md)
## Residual Analysis [»](residuals_analysis/README.md)
Command|Description|Source
------ | --------|----
`pick` |pick one of the model fitting | Supports [ARIMA](https://en.wikipedia.org/wiki/Autoregressive_integrated_moving_average), [Naive](https://en.wikipedia.org/wiki/Forecasting#Naïve_approach)
@@ -340,25 +356,27 @@ Command|Description|Source
&nbsp;
## Economy [»](econ/README.md)
Command|Description|Source
------ | -------- | --------
`events` | economic impact events | https://finnhub.io
`fred` | display customized FRED data | https://fred.stlouisfed.org
`vixcls` | Volatility Index | https://fred.stlouisfed.org
`gdp` | Gross Domestic Product | https://fred.stlouisfed.org
`unrate` | Unemployment Rate | https://fred.stlouisfed.org
`dgs1` | 1-Year Treasury Constant Maturity Rate | https://fred.stlouisfed.org
`dgs5` | 5-Year Treasury Constant Maturity Rate | https://fred.stlouisfed.org
`dgs10` | 10-Year Treasury Constant Maturity Rate | https://fred.stlouisfed.org
`dgs30` | 30-Year Treasury Constant Maturity Rate | https://fred.stlouisfed.org
`mortgage30us` | 30-Year Fixed Rate Mortgage Average | https://fred.stlouisfed.org
`fedfunds` | Effective Federal Funds Rate | https://fred.stlouisfed.org
`aaa` | Moody's Seasoned AAA Corporate Bond Yield | https://fred.stlouisfed.org
`dexcaus` | Canada / U.S. Foreign Exchange Rate (CAD per 1 USD) | https://fred.stlouisfed.org
------ | -------- | --------
`events` | economic impact events | <https://finnhub.io>
`fred` | display customized FRED data | <https://fred.stlouisfed.org>
`vixcls` | Volatility Index | <https://fred.stlouisfed.org>
`gdp` | Gross Domestic Product | <https://fred.stlouisfed.org>
`unrate` | Unemployment Rate | <https://fred.stlouisfed.org>
`dgs1` | 1-Year Treasury Constant Maturity Rate | <https://fred.stlouisfed.org>
`dgs5` | 5-Year Treasury Constant Maturity Rate | <https://fred.stlouisfed.org>
`dgs10` | 10-Year Treasury Constant Maturity Rate | <https://fred.stlouisfed.org>
`dgs30` | 30-Year Treasury Constant Maturity Rate | <https://fred.stlouisfed.org>
`mortgage30us` | 30-Year Fixed Rate Mortgage Average | <https://fred.stlouisfed.org>
`fedfunds` | Effective Federal Funds Rate | <https://fred.stlouisfed.org>
`aaa` | Moody's Seasoned AAA Corporate Bond Yield | <https://fred.stlouisfed.org>
`dexcaus` | Canada / U.S. Foreign Exchange Rate (CAD per 1 USD) | <https://fred.stlouisfed.org>
&nbsp;
## Options [»](options/README.md)
Command|Description|Source
------ | --------|----
`exp` | see/set expiry date
@@ -371,6 +389,7 @@ Command|Description|Source
&nbsp;
## Screener [»](screener/README.md)
Command|Description|Source
------ | --------|----
view |view available presets | [presets]((screener/presets/README.md))
@@ -388,6 +407,7 @@ signals |view filter signals (e.g. -s top_gainers)
&nbsp;
## Forex [»](forex/README.md)
Command|Description
------ | --------
summary |display a summary of your account
@@ -408,20 +428,35 @@ positionbook |display the positionbook if Oanda provides one for the forex instr
&nbsp;
## Backtesting [»](backtesting/README.md)
Command|Description
------ | --------
`ema` | buy when price exceeds EMA(l)
`ema_cross` | buy when EMA(short) > EMA(long)
`rsi` | buy when RSI < low and sell when RSI > high
## Resource Collection [»](resource_collection/README.md)
Command|Website
----|----
`hfletters` |https://miltonfmr.com/hedge-fund-letters/
`learn` |https://moongangcapital.com/free-stock-market-resources/
`hfletters` |<https://miltonfmr.com/hedge-fund-letters/>
`arxiv` |<https://arxiv.org>
`finra` |<https://www.finra.org/#/>
`edgar` |<https://www.sec.gov/edgar.shtml>
`fred` |<https://fred.stlouisfed.org>
`learn` |<https://moongangcapital.com/free-stock-market-resources/>
&nbsp;
## Government [»](government/README.md)
Command|Website
----|----
`last_congress` |last congress trading
`buy_congress` |top buy congress tickers
`sell_congress` |top sell congress tickers
with ticker provided |
`congress` | congress trades on the ticker
&nbsp;

View File

@@ -3,7 +3,7 @@
This menu aims to compare a pre-loaded stock with similar companies, and the usage of the following commands along with an example will be exploited below.
* [get](#get)
* get similar companies [Finviz or Polygon]
* get similar companies [Finviz, Finnhub, Polygon]
* [select](#select)
* select similar companies
* [historical](#historical)
@@ -33,19 +33,22 @@ This menu aims to compare a pre-loaded stock with similar companies, and the usa
* [technical](#technical)
* brief technical (e.g. Beta, SMA50, 52W Low, RSI, Change) [Finviz]
* [> po](portfolio_optimization/README.md)
* portfolio optimization for selected tickers
* **portfolio optimization for selected tickers**
## get <a name="get"></a>
```text
get [-p] [--nocountry]
get [-s {polygon,finnhub,finviz}] [--nocountry]
```
Get similar companies to compare with. [Source: Finviz by default]
* -p : get similar companies using polygon source. Default False, i.e. using Finviz source.
* --nocountry : when getting similar companies from Finviz, we filter by same Industry, Sector and Country. However, if we don't want to filter by same country we can set this flag. For this flag to work, the `-p` flag can't be selected
* -s : source that provides similar companies. Default: polygon.
* --nocountry : when getting similar companies from Finviz, we filter by same Industry, Sector and Country. However, if we don't want to filter by same country we can set this flag. For this flag to work, the `-p` flag can't be selected.
<img width="1005" alt="Captura de ecrã 2021-05-06, às 23 09 22" src="https://user-images.githubusercontent.com/25267873/117372489-864c4a80-aec1-11eb-87ec-ccd1a5a0a0e7.png">
## select <a name="select"></a>

View File

@@ -136,25 +136,25 @@ class ComparisonAnalysisController:
other_args : List[str]
argparse other args
"""
parser = argparse.ArgumentParser(
add_help=False,
prog="get",
description="""Get similar companies to compare with.""",
)
parser.add_argument(
"-p",
"--polygon",
action="store_true",
default=False,
dest="b_polygon",
help="Polygon data source flag.",
"-s",
"--source",
action="store",
default="finviz",
dest="source",
choices=["polygon", "finnhub", "finviz"],
help="source that provides similar companies",
)
# If polygon source not selected, the user may want to get
# If source is finviz the user may want to get
# similar companies based on Industry and Sector only, and not
# on the fact that they are based on the same country
if "-p" not in other_args and "--polygon" not in other_args:
if "finviz" in other_args or not other_args:
parser.add_argument(
"--nocountry",
action="store_true",
@@ -164,11 +164,15 @@ class ComparisonAnalysisController:
)
try:
if other_args:
if "-" not in other_args[0]:
other_args.insert(0, "-s")
ns_parser = parse_known_args_and_warn(parser, other_args)
if not ns_parser:
return
if ns_parser.b_polygon:
if ns_parser.source == "polygon":
result = requests.get(
f"https://api.polygon.io/v1/meta/symbols/{self.ticker.upper()}/company?&apiKey={cfg.API_POLYGON_KEY}"
)
@@ -179,6 +183,20 @@ class ComparisonAnalysisController:
else:
print(result.json()["error"])
elif ns_parser.source == "finnhub":
result = requests.get(
f"https://finnhub.io/api/v1/stock/peers?symbol={self.ticker}&token={cfg.API_FINNHUB_KEY}"
)
if result.status_code == 200:
d_peers = result.json()
if d_peers:
self.similar = d_peers
self.user = "Finnhub"
else:
print("Similar companies not found.")
else:
if ns_parser.b_no_country:
compare_list = ["Sector", "Industry"]
@@ -192,17 +210,18 @@ class ComparisonAnalysisController:
)
self.user = "Finviz"
if self.similar:
print(f"\n[{self.user}] Similar Companies: {', '.join(self.similar)}")
if self.ticker.upper() in self.similar:
self.similar.remove(self.ticker.upper())
if len(self.similar) > 10:
print(
"\nThe limit of stocks to compare with are 10. Hence, 10 random similar stocks will be displayed.",
"\nThe selected list will be:",
)
random.shuffle(self.similar)
self.similar = sorted(self.similar[:10])
print(", ".join(self.similar))
print(
"The limit of stocks to compare with are 10. Hence, 10 random similar stocks will be displayed.\n",
)
if self.similar:
print(f"[{self.user}] Similar Companies: {', '.join(self.similar)}")
except Exception as e:
print(e)

View File

@@ -0,0 +1,64 @@
# GOVERNMENT
This menu aims to get some insights regarding government data, and the usage of the following commands along with an example will be exploited below.
This data has been provided by [quiverquant](https://www.quiverquant.com).
* [last_congress](#last_congress)
* last congress trading
* [buy_congress](#buy_congress)
* top buy congress tickers
* [sell_congress](#sell_congress)
* top sell congress tickers
#### WITH TICKER PROVIDED
* [congress](#congress)
* congress trades on the ticker
## last_congress <a name="last_congress"></a>
```text
usage: last_congress [-p PAST_TRANSACTIONS_DAYS]
```
Last congress trading. [Source: www.quiverquant.com]
* -p : Past transaction days. Default: 5.
* -r : Congress representative.
<img width="1013" alt="last_congress" src="https://user-images.githubusercontent.com/25267873/117346752-16799800-aea0-11eb-9b82-c28e712694d1.png">
## buy_congress <a name="buy_congress"></a>
```text
usage: buy_congress [-p PAST_TRANSACTIONS_MONTHS] [-t TOP_NUM]
```
Top buy congress trading. [Source: www.quiverquant.com]
* -p : Past transaction months. Default: 6.
* -t : Number of top tickers. Default: 10.
![buy](https://user-images.githubusercontent.com/25267873/117505803-8b220480-af7c-11eb-91cb-f51d2b585a17.png)
## sell_congress <a name="sell_congress"></a>
```text
usage: sell_congress [-p PAST_TRANSACTIONS_MONTHS] [-t TOP_NUM]
```
Top sell congress trading. [Source: www.quiverquant.com]
* -p : Past transaction months. Default: 6.
* -t : Number of top tickers. Default: 10.
![sold](https://user-images.githubusercontent.com/25267873/117505806-8c533180-af7c-11eb-8223-f11b08c72675.png)
## congress <a name="congress"></a>
```text
usage: congress [-p PAST_TRANSACTIONS_MONTHS]
```
Congress trading. [Source: www.quiverquant.com]
* -p : Past transaction months. Default: 6.
![congress](https://user-images.githubusercontent.com/25267873/117347548-280f6f80-aea1-11eb-8ee7-b511cdf863e1.png)

View File

@@ -0,0 +1,134 @@
"""Government Controller Module"""
__docformat__ = "numpy"
import argparse
from typing import List
from matplotlib import pyplot as plt
from gamestonk_terminal import feature_flags as gtff
from gamestonk_terminal.helper_funcs import get_flair
from gamestonk_terminal.menu import session
from prompt_toolkit.completion import NestedCompleter
from gamestonk_terminal.government import quiverquant_view
class GovController:
"""Gov Controller class"""
# Command choices
CHOICES = [
"help",
"q",
"quit",
"last_congress",
"buy_congress",
"sell_congress",
"congress",
]
def __init__(
self,
ticker: str,
):
"""Constructor"""
self.ticker = ticker
self.gov_parser = argparse.ArgumentParser(add_help=False, prog="gov")
self.gov_parser.add_argument(
"cmd",
choices=self.CHOICES,
)
@staticmethod
def print_help(self):
"""Print help"""
print("\nExploratory Data Analysis:")
print(" help show this comparison analysis menu again")
print(" q quit this menu, and shows back to main menu")
print(" quit quit to abandon program")
print("")
print("Explore:")
print(" last_congress last congress trading")
print(" buy_congress top buy congress tickers")
print(" sell_congress top sell congress tickers")
print("")
if self.ticker:
print(f"Ticker: {self.ticker}")
print(" congress congress trades on the ticker")
print("")
return
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.gov_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(self)
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_last_congress(self, other_args: List[str]):
"""Process last_congress command"""
quiverquant_view.last_congress(other_args)
def call_buy_congress(self, other_args: List[str]):
"""Process buy_congress command"""
quiverquant_view.buy_congress(other_args)
def call_sell_congress(self, other_args: List[str]):
"""Process sell_congress command"""
quiverquant_view.sell_congress(other_args)
def call_congress(self, other_args: List[str]):
"""Process congress command"""
quiverquant_view.congress(other_args, self.ticker)
def menu(ticker: str):
"""Government Menu"""
gov_controller = GovController(ticker)
gov_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 gov_controller.CHOICES}
)
an_input = session.prompt(
f"{get_flair()} (gov)> ",
completer=completer,
)
else:
an_input = input(f"{get_flair()} (gov)> ")
try:
plt.close("all")
process_input = gov_controller.switch(an_input)
if process_input is not None:
return process_input
except SystemExit:
print("The command selected doesn't exist\n")
continue

View File

@@ -0,0 +1,36 @@
import requests
import pandas as pd
# Provided by Quiverquant guys to GST users
API_QUIVERQUANT_KEY = "5cd2a65e96d0486efbe926a7cdbc1e8d8ab6c7b3"
def get_congress_trading(ticker: str = "") -> pd.DataFrame:
"""Returns the most recent transactions by members of U.S. Congress
Parameters
----------
ticker : str
Ticker to get congress trading data from
Returns
-------
pd.DataFrame
Most recent transactions by members of U.S. Congress
"""
if ticker:
url = f"https://api.quiverquant.com/beta/historical/congresstrading/{ticker}"
else:
url = "https://api.quiverquant.com/beta/live/congresstrading"
headers = {
"accept": "application/json",
"X-CSRFToken": "TyTJwjuEC7VV7mOqZ622haRaaUr0x0Ng4nrwSRFKQs7vdoBcJlK9qjAS69ghzhFu",
"Authorization": f"Token {API_QUIVERQUANT_KEY}",
}
response = requests.get(url, headers=headers)
if response.status_code == 200:
return pd.DataFrame(response.json())
return pd.DataFrame()

View File

@@ -0,0 +1,429 @@
import argparse
from typing import List
import pandas as pd
from datetime import datetime, timedelta
from gamestonk_terminal.government import quiverquant_model
from matplotlib import pyplot as plt
import matplotlib.dates as mdates
from gamestonk_terminal.helper_funcs import (
parse_known_args_and_warn,
check_positive,
plot_autoscale,
)
from gamestonk_terminal.config_plot import PLOT_DPI
from gamestonk_terminal import feature_flags as gtff
def last_congress(other_args: List[str]):
"""Last congress trading
Parameters
----------
other_args : List[str]
Command line arguments to be processed with argparse
"""
parser = argparse.ArgumentParser(
add_help=False,
prog="last_congress",
description="""
Last congress trading. [Source: www.quiverquant.com]
""",
)
parser.add_argument(
"-p",
"--past_transactions_days",
action="store",
dest="past_transactions_days",
type=check_positive,
default=5,
help="Past transaction days",
)
parser.add_argument(
"-r",
"--representative",
action="store",
dest="representative",
type=str,
default="",
help="Congress representative",
)
try:
if other_args:
if "-" not in other_args[0]:
other_args.insert(0, "-p")
ns_parser = parse_known_args_and_warn(parser, other_args)
if not ns_parser:
return
df_congress = quiverquant_model.get_congress_trading()
if df_congress.empty:
print("No congress trading data found\n")
return
df_congress = df_congress.sort_values("TransactionDate", ascending=False)
df_congress = df_congress[
df_congress["TransactionDate"].isin(
df_congress["TransactionDate"].unique()[
: ns_parser.past_transactions_days
]
)
]
df_congress = df_congress[
[
"TransactionDate",
"Ticker",
"Representative",
"Transaction",
"House",
"Range",
"ReportDate",
]
].rename(
columns={"TransactionDate": "Transaction Date", "ReportDate": "Report Date"}
)
if ns_parser.representative:
df_congress_rep = df_congress[
df_congress["Representative"].str.split().str[0]
== ns_parser.representative
]
if df_congress_rep.empty:
print(
f"No representative {ns_parser.representative} found in the past {ns_parser.past_transactions_days}"
f" days. The following are available: "
f"{', '.join(df_congress['Representative'].str.split().str[0].unique())}"
)
else:
print(df_congress_rep.to_string(index=False))
else:
print(df_congress.to_string(index=False))
print("")
except Exception as e:
print(e, "\n")
def buy_congress(other_args: List[str]):
"""Top buy congress trading
Parameters
----------
other_args : List[str]
Command line arguments to be processed with argparse
"""
parser = argparse.ArgumentParser(
add_help=False,
prog="buy_congress",
description="""
Top buy congress trading. [Source: www.quiverquant.com]
""",
)
parser.add_argument(
"-p",
"--past_transactions_months",
action="store",
dest="past_transactions_months",
type=check_positive,
default=6,
help="Past transaction months",
)
parser.add_argument(
"-t",
"--top",
action="store",
dest="top_num",
type=check_positive,
default=10,
help="Number of top tickers",
)
try:
ns_parser = parse_known_args_and_warn(parser, other_args)
if not ns_parser:
return
df_congress = quiverquant_model.get_congress_trading()
if df_congress.empty:
print("No congress trading data found\n")
return
df_congress = df_congress.sort_values("TransactionDate", ascending=False)
start_date = datetime.now() - timedelta(
days=ns_parser.past_transactions_months * 30
)
df_congress["TransactionDate"] = pd.to_datetime(df_congress["TransactionDate"])
df_congress = df_congress[df_congress["TransactionDate"] > start_date].dropna()
df_congress["min"] = df_congress["Range"].apply(
lambda x: x.split("-")[0].strip("$").replace(",", "").strip()
)
df_congress["max"] = df_congress["Range"].apply(
lambda x: x.split("-")[1].replace(",", "").strip().strip("$")
if "-" in x
else x.strip("$").replace(",", "")
)
df_congress["lower"] = df_congress[["min", "max", "Transaction"]].apply(
lambda x: float(x["min"])
if x["Transaction"] == "Purchase"
else -float(x["max"]),
axis=1,
)
df_congress["upper"] = df_congress[["min", "max", "Transaction"]].apply(
lambda x: float(x["max"])
if x["Transaction"] == "Purchase"
else -float(x["min"]),
axis=1,
)
df_congress = df_congress.sort_values("TransactionDate", ascending=True)
plt.figure(figsize=plot_autoscale(), dpi=PLOT_DPI)
df_congress.groupby("Ticker")["upper"].sum().sort_values(ascending=False).head(
n=ns_parser.top_num
).plot(kind="bar", rot=0)
plt.ylabel("Amount [$]")
plt.title(
f"Top {ns_parser.top_num} most bought stocks since last {ns_parser.past_transactions_months} "
"months (upper bound)"
)
plt.gcf().axes[0].yaxis.get_major_formatter().set_scientific(False)
if gtff.USE_ION:
plt.ion()
plt.show()
print("")
except Exception as e:
print(e, "\n")
def sell_congress(other_args: List[str]):
"""Top sell congress trading
Parameters
----------
other_args : List[str]
Command line arguments to be processed with argparse
"""
parser = argparse.ArgumentParser(
add_help=False,
prog="sell_congress",
description="""
Top sell congress trading. [Source: www.quiverquant.com]
""",
)
parser.add_argument(
"-p",
"--past_transactions_months",
action="store",
dest="past_transactions_months",
type=check_positive,
default=6,
help="Past transaction months",
)
parser.add_argument(
"-t",
"--top",
action="store",
dest="top_num",
type=check_positive,
default=10,
help="Number of top tickers",
)
try:
ns_parser = parse_known_args_and_warn(parser, other_args)
if not ns_parser:
return
df_congress = quiverquant_model.get_congress_trading()
if df_congress.empty:
print("No congress trading data found\n")
return
df_congress = df_congress.sort_values("TransactionDate", ascending=False)
start_date = datetime.now() - timedelta(
days=ns_parser.past_transactions_months * 30
)
df_congress["TransactionDate"] = pd.to_datetime(df_congress["TransactionDate"])
df_congress = df_congress[df_congress["TransactionDate"] > start_date].dropna()
df_congress["min"] = df_congress["Range"].apply(
lambda x: x.split("-")[0].strip("$").replace(",", "").strip()
)
df_congress["max"] = df_congress["Range"].apply(
lambda x: x.split("-")[1].replace(",", "").strip().strip("$")
if "-" in x
else x.strip("$").replace(",", "")
)
df_congress["lower"] = df_congress[["min", "max", "Transaction"]].apply(
lambda x: float(x["min"])
if x["Transaction"] == "Purchase"
else -float(x["max"]),
axis=1,
)
df_congress["upper"] = df_congress[["min", "max", "Transaction"]].apply(
lambda x: float(x["max"])
if x["Transaction"] == "Purchase"
else -float(x["min"]),
axis=1,
)
df_congress = df_congress.sort_values("TransactionDate", ascending=True)
plt.figure(figsize=plot_autoscale(), dpi=PLOT_DPI)
df_congress.groupby("Ticker")["lower"].sum().sort_values().abs().head(
n=ns_parser.top_num
).plot(kind="bar", rot=0)
plt.ylabel("Amount [$]")
plt.title(
f"Top {ns_parser.top_num} most sold stocks since last {ns_parser.past_transactions_months} months"
" (upper bound)"
)
plt.gcf().axes[0].yaxis.get_major_formatter().set_scientific(False)
if gtff.USE_ION:
plt.ion()
plt.show()
print("")
except Exception as e:
print(e, "\n")
def plot_congress(congress: pd.DataFrame, ticker: str):
"""Plot congress trading
Parameters
----------
other_args : List[str]
Command line arguments to be processed with argparse
ticker: str
Ticker to plot congress trading
"""
plt.figure(figsize=plot_autoscale(), dpi=PLOT_DPI)
plt.gca().fill_between(
congress["TransactionDate"].unique(),
congress.groupby("TransactionDate")["lower"].sum().values / 1000,
congress.groupby("TransactionDate")["upper"].sum().values / 1000,
)
plt.xlim(
[congress["TransactionDate"].values[0], congress["TransactionDate"].values[-1]]
)
plt.grid()
plt.title(f"Congress trading on {ticker}")
plt.xlabel("Date")
plt.ylabel("Amount [1k $]")
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter("%Y/%m/%d"))
plt.gcf().autofmt_xdate()
if gtff.USE_ION:
plt.ion()
plt.show()
def congress(other_args: List[str], ticker: str):
"""Congress trading
Parameters
----------
other_args : List[str]
Command line arguments to be processed with argparse
ticker: str
Ticker to get congress trading data from
"""
parser = argparse.ArgumentParser(
add_help=False,
prog="congress",
description="""
Congress trading. [Source: www.quiverquant.com]
""",
)
parser.add_argument(
"-p",
"--past_transactions_months",
action="store",
dest="past_transactions_months",
type=check_positive,
default=6,
help="Past transaction months",
)
try:
if other_args:
if "-" not in other_args[0]:
other_args.insert(0, "-p")
ns_parser = parse_known_args_and_warn(parser, other_args)
if not ns_parser:
return
df_congress = quiverquant_model.get_congress_trading(ticker)
if df_congress.empty:
print("No congress trading data found\n")
return
df_congress = df_congress.sort_values("TransactionDate", ascending=False)
start_date = datetime.now() - timedelta(
days=ns_parser.past_transactions_months * 30
)
df_congress["TransactionDate"] = pd.to_datetime(df_congress["TransactionDate"])
df_congress = df_congress[df_congress["TransactionDate"] > start_date]
df_congress["min"] = df_congress["Range"].apply(
lambda x: x.split("-")[0].strip("$").replace(",", "").strip()
)
df_congress["max"] = df_congress["Range"].apply(
lambda x: x.split("-")[1].replace(",", "").strip().strip("$")
if "-" in x
else x.strip("$").replace(",", "")
)
df_congress["lower"] = df_congress[["min", "max", "Transaction"]].apply(
lambda x: int(x["min"])
if x["Transaction"] == "Purchase"
else -int(x["max"]),
axis=1,
)
df_congress["upper"] = df_congress[["min", "max", "Transaction"]].apply(
lambda x: int(x["max"])
if x["Transaction"] == "Purchase"
else -int(x["min"]),
axis=1,
)
df_congress = df_congress.sort_values("TransactionDate", ascending=True)
plot_congress(df_congress, ticker)
print("")
except Exception as e:
print(e, "\n")

View File

@@ -65,6 +65,7 @@ def print_help(s_ticker, s_start, s_interval, b_is_market_open):
print(
" > po portfolio optimization, \t optimal portfolio weights from pyportfolioopt"
)
print(" > gov government menu, \t\t congress, senate, house trading")
print(" > fx forex menu, \t\t\t forex support through Oanda")
print(" > rc resource collection, \t\t e.g. hf letters")
@@ -100,7 +101,7 @@ def print_help(s_ticker, s_start, s_interval, b_is_market_open):
" > ra residuals analysis, \t e.g.: model fit, qqplot, hypothesis test"
)
print(
" > op options info , \t e.g.: volume and open interest"
" > op options info, \t e.g.: volume and open interest"
)
print("")

View File

@@ -1,4 +1,4 @@
# Portfolio Optimization
# PORTFOLIO OPTIMIZATION
This menu aims to optimize a portfolio of pre-loaded stocks, and the usage of the following commands along with an example will be exploited below.
@@ -6,6 +6,9 @@ This menu aims to optimize a portfolio of pre-loaded stocks, and the usage of th
* add ticker to optimize
* [select](#select)
* overwrite current tickers with new tickers
[Optimization](#Optimization)
* [equal](#equal)
* equally weighted
* [mktcap](#mktcap)
@@ -30,6 +33,10 @@ This menu aims to optimize a portfolio of pre-loaded stocks, and the usage of th
* [ef](#ef)
* show the efficient frontier
&nbsp;
* [> ca](comparison_analysis/README.md)
* **comparison analysis for selected tickers**
### add <a name="add"></a>
@@ -53,6 +60,8 @@ Add/Select tickers for portfolio to be optimized.
* -t : Tickers to be used in the portfolio to optimize
## Optimization <a name="Optimization"></a>
### equal <a name="equal"></a>
```text

View File

@@ -79,7 +79,7 @@ class PortfolioOptimization:
print("")
print(" ef show the efficient frontier")
print("")
if tickers:
if len(tickers) > 1:
print(" > ca comparison analysis for selected tickers")
print("")

View File

@@ -4,6 +4,14 @@ This menu aims to store a collection of useful resources that can't be scraped,
* [hfletters](#hfletters)
* hedge fund letters or reports
* [arxiv](#arxiv)
* open-access archive for academic articles
* [finra](#finra)
* self-regulatory organization
* [edgar](#edgar)
* online public database from SEC
* [fred](#fred)
* economic research data
* [learn](#learn)
* trading analysis, tips and resources
@@ -18,6 +26,42 @@ usage: hfletters
<img width="1227" alt="Captura de ecrã 2021-05-01, às 21 14 08" src="https://user-images.githubusercontent.com/25267873/116794053-3edd4d00-aac2-11eb-8abf-5a3a32ae3484.png">
## arxiv <a name="arxiv"></a>
```text
usage: arxiv
```
<img width="1279" alt="arxiv" src="https://user-images.githubusercontent.com/25267873/117510134-6f6e2c80-af83-11eb-9458-a7a160bb57f0.png">
## finra <a name="finra"></a>
```text
usage: finra
```
<img width="1278" alt="finra" src="https://user-images.githubusercontent.com/25267873/117510141-7137f000-af83-11eb-8b07-65176791bf72.png">
## edgar <a name="edgar"></a>
```text
usage: edgar
```
<img width="1278" alt="edgar" src="https://user-images.githubusercontent.com/25267873/117510138-709f5980-af83-11eb-8968-919e4235d480.png">
## fred <a name="fred"></a>
```text
usage: fred
```
<img width="1279" alt="fred" src="https://user-images.githubusercontent.com/25267873/117510128-6c733c00-af83-11eb-9dfe-8a86412aeefb.png">
## learn <a name="learn"></a>
```text

View File

@@ -14,7 +14,17 @@ class ResourceCollectionController:
"""Resources Controller class"""
# Command choices
CHOICES = ["help", "q", "quit", "hfletters", "learn"]
CHOICES = [
"help",
"q",
"quit",
"hfletters",
"arxiv",
"finra",
"edgar",
"fred",
"learn",
]
def __init__(self):
"""Constructor"""
@@ -34,6 +44,10 @@ class ResourceCollectionController:
print(" quit quit to abandon program")
print("")
print(" hfletters hedge fund letters or reports")
print(" arxiv open-access archive for academic articles")
print(" finra self-regulatory organization")
print(" edgar online public database from SEC")
print(" fred economic research data")
print(" learn trading analysis, tips and resources")
print("")
@@ -73,6 +87,26 @@ class ResourceCollectionController:
webbrowser.open("https://miltonfmr.com/hedge-fund-letters/")
print("")
def call_arxiv(self, other_args: List[str]):
"""Process arxiv command"""
webbrowser.open("https://arxiv.org")
print("")
def call_finra(self, other_args: List[str]):
"""Process finra command"""
webbrowser.open("https://www.finra.org/#/")
print("")
def call_edgar(self, other_args: List[str]):
"""Process edgar command"""
webbrowser.open("https://www.sec.gov/edgar.shtml")
print("")
def call_fred(self, other_args: List[str]):
"""Process fred command"""
webbrowser.open("https://fred.stlouisfed.org")
print("")
def call_learn(self, other_args: List[str]):
"""Process learn command"""
webbrowser.open("https://moongangcapital.com/free-stock-market-resources/")

View File

@@ -24,17 +24,19 @@ This menu aims to filter stocks based on pre-specified preset filters, and the u
* [signals](#signals)
* view filter signals (e.g. -s top_gainers) [Finviz]
* [> po](portfolio_optimization/README.md)
* portfolio optimization for last screened tickers
* **portfolio optimization for last screened tickers**
## view <a name="view"></a>
```text
view
usage: view [-p {template,sexy_year}]
```
View available presets under presets folder.
<img width="938" alt="Captura de ecrã 2021-04-05, às 20 13 28" src="https://user-images.githubusercontent.com/25267873/113615237-856a9380-964b-11eb-9e39-a65f0291746d.png">
* -p : View specific preset filters.
<img width="1203" alt="Captura de ecrã 2021-05-06, às 20 46 41" src="https://user-images.githubusercontent.com/25267873/117356901-30b97300-aeac-11eb-91fe-ed6495db6614.png">
## set <a name="set"></a>

View File

@@ -3,6 +3,7 @@ __docformat__ = "numpy"
import os
import argparse
import configparser
from typing import List
import matplotlib.pyplot as plt
from gamestonk_terminal import feature_flags as gtff
@@ -86,37 +87,73 @@ class ScreenerController:
prog="view",
description="""View available presets under presets folder.""",
)
parser.add_argument(
"-p",
"--preset",
action="store",
dest="preset",
type=str,
help="View specific preset",
default="",
choices=[
preset.split(".")[0]
for preset in os.listdir("gamestonk_terminal/screener/presets")
if preset[-4:] == ".ini"
],
)
try:
if other_args:
if "-" not in other_args[0]:
other_args.insert(0, "-p")
ns_parser = parse_known_args_and_warn(parser, other_args)
if not ns_parser:
return
presets = [
preset.split(".")[0]
for preset in os.listdir("gamestonk_terminal/screener/presets")
if preset[-4:] == ".ini"
]
if ns_parser.preset:
preset_filter = configparser.RawConfigParser()
preset_filter.optionxform = str # type: ignore
preset_filter.read(
"gamestonk_terminal/screener/presets/" + ns_parser.preset + ".ini"
)
for preset in presets:
with open(
"gamestonk_terminal/screener/presets/" + preset + ".ini",
encoding="utf8",
) as f:
description = ""
for line in f:
if "[General]" == line.strip():
break
description += line.strip()
print(f"\nPRESET: {preset}")
print(description.split("Description: ")[1].replace("#", ""))
filters_headers = ["General", "Descriptive", "Fundamental", "Technical"]
print("")
for filter_header in filters_headers:
print(f" - {filter_header} -")
d_filters = {**preset_filter[filter_header]}
d_filters = {k: v for k, v in d_filters.items() if v}
if d_filters:
max_len = len(max(d_filters, key=len))
for key, value in d_filters.items():
print(f"{key}{(max_len-len(key))*' '}: {value}")
print("")
else:
presets = [
preset.split(".")[0]
for preset in os.listdir("gamestonk_terminal/screener/presets")
if preset[-4:] == ".ini"
]
for preset in presets:
with open(
"gamestonk_terminal/screener/presets/" + preset + ".ini",
encoding="utf8",
) as f:
description = ""
for line in f:
if "[General]" == line.strip():
break
description += line.strip()
print(f"\nPRESET: {preset}")
print(description.split("Description: ")[1].replace("#", ""))
print("")
except Exception as e:
print(e)
print("")
return
@staticmethod
def set_preset(self, other_args: List[str]):
"""Set preset"""

View File

@@ -43,6 +43,7 @@ from gamestonk_terminal.forex import fx_controller
from gamestonk_terminal.backtesting import bt_controller
from gamestonk_terminal.resource_collection import rc_controller
from gamestonk_terminal.research import res_controller
from gamestonk_terminal.government import gov_controller
# pylint: disable=too-many-statements,too-many-branches
@@ -99,6 +100,7 @@ def main():
"po",
"fx",
"rc",
"gov",
]
menu_parser.add_argument("opt", choices=choices)
@@ -378,6 +380,9 @@ def main():
elif ns_known_args.opt == "rc":
b_quit = rc_controller.menu()
elif ns_known_args.opt == "gov":
b_quit = gov_controller.menu(s_ticker)
else:
print("Shouldn't see this command!")
continue