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

백테스트

특정 투자 전략을 과거 데이터로 검증하는 작업.

백테스트 라이브러리

1. 집라인(Zipline): 대중적으로 많이 사용, 단점 느림. Python버전 환경 영향을 탐. 참조: https://wikidocs.net/4427
   - 재정지원에 중점. 이벤트 기반

   - https://github.com/quantopian/zipline

2. 파이알고트레이드(PyAlgoTrade) (무료) : https://gbeced.github.io/pyalgotrade/

   - 문서: http://gbeced.github.io/pyalgotrade/docs/v0.20/html/

   - 이벤트 기반

3. 트레이딩위드파이썬(TradingWithPython)

4. 파이백테스트(PyBackTest)

5. 백트레이더(BackTrader): 최근 각광, 오픈소스 기반
   https://www.backtrader.com/
 

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

  • Accdecoscillator
  • ATR
  • Bollinger
  • CCI
  • Crossover
  • Deviation
  • DirectionalMove
  • DMA
  • EMA
  • Ichimoku
  • MACD
  • Momentum
  • Sma
  • Stochastic
  • Willams
  • WMA

* 아래 오류 발생 시 matplotlib 버전을 3.2.2 로 재설치 한다.
pip uninstall matplotlib
pip install matplotlib==3.2.2

    from matplotlib.dates import (HOURS_PER_DAY, MIN_PER_HOUR, SEC_PER_MIN,
ImportError: cannot import name 'warnings' from 'matplotlib.dates' (/Users/jeahanjung/opt/anaconda3/envs/system_strading_py39_64/lib/python3.9/site-packages/matplotlib/dates.py)

 

import backtrader as bt
import yfinance as yf

class RsiStrategy(bt.Strategy):
    def __init__(self):
        self.rsi = bt.indicators.RSI(self.data.close)

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

        elif self.rsi > 70:
            self.order = self.sell()


cerebro = bt.Cerebro()  # create a "Cerebro" engine instance
cerebro.addstrategy(RsiStrategy)  # Add the trading strategy
# 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(1000*10000) # 초기투자 금액
cerebro.addsizer(bt.sizers.SizerFix, stake=30) # 매매단위

print(f'Initial Portfolio Value : {cerebro.broker.getvalue():,.0f} KRW')
cerebro.run()  # run it all
print(f'Final Portfolio Value : {cerebro.broker.getvalue():,.0f} KRW')
cerebro.plot()  # and plot it with a sing

[*********************100%***********************]  1 of 1 completed
Initial Portfolio Value : 10,000,000 KRW
Final Portfolio Value : 12,925,000 KRW

 

728x90

"쉽게 따라 만드는 파이썬 주식 자동매매 시스템" 책에 나온 매매 전략 요약

 

* 참조URL : https://thebook.io/080298/ch04/

 

1. 매매전략 - RSI기반 역추세

1.1 매수조건
 1) 20일 이동평균 > 60일 이동평균
 2) RSI(2) < 5
 3) 2일 전 주가 대비 현재 주가 변화율 < -2%(현재 주가가 2일 전보다 2% 이상 떨어진 경우)
    - 당일 종가 부근(15:00)에서 조건에 모두 해당하면 현재 최우선 매수로 호가 매수
1.2 매도 조건
 1) RSI(2) > 80
 2) 현재가 > 매수가
   - 장 중 조건에 모두 해당하면 현재 최우선 매도 호가로 매도

2. 매매종목선정(유니버스 구성)
2.1 ETF, 우선주 제외
 - 개별 기업 분석이 효율적이라 ETF제외
 - 우선주는 보퉁주를 따라 가는 경향이 있고, 거래량이 적어서 제외
2.2 지주 회사(홀딩스) 제외
 - 지배구조를 위한 기업으로 개별 기업으로 보기 어려워 제외
2.3 매출액 증가율 0보다 큰 기업 선택
2.4 ROE가 0보다 큰 기업
 - ROE(Return On Equity) : 자기자본이익율(ROE) = 당기순이익 / 평균자기자본총계 * 100
 - ROE가 +면 영업이익이 흑자, -면 적자라를 의미. 3)조건에서 적자에서 매출증가가 나올 수 있으므로,
   ROE가 +인 기업만 포함하도록 함.
2.5 ROE와 1/PER(PER의 역수)로 내림차순 했을 때 순위를 구해 두 순위의 평균을 계산한 후 상위 기업 200개 추출
 
3. 백테스팅
3.1 매매 종목 선정
 - 최대 보유 종목을 10개로 가정하면, 각 종목당 자금의 10% 비중으로 설정한다.
 - 수수료 및 세금은 0.015%, 0.3% 적용
 - 수행기간 적용 후 백테스트 진행

 

ps. 주의점
 - 상승장과 하락장에 따라 승률이 달라지므로, 하락장 보합장에서도 백테스팅 진행해서 검증할 것.
 - 상승장/하락장/보합장에 맞는 매매전략을 개발하는 것도 좋을 듯함.
 

end.

728x90

주식용어

■ 백테스팅  
백테스팅이란 시뮬레이션, 과거 데이터를 가지고 이 전략대로 매매한 시뮬레이션을 의미함.

■ 우선주  
보통주와 다르게 의결권이 없으나 특정 권리를 우선적으로 제공하는 주식을 우선주라한다.  
추가 배당, 우선 변제권을 부여받는다.

■ 유니버스  
유니버스랑 매매 대상으로 삼을 후보군을 의미함.

■ 턴어라운(Turn around)  
턴어라운드란 경제에서 기업회생을 의미하고, 주식 시장에서 좁은 의미로 기업이 적자에서 흑자로 전환된 상태로 돌아섰다는 의미로 사용함.

■ EPS(Earning Per Share) : 주당순이익 = 당기순이익 / 주식수

■ PER(Price Earning Ratio) : 주가수익비율 = 주식가격 / EPS

■ PBR(Price Book-value Ratio) : 주당순자산비율 = 주가 / 주당순자산

■ 주당순자산(BPS:Book-value Per Share) : (총자산 - 총부채) / 발생주식 
 - PBR이 1 이면, 특정 시점의 주가와 기업의 1주당 순자산이 같다는 뜻이고, 낮을 수록 기업의 저평가이고, 싸게 거래된다는 의미.

■ ROE(Return On Equity)  
자기자본이익율(ROE) = 당기순이익 / 평균자기자본총계 \* 100
 - 투입한 자기자본이 얼마만큼의 이익을 냈는지를 나타내는 지표

■ ETF (Exchanged Traded Fund)  
ETF란 특정 지수의 성과 자산 가치를 추종하는 펀드를 거래소에 상장하여 주식과 동일하게 매매 가능하도록 설계한 상품

728x90

+ Recent posts