Files
DeepStock/stockpredictor/analysis/IchimokuCloud.py
dsyoon 890418a3ae init
2021-02-16 04:29:48 +09:00

128 lines
6.5 KiB
Python

import pandas as pd
import datetime
from plotly import tools, subplots
import plotly.offline as offline
import plotly.graph_objs as go
import plotly.io as po
from stockpredictor.analysis.Common import Common
# graph: https://plotly.com/python/candlestick-charts/
# https://www.nanumtrading.com/fx-%EB%B0%B0%EC%9A%B0%EA%B8%B0/%EC%B0%A8%ED%8A%B8-%EB%B3%B4%EC%A1%B0%EC%A7%80%ED%91%9C-%EC%9D%B4%ED%95%B4/06-%EC%9D%BC%EB%AA%A9%EA%B7%A0%ED%98%95%ED%91%9C/
# 일목균형표 - 매매기법 알아보기 !: https://layhope.tistory.com/222
class IchimokuCloud:
common = None
def __init__(self):
self.common = Common()
return
def draw(self, stock):
item_name = stock["NAME"]
item_code = stock["CODE"]
df = pd.DataFrame(stock["PRICE"])
leadingSpan1 = go.Scatter(x=df.DATE, y=df['leadingSpan1'], name="선행스팬", line_color='#8B4513')
leadingSpan2 = go.Scatter(x=df.DATE, y=df['leadingSpan2'], name="후행스팬", line_color='#4169E1')
candle = go.Candlestick(x=df.DATE, open=df.open, high=df.high, low=df.low, close=df.close,
increasing_line_color= 'red', decreasing_line_color= 'blue')
data = [leadingSpan1, leadingSpan2, candle]
layout = go.Layout(title='{} MACD 그래프'.format(item_name))
fig = subplots.make_subplots(rows=1, cols=1, shared_xaxes=True)
for trace in data:
fig.append_trace(trace, 1,1)
fig = go.Figure(data=data, layout=layout)
path = "/Users/dsyoon/workspace/StockPredictor/resources/analysis/html"
po.write_html(fig, file=path + "/ichimokuCloud_" + item_code+'.html', auto_open=False)
return fig
# c=9, b=26, l=52
def apply(self, df, c=9, b=26, l=52):
# 입력받은 값이 dataframe이라는 것을 정의해줌
df = pd.DataFrame(df)
# 1. 전환선 = (과거 9일 동안 최고가 + 최저가) / 2
# 당일을 포함한 9일 동안의 최고가와 최저가의 중간 값을 평균으로 나타낸다.
changeLine = (df.high.rolling(c).max() + df.low.rolling(c).min()) / 2
# 2. 기준선 = 과거 26일 동안 최고가 + 최저가) / 2
# 당일을 포함한 26일 동안의 최고가와 최저가의 중간 값을 평균으로 나타낸다.
baseLine = (df.high.rolling(b).max() + df.low.rolling(b).min()) / 2
# 3. 선행스팬 1 = ((기준선 + 전환선) / 2)를 26일 선행하여 배치
# 전환선과 기준선의 평균값을 구해 당일 포함 26일 앞으로 이동시킨 선 (중-단기 구간의 힘을 보여줌)
leadingSpan1 = (changeLine + baseLine) / 2
move_LeadingSpan1 = list(leadingSpan1.values)
for i in range(b - 1):
move_LeadingSpan1.insert(0, None)
# 4. 선행스팬 2 = ((최근 52일 동안 최고가 + 최저가) / 2)를 26일 선행하여 배치
# 당일을 포함한 52일 동안의 최고가와 최저가의 평균을 26일 앞으로 이동시킨 선 (장기으로 형성된 선이기 때문에 가장 느리게 변함)
leadingSpan2 = (df.high.rolling(l).max() + df.low.rolling(l).min()) / 2
move_LeadingSpan2 = list(leadingSpan2.values)
for i in range(l - 1):
move_LeadingSpan2.insert(0, None)
# leadingSpan2에 맞추어 뒤로 빈 row를 채운다.
for i in range(len(move_LeadingSpan2) - len(df)):
df = df.append({"DATE": None, "close": None, "diff": None, "open": None, "high": None, "low": None, "volume": None, "avg3": None, "avg5": None, "avg7": None, "avg10": None, "avg20": None, "avg30": None, "avg60": None, "avg90": None, "avg100": None, "avg120": None, "avg150": None, "avg180": None, "avg200": None, "avg240": None}, ignore_index=True)
move_changeLine = list(changeLine.values)
for i in range(len(move_LeadingSpan2) - len(move_changeLine)):
move_changeLine.append(None)
move_baseLine = list(baseLine.values)
for i in range(len(move_LeadingSpan2) - len(move_baseLine)):
move_baseLine.append(None)
for i in range(len(move_LeadingSpan2) - len(move_baseLine)):
move_LeadingSpan1.append(None)
# dataframe에 컬럼 추가
df = df.assign(changeLine=pd.Series(move_changeLine), baseLine=pd.Series(move_baseLine), leadingSpan1=pd.Series(move_LeadingSpan1), leadingSpan2=pd.Series(move_LeadingSpan2))
return df
# 일목균형표의 구성을 훑어보면 주가를 선행과 후행으로 과거의 주가를 통해 미래 혹은 현재의 주식의 가격의 추세를 예측해보려는 지표라는 것을 이해할 수 있다.
# 또한 구름층의 색을 통해서 주식의 추세를 손쉽게 확인할 수 있을 것 같다는 것도 이해할 수 있다면 끝 !
def analyze(self, stock):
df = pd.DataFrame()
df = df.from_dict(stock['PRICE'])
df = self.apply(df)
diff = len(df.changeLine) - len(stock['PRICE'])
lastDay = stock['PRICE'][len(stock['PRICE']) - 1]['DATE']
tmpLastDay = datetime.datetime.strptime(lastDay, "%Y-%m-%d")
for i in range(diff):
nextDay = tmpLastDay + datetime.timedelta(days=(i + 1))
stock['PRICE'].append(
{"DATE": nextDay.strftime("%Y-%m-%d"), "close": 0, "diff": 0, "open": 0, "high": 0, "low": 0, "volume": 0,
"avg3": 0, "avg5": 0, "avg7": 0, "avg10": 0, "avg20": 0, "avg30": 0, "avg60": 0, "avg90": 0, "avg100": 0,
"avg120": 0, "avg150": 0, "avg180": 0, "avg200": 0, "avg240": 0})
for i in range(len(df.changeLine)):
stock['PRICE'][i]['ichimoku_buy'] = 0
stock['PRICE'][i]['changeLine'] = df.changeLine.values[i]
stock['PRICE'][i]['baseLine'] = df.baseLine.values[i]
stock['PRICE'][i]['leadingSpan1'] = df.leadingSpan1.values[i]
stock['PRICE'][i]['leadingSpan2'] = df.leadingSpan2.values[i]
for i in range(len(df.changeLine)):
stock['PRICE'][i]['ichimoku_buy'] = self.common.getIchimokuCloudScore(stock['PRICE'], i)
results = []
for day in stock['PRICE']:
results.append({'DATE': day['DATE'],
'changeLine': day['changeLine'],
'baseLine': day['baseLine'],
'leadingSpan1': day['leadingSpan1'],
'leadingSpan2': day['leadingSpan2'],
'ichimoku_buy': day['ichimoku_buy']})
return results
if __name__ == "__main__":
ichimokuCloud = IchimokuCloud()