merge main

This commit is contained in:
Jamie
2021-05-01 20:18:56 -04:00
20 changed files with 937 additions and 700 deletions

View File

@@ -26,7 +26,7 @@
<br />
<p align="center">
<a href="https://github.com/DidierRLopes/GamestonkTerminal">
<img src="images/GamestonkLogo.png" alt="Logo" width="400" height="350">
<img src="images/gst_logo_rGreen.png" alt="Logo" width="400" height="400">
</a>
<h3 align="center">Gamestonk Terminal 🚀</h3>
@@ -136,13 +136,15 @@ cd GamestonkTerminal/
conda install poetry
```
7.5. If installing python 3.8
7.1. If installing python 3.8
```
conda deactivate
conda activate gst
```
*The `conda deactivate` -> `conda activate` in the middle is on purpose, this is sometimes required to avoid issues with poetry*
7.2. If on Windows, install/update Microsoft C++ Build Tools from here: https://visualstudio.microsoft.com/visual-cpp-build-tools/
8. Install poetry dependencies
```
poetry install
@@ -331,6 +333,8 @@ Distributed under the MIT License. See [LICENSE](https://github.com/DidierRLopes
"A few things I am not. I am not a cat. I am not an institutional investor, nor am I a hedge fund. I do not have clients and I do not provide personalized investment advice for fees or commissions." DFV
Trading in financial instruments involves high risks including the risk of losing some, or all, of your investment amount, and may not be suitable for all investors. Before deciding to trade in financial instrument you should be fully informed of the risks and costs associated with trading the financial markets, carefully consider your investment objectives, level of experience, and risk appetite, and seek professional advice where needed. The data contained in GST is not necessarily accurate. GST and any provider of the data contained in this website will not accept liability for any loss or damage as a result of your trading, or your reliance on the information displayed.
## Contacts
[Didier Rodrigues Lopes](https://www.linkedin.com/in/didier-lopes/) - dro.lopes@campus.fct.unl.pt

View File

@@ -15,13 +15,14 @@
* [Residual Analysis](#Residual-Analysis)
* [Portfolio Analysis](#Portfolio-Analysis)
* [Portfolio Optimization](#Portfolio-Optimization)
* [FRED](#FRED)
* [Economy](#Economy)
* [Options](#Options)
* [Credit Analysis](#Credit-Analysis)
* [Cryptocurrencies](#Cryptocurrencies)
* [Screener](#Screener)
* [Forex](#Forex)
* [Backtesting](#Backtesting)
* [Resource Collection](#Resource-Collection)
## Additional
@@ -146,6 +147,7 @@
* [x] Add alpaca (@jmaslek) - [PR #259](https://github.com/DidierRLopes/GamestonkTerminal/pull/229)
* [x] Add robinhood (@jmaslek) - [PR #229](https://github.com/DidierRLopes/GamestonkTerminal/pull/229)
* [x] Add Ally Invest (@jmaslek) - [PR #267](https://github.com/DidierRLopes/GamestonkTerminal/pull/267)
* [x] Degiro support (@deel) - [PR #381](https://github.com/DidierRLopes/GamestonkTerminal/pull/381)
**NEXT**
* [ ] Merge data from different brokers (@jmaslek)
@@ -166,8 +168,9 @@ ___
---
## FRED
## Economy
* [x] Implement Economic data (gpd, unemployment rate, ...) (@jmaslek) - [PR #167](https://github.com/DidierRLopes/GamestonkTerminal/pull/167)
* [x] Refactor FRED to ECON menu and add VIX view (@jmaslek) - [PR #405](https://github.com/DidierRLopes/GamestonkTerminal/pull/405)
**NEXT**
@@ -208,6 +211,7 @@ ___
* [x] Add screener signals (e.g. top gainers, new highs, most volatile, oversold, major news, ...) from Finviz (@didier) - [PR #314](https://github.com/DidierRLopes/GamestonkTerminal/pull/314)
* [x] Plot screener historical using Yahoo Finance data (@didier) - [PR #319](https://github.com/DidierRLopes/GamestonkTerminal/pull/319)
* [x] Add command to take tickers to portfolio optimization (@didier) - [PR #349](https://github.com/DidierRLopes/GamestonkTerminal/pull/349)
* [x] Add flags to save screeners and run papermill on returned tickers (@alokan) - [PR #414](https://github.com/DidierRLopes/GamestonkTerminal/pull/414)
**NEXT**
@@ -215,9 +219,21 @@ ___
## Forex
* [x] Add entire forex menu through Oanda (@alokan) - [PR #360](https://github.com/DidierRLopes/GamestonkTerminal/pull/360)
* [x] Add EDA menu, Behavioural Analysis menu, Due Diligence from other users in Reddit, and latest news regarding currency provided. (@alokan) - [PR #387](https://github.com/DidierRLopes/GamestonkTerminal/pull/387)
**NEXT**
---
## Resource Collection
* [x] Add hfletters and learn commands to resource collection (@didier) - [PR #427](https://github.com/DidierRLopes/GamestonkTerminal/pull/427)
**NEXT**
---
## Backtesting
* [x] Add simple backtest menu with simple strategies and benchmarks (@jmaslek) [PR #415](https://github.com/DidierRLopes/GamestonkTerminal/pull/415)
@@ -250,6 +266,7 @@ ___
* [x] Add Feature Flags (@aia) - [PR #158](https://github.com/DidierRLopes/GamestonkTerminal/pull/158)
* [x] Add ad-hoc builds (@aia) - [PR #192](https://github.com/DidierRLopes/GamestonkTerminal/pull/192)
* [x] Add test generators and test parametrization helpers (@aia) - [PR #264](https://github.com/DidierRLopes/GamestonkTerminal/pull/264)
* [x] Sphinx documentation https://gamestonk-terminal.readthedocs.io/en/latest/index.html (@piiq) - [PR #413](https://github.com/DidierRLopes/GamestonkTerminal/pull/413)
**NEXT**
* [ ] Write a developer guide

View File

@@ -3,7 +3,7 @@
### Table of contents
* [Discover Stocks](#Discover-Stocks-)
* [Behavioural Analysis](#Behavioural-Analysis-)
* [Research Web pages](#Research-Web-pages)
* [Research](#Research-)
* [Fundamental Analysis](#Fundamental-Analysis-)
* [Technical Analysis](#Technical-Analysis-)
* [Due Diligence](#Due-Diligence-)
@@ -14,10 +14,12 @@
* [Comparison Analysis](#Comparison-Analysis-)
* [Exploratory Data Analysis](#Exploratory-Data-Analysis-)
* [Residual Analysis](#Residual-Analysis-)
* [Economic Data](#Econ-)
* [Economy](#Economy)
* [Options](#Options-)
* [Screener](#Screener-)
* [Forex](#Forex-)
* [Backtesting](#Backtesting-)
* [Resource Collection](#Resource-Collection-)
## Main
@@ -115,7 +117,7 @@ Command|Description
&nbsp;
## Research Web pages
## Research [»](research/README.md)
Command|Website
----|----
`macroaxis` |www.macroaxis.com
@@ -136,11 +138,10 @@ Command|Website
`macrotrends` |www.macrotrends.net
`newsfilter` |www.newsfilter.io
`stockanalysis` |www.stockanalysis.com
`resources` |www.tradinganalysisresources.com
&nbsp;
### Fundamental Analysis [»](fundamental_analysis/README.md)
## Fundamental Analysis [»](fundamental_analysis/README.md)
Command|Description
----- | ---------
@@ -237,6 +238,7 @@ Command|Technique|Sources
`lstm` |Long Short-Term Memory | [Wikipedia](https://en.wikipedia.org/wiki/Long_short-term_memory), [Details](https://colah.github.io/posts/2015-08-Understanding-LSTMs/)
&nbsp;
## Portfolio Analysis [»](portfolio/README.md)
Command|Description|Brokers
@@ -250,6 +252,7 @@ Command|Description|Brokers
`hold` | view net holdings across all logins
&nbsp;
## Portfolio Optimization [»](portfolio_optimization/README.md)
Command|Description
@@ -267,7 +270,6 @@ Command|Description
&nbsp;
## Cryptocurrency [»](cryptocurrency/README.md)
Command|Description
@@ -282,6 +284,7 @@ Command|Description
`balance`| look at current binance holdings for loaded coin
&nbsp;
## Comparison Analysis [»](comparison_analysis/README.md)
Command|Description|Source
------ | --------|----
@@ -328,23 +331,22 @@ Command|Description|Source
`independence` |tests independent and identically distributed (BDS) | [Wikipedia](https://en.wikipedia.org/wiki/Pearson%27s_chi-squared_test#Testing_for_statistical_independence)
&nbsp;
## ECON [»](econ/README.md)
## Economy [»](econ/README.md)
Command|Description
------ | --------
FRED Data |
`gdp` | GDP
`unemp` | Unemployment Rate
`t1` | 1-Year Treasury Constant Maturity Rate
`t5` | 5-Year Treasury Constant Maturity Rate
`t10` | 10-Year Treasury Constant Maturity Rate
`t30` | 30-Year Treasury Constant Maturity Rate
`mort30` | 30-Year Fixed Rate Mortgage Average
`fedrate` | Effective Federal Funds Rate
`moodAAA` | Moody's Seasoned AAA Corporate Bond Yield
`usdcad` | Canada / U.S. Foreign Exchange Rate (CAD per 1 USD)
`cust` | User Specified FRED Data - Please Specify --id
VIX Data |
`view` | Plots VIX Historical Data
`vixcls` | Volatility Index
`gdp` | Gross Domestic Product
`unrate` | Unemployment Rate
`dgs1` | 1-Year Treasury Constant Maturity Rate
`dgs5` | 5-Year Treasury Constant Maturity Rate
`dgs10` | 10-Year Treasury Constant Maturity Rate
`dgs30` | 30-Year Treasury Constant Maturity Rate
`mortgage30us` | 30-Year Fixed Rate Mortgage Average
`fedfunds` | Effective Federal Funds Rate
`aaa` | Moody's Seasoned AAA Corporate Bond Yield
`dexcaus` | Canada / U.S. Foreign Exchange Rate (CAD per 1 USD)
&nbsp;
## Options [»](options/README.md)
@@ -376,7 +378,6 @@ signals |view filter signals (e.g. -s top_gainers)
&nbsp;
## Forex [»](forex/README.md)
Command|Description
------ | --------
@@ -395,5 +396,23 @@ order |place a limit order
orderbook |display the orderbook if Oanda provides one for the forex instrument
positionbook |display the positionbook if Oanda provides one for the forex instrument
&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/
&nbsp;

View File

@@ -1,53 +1,52 @@
# 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.
This menu aims to apply backtesting strategies regarding a pre-loaded ticker, and the usage of the following commands along with an example will be exploited below. Note that this is currently just a simple logic (i.e price comparisons). 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.
* [ema](#ema)
* buy when price exceeds EMA(l)
* [ema_cross](#ema_cross)
* buy when EMA(short) > EMA(long)
* [rsi](#rsi)
* buy when RSI < low and sell when RSI > high
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
NOTE: The current implementation uses the [bt](#http://pmorissette.github.io/bt/index.html) library.
### SimpleEMA <a name="SimpleEMA"></a>
This strategy buys when price > EMA(l)
### ema <a name="ema"></a>
````
usage: ema [-l] [--spy] [--no_bench]
````
This strategy buys when price > EMA(l).
* -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](https://user-images.githubusercontent.com/25267873/116769584-1eb37c80-aa35-11eb-898b-efa36d4a8f5c.png)
<img width="983" alt="ema2" src="https://user-images.githubusercontent.com/25267873/116769582-1d824f80-aa35-11eb-94bd-ecd4abe3b415.png">
### 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
### ema_cross <a name="ema_cross"></a>
````
usage: ema_cross [-l] [-s] [--spy] [--no_bench] [--no_short]
````
This strategy goes long when EMA(short) > EMA(long) and goes short when EMA(short) < EMA(long). It provides the option to go long only through the --no_short flag.
* -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
![ema_cross](https://user-images.githubusercontent.com/25267873/116769581-1ce9b900-aa35-11eb-85e9-133b3c0b09ad.png)
<img width="979" alt="ema_cross2" src="https://user-images.githubusercontent.com/25267873/116769583-1e1ae600-aa35-11eb-9732-9fda8eb2a8b1.png">
### rsi <a name="rsi"></a>
````
usage: rsi [-u] [-l] [-p] [--spy] [--no_bench] [--no_short]
````
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
* -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.
@@ -55,5 +54,5 @@ usage: rsi [-u] [-l] [-p] [--spy] [--no_bench] [--no_short]
* [--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.
![rsi](https://user-images.githubusercontent.com/25267873/116769576-19eec880-aa35-11eb-9e60-f77a31e51db0.png)
<img width="980" alt="rsi2" src="https://user-images.githubusercontent.com/25267873/116769579-1c512280-aa35-11eb-928b-aa4e8b90c1ec.png">

View File

@@ -43,7 +43,7 @@ class BacktestingController:
def print_help(self):
"""Print help"""
print("Back Testing Menu\n")
print("\nBacktesting:")
print(" help show this backtesting menu again")
print(" q quit this menu, and shows back to main menu")
print(" quit quit to abandon program")

View File

@@ -1,134 +1,183 @@
# ECON
# ECONONMY
## FRED
This menu aims to assess economy data, and the usage of the following commands along with an example will be exploited below.
https://fred.stlouisfed.org
* [fred](#fred)
* display customized FRED from https://fred.stlouisfed.org
* [vixcls](#vixcls)
* Volatility Index
* [gdp](#gdp)
* Gross Domestic Product
* [unrate](#unrate)
* Unemployment Rate
* [dgs1](#dgs1)
* 1-Year Treasury Constant Maturity Rate
* [dgs5](#dgs5)
* 5-Year Treasury Constant Maturity Rate
* [dgs10](#dgs10)
* 10-Year Treasury Constant Maturity Rate
* [dgs30](#dgs30)
* 30-Year Treasury Constant Maturity Rate
* [mortgage30us](#mortgage30us)
* 30-Year Fixed Rate Mortgage Average
* [fedfunds](#fedfunds)
* Effective Federal Funds Rate
* [aaa](#aaa)
* Moody's Seasoned AAA Corporate Bond Yield
* [dexcaus](#dexcaus)
* Canada / U.S. Foreign Exchange Rate (CAD per 1 USD)
The purpose of fred is to have the ability to look at economic data. This page offers 2 options:
* [predefined](#gdp)
* Get predefined data
* [cust](#cust)
* Get custom fred data
The current predefined options are
* GDP
* 1,5,10,30 Year Treasury Rates
* 30 Year Mortgage Rates
* Unemployment Rate
* Effective Federal Funds rate
* Moody's AAA Corporate Bond
* CAD to USD Conversion.
## predefined <a name="predefined"></a>
## fred <a name="fred"></a>
```text
usage: selected [-n N_TO_GET] [-s START_DATE] [--noplot] [--hidedata]
usage: fred [-i SERIES_ID] [-s START_DATE] [-t]
```
Gets predefined data. Arguments
* selected : Key from the predefined list.
* -s : Start Date. Format YYYY-mm-dd. First point to get. Defaults to Jan 1 2019
* --noplot : Flag to hide plot
* --hidedata : Flag to suppress printing output. Useful for data released daily/weekly.
To plot the 30-Year Mortgage rates since 2018-01-01 suppressing the output.
````
mort30 -s 2018-01-01 --hidedata
````
Display customized Federal Reserve Economic Data (FRED) from https://fred.stlouisfed.org.
![mort30](https://user-images.githubusercontent.com/18151143/111521185-3d80dc80-872f-11eb-989d-c2bb256aa213.png)
To show all GDP data since 1/1/2016, with no plot.
````
gdp -s 2016-01-01 --noplot
````
Output:
````
GDP
Date
2016-01-01 18470.156
2016-04-01 18656.207
2016-07-01 18821.359
2016-10-01 19032.580
2017-01-01 19237.435
2017-04-01 19379.232
2017-07-01 19617.288
2017-10-01 19937.963
2018-01-01 20242.215
2018-04-01 20552.653
2018-07-01 20742.723
2018-10-01 20909.853
2019-01-01 21115.309
2019-04-01 21329.877
2019-07-01 21540.325
2019-10-01 21747.394
2020-01-01 21561.139
2020-04-01 19520.114
2020-07-01 21170.252
2020-10-01 21487.896
````
* -i : FRED Series ID from https://fred.stlouisfed.org.
* -s : Starting date (YYYY-MM-DD) of data. Default: 2019-01-01.
* -t : Only output text data.
## cust <a name="cust"></a>
## vixcls <a name="vixcls"></a>
```text
usage: vixcls [-s START_DATE] [-t]
```
The fred database has many different datasets freely available. They each have their own custom SERIES_ID which can be obtained through the website.
Volatility Index
````
usage: cust [-i --id] [-s START_DATE] [--noplot] [--hidedata]
````
* -i/--id : Series ID for FRED data. Required argument
* -s : Start Date. Format YYYY-mm-dd. First point to get. Defaults to Jan 1 2015.
* --noplot : Flag to suppress output plot.
* --hidedata : Flag to suppress data output
* -s : Starting date (YYYY-MM-DD) of data. Default: 2019-01-01.
* -t : Only output text data.
An example of custom data could be the USD/EURO exchange rate.
According to https://fred.stlouisfed.org/series/DEXUSEU , the series ID is DEXUSEU. So to plot this from the start of February 2021 to now (3/17)
![vixcls](https://user-images.githubusercontent.com/25267873/116769167-160d7700-aa32-11eb-8874-3b864908c9c2.png)
````
cust --id DEXUSEU -s 2021-02-01
````
This will plot and display:
![cust](https://user-images.githubusercontent.com/18151143/111521481-92bcee00-872f-11eb-8a02-e7346e56e462.png)
````
DEXUSEU
Date
2021-02-01 1.2070
2021-02-02 1.2020
2021-02-03 1.2025
2021-02-04 1.1974
2021-02-05 1.2035
2021-02-08 1.2045
2021-02-09 1.2106
2021-02-10 1.2132
2021-02-11 1.2127
2021-02-12 1.2126
2021-02-15 NaN
2021-02-16 1.2107
2021-02-17 1.2042
2021-02-18 1.2078
2021-02-19 1.2136
2021-02-22 1.2155
2021-02-23 1.2142
2021-02-24 1.2143
2021-02-25 1.2229
2021-02-26 1.2093
2021-03-01 1.2054
2021-03-02 1.2079
2021-03-03 1.2073
2021-03-04 1.2045
2021-03-05 1.1914
2021-03-08 1.1849
2021-03-09 1.1885
2021-03-10 1.1900
2021-03-11 1.1978
````
## gdp <a name="gdp"></a>
```text
usage: gdp [-s START_DATE] [-t]
```
Note the NaN on 2-15, which corresponds to President's Day.
Gross Domestic Product
## VIX
* -s : Starting date (YYYY-MM-DD) of data. Default: 2019-01-01.
* -t : Only output text data.
This command pulls historical VIX data from yfinance module.
````
usage: view [-s START_DATE]
````
* -s Start date to plot historical VIX data
![gdp](https://user-images.githubusercontent.com/25267873/116769162-14dc4a00-aa32-11eb-886a-b5368146ed37.png)
## unrate <a name="unrate"></a>
```text
usage: unrate [-s START_DATE] [-t]
```
Unemployment Rate
* -s : Starting date (YYYY-MM-DD) of data. Default: 2019-01-01.
* -t : Only output text data.
![unrate](https://user-images.githubusercontent.com/25267873/116769161-14dc4a00-aa32-11eb-91f3-a0f80d687a12.png)
## dgs1 <a name="dgs1"></a>
```text
usage: dgs1 [-s START_DATE] [-t]
```
1-year Treasury Constant Maturity Rate
* -s : Starting date (YYYY-MM-DD) of data. Default: 2019-01-01.
* -t : Only output text data.
![dgs1](https://user-images.githubusercontent.com/25267873/116769166-160d7700-aa32-11eb-9247-78156af4d527.png)
## dgs5 <a name="dgs5"></a>
```text
usage: dgs5 [-s START_DATE] [-t]
```
5-year Treasury Constant Maturity Rate
* -s : Starting date (YYYY-MM-DD) of data. Default: 2019-01-01.
* -t : Only output text data.
![dgs5](https://user-images.githubusercontent.com/25267873/116769165-1574e080-aa32-11eb-96ee-c57728d8f57c.png)
## dgs10 <a name="dgs10"></a>
```text
usage: dgs10 [-s START_DATE] [-t]
```
10-year Treasury Constant Maturity Rate
* -s : Starting date (YYYY-MM-DD) of data. Default: 2019-01-01.
* -t : Only output text data.
![dgs10](https://user-images.githubusercontent.com/25267873/116769164-1574e080-aa32-11eb-93a0-3b8a2b7cb3d2.png)
## dgs30 <a name="dgs30"></a>
```text
usage: dgs30 [-s START_DATE] [-t]
```
30-year Treasury Constant Maturity Rate
* -s : Starting date (YYYY-MM-DD) of data. Default: 2019-01-01.
* -t : Only output text data.
![dgs30](https://user-images.githubusercontent.com/25267873/116769159-13ab1d00-aa32-11eb-8c3d-e53c8d1f1a19.png)
## mortgage30us <a name="mortgage30us"></a>
```text
usage: mortgage30us [-s START_DATE] [-t]
```
30-year Fixed Rate Mortgage Average
* -s : Starting date (YYYY-MM-DD) of data. Default: 2019-01-01.
* -t : Only output text data.
![mortgage30us](https://user-images.githubusercontent.com/25267873/116769157-13128680-aa32-11eb-8826-ccb2e6ae764e.png)
## fedfunds <a name="fedfunds"></a>
```text
usage: fedfunds [-s START_DATE] [-t]
```
Effective Federal Funds Rate
* -s : Starting date (YYYY-MM-DD) of data. Default: 2019-01-01.
* -t : Only output text data.
![fedfunds](https://user-images.githubusercontent.com/25267873/116769158-13ab1d00-aa32-11eb-9dc2-8296bc4f7e2c.png)
## aaa <a name="aaa"></a>
```text
usage: aaa [-s START_DATE] [-t]
```
Moody's Seasoned AAA Corporate Bond Yield
* -s : Starting date (YYYY-MM-DD) of data. Default: 2019-01-01.
* -t : Only output text data.
![aaa](https://user-images.githubusercontent.com/25267873/116769160-1443b380-aa32-11eb-84a8-036e15b47c9b.png)
## dexcaus <a name="dexcaus"></a>
```text
usage: dexcaus [-s START_DATE] [-t]
```
Canada / U.S. Foreign Exchange Rate (CAD per 1 USD)
* -s : Starting date (YYYY-MM-DD) of data. Default: 2019-01-01.
* -t : Only output text data.
![dexcaus](https://user-images.githubusercontent.com/25267873/116769155-10b02c80-aa32-11eb-8ece-d8e92b8df1af.png)

View File

@@ -8,7 +8,7 @@ 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
from gamestonk_terminal.econ import fred_view, vix_view
from gamestonk_terminal.econ import fred_view
class EconController:
@@ -19,24 +19,24 @@ class EconController:
"help",
"q",
"quit",
"fred",
"vixcls",
"gdp",
"unemp",
"t1",
"t5",
"t10",
"t30",
"mort30",
"fedrate",
"moodAAA",
"usdcad",
"cust",
"view",
"unrate",
"dgs1",
"dgs5",
"dgs10",
"dgs30",
"mortgage30us",
"fedfunds",
"aaa",
"dexcaus",
]
def __init__(self):
"""Constructor"""
self.disc_parser = argparse.ArgumentParser(add_help=False, prog="econ")
self.disc_parser.add_argument(
self.econ_parser = argparse.ArgumentParser(add_help=False, prog="econ")
self.econ_parser.add_argument(
"cmd",
choices=self.CHOICES,
)
@@ -50,21 +50,20 @@ class EconController:
print(" q quit this menu, and shows back to main menu")
print(" quit quit to abandon program")
print(" ")
print("VIX:")
print(" view plot VIX")
print(" ")
print("FRED:")
print(" gdp GDP")
print(" unemp Unemployment Rate")
print(" t1 1-Year Treasury Constant Maturity Rate")
print(" t5 5-Year Treasury Constant Maturity Rate")
print(" t10 10-Year Treasury Constant Maturity Rate")
print(" t30 30-Year Treasury Constant Maturity Rate")
print(" mort30 30-Year Fixed Rate Mortgage Average")
print(" fedrate Effective Federal Funds Rate")
print(" moodAAA Moody's Seasoned AAA Corporate Bond Yield")
print(" usdcad Canada / U.S. Foreign Exchange Rate (CAD per 1 USD)")
print(" cust User Specified FRED Data - Please Specify --id")
print(
" fred display customized FRED data from https://fred.stlouisfed.org"
)
print(" vixcls Volatility Index")
print(" gdp Gross Domestic Product")
print(" unrate Unemployment Rate")
print(" dgs1 1-year Treasury Constant Maturity Rate")
print(" dgs5 5-year Treasury Constant Maturity Rate")
print(" dgs10 10-year Treasury Constant Maturity Rate")
print(" dgs30 30-year Treasury Constant Maturity Rate")
print(" mortgage30us 30-year Fixed Rate Mortgage Average")
print(" fedfunds Effective Federal Funds Rate")
print(" aaa Moody's Seasoned AAA Corporate Bond Yield")
print(" dexcaus Canada / U.S. Foreign Exchange Rate (CAD per 1 USD)")
print("")
return
@@ -78,23 +77,7 @@ class EconController:
True - quit the program
None - continue in the menu
"""
(known_args, other_args) = self.disc_parser.parse_known_args(an_input.split())
fred_data_list = [
"gdp",
"unemp",
"t1",
"t5",
"t10",
"t30",
"mort30",
"fedrate",
"moodAAA",
"usdcad",
]
if known_args.cmd in fred_data_list:
return getattr(self, "call_fred_api")(other_args, known_args.cmd)
(known_args, other_args) = self.econ_parser.parse_known_args(an_input.split())
return getattr(
self, "call_" + known_args.cmd, lambda: "Command not recognized!"
@@ -112,17 +95,53 @@ class EconController:
"""Process Quit command - quit the program"""
return True
def call_fred_api(self, other_args: List[str], cmd: str):
"""Process Fred Data call"""
fred_view.get_fred_data(other_args, cmd)
def call_fred(self, other_args: List[str]):
"""Process fred command"""
fred_view.display_fred(other_args, "")
def call_view(self, other_args: List[str]):
"""Process view for VIX Data."""
vix_view.view_vix(other_args)
def call_vixcls(self, other_args: List[str]):
"""Process vixcls command"""
fred_view.display_fred(other_args, "VIXCLS")
def call_cust(self, other_args: List[str]):
"""Process cust call"""
fred_view.custom_data(other_args)
def call_gdp(self, other_args: List[str]):
"""Process gdp command"""
fred_view.display_fred(other_args, "GDP")
def call_unrate(self, other_args: List[str]):
"""Process unrate command"""
fred_view.display_fred(other_args, "UNRATE")
def call_dgs1(self, other_args: List[str]):
"""Process dgs1 command"""
fred_view.display_fred(other_args, "DGS1")
def call_dgs5(self, other_args: List[str]):
"""Process dgs5 command"""
fred_view.display_fred(other_args, "DGS5")
def call_dgs10(self, other_args: List[str]):
"""Process dgs10 command"""
fred_view.display_fred(other_args, "DGS10")
def call_dgs30(self, other_args: List[str]):
"""Process dgs30 command"""
fred_view.display_fred(other_args, "DGS30")
def call_mortgage30us(self, other_args: List[str]):
"""Process mortgage30us command"""
fred_view.display_fred(other_args, "MORTGAGE30US")
def call_fedfunds(self, other_args: List[str]):
"""Process fedfunds command"""
fred_view.display_fred(other_args, "FEDFUNDS")
def call_aaa(self, other_args: List[str]):
"""Process aaa command"""
fred_view.display_fred(other_args, "AAA")
def call_dexcaus(self, other_args: List[str]):
"""Process dexcaus command"""
fred_view.display_fred(other_args, "DEXCAUS")
def menu():

View File

@@ -18,138 +18,50 @@ from gamestonk_terminal import feature_flags as gtff
register_matplotlib_converters()
api_map = {
"gdp": "GDP",
"t10": "DGS10",
"t1": "DGS1",
"t5": "DGS5",
"t30": "DGS30",
"mort30": "MORTGAGE30US",
"fedrate": "FEDFUNDS",
"moodAAA": "AAA",
"usdcad": "DEXCAUS",
"unemp": "UNRATE",
}
title_map = {
"gdp": "Gross Domestic Product",
"t10": "10-Year Treasury Constant Maturity Rate",
"t1": "1-Year Treasury Constant Maturity Rate",
"t5": "5-Year Treasury Constant Maturity Rate",
"t30": "30-Year Treasury Constant Maturity Rate",
"mort30": "30-Year Mortgage Rate",
"fedrate": "Effective Federal Funds Rate",
"moodAAA": "Moody's Seasoned AAA Corporate Bond Yield",
"usdcad": "Canada / U.S. Foreign Exchange Rate",
"unemp": "Unemployment Rate",
fred_series_description = {
"VIXCLS": "Volatility Index",
"GDP": "Gross Domestic Product",
"UNRATE": "Unemployment Rate",
"DGS1": "1-Year Treasury Constant Maturity Rate",
"DGS5": "5-Year Treasury Constant Maturity Rate",
"DGS10": "10-Year Treasury Constant Maturity Rate",
"DGS30": "30-Year Treasury Constant Maturity Rate",
"MORTGAGE30US": "30-Year Mortgage Rate",
"FEDFUNDS": "Effective Federal Funds Rate",
"AAA": "Moody's Seasoned AAA Corporate Bond Yield",
"DEXCAUS": "Canada / U.S. Foreign Exchange Rate",
}
def get_fred_data(other_args: List[str], choice: str):
"""Displace Fred data and graph for a selected chosen data series
def display_fred(other_args: List[str], choice: str):
"""Display customized Federal Reserve Economic Data (FRED) from https://fred.stlouisfed.org.
Parameters
----------
other_args : List[str]
argparse other args
choice : str
Fred data series: "gdp","unemp", "t1", "t5", "t10", "t30", "mort30",
"fedrate", "moodAAA", "usdcad",
Fred data series: "VIXCLS", "GDP", "DGS1", "DGS5", "DGS10", "DGS30", "MORTGAGE30US", "FEDFUNDS",
"AAA", "DEXCAUS", "UNRATE",
"""
fred = Fred(api_key=API_FRED_KEY)
parser = argparse.ArgumentParser(
add_help=False,
prog="Custom",
prog=choice if choice else "fred",
description="""
Custom Data
Display customized Federal Reserve Economic Data (FRED) from https://fred.stlouisfed.org.
""",
)
parser.add_argument(
"-s",
dest="start_date",
type=valid_date,
default="2019-01-01",
required=False,
help="Starting date (YYYY-MM-DD) of data",
)
parser.add_argument(
"--noplot",
action="store_false",
default=True,
dest="noplot",
help="Suppress output plot",
)
parser.add_argument(
"--hidedata",
action="store_false",
default=True,
dest="hidedata",
help="Suppress data display plot",
)
try:
ns_parser = parse_known_args_and_warn(parser, other_args)
if not ns_parser:
return
string_to_get = api_map[choice]
title = title_map[choice]
data = fred.get_series(string_to_get, ns_parser.start_date)
data = pd.DataFrame(data, columns=[f"{string_to_get}"])
data.index.name = "Date"
if ns_parser.hidedata:
print(data)
print("")
if ns_parser.noplot:
plt.figure(figsize=plot_autoscale(), dpi=PLOT_DPI)
plt.plot(data.index, data.iloc[:, 0], "-ok")
plt.xlabel("Time")
plt.xlim(data.index[0], data.index[-1])
plt.ylabel(f"{string_to_get}")
plt.grid(b=True, which="major", color="#666666", linestyle="-")
plt.minorticks_on()
plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2)
plt.title(title)
plt.show()
print("")
if gtff.USE_ION:
plt.ion()
except SystemExit:
print("")
except Exception as e:
print(e)
print("")
return
def custom_data(other_args: List[str]):
"""Displace Fred data for a custom series request
Parameters
----------
other_args : List[str]
argparse other args
"""
fred = Fred(api_key=API_FRED_KEY)
parser = argparse.ArgumentParser(
add_help=False,
prog="Custom",
description="""
Custom Data
""",
)
parser.add_argument(
"-i", "--id", dest="series_id", required=True, type=str, help="FRED Series ID"
"-i",
"--id",
dest="series_id",
required=bool(choice),
type=str,
default=choice.upper(),
help="FRED Series ID from https://fred.stlouisfed.org",
)
parser.add_argument(
@@ -157,58 +69,55 @@ def custom_data(other_args: List[str]):
dest="start_date",
type=valid_date,
default="2019-01-01",
required=False,
help="Starting date (YYYY-MM-DD) of data",
)
parser.add_argument(
"--noplot",
action="store_false",
default=True,
dest="noplot",
help="Suppress output plot",
)
parser.add_argument(
"--hidedata",
action="store_false",
default=True,
dest="hidedata",
help="Suppress data display plot",
"-t",
"--text",
action="store_true",
dest="text",
help="Only output text data",
)
try:
if not choice:
if other_args:
if "-" not in other_args[0]:
other_args.insert(0, "-i")
ns_parser = parse_known_args_and_warn(parser, other_args)
if not ns_parser:
return
data = fred.get_series(ns_parser.series_id, ns_parser.start_date)
fred = Fred(api_key=API_FRED_KEY)
d_data = fred.get_series(ns_parser.series_id, ns_parser.start_date)
data = pd.DataFrame(data, columns=[f"{ns_parser.series_id}"])
data.index.name = "Date"
if ns_parser.hidedata:
print(data)
print("")
if ns_parser.noplot:
df_fred = pd.DataFrame(d_data, columns=[f"{ns_parser.series_id}"])
df_fred.index.name = "Date"
if ns_parser.text:
print(df_fred.to_string())
else:
plt.figure(figsize=plot_autoscale(), dpi=PLOT_DPI)
plt.plot(data.index, data.iloc[:, 0], "-ok")
plt.plot(df_fred.index, df_fred.iloc[:, 0])
plt.xlabel("Time")
plt.xlim(data.index[0], data.index[-1])
plt.ylabel(f"{ns_parser.series_id}")
plt.xlim(df_fred.index[0], df_fred.index[-1])
plt.ylabel(f"{ns_parser.series_id.upper()}")
plt.grid(b=True, which="major", color="#666666", linestyle="-")
plt.minorticks_on()
plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2)
plt.title(f"FRED {ns_parser.series_id} Series")
plt.show()
print("")
if choice:
plt.title(fred_series_description[ns_parser.series_id])
if gtff.USE_ION:
plt.ion()
plt.show()
print("")
except SystemExit:
print("")
except Exception as e:
print(e)
print("")
print(e, "\n")
return

View File

@@ -1,63 +0,0 @@
""" VIX View """
__docformat__ = "numpy"
import argparse
from typing import List
from pandas.plotting import register_matplotlib_converters
import matplotlib.pyplot as plt
import yfinance as yf
from gamestonk_terminal.helper_funcs import (
parse_known_args_and_warn,
valid_date,
plot_autoscale,
)
from gamestonk_terminal.config_plot import PLOT_DPI
from gamestonk_terminal import feature_flags as gtff
register_matplotlib_converters()
def view_vix(other_args: List[str]):
"""
Plot vix from a starting date using yfinance
Parameters
----------
other_args: List[str]
List of argparse arguments
Returns
-------
Plots VIX historical data
"""
parser = argparse.ArgumentParser(prog="vix_plot", add_help=False)
parser.add_argument(
"-s",
"--start",
type=valid_date,
default="2020-01-01",
dest="start_date",
help="The starting date (format YYYY-MM-DD) of the plot",
)
try:
ns_parser = parse_known_args_and_warn(parser, other_args)
if not ns_parser:
return
vix = yf.download("^VIX", start=ns_parser.start_date, progress=False)
_, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)
vix.plot(y="Adj Close", ax=ax)
plt.ylabel("VIX")
plt.grid(b=True, which="major", color="#666666", linestyle="-")
plt.minorticks_on()
plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2)
plt.title("Historical VIX Data")
print("")
if gtff.USE_ION:
plt.ion()
plt.show()
except Exception as e:
print(e)
print("")

View File

@@ -213,7 +213,7 @@ def sustainability(other_args: List[str], ticker: str):
df_sustainability = stock.sustainability
if not df_sustainability:
if df_sustainability.empty:
print(f"No sustainability information in Yahoo for {ticker}")
print("")
return

View File

@@ -1,5 +1,6 @@
import argparse
from sys import stdout
import random
from datetime import datetime, timedelta
import matplotlib.pyplot as plt
import pandas as pd
@@ -45,57 +46,59 @@ def print_help(s_ticker, s_start, s_interval, b_is_market_open):
print(f"\n{s_intraday} Stock: {s_ticker}")
else:
print("\nStock: ?")
print(f"Market {('CLOSED', 'OPEN')[b_is_market_open]}.")
print(f"Market {('CLOSED', 'OPEN')[b_is_market_open]}.\n")
print("\nMenus:")
print(
" disc discover trending stocks, \t e.g. map, sectors, high short interest"
" > disc discover trending stocks, \t e.g. map, sectors, high short interest"
)
print(
" scr screener stocks, \t\t e.g. overview/performance, using preset filters"
" > scr screener stocks, \t\t e.g. overview/performance, using preset filters"
)
print(" mill papermill menu, \t\t\t menu to generate notebook reports")
print(" econ economic data, \t\t\t from: FRED, VIX")
print(" pa portfolio analysis, \t\t supports: robinhood, alpaca, ally ")
print(" crypto cryptocurrencies, \t\t coingecko, coinmarketcap and binance")
print(" > mill papermill menu, \t\t menu to generate notebook reports")
print(" > econ economic data, \t\t from: FRED, VIX")
print(
" po portfolio optimization, \t\t optimal portfolio weights from pyportfolioopt"
" > pa portfolio analysis, \t\t supports: robinhood, alpaca, ally "
)
print(" fx forex menu, \t\t\t forex support through Oanda")
print(" > crypto cryptocurrencies, \t\t from: coingecko, coinmarketcap, binance")
print(
" > po portfolio optimization, \t optimal portfolio weights from pyportfolioopt"
)
print(" > fx forex menu, \t\t\t forex support through Oanda")
print(" > rc resource collection, \t\t e.g. hf letters")
if s_ticker:
print(
" ba behavioural analysis, \t from: reddit, stocktwits, twitter, google"
" > ba behavioural analysis, \t from: reddit, stocktwits, twitter, google"
)
print(
" res research web page, \t e.g.: macroaxis, yahoo finance, fool"
" > res research web page, \t e.g.: macroaxis, yahoo finance, fool"
)
print(
" ca comparison analysis, \t e.g.: historical, correlation, financials"
" > ca comparison analysis, \t e.g.: historical, correlation, financials"
)
print(
" fa fundamental analysis, \t e.g.: income, balance, cash, earnings"
" > fa fundamental analysis, \t e.g.: income, balance, cash, earnings"
)
print(
" ta technical analysis, \t e.g.: ema, macd, rsi, adx, bbands, obv"
" > 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"
" > 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"
" > dd in-depth due-diligence, \t e.g.: news, analyst, shorts, insider, sec"
)
print(
" eda exploratory data analysis,\t e.g.: decompose, cusum, residuals analysis"
" > eda exploratory data analysis,\t e.g.: decompose, cusum, residuals analysis"
)
print(
" pred prediction techniques, \t e.g.: regression, arima, rnn, lstm, prophet"
" > pred prediction techniques, \t e.g.: regression, arima, rnn, lstm, prophet"
)
print(
" ra residuals analysis, \t e.g.: model fit, qqplot, hypothesis test"
" > 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("")
@@ -181,41 +184,40 @@ def load(l_args, s_ticker, s_start, s_interval, df_stock):
if not ns_parser:
return [s_ticker, s_start, s_interval, df_stock]
except SystemExit:
print("")
return [s_ticker, s_start, s_interval, df_stock]
# Update values:
s_ticker = ns_parser.s_ticker.upper()
s_start = ns_parser.s_start_date
s_interval = str(ns_parser.n_interval) + "min"
try:
# Daily
if s_interval == "1440min":
if ns_parser.n_interval == 1440:
# Alpha Vantage Source
if ns_parser.source == "av":
ts = TimeSeries(key=cfg.API_KEY_ALPHAVANTAGE, output_format="pandas")
# pylint: disable=unbalanced-tuple-unpacking
df_stock, _ = ts.get_daily_adjusted(
df_stock_candidate, _ = ts.get_daily_adjusted(
symbol=ns_parser.s_ticker, outputsize="full"
)
# pylint: disable=no-member
df_stock.sort_index(ascending=True, inplace=True)
# Slice dataframe from the starting date YYYY-MM-DD selected
df_stock = df_stock[ns_parser.s_start_date :]
elif ns_parser.source == "yf":
df_stock = yf.download(
ns_parser.s_ticker, start=ns_parser.s_start_date, progress=False
)
# Check that a stock was successfully retrieved
if df_stock.empty:
# Check that loading a stock was not successful
if df_stock_candidate.empty:
print("")
return [s_ticker, s_start, s_interval, df_stock]
df_stock = df_stock.rename(
# pylint: disable=no-member
df_stock_candidate.sort_index(ascending=True, inplace=True)
# Slice dataframe from the starting date YYYY-MM-DD selected
df_stock_candidate = df_stock_candidate[ns_parser.s_start_date :]
# Yahoo Finance Source
elif ns_parser.source == "yf":
df_stock_candidate = yf.download(
ns_parser.s_ticker, start=ns_parser.s_start_date, progress=False
)
# Check that loading a stock was not successful
if df_stock_candidate.empty:
print("")
return [s_ticker, s_start, s_interval, df_stock]
df_stock_candidate = df_stock_candidate.rename(
columns={
"Open": "1. open",
"High": "2. high",
@@ -225,41 +227,57 @@ def load(l_args, s_ticker, s_start, s_interval, df_stock):
"Volume": "6. volume",
}
)
df_stock.index.name = "date"
df_stock_candidate.index.name = "date"
if df_stock.index[0] > s_start:
s_start = df_stock.index[0]
# Check if start time from dataframe is more recent than specified
if df_stock_candidate.index[0] > pd.to_datetime(ns_parser.s_start_date):
s_start = df_stock_candidate.index[0]
else:
s_start = ns_parser.s_start_date
# Intraday
else:
# Alpha Vantage Source
if ns_parser.source == "av":
ts = TimeSeries(key=cfg.API_KEY_ALPHAVANTAGE, output_format="pandas")
# pylint: disable=unbalanced-tuple-unpacking
df_stock, _ = ts.get_intraday(
symbol=ns_parser.s_ticker, outputsize="full", interval=s_interval
df_stock_candidate, _ = ts.get_intraday(
symbol=ns_parser.s_ticker,
outputsize="full",
interval=str(ns_parser.n_interval) + "min",
)
# Check that loading a stock was not successful
if df_stock_candidate.empty:
print("")
return [s_ticker, s_start, s_interval, df_stock]
# pylint: disable=no-member
df_stock.sort_index(ascending=True, inplace=True)
df_stock_candidate.sort_index(ascending=True, inplace=True)
# Slice dataframe from the starting date YYYY-MM-DD selected
df_stock = df_stock[ns_parser.s_start_date :]
df_stock_candidate = df_stock_candidate[ns_parser.s_start_date :]
# Check if start time from dataframe is more recent than specified
if df_stock_candidate.index[0] > pd.to_datetime(ns_parser.s_start_date):
s_start = df_stock_candidate.index[0]
else:
s_start = ns_parser.s_start_date
# Yahoo Finance Source
elif ns_parser.source == "yf":
s_int = s_interval[:-2]
s_int = str(ns_parser.n_interval) + "m"
d_granularity = {"1m": 6, "5m": 59, "15m": 59, "30m": 59, "60m": 729}
s_start_dt = datetime.utcnow() - timedelta(days=d_granularity[s_int])
s_date_start = s_start_dt.strftime("%Y-%m-%d")
s_start = pytz.utc.localize(s_start_dt)
if s_start_dt > ns_parser.s_start_date:
print(
f"Using Yahoo Finance with granularity {s_int} the starting date is set to: {s_date_start}\n"
)
# Using Yahoo Finance with granularity {s_int} the starting date is set to: {s_date_start}
df_stock = yf.download(
df_stock_candidate = yf.download(
ns_parser.s_ticker,
start=s_date_start,
progress=False,
@@ -268,7 +286,7 @@ def load(l_args, s_ticker, s_start, s_interval, df_stock):
)
else:
df_stock = yf.download(
df_stock_candidate = yf.download(
ns_parser.s_ticker,
start=ns_parser.s_start_date.strftime("%Y-%m-%d"),
progress=False,
@@ -276,12 +294,17 @@ def load(l_args, s_ticker, s_start, s_interval, df_stock):
prepost=ns_parser.b_prepost,
)
# Check that a stock was successfully retrieved
if df_stock.empty:
# Check that loading a stock was not successful
if df_stock_candidate.empty:
print("")
return [s_ticker, s_start, s_interval, df_stock]
df_stock = df_stock.rename(
if s_start_dt > ns_parser.s_start_date:
s_start = pytz.utc.localize(s_start_dt)
else:
s_start = ns_parser.s_start_date
df_stock_candidate = df_stock_candidate.rename(
columns={
"Open": "1. open",
"High": "2. high",
@@ -291,26 +314,29 @@ def load(l_args, s_ticker, s_start, s_interval, df_stock):
"Volume": "6. volume",
}
)
df_stock.index.name = "date"
df_stock_candidate.index.name = "date"
return [s_ticker, s_start, s_interval, df_stock]
s_intraday = (f"Intraday {s_interval}", "Daily")[ns_parser.n_interval == 1440]
print(
f"Loading {s_intraday} {ns_parser.s_ticker.upper()} stock "
f"with starting period {s_start.strftime('%Y-%m-%d')} for analysis.\n"
)
return [
ns_parser.s_ticker.upper(),
s_start,
str(ns_parser.n_interval) + "min",
df_stock_candidate,
]
except Exception as e:
print(e)
print("Either the ticker or the API_KEY are invalids. Try again!\n")
print(e, "\nEither the ticker or the API_KEY are invalids. Try again!\n")
return [s_ticker, s_start, s_interval, df_stock]
s_intraday = (f"Intraday {s_interval}", "Daily")[s_interval == "1440min"]
if s_start:
print(
f"Loading {s_intraday} {s_ticker} stock with starting period {s_start.strftime('%Y-%m-%d')} for analysis."
)
else:
print(f"Loading {s_intraday} {s_ticker} stock for analysis.")
print("")
return [s_ticker, s_start, s_interval, df_stock]
except SystemExit:
print("")
return [s_ticker, s_start, s_interval, df_stock]
def candle(s_ticker: str, s_start: str):
@@ -513,3 +539,32 @@ def export(l_args, df_stock):
df_stock.to_clipboard()
print("")
def print_goodbye():
goodbye_msg = [
"An informed ape, is a strong ape. ",
"Remember that stonks only go up. ",
"Diamond hands. ",
"Apes together strong. ",
"This is our way. ",
"Keep the spacesuit ape, we haven't reached the moon yet. ",
"I am not a cat. I'm an ape. ",
"We like the terminal. ",
]
goodbye_hr = datetime.now().hour
if goodbye_hr < 5:
goodbye_msg_time = "Go get some rest soldier!"
elif goodbye_hr < 11:
goodbye_msg_time = "Rise and shine baby!"
elif goodbye_hr < 17:
goodbye_msg_time = "Enjoy your day!"
elif goodbye_hr < 23:
goodbye_msg_time = "Tomorrow's another day!"
else:
goodbye_msg_time = "Go get some rest soldier!"
print(
goodbye_msg[random.randint(0, len(goodbye_msg) - 1)] + goodbye_msg_time + "\n"
)

View File

@@ -1,180 +0,0 @@
import argparse
import webbrowser
def print_research(s_ticker, s_start, s_interval):
"""Print help"""
s_intraday = (f"Intraday {s_interval}", "Daily")[s_interval == "1440min"]
if s_start:
print(f"\n{s_intraday} Stock: {s_ticker} (from {s_start.strftime('%Y-%m-%d')})")
else:
print(f"\n{s_intraday} Stock: {s_ticker}")
print("\nResearch Mode:")
print(" help show this research menu again")
print(" q quit this menu, and shows back to main menu")
print(" quit quit to abandon program")
print("")
print(" macroaxis www.macroaxis.com")
print(" yahoo www.finance.yahoo.com")
print(" finviz www.finviz.com")
print(" marketwatch www.marketwatch.com")
print(" fool www.fool.com")
print(" businessinsider www.markets.businessinsider.com")
print(" fmp www.financialmodelingprep.com")
print(" fidelity www.eresearch.fidelity.com")
print(" tradingview www.tradingview.com")
print(" marketchameleon www.marketchameleon.com")
print(" stockrow www.stockrow.com")
print(" barchart www.barchart.com")
print(" grufity www.grufity.com")
print(" fintel www.fintel.com")
print(" zacks www.zacks.com")
print(" macrotrends www.macrotrends.net")
print(" newsfilter www.newsfilter.io")
print(" stockanalysis www.stockanalysis.com")
print("")
print(" resources trading analysis, tips and research")
print("")
# pylint: disable=too-many-branches
def res_menu(s_ticker, s_start, s_interval):
# Add list of arguments that the research parser accepts
res_parser = argparse.ArgumentParser(add_help=False, prog="discovery")
res_parser.add_argument(
"cmd",
choices=[
"help",
"q",
"quit",
"macroaxis",
"yahoo",
"finviz",
"marketwatch",
"fool",
"businessinsider",
"fmp",
"fidelity",
"tradingview",
"marketchameleon",
"stockrow",
"barchart",
"grufity",
"fintel",
"zacks",
"macrotrends",
"newsfilter",
"resources",
"stockanalysis",
],
)
print_research(s_ticker, s_start, s_interval)
# Loop forever and ever
while True:
# Get input command from user
as_input = input("> ")
# Parse fundamental analysis command of the list of possible commands
try:
(ns_known_args, _) = res_parser.parse_known_args(as_input.split())
except SystemExit:
print("The command selected doesn't exist\n")
continue
try:
if ns_known_args.cmd == "help":
print_research(s_ticker, s_start, s_interval)
elif ns_known_args.cmd == "q":
# Just leave the RES menu
return False
elif ns_known_args.cmd == "quit":
# Abandon the program
return True
elif ns_known_args.cmd == "macroaxis":
webbrowser.open(f"https://www.macroaxis.com/invest/market/{s_ticker}")
elif ns_known_args.cmd == "yahoo":
webbrowser.open(f"https://finance.yahoo.com/quote/{s_ticker}")
elif ns_known_args.cmd == "finviz":
webbrowser.open(f"https://finviz.com/quote.ashx?t={s_ticker}")
elif ns_known_args.cmd == "marketwatch":
webbrowser.open(
f"https://www.marketwatch.com/investing/stock/{s_ticker}"
)
elif ns_known_args.cmd == "fool":
webbrowser.open(f"https://www.fool.com/quote/{s_ticker}")
elif ns_known_args.cmd == "businessinsider":
webbrowser.open(
f"https://markets.businessinsider.com/stocks/{s_ticker}-stock/"
)
elif ns_known_args.cmd == "fmp":
webbrowser.open(
f"https://financialmodelingprep.com/financial-summary/{s_ticker}"
)
elif ns_known_args.cmd == "fidelity":
webbrowser.open(
f"https://eresearch.fidelity.com/eresearch/goto/evaluate/snapshot.jhtml?symbols={s_ticker}"
)
elif ns_known_args.cmd == "tradingview":
webbrowser.open(f"https://www.tradingview.com/symbols/{s_ticker}")
elif ns_known_args.cmd == "marketchameleon":
webbrowser.open(f"https://marketchameleon.com/Overview/{s_ticker}")
elif ns_known_args.cmd == "stockrow":
webbrowser.open(f"https://stockrow.com/{s_ticker}")
elif ns_known_args.cmd == "barchart":
webbrowser.open(
f"https://www.barchart.com/stocks/quotes/{s_ticker}/overview"
)
elif ns_known_args.cmd == "grufity":
webbrowser.open(f"https://grufity.com/stock/{s_ticker}")
elif ns_known_args.cmd == "fintel":
webbrowser.open(f"https://fintel.io/s/us/{s_ticker}")
elif ns_known_args.cmd == "zacks":
webbrowser.open(f"https://www.zacks.com/stock/quote/{s_ticker}")
elif ns_known_args.cmd == "macrotrends":
webbrowser.open(
f"https://www.macrotrends.net/stocks/charts/{s_ticker}/{s_ticker}/market-cap"
)
elif ns_known_args.cmd == "newsfilter":
webbrowser.open(f"https://newsfilter.io/search?query={s_ticker}")
elif ns_known_args.cmd == "stockanalysis":
webbrowser.open(f"https://stockanalysis.com/stocks/{s_ticker}")
elif ns_known_args.cmd == "resources":
# webbrowser.open(f"https://www.tradinganalysisresources.com/2020/05/free-references-and-resources.html")
webbrowser.open(
"https://moongangcapital.com/free-stock-market-resources/"
)
else:
print("Command not recognized!")
print("")
except SystemExit:
print("")
return False

View File

@@ -0,0 +1,28 @@
# RESEARCH
This menu aims to investigate a stock from a website of reference. The list of the supported websites is displayed below.
<div align="center">
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
</div>

View File

@@ -0,0 +1,232 @@
"""Research Controller Module"""
__docformat__ = "numpy"
import argparse
import webbrowser
from datetime import datetime
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
class ResearchController:
"""Research Controller class"""
# Command choices
CHOICES = [
"help",
"q",
"quit",
"macroaxis",
"yahoo",
"finviz",
"marketwatch",
"fool",
"businessinsider",
"fmp",
"fidelity",
"tradingview",
"marketchameleon",
"stockrow",
"barchart",
"grufity",
"fintel",
"zacks",
"macrotrends",
"newsfilter",
"stockanalysis",
]
def __init__(self, ticker: str, start: datetime, interval: str):
"""Constructor"""
self.ticker = ticker
self.start = start
self.interval = interval
self.res_parser = argparse.ArgumentParser(add_help=False, prog="res")
self.res_parser.add_argument(
"cmd",
choices=self.CHOICES,
)
@staticmethod
def print_help(self):
"""Print help"""
s_intraday = (f"Intraday {self.interval}", "Daily")[self.interval == "1440min"]
if self.start:
print(
f"\n{s_intraday} Stock: {self.ticker} (from {self.start.strftime('%Y-%m-%d')})"
)
else:
print(f"\n{s_intraday} Stock: {self.ticker}")
print("\nResearch:")
print(" help show this behavioural analysis menu again")
print(" q quit this menu, and shows back to main menu")
print(" quit quit to abandon program")
print("")
print(" macroaxis www.macroaxis.com")
print(" yahoo www.finance.yahoo.com")
print(" finviz www.finviz.com")
print(" marketwatch www.marketwatch.com")
print(" fool www.fool.com")
print(" businessinsider www.markets.businessinsider.com")
print(" fmp www.financialmodelingprep.com")
print(" fidelity www.eresearch.fidelity.com")
print(" tradingview www.tradingview.com")
print(" marketchameleon www.marketchameleon.com")
print(" stockrow www.stockrow.com")
print(" barchart www.barchart.com")
print(" grufity www.grufity.com")
print(" fintel www.fintel.com")
print(" zacks www.zacks.com")
print(" macrotrends www.macrotrends.net")
print(" newsfilter www.newsfilter.io")
print(" stockanalysis www.stockanalysis.com")
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.res_parser.parse_known_args(an_input.split())
if other_args:
print(f"The following args were unexpected: {other_args}")
return getattr(
self, "call_" + known_args.cmd, lambda: "Command not recognized!"
)(None)
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_macroaxis(self, _):
"""Process macroaxis command"""
webbrowser.open(f"https://www.macroaxis.com/invest/market/{self.ticker}")
def call_yahoo(self, _):
"""Process yahoo command"""
webbrowser.open(f"https://finance.yahoo.com/quote/{self.ticker}")
def call_finviz(self, _):
"""Process finviz command"""
webbrowser.open(f"https://finviz.com/quote.ashx?t={self.ticker}")
def call_marketwatch(self, _):
"""Process marketwatch command"""
webbrowser.open(f"https://www.marketwatch.com/investing/stock/{self.ticker}")
def call_fool(self, _):
"""Process fool command"""
webbrowser.open(f"https://www.fool.com/quote/{self.ticker}")
def call_businessinsider(self, _):
"""Process businessinsider command"""
webbrowser.open(
f"https://markets.businessinsider.com/stocks/{self.ticker}-stock/"
)
def call_fmp(self, _):
"""Process fmp command"""
webbrowser.open(
f"https://financialmodelingprep.com/financial-summary/{self.ticker}"
)
def call_fidelity(self, _):
"""Process fidelity command"""
webbrowser.open(
f"https://eresearch.fidelity.com/eresearch/goto/evaluate/snapshot.jhtml?symbols={self.ticker}"
)
def call_tradingview(self, _):
"""Process tradingview command"""
webbrowser.open(f"https://www.tradingview.com/symbols/{self.ticker}")
def call_marketchameleon(self, _):
"""Process marketchameleon command"""
webbrowser.open(f"https://marketchameleon.com/Overview/{self.ticker}")
def call_stockrow(self, _):
"""Process stockrow command"""
webbrowser.open(f"https://stockrow.com/{self.ticker}")
def call_barchart(self, _):
"""Process barchart command"""
webbrowser.open(
f"https://www.barchart.com/stocks/quotes/{self.ticker}/overview"
)
def call_grufity(self, _):
"""Process grufity command"""
webbrowser.open(f"https://grufity.com/stock/{self.ticker}")
def call_fintel(self, _):
"""Process fintel command"""
webbrowser.open(f"https://fintel.io/s/us/{self.ticker}")
def call_zacks(self, _):
"""Process zacks command"""
webbrowser.open(f"https://www.zacks.com/stock/quote/{self.ticker}")
def call_macrotrends(self, _):
"""Process macrotrends command"""
webbrowser.open(
f"https://www.macrotrends.net/stocks/charts/{self.ticker}/{self.ticker}/market-cap"
)
def call_newsfilter(self, _):
"""Process newsfilter command"""
webbrowser.open(f"https://newsfilter.io/search?query={self.ticker}")
def call_stockanalysis(self, _):
"""Process stockanalysis command"""
webbrowser.open(f"https://stockanalysis.com/stocks/{self.ticker}/")
def menu(ticker: str, start: datetime, interval: str):
"""Research Menu"""
res_controller = ResearchController(ticker, start, interval)
res_controller.call_help(None)
print("")
while True:
# Get input command from user
if session and gtff.USE_PROMPT_TOOLKIT:
completer = NestedCompleter.from_nested_dict(
{c: None for c in res_controller.CHOICES}
)
an_input = session.prompt(
f"{get_flair()} (res)> ",
completer=completer,
)
else:
an_input = input(f"{get_flair()} (res)> ")
try:
process_input = res_controller.switch(an_input)
print("")
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,28 @@
# RESOURCE COLLECTION
This menu aims to store a collection of useful resources that can't be scraped, or extracted in a "useful" manner, and the usage of the following commands along with an example will be exploited below.
* [hfletters](#hfletters)
* hedge fund letters or reports
* [learn](#learn)
* trading analysis, tips and resources
## hfletters <a name="hfletters"></a>
```text
usage: hfletters
```
<img width="1144" alt="Captura de ecrã 2021-05-01, às 21 13 22" src="https://user-images.githubusercontent.com/25267873/116794054-400e7a00-aac2-11eb-92ba-b14d979ef6c1.png">
<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">
## learn <a name="learn"></a>
```text
usage: learn
```
<img width="1231" alt="Captura de ecrã 2021-05-01, às 21 16 07" src="https://user-images.githubusercontent.com/25267873/116794091-79df8080-aac2-11eb-902c-0d165ee3563b.png">

View File

@@ -0,0 +1,109 @@
"""Resource Collection Controller Module"""
__docformat__ = "numpy"
import argparse
import webbrowser
from typing import List
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
class ResourceCollectionController:
"""Resources Controller class"""
# Command choices
CHOICES = ["help", "q", "quit", "hfletters", "learn"]
def __init__(self):
"""Constructor"""
self.rc_parser = argparse.ArgumentParser(add_help=False, prog="rc")
self.rc_parser.add_argument(
"cmd",
choices=self.CHOICES,
)
@staticmethod
def print_help():
"""Print help"""
print("\nResources:")
print(" help show this behavioural analysis menu again")
print(" q quit this menu, and shows back to main menu")
print(" quit quit to abandon program")
print("")
print(" hfletters hedge fund letters or reports")
print(" learn trading analysis, tips and resources")
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.rc_parser.parse_known_args(an_input.split())
if other_args:
print(f"The following args were unexpected: {other_args}")
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_hfletters(self, other_args: List[str]):
"""Process hfletters command"""
webbrowser.open("https://miltonfmr.com/hedge-fund-letters/")
print("")
def call_learn(self, other_args: List[str]):
"""Process learn command"""
webbrowser.open("https://moongangcapital.com/free-stock-market-resources/")
print("")
def menu():
"""Resource Collection Menu"""
rc_controller = ResourceCollectionController()
rc_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 rc_controller.CHOICES}
)
an_input = session.prompt(
f"{get_flair()} (rc)> ",
completer=completer,
)
else:
an_input = input(f"{get_flair()} (rc)> ")
try:
process_input = rc_controller.switch(an_input)
if process_input is not None:
return process_input
except SystemExit:
print("The command selected doesn't exist\n")
continue

BIN
images/gst_logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

BIN
images/gst_logo_rGreen.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

View File

@@ -13,12 +13,19 @@ from prompt_toolkit.completion import NestedCompleter
from gamestonk_terminal import config_terminal as cfg
from gamestonk_terminal import feature_flags as gtff
from gamestonk_terminal import thought_of_the_day as thought
from gamestonk_terminal import res_menu as rm
from gamestonk_terminal.discovery import disc_controller
from gamestonk_terminal.due_diligence import dd_controller
from gamestonk_terminal.fundamental_analysis import fa_controller
from gamestonk_terminal.helper_funcs import b_is_stock_market_open, get_flair
from gamestonk_terminal.main_helper import clear, export, load, print_help, view, candle
from gamestonk_terminal.main_helper import (
clear,
export,
load,
print_help,
view,
candle,
print_goodbye,
)
from gamestonk_terminal.menu import session
from gamestonk_terminal.papermill import papermill_controller as mill
from gamestonk_terminal.behavioural_analysis import ba_controller
@@ -34,6 +41,8 @@ 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
from gamestonk_terminal.resource_collection import rc_controller
from gamestonk_terminal.research import res_controller
# pylint: disable=too-many-statements,too-many-branches
@@ -47,7 +56,7 @@ def main():
os.system("")
s_ticker = ""
s_start = ""
s_start = "2015-01-01"
df_stock = pd.DataFrame()
s_interval = "1440min"
@@ -89,6 +98,7 @@ def main():
"ra",
"po",
"fx",
"rc",
]
menu_parser.add_argument("opt", choices=choices)
@@ -102,7 +112,7 @@ def main():
print(e, "\n")
# Print first welcome message and help
print("\nWelcome to Gamestonk Terminal 🚀\n")
print("\nWelcome to Gamestonk Terminal Ape.\n")
should_print_help = True
parsed_stdin = False
@@ -211,7 +221,7 @@ def main():
)
elif ns_known_args.opt == "res":
b_quit = rm.res_menu(
b_quit = res_controller.menu(
s_ticker.split(".")[0] if "." in s_ticker else s_ticker,
s_start,
s_interval,
@@ -365,6 +375,9 @@ def main():
s_ticker.split(".")[0] if "." in s_ticker else s_ticker, s_start
)
elif ns_known_args.opt == "rc":
b_quit = rc_controller.menu()
else:
print("Shouldn't see this command!")
continue
@@ -375,9 +388,7 @@ def main():
if not main_cmd:
should_print_help = True
print(
"Hope you enjoyed the terminal. Remember that stonks only go up. Diamond hands.\n"
)
print_goodbye()
if __name__ == "__main__":

View File

@@ -5,7 +5,7 @@ from io import StringIO
import pandas as pd
# pylint: disable=unused-import
from gamestonk_terminal.econ.fred_view import get_fred_data # noqa: F401
from gamestonk_terminal.econ.fred_view import display_fred # noqa: F401
fred_data_mock = """
,GDP
@@ -17,14 +17,15 @@ fred_data_mock = """
2020-04-01,19520.114
2020-07-01,21170.252
2020-10-01,21494.731
2021-01-01,22048.894
"""
class TestFredFredView(unittest.TestCase):
@mock.patch("gamestonk_terminal.econ.fred_view.Fred.get_series")
def test_get_fred_data(self, mock_get_series):
def test_display_fred(self, mock_get_series):
fred_data = pd.read_csv(StringIO(fred_data_mock), header=0, index_col=0)
mock_get_series.return_value = fred_data
get_fred_data(["--noplot"], "gdp")
display_fred(["-t"], "gdp")