<jupyter_start><jupyter_text>**트레이딩 전략과 구현 6장 | 볼린저 밴드 매매2 | 반전매매 기법****[파이썬 증권 데이터 분석 6장 | nbviewer](https://nbviewer.jupyter.org/github/INVESTAR/StockAnalysisInPython/tree/master/06_Trading_Strategy/)** **1 반전 (Reversals) 매매기법**- **일중 강도율 (Intraday Intensity)** 와 **매집 분산율 (AD%)** 을 기술적 지표로 활용- 둘 중 **일중 강도율(II%)** 하나만 활용하여 매매한다- 매수 : 주가 하단밴드 부근에서 W패턴을 나타내고, 강제 지표가 확증할 때(%b가 0.05보다 작고,II% 가 0보다 클 때)- 매도 : 상단 밴드 부근에서 일련으 주가 Tag가 일어나며, 약세 지표가 확증할 때 (%b가 0.95보다 크고, II%가 0보다 작을 때) **01 데이터 불러오기 + 볼린저 밴드 추가**<jupyter_code>import os
import pandas as pd
file_save = "data/boillingeSkHy.csv"
if os.path.isfile(file_save):
    data_df = pd.read_csv(file_save)
    data_df['Date'] = pd.to_datetime(data_df['Date']) # datetime 포맷 변경
    data_df = data_df.set_index('Date')
else:
    from FinanceDataReader import DataReader as fdr
    data_df = fdr("000660", "2019-01-01")
    data_df.to_csv(file_save)

data_df.columns = [_.lower() for _ in data_df.columns]
data_raw = data_df.copy()
data_df.tail(3)<jupyter_output><empty_output><jupyter_text>**02 일중 강도율**거래 범위 내에서 **종가의 위치** 를 토대로 **종목내 자금 흐름** 을 설명한다$$ 일중강도 = {\frac{2 \times close-high-low}{high-low}} \times volume $$$$ 일중 강도율 = {\frac{ 일중강도 (21일) 합계 }{ 거래량 (21일) 합계 }} \times 100 $$<jupyter_code># 볼린저 밴드 계산하기
data_df['MA20'] = data_df['close'].rolling(window=20).mean() 
data_df['stddev'] = data_df['close'].rolling(window=20).std() 
data_df['upper'] = data_df['MA20'] + (data_df['stddev'] * 2)
data_df['lower'] = data_df['MA20'] - (data_df['stddev'] * 2)
data_df['PB'] = (data_df['close'] - data_df['lower'])\
        / (data_df['upper'] - data_df['lower']) # %b 를 계산한다

# 일중강도 : 일중 강도율 계산하기
data_df['II'] = (2 * data_df['close'] - data_df['high'] - data_df['low'])\
        / (data_df['high'] - data_df['low']) * data_df['volume']
# 일중강도율 : 21간의 일중 강도율 합계 
data_df['IIP21'] = data_df['II'].rolling(window=21).sum()\
        / data_df['volume'].rolling(window=21).sum()*100
data_df = data_df.dropna()
data_df.tail(3)<jupyter_output><empty_output><jupyter_text>**03 Visualization**결과값 시각화 작업<jupyter_code>%matplotlib inline
%config InlineBackend.figure_format = 'retina'

# Loading ... Visualization Modules
import matplotlib.pyplot as plt
import warnings
plt.style.use('seaborn')
warnings.simplefilter(action='ignore', category=FutureWarning)

from matplotlib.font_manager import fontManager as fm # 한글폰트 확인 및 추가
font_list_check  = ['D2Coding', 'NanumGothicCoding', 'NanumGothic']
for _ in font_list_check:
    font_counts = [f  for f in font_list_check if _ in [_.name for _ in fm.ttflist]]
    if len(font_counts) > 1: print(f"found : {_}"); plt.rc('font', family=_); break 
plt.figure(figsize=(20, 8))
plt.subplot(3, 1, 1) # 볼린저 밴드 그리기
plt.title('SK Hynix Bollinger Band(20 day, 2 std) - Reversals')
plt.plot(data_df.index, data_df['close'], 'b', label='Close')
plt.plot(data_df.index, data_df['upper'], 'r--', label ='Upper band')
plt.plot(data_df.index, data_df['MA20'], 'k--', label='Moving average 20')
plt.plot(data_df.index, data_df['lower'], 'c--', label ='Lower band')
plt.fill_between(data_df.index, data_df['upper'], data_df['lower'], color='0.9')
plt.legend(loc='best')

plt.subplot(3, 1, 2) # 볼린저밴드 간격 변화값
plt.plot(data_df.index, data_df['PB'], 'b', label='%b')
plt.grid(True)
plt.legend(loc='best')

plt.subplot(3, 1, 3)  # 일중 강도율
plt.bar(data_df.index, data_df['IIP21'], color='g', label='II% 21day')  # ④
plt.grid(True)
plt.legend(loc='best')
plt.show()<jupyter_output><empty_output><jupyter_text>**04 Visualization2 | 반전매매 구현하기**- 매수시점 : $ \%b  0 $ - 매도시점 : $ \%b > 0.95 $ , $ (21일) 일중강도율 < 0 $<jupyter_code>plt.figure(figsize=(20, 8))
plt.subplot(3, 1, 1)  # 볼린저 밴드 그리기
plt.title('SK Hynix Bollinger Band(20 day, 2 std) - Reversals')
plt.plot(data_df.index, data_df['close'], label='Close', color="orange")
plt.plot(data_df.index, data_df['upper'], 'r--', label ='Upper band')
plt.plot(data_df.index, data_df['MA20'], 'k--', label='Moving average 20')
plt.plot(data_df.index, data_df['lower'], 'c--', label ='Lower band')
plt.fill_between(data_df.index, data_df['upper'], data_df['lower'], color='0.9')
for i in range(0, len(data_df.close)):
    if data_df.PB.values[i] < 0.05 and data_df.IIP21.values[i] > 0: # 매수시점
        plt.plot(data_df.index.values[i], data_df.close.values[i], 'r^')
    elif data_df.PB.values[i] > 0.95 and data_df.IIP21.values[i] < 0: # 매도시점
        plt.plot(data_df.index.values[i], data_df.close.values[i], 'bv')
plt.legend(loc='best')

plt.subplot(3, 1, 2) # 볼린저 밴드 변동률
plt.plot(data_df.index, data_df['PB'], 'b', label='%b')
plt.grid(True)
plt.legend(loc='best')

plt.subplot(3, 1, 3)  # 일중 강도율
plt.bar(data_df.index, data_df['IIP21'], color='g', label='II% 21day')
for i in range(0, len(data_df.close)):
    if data_df.PB.values[i] < 0.05 and data_df.IIP21.values[i] > 0:
        plt.plot(data_df.index.values[i], 0, 'r^')
    elif data_df.PB.values[i] > 0.95 and data_df.IIP21.values[i] < 0:
        plt.plot(data_df.index.values[i], 0, 'bv')
plt.grid(True)
plt.legend(loc='best')
plt.show()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.19578193394349383, 'fraction_numerical': 0.031436530043772386, 'mean_word_length': 4.984523809523809, 'pattern_counts': {'":': 0, '<': 22, '<?xml version=': 0, '>': 23, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '498625', 'license': 'BSD-3-Clause', 'n_tokens_mistral': 2588, 'n_tokens_neox': 2639, 'n_words': 444, 'path': 'stock-books/T2_boll2reverse.ipynb', 'repo_name': 'YongBeomKim/TradingPython', 'size': '5026'}