-
Notifications
You must be signed in to change notification settings - Fork 37
/
report_relative_strength.py
144 lines (120 loc) · 4.15 KB
/
report_relative_strength.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
"""
Plot best and worst performing stocks against a base ticker.
By default it compares the whole market against SPY
"""
import itertools
from argparse import ArgumentParser
from datetime import datetime
import matplotlib.pyplot as plt
import pandas as pd
from common.analyst import DAYS_IN_MONTH
from common.analyst import load_ticker_df
from common.market import load_all_tickers
from common.plotting import save_and_open_plt_fig
def load_both_tickers(ticker1, ticker2):
left_df = load_ticker_df(ticker1)
right_df = load_ticker_df(ticker2)
return left_df, right_df
def pmo(data):
data["smooth_mul"] = 2 / 35
data["roc"] = data["close_-1_r"]
data["ema_roc"] = data["roc_34_ema"]
data["ema_ema_roc"] = data["ema_roc_19_ema"]
return 10 * data["ema_ema_roc"]
def calculate_pmo(left_df, right_df):
df = pd.DataFrame()
df["left_close"] = left_df["close"]
df["right_close"] = right_df["close"]
df["left_close_rebased"] = (left_df["close"].pct_change() + 1).cumprod()
df["right_close_rebased"] = (right_df["close"].pct_change() + 1).cumprod()
df["left_pmo"] = pmo(left_df)
df["right_pmo"] = pmo(right_df)
return df
def plt_charts(fig, num, df, ticker):
ax = fig.add_subplot(2, 5, num + 1)
ax.plot(df["left_pmo"], linestyle="-")
ax.plot(df["right_pmo"], linestyle="-", label=f"{ticker}")
ax.legend()
ax.set_xticks([])
ax.set_yticks([])
ax.grid(True)
def parse_args():
parser = ArgumentParser(description=__doc__)
parser.add_argument(
"-b",
"--base-ticker",
help="Base ticker to compare relative strength",
default="SPY",
)
parser.add_argument(
"-m",
"--market-type",
help="Select Market for analysis. Choose between all(All tickers), large-cap(S&P500)",
default="large-cap",
)
parser.add_argument(
"-s",
"--stocks",
help="Comma separated list of stocks to compare with base ticker.",
)
return parser.parse_args()
def sort_stocks(k):
pmo_diff = k["right_pmo"] - k["left_pmo"]
short_ma = pmo_diff.rolling(5).mean()
long_ma = pmo_diff.rolling(10).mean()
return (short_ma - long_ma).iloc[-1]
def generate_charts(title: str, selected_stocks, stocks_rs_data):
dt_now = datetime.now()
fig = plt.figure(figsize=(15, 10))
fig.suptitle(f"{title} ({dt_now.strftime('%d %B %Y')}) ")
print("Plotting {} -> {}".format(title, selected_stocks))
for num, stock in enumerate(selected_stocks):
plt_charts(fig, num, stocks_rs_data[stock][-1 * DAYS_IN_MONTH :], stock)
file_path = (
f"output/{dt_now.strftime('%Y-%m-%d')}-{title.lower()}-relative-strength.png"
)
save_and_open_plt_fig(fig, file_path, close_fig=False)
def main():
args = parse_args()
base_ticker = args.base_ticker
market_type = args.market_type
stocks: str = args.stocks
print(args)
left_df = load_ticker_df(base_ticker)
all_tickers = load_all_tickers(market_type=market_type)
if stocks:
all_tickers = [s.strip() for s in stocks.split(",")]
stocks_rs_data = {}
for num, ticker in enumerate(all_tickers):
try:
print(
"Calculating relative strength between {} and {}".format(
base_ticker, ticker
)
)
right_df = load_ticker_df(ticker)
if left_df is None or left_df.empty or right_df is None or right_df.empty:
continue
plt_df = calculate_pmo(left_df, right_df)
stocks_rs_data[ticker] = plt_df
except:
print(f"Unable to calculate relative strength of {ticker}")
leaders = list(
itertools.islice(
sorted(
stocks_rs_data,
key=lambda k: sort_stocks(stocks_rs_data[k]),
reverse=True,
),
10,
)
)
generate_charts("Leaders", leaders, stocks_rs_data)
laggards = list(
itertools.islice(
sorted(stocks_rs_data, key=lambda k: sort_stocks(stocks_rs_data[k])), 10
)
)
generate_charts("Laggards", laggards, stocks_rs_data)
if __name__ == "__main__":
main()