Merge branch 'DidierRLopes:main' into main

This commit is contained in:
DJ
2021-05-06 19:03:22 -06:00
37 changed files with 1584 additions and 91 deletions

38
.pre-commit-config.yaml Normal file
View File

@@ -0,0 +1,38 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v3.4.0
hooks:
- id: check-yaml
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: https://github.com/psf/black
rev: 21.4b2
hooks:
- id: black
- repo: https://github.com/pycqa/flake8
rev: 3.9.1
hooks:
- id: flake8
entry: flake8 --max-line-length=122 --ignore=E203,W503
- repo: https://github.com/codespell-project/codespell
rev: v2.0.0
hooks:
- id: codespell
entry: codespell
args: [ '--ignore-words-list="mape","ba","hist"', '--quiet-level=2', '--skip=".git,*.yaml,*.json,./tests"' ]
- repo: https://github.com/pre-commit/mirrors-mypy
rev: 'v0.812'
hooks:
- id: mypy
args: [ --ignore-missing-imports ]
- repo: https://github.com/pre-commit/mirrors-pylint
rev: 'v3.0.0a3'
hooks:
- id: pylint
entry: pylint terminal.py gamestonk_terminal tests
- repo: https://github.com/Yelp/detect-secrets
rev: v1.1.0
hooks:
- id: detect-secrets
args: [ '--baseline', '.secrets.baseline' ]
exclude: package.lock.json

103
.secrets.baseline Normal file
View File

@@ -0,0 +1,103 @@
{
"version": "1.1.0",
"plugins_used": [
{
"name": "ArtifactoryDetector"
},
{
"name": "AWSKeyDetector"
},
{
"name": "AzureStorageKeyDetector"
},
{
"name": "Base64HighEntropyString",
"limit": 4.5
},
{
"name": "BasicAuthDetector"
},
{
"name": "CloudantDetector"
},
{
"name": "HexHighEntropyString",
"limit": 3.0
},
{
"name": "IbmCloudIamDetector"
},
{
"name": "IbmCosHmacDetector"
},
{
"name": "JwtTokenDetector"
},
{
"name": "KeywordDetector",
"keyword_exclude": ""
},
{
"name": "MailchimpDetector"
},
{
"name": "NpmDetector"
},
{
"name": "PrivateKeyDetector"
},
{
"name": "SlackDetector"
},
{
"name": "SoftlayerDetector"
},
{
"name": "SquareOAuthDetector"
},
{
"name": "StripeDetector"
},
{
"name": "TwilioKeyDetector"
}
],
"filters_used": [
{
"path": "detect_secrets.filters.allowlist.is_line_allowlisted"
},
{
"path": "detect_secrets.filters.common.is_ignored_due_to_verification_policies",
"min_level": 2
},
{
"path": "detect_secrets.filters.heuristic.is_indirect_reference"
},
{
"path": "detect_secrets.filters.heuristic.is_likely_id_string"
},
{
"path": "detect_secrets.filters.heuristic.is_lock_file"
},
{
"path": "detect_secrets.filters.heuristic.is_not_alphanumeric_string"
},
{
"path": "detect_secrets.filters.heuristic.is_potential_uuid"
},
{
"path": "detect_secrets.filters.heuristic.is_prefixed_with_dollar_sign"
},
{
"path": "detect_secrets.filters.heuristic.is_sequential_string"
},
{
"path": "detect_secrets.filters.heuristic.is_swagger_file"
},
{
"path": "detect_secrets.filters.heuristic.is_templated_secret"
}
],
"results": {},
"generated_at": "2021-05-03T16:53:30Z"
}

View File

@@ -20,13 +20,13 @@
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
![Discord Shield](https://discordapp.com/api/guilds/831165782750789672/widget.png?style=shield)
[![Twitter](https://img.shields.io/twitter/url/https/twitter.com/gamestonkt.svg?style=social&label=Follow%20%40gamestonkt)](https://twitter.com/gamestonkt)
<!-- PROJECT LOGO -->
<br />
<p align="center">
<a href="https://github.com/DidierRLopes/GamestonkTerminal">
<img src="images/gst_logo_rGreen.png" alt="Logo" width="400" height="400">
<img src="images/gst_logo_lockup_rGreen_with_letters.png" alt="Logo" width="800" height="276">
</a>
<h3 align="center">Gamestonk Terminal 🚀</h3>
@@ -88,6 +88,8 @@ As a modern Python-based environment, GamestonkTerminal opens access to numerous
## 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).
This project was originally written and tested with Python 3.6.8. It should now support Python 3.6, 3.7, and 3.8.
Our current recommendation is to use this project with Anaconda's Python distribution - either full [__Anaconda3 Latest__](https://repo.anaconda.com/archive/) or [__Miniconda3 Latest__](https://repo.anaconda.com/archive/). Several features in this project utilize Machine Learning. Machine Learning Python dependencies are optional. If you decided to add Machine Learning features at a later point, you will likely have better user experience with Anaconda's Python distribution.
@@ -158,7 +160,7 @@ python terminal.py
```
10. (Windows - Optional) Speeding up opening process in the future
After you've installed Gamestonk Terminal, you'll find a file named "Gamestonk Terminal.bat". You can use this file to open Gamestonk Terminal quicker. This file can be moved to your desktop if you'd like. If you run into issues while trying to run the batch file. If you run into issues with the batch files, edit the file and check to see if the directories match up. This file assumes you used the default directories when installing.
After you've installed Gamestonk Terminal, you'll find a file named "Gamestonk Terminal.bat". You can use this file to open Gamestonk Terminal quicker. This file can be moved to your desktop if you'd like. If you run into issues while trying to run the batch file. If you run into issues with the batch files, edit the file and check to see if the directories match up. This file assumes you used the default directories when installing.
**NOTE:** When you close the terminal and re-open it, the only command you need to re-call is `conda activate gst` before you call `python terminal.py` again.
@@ -227,10 +229,12 @@ These are the ones where a key is necessary:
* Tradier: https://developer.tradier.com/getting_started
* Oanda API: https://developer.oanda.com
* CoinMarketCap API: https://coinmarketcap.com/api/
* Finhub API: https://finnhub.io
* Binance: https://binance.us (US) / https://binance.com (Outside US)
When these are obtained, don't forget to update [config_terminal.py](/gamestonk_terminal/config_terminal.py).
Alternatively, you can also set them to the following environment variables: GT_API_KEY_ALPHAVANTAGE, GT_API_KEY_FINANCIALMODELINGPREP, GT_API_KEY_QUANDL, GT_API_REDDIT_CLIENT_ID, GT_API_REDDIT_CLIENT_SECRET, GT_API_REDDIT_USERNAME, GT_API_REDDIT_USER_AGENT, GT_API_REDDIT_PASSWORD, GT_API_TWITTER_KEY, GT_API_TWITTER_SECRET_KEY, GT_API_TWITTER_BEARER_TOKEN, GT_API_POLYGON_KEY, GT_FRED_API_KEY, GT_API_NEWS_TOKEN, GT_OANDA_TOKEN, GT_OANDA_ACCOUNT, GT_TRADIER_TOKEN, GT_CMC_API_KEY.
Alternatively, you can also set them to the following environment variables: GT_API_KEY_ALPHAVANTAGE, GT_API_KEY_FINANCIALMODELINGPREP, GT_API_KEY_QUANDL, GT_API_REDDIT_CLIENT_ID, GT_API_REDDIT_CLIENT_SECRET, GT_API_REDDIT_USERNAME, GT_API_REDDIT_USER_AGENT, GT_API_REDDIT_PASSWORD, GT_API_TWITTER_KEY, GT_API_TWITTER_SECRET_KEY, GT_API_TWITTER_BEARER_TOKEN, GT_API_POLYGON_KEY, GT_FRED_API_KEY, GT_API_NEWS_TOKEN, GT_OANDA_TOKEN, GT_OANDA_ACCOUNT, GT_TRADIER_TOKEN, GT_CMC_API_KEY, GT_CMC_API_KEY, API_FINNHUB_KEY, GT_API_BINANCE_KEY, GT_API_BINANCE_SECRET.
Example:
```
@@ -295,9 +299,9 @@ Recommended if you bought the dip, and the share price keeps dipping. You may as
1. Fork the Project
2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`)
3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`)
4. Appease the linters and commit again if needed
1. Install and run `black` for every change you've made
2. Install and run `flake8` for every change you've made. `flake8 . --count --ignore=E203,W503 --max-line-length=122 --show-source --statistics`
4. Install the pre-commit hooks by running:
```pre-commit install```.
Any time you commit a change, linters will be run automatically. On changes, you will have to re-commit.
5. Push to your Branch (`git push origin feature/AmazingFeature`)
6. Open a Pull Request
@@ -339,15 +343,18 @@ Trading in financial instruments involves high risks including the risk of losin
[James Maslek](https://www.linkedin.com/in/james-maslek-b6810186/) - jmaslek11@gmail.com
Feel free to share loss porn, memes or any questions: https://discord.gg/Up2QGbMKHY
Feel free to share loss porn, memes or any questions at:
* Discord: https://discord.gg/Up2QGbMKHY
* Twitter: [@gamestonkt](https://twitter.com/gamestonkt)
## Acknowledgments
* [VICE article](https://www.vice.com/en/article/qjp9vp/gamestonk-terminal-is-a-diy-meme-stock-version-of-bloomberg-terminal)
* [Daily Fintech article](https://dailyfintech.com/2021/02/25/never-underestimate-bloomberg-but-here-are-5-reasons-why-the-gamestonk-terminal-is-a-contender/)
* [HackerNews](https://news.ycombinator.com/item?id=26258773)
* [Reddit r/algotrading](https://www.reddit.com/r/algotrading/comments/m4uvza/gamestonk_terminal_the_next_best_thing_after/)
* [Reddit r/Python](https://www.reddit.com/r/Python/comments/m515yk/gamestonk_terminal_the_equivalent_to_an/)
* [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)
* [Daily Fintech article - Never underestimate Bloomberg, but here are 5 reasons why the Gamestonk Terminal is a contender](https://dailyfintech.com/2021/02/25/never-underestimate-bloomberg-but-here-are-5-reasons-why-the-gamestonk-terminal-is-a-contender/)
* [HackerNews - Show HN: Can’t afford Bloomberg Terminal? No prob, I built the next best thing ](https://news.ycombinator.com/item?id=26258773)
* [Reddit r/algotrading - Gamestonk Terminal: The next best thing after Bloomberg Terminal.](https://www.reddit.com/r/algotrading/comments/m4uvza/gamestonk_terminal_the_next_best_thing_after/)
* [Reddit r/Python - Gamestonk Terminal: The equivalent to an open-source python Bloomberg Terminal.](https://www.reddit.com/r/Python/comments/m515yk/gamestonk_terminal_the_equivalent_to_an/)
* [Reddit r/Superstonk - Move over Bloomberg Terminal, here comes Gamestonk Terminal](https://www.reddit.com/r/Superstonk/comments/mx2cjh/move_over_bloomberg_terminal_here_comes_gamestonk/)
<!-- MARKDOWN LINKS & IMAGES -->

View File

@@ -40,6 +40,7 @@
* [x] Add latest and trending news commands (@hinxx) - [PR #347](https://github.com/DidierRLopes/GamestonkTerminal/pull/347)
* [x] Add top ratings updates (@hinxx) - [PR #357](https://github.com/DidierRLopes/GamestonkTerminal/pull/357)
* [x] Add dark pool (ATS) data of tickers with growing trades activity (@didier) - [PR #372](https://github.com/DidierRLopes/GamestonkTerminal/pull/372)
* [x] Past and future IPOs calendar (@didier) - [PR #432](https://github.com/DidierRLopes/GamestonkTerminal/pull/432)
**NEXT**
@@ -49,6 +50,7 @@
## Behavioral Analysis
* [x] Add FinBrain sentiment from news (@didier) - [PR #223](https://github.com/DidierRLopes/GamestonkTerminal/pull/223)
* [x] Sentiment stats from Finnhub (@didier) - [PR #433](https://github.com/DidierRLopes/GamestonkTerminal/pull/433)
**NEXT**
* [ ] Implement a better Twitter client (@aia)
@@ -78,15 +80,17 @@
* [x] Add technical summary report provided by FinBrain (@didier) - [PR #294](https://github.com/DidierRLopes/GamestonkTerminal/pull/294)
* [x] Add recommendation based on technical indicators from Tradingview (@didier) - [PR #301](https://github.com/DidierRLopes/GamestonkTerminal/pull/301)
* [x] Add view of stock historical price with trendlines (support, resistance) by Finviz (@didier) - [PR #317](https://github.com/DidierRLopes/GamestonkTerminal/pull/317)
* [x] Add auto-recognition of major TA patterns (@didier) - [PR #429](https://github.com/DidierRLopes/GamestonkTerminal/pull/429)
**NEXT**
* [ ] Add auto-recognition of major TA patterns (@didier)
---
## Due Diligence
* [x] Add dark pools (ATS) vs Non-ATS data over time (@didier) - [PR #363](https://github.com/DidierRLopes/GamestonkTerminal/pull/363)
* [x] Add failure to deliver command (@hinxx) - [PR #366](#https://github.com/DidierRLopes/GamestonkTerminal/pull/366)
* [x] Add failure to deliver command (@hinxx) - [PR #366](https://github.com/DidierRLopes/GamestonkTerminal/pull/366)
* [x] Ratings over time (@didier) - [PR #431](https://github.com/DidierRLopes/GamestonkTerminal/pull/431)
**NEXT**
@@ -171,6 +175,7 @@ ___
## 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)
* [x] Output economic impact events calendar (@didier) - [PR #430](https://github.com/DidierRLopes/GamestonkTerminal/pull/430)
**NEXT**
@@ -195,13 +200,13 @@ ___
---
## Cryptocurrencies
* [x] Add Coingecko (@jmaslek) - [PR #283](#https://github.com/DidierRLopes/GamestonkTerminal/pull/283)
* [x] Add Coingecko (@jmaslek) - [PR #283](https://github.com/DidierRLopes/GamestonkTerminal/pull/283)
* [x] view top coins from coinmarketcap (@jmaslek) - [PR #378](https://github.com/DidierRLopes/GamestonkTerminal/pull/378)
* [x] Add binance (@jmaslek) [PR #428](#https://github.com/DidierRLopes/GamestonkTerminal/pull/428)
**NEXT**
* [ ] Add [Coinpaprika](https://coinpaprika.com/api/)
* [ ] Add crypto charts
* [ ] Add binance
* [ ] Add top altcoin lists
---

View File

@@ -68,6 +68,7 @@ export -f GNUS_data -F csv
## Discover Stocks [»](discovery/README.md)
Command|Description|Source
---|---|---
`ipo` |past and future IPOs |[Finnhub](https://finnhub.io)
`map` |S&P500 index stocks map |[Finviz](https://finviz.com)
`rtp_sectors` |real-time performance sectors |[Alpha Vantage](www.alphavantage.co)
`gainers` |show latest top gainers |[Yahoo Finance](https://finance.yahoo.com/)
@@ -95,6 +96,7 @@ Command|Description
----|----
[FinBrain](https://finbrain.tech)|
`finbrain` |sentiment from 15+ major news headlines
`stats` |sentiment stats including comparison with sector
[Reddit](https://reddit.com)|
`wsb` |show what WSB gang is up to in subreddit wallstreetbets
`watchlist` |show other users watchlist
@@ -183,6 +185,7 @@ Command | Description | Sources
`view` | view historical data and trendlines| [Finviz](https://finviz.com/quote.ashx?t=tsla)
`summary` | technical summary report| [FinBrain](https://finbrain.tech)
`recom` | recommendation based on Technical Indicators| [Tradingview](https://uk.tradingview.com/widget/technical-analysis/)
`pr` | pattern recognition| [Finnhub](https://finnhub.io)
[overlap](https://github.com/twopirllc/pandas-ta/tree/master/pandas_ta/overlap) |
`ema` | exponential moving average | [Wikipedia](https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average), [Investopedia](https://www.investopedia.com/terms/e/ema.asp)
`sma` |simple moving average | [Wikipedia](https://en.wikipedia.org/wiki/Moving_average#Simple_moving_average_(boxcar_filter)), [Investopedia](https://www.investopedia.com/terms/s/sma.asp)
@@ -211,6 +214,7 @@ Command|Description|Source
`analyst` |analyst prices and ratings of the company |[Finviz](https://finviz.com/)
`rating` |rating of the company from strong sell to strong buy | [FMP](https://financialmodelingprep.com/)
`pt` |price targets over time |[Business Insider](https://www.businessinsider.com/)
`rot` |ratings over time |[Finnhub](https://finnhub.io)
`est` |quarter and year analysts earnings estimates |[Business Insider](https://www.businessinsider.com/)
`ins` |insider activity over time |[Business Insider](https://www.businessinsider.com/)
`insider` |insider trading of the company |[Finviz](https://finviz.com/)
@@ -274,9 +278,17 @@ Command|Description
Command|Description
------ | ------------
`load`| load cryptocurrency data
`view`| load and view cryptocurrency data
[coingecko](#https://www.coingecko.com/en)|
`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)|
`select` | Select a coin/currency
`book`| show order book
`candle`| get klines/candles and plot
`balance`| show coin balance
&nbsp;
@@ -328,19 +340,21 @@ Command|Description|Source
&nbsp;
## Economy [»](econ/README.md)
Command|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 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)
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
&nbsp;
@@ -397,7 +411,7 @@ positionbook |display the positionbook if Oanda provides one for the forex instr
Command|Description
------ | --------
`ema` | buy when price exceeds EMA(l)
`ema_cross` | buy when EMA(short) > EMA(long)
`ema_cross` | buy when EMA(short) > EMA(long)
`rsi` | buy when RSI < low and sell when RSI > high

View File

@@ -3,6 +3,9 @@
This menu aims to extrapolate behavioural analysis regarding a pre-loaded ticker, and the usage of the following commands along with an example will be exploited below.
* [finbrain](#finbrain)
- sentiment from 15+ major news headlines
* [stats](#stats)
- sentiment stats including comparison with sector
[REDDIT](#REDDIT)
* [wsb](#wsb)
@@ -54,6 +57,15 @@ FinBrain collects the news headlines from 15+ major financial news sources on a
<img width="986" alt="Captura de ecrã 2021-03-18, às 12 53 31" src="https://user-images.githubusercontent.com/25267873/111629542-4fbf5100-87e9-11eb-8d5d-96faa8d3fca4.png">
## stats <a name="stats"></a>
```
usage: stats
```
Sentiment stats which displays buzz, news score, articles last week, articles weekly average, bullish vs bearish percentages, sector average bullish percentage, and sector average news score. [Source: https://finnhub.io]
<img width="1003" alt="Captura de ecrã 2021-05-03, às 15 26 09" src="https://user-images.githubusercontent.com/25267873/116888922-e9b94c80-ac23-11eb-959e-be24c79488a3.png">
# REDDIT <a name="REDDIT"></a>
## wsb <a name="wsb"></a>

View File

@@ -14,6 +14,7 @@ from gamestonk_terminal.behavioural_analysis import (
reddit_view,
stocktwits_view,
finbrain_view,
finnhub_view,
)
@@ -41,6 +42,7 @@ class BehaviouralAnalysisController:
"queries",
"rise",
"finbrain",
"stats",
]
def __init__(self, ticker: str, start: datetime):
@@ -63,6 +65,7 @@ class BehaviouralAnalysisController:
print(" quit quit to abandon program")
print("")
print(" finbrain sentiment from 15+ major news headlines")
print(" stats sentiment stats including comparison with sector")
print("")
print("Reddit:")
print(
@@ -218,6 +221,10 @@ class BehaviouralAnalysisController:
"""Process finbrain command"""
finbrain_view.sentiment_analysis(other_args, self.ticker)
def call_stats(self, other_args: List[str]):
"""Process stats command"""
finnhub_view.sentiment_stats(other_args, self.ticker)
def menu(ticker: str, start: datetime):
"""Behavioural Analysis Menu"""

View File

@@ -0,0 +1,82 @@
import argparse
from typing import List, Dict
import requests
from gamestonk_terminal import config_terminal as cfg
from gamestonk_terminal.helper_funcs import (
parse_known_args_and_warn,
)
def get_sentiment_stats(ticker: str) -> Dict:
"""Get sentiment stats
Parameters
----------
ticker : str
Ticker to get sentiment stats
Returns
-------
Dict
Get sentiment stats
"""
response = requests.get(
f"https://finnhub.io/api/v1/news-sentiment?symbol={ticker}&token={cfg.API_FINNHUB_KEY}"
)
if response.status_code == 200:
return response.json()
return {}
def sentiment_stats(other_args: List[str], ticker: str):
"""Sentiment stats which displays buzz, news score, articles last week, articles weekly average,
bullish vs bearish percentages, sector average bullish percentage, and sector average news score
Parameters
----------
other_args : List[str]
Command line arguments to be processed with argparse
ticker : str
Ticker to get sentiment stats
"""
parser = argparse.ArgumentParser(
add_help=False,
prog="stats",
description="""
Sentiment stats which displays buzz, news score, articles last week, articles weekly average,
bullish vs bearish percentages, sector average bullish percentage, and sector average news score.
[Source: https://finnhub.io]
""",
)
try:
ns_parser = parse_known_args_and_warn(parser, other_args)
if not ns_parser:
return
d_stats = get_sentiment_stats(ticker)
if d_stats:
print(f"Buzz: {round(100*d_stats['buzz']['buzz'],2)} %")
print(f"News Score: {round(100*d_stats['companyNewsScore'],2)} %")
print("")
print(f"Articles Last Week: {d_stats['buzz']['articlesInLastWeek']}")
print(f"Articles Weekly Average: {d_stats['buzz']['weeklyAverage']}")
print("")
print(f"Bullish: {round(100*d_stats['sentiment']['bullishPercent'],2)} %")
print(f"Bearish: {round(100*d_stats['sentiment']['bearishPercent'],2)} %")
print("")
print(
f"Sector Average Bullish: {round(100*d_stats['sectorAverageBullishPercent'],2)} %"
)
print(
f"Sector Average News Score: {round(100*d_stats['sectorAverageNewsScore'],2)} %"
)
else:
print("No sentiment stats found.")
print("")
except Exception as e:
print(e, "\n")

View File

@@ -33,7 +33,7 @@ API_TWITTER_SECRET_KEY = os.getenv("GT_API_TWITTER_SECRET_KEY") or "REPLACE_ME"
API_TWITTER_BEARER_TOKEN = os.getenv("GT_API_TWITTER_BEARER_TOKEN") or "REPLACE_ME"
# https://fred.stlouisfed.org/docs/api/api_key.html
API_FRED_KEY = os.getenv("GT_FRED_API_KEY") or "REPLACE_ME"
API_FRED_KEY = os.getenv("GT_API_FRED_KEY") or "REPLACE_ME"
# https://newsapi.org
API_NEWS_TOKEN = os.getenv("GT_API_NEWS_TOKEN") or "REPLACE_ME"
@@ -51,11 +51,18 @@ OANDA_ACCOUNT = os.getenv("GT_OANDA_ACCOUNT") or "REPLACE ME"
OANDA_TOKEN = os.getenv("GT_OANDA_TOKEN") or "REPLACE ME"
# https://tradier.com/products/market-data-api
TRADIER_TOKEN = os.getenv("GT_TRADIER_TOKEN") or "REPLACE_ME"
TRADIER_TOKEN = os.getenv("GT_API_TRADIER_TOKEN") or "REPLACE_ME"
# Selenium Webbrowser drivers can be found at https://selenium-python.readthedocs.io/installation.html
WEBDRIVER_TO_USE = "chrome"
PATH_TO_SELENIUM_DRIVER = None # Replace with "PATH"
# https://coinmarketcap.com/api/
COINMARKETCAP_KEY = os.getenv("GT_CMC_API_KEY") or "REPLACE_ME"
API_CMC_KEY = os.getenv("GT_API_CMC_KEY") or "REPLACE_ME"
# https://www.binance.com/en/
API_BINANCE_KEY = os.getenv("GT_API_BINANCE_KEY") or "REPLACE_ME"
API_BINANCE_SECRET = os.getenv("GT_API_BINANCE_SECRET") or "REPLACE_ME"
# https://finnhub.io
API_FINNHUB_KEY = os.getenv("GT_API_FINNHUB_KEY") or "REPLACE_ME"

View File

@@ -2,14 +2,29 @@
This menu aims to explore crypto world, and the usage of the following commands along with an example will be exploited below.
[COINGECKO](#COINGECKO)
* [load](#load)
* load a given coin vs a given currency [CoinGecko]
* [view](#view)
* plot the loaded crypto data
* [trend](#trend)
* show top 7 trending coins
[COINMARKETCAP](#COINMARKETCAP)
* [top](#top)
* view top coins from coinmarketcap [coinmarketcap.com]
[BINANCE](#BINANCE)
* [select](#select)
* select coin/currency to use
* [book](#book)
* show order book
* [candle](#candle)
* get klines/candles and plot
* [balance](#balance)
* show coin balance
# COINGECKO <a name="COINGECKO"></a>
## load <a name="load"></a>
````
@@ -36,6 +51,17 @@ Plot the loaded crypto data.
![crypto_view](https://user-images.githubusercontent.com/25267873/115787452-20889a80-a3ba-11eb-9216-f7fd1ffc98cf.png)
## trend <a name="trend"></a>
````
usage: trend
````
Print the top 7 trending coins from coingecko.
<img width="1004" alt="Captura de ecrã 2021-05-03, às 15 07 15" src="https://user-images.githubusercontent.com/25267873/116886674-45cea180-ac21-11eb-9951-ff10271df370.png">
# COINMARKETCAP <a name="COINMARKETCAP"></a>
## top <a name="top"></a>
````
@@ -50,3 +76,48 @@ This command displays the top n cryptocurrencies from coinmarketcap.com.
<img width="990" alt="crypto" src="https://user-images.githubusercontent.com/25267873/115787544-4746d100-a3ba-11eb-9433-b7cb9142404a.png">
# BINANCE <a name="BINANCE"></a>
## select <a name="select"></a>
````
usage: select [-c --coin] [-q --quote]
````
Select a coin/currency to the current object. Note that in binance, the exchange "ticker" is usually COINCURR, such as BTCEUR for BTC to EURO. There is no USD, but it uses a coin tethered to the USD (USDT), which is the default. Some symbols are a combination of coins, as `ETHBTC` is a valid symbol
* -c/--coin Coin to load. If not specified, BTC will be loaded to prevent errors later.
* -q/--quote Quote currency. Defaults to `USDT` (which is 1-to-1 with USD)
## book <a name="book"></a>
````
usage: book -l/--limit
````
Gets and shows the order book for the given coin/currency. Shows the cumulative amount of orders.
* -l/--limit Number of orders to get on each side. One of [5,10,20,50,100,500,1000,5000]. Defaults to 100.
![orderbook](https://user-images.githubusercontent.com/25267873/116886857-84fcf280-ac21-11eb-9803-5baa8bceca05.png)
## candle <a name="candle"></a>
````
usage: candle [-i --interval] [-l --limit]
````
Show candle chart for loaded coin/currency.
* -i/--interval. Interval for candles. One of [1day,3day,1hour,2hour,4hour,6hour,8hour,12hour,1week,1min,3min,5min,15min,30min,1month]. Defaults to 1day.
* -l/--limit. Number of candles to get. Defaults to 100.
![candle](https://user-images.githubusercontent.com/25267873/116886993-abbb2900-ac21-11eb-9ff8-b6a8131fdac5.png)
## balance <a name="balance"></a>
````
usage: balance
````
Shows the current holding balance in your account.

View File

@@ -0,0 +1,259 @@
"""Binance model"""
__docformat__ = "numpy"
import argparse
from typing import List
import pandas as pd
import numpy as np
from binance.client import Client
from binance.exceptions import BinanceAPIException
from tabulate import tabulate
from gamestonk_terminal.main_helper import parse_known_args_and_warn
import gamestonk_terminal.config_terminal as cfg
from gamestonk_terminal.cryptocurrency.binance_view import plot_order_book, plot_candles
def check_valid_binance_str(symbol: str) -> str:
"""Check if symbol is in defined binance"""
client = Client(cfg.API_BINANCE_KEY, cfg.API_BINANCE_SECRET)
try:
client.get_avg_price(symbol=symbol.upper())
return symbol.upper()
except BinanceAPIException as e:
raise argparse.ArgumentTypeError(
f"{symbol} is not a valid binance symbol"
) from e
# pylint: disable=inconsistent-return-statements
def select_binance_coin(other_args: List[str]):
"""Define current_coin from binance
Parameters
----------
other_args: List[str]
Argparse arguments
Returns
-------
coin: str
Coin that is defined on binance
"""
parser = argparse.ArgumentParser(
prog="select",
add_help=False,
description="Define the coin to be used from binance",
)
parser.add_argument(
"-c", "--coin", help="Coin to get", dest="coin", type=str, default="BTC"
)
parser.add_argument(
"-q",
"--quote",
help="Quote currency (what to view coin vs)",
dest="quote",
type=str,
default="USDT",
)
try:
if other_args:
if "-" not in other_args[0]:
other_args.insert(0, "-c")
ns_parser = parse_known_args_and_warn(parser, other_args)
if not ns_parser:
return None, None
coin = ns_parser.coin + ns_parser.quote
if check_valid_binance_str(coin):
print(f"{ns_parser.coin.upper()} loaded vs {ns_parser.quote.upper()}")
return ns_parser.coin.upper(), ns_parser.quote.upper()
except Exception as e:
print(e, "\n")
return None, None
def order_book(other_args: List[str], coin: str, currency: str):
"""Get order book for currency
Parameters
----------
other_args: List[str]
Argparse arguments
coin: str
Coin to get symbol of
currency : str
Currency against which to check symbol
"""
limit_list = [5, 10, 20, 50, 100, 500, 1000, 5000]
parser = argparse.ArgumentParser(
prog="book", add_help=False, description="Get the order book for selected coin"
)
parser.add_argument(
"-l",
"--limit",
dest="limit",
help="Limit parameter. Adjusts the weight",
default=100,
type=int,
choices=limit_list,
)
try:
if not coin or not currency:
print("Coin needs to be selected prior to this command\n")
return
coin += currency
ns_parser = parse_known_args_and_warn(parser, other_args)
if not ns_parser:
return
client = Client(cfg.API_BINANCE_KEY, cfg.API_BINANCE_SECRET)
market_book = client.get_order_book(symbol=coin, limit=ns_parser.limit)
bids = np.asarray(market_book["bids"], dtype=float)
asks = np.asarray(market_book["asks"], dtype=float)
bids = np.insert(bids, 2, bids[:, 1].cumsum(), axis=1)
asks = np.insert(asks, 2, np.flipud(asks[:, 1]).cumsum(), axis=1)
plot_order_book(bids, asks, coin)
except Exception as e:
print(e, "\n")
def show_candles(other_args: List[str], coin: str, currency: str):
"""Get klines/candles for coin
Parameters
----------
other_args: List[str]
Argparse arguments
coin: str
Coin to get symbol of
currency : str
Currency against which to check symbol
"""
client = Client(cfg.API_BINANCE_KEY, cfg.API_BINANCE_SECRET)
interval_map = {
"1day": client.KLINE_INTERVAL_1DAY,
"3day": client.KLINE_INTERVAL_3DAY,
"1hour": client.KLINE_INTERVAL_1HOUR,
"2hour": client.KLINE_INTERVAL_2HOUR,
"4hour": client.KLINE_INTERVAL_4HOUR,
"6hour": client.KLINE_INTERVAL_6HOUR,
"8hour": client.KLINE_INTERVAL_8HOUR,
"12hour": client.KLINE_INTERVAL_12HOUR,
"1week": client.KLINE_INTERVAL_1WEEK,
"1min": client.KLINE_INTERVAL_1MINUTE,
"3min": client.KLINE_INTERVAL_3MINUTE,
"5min": client.KLINE_INTERVAL_5MINUTE,
"15min": client.KLINE_INTERVAL_15MINUTE,
"30min": client.KLINE_INTERVAL_30MINUTE,
"1month": client.KLINE_INTERVAL_1MONTH,
}
interval_choices = list(interval_map.keys())
parser = argparse.ArgumentParser(
prog="candle",
add_help=False,
description="Program to plot candles for binance data",
)
parser.add_argument(
"-i",
"--interval",
help="Interval to get data",
choices=interval_choices,
dest="interval",
default="1day",
type=str,
)
parser.add_argument(
"-l", "--limit", dest="limit", default=100, help="Number to get", type=int
)
try:
if not coin or not currency:
print("Coin needs to be selected prior to this command\n")
return
coin += currency
ns_parser = parse_known_args_and_warn(parser, other_args)
if not ns_parser:
return
candles = client.get_klines(
symbol=coin,
interval=interval_map[ns_parser.interval],
limit=ns_parser.limit,
)
# Response
# 1499040000000, // Open time
# "0.01634790", // Open
# "0.80000000", // High
# "0.01575800", // Low
# "0.01577100", // Close
# "148976.11427815", // Volume
# 1499644799999, // Close time
# "2434.19055334", // Quote asset volume
# 308, // Number of trades
# "1756.87402397", // Taker buy base asset volume
# "28.46694368", // Taker buy quote asset volume
# "17928899.62484339" // Ignore.
candles_df = pd.DataFrame(candles).astype(float).iloc[:, :7]
candles_df.columns = [
"Time0",
"Open",
"High",
"Low",
"Close",
"Volume",
"Time1",
]
candles_df.index = pd.to_datetime(
(candles_df["Time0"] + candles_df["Time1"]) / 2, unit="ms"
)
plot_candles(
candles_df,
f"{coin} from {candles_df.index[0].strftime('%Y/%m/%d')} to "
f"{candles_df.index[-1].strftime('%Y/%m/%d')}",
)
except Exception as e:
print(e, "\n")
def balance(coin: str):
"""Get account holdings for asset
Parameters
----------
coin: str
Coin to get holdings of
"""
client = Client(cfg.API_BINANCE_KEY, cfg.API_BINANCE_SECRET)
try:
current_balance = client.get_asset_balance(asset=coin)
if current_balance is None:
print("Check loaded coin")
return
print("")
amounts = [float(current_balance["free"]), float(current_balance["locked"])]
total = np.sum(amounts)
df = pd.DataFrame(amounts).apply(lambda x: str(float(x)))
df.columns = ["Amount"]
df.index = ["Free", "Locked"]
df["Percent"] = df.div(df.sum(axis=0), axis=1).round(3)
print(f"You currently have {total} coins and the breakdown is:")
print(tabulate(df, headers=df.columns, showindex=True, tablefmt="fancy_grid"))
print("")
return
except Exception as e:
print(e, "\n")
return

View File

@@ -0,0 +1,78 @@
"""Binance view functions"""
__docformat__ = "numpy"
import numpy as np
import matplotlib.pyplot as plt
import mplfinance as mpf
import pandas as pd
from gamestonk_terminal.main_helper import plot_autoscale
from gamestonk_terminal.config_plot import PLOT_DPI
from gamestonk_terminal.feature_flags import USE_ION as ion
def plot_order_book(bids: np.array, asks: np.array, coin: str):
"""
Plots Bid/Ask
Parameters
----------
bids : np.array
array of bids with columns: price, size, cumulative size
asks : np.array
array of asks with columns: price, size, cumulative size
coin : str
Coin being plotted
Returns
-------
"""
_, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)
ax.plot(bids[:, 0], bids[:, 2], "g", label="bids")
ax.fill_between(bids[:, 0], bids[:, 2], color="g", alpha=0.4)
ax.plot(asks[:, 0], asks[:, 2], "r", label="asks")
ax.fill_between(asks[:, 0], asks[:, 2], color="r", alpha=0.4)
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.legend(loc=0)
plt.xlabel("Price")
plt.ylabel("Size (Coins) ")
plt.title(f"Order Book for {coin}")
if ion:
plt.ion()
plt.show()
print("")
def plot_candles(candles_df: pd.DataFrame, title: str):
"""
Plot candle chart from dataframe
Parameters
----------
candles_df: pd.DataFrame
Dataframe containing time and OHLVC
title: str
title of graph
Returns
-------
"""
mpf.plot(
candles_df,
type="candle",
volume=True,
title=f"{title}",
xrotation=20,
style="binance",
figratio=(10, 7),
figscale=1.10,
figsize=(plot_autoscale()),
update_width_config=dict(
candle_linewidth=1.0, candle_width=0.8, volume_linewidth=1.0
),
)
if ion:
plt.ion()
plt.show()
print("")

View File

@@ -6,7 +6,7 @@ from typing import List
import pandas as pd
from tabulate import tabulate
from coinmarketcapapi import CoinMarketCapAPI
from gamestonk_terminal.config_terminal import COINMARKETCAP_KEY
import gamestonk_terminal.config_terminal as cfg
from gamestonk_terminal.helper_funcs import parse_known_args_and_warn
sort_options = ["Symbol", "CMC_Rank", "LastPrice", "DayPctChange", "MarketCap"]
@@ -62,7 +62,7 @@ def get_cmc_top_n(other_args: List[str]):
if not ns_parser:
return
cmc = CoinMarketCapAPI(COINMARKETCAP_KEY)
cmc = CoinMarketCapAPI(cfg.API_CMC_KEY)
ratings = cmc.cryptocurrency_listings_latest().data
symbol, rank, price, pchange1d, mkt_cap = [], [], [], [], []

View File

@@ -1,3 +1,4 @@
"""Cryptocurrency Controller"""
__docformat__ = "numpy"
import argparse
@@ -7,13 +8,29 @@ 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.cryptocurrency import pycoingecko_view
from gamestonk_terminal.cryptocurrency import coinmarketcap_view as cmc_view
from gamestonk_terminal.cryptocurrency import (
binance_model,
pycoingecko_view,
coinmarketcap_view as cmc_view,
)
class CryptoController:
CHOICES = ["help", "q", "quit", "load", "view", "top"]
CHOICES = [
"help",
"q",
"quit",
"load",
"view",
"top",
"trend",
"book",
"trades",
"candle",
"balance",
"select",
]
def __init__(self):
"""CONSTRUCTOR"""
@@ -21,22 +38,31 @@ class CryptoController:
self.crypto_parser = argparse.ArgumentParser(add_help=False, prog="crypto")
self.crypto_parser.add_argument("cmd", choices=self.CHOICES)
self.current_coin = None
self.current_currency = None
self.current_df = pd.DataFrame()
@staticmethod
def print_help(current_coin):
def print_help(self):
"""Print help"""
print("\nCryptocurrency:")
print(" help show this menu again")
print(" q quit this menu, and shows back to main menu")
print(" quit quit to abandon program")
print(f"\nCurrent Coin: {current_coin}")
print(f"\nCurrent Coin: {self.current_coin}")
print("")
print("Coingecko:")
print(" load load cryptocurrency data")
print(" view load and view cryptocurrency data")
print(" trend show top 7 trending coins")
print("")
print("CoinMarketCap:")
print(" top view top coins from coinmarketcap")
print("")
print("Binance:")
print(" select select coin/currency to use")
print(" book show order book")
print(" candle get klines/candles and plot")
print(" balance show coin balance")
print("")
def switch(self, an_input: str):
"""Process and dispatch input
@@ -56,7 +82,7 @@ class CryptoController:
def call_help(self, _):
"""Process Help command"""
self.print_help(self.current_coin)
self.print_help()
def call_q(self, _):
"""Process Q command - quit the menu"""
@@ -67,9 +93,11 @@ class CryptoController:
return True
def call_load(self, other_args):
"""Process load command"""
self.current_coin, self.current_df = pycoingecko_view.load(other_args)
def call_view(self, other_args):
"""Process view command"""
if self.current_coin:
pycoingecko_view.view(self.current_coin, self.current_df, other_args)
@@ -77,13 +105,37 @@ class CryptoController:
print("No coin selected. Use 'load' to load the coin you want to look at.")
print("")
def call_trend(self, _):
"""Process trend command"""
pycoingecko_view.trend()
def call_top(self, other_args):
"""Process top command"""
cmc_view.get_cmc_top_n(other_args)
def call_book(self, other_args):
"""Process book command"""
binance_model.order_book(other_args, self.current_coin, self.current_currency)
def call_candle(self, other_args):
"""Process candle command"""
binance_model.show_candles(other_args, self.current_coin, self.current_currency)
def call_balance(self, _):
"""Process balance command"""
binance_model.balance(self.current_coin)
def call_select(self, other_args):
"""Process select command"""
self.current_coin, self.current_currency = binance_model.select_binance_coin(
other_args
)
print("")
def menu():
crypto_controller = CryptoController()
crypto_controller.print_help(crypto_controller.current_coin)
crypto_controller.print_help()
plt.close("all")
while True:
# Get input command from user

View File

@@ -1,15 +0,0 @@
"""
Helper script that generates a dictionary to convert between symbols and IDs.
This allows the user to input (for example) "btc" instead of the expected "bitcoin"
"""
from pycoingecko import CoinGeckoAPI
cg = CoinGeckoAPI()
coins = cg.get_coins()
coin_symbol_to_id = {}
coin_ids = []
for coin in coins:
coin_symbol_to_id[coin["symbol"]] = coin["id"]
coin_ids.append(coin["id"])

View File

@@ -6,12 +6,23 @@ from typing import List
import pandas as pd
from pandas.plotting import register_matplotlib_converters
import matplotlib.pyplot as plt
from tabulate import tabulate
from pycoingecko import CoinGeckoAPI
from gamestonk_terminal.helper_funcs import parse_known_args_and_warn, plot_autoscale
from gamestonk_terminal.cryptocurrency.crypto_helper import coin_symbol_to_id, coin_ids
from gamestonk_terminal.config_plot import PLOT_DPI
register_matplotlib_converters()
# Generate a list of valid coins to be checked against later
cg_api = CoinGeckoAPI()
coins = cg_api.get_coins()
coin_symbol_to_id = {}
coin_ids = []
for single_coin in coins:
coin_symbol_to_id[single_coin["symbol"]] = single_coin["id"]
coin_ids.append(single_coin["id"])
# pylint: disable=inconsistent-return-statements
@@ -135,3 +146,33 @@ def view(coin: str, prices: pd.DataFrame, other_args: List[str]):
except Exception as e:
print(e)
print("")
def trend():
"""Prints top 7 coins from pycoingecko"""
cg = CoinGeckoAPI()
trending = cg.get_search_trending()["coins"]
name, symbol, price, rank = [], [], [], []
for coin in trending:
name.append(coin["item"]["name"])
symbol.append(coin["item"]["symbol"])
coin_id = coin["item"]["id"]
price.append(cg.get_price(coin_id, vs_currencies="USD")[coin_id]["usd"])
rank.append(coin["item"]["market_cap_rank"])
df = pd.DataFrame()
df["name"] = name
df["symbol"] = symbol
df["last_price"] = price
df["market_cap_rank"] = rank
print(
tabulate(
df,
headers=df.columns,
floatfmt=".2f",
showindex=False,
tablefmt="fancy_grid",
)
)
print("")

View File

@@ -2,6 +2,8 @@
This menu aims to discover new stocks, and the usage of the following commands along with an example will be exploited below.
* [ipo](#ipo)
* past and future IPOs [Finnhub]
* [map](#map)
* S&P500 index stocks map [Finviz]
* [rtp_sectors](#rtp_sectors)
@@ -42,6 +44,20 @@ This menu aims to discover new stocks, and the usage of the following commands a
* dark pool tickers with growing activity [FINRA]
## ipo <a name="ipo"></a>
```shell
usage: ipo [-p PAST_DAYS] [-f FUTURE_DAYS]
```
Past and future IPOs. [Source: https://finnhub.io]
* -p : Number of past days to look for IPOs. Default 0.
* -f : Number of future days to look for IPOs. Default 10.
<img width="1005" alt="Captura de ecrã 2021-05-03, às 12 54 44" src="https://user-images.githubusercontent.com/25267873/116873168-1e6ed900-ac0f-11eb-9d80-dddc8a754885.png">
## map <a name="map"></a>
```shell

View File

@@ -22,6 +22,7 @@ from gamestonk_terminal.discovery import (
yahoo_finance_view,
marketbeat_view,
finra_ats_view,
finnhub_view,
)
@@ -33,6 +34,7 @@ class DiscoveryController:
"help",
"q",
"quit",
"ipo",
"map",
"rtp_sectors",
"gainers",
@@ -72,6 +74,7 @@ class DiscoveryController:
print(" q quit this menu, and shows back to main menu")
print(" quit quit to abandon program")
print("")
print(" ipo past and future IPOs [Finnhub]")
print(" map S&P500 index stocks map [Finviz]")
print(" rtp_sectors real-time performance sectors [Alpha Vantage]")
print(" gainers show latest top gainers [Yahoo Finance]")
@@ -135,6 +138,10 @@ class DiscoveryController:
"""Process Quit command - quit the program"""
return True
def call_ipo(self, other_args: List[str]):
"""Process ipo command"""
finnhub_view.ipo_calendar(other_args)
def call_map(self, other_args: List[str]):
"""Process map command"""
finviz_view.map_sp500_view(other_args)

View File

@@ -0,0 +1,122 @@
import argparse
from typing import List
from datetime import datetime, timedelta
import requests
import pandas as pd
from gamestonk_terminal import config_terminal as cfg
from gamestonk_terminal.helper_funcs import (
parse_known_args_and_warn,
check_non_negative,
)
def get_ipo_calendar(from_date: str, to_date: str) -> pd.DataFrame:
"""Get IPO calendar
Parameters
----------
from_date : str
from date (%Y-%m-%d) to get IPO calendar
to_date : str
to date (%Y-%m-%d) to get IPO calendar
Returns
-------
pd.DataFrame
Get dataframe with economic calendar events
"""
response = requests.get(
f"https://finnhub.io/api/v1/calendar/ipo?from={from_date}&to={to_date}&token={cfg.API_FINNHUB_KEY}"
)
if response.status_code == 200:
d_data = response.json()
if "ipoCalendar" in d_data:
d_refactor_columns = {
"numberOfShares": "Number of Shares",
"totalSharesValue": "Total Shares Value",
"date": "Date",
"exchange": "Exchange",
"name": "Name",
"price": "Price",
"status": "Status",
}
return pd.DataFrame(d_data["ipoCalendar"]).rename(
columns=d_refactor_columns
)
return pd.DataFrame()
def ipo_calendar(other_args: List[str]):
"""Past and future IPOs calendar [Finnhub]
Parameters
----------
other_args : List[str]
Command line arguments to be processed with argparse
"""
parser = argparse.ArgumentParser(
add_help=False,
prog="ipo",
description="""
Past and future IPOs. [Source: https://finnhub.io]
""",
)
parser.add_argument(
"-p",
"--past",
action="store",
dest="past_days",
type=check_non_negative,
default=0,
help="Number of past days to look for IPOs.",
)
parser.add_argument(
"-f",
"--future",
action="store",
dest="future_days",
type=check_non_negative,
default=10,
help="Number of future days to look for IPOs.",
)
try:
if other_args:
if "-" not in other_args[0]:
other_args.insert(0, "-f")
ns_parser = parse_known_args_and_warn(parser, other_args)
if not ns_parser:
return
today = datetime.now()
if ns_parser.future_days > 0:
future_date = today + timedelta(days=ns_parser.future_days)
df_future_ipo = get_ipo_calendar(
today.strftime("%Y-%m-%d"), future_date.strftime("%Y-%m-%d")
).rename(columns={"Date": "Future"})
if df_future_ipo.empty:
print(f"No IPOs found for the next {ns_parser.future_days} days")
else:
print(df_future_ipo.to_string(index=False))
print("")
if ns_parser.past_days > 0:
past_date = today - timedelta(days=ns_parser.past_days)
df_past_ipo = get_ipo_calendar(
past_date.strftime("%Y-%m-%d"), today.strftime("%Y-%m-%d")
).rename(columns={"Date": "Past"})
if df_past_ipo.empty:
print(f"No IPOs found since the last {ns_parser.past_days} days")
else:
print(df_past_ipo.to_string(index=False))
print("")
except Exception as e:
print(e, "\n")

View File

@@ -12,6 +12,8 @@ This menu aims to help in due-diligence of a pre-loaded stock, and the usage of
* rating of the company from strong sell to strong buy [FMP]
* [pt](#pt)
* price targets over time [Business Insider]
* [rot](#rot)
* ratings over time [Finnhub]
* [est](#est)
* quarter and year analysts earnings estimates [Business Insider]
* [ins](#ins)
@@ -89,6 +91,18 @@ Prints price target from analysts. [Source: Business Insider]
<img width="940" alt="pt2" src="https://user-images.githubusercontent.com/25267873/108609914-3af9c400-73c9-11eb-8820-0abfa9e57119.png">
## rot <a name="rot"></a>
```text
usage: rot
```
Plots ratings over time. [Source: Finnhub]
![rot](https://user-images.githubusercontent.com/25267873/116864981-ad282980-ac00-11eb-9e86-7163782a8ef6.png)
## est <a name="est"></a>
```text

View File

@@ -15,6 +15,7 @@ from gamestonk_terminal.due_diligence import reddit_view as r_view
from gamestonk_terminal.due_diligence import news_view
from gamestonk_terminal.due_diligence import finra_view
from gamestonk_terminal.due_diligence import sec_view
from gamestonk_terminal.due_diligence import finnhub_view
from gamestonk_terminal import feature_flags as gtff
from gamestonk_terminal.helper_funcs import get_flair
from gamestonk_terminal.menu import session
@@ -32,6 +33,7 @@ class DueDiligenceController:
"short",
"rating",
"pt",
"rot",
"est",
"ins",
"insider",
@@ -91,6 +93,9 @@ class DueDiligenceController:
" rating rating of the company from strong sell to strong buy [FMP]"
)
print(" pt price targets over time [Business Insider]")
print(
" rot rating over timefrom strong sell to strong buy [Finnhub]"
)
print(
" est quarter and year analysts earnings estimates [Business Insider]"
)
@@ -155,6 +160,10 @@ class DueDiligenceController:
other_args, self.stock, self.ticker, self.start, self.interval
)
def call_rot(self, other_args: List[str]):
"""Process rot command"""
finnhub_view.rating_over_time(other_args, self.ticker)
def call_est(self, other_args: List[str]):
"""Process est command"""
bi_view.estimates(other_args, self.ticker)

View File

@@ -0,0 +1,108 @@
import argparse
from typing import List
import requests
import pandas as pd
from matplotlib import pyplot as plt
from pandas.plotting import register_matplotlib_converters
from gamestonk_terminal import config_terminal as cfg
from gamestonk_terminal.helper_funcs import (
parse_known_args_and_warn,
plot_autoscale,
)
from gamestonk_terminal.config_plot import PLOT_DPI
from gamestonk_terminal import feature_flags as gtff
register_matplotlib_converters()
def get_rating_over_time(ticker: str) -> pd.DataFrame:
"""Get rating over time
Parameters
----------
ticker : str
Ticker to get ratings from
Returns
-------
pd.DataFrame
Get dataframe with economic calendar events
"""
response = requests.get(
f"https://finnhub.io/api/v1/stock/recommendation?symbol={ticker}&token={cfg.API_FINNHUB_KEY}"
)
if response.status_code == 200:
return pd.DataFrame(response.json())
return pd.DataFrame()
def plot_rating_over_time(rot: pd.DataFrame, ticker: str):
"""Plot rating over time
Parameters
----------
rot : pd.DataFrame
Rating over time
ticker : str
Ticker associated with ratings
"""
plt.figure(figsize=plot_autoscale(), dpi=PLOT_DPI)
rot.sort_values("period", inplace=True)
plt.plot(pd.to_datetime(rot["period"]), rot["strongBuy"], c="green", lw=3)
plt.plot(pd.to_datetime(rot["period"]), rot["buy"], c="lightgreen", lw=3)
plt.plot(pd.to_datetime(rot["period"]), rot["hold"], c="grey", lw=3)
plt.plot(pd.to_datetime(rot["period"]), rot["sell"], c="pink", lw=3)
plt.plot(pd.to_datetime(rot["period"]), rot["strongSell"], c="red", lw=3)
plt.xlim(
pd.to_datetime(rot["period"].values[0]),
pd.to_datetime(rot["period"].values[-1]),
)
plt.grid()
plt.title(f"{ticker}'s ratings over time")
plt.xlabel("Time")
plt.ylabel("Rating")
plt.legend(["Strong Buy", "Buy", "Hold", "Sell", "Strong Sell"])
if gtff.USE_ION:
plt.ion()
plt.show()
def rating_over_time(other_args: List[str], ticker: str):
"""Rating over time
Parameters
----------
other_args : List[str]
Command line arguments to be processed with argparse
ticker : str
Ticker to get ratings from
"""
parser = argparse.ArgumentParser(
add_help=False,
prog="rot",
description="""
Rating over time. [Source: https://finnhub.io]
""",
)
try:
ns_parser = parse_known_args_and_warn(parser, other_args)
if not ns_parser:
return
df_rot = get_rating_over_time(ticker)
if df_rot.empty:
print("No ratings over time found\n")
return
plot_rating_over_time(df_rot, ticker)
print("")
except Exception as e:
print(e, "\n")

View File

@@ -1,7 +1,9 @@
# ECONONMY
# ECONOMY
This menu aims to assess economy data, and the usage of the following commands along with an example will be exploited below.
* [events](#events)
* economic impact events [Finnhub]
* [fred](#fred)
* display customized FRED from https://fred.stlouisfed.org
* [vixcls](#vixcls)
@@ -28,6 +30,20 @@ This menu aims to assess economy data, and the usage of the following commands a
* Canada / U.S. Foreign Exchange Rate (CAD per 1 USD)
## events <a name="events"></a>
```text
usage: events [-c {NZ,AU,ERL,CA,EU,US,JP,CN,GB,CH}] [-i {low,medium,high,all}] [-n NUM]
```
Output economy impact calendar impact events. [Source: https://finnhub.io]
* -c : Country from where to get economy calendar impact events, between NZ,AU,ERL,CA,EU,US,JP,CN,GB,CH. Default: US.
* -i : Impact of the economy event, between low,medium,high,all. Default: all.
* -n : Number economy calendar impact events to display. Default: 10.
<img width="1055" alt="Captura de ecrã 2021-05-02, às 19 51 47" src="https://user-images.githubusercontent.com/25267873/116824200-def9ab80-ab80-11eb-948a-48a94f662b53.png">
## fred <a name="fred"></a>
```text
usage: fred [-i SERIES_ID] [-s START_DATE] [-t]

View File

@@ -9,6 +9,7 @@ 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
from gamestonk_terminal.econ import finnhub_view
class EconController:
@@ -19,6 +20,7 @@ class EconController:
"help",
"q",
"quit",
"events",
"fred",
"vixcls",
"gdp",
@@ -50,6 +52,7 @@ class EconController:
print(" q quit this menu, and shows back to main menu")
print(" quit quit to abandon program")
print(" ")
print(" events economic impact events [Finnhub]")
print(
" fred display customized FRED data from https://fred.stlouisfed.org"
)
@@ -95,6 +98,10 @@ class EconController:
"""Process Quit command - quit the program"""
return True
def call_events(self, other_args: List[str]):
"""Process events command"""
finnhub_view.economy_calendar_events(other_args)
def call_fred(self, other_args: List[str]):
"""Process fred command"""
fred_view.display_fred(other_args, "")

View File

@@ -0,0 +1,131 @@
import argparse
from typing import List
import requests
import pandas as pd
from gamestonk_terminal import config_terminal as cfg
from gamestonk_terminal.helper_funcs import (
parse_known_args_and_warn,
check_positive,
)
def get_economy_calendar_events() -> pd.DataFrame:
"""Get economic calendar events
Returns
-------
pd.DataFrame
Get dataframe with economic calendar events
"""
response = requests.get(
f"https://finnhub.io/api/v1/calendar/economic?token={cfg.API_FINNHUB_KEY}"
)
if response.status_code == 200:
d_data = response.json()
if "economicCalendar" in d_data:
return pd.DataFrame(d_data["economicCalendar"])
return pd.DataFrame()
def economy_calendar_events(other_args: List[str]):
"""Output economy calendar impact events
Parameters
----------
other_args : List[str]
Command line arguments to be processed with argparse
"""
parser = argparse.ArgumentParser(
add_help=False,
prog="events",
description="""
Output economy impact calendar impact events. [Source: https://finnhub.io]
""",
)
parser.add_argument(
"-c",
"--country",
action="store",
dest="country",
type=str,
default="US",
choices=["NZ", "AU", "ERL", "CA", "EU", "US", "JP", "CN", "GB", "CH"],
help="Country from where to get economy calendar impact events",
)
parser.add_argument(
"-n",
"--num",
action="store",
dest="num",
type=check_positive,
default=10,
help="Number economy calendar impact events to display",
)
parser.add_argument(
"-i",
"--impact",
action="store",
dest="impact",
type=str,
default="all",
choices=["low", "medium", "high", "all"],
help="Impact of the economy event",
)
try:
if other_args:
if "-" not in other_args[0]:
other_args.insert(0, "-c")
ns_parser = parse_known_args_and_warn(parser, other_args)
if not ns_parser:
return
df_events = get_economy_calendar_events()
if df_events.empty:
print("No latest economy calendar events found\n")
return
df_econ_calendar = df_events[
df_events["country"] == ns_parser.country
].sort_values("time", ascending=False)
if df_econ_calendar.empty:
print("No latet economy calendar events found in the specified country\n")
return
if ns_parser.impact != "all":
df_econ_calendar = df_econ_calendar[
df_econ_calendar["impact"] == ns_parser.impact
]
if df_econ_calendar.empty:
print(
"No latet economy calendar events found in the specified country with this impact\n"
)
return
df_econ_calendar = df_econ_calendar.fillna("---").head(n=ns_parser.num)
d_econ_calendar_map = {
"actual": "Actual release",
"prev": "Previous release",
"country": "Country",
"unit": "Unit",
"estimate": "Estimate",
"event": "Event",
"impact": "Impact Level",
"time": "Release time",
}
df_econ_calendar = df_econ_calendar[
["time", "event", "impact", "prev", "estimate", "actual", "unit"]
].rename(columns=d_econ_calendar_map)
print(df_econ_calendar.to_string(index=False))
print("")
except Exception as e:
print(e, "\n")

View File

@@ -58,7 +58,7 @@ def display_fred(other_args: List[str], choice: str):
"-i",
"--id",
dest="series_id",
required=bool(choice),
required=not bool(choice),
type=str,
default=choice.upper(),
help="FRED Series ID from https://fred.stlouisfed.org",

View File

@@ -55,11 +55,13 @@ def print_help(s_ticker, s_start, s_interval, b_is_market_open):
" > scr screener stocks, \t\t e.g. overview/performance, using preset filters"
)
print(" > mill papermill menu, \t\t menu to generate notebook reports")
print(" > econ economic data, \t\t from: FRED, VIX")
print(" > econ economic data, \t\t e.g.: FRED, events")
print(
" > pa portfolio analysis, \t\t supports: robinhood, alpaca, ally "
)
print(" > crypto cryptocurrencies, \t\t uses coingecko api")
print(
" > crypto cryptocurrencies, \t\t from: coingecko, coinmarketcap, binance"
)
print(
" > po portfolio optimization, \t optimal portfolio weights from pyportfolioopt"
)

View File

@@ -8,6 +8,8 @@ This menu aims to perform a technical analysis on a pre-loaded ticker chart, and
- technical summary report [FinBrain API]
* [recom](#recom)
- recommendation based on Technical Indicators [Tradingview API]
* [pr](#pr)
- pattern recognition [Finnhub]
[OVERLAP](#OVERLAP)
* [ema](#ema)
@@ -79,6 +81,19 @@ Print tradingview recommendation based on technical indicators. [Source: https:/
<img width="977" alt="Captura de ecrã 2021-03-31, às 00 14 41" src="https://user-images.githubusercontent.com/25267873/113069531-76ea2b00-91b8-11eb-8934-9f693d3b4ffa.png">
## pr <a name="pr"></a>
```
usage: pr [-r {1,5,15,30,60,D,W,M}]
```
Display pattern recognition signals on the data. [Source: https://finnhub.io]
* -r : Plot resolution to look for pattern signals. Default 'D'.
![pr](https://user-images.githubusercontent.com/25267873/116812520-06338700-ab47-11eb-8db4-8f5e940507ed.png)
<img width="985" alt="Captura de ecrã 2021-05-02, às 02 27 10" src="https://user-images.githubusercontent.com/25267873/116812505-f6b43e00-ab46-11eb-9776-fa469dc3d3f0.png">
# OVERLAP <a name="OVERLAP"></a>
## ema <a name="ema"></a>

View File

@@ -0,0 +1,185 @@
import argparse
from typing import List
import math
from datetime import datetime
import requests
import yfinance as yf
import mplfinance as mpf
import pandas as pd
from gamestonk_terminal import config_terminal as cfg
from gamestonk_terminal.helper_funcs import (
parse_known_args_and_warn,
plot_autoscale,
)
def get_pattern_recognition(ticker: str, resolution: str) -> pd.DataFrame:
"""Get pattern recognition data
Parameters
----------
ticker : str
Ticker to get pattern recognition data
resolution : str
Resolution of data to get pattern recognition from
Returns
-------
pd.DataFrame
Get datapoints corresponding to pattern signal data
"""
response = requests.get(
f"https://finnhub.io/api/v1/scan/pattern?symbol={ticker}&resolution={resolution}&token={cfg.API_FINNHUB_KEY}"
)
if response.status_code == 200:
d_data = response.json()
if "points" in d_data:
return pd.DataFrame(d_data["points"]).T
return pd.DataFrame()
def plot_pattern_recognition(ticker: str, pattern: pd.DataFrame):
"""Plot pattern recognition signal
Parameters
----------
ticker : str
Ticker to display pattern recognition on top of the data
pattern : pd.DataFrame
Pattern recognition signal data
"""
l_segments = list()
for i in pattern:
a_part = ("", "")
if "aprice" in pattern[i]:
if pattern[i]["aprice"] != 0 and not math.isnan(pattern[i]["aprice"]):
a_part = (
datetime.utcfromtimestamp(pattern[i]["atime"]).strftime("%Y-%m-%d"),
pattern[i]["aprice"],
)
b_part = ("", "")
if "bprice" in pattern[i]:
if pattern[i]["bprice"] != 0 and not math.isnan(pattern[i]["bprice"]):
b_part = (
datetime.utcfromtimestamp(pattern[i]["btime"]).strftime("%Y-%m-%d"),
pattern[i]["bprice"],
)
c_part = ("", "")
if "cprice" in pattern[i]:
if pattern[i]["cprice"] != 0 and not math.isnan(pattern[i]["cprice"]):
c_part = (
datetime.utcfromtimestamp(pattern[i]["ctime"]).strftime("%Y-%m-%d"),
pattern[i]["cprice"],
)
d_part = ("", "")
if "dprice" in pattern[i]:
if pattern[i]["dprice"] != 0 and not math.isnan(pattern[i]["dprice"]):
d_part = (
datetime.utcfromtimestamp(pattern[i]["dtime"]).strftime("%Y-%m-%d"),
pattern[i]["dprice"],
)
segment = (a_part, b_part, c_part, d_part)
l_segment = list(segment)
while ("", "") in l_segment:
l_segment.remove(("", ""))
segm = tuple(l_segment)
l_segments.append(segm)
start_time = 999999999999
for i in pattern:
if pattern[i]["atime"] < start_time:
start_time = pattern[i]["atime"]
df_stock = yf.download(
ticker,
start=datetime.utcfromtimestamp(start_time).strftime("%Y-%m-%d"),
progress=False,
)
df_stock["date_id"] = (df_stock.index.date - df_stock.index.date.min()).astype(
"timedelta64[D]"
)
df_stock["date_id"] = df_stock["date_id"].dt.days + 1
df_stock["OC_High"] = df_stock[["Open", "Close"]].max(axis=1)
df_stock["OC_Low"] = df_stock[["Open", "Close"]].min(axis=1)
mc = mpf.make_marketcolors(
up="green", down="red", edge="black", wick="black", volume="in", ohlc="i"
)
s = mpf.make_mpf_style(marketcolors=mc, gridstyle=":", y_on_right=False)
mpf.plot(
df_stock,
type="candle",
volume=False,
title=f"\n{ticker}",
alines=l_segments,
xrotation=10,
style=s,
figratio=(10, 7),
figscale=1.10,
figsize=plot_autoscale(),
update_width_config=dict(
candle_linewidth=1.0, candle_width=0.8, volume_linewidth=1.0
),
)
for ix in range(len(pattern.columns)):
print(f"From {l_segments[ix][0][0]} to {l_segments[ix][-1][0]}")
print(f"Pattern: {pattern[0]['patternname']} ({pattern[0]['patterntype']})")
print("")
def pattern_recognition_view(other_args: List[str], ticker: str):
"""Display pattern recognition signals on the data
Parameters
----------
other_args : List[str]
Command line arguments to be processed with argparse
ticker : str
Ticker to display pattern recognition on top of the data
"""
parser = argparse.ArgumentParser(
add_help=False,
prog="pr",
description="""
Display pattern recognition signals on the data. [Source: https://finnhub.io]
""",
)
parser.add_argument(
"-r",
"--resolution",
action="store",
dest="resolution",
type=str,
default="D",
choices=["1", "5", "15", "30", "60", "D", "W", "M"],
help="Plot resolution to look for pattern signals",
)
try:
ns_parser = parse_known_args_and_warn(parser, other_args)
if not ns_parser:
return
df_pattern = get_pattern_recognition(ticker, ns_parser.resolution)
if df_pattern.empty:
print("No pattern identified in this data", "\n")
return
plot_pattern_recognition(ticker, df_pattern)
except Exception as e:
print(e, "\n")

View File

@@ -20,6 +20,7 @@ from gamestonk_terminal.technical_analysis import volume as ta_volume
from gamestonk_terminal.technical_analysis import finbrain_view
from gamestonk_terminal.technical_analysis import tradingview_view
from gamestonk_terminal.technical_analysis import finviz_view
from gamestonk_terminal.technical_analysis import finnhub_view
class TechnicalAnalysisController:
@@ -33,6 +34,7 @@ class TechnicalAnalysisController:
"view",
"summary",
"recom",
"pr",
"ema",
"sma",
"vwap",
@@ -88,6 +90,8 @@ class TechnicalAnalysisController:
print(
" recom recommendation based on Technical Indicators [Tradingview API]"
)
print(" pr pattern recognition [Finnhub]")
print("")
print("overlap:")
print(" ema exponential moving average")
print(" sma simple moving average")
@@ -157,6 +161,10 @@ class TechnicalAnalysisController:
"""Process recom command"""
tradingview_view.print_recommendation(other_args, self.ticker)
def call_pr(self, other_args: List[str]):
"""Process pr command"""
finnhub_view.pattern_recognition_view(other_args, self.ticker)
# OVERLAP
def call_ema(self, other_args: List[str]):
"""Process ema command"""

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

137
poetry.lock generated
View File

@@ -436,6 +436,23 @@ category = "main"
optional = false
python-versions = ">=3.6, <3.7"
[[package]]
name = "dateparser"
version = "1.0.0"
description = "Date parsing library designed to parse dates from HTML pages"
category = "main"
optional = false
python-versions = ">=3.5"
[package.dependencies]
python-dateutil = "*"
pytz = "*"
regex = "!=2019.02.19"
tzlocal = "*"
[package.extras]
calendars = ["convertdate", "hijri-converter", "convertdate"]
[[package]]
name = "datetime"
version = "4.3"
@@ -712,7 +729,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
[[package]]
name = "gdown"
version = "3.12.2"
version = "3.13.0"
description = "Google Drive direct download of big files."
category = "main"
optional = true
@@ -720,7 +737,7 @@ python-versions = "*"
[package.dependencies]
filelock = "*"
requests = {version = "*", extras = ["socks"]}
requests = {version = ">=2.12.0", extras = ["socks"]}
six = "*"
tqdm = "*"
@@ -2009,7 +2026,7 @@ python-versions = "*"
[[package]]
name = "pyobjc-core"
version = "7.1"
version = "7.2"
description = "Python<->ObjC Interoperability Module"
category = "main"
optional = false
@@ -2017,14 +2034,14 @@ python-versions = ">=3.6"
[[package]]
name = "pyobjc-framework-cocoa"
version = "7.1"
version = "7.2"
description = "Wrappers for the Cocoa frameworks on macOS"
category = "main"
optional = false
python-versions = ">=3.6"
[package.dependencies]
pyobjc-core = ">=7.1"
pyobjc-core = ">=7.2"
[[package]]
name = "pyotp"
@@ -2120,6 +2137,22 @@ toml = "*"
[package.extras]
testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"]
[[package]]
name = "python-binance"
version = "1.0.1"
description = "Binance REST API python implementation"
category = "main"
optional = false
python-versions = "*"
[package.dependencies]
aiohttp = "*"
dateparser = "*"
requests = "*"
six = "*"
ujson = "*"
websockets = "*"
[[package]]
name = "python-coinmarketcap"
version = "0.2"
@@ -2173,7 +2206,7 @@ python-versions = "*"
[[package]]
name = "pyupgrade"
version = "2.13.0"
version = "2.14.0"
description = "A tool to automatically upgrade syntax for newer versions."
category = "dev"
optional = false
@@ -2232,7 +2265,7 @@ scipy = ">=0.13.2"
[[package]]
name = "qtconsole"
version = "5.0.3"
version = "5.1.0"
description = "Jupyter Qt console"
category = "main"
optional = false
@@ -2863,6 +2896,25 @@ category = "main"
optional = false
python-versions = "*"
[[package]]
name = "tzlocal"
version = "2.1"
description = "tzinfo object for the local timezone"
category = "main"
optional = false
python-versions = "*"
[package.dependencies]
pytz = "*"
[[package]]
name = "ujson"
version = "4.0.2"
description = "Ultra fast JSON encoder and decoder for Python"
category = "main"
optional = false
python-versions = ">=3.6"
[[package]]
name = "update-checker"
version = "0.18.0"
@@ -3036,7 +3088,7 @@ prediction = ["fbprophet", "tensorflow", "pmdarima", "transformers", "flair", "t
[metadata]
lock-version = "1.1"
python-versions = "^3.6.8"
content-hash = "51e9191a579c58d229a6a32b419f3f8d891d2e7ce12decb6f74a283fb46a851a"
content-hash = "9f2c8b046494863b5a83e395b8a79edbca42fd2b61b5e977877e08aedc53e165"
[metadata.files]
absl-py = [
@@ -3329,6 +3381,10 @@ dataclasses = [
{file = "dataclasses-0.8-py3-none-any.whl", hash = "sha256:0201d89fa866f68c8ebd9d08ee6ff50c0b255f8ec63a71c16fda7af82bb887bf"},
{file = "dataclasses-0.8.tar.gz", hash = "sha256:8479067f342acf957dc82ec415d355ab5edb7e7646b90dc6e2fd1d96ad084c97"},
]
dateparser = [
{file = "dateparser-1.0.0-py2.py3-none-any.whl", hash = "sha256:17202df32c7a36e773136ff353aa3767e987f8b3e27374c39fd21a30a803d6f8"},
{file = "dateparser-1.0.0.tar.gz", hash = "sha256:159cc4e01a593706a15cd4e269a0b3345edf3aef8bf9278a57dac8adf5bf1e4a"},
]
datetime = [
{file = "DateTime-4.3-py2.py3-none-any.whl", hash = "sha256:371dba07417b929a4fa685c2f7a3eaa6a62d60c02947831f97d4df9a9e70dfd0"},
{file = "DateTime-4.3.tar.gz", hash = "sha256:5cef605bab8259ff61281762cdf3290e459fbf0b4719951d5fab967d5f2ea0ea"},
@@ -3458,7 +3514,7 @@ gast = [
{file = "gast-0.3.3.tar.gz", hash = "sha256:b881ef288a49aa81440d2c5eb8aeefd4c2bb8993d5f50edae7413a85bfdb3b57"},
]
gdown = [
{file = "gdown-3.12.2.tar.gz", hash = "sha256:4b3a1301e57bfd8dce939bf25ef8fbb4b23967fd0f878eede328bdcc41386bac"},
{file = "gdown-3.13.0.tar.gz", hash = "sha256:d5f9389539673875712beba4936c4ace95d24324953c6f0408a858c534c0bf21"},
]
gensim = [
{file = "gensim-3.8.3-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:61eed1d6b5fbe6dda0586ea447ebc2dc7890a7f70c2ed953d5abc3fe3cfb94bb"},
@@ -4335,20 +4391,20 @@ pymeeus = [
{file = "PyMeeus-0.5.11.tar.gz", hash = "sha256:bb9d670818d8b0594317b48a7dadea02a0594e5344263bf2054e1a011c8fed55"},
]
pyobjc-core = [
{file = "pyobjc-core-7.1.tar.gz", hash = "sha256:a0616d5d816b4471f8f782c3a9a8923d2cc85014d88ad4f7fec694be9e6ea349"},
{file = "pyobjc_core-7.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f9fb45c9916f2a03ecd6b9ecde4c35d1d0f1a590ae2ea2372f9d9a360226ac1d"},
{file = "pyobjc_core-7.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:fff8e87358c6195a2937004f279050cce3d4c02cd77acd73c5ad367307def855"},
{file = "pyobjc_core-7.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:afb38efd3f2960eb49eb78552d465cfd025a9d6efa06cd4cd8694dafbe7c6e06"},
{file = "pyobjc_core-7.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7cb329c4119044fe83bcb3c5d4794d636c706ff0cb7c1c77d36ef5c373100082"},
{file = "pyobjc_core-7.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7913d7b20217c294900537faf58e5cc15942ed7af277bf05db25667d18255114"},
{file = "pyobjc-core-7.2.tar.gz", hash = "sha256:9e9ec482d80ea030cdb1613d05a247f31eedabe6666d884d42dd890cc5fb0e05"},
{file = "pyobjc_core-7.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:94b4d9de9d228db52dd35012096d63bdf8c1ace58ea3be1d5f6f39313cd502f2"},
{file = "pyobjc_core-7.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:971cbd7189ae1aa03ef0d16124aa5bcd053779e0e6b6011a41c3dbd5b4ea7e88"},
{file = "pyobjc_core-7.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9d93b20394008373d6d2856d49aaff26f4b97ff42d924a14516c8a82313ec8c0"},
{file = "pyobjc_core-7.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:860183540d1be792c26426018139ac8ba75e85f675c59ba080ccdc52d8e74c7a"},
{file = "pyobjc_core-7.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ffe61d3c2a404354daf2d895e34e38c5044453353581b3c396bf5365de26250c"},
]
pyobjc-framework-cocoa = [
{file = "pyobjc-framework-Cocoa-7.1.tar.gz", hash = "sha256:67966152b3d38a0225176fceca2e9f56d849c8e7445548da09a00cb13155ec3e"},
{file = "pyobjc_framework_Cocoa-7.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:bef77eafaac5eaf1d91d479d5483fd02216caa3edc27e8f5adc9af0b3fecdac3"},
{file = "pyobjc_framework_Cocoa-7.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b2ea3582c456827dc20e648c905fdbcf8d3dfae89434f981e9b761cd07262049"},
{file = "pyobjc_framework_Cocoa-7.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1a4050f2d776f40c2409a151c6f7896420e936934b3bdbfabedf91509637ed9b"},
{file = "pyobjc_framework_Cocoa-7.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:3f68f022f1f6d5985c418e10c6608c562fcf4bfe3714ec64fd10ce3dc6221bd4"},
{file = "pyobjc_framework_Cocoa-7.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ecfefd4c48dae42275c18679c69f6f2fff970e711097515a0a8732fc10194018"},
{file = "pyobjc-framework-Cocoa-7.2.tar.gz", hash = "sha256:c8b23f03dc3f4436d36c0fd006a8a084835c4f6015187df7c3aa5de8ecd5c653"},
{file = "pyobjc_framework_Cocoa-7.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8e5dd5daa0096755937ec24c345a4b07c3fa131a457f99e0fdeeb01979178ec7"},
{file = "pyobjc_framework_Cocoa-7.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:828d183947fc7746953fd0c9b1092cc423745ba0b49719e7b7d1e1614aaa20ec"},
{file = "pyobjc_framework_Cocoa-7.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7e4c6d7baa0c2ab5ea5efb8836ad0b3b3976cffcfc6195c1f195e826c6eb5744"},
{file = "pyobjc_framework_Cocoa-7.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c9a9d1d49cc5a810773c88d6de821e60c8cc41d01113cf1b9e7662938f5f7d66"},
{file = "pyobjc_framework_Cocoa-7.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:506c2cd09f421eac92b9008a0142174c3d1d70ecd4b0e3fa2b924767995fd14e"},
]
pyotp = [
{file = "pyotp-2.6.0-py2.py3-none-any.whl", hash = "sha256:9d144de0f8a601d6869abe1409f4a3f75f097c37b50a36a3bf165810a6e23f28"},
@@ -4400,6 +4456,10 @@ pytest = [
{file = "pytest-6.2.3-py3-none-any.whl", hash = "sha256:6ad9c7bdf517a808242b998ac20063c41532a570d088d77eec1ee12b0b5574bc"},
{file = "pytest-6.2.3.tar.gz", hash = "sha256:671238a46e4df0f3498d1c3270e5deb9b32d25134c99b7d75370a68cfbe9b634"},
]
python-binance = [
{file = "python-binance-1.0.1.tar.gz", hash = "sha256:7987189651938bb81a4e2f86993a32c77c55255d9c33891efb1d2bca918b8142"},
{file = "python_binance-1.0.1-py2.py3-none-any.whl", hash = "sha256:80dc4402837103024c44f0f57c5ac90c43e5ebe1da4f53104ebd4b9b788bd17d"},
]
python-coinmarketcap = [
{file = "python-coinmarketcap-0.2.tar.gz", hash = "sha256:b1e0e8b098fc910a5ec943a06774d5ee3b190e915123366e2f16238ef0a8a433"},
{file = "python_coinmarketcap-0.2-py2-none-any.whl", hash = "sha256:54c278154ee11ca78837fb73eae8c322a60af93dc0ce75b515fecf895d181cf5"},
@@ -4422,8 +4482,8 @@ pytz = [
{file = "pytz-2021.1.tar.gz", hash = "sha256:83a4a90894bf38e243cf052c8b58f381bfe9a7a483f6a9cab140bc7f702ac4da"},
]
pyupgrade = [
{file = "pyupgrade-2.13.0-py2.py3-none-any.whl", hash = "sha256:1cb5a15573fc63824b952bf7dde5b96f9672a1179ec779ac2d159a845da743c8"},
{file = "pyupgrade-2.13.0.tar.gz", hash = "sha256:dc6b580b7bc82f357acb354bbba03d8d69da51425ecd5993a2651059bca80518"},
{file = "pyupgrade-2.14.0-py2.py3-none-any.whl", hash = "sha256:19bd23babd4c09171be66d393d83a53e5ae8d54c6534001c4b7ad92c4d560d69"},
{file = "pyupgrade-2.14.0.tar.gz", hash = "sha256:34f5dfa57d8007f6cd455a0a423e06e96753b07e4711bac63e3d5c4f3af97cea"},
]
pywin32 = [
{file = "pywin32-300-cp35-cp35m-win32.whl", hash = "sha256:1c204a81daed2089e55d11eefa4826c05e604d27fe2be40b6bf8db7b6a39da63"},
@@ -4528,8 +4588,8 @@ qdldl = [
{file = "qdldl-0.1.5.post0.tar.gz", hash = "sha256:c392c7427651d8b226423c7aba4a0f2338a1f38a4bbdabac6bc4afd8bc934f06"},
]
qtconsole = [
{file = "qtconsole-5.0.3-py3-none-any.whl", hash = "sha256:4a38053993ca2da058f76f8d75b3d8906efbf9183de516f92f222ac8e37d9614"},
{file = "qtconsole-5.0.3.tar.gz", hash = "sha256:c091a35607d2a2432e004c4a112d241ce908086570cf68594176dd52ccaa212d"},
{file = "qtconsole-5.1.0-py3-none-any.whl", hash = "sha256:3a2adecc43ff201a08972fb2179df22e7b3a08d71b9ed680f46ad1bfd4fb9132"},
{file = "qtconsole-5.1.0.tar.gz", hash = "sha256:12c734494901658787339dea9bbd82f3dc0d5e394071377a1c77b4a0954d7d8b"},
]
qtpy = [
{file = "QtPy-1.9.0-py2.py3-none-any.whl", hash = "sha256:fa0b8363b363e89b2a6f49eddc162a04c0699ae95e109a6be3bb145a913190ea"},
@@ -5009,6 +5069,33 @@ typing-extensions = [
{file = "typing_extensions-3.7.4.3-py3-none-any.whl", hash = "sha256:7cb407020f00f7bfc3cb3e7881628838e69d8f3fcab2f64742a5e76b2f841918"},
{file = "typing_extensions-3.7.4.3.tar.gz", hash = "sha256:99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c"},
]
tzlocal = [
{file = "tzlocal-2.1-py2.py3-none-any.whl", hash = "sha256:e2cb6c6b5b604af38597403e9852872d7f534962ae2954c7f35efcb1ccacf4a4"},
{file = "tzlocal-2.1.tar.gz", hash = "sha256:643c97c5294aedc737780a49d9df30889321cbe1204eac2c2ec6134035a92e44"},
]
ujson = [
{file = "ujson-4.0.2-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:e390df0dcc7897ffb98e17eae1f4c442c39c91814c298ad84d935a3c5c7a32fa"},
{file = "ujson-4.0.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:84b1dca0d53b0a8d58835f72ea2894e4d6cf7a5dd8f520ab4cbd698c81e49737"},
{file = "ujson-4.0.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:91396a585ba51f84dc71c8da60cdc86de6b60ba0272c389b6482020a1fac9394"},
{file = "ujson-4.0.2-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:eb6b25a7670c7537a5998e695fa62ff13c7f9c33faf82927adf4daa460d5f62e"},
{file = "ujson-4.0.2-cp36-cp36m-win_amd64.whl", hash = "sha256:f8aded54c2bc554ce20b397f72101737dd61ee7b81c771684a7dd7805e6cca0c"},
{file = "ujson-4.0.2-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:30962467c36ff6de6161d784cd2a6aac1097f0128b522d6e9291678e34fb2b47"},
{file = "ujson-4.0.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:fc51e545d65689c398161f07fd405104956ec27f22453de85898fa088b2cd4bb"},
{file = "ujson-4.0.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e6e90330670c78e727d6637bb5a215d3e093d8e3570d439fd4922942f88da361"},
{file = "ujson-4.0.2-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:5e1636b94c7f1f59a8ead4c8a7bab1b12cc52d4c21ababa295ffec56b445fd2a"},
{file = "ujson-4.0.2-cp37-cp37m-win_amd64.whl", hash = "sha256:e2cadeb0ddc98e3963bea266cc5b884e5d77d73adf807f0bda9eca64d1c509d5"},
{file = "ujson-4.0.2-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:a214ba5a21dad71a43c0f5aef917cd56a2d70bc974d845be211c66b6742a471c"},
{file = "ujson-4.0.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:0190d26c0e990c17ad072ec8593647218fe1c675d11089cd3d1440175b568967"},
{file = "ujson-4.0.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:f273a875c0b42c2a019c337631bc1907f6fdfbc84210cc0d1fff0e2019bbfaec"},
{file = "ujson-4.0.2-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:d3a87888c40b5bfcf69b4030427cd666893e826e82cc8608d1ba8b4b5e04ea99"},
{file = "ujson-4.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:7333e8bc45ea28c74ae26157eacaed5e5629dbada32e0103c23eb368f93af108"},
{file = "ujson-4.0.2-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:b3a6dcc660220539aa718bcc9dbd6dedf2a01d19c875d1033f028f212e36d6bb"},
{file = "ujson-4.0.2-cp39-cp39-manylinux1_i686.whl", hash = "sha256:0ea07fe57f9157118ca689e7f6db72759395b99121c0ff038d2e38649c626fb1"},
{file = "ujson-4.0.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:4d6d061563470cac889c0a9fd367013a5dbd8efc36ad01ab3e67a57e56cad720"},
{file = "ujson-4.0.2-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:b5c70704962cf93ec6ea3271a47d952b75ae1980d6c56b8496cec2a722075939"},
{file = "ujson-4.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:aad6d92f4d71e37ea70e966500f1951ecd065edca3a70d3861b37b176dd6702c"},
{file = "ujson-4.0.2.tar.gz", hash = "sha256:c615a9e9e378a7383b756b7e7a73c38b22aeb8967a8bfbffd4741f7ffd043c4d"},
]
update-checker = [
{file = "update_checker-0.18.0-py3-none-any.whl", hash = "sha256:cbba64760a36fe2640d80d85306e8fe82b6816659190993b7bdabadee4d4bbfd"},
{file = "update_checker-0.18.0.tar.gz", hash = "sha256:6a2d45bb4ac585884a6b03f9eade9161cedd9e8111545141e9aa9058932acb13"},

View File

@@ -63,6 +63,7 @@ oandapyV20 = "^0.6.3"
degiroapi = "^0.9.5"
valinvest = "^0.0.2"
bt = "^0.2.9"
python-binance = "^1.0.1"
[tool.poetry.dev-dependencies]
pytest = "^6.2.2"

View File

@@ -149,6 +149,7 @@ pyportfolioopt==1.4.1; python_full_version >= "3.6.1" and python_full_version <
pyrsistent==0.14.11
pysocks==1.7.1; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0"
pystan==2.19.1.1
python-binance==1.0.1
python-coinmarketcap==0.2
python-dateutil==2.8.1; python_full_version >= "3.6.1" and python_version >= "3.6" and (python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.6") and (python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.3.0") and (python_version >= "2.7" and python_full_version < "3.0.0" and python_version < "4" or python_version >= "2.7" and python_version < "4" and python_full_version >= "3.3.0")
python-dotenv==0.17.0; python_version >= "3"

View File

@@ -94,6 +94,7 @@ pyparsing==2.4.7; python_full_version >= "3.6.0" and python_version >= "3.6"
pyportfolioopt==1.4.1
pysocks==1.7.1; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0"
pystan==2.18
python-binance==1.0.1
python-coinmarketcap==0.2
python-dateutil==2.8.1; python_full_version >= "3.6.1" and python_version >= "3.5" and (python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.6") and (python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.3.0") and (python_version >= "2.7" and python_full_version < "3.0.0" and python_version < "4" or python_version >= "2.7" and python_version < "4" and python_full_version >= "3.3.0")
pytest==6.2.2; python_version >= "3.6"

View File

@@ -96,6 +96,7 @@ pyparsing==2.4.7; python_full_version >= "3.6.0" and python_version >= "3.6"
pyportfolioopt==1.4.1
pysocks==1.7.1; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0"
pystan==2.19.1.1
python-binance==1.0.1
python-coinmarketcap==0.2
python-dateutil==2.8.1; python_full_version >= "3.6.1" and python_version >= "3.5" and (python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.6") and (python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.3.0") and (python_version >= "2.7" and python_full_version < "3.0.0" and python_version < "4" or python_version >= "2.7" and python_version < "4" and python_full_version >= "3.3.0")
pytest==6.2.2; python_version >= "3.6"

View File

@@ -113,6 +113,7 @@ pyparsing==2.4.7; python_version >= "3.6" and python_full_version < "3.0.0" or p
pyportfolioopt==1.4.1; python_full_version >= "3.6.1" and python_full_version < "4.0.0"
pyrsistent==0.14.11
pysocks==1.7.1; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0"
python-binance==1.0.1
python-coinmarketcap==0.2
python-dateutil==2.8.1; python_full_version >= "3.6.1" and python_version >= "3.6" and (python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.6") and (python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.3.0")
python-dotenv==0.17.0; python_version >= "3"