mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-27 04:31:13 +00:00
Reorganize code structure in fa and ta folders
This commit is contained in:
2
config_bot.py
Normal file
2
config_bot.py
Normal file
@@ -0,0 +1,2 @@
|
||||
API_KEY_ALPHAVANTAGE = 'P6YGOQ6FL6OEIZ3B'
|
||||
API_KEY_FINANCIALMODELINGPREP = "845b22316eeec4168d249976bba94330"
|
||||
BIN
fundamental_analysis/.DS_Store
vendored
Normal file
BIN
fundamental_analysis/.DS_Store
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
fundamental_analysis/__pycache__/menu.cpython-36.pyc
Normal file
BIN
fundamental_analysis/__pycache__/menu.cpython-36.pyc
Normal file
Binary file not shown.
327
fundamental_analysis/alpha_vantage_api.py
Normal file
327
fundamental_analysis/alpha_vantage_api.py
Normal file
@@ -0,0 +1,327 @@
|
||||
from alpha_vantage.fundamentaldata import FundamentalData
|
||||
import config_bot as cfg
|
||||
import argparse
|
||||
from stock_market_helper_funcs import *
|
||||
import pandas as pd
|
||||
import json
|
||||
import requests
|
||||
from pandas.io.json import json_normalize
|
||||
|
||||
|
||||
# ---------------------------------------------------- OVERVIEW ----------------------------------------------------
|
||||
def overview(l_args, s_ticker):
|
||||
parser = argparse.ArgumentParser(prog='overview',
|
||||
description="""Gives an overview about the company. The following fields are expected:
|
||||
Symbol, Asset type, Name, Description, Exchange, Currency, Country, Sector, Industry,
|
||||
Address, Full time employees, Fiscal year end, Latest quarter, Market capitalization,
|
||||
EBITDA, PE ratio, PEG ratio, Book value, Dividend per share, Dividend yield, EPS,
|
||||
Revenue per share TTM, Profit margin, Operating margin TTM, Return on assets TTM,
|
||||
Return on equity TTM, Revenue TTM, Gross profit TTM, Diluted EPS TTM, Quarterly earnings growth YOY,
|
||||
Quarterly revenue growth YOY, Analyst target price, Trailing PE, Forward PE,
|
||||
Price to sales ratio TTM, Price to book ratio, EV to revenue, EV to EBITDA, Beta, 52 week high,
|
||||
52 week low, 50 day moving average, 200 day moving average, Shares outstanding, Shares float,
|
||||
Shares short, Shares short prior month, Short ratio, Short percent outstanding, Short percent float,
|
||||
Percent insiders, Percent institutions, Forward annual dividend rate, Forward annual dividend yield,
|
||||
Payout ratio, Dividend date, Ex dividend date, Last split factor, and Last split date.
|
||||
[Source: Alpha Vantage API]""")
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
# Request OVERVIEW data from Alpha Vantage API
|
||||
s_req = f"https://www.alphavantage.co/query?function=OVERVIEW&symbol={s_ticker}&apikey={cfg.API_KEY_ALPHAVANTAGE}"
|
||||
result = requests.get(s_req, stream=True)
|
||||
|
||||
# If the returned data was successful
|
||||
if result.status_code == 200:
|
||||
# Parse json data to dataframe
|
||||
df_fa = json_normalize(result.json())
|
||||
# Keep json data sorting in dataframe
|
||||
df_fa = df_fa[list(result.json().keys())].T
|
||||
df_fa = df_fa.applymap(lambda x: long_number_format(x))
|
||||
df_fa.index = [''.join(' ' + char if char.isupper() else char.strip() for char in idx).strip() for idx in df_fa.index.tolist()]
|
||||
df_fa.index = [s_val.capitalize() for s_val in df_fa.index]
|
||||
df_fa = df_fa.rename(index={"E b i t d a":"EBITDA",
|
||||
"P e ratio":"PE ratio",
|
||||
"P e g ratio":"PEG ratio",
|
||||
"E p s":"EPS",
|
||||
"Revenue per share t t m":"Revenue per share TTM",
|
||||
"Operating margin t t m":"Operating margin TTM",
|
||||
"Return on assets t t m":"Return on assets TTM",
|
||||
"Return on equity t t m":"Return on equity TTM",
|
||||
"Revenue t t m":"Revenue TTM",
|
||||
"Gross profit t t m":"Gross profit TTM",
|
||||
"Diluted e p s t t m":"Diluted EPS TTM",
|
||||
"Quarterly earnings growth y o y":"Quarterly earnings growth YOY",
|
||||
"Quarterly revenue growth y o y":"Quarterly revenue growth YOY",
|
||||
"Trailing p e":"Trailing PE",
|
||||
"Forward p e":"Forward PE",
|
||||
"Price to sales ratio t t m":"Price to sales ratio TTM",
|
||||
"E v to revenue":"EV to revenue",
|
||||
"E v to e b i t d a":"EV to EBITDA"})
|
||||
|
||||
pd.set_option('display.max_colwidth', -1)
|
||||
|
||||
print(df_fa.drop(index=['Description']).to_string(header=False))
|
||||
print(f"Description: {df_fa.loc['Description'][0]}")
|
||||
print("")
|
||||
else:
|
||||
print(f"Error: {result.status_code}")
|
||||
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
return
|
||||
|
||||
|
||||
# ------------------------------------------------------ KEY ------------------------------------------------------
|
||||
def key(l_args, s_ticker):
|
||||
parser = argparse.ArgumentParser(prog='key',
|
||||
description="""Gives main key metrics about the company (it's a subset of the
|
||||
Overview data from Alpha Vantage API). The following fields are expected:
|
||||
Market capitalization, EBITDA, EPS, PE ratio, PEG ratio, Price to book ratio,
|
||||
Return on equity TTM, Payout ratio, Price to sales ratio TTM, Dividend yield,
|
||||
50 day moving average, Analyst target price, Beta [Source: Alpha Vantage API]""")
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
# Request OVERVIEW data
|
||||
s_req = f"https://www.alphavantage.co/query?function=OVERVIEW&symbol={s_ticker}&apikey={cfg.API_KEY_ALPHAVANTAGE}"
|
||||
result = requests.get(s_req, stream=True)
|
||||
|
||||
# If the returned data was successful
|
||||
if result.status_code == 200:
|
||||
df_fa = json_normalize(result.json())
|
||||
df_fa = df_fa[list(result.json().keys())].T
|
||||
|
||||
df_fa = df_fa.applymap(lambda x: long_number_format(x))
|
||||
df_fa.index = [''.join(' ' + char if char.isupper() else char.strip() for char in idx).strip() for idx in df_fa.index.tolist()]
|
||||
df_fa.index = [s_val.capitalize() for s_val in df_fa.index]
|
||||
df_fa = df_fa.rename(index={"E b i t d a":"EBITDA",
|
||||
"P e ratio":"PE ratio",
|
||||
"P e g ratio":"PEG ratio",
|
||||
"E p s":"EPS",
|
||||
"Return on equity t t m":"Return on equity TTM",
|
||||
"Price to sales ratio t t m":"Price to sales ratio TTM"})
|
||||
as_key_metrics = ["Market capitalization", "EBITDA", "EPS", "PE ratio", "PEG ratio", "Price to book ratio",
|
||||
"Return on equity TTM", "Payout ratio", "Price to sales ratio TTM", "Dividend yield",
|
||||
"50 day moving average", "Analyst target price", "Beta"]
|
||||
print(df_fa.loc[as_key_metrics].to_string(header=False))
|
||||
print("")
|
||||
else:
|
||||
print(f"Error: {result.status_code}")
|
||||
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
return
|
||||
|
||||
|
||||
# ---------------------------------------------------- INCOME_STATEMENT ----------------------------------------------------
|
||||
def income_statement(l_args, s_ticker):
|
||||
parser = argparse.ArgumentParser(prog='income',
|
||||
description="""Collects a complete income statement over time. This can be either quarterly
|
||||
or annually. The following fields are expected: Accepted date, Cost and expenses, Cost of
|
||||
revenue, Depreciation and amortization, Ebitda, Ebitdaratio, Eps, Epsdiluted, Filling date,
|
||||
Final link, General and administrative expenses, Gross profit, Gross profit ratio, Income
|
||||
before tax, Income before tax ratio, Income tax expense, Interest expense, Link, Net income,
|
||||
Net income ratio, Operating expenses, Operating income, Operating income ratio, Other expenses,
|
||||
Period, Research and development expenses, Revenue, Selling and marketing expenses, Total other
|
||||
income expenses net, Weighted average shs out, Weighted average shs out dil [Source: Alpha Vantage API]""")
|
||||
|
||||
parser.add_argument('-n', "--num", action="store", dest="n_num", type=check_positive, default=1, help='Number of latest info')
|
||||
parser.add_argument('-q', "--quarter", action="store_true", default=False, dest="b_quarter", help='Quarter fundamental data')
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
if ns_parser.n_num == 1:
|
||||
pd.set_option('display.max_colwidth', -1)
|
||||
else:
|
||||
pd.options.display.max_colwidth = 40
|
||||
|
||||
fd = FundamentalData(key=cfg.API_KEY_ALPHAVANTAGE, output_format='pandas')
|
||||
if ns_parser.b_quarter:
|
||||
df_fa, d_fd_metadata = fd.get_income_statement_quarterly(symbol=s_ticker)
|
||||
else:
|
||||
df_fa, d_fd_metadata = fd.get_income_statement_annual(symbol=s_ticker)
|
||||
|
||||
df_fa = df_fa.set_index('fiscalDateEnding')
|
||||
df_fa = df_fa.head(n=ns_parser.n_num).T
|
||||
df_fa = df_fa.mask(df_fa.astype(object).eq(ns_parser.n_num*['None'])).dropna()
|
||||
df_fa = df_fa.mask(df_fa.astype(object).eq(ns_parser.n_num*['0'])).dropna()
|
||||
df_fa = df_fa.applymap(lambda x: long_number_format(x))
|
||||
df_fa.index = [''.join(' ' + char if char.isupper() else char.strip() for char in idx).strip() for idx in df_fa.index.tolist()]
|
||||
df_fa.index = [s_val.capitalize() for s_val in df_fa.index]
|
||||
df_fa.columns.name = "Fiscal Date Ending"
|
||||
print(df_fa)
|
||||
print("")
|
||||
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
return
|
||||
|
||||
|
||||
# ---------------------------------------------------- BALANCE_SHEET ----------------------------------------------------
|
||||
def balance_sheet(l_args, s_ticker):
|
||||
parser = argparse.ArgumentParser(prog='balance',
|
||||
description="""Collects a complete balance sheet statement over time. This can be
|
||||
either quarterly or annually. The following fields are expected: Accepted date,
|
||||
Account payables, Accumulated other comprehensive income loss, Cash and cash
|
||||
equivalents, Cash and short term investments, Common stock, Deferred revenue,
|
||||
Deferred revenue non current, Deferred tax liabilities non current, Filling date,
|
||||
Final link, Goodwill, Goodwill and intangible assets, Intangible assets, Inventory,
|
||||
Link, Long term debt, Long term investments, Net debt, Net receivables, Other assets,
|
||||
Other current assets, Other current liabilities, Other liabilities, Other non current
|
||||
assets, Other non current liabilities, Othertotal stockholders equity, Period, Property
|
||||
plant equipment net, Retained earnings, Short term debt, Short term investments, Tax assets,
|
||||
Tax payables, Total assets, Total current assets, Total current liabilities, Total debt,
|
||||
Total investments, Total liabilities, Total liabilities and stockholders equity, Total
|
||||
non current assets, Total non current liabilities, and Total stockholders equity.
|
||||
[Source: Alpha Vantage API]""")
|
||||
|
||||
parser.add_argument('-n', "--num", action="store", dest="n_num", type=check_positive, default=1, help='Number of informations')
|
||||
parser.add_argument('-q', "--quarter", action="store_true", default=False, dest="b_quarter", help='Quarter fundamental data')
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
if ns_parser.n_num == 1:
|
||||
pd.set_option('display.max_colwidth', -1)
|
||||
else:
|
||||
pd.options.display.max_colwidth = 40
|
||||
|
||||
fd = FundamentalData(key=cfg.API_KEY_ALPHAVANTAGE, output_format='pandas')
|
||||
if ns_parser.b_quarter:
|
||||
df_fa, d_fd_metadata = fd.get_balance_sheet_quarterly(symbol=s_ticker)
|
||||
else:
|
||||
df_fa, d_fd_metadata = fd.get_balance_sheet_annual(symbol=s_ticker)
|
||||
|
||||
df_fa = df_fa.set_index('fiscalDateEnding')
|
||||
df_fa = df_fa.head(n=ns_parser.n_num).T
|
||||
df_fa = df_fa.mask(df_fa.astype(object).eq(ns_parser.n_num*['None'])).dropna()
|
||||
df_fa = df_fa.mask(df_fa.astype(object).eq(ns_parser.n_num*['0'])).dropna()
|
||||
df_fa = df_fa.applymap(lambda x: long_number_format(x))
|
||||
df_fa.index = [''.join(' ' + char if char.isupper() else char.strip() for char in idx).strip() for idx in df_fa.index.tolist()]
|
||||
df_fa.index = [s_val.capitalize() for s_val in df_fa.index]
|
||||
df_fa.columns.name = "Fiscal Date Ending"
|
||||
print(df_fa)
|
||||
print("")
|
||||
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
return
|
||||
|
||||
|
||||
# ---------------------------------------------------- CASH_FLOW ----------------------------------------------------
|
||||
def cash_flow(l_args, s_ticker):
|
||||
parser = argparse.ArgumentParser(prog='cash',
|
||||
description="""Collects a complete cash flow statement over time. This can be either
|
||||
quarterly or annually. The following fields are expected: Accepted date, Accounts payables,
|
||||
Accounts receivables, Acquisitions net, Capital expenditure, Cash at beginning of period,
|
||||
Cash at end of period, Change in working capital, Common stock issued, Common stock repurchased,
|
||||
Debt repayment, Deferred income tax, Depreciation and amortization, Dividends paid,
|
||||
Effect of forex changes on cash, Filling date, Final link, Free cash flow, Inventory,
|
||||
Investments in property plant and equipment, Link, Net cash provided by operating activities,
|
||||
Net cash used for investing activites, Net cash used provided by financing activities, Net
|
||||
change in cash, Net income, Operating cash flow, Other financing activites, Other investing
|
||||
activites, Other non cash items, Other working capital, Period, Purchases of investments,
|
||||
Sales maturities of investments, Stock based compensation. [Source: Alpha Vantage API]""")
|
||||
|
||||
parser.add_argument('-n', "--num", action="store", dest="n_num", type=check_positive, default=1, help='Number of informations')
|
||||
parser.add_argument('-q', "--quarter", action="store_true", default=False, dest="b_quarter", help='Quarter fundamental data')
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
if ns_parser.n_num == 1:
|
||||
pd.set_option('display.max_colwidth', -1)
|
||||
else:
|
||||
pd.options.display.max_colwidth = 40
|
||||
|
||||
fd = FundamentalData(key=cfg.API_KEY_ALPHAVANTAGE, output_format='pandas')
|
||||
if ns_parser.b_quarter:
|
||||
df_fa, d_fd_metadata = fd.get_cash_flow_quarterly(symbol=s_ticker)
|
||||
else:
|
||||
df_fa, d_fd_metadata = fd.get_cash_flow_annual(symbol=s_ticker)
|
||||
|
||||
df_fa = df_fa.set_index('fiscalDateEnding')
|
||||
df_fa = df_fa.head(n=ns_parser.n_num).T
|
||||
df_fa = df_fa.mask(df_fa.astype(object).eq(ns_parser.n_num*['None'])).dropna()
|
||||
df_fa = df_fa.mask(df_fa.astype(object).eq(ns_parser.n_num*['0'])).dropna()
|
||||
df_fa = df_fa.applymap(lambda x: long_number_format(x))
|
||||
df_fa.index = [''.join(' ' + char if char.isupper() else char.strip() for char in idx).strip() for idx in df_fa.index.tolist()]
|
||||
df_fa.index = [s_val.capitalize() for s_val in df_fa.index]
|
||||
df_fa.columns.name = "Fiscal Date Ending"
|
||||
print(df_fa)
|
||||
print("")
|
||||
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
return
|
||||
|
||||
|
||||
# ---------------------------------------------------- EARNINGS ----------------------------------------------------
|
||||
def earnings(l_args, s_ticker):
|
||||
parser = argparse.ArgumentParser(prog='earnings',
|
||||
description="""Retrieves earnings dates and reported EPS of the company.
|
||||
The following fields are expected: Fiscal Date Ending and Reported EPS.
|
||||
[Source: Alpha Vantage API]""")
|
||||
|
||||
parser.add_argument('-q', "--quarter", action="store_true", default=False, dest="b_quarter", help='Quarter fundamental data')
|
||||
parser.add_argument('-n', "--num", action="store", dest="n_num", type=check_positive, default=5, help='Number of latest info')
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
if ns_parser.n_num == 1:
|
||||
pd.set_option('display.max_colwidth', -1)
|
||||
else:
|
||||
pd.options.display.max_colwidth = 40
|
||||
|
||||
# Request EARNINGS data from Alpha Vantage API
|
||||
s_req = f"https://www.alphavantage.co/query?function=EARNINGS&symbol={s_ticker}&apikey={cfg.API_KEY_FINANCIALMODELINGPREP}"
|
||||
result = requests.get(s_req, stream=True)
|
||||
|
||||
# If the returned data was successful
|
||||
if result.status_code == 200:
|
||||
df_fa = json_normalize(result.json())
|
||||
if ns_parser.b_quarter:
|
||||
df_fa = pd.DataFrame(df_fa['quarterlyEarnings'][0])
|
||||
df_fa = df_fa[["fiscalDateEnding", "reportedDate", "reportedEPS", "estimatedEPS", "surprise", "surprisePercentage"]]
|
||||
df_fa = df_fa.rename(columns={"fiscalDateEnding":"Fiscal Date Ending",
|
||||
"reportedEPS":"Reported EPS",
|
||||
"estimatedEPS":"Estimated EPS",
|
||||
"reportedDate":"Reported Date",
|
||||
"surprise":"Surprise",
|
||||
"surprisePercentage":"Suprise Percentage"})
|
||||
else:
|
||||
df_fa = pd.DataFrame(df_fa['annualEarnings'][0])
|
||||
df_fa = df_fa.rename(columns={"fiscalDateEnding":"Fiscal Date Ending",
|
||||
"reportedEPS":"Reported EPS"})
|
||||
|
||||
print(df_fa.head(n=ns_parser.n_num).T.to_string(header=False))
|
||||
print("")
|
||||
else:
|
||||
print(f"Error: {result.status_code}")
|
||||
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
return
|
||||
@@ -1,161 +1,10 @@
|
||||
import FundamentalAnalysis as fa
|
||||
from alpha_vantage.fundamentaldata import FundamentalData
|
||||
import FundamentalAnalysis as fa # Financial Modeling Prep
|
||||
import config_bot as cfg
|
||||
import argparse
|
||||
import datetime
|
||||
from datetime import datetime
|
||||
from stock_market_helper_funcs import *
|
||||
import pandas as pd
|
||||
import json
|
||||
import requests
|
||||
from pandas.io.json import json_normalize
|
||||
|
||||
|
||||
# ---------------------------------------------------- INFO ----------------------------------------------------
|
||||
def info(l_args, s_ticker):
|
||||
parser = argparse.ArgumentParser(prog='info',
|
||||
description="""Provides information about main key metrics. Namely: EBITDA,
|
||||
EPS, P/E, PEG, FCF, P/B, ROE, DPR, P/S, Dividend Yield Ratio, D/E, and Beta.""")
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
except SystemExit:
|
||||
print("")
|
||||
return
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
try:
|
||||
filepath = 'fundamental_analysis_indicators_explained.txt'
|
||||
with open(filepath) as fp:
|
||||
line = fp.readline()
|
||||
while line:
|
||||
print("{}".format(line.strip()))
|
||||
line = fp.readline()
|
||||
print("")
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
|
||||
|
||||
# ---------------------------------------------------- OVERVIEW ----------------------------------------------------
|
||||
def overview(l_args, s_ticker):
|
||||
parser = argparse.ArgumentParser(prog='overview',
|
||||
description="""Gives an overview about the company. The following fields are expected:
|
||||
Symbol, Asset type, Name, Description, Exchange, Currency, Country, Sector, Industry,
|
||||
Address, Full time employees, Fiscal year end, Latest quarter, Market capitalization,
|
||||
EBITDA, PE ratio, PEG ratio, Book value, Dividend per share, Dividend yield, EPS,
|
||||
Revenue per share TTM, Profit margin, Operating margin TTM, Return on assets TTM,
|
||||
Return on equity TTM, Revenue TTM, Gross profit TTM, Diluted EPS TTM, Quarterly earnings growth YOY,
|
||||
Quarterly revenue growth YOY, Analyst target price, Trailing PE, Forward PE,
|
||||
Price to sales ratio TTM, Price to book ratio, EV to revenue, EV to EBITDA, Beta, 52 week high,
|
||||
52 week low, 50 day moving average, 200 day moving average, Shares outstanding, Shares float,
|
||||
Shares short, Shares short prior month, Short ratio, Short percent outstanding, Short percent float,
|
||||
Percent insiders, Percent institutions, Forward annual dividend rate, Forward annual dividend yield,
|
||||
Payout ratio, Dividend date, Ex dividend date, Last split factor, and Last split date.
|
||||
[Source: Alpha Vantage API]""")
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
except SystemExit:
|
||||
print("")
|
||||
return
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
try:
|
||||
# Request OVERVIEW data from Alpha Vantage API
|
||||
s_req = f"https://www.alphavantage.co/query?function=OVERVIEW&symbol={s_ticker}&apikey={cfg.API_KEY_FINANCIALMODELINGPREP}"
|
||||
result = requests.get(s_req, stream=True)
|
||||
|
||||
# If the returned data was successful
|
||||
if result.status_code == 200:
|
||||
# Parse json data to dataframe
|
||||
df_fa = json_normalize(result.json())
|
||||
# Keep json data sorting in dataframe
|
||||
df_fa = df_fa[list(result.json().keys())].T
|
||||
df_fa = df_fa.applymap(lambda x: long_number_format(x))
|
||||
df_fa.index = [''.join(' ' + char if char.isupper() else char.strip() for char in idx).strip() for idx in df_fa.index.tolist()]
|
||||
df_fa.index = [s_val.capitalize() for s_val in df_fa.index]
|
||||
df_fa = df_fa.rename(index={"E b i t d a":"EBITDA",
|
||||
"P e ratio":"PE ratio",
|
||||
"P e g ratio":"PEG ratio",
|
||||
"E p s":"EPS",
|
||||
"Revenue per share t t m":"Revenue per share TTM",
|
||||
"Operating margin t t m":"Operating margin TTM",
|
||||
"Return on assets t t m":"Return on assets TTM",
|
||||
"Return on equity t t m":"Return on equity TTM",
|
||||
"Revenue t t m":"Revenue TTM",
|
||||
"Gross profit t t m":"Gross profit TTM",
|
||||
"Diluted e p s t t m":"Diluted EPS TTM",
|
||||
"Quarterly earnings growth y o y":"Quarterly earnings growth YOY",
|
||||
"Quarterly revenue growth y o y":"Quarterly revenue growth YOY",
|
||||
"Trailing p e":"Trailing PE",
|
||||
"Forward p e":"Forward PE",
|
||||
"Price to sales ratio t t m":"Price to sales ratio TTM",
|
||||
"E v to revenue":"EV to revenue",
|
||||
"E v to e b i t d a":"EV to EBITDA"})
|
||||
|
||||
pd.set_option('display.max_colwidth', -1)
|
||||
|
||||
print(df_fa.drop(index=['Description']).to_string(header=False))
|
||||
print(f"Description: {df_fa.loc['Description'][0]}")
|
||||
print("")
|
||||
else:
|
||||
print(f"Error: {result.status_code}")
|
||||
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
|
||||
|
||||
# ------------------------------------------------------ KEY ------------------------------------------------------
|
||||
def key(l_args, s_ticker):
|
||||
parser = argparse.ArgumentParser(prog='key',
|
||||
description="""Gives main key metrics about the company (it's a subset of the
|
||||
Overview data from Alpha Vantage API). The following fields are expected:
|
||||
Market capitalization, EBITDA, EPS, PE ratio, PEG ratio, Price to book ratio,
|
||||
Return on equity TTM, Payout ratio, Price to sales ratio TTM, Dividend yield,
|
||||
50 day moving average, Analyst target price, Beta [Source: Alpha Vantage API]""")
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
except SystemExit:
|
||||
print("")
|
||||
return
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
try:
|
||||
# Request OVERVIEW data
|
||||
s_req = f"https://www.alphavantage.co/query?function=OVERVIEW&symbol={s_ticker}&apikey={cfg.API_KEY_ALPHAVANTAGE}"
|
||||
result = requests.get(s_req, stream=True)
|
||||
|
||||
# If the returned data was successful
|
||||
if result.status_code == 200:
|
||||
df_fa = json_normalize(result.json())
|
||||
df_fa = df_fa[list(result.json().keys())].T
|
||||
|
||||
df_fa = df_fa.applymap(lambda x: long_number_format(x))
|
||||
df_fa.index = [''.join(' ' + char if char.isupper() else char.strip() for char in idx).strip() for idx in df_fa.index.tolist()]
|
||||
df_fa.index = [s_val.capitalize() for s_val in df_fa.index]
|
||||
df_fa = df_fa.rename(index={"E b i t d a":"EBITDA",
|
||||
"P e ratio":"PE ratio",
|
||||
"P e g ratio":"PEG ratio",
|
||||
"E p s":"EPS",
|
||||
"Return on equity t t m":"Return on equity TTM",
|
||||
"Price to sales ratio t t m":"Price to sales ratio TTM"})
|
||||
as_key_metrics = ["Market capitalization", "EBITDA", "EPS", "PE ratio", "PEG ratio", "Price to book ratio",
|
||||
"Return on equity TTM", "Payout ratio", "Price to sales ratio TTM", "Dividend yield",
|
||||
"50 day moving average", "Analyst target price", "Beta"]
|
||||
print(df_fa.loc[as_key_metrics].to_string(header=False))
|
||||
print("")
|
||||
else:
|
||||
print(f"Error: {result.status_code}")
|
||||
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
|
||||
|
||||
# ---------------------------------------------------- PROFILE ----------------------------------------------------
|
||||
@@ -170,14 +19,10 @@ def profile(l_args, s_ticker):
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
except SystemExit:
|
||||
print("")
|
||||
return
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
try:
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
df_fa = fa.profile(s_ticker, cfg.API_KEY_FINANCIALMODELINGPREP)
|
||||
df_fa.index = [''.join(' ' + char if char.isupper() else char.strip() for char in idx).strip() for idx in df_fa.index.tolist()]
|
||||
df_fa.index = [s_val.capitalize() for s_val in df_fa.index]
|
||||
@@ -185,9 +30,11 @@ def profile(l_args, s_ticker):
|
||||
print(f"\nImage: {df_fa.loc['Image'][0]}")
|
||||
print(f"\nDescription: {df_fa.loc['Description'][0]}")
|
||||
print("")
|
||||
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
|
||||
return
|
||||
|
||||
|
||||
# ---------------------------------------------------- RATING ----------------------------------------------------
|
||||
def rating(l_args, s_ticker):
|
||||
@@ -198,21 +45,19 @@ def rating(l_args, s_ticker):
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
except SystemExit:
|
||||
print("")
|
||||
return
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
try:
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
df_fa = fa.rating(s_ticker, cfg.API_KEY_FINANCIALMODELINGPREP)
|
||||
print(df_fa)
|
||||
print("")
|
||||
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
return
|
||||
|
||||
|
||||
|
||||
# ---------------------------------------------------- QUOTE ----------------------------------------------------
|
||||
def quote(l_args, s_ticker):
|
||||
parser = argparse.ArgumentParser(prog='quote',
|
||||
@@ -225,14 +70,10 @@ def quote(l_args, s_ticker):
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
except SystemExit:
|
||||
print("")
|
||||
return
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
try:
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
df_fa = fa.quote(s_ticker, cfg.API_KEY_FINANCIALMODELINGPREP)
|
||||
df_fa.index = [''.join(' ' + char if char.isupper() else char.strip() for char in idx).strip() for idx in df_fa.index.tolist()]
|
||||
df_fa.index = [s_val.capitalize() for s_val in df_fa.index]
|
||||
@@ -243,9 +84,11 @@ def quote(l_args, s_ticker):
|
||||
df_fa.loc['Earnings announcement'][0] = f"{earning_announcment.date()} {earning_announcment.time()}"
|
||||
print(df_fa.to_string(header=False))
|
||||
print("")
|
||||
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
|
||||
return
|
||||
|
||||
|
||||
# ---------------------------------------------------- ENTERPRISE ----------------------------------------------------
|
||||
def enterprise(l_args, s_ticker):
|
||||
@@ -260,19 +103,15 @@ def enterprise(l_args, s_ticker):
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
except SystemExit:
|
||||
print("")
|
||||
return
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
if ns_parser.n_num == 1:
|
||||
pd.set_option('display.max_colwidth', -1)
|
||||
else:
|
||||
pd.options.display.max_colwidth = 40
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
if ns_parser.n_num == 1:
|
||||
pd.set_option('display.max_colwidth', -1)
|
||||
else:
|
||||
pd.options.display.max_colwidth = 40
|
||||
|
||||
try:
|
||||
if ns_parser.b_quarter:
|
||||
df_fa = fa.enterprise(s_ticker, cfg.API_KEY_FINANCIALMODELINGPREP, period='quarter')
|
||||
else:
|
||||
@@ -284,8 +123,10 @@ def enterprise(l_args, s_ticker):
|
||||
df_fa.index = [s_val.capitalize() for s_val in df_fa.index]
|
||||
print(df_fa)
|
||||
print("")
|
||||
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
return
|
||||
|
||||
|
||||
# ------------------------------------------ DISCOUNTED CASH FLOW ------------------------------------------------------
|
||||
@@ -299,19 +140,15 @@ def discounted_cash_flow(l_args, s_ticker):
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
except SystemExit:
|
||||
print("")
|
||||
return
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
if ns_parser.n_num == 1:
|
||||
pd.set_option('display.max_colwidth', -1)
|
||||
else:
|
||||
pd.options.display.max_colwidth = 40
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
if ns_parser.n_num == 1:
|
||||
pd.set_option('display.max_colwidth', -1)
|
||||
else:
|
||||
pd.options.display.max_colwidth = 40
|
||||
|
||||
try:
|
||||
if ns_parser.b_quarter:
|
||||
df_fa = fa.discounted_cash_flow(s_ticker, cfg.API_KEY_FINANCIALMODELINGPREP, period='quarter')
|
||||
else:
|
||||
@@ -324,58 +161,10 @@ def discounted_cash_flow(l_args, s_ticker):
|
||||
df_fa = df_fa.rename(index={"D c f": "DCF"})
|
||||
print(df_fa)
|
||||
print("")
|
||||
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
|
||||
|
||||
# ---------------------------------------------------- EARNINGS ----------------------------------------------------
|
||||
def earnings(l_args, s_ticker):
|
||||
parser = argparse.ArgumentParser(prog='earnings',
|
||||
description="""Retrieves earnings dates and reported EPS of the company.
|
||||
The following fields are expected: Fiscal Date Ending and Reported EPS.
|
||||
[Source: Alpha Vantage API]""")
|
||||
|
||||
parser.add_argument('-q', "--quarter", action="store_true", default=False, dest="b_quarter", help='Quarter fundamental data')
|
||||
parser.add_argument('-n', "--num", action="store", dest="n_num", type=check_positive, default=5, help='Number of latest info')
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
except SystemExit:
|
||||
print("")
|
||||
return
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
try:
|
||||
# Request EARNINGS data from Alpha Vantage API
|
||||
s_req = f"https://www.alphavantage.co/query?function=EARNINGS&symbol={s_ticker}&apikey={cfg.API_KEY_FINANCIALMODELINGPREP}"
|
||||
result = requests.get(s_req, stream=True)
|
||||
|
||||
# If the returned data was successful
|
||||
if result.status_code == 200:
|
||||
df_fa = json_normalize(result.json())
|
||||
if ns_parser.b_quarter:
|
||||
df_fa = pd.DataFrame(df_fa['quarterlyEarnings'][0])
|
||||
df_fa = df_fa[["fiscalDateEnding", "reportedDate", "reportedEPS", "estimatedEPS", "surprise", "surprisePercentage"]]
|
||||
df_fa = df_fa.rename(columns={"fiscalDateEnding":"Fiscal Date Ending",
|
||||
"reportedEPS":"Reported EPS",
|
||||
"estimatedEPS":"Estimated EPS",
|
||||
"reportedDate":"Reported Date",
|
||||
"surprise":"Surprise",
|
||||
"surprisePercentage":"Suprise Percentage"})
|
||||
else:
|
||||
df_fa = pd.DataFrame(df_fa['annualEarnings'][0])
|
||||
df_fa = df_fa.rename(columns={"fiscalDateEnding":"Fiscal Date Ending",
|
||||
"reportedEPS":"Reported EPS"})
|
||||
|
||||
print(df_fa.head(n=ns_parser.n_num).T.to_string(header=False))
|
||||
print("")
|
||||
else:
|
||||
print(f"Error: {result.status_code}")
|
||||
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
|
||||
|
||||
# ---------------------------------------------------- INCOME_STATEMENT ----------------------------------------------------
|
||||
@@ -388,71 +177,48 @@ def income_statement(l_args, s_ticker):
|
||||
before tax, Income before tax ratio, Income tax expense, Interest expense, Link, Net income,
|
||||
Net income ratio, Operating expenses, Operating income, Operating income ratio, Other expenses,
|
||||
Period, Research and development expenses, Revenue, Selling and marketing expenses, Total other
|
||||
income expenses net, Weighted average shs out, Weighted average shs out dil [Default source:
|
||||
Alpha Vantage API; Other possible source: Financial Modeling Prep API]""")
|
||||
income expenses net, Weighted average shs out, Weighted average shs out dil
|
||||
[Source: Financial Modeling Prep API]""")
|
||||
|
||||
parser.add_argument('-n', "--num", action="store", dest="n_num", type=check_positive, default=1, help='Number of latest info')
|
||||
parser.add_argument('-q', "--quarter", action="store_true", default=False, dest="b_quarter", help='Quarter fundamental data')
|
||||
parser.add_argument('--fmp', action="store_true", default=False, dest="b_fmp", help='Use Financial Modeling Prep instead of Alpha Vantage')
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
except SystemExit:
|
||||
print("")
|
||||
return
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
try:
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
if ns_parser.n_num == 1:
|
||||
pd.set_option('display.max_colwidth', -1)
|
||||
else:
|
||||
pd.options.display.max_colwidth = 40
|
||||
|
||||
# Use Financial Modeling Prep API
|
||||
if ns_parser.b_fmp:
|
||||
if ns_parser.b_quarter:
|
||||
df_fa = fa.income_statement(s_ticker, cfg.API_KEY_FINANCIALMODELINGPREP, period='quarter')
|
||||
else:
|
||||
df_fa = fa.income_statement(s_ticker, cfg.API_KEY_FINANCIALMODELINGPREP)
|
||||
|
||||
df_fa = df_fa.iloc[:, 0:ns_parser.n_num]
|
||||
df_fa = df_fa.mask(df_fa.astype(object).eq(ns_parser.n_num*['None'])).dropna()
|
||||
df_fa = df_fa.mask(df_fa.astype(object).eq(ns_parser.n_num*['0'])).dropna()
|
||||
df_fa = df_fa.applymap(lambda x: long_number_format(x))
|
||||
df_fa.index = [''.join(' ' + char if char.isupper() else char.strip() for char in idx).strip() for idx in df_fa.index.tolist()]
|
||||
df_fa.index = [s_val.capitalize() for s_val in df_fa.index]
|
||||
df_fa.columns.name = "Fiscal Date Ending"
|
||||
print(df_fa.drop(index=['Final link', 'Link']).to_string())
|
||||
|
||||
pd.set_option('display.max_colwidth', -1)
|
||||
print("")
|
||||
print(df_fa.loc['Final link'].to_frame().to_string())
|
||||
print("")
|
||||
print(df_fa.loc['Link'].to_frame().to_string())
|
||||
|
||||
# Use Alpha Vantage API
|
||||
if ns_parser.b_quarter:
|
||||
df_fa = fa.income_statement(s_ticker, cfg.API_KEY_FINANCIALMODELINGPREP, period='quarter')
|
||||
else:
|
||||
fd = FundamentalData(key=cfg.API_KEY_ALPHAVANTAGE, output_format='pandas')
|
||||
if ns_parser.b_quarter:
|
||||
df_fa, d_fd_metadata = fd.get_income_statement_quarterly(symbol=s_ticker)
|
||||
else:
|
||||
df_fa, d_fd_metadata = fd.get_income_statement_annual(symbol=s_ticker)
|
||||
df_fa = fa.income_statement(s_ticker, cfg.API_KEY_FINANCIALMODELINGPREP)
|
||||
|
||||
df_fa = df_fa.set_index('fiscalDateEnding')
|
||||
df_fa = df_fa.head(n=ns_parser.n_num).T
|
||||
df_fa = df_fa.mask(df_fa.astype(object).eq(ns_parser.n_num*['None'])).dropna()
|
||||
df_fa = df_fa.mask(df_fa.astype(object).eq(ns_parser.n_num*['0'])).dropna()
|
||||
df_fa = df_fa.applymap(lambda x: long_number_format(x))
|
||||
df_fa.index = [''.join(' ' + char if char.isupper() else char.strip() for char in idx).strip() for idx in df_fa.index.tolist()]
|
||||
df_fa.index = [s_val.capitalize() for s_val in df_fa.index]
|
||||
df_fa.columns.name = "Fiscal Date Ending"
|
||||
print(df_fa)
|
||||
df_fa = df_fa.iloc[:, 0:ns_parser.n_num]
|
||||
df_fa = df_fa.mask(df_fa.astype(object).eq(ns_parser.n_num*['None'])).dropna()
|
||||
df_fa = df_fa.mask(df_fa.astype(object).eq(ns_parser.n_num*['0'])).dropna()
|
||||
df_fa = df_fa.applymap(lambda x: long_number_format(x))
|
||||
df_fa.index = [''.join(' ' + char if char.isupper() else char.strip() for char in idx).strip() for idx in df_fa.index.tolist()]
|
||||
df_fa.index = [s_val.capitalize() for s_val in df_fa.index]
|
||||
df_fa.columns.name = "Fiscal Date Ending"
|
||||
print(df_fa.drop(index=['Final link', 'Link']).to_string())
|
||||
|
||||
pd.set_option('display.max_colwidth', -1)
|
||||
print("")
|
||||
print(df_fa.loc['Final link'].to_frame().to_string())
|
||||
print("")
|
||||
print(df_fa.loc['Link'].to_frame().to_string())
|
||||
print("")
|
||||
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
return
|
||||
|
||||
|
||||
# ---------------------------------------------------- BALANCE_SHEET ----------------------------------------------------
|
||||
def balance_sheet(l_args, s_ticker):
|
||||
@@ -470,68 +236,48 @@ def balance_sheet(l_args, s_ticker):
|
||||
Tax payables, Total assets, Total current assets, Total current liabilities, Total debt,
|
||||
Total investments, Total liabilities, Total liabilities and stockholders equity, Total
|
||||
non current assets, Total non current liabilities, and Total stockholders equity.
|
||||
[Default source: Alpha Vantage API; Other possible source: Financial Modeling Prep API]""")
|
||||
[Source: Financial Modeling Prep API]""")
|
||||
|
||||
parser.add_argument('-n', "--num", action="store", dest="n_num", type=check_positive, default=1, help='Number of informations')
|
||||
parser.add_argument('-q', "--quarter", action="store_true", default=False, dest="b_quarter", help='Quarter fundamental data')
|
||||
parser.add_argument('--fmp', action="store_true", default=False, dest="b_fmp", help='Use Financial Modeling Prep instead of Alpha Vantage')
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
except SystemExit:
|
||||
print("")
|
||||
return
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
try:
|
||||
# Use Financial Modeling Prep API
|
||||
if ns_parser.b_fmp:
|
||||
if ns_parser.b_quarter:
|
||||
df_fa = fa.balance_sheet_statement(s_ticker, cfg.API_KEY_FINANCIALMODELINGPREP, period='quarter')
|
||||
else:
|
||||
df_fa = fa.balance_sheet_statement(s_ticker, cfg.API_KEY_FINANCIALMODELINGPREP)
|
||||
|
||||
df_fa = df_fa.iloc[:, 0:ns_parser.n_num]
|
||||
df_fa = df_fa.mask(df_fa.astype(object).eq(ns_parser.n_num*['None'])).dropna()
|
||||
df_fa = df_fa.mask(df_fa.astype(object).eq(ns_parser.n_num*['0'])).dropna()
|
||||
df_fa = df_fa.applymap(lambda x: long_number_format(x))
|
||||
df_fa.index = [''.join(' ' + char if char.isupper() else char.strip() for char in idx).strip() for idx in df_fa.index.tolist()]
|
||||
df_fa.index = [s_val.capitalize() for s_val in df_fa.index]
|
||||
df_fa.columns.name = "Fiscal Date Ending"
|
||||
print(df_fa.drop(index=['Final link', 'Link']).to_string())
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
if ns_parser.n_num == 1:
|
||||
pd.set_option('display.max_colwidth', -1)
|
||||
print("")
|
||||
print(df_fa.loc['Final link'].to_frame().to_string())
|
||||
print("")
|
||||
print(df_fa.loc['Link'].to_frame().to_string())
|
||||
|
||||
# Use Alpha Vantage API
|
||||
else:
|
||||
fd = FundamentalData(key=cfg.API_KEY_ALPHAVANTAGE, output_format='pandas')
|
||||
if ns_parser.b_quarter:
|
||||
df_fa, d_fd_metadata = fd.get_balance_sheet_quarterly(symbol=s_ticker)
|
||||
else:
|
||||
df_fa, d_fd_metadata = fd.get_balance_sheet_annual(symbol=s_ticker)
|
||||
|
||||
df_fa = df_fa.set_index('fiscalDateEnding')
|
||||
df_fa = df_fa.head(n=ns_parser.n_num).T
|
||||
df_fa = df_fa.mask(df_fa.astype(object).eq(ns_parser.n_num*['None'])).dropna()
|
||||
df_fa = df_fa.mask(df_fa.astype(object).eq(ns_parser.n_num*['0'])).dropna()
|
||||
df_fa = df_fa.applymap(lambda x: long_number_format(x))
|
||||
df_fa.index = [''.join(' ' + char if char.isupper() else char.strip() for char in idx).strip() for idx in df_fa.index.tolist()]
|
||||
df_fa.index = [s_val.capitalize() for s_val in df_fa.index]
|
||||
df_fa.columns.name = "Fiscal Date Ending"
|
||||
print(df_fa)
|
||||
pd.options.display.max_colwidth = 40
|
||||
|
||||
if ns_parser.b_quarter:
|
||||
df_fa = fa.balance_sheet_statement(s_ticker, cfg.API_KEY_FINANCIALMODELINGPREP, period='quarter')
|
||||
else:
|
||||
df_fa = fa.balance_sheet_statement(s_ticker, cfg.API_KEY_FINANCIALMODELINGPREP)
|
||||
|
||||
df_fa = df_fa.iloc[:, 0:ns_parser.n_num]
|
||||
df_fa = df_fa.mask(df_fa.astype(object).eq(ns_parser.n_num*['None'])).dropna()
|
||||
df_fa = df_fa.mask(df_fa.astype(object).eq(ns_parser.n_num*['0'])).dropna()
|
||||
df_fa = df_fa.applymap(lambda x: long_number_format(x))
|
||||
df_fa.index = [''.join(' ' + char if char.isupper() else char.strip() for char in idx).strip() for idx in df_fa.index.tolist()]
|
||||
df_fa.index = [s_val.capitalize() for s_val in df_fa.index]
|
||||
df_fa.columns.name = "Fiscal Date Ending"
|
||||
print(df_fa.drop(index=['Final link', 'Link']).to_string())
|
||||
|
||||
pd.set_option('display.max_colwidth', -1)
|
||||
print("")
|
||||
print(df_fa.loc['Final link'].to_frame().to_string())
|
||||
print("")
|
||||
print(df_fa.loc['Link'].to_frame().to_string())
|
||||
print("")
|
||||
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
return
|
||||
|
||||
|
||||
|
||||
# ---------------------------------------------------- CASH_FLOW ----------------------------------------------------
|
||||
def cash_flow(l_args, s_ticker):
|
||||
parser = argparse.ArgumentParser(prog='cash',
|
||||
@@ -545,72 +291,47 @@ def cash_flow(l_args, s_ticker):
|
||||
Net cash used for investing activites, Net cash used provided by financing activities, Net
|
||||
change in cash, Net income, Operating cash flow, Other financing activites, Other investing
|
||||
activites, Other non cash items, Other working capital, Period, Purchases of investments,
|
||||
Sales maturities of investments, Stock based compensation. [Default source: Alpha Vantage API;
|
||||
Other possible source: Financial Modeling Prep API]""")
|
||||
Sales maturities of investments, Stock based compensation. [Source: Financial Modeling Prep API]""")
|
||||
|
||||
parser.add_argument('-n', "--num", action="store", dest="n_num", type=check_positive, default=1, help='Number of informations')
|
||||
parser.add_argument('-q', "--quarter", action="store_true", default=False, dest="b_quarter", help='Quarter fundamental data')
|
||||
parser.add_argument('--fmp', action="store_true", default=False, dest="b_fmp", help='Use Financial Modeling Prep instead of Alpha Vantage')
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
except SystemExit:
|
||||
print("")
|
||||
return
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
try:
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
if ns_parser.n_num == 1:
|
||||
pd.set_option('display.max_colwidth', -1)
|
||||
else:
|
||||
pd.options.display.max_colwidth = 40
|
||||
|
||||
# Use Financial Modeling Prep API
|
||||
if ns_parser.b_fmp:
|
||||
if ns_parser.b_quarter:
|
||||
df_fa = fa.cash_flow_statement(s_ticker, cfg.API_KEY_FINANCIALMODELINGPREP, period='quarter')
|
||||
else:
|
||||
df_fa = fa.cash_flow_statement(s_ticker, cfg.API_KEY_FINANCIALMODELINGPREP)
|
||||
|
||||
df_fa = df_fa.iloc[:, 0:ns_parser.n_num]
|
||||
df_fa = df_fa.mask(df_fa.astype(object).eq(ns_parser.n_num*['None'])).dropna()
|
||||
df_fa = df_fa.mask(df_fa.astype(object).eq(ns_parser.n_num*['0'])).dropna()
|
||||
df_fa = df_fa.applymap(lambda x: long_number_format(x))
|
||||
df_fa.index = [''.join(' ' + char if char.isupper() else char.strip() for char in idx).strip() for idx in df_fa.index.tolist()]
|
||||
df_fa.index = [s_val.capitalize() for s_val in df_fa.index]
|
||||
df_fa.columns.name = "Fiscal Date Ending"
|
||||
print(df_fa.drop(index=['Final link', 'Link']).to_string())
|
||||
|
||||
pd.set_option('display.max_colwidth', -1)
|
||||
print("")
|
||||
print(df_fa.loc['Final link'].to_frame().to_string())
|
||||
print("")
|
||||
print(df_fa.loc['Link'].to_frame().to_string())
|
||||
# Use Alpha Vantage API
|
||||
if ns_parser.b_quarter:
|
||||
df_fa = fa.cash_flow_statement(s_ticker, cfg.API_KEY_FINANCIALMODELINGPREP, period='quarter')
|
||||
else:
|
||||
fd = FundamentalData(key=cfg.API_KEY_ALPHAVANTAGE, output_format='pandas')
|
||||
if ns_parser.b_quarter:
|
||||
df_fa, d_fd_metadata = fd.get_cash_flow_quarterly(symbol=s_ticker)
|
||||
else:
|
||||
df_fa, d_fd_metadata = fd.get_cash_flow_annual(symbol=s_ticker)
|
||||
df_fa = fa.cash_flow_statement(s_ticker, cfg.API_KEY_FINANCIALMODELINGPREP)
|
||||
|
||||
df_fa = df_fa.set_index('fiscalDateEnding')
|
||||
df_fa = df_fa.head(n=ns_parser.n_num).T
|
||||
df_fa = df_fa.mask(df_fa.astype(object).eq(ns_parser.n_num*['None'])).dropna()
|
||||
df_fa = df_fa.mask(df_fa.astype(object).eq(ns_parser.n_num*['0'])).dropna()
|
||||
df_fa = df_fa.applymap(lambda x: long_number_format(x))
|
||||
df_fa.index = [''.join(' ' + char if char.isupper() else char.strip() for char in idx).strip() for idx in df_fa.index.tolist()]
|
||||
df_fa.index = [s_val.capitalize() for s_val in df_fa.index]
|
||||
df_fa.columns.name = "Fiscal Date Ending"
|
||||
print(df_fa)
|
||||
df_fa = df_fa.iloc[:, 0:ns_parser.n_num]
|
||||
df_fa = df_fa.mask(df_fa.astype(object).eq(ns_parser.n_num*['None'])).dropna()
|
||||
df_fa = df_fa.mask(df_fa.astype(object).eq(ns_parser.n_num*['0'])).dropna()
|
||||
df_fa = df_fa.applymap(lambda x: long_number_format(x))
|
||||
df_fa.index = [''.join(' ' + char if char.isupper() else char.strip() for char in idx).strip() for idx in df_fa.index.tolist()]
|
||||
df_fa.index = [s_val.capitalize() for s_val in df_fa.index]
|
||||
df_fa.columns.name = "Fiscal Date Ending"
|
||||
print(df_fa.drop(index=['Final link', 'Link']).to_string())
|
||||
|
||||
pd.set_option('display.max_colwidth', -1)
|
||||
print("")
|
||||
print(df_fa.loc['Final link'].to_frame().to_string())
|
||||
print("")
|
||||
print(df_fa.loc['Link'].to_frame().to_string())
|
||||
print("")
|
||||
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
return
|
||||
|
||||
|
||||
|
||||
# ---------------------------------------------------- KEY_METRICS ----------------------------------------------------
|
||||
def key_metrics(l_args, s_ticker):
|
||||
@@ -637,14 +358,10 @@ def key_metrics(l_args, s_ticker):
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
except SystemExit:
|
||||
print("")
|
||||
return
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
try:
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
if ns_parser.n_num == 1:
|
||||
pd.set_option('display.max_colwidth', -1)
|
||||
else:
|
||||
@@ -666,10 +383,11 @@ def key_metrics(l_args, s_ticker):
|
||||
df_fa = df_fa.rename(index={"Net debt to e b i t d a": "Net debt to EBITDA"})
|
||||
print(df_fa)
|
||||
print("")
|
||||
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
return
|
||||
|
||||
|
||||
|
||||
# ---------------------------------------------------- FINANCIAL_RATIOS ----------------------------------------------------
|
||||
def financial_ratios(l_args, s_ticker):
|
||||
@@ -697,14 +415,10 @@ def financial_ratios(l_args, s_ticker):
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
except SystemExit:
|
||||
print("")
|
||||
return
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
try:
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
if ns_parser.n_num == 1:
|
||||
pd.set_option('display.max_colwidth', -1)
|
||||
else:
|
||||
@@ -723,9 +437,9 @@ def financial_ratios(l_args, s_ticker):
|
||||
df_fa.index = [s_val.capitalize() for s_val in df_fa.index]
|
||||
df_fa.columns.name = "Fiscal Date Ending"
|
||||
df_fa = df_fa.rename(index={"Net income per e b t": "Net income per EBT"})
|
||||
|
||||
print(df_fa)
|
||||
print("")
|
||||
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
return
|
||||
@@ -754,14 +468,10 @@ def financial_statement_growth(l_args, s_ticker):
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
except SystemExit:
|
||||
print("")
|
||||
return
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
try:
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
if ns_parser.n_num == 1:
|
||||
pd.set_option('display.max_colwidth', -1)
|
||||
else:
|
||||
@@ -782,6 +492,8 @@ def financial_statement_growth(l_args, s_ticker):
|
||||
|
||||
print(df_fa)
|
||||
print("")
|
||||
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
return
|
||||
|
||||
35
fundamental_analysis/key_metrics_explained.txt
Normal file
35
fundamental_analysis/key_metrics_explained.txt
Normal file
@@ -0,0 +1,35 @@
|
||||
EBITDA
|
||||
Earnings (net income) before interest, taxes, depreciation, and amortisation. EBITDA can be used to analyse and compare profitability among companies and industries, as it eliminates the effects of financing and capital expenditures.
|
||||
|
||||
EARNINGS PER SHARE (EPS)
|
||||
This is the portion of a company’s profit that is assigned to each share of its stock. It’s essentially the bottom line net income, just on a per-share basis. A growing EPS is a good sign to investors because it means that their shares are likely to be worth more.
|
||||
|
||||
PRICE TO EARNINGS RATIO (P/E)
|
||||
The price-to-earnings ratio measures the relationship between the stock price of a company and its per-share earnings. It helps investors determine if a stock is undervalued or overvalued relative to others in the same sector. Since the P/E ratio shows what the market is willing to pay today for a stock based on its past or future earnings, investors simply compare the P/E ratio of a stock to those of its competitors and industry standards. A lower P/E ratio means the current stock price is low relative to earnings, which is favourable to investors.
|
||||
|
||||
PROJECTED EARNINGS GROWTH (PEG)
|
||||
The P/E ratio is a good fundamental analysis indicator but is somewhat limited by the fact that it doesn’t include future earnings growth. The PEG compensates for this by anticipating the one-year earnings growth rate of the stock. Analysts can estimate the future growth rate of a company by looking at its historical growth rate. This provides a more complete picture of a stock’s valuation. To calculate Projected Earnings Growth, divide the P/E ratio by the company’s 12-month growth rate. The percentage in growth rate is removed in the calculation.
|
||||
|
||||
FREE CASH FLOW (FCF)
|
||||
In simplest terms, Free Cash Flow is the cash left over after a company has paid for its operating expenses and capital expenditures. Cash is critical to the sustenance and amelioration of a business. Companies with high free cash flow can improve shareholder value, fund innovation, and survive downturns better than their less-liquid counterparts. Many investors cherish FCF as a fundamental indicator because it shows whether a company still has enough cash to reward its shareholders through dividends after funding operations and capital expenditures. Here's where this can be useful, if a company's P/E ratio makes it look excessively cheap or expensive, calculating the company's free cash flow can help you understand why.
|
||||
|
||||
PRICE TO BOOK RATIO (P/B)
|
||||
Also known as the price to equity ratio, the price-to-book ratio is a fundamental analysis indicator that compares the book value of a stock to its market value. By showing the difference between the stock’s market value and the value the company has stated in its financial books, P/B helps investors determine whether the stock is under or overvalued relative to its book value. It is the theoretical value of a company if it will be liquidated. Value investors often look for low P/B multiples when searching for bargain-priced stocks.
|
||||
|
||||
RETURN ON EQUITY (ROE)
|
||||
ROE is a profitability ratio that signifies the rate of return a shareholder receives for the portion of their investment in that company. It measures how well a company generates positive returns to its shareholders’ investment. Since profit is an actual driver of stock prices, separating out the profits earned with shareholder equity is actually a pretty good indicator of the financial health of a company and fair value of its stock.
|
||||
|
||||
DIVIDEND PAYOUT RATIO (DPR)
|
||||
As you know, companies pay a part of their profits to their shareholders in the form of dividends. But it’s also important to know how well the company’s earnings support those dividend payments. This is what the Dividend Payout Ratio is all about. It tells you what portion of net income a company returns to its shareholders, as well as how much it sets aside for growth, cash reserve, and debt repayments.
|
||||
|
||||
PRICE TO SALES RATIO (P/S)
|
||||
The price-to-sales ratio is a fundamental analysis indicator that can help determine the fair value of a stock by utilising a company’s market capitalisation and revenue. It shows how much the market values the company’s sales, which can be effective in valuing growth stocks that have yet to turn a profit or aren’t performing as expected due to a temporary setback. The P/S formula is calculated by dividing sales per share by the market value per share. A lower P/S ratio is seen as a good sign by investors. This is another metric that’s also useful when comparing companies in the same sector or industry.
|
||||
|
||||
DIVIDEND YIELD RATIO
|
||||
Dividend yield ratio looks at the amount paid by a company in dividends every year relative to its share price. It is an estimate of the dividend-only return of a stock investment. Assuming there are no changes to the dividend, the yield features an inverse relationship with the stock price — the yield rises when the stock price falls and vice versa. This is important to investors because it tells them how much they are getting back from every dollar they’ve invested in the company’s stock.
|
||||
|
||||
DEBT-TO-EQUITY RATIO (D/E)
|
||||
The debt to equity ratio is the last fundamental analysis indicator on this list. It measures the relationship between a company’s borrowed capital and the capital provided by its shareholders. Investors can use it to determine how a company finances its assets. The debt-to-equity ratio (D/E) helps investors evaluate the financial leverage of a company, signalling just how much shareholder’s equity can fulfil obligations to creditors should the business encounter financial hardship.
|
||||
|
||||
Beta
|
||||
Beta is a measurement of how reactive a stock is, compared to the overall market, generally defined as the S&P 500. A beta of 1 indicates that a stock tends to move in line with the S&P 500 -- that is, a 5% upward move in the index should produce roughly the same move in the stock. A beta of less than 1 indicates that a stock is less reactive to market swings, while a beta of more than 1 indicates a more volatile stock. For example, if a stock's beta is 0.4, a 10% move in the S&P 500 should theoretically produce a 4% swing in the stock. And a negative beta indicates that a stock tends to move in the opposite direction of the market. Beta can be found in most stock quotes, and it will give you an idea of how much volatility you're taking on before you buy a stock.
|
||||
170
fundamental_analysis/menu.py
Normal file
170
fundamental_analysis/menu.py
Normal file
@@ -0,0 +1,170 @@
|
||||
import FundamentalAnalysis as fa
|
||||
from alpha_vantage.fundamentaldata import FundamentalData
|
||||
import config_bot as cfg
|
||||
import argparse
|
||||
import datetime
|
||||
from datetime import datetime
|
||||
from stock_market_helper_funcs import *
|
||||
import pandas as pd
|
||||
import json
|
||||
import requests
|
||||
from pandas.io.json import json_normalize
|
||||
|
||||
from fundamental_analysis import alpha_vantage_api as av_api
|
||||
from fundamental_analysis import financial_modeling_prep_api as fmp_api
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------------------------
|
||||
def print_fundamental_analysis(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("\nFundamental Analysis:") # https://github.com/JerBouma/FundamentalAnalysis
|
||||
print(" info provides information on main key metrics of company")
|
||||
print(" help show this fundamental analysis menu again")
|
||||
print(" q quit this menu, and shows back to main menu")
|
||||
print(" quit quit to abandon program")
|
||||
print("\nAlpha Vantage API")
|
||||
print(" overview overview of the company")
|
||||
print(" key main key metrics of the company")
|
||||
print(" income income statements of the company")
|
||||
print(" balance balance sheet of the company")
|
||||
print(" cash cash flow of the company")
|
||||
print(" earnings earnings dates and reported EPS")
|
||||
print("\nFinancial Modeling Prep API")
|
||||
print(" profile profile of the company")
|
||||
print(" rating rating of the company from strong sell to strong buy")
|
||||
print(" quote quote of the company")
|
||||
print(" enterprise enterprise value of the company over time")
|
||||
print(" dcf discounted cash flow of the company over time")
|
||||
print(" income income statements of the company")
|
||||
print(" balance balance sheet of the company")
|
||||
print(" cash cash flow of the company")
|
||||
print(" metrics key metrics of the company")
|
||||
print(" ratios financial ratios of the company")
|
||||
print(" growth financial statement growth of the company")
|
||||
print("")
|
||||
|
||||
|
||||
# ---------------------------------------------------- INFO ----------------------------------------------------
|
||||
def info(l_args, s_ticker):
|
||||
parser = argparse.ArgumentParser(prog='info',
|
||||
description="""Provides information about main key metrics. Namely: EBITDA,
|
||||
EPS, P/E, PEG, FCF, P/B, ROE, DPR, P/S, Dividend Yield Ratio, D/E, and Beta.""")
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
filepath = 'fundamental_analysis/key_metrics_explained.txt'
|
||||
with open(filepath) as fp:
|
||||
line = fp.readline()
|
||||
while line:
|
||||
print("{}".format(line.strip()))
|
||||
line = fp.readline()
|
||||
print("")
|
||||
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
return
|
||||
|
||||
|
||||
# ---------------------------------------------------- MENU ----------------------------------------------------
|
||||
def fa_menu(fa_parser, s_ticker, s_start, s_interval):
|
||||
|
||||
print_fundamental_analysis(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, l_args) = fa_parser.parse_known_args(as_input.split())
|
||||
|
||||
except SystemExit:
|
||||
print("The command selected doesn't exist\n")
|
||||
continue
|
||||
|
||||
if ns_known_args.fa == 'info':
|
||||
info(l_args, s_ticker)
|
||||
|
||||
elif ns_known_args.fa == 'help':
|
||||
print_fundamental_analysis(s_ticker, s_start, s_interval)
|
||||
|
||||
elif ns_known_args.fa == 'q':
|
||||
# Just leave the FA menu
|
||||
return False
|
||||
|
||||
elif ns_known_args.fa == 'quit':
|
||||
# Abandon the program
|
||||
return True
|
||||
|
||||
# ----------------------------------------------- ALPHA VANTAGE ----------------------------------------------
|
||||
elif ns_known_args.fa == 'overview':
|
||||
av_api.overview(l_args, s_ticker)
|
||||
|
||||
elif ns_known_args.fa == 'key':
|
||||
av_api.key(l_args, s_ticker)
|
||||
|
||||
elif ns_known_args.fa == 'income':
|
||||
av_api.income_statement(l_args, s_ticker)
|
||||
|
||||
elif ns_known_args.fa == 'balance':
|
||||
av_api.balance_sheet(l_args, s_ticker)
|
||||
|
||||
elif ns_known_args.fa == 'cash':
|
||||
av_api.cash_flow(l_args, s_ticker)
|
||||
|
||||
elif ns_known_args.fa == 'earnings':
|
||||
av_api.earnings(l_args, s_ticker)
|
||||
|
||||
# -------------------------------------------- FINANCIAL MODELING PREP -----------------------------------------
|
||||
# Details:
|
||||
elif ns_known_args.fa == 'profile':
|
||||
fmp_api.profile(l_args, s_ticker)
|
||||
|
||||
elif ns_known_args.fa == 'rating':
|
||||
fmp_api.rating(l_args, s_ticker)
|
||||
|
||||
elif ns_known_args.fa == 'quote':
|
||||
fmp_api.quote(l_args, s_ticker)
|
||||
|
||||
elif ns_known_args.fa == 'enterprise':
|
||||
fmp_api.enterprise(l_args, s_ticker)
|
||||
|
||||
elif ns_known_args.fa == 'dcf':
|
||||
fmp_api.discounted_cash_flow(l_args, s_ticker)
|
||||
|
||||
# Financial statement:
|
||||
elif ns_known_args.fa == 'income':
|
||||
fmp_api.income_statement(l_args, s_ticker)
|
||||
|
||||
elif ns_known_args.fa == 'balance':
|
||||
fmp_api.balance_sheet(l_args, s_ticker)
|
||||
|
||||
elif ns_known_args.fa == 'cash':
|
||||
fmp_api.cash_flow(l_args, s_ticker)
|
||||
|
||||
# Ratios:
|
||||
elif ns_known_args.fa == 'metrics':
|
||||
fmp_api.key_metrics(l_args, s_ticker)
|
||||
|
||||
elif ns_known_args.fa == 'ratios':
|
||||
fmp_api.financial_ratios(l_args, s_ticker)
|
||||
|
||||
elif ns_known_args.fa == 'growth':
|
||||
fmp_api.financial_statement_growth(l_args, s_ticker)
|
||||
|
||||
# ------------------------------------------------------------------------------------------------------------
|
||||
else:
|
||||
print("Command not recognized!")
|
||||
@@ -21,18 +21,17 @@
|
||||
|
||||
"""
|
||||
|
||||
from alpha_vantage.timeseries import TimeSeries
|
||||
import argparse
|
||||
import config_bot as cfg
|
||||
import pandas as pd
|
||||
import pandas_ta as ta
|
||||
from pandas.plotting import register_matplotlib_converters
|
||||
register_matplotlib_converters()
|
||||
|
||||
from stock_market_helper_funcs import *
|
||||
import stock_market_menu as smm
|
||||
import stock_market_technical_analysis as smta
|
||||
import stock_market_fundamental_analysis as smfa
|
||||
from fundamental_analysis import menu as fam
|
||||
from technical_analysis import menu as tam
|
||||
|
||||
# delete this important when automatic loading tesla
|
||||
#i.e. when program is done
|
||||
import config_bot as cfg
|
||||
from alpha_vantage.timeseries import TimeSeries
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------------------------
|
||||
def print_help(s_ticker, s_start, s_interval, b_is_market_open):
|
||||
@@ -75,78 +74,6 @@ def print_help(s_ticker, s_start, s_interval, b_is_market_open):
|
||||
'''
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------------------------
|
||||
def print_fundamental_analysis(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("\nFundamental Analysis:") # https://github.com/JerBouma/FundamentalAnalysis
|
||||
print(" info provides information on main key metrics of company")
|
||||
print(" help show this fundamental analysis menu again")
|
||||
print(" q quit this menu, and shows back to main menu")
|
||||
print(" quit quit to abandon program")
|
||||
print("details:")
|
||||
print(" overview overview of the company [AV]")
|
||||
print(" key main key metrics of the company [AV]")
|
||||
print(" profile profile of the company [FMP]")
|
||||
print(" rating rating of the company from strong sell to strong buy [FMP]")
|
||||
print(" quote quote of the company [FMP]")
|
||||
print(" enterprise enterprise value of the company over time [FMP]")
|
||||
print(" dcf discounted cash flow of the company over time [FMP]")
|
||||
print("financial statement:")
|
||||
print(" income income statements of the company [default: AV, FMP]")
|
||||
print(" balance balance sheet of the company [default: AV, FMP]")
|
||||
print(" cash cash flow of the company [default: AV, FMP]")
|
||||
print(" earnings earnings dates and reported EPS [AV]")
|
||||
print("ratios:")
|
||||
print(" metrics key metrics of the company [FMP]")
|
||||
print(" ratios financial ratios of the company [FMP]")
|
||||
print(" growth financial statement growth of the company [FMP]")
|
||||
print("")
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------------------------
|
||||
def print_technical_analysis(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("\nTechnical Analysis:") # https://github.com/twopirllc/pandas-ta
|
||||
print(" help show this technical analysis menu again")
|
||||
print(" q quit this menu, and shows back to main menu")
|
||||
print(" quit quit to abandon program")
|
||||
print("overlap:")
|
||||
print(" ema exponential moving average")
|
||||
print(" sma simple moving average")
|
||||
if s_interval != "1440min":
|
||||
print(" vwap volume weighted average price")
|
||||
print("momentum:")
|
||||
print(" cci commodity channel index")
|
||||
print(" macd moving average convergence/divergence")
|
||||
print(" rsi relative strength index")
|
||||
print(" stoch stochastic oscillator")
|
||||
print("trend:")
|
||||
print(" adx average directional movement index")
|
||||
print(" aroon aroon indicator")
|
||||
print("volatility:")
|
||||
print(" bbands bollinger bands")
|
||||
print("volume:")
|
||||
print(" ad chaikin accumulation/distribution line values")
|
||||
print(" obv on balance volume")
|
||||
print("")
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------------------------
|
||||
def main():
|
||||
""" Main function of the program
|
||||
@@ -207,10 +134,6 @@ def main():
|
||||
print("The command selected doesn't exist\n")
|
||||
continue
|
||||
|
||||
# --------------------------------------------------------------------------------------------------------------
|
||||
# --------------------------------------------------- MENU -----------------------------------------------------
|
||||
# --------------------------------------------------------------------------------------------------------------
|
||||
|
||||
# --------------------------------------------------- GAINERS --------------------------------------------------
|
||||
if ns_known_args.cmd == 'gainers':
|
||||
smm.gainers(l_args)
|
||||
@@ -242,171 +165,30 @@ def main():
|
||||
print("Hope you made money today. Good bye my lover, good bye my friend.\n")
|
||||
return
|
||||
|
||||
# --------------------------------------------------------------------------------------------------------------
|
||||
# ------------------------------------------- FUNDAMENTAL ANALYSIS ---------------------------------------------
|
||||
# --------------------------------------------------------------------------------------------------------------
|
||||
elif ns_known_args.cmd == 'fa':
|
||||
# Print fundamental analysis menun
|
||||
print_fundamental_analysis(s_ticker, s_start, s_interval)
|
||||
b_quit = fam.fa_menu(fa_parser, 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, l_args) = fa_parser.parse_known_args(as_input.split())
|
||||
if b_quit:
|
||||
print("Hope you made money today. Good bye my lover, good bye my friend.\n")
|
||||
return
|
||||
else:
|
||||
print_help(s_ticker, s_start, s_interval, b_is_stock_market_open())
|
||||
|
||||
except SystemExit:
|
||||
print("The command selected doesn't exist\n")
|
||||
continue
|
||||
|
||||
if ns_known_args.fa == 'info':
|
||||
smfa.info(l_args, s_ticker)
|
||||
|
||||
elif ns_known_args.fa == 'help':
|
||||
print_fundamental_analysis(s_ticker, s_start, s_interval)
|
||||
|
||||
elif ns_known_args.fa == 'q':
|
||||
print_help(s_ticker, s_start, s_interval, b_is_stock_market_open())
|
||||
break
|
||||
|
||||
elif ns_known_args.fa == 'quit':
|
||||
print("Hope you made money today. Good bye my lover, good bye my friend.\n")
|
||||
return
|
||||
|
||||
# -------------------------------------------------- DETAILS --------------------------------------------------
|
||||
elif ns_known_args.fa == 'profile':
|
||||
smfa.profile(l_args, s_ticker)
|
||||
|
||||
elif ns_known_args.fa == 'rating':
|
||||
smfa.rating(l_args, s_ticker)
|
||||
|
||||
elif ns_known_args.fa == 'quote':
|
||||
smfa.quote(l_args, s_ticker)
|
||||
|
||||
elif ns_known_args.fa == 'enterprise':
|
||||
smfa.enterprise(l_args, s_ticker)
|
||||
|
||||
elif ns_known_args.fa == 'dcf':
|
||||
smfa.discounted_cash_flow(l_args, s_ticker)
|
||||
|
||||
elif ns_known_args.fa == 'overview':
|
||||
smfa.overview(l_args, s_ticker)
|
||||
|
||||
elif ns_known_args.fa == 'key':
|
||||
smfa.key(l_args, s_ticker)
|
||||
|
||||
# --------------------------------------------- FINANCIAL STATEMENT --------------------------------------------
|
||||
elif ns_known_args.fa == 'income':
|
||||
smfa.income_statement(l_args, s_ticker)
|
||||
|
||||
elif ns_known_args.fa == 'balance':
|
||||
smfa.balance_sheet(l_args, s_ticker)
|
||||
|
||||
elif ns_known_args.fa == 'cash':
|
||||
smfa.cash_flow(l_args, s_ticker)
|
||||
|
||||
elif ns_known_args.fa == 'earnings':
|
||||
smfa.earnings(l_args, s_ticker)
|
||||
|
||||
# --------------------------------------------------- RATIOS -----------------------------------------------------
|
||||
elif ns_known_args.fa == 'metrics':
|
||||
smfa.key_metrics(l_args, s_ticker)
|
||||
|
||||
elif ns_known_args.fa == 'ratios':
|
||||
smfa.financial_ratios(l_args, s_ticker)
|
||||
|
||||
elif ns_known_args.fa == 'growth':
|
||||
smfa.financial_statement_growth(l_args, s_ticker)
|
||||
|
||||
# ------------------------------------------------------------------------------------------------------------
|
||||
else:
|
||||
print("Command not recognized!")
|
||||
|
||||
print("")
|
||||
|
||||
# --------------------------------------------------------------------------------------------------------------
|
||||
# -------------------------------------------- TECHNICAL ANALYSIS ----------------------------------------------
|
||||
# --------------------------------------------------------------------------------------------------------------
|
||||
elif ns_known_args.cmd == 'ta':
|
||||
# Print technical analysis menun
|
||||
print_technical_analysis(s_ticker, s_start, s_interval)
|
||||
b_quit = tam.ta_menu(ta_parser, df_stock, 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, l_args) = ta_parser.parse_known_args(as_input.split())
|
||||
if b_quit:
|
||||
print("Hope you made money today. Good bye my lover, good bye my friend.\n")
|
||||
return
|
||||
else:
|
||||
print_help(s_ticker, s_start, s_interval, b_is_stock_market_open())
|
||||
|
||||
except SystemExit:
|
||||
print("The command selected doesn't exist\n")
|
||||
continue
|
||||
|
||||
if ns_known_args.ta == 'help':
|
||||
print_technical_analysis(s_ticker, s_start, s_interval)
|
||||
|
||||
elif ns_known_args.ta == 'q':
|
||||
print_help(s_ticker, s_start, s_interval, b_is_stock_market_open())
|
||||
break
|
||||
|
||||
elif ns_known_args.ta == 'quit':
|
||||
print("Hope you made money today. Good bye my lover, good bye my friend.\n")
|
||||
return
|
||||
|
||||
# -------------------------------------------------- OVERLAP --------------------------------------------------
|
||||
elif ns_known_args.ta == 'ema':
|
||||
smta.ema(l_args, s_ticker, s_interval, df_stock)
|
||||
|
||||
elif ns_known_args.ta == 'sma':
|
||||
smta.sma(l_args, s_ticker, s_interval, df_stock)
|
||||
|
||||
elif ns_known_args.ta == 'vwap':
|
||||
smta.vwap(l_args, s_ticker, s_interval, df_stock)
|
||||
|
||||
# --------------------------------------------------- MOMENTUM ---------------------------------------------------
|
||||
elif ns_known_args.ta == 'cci':
|
||||
smta.cci(l_args, s_ticker, s_interval, df_stock)
|
||||
|
||||
elif ns_known_args.ta == 'macd':
|
||||
smta.macd(l_args, s_ticker, s_interval, df_stock)
|
||||
|
||||
elif ns_known_args.ta == 'rsi':
|
||||
smta.rsi(l_args, s_ticker, s_interval, df_stock)
|
||||
|
||||
elif ns_known_args.ta == 'stoch':
|
||||
smta.stoch(l_args, s_ticker, s_interval, df_stock)
|
||||
|
||||
# ---------------------------------------------------- TREND ----------------------------------------------------
|
||||
elif ns_known_args.ta == 'adx':
|
||||
smta.adx(l_args, s_ticker, s_interval, df_stock)
|
||||
|
||||
elif ns_known_args.ta == 'aroon':
|
||||
smta.aroon(l_args, s_ticker, s_interval, df_stock)
|
||||
|
||||
# -------------------------------------------------- VOLATILITY --------------------------------------------------
|
||||
elif ns_known_args.ta == 'bbands':
|
||||
smta.bbands(l_args, s_ticker, s_interval, df_stock)
|
||||
|
||||
# ---------------------------------------------------- VOLUME ----------------------------------------------------
|
||||
elif ns_known_args.ta == 'ad':
|
||||
smta.ad(l_args, s_ticker, s_interval, df_stock)
|
||||
|
||||
elif ns_known_args.ta == 'obv':
|
||||
smta.obv(l_args, s_ticker, s_interval, df_stock)
|
||||
|
||||
# ------------------------------------------------------------------------------------------------------------
|
||||
else:
|
||||
print("Command not recognized!")
|
||||
|
||||
# --------------------------------------------------------------------------------------------------------------
|
||||
# ------------------------------------------------ PREDICTION --------------------------------------------------
|
||||
# --------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------------------------------------------
|
||||
else:
|
||||
print('Shouldnt see this command!')
|
||||
|
||||
|
||||
@@ -1,491 +0,0 @@
|
||||
import argparse
|
||||
from alpha_vantage.timeseries import TimeSeries
|
||||
from alpha_vantage.techindicators import TechIndicators
|
||||
import pandas_ta as ta
|
||||
import config_bot as cfg
|
||||
from stock_market_helper_funcs import *
|
||||
|
||||
# ----------------------------------------------------- EMA -----------------------------------------------------
|
||||
def ema(l_args, s_ticker, s_interval, df_stock):
|
||||
parser = argparse.ArgumentParser(prog='ema',
|
||||
description=""" The Exponential Moving Average is a staple of technical
|
||||
analysis and is used in countless technical indicators. In a Simple Moving
|
||||
Average, each value in the time period carries equal weight, and values outside
|
||||
of the time period are not included in the average. However, the Exponential
|
||||
Moving Average is a cumulative calculation, including all data. Past values have
|
||||
a diminishing contribution to the average, while more recent values have a greater
|
||||
contribution. This method allows the moving average to be more responsive to changes
|
||||
in the data. """)
|
||||
|
||||
parser.add_argument('-l', "--length", action="store", dest="n_length", type=check_positive, default=10, help='length')
|
||||
parser.add_argument('-o', "--offset", action="store", dest="n_offset", type=check_positive, default=0, help='offset')
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
except SystemExit:
|
||||
print("")
|
||||
return
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
try:
|
||||
# Daily
|
||||
if s_interval == "1440min":
|
||||
df_ta = ta.ema(df_stock['5. adjusted close'], length=ns_parser.n_length, offset=ns_parser.n_offset).dropna()
|
||||
plot_stock_ta(df_stock['5. adjusted close'], s_ticker, df_ta, "EMA")
|
||||
# Intraday
|
||||
else:
|
||||
df_ta = ta.ema(df_stock['4. close'], length=ns_parser.n_length, offset=ns_parser.n_offset).dropna()
|
||||
plot_stock_ta(df_stock['4. close'], s_ticker, df_ta, "EMA")
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
return
|
||||
|
||||
|
||||
# ----------------------------------------------------- SMA -----------------------------------------------------
|
||||
def sma(l_args, s_ticker, s_interval, df_stock):
|
||||
parser = argparse.ArgumentParser(prog='sma',
|
||||
description=""" Moving Averages are used to smooth the data in an array to
|
||||
help eliminate noise and identify trends. The Simple Moving Average is literally
|
||||
the simplest form of a moving average. Each output value is the average of the
|
||||
previous n values. In a Simple Moving Average, each value in the time period carries
|
||||
equal weight, and values outside of the time period are not included in the average.
|
||||
This makes it less responsive to recent changes in the data, which can be useful for
|
||||
filtering out those changes. """)
|
||||
|
||||
parser.add_argument('-l', "--length", action="store", dest="n_length", type=check_positive, default=10, help='length')
|
||||
parser.add_argument('-o', "--offset", action="store", dest="n_offset", type=check_positive, default=0, help='offset')
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
except SystemExit:
|
||||
print("")
|
||||
return
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
try:
|
||||
# Daily
|
||||
if s_interval == "1440min":
|
||||
df_ta = ta.sma(df_stock['5. adjusted close'], length=ns_parser.n_length, offset=ns_parser.n_offset).dropna()
|
||||
plot_stock_ta(df_stock['5. adjusted close'], s_ticker, df_ta, "SMA")
|
||||
# Intraday
|
||||
else:
|
||||
df_ta = ta.sma(df_stock['4. close'], length=ns_parser.n_length, offset=ns_parser.n_offset).dropna()
|
||||
plot_stock_ta(df_stock['4. close'], s_ticker, df_ta, "SMA")
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
return
|
||||
|
||||
|
||||
# ----------------------------------------------------- VWAP -----------------------------------------------------
|
||||
def vwap(l_args, s_ticker, s_interval, df_stock):
|
||||
parser = argparse.ArgumentParser(prog='vwap',
|
||||
description=""" The Volume Weighted Average Price that measures the average typical price
|
||||
by volume. It is typically used with intraday charts to identify general direction. """)
|
||||
|
||||
parser.add_argument('-o', "--offset", action="store", dest="n_offset", type=check_positive, default=0, help='offset')
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
except SystemExit:
|
||||
print("")
|
||||
return
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
try:
|
||||
df_ta = ta.vwap(high=df_stock['2. high'], low=df_stock['3. low'], close=df_stock['4. close'],
|
||||
volume=df_stock['5. volume'], offset=ns_parser.n_offset)
|
||||
|
||||
plot_stock_ta(df_stock['4. close'], s_ticker, df_ta, "VWAP")
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
return
|
||||
|
||||
|
||||
# ----------------------------------------------------- CCI -----------------------------------------------------
|
||||
def cci(l_args, s_ticker, s_interval, df_stock):
|
||||
parser = argparse.ArgumentParser(prog='cci',
|
||||
description=""" The CCI is designed to detect beginning and ending market trends.
|
||||
The range of 100 to -100 is the normal trading range. CCI values outside of this
|
||||
range indicate overbought or oversold conditions. You can also look for price
|
||||
divergence in the CCI. If the price is making new highs, and the CCI is not,
|
||||
then a price correction is likely. """)
|
||||
|
||||
parser.add_argument('-l', "--length", action="store", dest="n_length", type=check_positive, default=14, help='length')
|
||||
parser.add_argument('-s', "--scalar", action="store", dest="n_scalar", type=check_positive, default=0.015, help='scalar')
|
||||
parser.add_argument('-o', "--offset", action="store", dest="n_offset", type=check_positive, default=0, help='offset')
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
except SystemExit:
|
||||
print("")
|
||||
return
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
try:
|
||||
# Daily
|
||||
if s_interval == "1440min":
|
||||
df_ta = ta.cci(high=df_stock['2. high'], low=df_stock['3. low'], close=df_stock['5. adjusted close'],
|
||||
length=ns_parser.n_length, scalar=ns_parser.n_scalar, offset=ns_parser.n_offset).dropna()
|
||||
plot_stock_and_ta(df_stock['5. adjusted close'], s_ticker, df_ta, "CCI")
|
||||
# Intraday
|
||||
else:
|
||||
df_ta = ta.cci(high=df_stock['2. high'], low=df_stock['3. low'], close=df_stock['4. close'],
|
||||
length=ns_parser.n_length, scalar=ns_parser.n_scalar, offset=ns_parser.n_offset).dropna()
|
||||
plot_stock_and_ta(df_stock['4. close'], s_ticker, df_ta, "CCI")
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
return
|
||||
|
||||
|
||||
# ----------------------------------------------------- MACD -----------------------------------------------------
|
||||
def macd(l_args, s_ticker, s_interval, df_stock):
|
||||
parser = argparse.ArgumentParser(prog='macd',
|
||||
description=""" The Moving Average Convergence Divergence (MACD) is the difference
|
||||
between two Exponential Moving Averages. The Signal line is an Exponential Moving
|
||||
Average of the MACD. \n \n The MACD signals trend changes and indicates the start
|
||||
of new trend direction. High values indicate overbought conditions, low values
|
||||
indicate oversold conditions. Divergence with the price indicates an end to the
|
||||
current trend, especially if the MACD is at extreme high or low values. When the MACD
|
||||
line crosses above the signal line a buy signal is generated. When the MACD crosses
|
||||
below the signal line a sell signal is generated. To confirm the signal, the MACD
|
||||
should be above zero for a buy, and below zero for a sell. """)
|
||||
|
||||
parser.add_argument('-f', "--fast", action="store", dest="n_fast", type=check_positive, default=12,
|
||||
help='The short period.')
|
||||
parser.add_argument('-s', "--slow", action="store", dest="n_slow", type=check_positive, default=26,
|
||||
help='The long period.')
|
||||
parser.add_argument("--signal", action="store", dest="n_signal", type=check_positive, default=9,
|
||||
help='The signal period.')
|
||||
parser.add_argument('-o', "--offset", action="store", dest="n_offset", type=check_positive, default=0,
|
||||
help='How many periods to offset the result.')
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
except SystemExit:
|
||||
print("")
|
||||
return
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
try:
|
||||
# Daily
|
||||
if s_interval == "1440min":
|
||||
df_ta = ta.macd(df_stock['5. adjusted close'], fast=ns_parser.n_fast, slow=ns_parser.n_slow,
|
||||
signal=ns_parser.n_signal, offset=ns_parser.n_offset).dropna()
|
||||
plot_stock_and_ta(df_stock['5. adjusted close'], s_ticker, df_ta, "MACD")
|
||||
# Intraday
|
||||
else:
|
||||
df_ta = ta.macd(df_stock['4. close'], fast=ns_parser.n_fast, slow=ns_parser.n_slow,
|
||||
signal=ns_parser.n_signal, offset=ns_parser.n_offset).dropna()
|
||||
plot_stock_and_ta(df_stock['4. close'], s_ticker, df_ta, "MACD")
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
return
|
||||
|
||||
|
||||
# ----------------------------------------------------- RSI -----------------------------------------------------
|
||||
def rsi(l_args, s_ticker, s_interval, df_stock):
|
||||
parser = argparse.ArgumentParser(prog='rsi',
|
||||
description=""" The Relative Strength Index (RSI) calculates a ratio of the
|
||||
recent upward price movements to the absolute price movement. The RSI ranges
|
||||
from 0 to 100. The RSI is interpreted as an overbought/oversold indicator when
|
||||
the value is over 70/below 30. You can also look for divergence with price. If
|
||||
the price is making new highs/lows, and the RSI is not, it indicates a reversal. """)
|
||||
|
||||
parser.add_argument('-l', "--length", action="store", dest="n_length", type=check_positive, default=14, help='length')
|
||||
parser.add_argument('-s', "--scalar", action="store", dest="n_scalar", type=check_positive, default=100, help='scalar')
|
||||
parser.add_argument('-d', "--drift", action="store", dest="n_drift", type=check_positive, default=1, help='drift')
|
||||
parser.add_argument('-o', "--offset", action="store", dest="n_offset", type=check_positive, default=0, help='offset')
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
except SystemExit:
|
||||
print("")
|
||||
return
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
try:
|
||||
# Daily
|
||||
if s_interval == "1440min":
|
||||
df_ta = ta.rsi(df_stock['5. adjusted close'], length=ns_parser.n_length, scalar=ns_parser.n_scalar,
|
||||
drift=ns_parser.n_drift, offset=ns_parser.n_offset).dropna()
|
||||
plot_stock_and_ta(df_stock['5. adjusted close'], s_ticker, df_ta, "RSI")
|
||||
# Intraday
|
||||
else:
|
||||
df_ta = ta.rsi(df_stock['4. close'], length=ns_parser.n_length, scalar=ns_parser.n_scalar,
|
||||
drift=ns_parser.n_drift, offset=ns_parser.n_offset).dropna()
|
||||
plot_stock_and_ta(df_stock['4. close'], s_ticker, df_ta, "RSI")
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
return
|
||||
|
||||
|
||||
# ----------------------------------------------------- STOCH -----------------------------------------------------
|
||||
def stoch(l_args, s_ticker, s_interval, df_stock):
|
||||
parser = argparse.ArgumentParser(prog='stoch',
|
||||
description=""" The Stochastic Oscillator measures where the close is in relation
|
||||
to the recent trading range. The values range from zero to 100. %D values over 75
|
||||
indicate an overbought condition; values under 25 indicate an oversold condition.
|
||||
When the Fast %D crosses above the Slow %D, it is a buy signal; when it crosses
|
||||
below, it is a sell signal. The Raw %K is generally considered too erratic to use
|
||||
for crossover signals. """)
|
||||
|
||||
parser.add_argument('-k', "--fastkperiod", action="store", dest="n_fastkperiod", type=check_positive, default=14,
|
||||
help='The time period of the fastk moving average')
|
||||
parser.add_argument('-d', "--slowdperiod", action="store", dest="n_slowdperiod", type=check_positive, default=3,
|
||||
help='TThe time period of the slowd moving average')
|
||||
parser.add_argument("--slowkperiod", action="store", dest="n_slowkperiod", type=check_positive, default=3,
|
||||
help='The time period of the slowk moving average')
|
||||
parser.add_argument('-o', "--offset", action="store", dest="n_offset", type=check_positive, default=0, help='offset')
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
except SystemExit:
|
||||
print("")
|
||||
return
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
try:
|
||||
# Daily
|
||||
if s_interval == "1440min":
|
||||
df_ta = ta.stoch(high=df_stock['2. high'], low=df_stock['3. low'], close=df_stock['5. adjusted close'], k=ns_parser.n_fastkperiod,
|
||||
d=ns_parser.n_slowdperiod, smooth_k=ns_parser.n_slowkperiod, offset=ns_parser.n_offset).dropna()
|
||||
plot_stock_and_ta(df_stock['5. adjusted close'], s_ticker, df_ta, "STOCH")
|
||||
# Intraday
|
||||
else:
|
||||
df_ta = ta.stoch(high=df_stock['2. high'], low=df_stock['3. low'], close=df_stock['4. close'], k=ns_parser.n_fastkperiod,
|
||||
d=ns_parser.n_slowdperiod, smooth_k=ns_parser.n_slowkperiod, offset=ns_parser.n_offset).dropna()
|
||||
plot_stock_and_ta(df_stock['4. close'], s_ticker, df_ta, "STOCH")
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
return
|
||||
|
||||
|
||||
# ----------------------------------------------------- ADX -----------------------------------------------------
|
||||
def adx(l_args, s_ticker, s_interval, df_stock):
|
||||
parser = argparse.ArgumentParser(prog='adx',
|
||||
description=""" The ADX is a Welles Wilder style moving average of the Directional
|
||||
Movement Index (DX). The values range from 0 to 100, but rarely get above 60.
|
||||
To interpret the ADX, consider a high number to be a strong trend, and a low number,
|
||||
a weak trend. """)
|
||||
|
||||
parser.add_argument('-l', "--length", action="store", dest="n_length", type=check_positive, default=14, help='length')
|
||||
parser.add_argument('-s', "--scalar", action="store", dest="n_scalar", type=check_positive, default=100, help='scalar')
|
||||
parser.add_argument('-d', "--drift", action="store", dest="n_drift", type=check_positive, default=1, help='drift')
|
||||
parser.add_argument('-o', "--offset", action="store", dest="n_offset", type=check_positive, default=0, help='offset')
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
except SystemExit:
|
||||
print("")
|
||||
return
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
try:
|
||||
# Daily
|
||||
if s_interval == "1440min":
|
||||
df_ta = ta.adx(high=df_stock['2. high'], low=df_stock['3. low'], close=df_stock['5. adjusted close'], length=ns_parser.n_length,
|
||||
scalar=ns_parser.n_scalar, drift=ns_parser.n_drift, offset=ns_parser.n_offset).dropna()
|
||||
plot_stock_and_ta(df_stock['5. adjusted close'], s_ticker, df_ta, "ADX")
|
||||
# Intraday
|
||||
else:
|
||||
df_ta = ta.adx(high=df_stock['2. high'], low=df_stock['3. low'], close=df_stock['4. close'], length=ns_parser.n_length,
|
||||
scalar=ns_parser.n_scalar, drift=ns_parser.n_drift, offset=ns_parser.n_offset).dropna()
|
||||
plot_stock_and_ta(df_stock['4. close'], s_ticker, df_ta, "ADX")
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
return
|
||||
|
||||
|
||||
# ----------------------------------------------------- AROON -----------------------------------------------------
|
||||
def aroon(l_args, s_ticker, s_interval, df_stock):
|
||||
parser = argparse.ArgumentParser(prog='aroon',
|
||||
description=""" The word aroon is Sanskrit for "dawn's early light." The Aroon
|
||||
indicator attempts to show when a new trend is dawning. The indicator consists
|
||||
of two lines (Up and Down) that measure how long it has been since the highest
|
||||
high/lowest low has occurred within an n period range. \n \n When the Aroon Up is
|
||||
staying between 70 and 100 then it indicates an upward trend. When the Aroon Down
|
||||
is staying between 70 and 100 then it indicates an downward trend. A strong upward
|
||||
trend is indicated when the Aroon Up is above 70 while the Aroon Down is below 30.
|
||||
Likewise, a strong downward trend is indicated when the Aroon Down is above 70 while
|
||||
the Aroon Up is below 30. Also look for crossovers. When the Aroon Down crosses above
|
||||
the Aroon Up, it indicates a weakening of the upward trend (and vice versa). """)
|
||||
|
||||
parser.add_argument('-l', "--length", action="store", dest="n_length", type=check_positive, default=14, help='length')
|
||||
parser.add_argument('-s', "--scalar", action="store", dest="n_scalar", type=check_positive, default=100, help='scalar')
|
||||
parser.add_argument('-o', "--offset", action="store", dest="n_offset", type=check_positive, default=0, help='offset')
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
except SystemExit:
|
||||
print("")
|
||||
return
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
try:
|
||||
df_ta = ta.aroon(high=df_stock['2. high'], low=df_stock['3. low'], length=ns_parser.n_length,
|
||||
scalar=ns_parser.n_scalar, offset=ns_parser.n_offset).dropna()
|
||||
# Daily
|
||||
if s_interval == "1440min":
|
||||
plot_stock_and_ta(df_stock['5. adjusted close'], s_ticker, df_ta.iloc[:,-1], "AROON")
|
||||
# Intraday
|
||||
else:
|
||||
plot_stock_and_ta(df_stock['4. close'], s_ticker, df_ta.iloc[:,-1], "AROON")
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
return
|
||||
|
||||
|
||||
# ----------------------------------------------------- BBANDS -----------------------------------------------------
|
||||
def bbands(l_args, s_ticker, s_interval, df_stock):
|
||||
parser = argparse.ArgumentParser(prog='bbands',
|
||||
description=""" Bollinger Bands consist of three lines. The middle band is a simple
|
||||
moving average (generally 20 periods) of the typical price (TP). The upper and lower
|
||||
bands are F standard deviations (generally 2) above and below the middle band.
|
||||
The bands widen and narrow when the volatility of the price is higher or lower, respectively.
|
||||
\n \nBollinger Bands do not, in themselves, generate buy or sell signals; they are an
|
||||
indicator of overbought or oversold conditions. When the price is near the upper or lower
|
||||
band it indicates that a reversal may be imminent. The middle band becomes a support or
|
||||
resistance level. The upper and lower bands can also be interpreted as price targets.
|
||||
When the price bounces off of the lower band and crosses the middle band, then the
|
||||
upper band becomes the price target. """)
|
||||
|
||||
parser.add_argument('-l', "--length", action="store", dest="n_length", type=check_positive, default=5, help='length')
|
||||
parser.add_argument('-s', "--std", action="store", dest="n_std", type=check_positive, default=2, help='std')
|
||||
parser.add_argument('-m', "--mamode", action="store", dest="s_mamode", default="sma", help='mamode')
|
||||
parser.add_argument('-o', "--offset", action="store", dest="n_offset", type=check_positive, default=0, help='offset')
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
except SystemExit:
|
||||
print("")
|
||||
return
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
try:
|
||||
# Daily
|
||||
if s_interval == "1440min":
|
||||
df_ta = ta.bbands(close=df_stock['5. adjusted close'], length=ns_parser.n_length, std=ns_parser.n_std,
|
||||
mamode=ns_parser.s_mamode, offset=ns_parser.n_offset).dropna()
|
||||
plot_stock_ta(df_stock['5. adjusted close'], s_ticker, df_ta, "BBANDS")
|
||||
# Intraday
|
||||
else:
|
||||
df_ta = ta.bbands(close=df_stock['4. close'], length=ns_parser.n_length, std=ns_parser.n_std,
|
||||
mamode=ns_parser.s_mamode, offset=ns_parser.n_offset).dropna()
|
||||
plot_stock_ta(df_stock['4. close'], s_ticker, df_ta, "BBANDS")
|
||||
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
return
|
||||
|
||||
|
||||
# ------------------------------------------------------- AD -------------------------------------------------------
|
||||
def ad(l_args, s_ticker, s_interval, df_stock):
|
||||
parser = argparse.ArgumentParser(prog='ad',
|
||||
description=""" The Accumulation/Distribution Line is similar to the On Balance
|
||||
Volume (OBV), which sums the volume times +1/-1 based on whether the close is
|
||||
higher than the previous close. The Accumulation/Distribution indicator, however
|
||||
multiplies the volume by the close location value (CLV). The CLV is based on the
|
||||
movement of the issue within a single bar and can be +1, -1 or zero. \n \n
|
||||
The Accumulation/Distribution Line is interpreted by looking for a divergence in
|
||||
the direction of the indicator relative to price. If the Accumulation/Distribution
|
||||
Line is trending upward it indicates that the price may follow. Also, if the
|
||||
Accumulation/Distribution Line becomes flat while the price is still rising (or falling)
|
||||
then it signals an impending flattening of the price.""")
|
||||
|
||||
parser.add_argument('-o', "--offset", action="store", dest="n_offset", type=check_positive, default=0, help='offset')
|
||||
parser.add_argument('--open', action="store_true", default=False, dest="b_use_open", help='uses open value of stock')
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
except SystemExit:
|
||||
print("")
|
||||
return
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
try:
|
||||
# Daily
|
||||
if s_interval == "1440min":
|
||||
# Use open stock values
|
||||
if ns_parser.b_use_open:
|
||||
df_ta = ta.ad(high=df_stock['2. high'], low=df_stock['3. low'], close=df_stock['5. adjusted close'],
|
||||
volume=df_stock['6. volume'], offset=ns_parser.n_offset, open_=df_stock['1. open']).dropna()
|
||||
# Do not use open stock values
|
||||
else:
|
||||
df_ta = ta.ad(high=df_stock['2. high'], low=df_stock['3. low'], close=df_stock['5. adjusted close'],
|
||||
volume=df_stock['6. volume'], offset=ns_parser.n_offset).dropna()
|
||||
|
||||
plot_stock_and_ta(df_stock['5. adjusted close'], s_ticker, df_ta, "AD")
|
||||
# Intraday
|
||||
else:
|
||||
# Use open stock values
|
||||
if ns_parser.b_use_open:
|
||||
df_ta = ta.ad(high=df_stock['2. high'], low=df_stock['3. low'], close=df_stock['4. close'],
|
||||
volume=df_stock['5. volume'], offset=ns_parser.n_offset, open_=df_stock['1. open']).dropna()
|
||||
# Do not use open stock values
|
||||
else:
|
||||
df_ta = ta.ad(high=df_stock['2. high'], low=df_stock['3. low'], close=df_stock['4. close'],
|
||||
volume=df_stock['5. volume'], offset=ns_parser.n_offset).dropna()
|
||||
|
||||
plot_stock_and_ta(df_stock['4. close'], s_ticker, df_ta, "AD")
|
||||
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
return
|
||||
|
||||
|
||||
# ------------------------------------------------------- OBV -------------------------------------------------------
|
||||
def obv(l_args, s_ticker, s_interval, df_stock):
|
||||
parser = argparse.ArgumentParser(prog='obv',
|
||||
description=""" The On Balance Volume (OBV) is a cumulative total of the up and
|
||||
down volume. When the close is higher than the previous close, the volume is added
|
||||
to the running total, and when the close is lower than the previous close, the volume
|
||||
is subtracted from the running total. \n \n To interpret the OBV, look for the OBV
|
||||
to move with the price or precede price moves. If the price moves before the OBV,
|
||||
then it is a non-confirmed move. A series of rising peaks, or falling troughs, in the
|
||||
OBV indicates a strong trend. If the OBV is flat, then the market is not trending. """)
|
||||
|
||||
parser.add_argument('-o', "--offset", action="store", dest="n_offset", type=check_positive, default=0, help='offset')
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
except SystemExit:
|
||||
print("")
|
||||
return
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
try:
|
||||
# Daily
|
||||
if s_interval == "1440min":
|
||||
df_ta = ta.obv(close=df_stock['5. adjusted close'], volume=df_stock['6. volume'], offset=ns_parser.n_offset).dropna()
|
||||
plot_stock_and_ta(df_stock['5. adjusted close'], s_ticker, df_ta, "OBV")
|
||||
# Intraday
|
||||
else:
|
||||
df_ta = ta.ad(close=df_stock['4. close'], volume=df_stock['5. volume'], offset=ns_parser.n_offset).dropna()
|
||||
plot_stock_and_ta(df_stock['4. close'], s_ticker, df_ta, "OBV")
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
return
|
||||
BIN
technical_analysis/.DS_Store
vendored
Normal file
BIN
technical_analysis/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
technical_analysis/__pycache__/alpha_vantage_api.cpython-36.pyc
Normal file
BIN
technical_analysis/__pycache__/alpha_vantage_api.cpython-36.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
technical_analysis/__pycache__/menu.cpython-36.pyc
Normal file
BIN
technical_analysis/__pycache__/menu.cpython-36.pyc
Normal file
Binary file not shown.
BIN
technical_analysis/__pycache__/momentum.cpython-36.pyc
Normal file
BIN
technical_analysis/__pycache__/momentum.cpython-36.pyc
Normal file
Binary file not shown.
BIN
technical_analysis/__pycache__/overlap.cpython-36.pyc
Normal file
BIN
technical_analysis/__pycache__/overlap.cpython-36.pyc
Normal file
Binary file not shown.
BIN
technical_analysis/__pycache__/trend.cpython-36.pyc
Normal file
BIN
technical_analysis/__pycache__/trend.cpython-36.pyc
Normal file
Binary file not shown.
BIN
technical_analysis/__pycache__/volatility.cpython-36.pyc
Normal file
BIN
technical_analysis/__pycache__/volatility.cpython-36.pyc
Normal file
Binary file not shown.
BIN
technical_analysis/__pycache__/volume.cpython-36.pyc
Normal file
BIN
technical_analysis/__pycache__/volume.cpython-36.pyc
Normal file
Binary file not shown.
127
technical_analysis/menu.py
Normal file
127
technical_analysis/menu.py
Normal file
@@ -0,0 +1,127 @@
|
||||
import FundamentalAnalysis as fa
|
||||
from alpha_vantage.fundamentaldata import FundamentalData
|
||||
import config_bot as cfg
|
||||
import argparse
|
||||
import datetime
|
||||
from datetime import datetime
|
||||
from stock_market_helper_funcs import *
|
||||
import pandas as pd
|
||||
import json
|
||||
import requests
|
||||
from pandas.io.json import json_normalize
|
||||
|
||||
from technical_analysis import overlap as ta_overlap
|
||||
from technical_analysis import momentum as ta_momentum
|
||||
from technical_analysis import trend as ta_trend
|
||||
from technical_analysis import volatility as ta_volatility
|
||||
from technical_analysis import volume as ta_volume
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------------------------
|
||||
def print_technical_analysis(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("\nTechnical Analysis:") # https://github.com/twopirllc/pandas-ta
|
||||
print(" help show this technical analysis menu again")
|
||||
print(" q quit this menu, and shows back to main menu")
|
||||
print(" quit quit to abandon program")
|
||||
print("overlap:")
|
||||
print(" ema exponential moving average")
|
||||
print(" sma simple moving average")
|
||||
if s_interval != "1440min":
|
||||
print(" vwap volume weighted average price")
|
||||
print("momentum:")
|
||||
print(" cci commodity channel index")
|
||||
print(" macd moving average convergence/divergence")
|
||||
print(" rsi relative strength index")
|
||||
print(" stoch stochastic oscillator")
|
||||
print("trend:")
|
||||
print(" adx average directional movement index")
|
||||
print(" aroon aroon indicator")
|
||||
print("volatility:")
|
||||
print(" bbands bollinger bands")
|
||||
print("volume:")
|
||||
print(" ad chaikin accumulation/distribution line values")
|
||||
print(" obv on balance volume")
|
||||
print("")
|
||||
|
||||
|
||||
# ---------------------------------------------------- MENU ----------------------------------------------------
|
||||
def ta_menu(ta_parser, df_stock, s_ticker, s_start, s_interval):
|
||||
|
||||
print_technical_analysis(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, l_args) = ta_parser.parse_known_args(as_input.split())
|
||||
|
||||
except SystemExit:
|
||||
print("The command selected doesn't exist\n")
|
||||
continue
|
||||
|
||||
if ns_known_args.ta == 'help':
|
||||
print_technical_analysis(s_ticker, s_start, s_interval)
|
||||
|
||||
elif ns_known_args.ta == 'q':
|
||||
# Just leave the FA menu
|
||||
return False
|
||||
|
||||
elif ns_known_args.ta == 'quit':
|
||||
# Abandon the program
|
||||
return True
|
||||
|
||||
# -------------------------------------------------- OVERLAP --------------------------------------------------
|
||||
elif ns_known_args.ta == 'ema':
|
||||
ta_overlap.ema(l_args, s_ticker, s_interval, df_stock)
|
||||
|
||||
elif ns_known_args.ta == 'sma':
|
||||
ta_overlap.sma(l_args, s_ticker, s_interval, df_stock)
|
||||
|
||||
elif ns_known_args.ta == 'vwap':
|
||||
ta_overlap.vwap(l_args, s_ticker, s_interval, df_stock)
|
||||
|
||||
# --------------------------------------------------- MOMENTUM ---------------------------------------------------
|
||||
elif ns_known_args.ta == 'cci':
|
||||
ta_momentum.cci(l_args, s_ticker, s_interval, df_stock)
|
||||
|
||||
elif ns_known_args.ta == 'macd':
|
||||
ta_momentum.macd(l_args, s_ticker, s_interval, df_stock)
|
||||
|
||||
elif ns_known_args.ta == 'rsi':
|
||||
ta_momentum.rsi(l_args, s_ticker, s_interval, df_stock)
|
||||
|
||||
elif ns_known_args.ta == 'stoch':
|
||||
ta_momentum.stoch(l_args, s_ticker, s_interval, df_stock)
|
||||
|
||||
# ---------------------------------------------------- TREND ----------------------------------------------------
|
||||
elif ns_known_args.ta == 'adx':
|
||||
ta_trend.adx(l_args, s_ticker, s_interval, df_stock)
|
||||
|
||||
elif ns_known_args.ta == 'aroon':
|
||||
ta_trend.aroon(l_args, s_ticker, s_interval, df_stock)
|
||||
|
||||
# -------------------------------------------------- VOLATILITY --------------------------------------------------
|
||||
elif ns_known_args.ta == 'bbands':
|
||||
ta_volatility.bbands(l_args, s_ticker, s_interval, df_stock)
|
||||
|
||||
# ---------------------------------------------------- VOLUME ----------------------------------------------------
|
||||
elif ns_known_args.ta == 'ad':
|
||||
ta_volume.ad(l_args, s_ticker, s_interval, df_stock)
|
||||
|
||||
elif ns_known_args.ta == 'obv':
|
||||
ta_volume.obv(l_args, s_ticker, s_interval, df_stock)
|
||||
|
||||
# ------------------------------------------------------------------------------------------------------------
|
||||
else:
|
||||
print("Command not recognized!")
|
||||
159
technical_analysis/momentum.py
Normal file
159
technical_analysis/momentum.py
Normal file
@@ -0,0 +1,159 @@
|
||||
import argparse
|
||||
import pandas_ta as ta
|
||||
from stock_market_helper_funcs import *
|
||||
from pandas.plotting import register_matplotlib_converters
|
||||
register_matplotlib_converters()
|
||||
|
||||
# ----------------------------------------------------- CCI -----------------------------------------------------
|
||||
def cci(l_args, s_ticker, s_interval, df_stock):
|
||||
parser = argparse.ArgumentParser(prog='cci',
|
||||
description=""" The CCI is designed to detect beginning and ending market trends.
|
||||
The range of 100 to -100 is the normal trading range. CCI values outside of this
|
||||
range indicate overbought or oversold conditions. You can also look for price
|
||||
divergence in the CCI. If the price is making new highs, and the CCI is not,
|
||||
then a price correction is likely. """)
|
||||
|
||||
parser.add_argument('-l', "--length", action="store", dest="n_length", type=check_positive, default=14, help='length')
|
||||
parser.add_argument('-s', "--scalar", action="store", dest="n_scalar", type=check_positive, default=0.015, help='scalar')
|
||||
parser.add_argument('-o', "--offset", action="store", dest="n_offset", type=check_positive, default=0, help='offset')
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
# Daily
|
||||
if s_interval == "1440min":
|
||||
df_ta = ta.cci(high=df_stock['2. high'], low=df_stock['3. low'], close=df_stock['5. adjusted close'],
|
||||
length=ns_parser.n_length, scalar=ns_parser.n_scalar, offset=ns_parser.n_offset).dropna()
|
||||
plot_stock_and_ta(df_stock['5. adjusted close'], s_ticker, df_ta, "CCI")
|
||||
# Intraday
|
||||
else:
|
||||
df_ta = ta.cci(high=df_stock['2. high'], low=df_stock['3. low'], close=df_stock['4. close'],
|
||||
length=ns_parser.n_length, scalar=ns_parser.n_scalar, offset=ns_parser.n_offset).dropna()
|
||||
plot_stock_and_ta(df_stock['4. close'], s_ticker, df_ta, "CCI")
|
||||
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
|
||||
|
||||
# ----------------------------------------------------- MACD -----------------------------------------------------
|
||||
def macd(l_args, s_ticker, s_interval, df_stock):
|
||||
parser = argparse.ArgumentParser(prog='macd',
|
||||
description=""" The Moving Average Convergence Divergence (MACD) is the difference
|
||||
between two Exponential Moving Averages. The Signal line is an Exponential Moving
|
||||
Average of the MACD. \n \n The MACD signals trend changes and indicates the start
|
||||
of new trend direction. High values indicate overbought conditions, low values
|
||||
indicate oversold conditions. Divergence with the price indicates an end to the
|
||||
current trend, especially if the MACD is at extreme high or low values. When the MACD
|
||||
line crosses above the signal line a buy signal is generated. When the MACD crosses
|
||||
below the signal line a sell signal is generated. To confirm the signal, the MACD
|
||||
should be above zero for a buy, and below zero for a sell. """)
|
||||
|
||||
parser.add_argument('-f', "--fast", action="store", dest="n_fast", type=check_positive, default=12,
|
||||
help='The short period.')
|
||||
parser.add_argument('-s', "--slow", action="store", dest="n_slow", type=check_positive, default=26,
|
||||
help='The long period.')
|
||||
parser.add_argument("--signal", action="store", dest="n_signal", type=check_positive, default=9,
|
||||
help='The signal period.')
|
||||
parser.add_argument('-o', "--offset", action="store", dest="n_offset", type=check_positive, default=0,
|
||||
help='How many periods to offset the result.')
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
# Daily
|
||||
if s_interval == "1440min":
|
||||
df_ta = ta.macd(df_stock['5. adjusted close'], fast=ns_parser.n_fast, slow=ns_parser.n_slow,
|
||||
signal=ns_parser.n_signal, offset=ns_parser.n_offset).dropna()
|
||||
plot_stock_and_ta(df_stock['5. adjusted close'], s_ticker, df_ta, "MACD")
|
||||
# Intraday
|
||||
else:
|
||||
df_ta = ta.macd(df_stock['4. close'], fast=ns_parser.n_fast, slow=ns_parser.n_slow,
|
||||
signal=ns_parser.n_signal, offset=ns_parser.n_offset).dropna()
|
||||
plot_stock_and_ta(df_stock['4. close'], s_ticker, df_ta, "MACD")
|
||||
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
return
|
||||
|
||||
|
||||
# ----------------------------------------------------- RSI -----------------------------------------------------
|
||||
def rsi(l_args, s_ticker, s_interval, df_stock):
|
||||
parser = argparse.ArgumentParser(prog='rsi',
|
||||
description=""" The Relative Strength Index (RSI) calculates a ratio of the
|
||||
recent upward price movements to the absolute price movement. The RSI ranges
|
||||
from 0 to 100. The RSI is interpreted as an overbought/oversold indicator when
|
||||
the value is over 70/below 30. You can also look for divergence with price. If
|
||||
the price is making new highs/lows, and the RSI is not, it indicates a reversal. """)
|
||||
|
||||
parser.add_argument('-l', "--length", action="store", dest="n_length", type=check_positive, default=14, help='length')
|
||||
parser.add_argument('-s', "--scalar", action="store", dest="n_scalar", type=check_positive, default=100, help='scalar')
|
||||
parser.add_argument('-d', "--drift", action="store", dest="n_drift", type=check_positive, default=1, help='drift')
|
||||
parser.add_argument('-o', "--offset", action="store", dest="n_offset", type=check_positive, default=0, help='offset')
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
# Daily
|
||||
if s_interval == "1440min":
|
||||
df_ta = ta.rsi(df_stock['5. adjusted close'], length=ns_parser.n_length, scalar=ns_parser.n_scalar,
|
||||
drift=ns_parser.n_drift, offset=ns_parser.n_offset).dropna()
|
||||
plot_stock_and_ta(df_stock['5. adjusted close'], s_ticker, df_ta, "RSI")
|
||||
# Intraday
|
||||
else:
|
||||
df_ta = ta.rsi(df_stock['4. close'], length=ns_parser.n_length, scalar=ns_parser.n_scalar,
|
||||
drift=ns_parser.n_drift, offset=ns_parser.n_offset).dropna()
|
||||
plot_stock_and_ta(df_stock['4. close'], s_ticker, df_ta, "RSI")
|
||||
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
return
|
||||
|
||||
|
||||
# ----------------------------------------------------- STOCH -----------------------------------------------------
|
||||
def stoch(l_args, s_ticker, s_interval, df_stock):
|
||||
parser = argparse.ArgumentParser(prog='stoch',
|
||||
description=""" The Stochastic Oscillator measures where the close is in relation
|
||||
to the recent trading range. The values range from zero to 100. %D values over 75
|
||||
indicate an overbought condition; values under 25 indicate an oversold condition.
|
||||
When the Fast %D crosses above the Slow %D, it is a buy signal; when it crosses
|
||||
below, it is a sell signal. The Raw %K is generally considered too erratic to use
|
||||
for crossover signals. """)
|
||||
|
||||
parser.add_argument('-k', "--fastkperiod", action="store", dest="n_fastkperiod", type=check_positive, default=14,
|
||||
help='The time period of the fastk moving average')
|
||||
parser.add_argument('-d', "--slowdperiod", action="store", dest="n_slowdperiod", type=check_positive, default=3,
|
||||
help='TThe time period of the slowd moving average')
|
||||
parser.add_argument("--slowkperiod", action="store", dest="n_slowkperiod", type=check_positive, default=3,
|
||||
help='The time period of the slowk moving average')
|
||||
parser.add_argument('-o', "--offset", action="store", dest="n_offset", type=check_positive, default=0, help='offset')
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
# Daily
|
||||
if s_interval == "1440min":
|
||||
df_ta = ta.stoch(high=df_stock['2. high'], low=df_stock['3. low'], close=df_stock['5. adjusted close'], k=ns_parser.n_fastkperiod,
|
||||
d=ns_parser.n_slowdperiod, smooth_k=ns_parser.n_slowkperiod, offset=ns_parser.n_offset).dropna()
|
||||
plot_stock_and_ta(df_stock['5. adjusted close'], s_ticker, df_ta, "STOCH")
|
||||
# Intraday
|
||||
else:
|
||||
df_ta = ta.stoch(high=df_stock['2. high'], low=df_stock['3. low'], close=df_stock['4. close'], k=ns_parser.n_fastkperiod,
|
||||
d=ns_parser.n_slowdperiod, smooth_k=ns_parser.n_slowkperiod, offset=ns_parser.n_offset).dropna()
|
||||
plot_stock_and_ta(df_stock['4. close'], s_ticker, df_ta, "STOCH")
|
||||
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
return
|
||||
|
||||
98
technical_analysis/overlap.py
Normal file
98
technical_analysis/overlap.py
Normal file
@@ -0,0 +1,98 @@
|
||||
import argparse
|
||||
import pandas_ta as ta
|
||||
from stock_market_helper_funcs import *
|
||||
from pandas.plotting import register_matplotlib_converters
|
||||
register_matplotlib_converters()
|
||||
|
||||
# ----------------------------------------------------- EMA -----------------------------------------------------
|
||||
def ema(l_args, s_ticker, s_interval, df_stock):
|
||||
parser = argparse.ArgumentParser(prog='ema',
|
||||
description=""" The Exponential Moving Average is a staple of technical
|
||||
analysis and is used in countless technical indicators. In a Simple Moving
|
||||
Average, each value in the time period carries equal weight, and values outside
|
||||
of the time period are not included in the average. However, the Exponential
|
||||
Moving Average is a cumulative calculation, including all data. Past values have
|
||||
a diminishing contribution to the average, while more recent values have a greater
|
||||
contribution. This method allows the moving average to be more responsive to changes
|
||||
in the data. """)
|
||||
|
||||
parser.add_argument('-l', "--length", action="store", dest="n_length", type=check_positive, default=10, help='length')
|
||||
parser.add_argument('-o', "--offset", action="store", dest="n_offset", type=check_positive, default=0, help='offset')
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
# Daily
|
||||
if s_interval == "1440min":
|
||||
df_ta = ta.ema(df_stock['5. adjusted close'], length=ns_parser.n_length, offset=ns_parser.n_offset).dropna()
|
||||
plot_stock_ta(df_stock['5. adjusted close'], s_ticker, df_ta, "EMA")
|
||||
# Intraday
|
||||
else:
|
||||
df_ta = ta.ema(df_stock['4. close'], length=ns_parser.n_length, offset=ns_parser.n_offset).dropna()
|
||||
plot_stock_ta(df_stock['4. close'], s_ticker, df_ta, "EMA")
|
||||
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
return
|
||||
|
||||
|
||||
# ----------------------------------------------------- SMA -----------------------------------------------------
|
||||
def sma(l_args, s_ticker, s_interval, df_stock):
|
||||
parser = argparse.ArgumentParser(prog='sma',
|
||||
description=""" Moving Averages are used to smooth the data in an array to
|
||||
help eliminate noise and identify trends. The Simple Moving Average is literally
|
||||
the simplest form of a moving average. Each output value is the average of the
|
||||
previous n values. In a Simple Moving Average, each value in the time period carries
|
||||
equal weight, and values outside of the time period are not included in the average.
|
||||
This makes it less responsive to recent changes in the data, which can be useful for
|
||||
filtering out those changes. """)
|
||||
|
||||
parser.add_argument('-l', "--length", action="store", dest="n_length", type=check_positive, default=10, help='length')
|
||||
parser.add_argument('-o', "--offset", action="store", dest="n_offset", type=check_positive, default=0, help='offset')
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
# Daily
|
||||
if s_interval == "1440min":
|
||||
df_ta = ta.sma(df_stock['5. adjusted close'], length=ns_parser.n_length, offset=ns_parser.n_offset).dropna()
|
||||
plot_stock_ta(df_stock['5. adjusted close'], s_ticker, df_ta, "SMA")
|
||||
# Intraday
|
||||
else:
|
||||
df_ta = ta.sma(df_stock['4. close'], length=ns_parser.n_length, offset=ns_parser.n_offset).dropna()
|
||||
plot_stock_ta(df_stock['4. close'], s_ticker, df_ta, "SMA")
|
||||
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
return
|
||||
|
||||
|
||||
# ----------------------------------------------------- VWAP -----------------------------------------------------
|
||||
def vwap(l_args, s_ticker, s_interval, df_stock):
|
||||
parser = argparse.ArgumentParser(prog='vwap',
|
||||
description=""" The Volume Weighted Average Price that measures the average typical price
|
||||
by volume. It is typically used with intraday charts to identify general direction. """)
|
||||
|
||||
parser.add_argument('-o', "--offset", action="store", dest="n_offset", type=check_positive, default=0, help='offset')
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
df_ta = ta.vwap(high=df_stock['2. high'], low=df_stock['3. low'], close=df_stock['4. close'],
|
||||
volume=df_stock['5. volume'], offset=ns_parser.n_offset)
|
||||
|
||||
plot_stock_ta(df_stock['4. close'], s_ticker, df_ta, "VWAP")
|
||||
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
return
|
||||
|
||||
78
technical_analysis/trend.py
Normal file
78
technical_analysis/trend.py
Normal file
@@ -0,0 +1,78 @@
|
||||
import argparse
|
||||
import pandas_ta as ta
|
||||
from stock_market_helper_funcs import *
|
||||
from pandas.plotting import register_matplotlib_converters
|
||||
register_matplotlib_converters()
|
||||
|
||||
# ----------------------------------------------------- ADX -----------------------------------------------------
|
||||
def adx(l_args, s_ticker, s_interval, df_stock):
|
||||
parser = argparse.ArgumentParser(prog='adx',
|
||||
description=""" The ADX is a Welles Wilder style moving average of the Directional
|
||||
Movement Index (DX). The values range from 0 to 100, but rarely get above 60.
|
||||
To interpret the ADX, consider a high number to be a strong trend, and a low number,
|
||||
a weak trend. """)
|
||||
|
||||
parser.add_argument('-l', "--length", action="store", dest="n_length", type=check_positive, default=14, help='length')
|
||||
parser.add_argument('-s', "--scalar", action="store", dest="n_scalar", type=check_positive, default=100, help='scalar')
|
||||
parser.add_argument('-d', "--drift", action="store", dest="n_drift", type=check_positive, default=1, help='drift')
|
||||
parser.add_argument('-o', "--offset", action="store", dest="n_offset", type=check_positive, default=0, help='offset')
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
# Daily
|
||||
if s_interval == "1440min":
|
||||
df_ta = ta.adx(high=df_stock['2. high'], low=df_stock['3. low'], close=df_stock['5. adjusted close'], length=ns_parser.n_length,
|
||||
scalar=ns_parser.n_scalar, drift=ns_parser.n_drift, offset=ns_parser.n_offset).dropna()
|
||||
plot_stock_and_ta(df_stock['5. adjusted close'], s_ticker, df_ta, "ADX")
|
||||
# Intraday
|
||||
else:
|
||||
df_ta = ta.adx(high=df_stock['2. high'], low=df_stock['3. low'], close=df_stock['4. close'], length=ns_parser.n_length,
|
||||
scalar=ns_parser.n_scalar, drift=ns_parser.n_drift, offset=ns_parser.n_offset).dropna()
|
||||
plot_stock_and_ta(df_stock['4. close'], s_ticker, df_ta, "ADX")
|
||||
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
return
|
||||
|
||||
|
||||
# ----------------------------------------------------- AROON -----------------------------------------------------
|
||||
def aroon(l_args, s_ticker, s_interval, df_stock):
|
||||
parser = argparse.ArgumentParser(prog='aroon',
|
||||
description=""" The word aroon is Sanskrit for "dawn's early light." The Aroon
|
||||
indicator attempts to show when a new trend is dawning. The indicator consists
|
||||
of two lines (Up and Down) that measure how long it has been since the highest
|
||||
high/lowest low has occurred within an n period range. \n \n When the Aroon Up is
|
||||
staying between 70 and 100 then it indicates an upward trend. When the Aroon Down
|
||||
is staying between 70 and 100 then it indicates an downward trend. A strong upward
|
||||
trend is indicated when the Aroon Up is above 70 while the Aroon Down is below 30.
|
||||
Likewise, a strong downward trend is indicated when the Aroon Down is above 70 while
|
||||
the Aroon Up is below 30. Also look for crossovers. When the Aroon Down crosses above
|
||||
the Aroon Up, it indicates a weakening of the upward trend (and vice versa). """)
|
||||
|
||||
parser.add_argument('-l', "--length", action="store", dest="n_length", type=check_positive, default=14, help='length')
|
||||
parser.add_argument('-s', "--scalar", action="store", dest="n_scalar", type=check_positive, default=100, help='scalar')
|
||||
parser.add_argument('-o', "--offset", action="store", dest="n_offset", type=check_positive, default=0, help='offset')
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
df_ta = ta.aroon(high=df_stock['2. high'], low=df_stock['3. low'], length=ns_parser.n_length,
|
||||
scalar=ns_parser.n_scalar, offset=ns_parser.n_offset).dropna()
|
||||
# Daily
|
||||
if s_interval == "1440min":
|
||||
plot_stock_and_ta(df_stock['5. adjusted close'], s_ticker, df_ta.iloc[:,-1], "AROON")
|
||||
# Intraday
|
||||
else:
|
||||
plot_stock_and_ta(df_stock['4. close'], s_ticker, df_ta.iloc[:,-1], "AROON")
|
||||
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
return
|
||||
|
||||
46
technical_analysis/volatility.py
Normal file
46
technical_analysis/volatility.py
Normal file
@@ -0,0 +1,46 @@
|
||||
import argparse
|
||||
import pandas_ta as ta
|
||||
from stock_market_helper_funcs import *
|
||||
from pandas.plotting import register_matplotlib_converters
|
||||
register_matplotlib_converters()
|
||||
|
||||
# ----------------------------------------------------- BBANDS -----------------------------------------------------
|
||||
def bbands(l_args, s_ticker, s_interval, df_stock):
|
||||
parser = argparse.ArgumentParser(prog='bbands',
|
||||
description=""" Bollinger Bands consist of three lines. The middle band is a simple
|
||||
moving average (generally 20 periods) of the typical price (TP). The upper and lower
|
||||
bands are F standard deviations (generally 2) above and below the middle band.
|
||||
The bands widen and narrow when the volatility of the price is higher or lower, respectively.
|
||||
\n \nBollinger Bands do not, in themselves, generate buy or sell signals; they are an
|
||||
indicator of overbought or oversold conditions. When the price is near the upper or lower
|
||||
band it indicates that a reversal may be imminent. The middle band becomes a support or
|
||||
resistance level. The upper and lower bands can also be interpreted as price targets.
|
||||
When the price bounces off of the lower band and crosses the middle band, then the
|
||||
upper band becomes the price target. """)
|
||||
|
||||
parser.add_argument('-l', "--length", action="store", dest="n_length", type=check_positive, default=5, help='length')
|
||||
parser.add_argument('-s', "--std", action="store", dest="n_std", type=check_positive, default=2, help='std')
|
||||
parser.add_argument('-m', "--mamode", action="store", dest="s_mamode", default="sma", help='mamode')
|
||||
parser.add_argument('-o', "--offset", action="store", dest="n_offset", type=check_positive, default=0, help='offset')
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
# Daily
|
||||
if s_interval == "1440min":
|
||||
df_ta = ta.bbands(close=df_stock['5. adjusted close'], length=ns_parser.n_length, std=ns_parser.n_std,
|
||||
mamode=ns_parser.s_mamode, offset=ns_parser.n_offset).dropna()
|
||||
plot_stock_ta(df_stock['5. adjusted close'], s_ticker, df_ta, "BBANDS")
|
||||
# Intraday
|
||||
else:
|
||||
df_ta = ta.bbands(close=df_stock['4. close'], length=ns_parser.n_length, std=ns_parser.n_std,
|
||||
mamode=ns_parser.s_mamode, offset=ns_parser.n_offset).dropna()
|
||||
plot_stock_ta(df_stock['4. close'], s_ticker, df_ta, "BBANDS")
|
||||
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
return
|
||||
|
||||
91
technical_analysis/volume.py
Normal file
91
technical_analysis/volume.py
Normal file
@@ -0,0 +1,91 @@
|
||||
import argparse
|
||||
import pandas_ta as ta
|
||||
from stock_market_helper_funcs import *
|
||||
from pandas.plotting import register_matplotlib_converters
|
||||
register_matplotlib_converters()
|
||||
|
||||
# ------------------------------------------------------- AD -------------------------------------------------------
|
||||
def ad(l_args, s_ticker, s_interval, df_stock):
|
||||
parser = argparse.ArgumentParser(prog='ad',
|
||||
description=""" The Accumulation/Distribution Line is similar to the On Balance
|
||||
Volume (OBV), which sums the volume times +1/-1 based on whether the close is
|
||||
higher than the previous close. The Accumulation/Distribution indicator, however
|
||||
multiplies the volume by the close location value (CLV). The CLV is based on the
|
||||
movement of the issue within a single bar and can be +1, -1 or zero. \n \n
|
||||
The Accumulation/Distribution Line is interpreted by looking for a divergence in
|
||||
the direction of the indicator relative to price. If the Accumulation/Distribution
|
||||
Line is trending upward it indicates that the price may follow. Also, if the
|
||||
Accumulation/Distribution Line becomes flat while the price is still rising (or falling)
|
||||
then it signals an impending flattening of the price.""")
|
||||
|
||||
parser.add_argument('-o', "--offset", action="store", dest="n_offset", type=check_positive, default=0, help='offset')
|
||||
parser.add_argument('--open', action="store_true", default=False, dest="b_use_open", help='uses open value of stock')
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
# Daily
|
||||
if s_interval == "1440min":
|
||||
# Use open stock values
|
||||
if ns_parser.b_use_open:
|
||||
df_ta = ta.ad(high=df_stock['2. high'], low=df_stock['3. low'], close=df_stock['5. adjusted close'],
|
||||
volume=df_stock['6. volume'], offset=ns_parser.n_offset, open_=df_stock['1. open']).dropna()
|
||||
# Do not use open stock values
|
||||
else:
|
||||
df_ta = ta.ad(high=df_stock['2. high'], low=df_stock['3. low'], close=df_stock['5. adjusted close'],
|
||||
volume=df_stock['6. volume'], offset=ns_parser.n_offset).dropna()
|
||||
|
||||
plot_stock_and_ta(df_stock['5. adjusted close'], s_ticker, df_ta, "AD")
|
||||
# Intraday
|
||||
else:
|
||||
# Use open stock values
|
||||
if ns_parser.b_use_open:
|
||||
df_ta = ta.ad(high=df_stock['2. high'], low=df_stock['3. low'], close=df_stock['4. close'],
|
||||
volume=df_stock['5. volume'], offset=ns_parser.n_offset, open_=df_stock['1. open']).dropna()
|
||||
# Do not use open stock values
|
||||
else:
|
||||
df_ta = ta.ad(high=df_stock['2. high'], low=df_stock['3. low'], close=df_stock['4. close'],
|
||||
volume=df_stock['5. volume'], offset=ns_parser.n_offset).dropna()
|
||||
|
||||
plot_stock_and_ta(df_stock['4. close'], s_ticker, df_ta, "AD")
|
||||
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
return
|
||||
|
||||
|
||||
# ------------------------------------------------------- OBV -------------------------------------------------------
|
||||
def obv(l_args, s_ticker, s_interval, df_stock):
|
||||
parser = argparse.ArgumentParser(prog='obv',
|
||||
description=""" The On Balance Volume (OBV) is a cumulative total of the up and
|
||||
down volume. When the close is higher than the previous close, the volume is added
|
||||
to the running total, and when the close is lower than the previous close, the volume
|
||||
is subtracted from the running total. \n \n To interpret the OBV, look for the OBV
|
||||
to move with the price or precede price moves. If the price moves before the OBV,
|
||||
then it is a non-confirmed move. A series of rising peaks, or falling troughs, in the
|
||||
OBV indicates a strong trend. If the OBV is flat, then the market is not trending. """)
|
||||
|
||||
parser.add_argument('-o', "--offset", action="store", dest="n_offset", type=check_positive, default=0, help='offset')
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}")
|
||||
|
||||
# Daily
|
||||
if s_interval == "1440min":
|
||||
df_ta = ta.obv(close=df_stock['5. adjusted close'], volume=df_stock['6. volume'], offset=ns_parser.n_offset).dropna()
|
||||
plot_stock_and_ta(df_stock['5. adjusted close'], s_ticker, df_ta, "OBV")
|
||||
# Intraday
|
||||
else:
|
||||
df_ta = ta.obv(close=df_stock['4. close'], volume=df_stock['5. volume'], offset=ns_parser.n_offset).dropna()
|
||||
plot_stock_and_ta(df_stock['4. close'], s_ticker, df_ta, "OBV")
|
||||
|
||||
except:
|
||||
print("ERROR!\n")
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user