Improve plotly interface for plots (#1213)

* Improve plotly interface for plots

* add interactiv linear/log button

* change volexch to mpl default

Co-authored-by: Colin Delahunty <72827203+colin99d@users.noreply.github.com>
This commit is contained in:
jmaslek
2022-01-19 15:52:45 -05:00
committed by GitHub
parent eb1c74f918
commit 4e1abb2d2f
3 changed files with 142 additions and 77 deletions

View File

@@ -544,12 +544,12 @@ class DarkPoolShortsController(BaseController):
default=False,
)
parser.add_argument(
"-m",
"--mpl",
help="Display plot using matplotlb.",
dest="mpl",
action="store_true",
default=False,
"-p",
"--plotly",
help="Display plot using interactive plotly.",
dest="plotly",
action="store_false",
default=True,
)
ns_parser = parse_known_args_and_warn(
parser, other_args, export_allowed=EXPORT_BOTH_RAW_DATA_AND_FIGURES
@@ -561,7 +561,7 @@ class DarkPoolShortsController(BaseController):
raw=ns_parser.raw,
sort=ns_parser.sort,
asc=ns_parser.asc,
mpl=ns_parser.mpl,
mpl=ns_parser.plotly,
export=ns_parser.export,
)
else:

View File

@@ -290,12 +290,12 @@ Stock: [/param]{stock_text}
description="Shows historic data for a stock",
)
parser.add_argument(
"-m",
"--matplotlib",
dest="matplotlib",
action="store_true",
default=False,
help="Flag to show matplotlib instead of interactive plot using plotly.",
"-p",
"--plotly",
dest="plotly",
action="store_false",
default=True,
help="Flag to show interactive plotly chart.",
)
parser.add_argument(
"--sort",
@@ -337,6 +337,21 @@ Stock: [/param]{stock_text}
dest="num",
default=20,
)
parser.add_argument(
"-t",
"--trend",
action="store_true",
default=False,
help="Flag to add high and low trends to candle.",
dest="trendlines",
)
parser.add_argument(
"--ma",
dest="mov_avg",
type=str,
help="Add moving averaged to plot",
default="",
)
ns_parser = parse_known_args_and_warn(
parser, other_args, EXPORT_ONLY_RAW_DATA_ALLOWED
@@ -361,13 +376,21 @@ Stock: [/param]{stock_text}
)
else:
data = stocks_helper.process_candle(self.stock)
mov_avgs = (
tuple(int(num) for num in ns_parser.mov_avg.split(","))
if ns_parser.mov_avg
else None
)
stocks_helper.display_candle(
s_ticker=self.ticker,
df_stock=data,
use_matplotlib=ns_parser.matplotlib,
use_matplotlib=ns_parser.plotly,
intraday=self.interval != "1440min",
add_trend=ns_parser.trendlines,
ma=mov_avgs,
)
else:
console.print("No ticker loaded. First use `load {ticker}`\n")

View File

@@ -1,12 +1,14 @@
"""Main helper"""
__docformat__ = "numpy"
import argparse
import json
from datetime import datetime, timedelta
from typing import List, Union
from typing import List, Union, Tuple, Optional
import matplotlib.pyplot as plt
import mplfinance as mpf
import numpy as np
import pandas as pd
import pandas_market_calendars as mcal
import plotly.graph_objects as go
@@ -266,7 +268,12 @@ def load(
def display_candle(
s_ticker: str, df_stock: pd.DataFrame, use_matplotlib: bool, intraday: bool = False
s_ticker: str,
df_stock: pd.DataFrame,
use_matplotlib: bool,
intraday: bool = False,
add_trend: bool = False,
ma: Optional[Tuple[int, ...]] = None,
):
"""Shows candle plot of loaded ticker. [Source: Yahoo Finance, IEX Cloud or Alpha Vantage]
@@ -280,10 +287,15 @@ def display_candle(
Flag to use matplotlib instead of interactive plotly chart
intraday: bool
Flag for intraday data for plotly range breaks
add_trend: bool
Flag to add high and low trends to chart
mov_avg: Tuple[int]
Moving averages to add to the candle
"""
if (df_stock.index[1] - df_stock.index[0]).total_seconds() >= 86400:
df_stock = find_trendline(df_stock, "OC_High", "high")
df_stock = find_trendline(df_stock, "OC_Low", "low")
if add_trend:
if (df_stock.index[1] - df_stock.index[0]).total_seconds() >= 86400:
df_stock = find_trendline(df_stock, "OC_High", "high")
df_stock = find_trendline(df_stock, "OC_Low", "low")
if use_matplotlib:
mc = mpf.make_marketcolors(
@@ -298,24 +310,24 @@ def display_candle(
s = mpf.make_mpf_style(marketcolors=mc, gridstyle=":", y_on_right=True)
ap0 = []
if add_trend:
if "OC_High_trend" in df_stock.columns:
ap0.append(
mpf.make_addplot(df_stock["OC_High_trend"], color="g"),
)
if "OC_High_trend" in df_stock.columns:
ap0.append(
mpf.make_addplot(df_stock["OC_High_trend"], color="g"),
)
if "OC_Low_trend" in df_stock.columns:
ap0.append(
mpf.make_addplot(df_stock["OC_Low_trend"], color="b"),
)
if "OC_Low_trend" in df_stock.columns:
ap0.append(
mpf.make_addplot(df_stock["OC_Low_trend"], color="b"),
)
if gtff.USE_ION:
plt.ion()
kwargs = {"mav": ma} if ma else {}
mpf.plot(
df_stock,
type="candle",
mav=(20, 50),
volume=True,
title=f"\nStock {s_ticker}",
addplot=ap0,
@@ -327,6 +339,8 @@ def display_candle(
update_width_config=dict(
candle_linewidth=1.0, candle_width=0.8, volume_linewidth=1.0
),
warn_too_much_data=10000,
**kwargs,
)
else:
fig = make_subplots(
@@ -349,60 +363,70 @@ def display_candle(
row=1,
col=1,
)
fig.add_trace(
go.Scatter(
x=df_stock.index,
y=df_stock["ma20"],
name="MA20",
mode="lines",
line=go.scatter.Line(color="royalblue"),
),
row=1,
col=1,
)
fig.add_trace(
go.Scatter(
x=df_stock.index,
y=df_stock["ma50"],
name="MA50",
mode="lines",
line=go.scatter.Line(color="black"),
),
row=1,
col=1,
)
if ma:
plotly_colors = [
"black",
"teal",
"blue",
"purple",
"orange",
"gray",
"deepskyblue",
]
for idx, ma_val in enumerate(ma):
temp = df_stock["Adj Close"].copy()
temp[f"ma{ma_val}"] = df_stock["Adj Close"].rolling(ma_val).mean()
temp = temp.dropna()
fig.add_trace(
go.Scatter(
x=temp.index,
y=temp[f"ma{ma_val}"],
name=f"MA{ma_val}",
mode="lines",
line=go.scatter.Line(
color=plotly_colors[np.mod(idx, len(plotly_colors))]
),
),
row=1,
col=1,
)
if "OC_High_trend" in df_stock.columns:
fig.add_trace(
go.Scatter(
x=df_stock.index,
y=df_stock["OC_High_trend"],
name="High Trend",
mode="lines",
line=go.scatter.Line(color="green"),
),
row=1,
col=1,
)
if "OC_Low_trend" in df_stock.columns:
fig.add_trace(
go.Scatter(
x=df_stock.index,
y=df_stock["OC_Low_trend"],
name="Low Trend",
mode="lines",
line=go.scatter.Line(color="red"),
),
row=1,
col=1,
)
if add_trend:
if "OC_High_trend" in df_stock.columns:
fig.add_trace(
go.Scatter(
x=df_stock.index,
y=df_stock["OC_High_trend"],
name="High Trend",
mode="lines",
line=go.scatter.Line(color="green"),
),
row=1,
col=1,
)
if "OC_Low_trend" in df_stock.columns:
fig.add_trace(
go.Scatter(
x=df_stock.index,
y=df_stock["OC_Low_trend"],
name="Low Trend",
mode="lines",
line=go.scatter.Line(color="red"),
),
row=1,
col=1,
)
colors = [
"red" if row.Open < row["Adj Close"] else "green"
for _, row in df_stock.iterrows()
]
fig.add_trace(
go.Bar(
x=df_stock.index,
y=df_stock.Volume,
name="Volume",
marker_color="#696969",
marker_color=colors,
),
row=2,
col=1,
@@ -440,11 +464,29 @@ def display_candle(
type="date",
),
)
fig.update_layout(
updatemenus=[
dict(
buttons=[
dict(
label="linear",
method="relayout",
args=[{"yaxis.type": "linear"}],
),
dict(
label="log", method="relayout", args=[{"yaxis.type": "log"}]
),
]
)
]
)
if intraday:
fig.update_xaxes(
rangebreaks=[
dict(bounds=["sat", "mon"]),
dict(bounds=[16, 9.5], pattern="hour"),
dict(bounds=[20, 9], pattern="hour"),
]
)