1. TA(Technical Analysis) Library in Python

 - Pandas, Numpy 기반을 작성되었고, financial time Series dataset(Open, Close, High, Low, Volume) 자료로 지표자료를 계산합니다.

 

 - 라이브러리 사용 URL: https://technical-analysis-library-in-python.readthedocs.io/en/latest/ta.html

 - github URL: https://github.com/bukosabino/ta

 - matplotlib : https://matplotlib.org/3.5.1/index.html

2. 사용가능한 지표

Volume

  • Money Flow Index (MFI)
  • Accumulation/Distribution Index (ADI)
  • On-Balance Volume (OBV)
  • Chaikin Money Flow (CMF)
  • Force Index (FI)
  • Ease of Movement (EoM, EMV)
  • Volume-price Trend (VPT)
  • Negative Volume Index (NVI)
  • Volume Weighted Average Price (VWAP)

Volatility

  • Average True Range (ATR)
  • Bollinger Bands (BB)
  • Keltner Channel (KC)
  • Donchian Channel (DC)
  • Ulcer Index (UI)

Trend

  • Simple Moving Average (SMA)
  • Exponential Moving Average (EMA)
  • Weighted Moving Average (WMA)
  • Moving Average Convergence Divergence (MACD)
  • Average Directional Movement Index (ADX)
  • Vortex Indicator (VI)
  • Trix (TRIX)
  • Mass Index (MI)
  • Commodity Channel Index (CCI)
  • Detrended Price Oscillator (DPO)
  • KST Oscillator (KST)
  • Ichimoku Kinkō Hyō (Ichimoku) (일목균형표)
  • Parabolic Stop And Reverse (Parabolic SAR)
  • Schaff Trend Cycle (STC)

Momentum

  • Relative Strength Index (RSI)
  • Stochastic RSI (SRSI)
  • True strength index (TSI)
  • Ultimate Oscillator (UO)
  • Stochastic Oscillator (SR)
  • Williams %R (WR)
  • Awesome Oscillator (AO)
  • Kaufman's Adaptive Moving Average (KAMA)
  • Rate of Change (ROC)
  • Percentage Price Oscillator (PPO)
  • Percentage Volume Oscillator (PVO)

Others

  • Daily Return (DR)
  • Daily Log Return (DLR)
  • Cumulative Return (CR)

3. 사용법

설치

pip install --upgrade ta

 

전체 지표 계산코드. 한번에 계산할 수 있는 모든 지표를 처리하는데, 지표가 많다보니 경고가 나옵니다.

계산 시간도 있을 테고, 비효율적이라 추천하지는 않습니다.

import pandas as pd
from ta import add_all_ta_features
from ta.utils import dropna


# Load datas
df = pd.read_csv('ta/tests/data/datas.csv', sep=',')

# Clean NaN values
df = dropna(df)

# Add all ta features
df = add_all_ta_features(
    df, open="Open", high="High", low="Low", close="Close", volume="Volume_BTC")

 

4. 샘플

https://github.com/bukosabino/ta/tree/master/examples_to_use

 

GitHub - bukosabino/ta: Technical Analysis Library using Pandas and Numpy

Technical Analysis Library using Pandas and Numpy. Contribute to bukosabino/ta development by creating an account on GitHub.

github.com

 

import numpy as np
import pandas as pd
from trade.util.db_helper import *
from ta.trend import IchimokuIndicator
import matplotlib.dates as mdates
from mplfinance.original_flavor import candlestick_ohlc
from matplotlib import rc, font_manager
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec

# 종목코드
code = '010060'
db_name = 'RSIStrategy'

# 300건으로 분석
sql = f"""
SELECT *
FROM (
SELECT `index`, open, high, low, close, volumn as volume FROM `{code}` ORDER BY `index` DESC LIMIT 300
)
ORDER BY `INDEX`            
"""

# database에서 일별 거래정보 조회
cur = execute_sql(db_name, sql)

cols = [column[0] for column in cur.description]
df = pd.DataFrame.from_records(data=cur.fetchall(), columns=cols)
df = df.set_index('index')

# 일목균형표 데이터 생성
id_ichimoku = IchimokuIndicator(high=df['high'], low=df['low'], visual=True, fillna=True)
df['span_a'] = id_ichimoku.ichimoku_a()
df['span_b'] = id_ichimoku.ichimoku_b()
df['base_line'] = id_ichimoku.ichimoku_base_line()
df['conv_line'] = id_ichimoku.ichimoku_conversion_line()

# 한글폰트
f_path = "C:/windows/Fonts/malgun.ttf"
font_manager.FontProperties(fname=f_path).get_name()
rc('font', family='Malgun Gothic')

fig = plt.figure(figsize=(12, 8))
fig.set_facecolor('w')
gs = gridspec.GridSpec(2, 1, height_ratios=[3, 1])

# fig, ax = plt.subplots(1, 1, figsize=(10, 6), constrained_layout=True)
axs = []
axs.append(plt.subplot(gs[0]))
axs.append(plt.subplot(gs[1], sharex=axs[0]))

for ax in axs:
    ax.xaxis.set_major_locator(mdates.MonthLocator(bymonth=range(1, 13)))
    ax.xaxis.set_minor_locator(mdates.MonthLocator())

# ax. 캔들 차트
ax = axs[0]
x = np.arange(len(df.index))
ohlc = df[['open', 'high', 'low', 'close']].astype(int).values
dohlc = np.hstack((np.reshape(x, (-1, 1)), ohlc))
candlestick_ohlc(ax, dohlc, width=0.5, colorup='r', colordown='b')

# 일목균형표 추가
# ax.plot(df.close, label='close', linestyle='solid', color='purple', linewidth=2)
ax.plot(df.span_a, label='span_a', linestyle='solid', color='pink')
ax.plot(df.span_b, label='span_b', linestyle='solid', color='lightsteelblue')
ax.plot(df.base_line, label='base_line', linestyle='solid', color='green', linewidth=2)
ax.plot(df.conv_line, label='conv_line', linestyle='solid', color='darkorange')
ax.grid(True, axis='y', color='grey', alpha=0.5, linestyle='--')
ax.fill_between(df.index, df.span_a, df.span_b, alpha=0.3)

ax.set_title(f'OCI({code}) - 일목균형표')
ax.legend()

# ax2. 거래량 차트
ax2 = axs[1]
ax2.bar(x, df['volume'], color='k', width=0.6, align='center')

plt.tight_layout()
plt.show()

 

 

end.

728x90

일목균형표를 해외에서는 Ichimoku Kinkō Hyō 라고 부럽니다. (일본어를 영어식 발음으로 한 듯)

 

사이트 URL: https://stockcharts.com/h-sc/ui

지표에대한 설명: https://school.stockcharts.com/doku.php?id=technical_indicators:ichimoku_cloud 

 

설정을 아래와 같이 몇가지 변경해야, 국내에서 볼 수 있는 차표처럼 보입니다.

아래 Indicators 에 지표 추가도 가능하네요.

 

 

728x90

엠피엘파이낸스 패키지를 이용한 캔들 차트 표시

일거래 데이터는 증권사로 부터 내려받아서 RSIStrategy.db에 종목별로 보관하고 있고, 

테이블 조회 후 캐들 차트를 표시함.

 

일자를 datetime으로 변화해줘야 함.

 

엠피엘파이낸스 패키지 링크: https://github.com/matplotlib/mplfinance

 

import sqlite3
import pandas as pd
import mplfinance as mpf


def execute_sql(sql, param={}):
    with sqlite3.connect('RSIStrategy.db') as con:
        cur = con.cursor()
        cur.execute(sql, param)
        return cur

code = '010060' # OCI
sql = '''SELECT Date, Open, High, Low, Close, Volume
  FROM (
		SELECT `index` as Date, Open, High, Low, Close, Volumn as Volume
		 , ROW_NUMBER() over(order by "index" desc ) as rownum 
		  FROM `{}`
       )
where rownum <= 150  
'''.format(code)

cur = execute_sql(sql)
cols = [column[0] for column in cur.description]
df = pd.DataFrame.from_records(data=cur.fetchall(), columns=cols)
df = df.sort_values(by='Date')
df.index = pd.to_datetime(df['Date'], format='%Y%m%d')
df = df[['Open', 'High', 'Low', 'Close', 'Volume']]
print(df)

kwargs = dict(title='OCI candle chart', type='candle', mav=(5, 10, 20), volume=True, ylabel='ohlc candles')
mc = mpf.make_marketcolors(up='r', down='b', inherit=True)
s = mpf.make_mpf_style(marketcolors=mc)
# mpf.plot(df, title='OCI candle chart', type='candle')
mpf.plot(df, **kwargs, style=s)

 

728x90

RSI_SMA: RSI 단순이동평균 지표. 커틀러RSI라고 함.

 

 - backtrader URL: https://www.backtrader.com/

 - 참조서적: http://www.yes24.com/Product/Goods/90578506

 

파이썬 증권 데이터 분석 - YES24

투자 기법과 프로그래밍 기술로 자신만의 퀀트 투자 시스템을 완성하라『파이썬 증권 데이터 분석』은 웹 스크레이핑으로 증권 데이터를 주기적으로 자동 수집, 분석, 자동 매매, 예측하는 전

www.yes24.com

 

backtrader 지원 지표 (bt.indicators 패키지)

 

 - Indicator Reference : https://www.backtrader.com/docu/indautoref/

 - 커뮤니티: https://community.backtrader.com/

 

  • Accdecoscillator
  • ATR
  • Bollinger
  • CCI
  • Crossover
  • Deviation
  • DirectionalMove
  • DMA
  • EMA
  • Ichimoku (일목균형표)
  • MACD
  • Momentum
  • Sma: Simple Moving Average
  • Stochastic
  • Willams
  • WMA

 

 

아래 샘플에서 차트를 표시하려면, matplotlib버전을 3.2.2 로 내려야 합니다. !!!

pip uninstall matplotlib
pip instaill matplotlib==3.3.2

 

import backtrader as bt
import yfinance as yf

class MyStrategy(bt.Strategy):
    def __init__(self):
        self.dataclose = self.datas[0].close
        self.order = None
        self.buyprice = None
        self.buycomm = None
        self.rsi = bt.indicators.RSI_SMA(self.data.close, period=21)

    def notify_order(self, order):
        if order.status in [order.Submitted, order.Accepted]:
            return
        if order.status in [order.Completed]:
            if order.isbuy():
                self.log(f'BUY  : 주가 {order.executed.price:,.0f}, '
                    f'수량 {order.executed.size:,.0f}, '
                    f'수수료 {order.executed.comm:,.0f}, '        
                    f'자산 {cerebro.broker.getvalue():,.0f}')
                self.buyprice = order.executed.price
                self.buycomm = order.executed.comm
            else:
                self.log(f'SELL : 주가 {order.executed.price:,.0f}, '
                    f'수량 {order.executed.size:,.0f}, '
                    f'수수료 {order.executed.comm:,.0f}, '
                    f'자산 {cerebro.broker.getvalue():,.0f}')
            self.bar_executed = len(self)
        elif order.status in [order.Canceled]:
            self.log('ORDER CANCELD')
        elif order.status in [order.Margin]:
            self.log('ORDER MARGIN')
        elif order.status in [order.Rejected]:
            self.log('ORDER REJECTED')
        self.order = None

    def next(self):
        if not self.position:
            if self.rsi < 30:
                self.order = self.buy()
        else:
            if self.rsi > 70:
                self.order = self.sell()

    def log(self, txt, dt=None):
        dt = self.datas[0].datetime.date(0)
        print(f'[{dt.isoformat()}] {txt}')

cerebro = bt.Cerebro()
cerebro.addstrategy(MyStrategy)
# data = bt.feeds.YahooFinanceData(dataname='036570.KS', fromdate=datetime(2017, 1, 1), todate=datetime(2019, 12, 1))
data = bt.feeds.PandasData(dataname=yf.download('036570.KS', '2018-01-01', '2021-12-01'))

cerebro.adddata(data)
cerebro.broker.setcash(10000000)
cerebro.broker.setcommission(commission=0.0014)
cerebro.addsizer(bt.sizers.PercentSizer, percents=90)

print(f'Initial Portfolio Value : {cerebro.broker.getvalue():,.0f} KRW')
cerebro.run()
print(f'Final Portfolio Value   : {cerebro.broker.getvalue():,.0f} KRW')
cerebro.plot(style='candlestick')

 

[*********************100%***********************]  1 of 1 completed
Initial Portfolio Value : 10,000,000 KRW
[2018-03-02] BUY  : 주가 370,000, 수량 24, 수수료 12,432, 자산 10,083,568
[2018-04-02] SELL : 주가 425,000, 수량 -24, 수수료 14,280, 자산 11,293,288
[2018-04-25] BUY  : 주가 358,000, 수량 28, 수수료 14,150, 자산 11,166,205
[2018-09-13] SELL : 주가 427,000, 수량 -28, 수수료 16,878, 자산 13,210,352
[2019-02-22] BUY  : 주가 444,000, 수량 27, 수수료 16,645, 자산 12,832,207
[2019-03-29] SELL : 주가 498,000, 수량 -27, 수수료 18,669, 자산 14,621,035
[2019-06-04] BUY  : 주가 467,500, 수량 28, 수수료 18,522, 자산 14,305,377
[2019-08-05] SELL : 주가 520,000, 수량 -28, 수수료 20,602, 자산 16,067,598
[2019-10-07] BUY  : 주가 509,000, 수량 29, 수수료 20,365, 자산 16,104,390
[2020-01-03] SELL : 주가 547,000, 수량 -29, 수수료 21,886, 자산 17,111,339
[2020-03-20] BUY  : 주가 559,000, 수량 29, 수수료 22,740, 자산 17,321,055
[2020-05-26] SELL : 주가 813,000, 수량 -29, 수수료 33,073, 자산 24,436,002
[2020-08-05] BUY  : 주가 841,000, 수량 26, 수수료 30,607, 자산 24,535,374
[2020-12-14] SELL : 주가 896,000, 수량 -26, 수수료 32,609, 자산 25,802,552
[2021-03-30] BUY  : 주가 834,000, 수량 28, 수수료 32,511, 자산 26,076,330
[2021-11-12] SELL : 주가 757,000, 수량 -28, 수수료 29,510, 자산 23,596,506
Final Portfolio Value   : 23,596,506 KRW

 

728x90

'Etc > 주식 자동 매매' 카테고리의 다른 글

해외 일목균형표 분석 URL  (0) 2022.03.19
[Python] 캔들차트 표시  (0) 2022.03.15
[Python] 주식 백테스트 backtrader  (0) 2022.03.14
[주식자동매매] 매매전략 - RSI기반 역추세  (0) 2022.03.06
주식용어  (0) 2022.03.06

+ Recent posts