-
Notifications
You must be signed in to change notification settings - Fork 372
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a62ab5c
commit b166e9c
Showing
14 changed files
with
1,332 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,254 @@ | ||
#-*- coding: utf-8 -*- | ||
# | ||
# FinaceDataReader chart.py | ||
# (c)2018-2024 FinaceData.KR | ||
|
||
from FinanceDataReader.chart import (plot, candle, line) | ||
|
||
# import numpy as np | ||
# import pandas as pd | ||
# from datetime import datetime, date | ||
# import itertools | ||
|
||
# plotly_install_msg = f''' | ||
# {'-' * 80} | ||
# FinanceDataReade.chart.plot() dependen on plotly | ||
# plotly not installed please install as follows | ||
|
||
# pip install plotly | ||
|
||
# FinanceDataReade.chart.plot()는 plotly에 의존성이 있습니다. | ||
# 명령창에서 다음과 같이 plotly를 설치하세요 | ||
|
||
# pip install plotly | ||
# ''' | ||
|
||
# try: | ||
# import plotly.graph_objects as go | ||
# from plotly.subplots import make_subplots | ||
# except ModuleNotFoundError as e: | ||
# raise ModuleNotFoundError(plotly_install_msg) | ||
|
||
# ## holiday Calendar | ||
# holidays_url_base = 'https://raw.githubusercontent.com/FinanceData/FinanceDataReader/master/calendars' | ||
|
||
# holidays_krx,holidays_hyse = None, None | ||
|
||
# ## Chart plot | ||
# def plot(df, tools=None, layout=None): | ||
# ''' | ||
# plot candle chart with DataFrame | ||
# * df: OHLCV data(DataFrame) | ||
# * updates: additional chart configurations | ||
# ''' | ||
# global holidays_krx, holidays_hyse | ||
|
||
# if holidays_krx is None: | ||
# holidays_krx = pd.read_csv(f'{holidays_url_base}/holidays-krx.csv')['date'].values | ||
# if holidays_hyse is None: | ||
# holidays_hyse = pd.read_csv(f'{holidays_url_base}/holidays-nyse.csv')['date'].values | ||
|
||
|
||
# tools = {'SMA': [10, 20, 60]} if not tools else tools | ||
# layout = dict() if not layout else layout | ||
|
||
# x_ticks = df.index | ||
|
||
# change = df["Close"].pct_change() | ||
# oc_ratio = (df["Close"]-df["Open"])/df["Open"] | ||
# oh_ratio = (df["High"]-df["Open"])/df["Open"] | ||
# hover_text = [f'DoD: {chg:.1%} OC: {oc:.1%}, OH: {oh:.1%}' for chg, oc, oh in zip(change, oc_ratio, oh_ratio)] | ||
|
||
# # OHLC candle chart | ||
# candle = go.Candlestick( | ||
# x=x_ticks, | ||
# open=df["Open"], high=df["High"], low=df["Low"], close=df["Close"], | ||
# name='', | ||
# text = hover_text, | ||
# increasing_fillcolor = 'red', | ||
# decreasing_fillcolor = 'blue', | ||
# increasing_line_color = 'red', | ||
# decreasing_line_color = 'blue', | ||
# increasing_line_width = 1.5, | ||
# decreasing_line_width = 1.5, | ||
# showlegend = False, | ||
# opacity=0.75, | ||
# ) | ||
|
||
# # volume bar chart | ||
# vol_colors = np.where(df['Close'].shift(1) > df['Close'], 'blue', 'red') | ||
# vol_bar = go.Bar( | ||
# x=x_ticks, | ||
# y=df['Volume'], | ||
# showlegend=False, | ||
# name='', | ||
# opacity = 0.5, | ||
# marker={'color': vol_colors}, | ||
# ) | ||
|
||
# fig = make_subplots(rows=2, cols=1, | ||
# shared_xaxes=True, | ||
# vertical_spacing=0, | ||
# row_width=[0.3, 0.7]) | ||
|
||
# fig.add_trace(candle, row=1, col=1) | ||
# fig.add_trace(vol_bar, row=2, col=1) | ||
|
||
# # hide rangeslider | ||
# fig.update_xaxes(rangeslider_visible=False) | ||
|
||
# # holidays | ||
# holidays = holidays_krx | ||
# if df.attrs.get('exchange') != 'KRX': | ||
# holidays = holidays_hyse | ||
|
||
# # Remove non-business days | ||
# fig.update_xaxes(rangebreaks = [ | ||
# dict(bounds=['sat','mon']), # remove weekend | ||
# dict(values=holidays), # remove non biz days | ||
# # dict(bounds=[15.5, 9], pattern='hour'), # remove non biz hours | ||
# ]) | ||
|
||
# # draw axes and grid | ||
# fig.update_xaxes(showline=True, linewidth=1, linecolor='black', gridcolor='lightgray') | ||
# fig.update_yaxes(showline=True, linewidth=1, linecolor='black', gridcolor='lightgray') | ||
|
||
# # x-axis tick format | ||
# fig.update_xaxes(tickformat='%Y-%m-%d', row=2, col=1) | ||
# fig.update_xaxes(tickangle=45) | ||
|
||
# # y-axis tick format | ||
# fig.update_yaxes(tickformat=',', row='all', col=1) | ||
|
||
# # spikes | ||
# fig.update_xaxes(showspikes=True, spikethickness=1, spikedash="dot", spikecolor="lightgray", spikemode="across", spikesnap='cursor') | ||
# # fig.update_traces(xaxis="x2") # binding x-axis | ||
|
||
# # bgcolor | ||
# fig.update_layout(plot_bgcolor='white') | ||
# fig.update_layout(paper_bgcolor='white') | ||
|
||
# ## tools (tools: indicators and annotations) | ||
|
||
# # available_tools | ||
# available_tools = ['SMA', 'EMA', 'HLINE', 'VLINE', 'VRECT'] | ||
|
||
# for key in tools: | ||
# if key.upper() not in available_tools: | ||
# raise ValueError(f"Unsupport tool: {key}") | ||
|
||
# tools = {key.upper(): tools[key] for key in tools} # keys to upper case | ||
|
||
# # default tools | ||
# # default_ma_params = [10, 20, 60] # default moving averages params | ||
# # if all(x not in tools.keys() for x in ['SMA', 'EMA']): | ||
# # tools['SMA'] = default_ma_params | ||
|
||
# line_dashes = ['solid', 'dot', 'dash', 'longdash', 'dashdot', 'longdashdot'] | ||
# line_colors = ['darkmagenta', 'gold', 'limegreen', 'maroon', 'chocolate', 'seagreen', 'coral'] | ||
# line_style_cycler = itertools.cycle(itertools.product(line_dashes, line_colors)) | ||
|
||
# default_line_width = 0.75 | ||
|
||
# if 'SMA' in tools: # SMA: simple moving average | ||
# args = tools.pop('SMA') | ||
# for arg in args: | ||
# line_dash, line_color = next(line_style_cycler) | ||
# ma_args = dict() | ||
# ma_args['line_width'] = default_line_width | ||
# if type(arg) == int: | ||
# window = arg | ||
# ma_args['line_dash'] = line_dash | ||
# ma_args['line_color'] = line_color | ||
# ma_args['line_width'] = default_line_width | ||
# elif type(arg) == dict: | ||
# window = arg['window'] | ||
# ma_args['line_dash'] = arg['line_dash'] if 'line_dash' in arg else line_dash | ||
# ma_args['line_color'] = arg['line_color'] if 'line_color' in arg else line_color | ||
# ma_args['line_width'] = arg['line_width'] if 'line_width' in arg else default_line_width | ||
# ma_price = df['Close'].rolling(window).mean().round(0) | ||
# ma_args['x'] = ma_price.index | ||
# ma_args['y'] = ma_price | ||
# ma_args['name'] = f'SMA_{window}' | ||
# fig.add_trace(go.Scatter(**ma_args), row=1, col=1) | ||
|
||
# if 'EMA' in tools: # EMA: exponential moving average | ||
# args = tools.pop('EMA') | ||
# for arg in args: | ||
# line_dash, line_color = next(line_style_cycler) | ||
# ma_args = dict() | ||
# ma_args['line_width'] = default_line_width | ||
# if type(arg) == int: | ||
# window = arg | ||
# ma_args['line_dash'] = line_dash | ||
# ma_args['line_color'] = line_color | ||
# ma_args['line_width'] = default_line_width | ||
# elif type(arg) == dict: | ||
# window = arg['window'] | ||
# ma_args.update(arg) | ||
# ma_args['line_dash'] = arg['line_dash'] if 'line_dash' in arg else line_dash | ||
# ma_args['line_color'] = arg['line_color'] if 'line_color' in arg else line_color | ||
# ma_args['line_width'] = arg['line_width'] if 'line_width' in arg else default_line_width | ||
# ma_price = df['Close'].ewm(span=window).mean() | ||
# ma_args['x'] = ma_price.index | ||
# ma_args['y'] = ma_price | ||
# ma_args['name'] = f'EMA_{window}' | ||
# fig.add_trace(go.Scatter(**ma_args), row=1, col=1) | ||
|
||
# if 'HLINE' in tools: # HLINE: Horizontal line | ||
# hline_args = dict(line_width=1.5, line_dash="dot", line_color="tomato", layer="below") | ||
# hline_value = tools.pop('HLINE') | ||
# if hasattr(hline_value, '__iter__'): | ||
# for hline in hline_value: | ||
# if type(hline) in [int, float]: | ||
# hline_args['y'] = hline | ||
# elif type(hline) == dict: | ||
# hline_args.update(hline) | ||
# else: | ||
# raise ValueError("'HLINE' must be list of str or list of dict") | ||
# fig.add_hline(**hline_args) | ||
# else: | ||
# hline_args['y'] = hline_value | ||
# fig.add_hline(**hline_args) # just one value | ||
|
||
# if 'VLINE' in tools: # VLINE: vertical line | ||
# vline_args = dict(line_width=1.5, line_dash="dot", line_color="tomato", layer="below") | ||
# vline_value = tools.pop('VLINE') | ||
# if hasattr(vline_value, '__iter__'): | ||
# for vline in vline_value: | ||
# if type(vline) in [pd.Timestamp, str, datetime, date]: | ||
# vline_args['x'] = pd.to_datetime(vline).timestamp() * 1000 | ||
# elif type(vline) == dict: | ||
# vline_args.update(vline) | ||
# vline_args['x'] = pd.to_datetime(vline_args['x']).timestamp() * 1000 | ||
# else: | ||
# raise ValueError("'VLINE' must be list of str or list of dict") | ||
# fig.add_vline(**vline_args) | ||
# else: | ||
# vline_args['y'] = vline_value | ||
# fig.add_hline(**vline_args) # just one value | ||
|
||
# if 'VRECT' in tools: # VRECT: highlighting period | ||
# vrect_list = tools.pop('VRECT') if 'VRECT' in tools else {} | ||
# for vrect in vrect_list: | ||
# vrect_args = dict(fillcolor="LightSalmon", opacity=0.3, layer="below", line_width=0) | ||
# if type(vrect) == tuple: | ||
# vrect_args['x0'] = str(vrect[0]) | ||
# vrect_args['x1'] = str(vrect[1]) | ||
# elif type(vrect) == dict: | ||
# vrect_args.update(vrect) | ||
# else: | ||
# raise ValueError("'vrect' must be list of tuple or list of dict") | ||
# fig.add_vrect(**vrect_args) | ||
|
||
# ## update_layout | ||
# layout_defaults = { | ||
# 'hovermode': 'x', # available hovermodes: 'closest', 'x', 'x unified', 'y', 'y unified' | ||
# 'margin': go.layout.Margin(l=0, r=0, b=0, t=0), # margins | ||
# 'width': 1280, | ||
# 'height': 640, | ||
# } | ||
# layout.update(layout_defaults) | ||
# fig.update_layout(layout) | ||
# return fig | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
from .plot import plot | ||
from .candle import candle |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.