Backtrader는 투자전략을 세우고 과거데이터들을 통해 투자전략을 검증하기 위해 사용되는 파이썬 프레임워크 입니다.
Backtrader 튜토리얼 | 설치, 기본설정, 금액설정, 데이터입력
Backtrader는 투자전략을 세우고 과거데이터들을 통해 투자전략을 검증하기 위해 사용되는 파이썬 프레임워크 입니다. Backtrader 설치 pip install backtrader Backtrader 시작 기본적으로 Backtrader를 실행시켜
stockfinancediary.tistory.com
사용할 데이터 파일
from __future__ import (absolute_import, division, print_function,
unicode_literals)
import datetime # For datetime objects
import os.path # To manage paths
import sys # To find out the script name (in argv[0])
# Import the backtrader platform
import backtrader as bt
# Create a Stratey
class TestStrategy(bt.Strategy):
def log(self, txt, dt=None):
''' Logging function for this strategy'''
dt = dt or self.datas[0].datetime.date(0)
print('%s, %s' % (dt.isoformat(), txt))
def __init__(self):
# Keep a reference to the "close" line in the data[0] dataseries
self.dataclose = self.datas[0].close
def next(self):
# Simply log the closing price of the series from the reference
self.log('Close, %.2f' % self.dataclose[0])
if __name__ == '__main__':
# Create a cerebro entity
cerebro = bt.Cerebro()
# Add a strategy
cerebro.addstrategy(TestStrategy)
# Datas are in a subfolder of the samples. Need to find where the script is
# because it could have been called from anywhere
modpath = os.path.dirname(os.path.abspath(sys.argv[0]))
datapath = os.path.join(modpath, 'orcl-1995-2014.txt')
# Create a Data Feed
data = bt.feeds.YahooFinanceCSVData(
dataname=datapath,
# Do not pass values before this date
fromdate=datetime.datetime(2000, 1, 1),
# Do not pass values before this date
todate=datetime.datetime(2000, 12, 31),
# Do not pass values after this date
reverse=False)
# Add the Data Feed to Cerebro
cerebro.adddata(data)
# Set our desired cash start
cerebro.broker.setcash(100000.0)
# Print out the starting conditions
print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
# Run over everything
cerebro.run()
# Print out the final result
print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
아래 함수를 통해 전략을 설정할 수 있습니다.
cerebro.addstrategy(전략Class)
전략을 수정하기 위해서는 class를 인자로 넘겨주어야 합니다. 이때 Class는 bt.Strategy를 상속받아 생성합니다.
# Create a Stratey
class TestStrategy(bt.Strategy):
def log(self, txt, dt=None):
''' Logging function for this strategy'''
dt = dt or self.datas[0].datetime.date(0)
print('%s, %s' % (dt.isoformat(), txt))
def __init__(self):
# Keep a reference to the "close" line in the data[0] dataseries
self.dataclose = self.datas[0].close
def next(self):
# Simply log the closing price of the series from the reference
self.log('Close, %.2f' % self.dataclose[0])
위와 같이 받은 cerebro.adddata(data)에서 받은 data를 활용할 수 있습니다. 종가 데이터를 추출하여 날짜와 종가데이터를 출력하는 방식입니다.
3일연속 하락한 경우 구매하는 전략을 만들어 봅시다.
# Create a Stratey
class TestStrategy(bt.Strategy):
def log(self, txt, dt=None):
''' Logging function fot this strategy'''
dt = dt or self.datas[0].datetime.date(0)
print('%s, %s' % (dt.isoformat(), txt))
def __init__(self):
# Keep a reference to the "close" line in the data[0] dataseries
self.dataclose = self.datas[0].close
def next(self):
# Simply log the closing price of the series from the reference
self.log('Close, %.2f' % self.dataclose[0])
if self.dataclose[0] < self.dataclose[-1]:
# current close less than previous close
if self.dataclose[-1] < self.dataclose[-2]:
# previous close less than the previous close
# BUY, BUY, BUY!!! (with all possible default parameters)
self.log('BUY CREATE, %.2f' % self.dataclose[0])
self.buy()
buy()는 구매함수입니다. 현재종가 < 1일전종가 < 2일전종가 일 경우 buy()함수가 실행됩니다.
from __future__ import (absolute_import, division, print_function,
unicode_literals)
import datetime # For datetime objects
import os.path # To manage paths
import sys # To find out the script name (in argv[0])
# Import the backtrader platform
import backtrader as bt
# Create a Stratey
class TestStrategy(bt.Strategy):
def log(self, txt, dt=None):
''' Logging function fot this strategy'''
dt = dt or self.datas[0].datetime.date(0)
print('%s, %s' % (dt.isoformat(), txt))
def __init__(self):
# Keep a reference to the "close" line in the data[0] dataseries
self.dataclose = self.datas[0].close
# To keep track of pending orders
self.order = None
def notify_order(self, order):
if order.status in [order.Submitted, order.Accepted]:
# Buy/Sell order submitted/accepted to/by broker - Nothing to do
return
# Check if an order has been completed
# Attention: broker could reject order if not enough cash
if order.status in [order.Completed]:
if order.isbuy():
self.log('BUY EXECUTED, %.2f' % order.executed.price)
elif order.issell():
self.log('SELL EXECUTED, %.2f' % order.executed.price)
self.bar_executed = len(self)
elif order.status in [order.Canceled, order.Margin, order.Rejected]:
self.log('Order Canceled/Margin/Rejected')
# Write down: no pending order
self.order = None
def next(self):
# Simply log the closing price of the series from the reference
self.log('Close, %.2f' % self.dataclose[0])
# Check if an order is pending ... if yes, we cannot send a 2nd one
if self.order:
return
# Check if we are in the market
if not self.position:
# Not yet ... we MIGHT BUY if ...
if self.dataclose[0] < self.dataclose[-1]:
# current close less than previous close
if self.dataclose[-1] < self.dataclose[-2]:
# previous close less than the previous close
# BUY, BUY, BUY!!! (with default parameters)
self.log('BUY CREATE, %.2f' % self.dataclose[0])
# Keep track of the created order to avoid a 2nd order
self.order = self.buy()
else:
# Already in the market ... we might sell
if len(self) >= (self.bar_executed + 5):
# SELL, SELL, SELL!!! (with all possible default parameters)
self.log('SELL CREATE, %.2f' % self.dataclose[0])
# Keep track of the created order to avoid a 2nd order
self.order = self.sell()
notify_order(self, order) 함수는 주문상태에 따라 내용을 출력해주는 함수입니다. 위 경우 주문완료 되거나 주문이 거절된 경우 로그를 통해 알려줍니다.
self.order를 통해 매매대기중인 경우 매매를 실행하지 않습니다.
self.position을 통해 포지션을 확인하고 포지션이 없다면 아래 조건에 따라 매수를 진행하며, 이미 주식을 보유하고 있다면 조건에 맞게 매도합니다.
판매전략도 추가되었습니다. 매수 후 5일 뒤 판매하는 전략입니다.
sell() 판매함수 입니다.
주식매매에는 매매비용도 고려하여야 합니다.
def __init__(self):
# Keep a reference to the "close" line in the data[0] dataseries
self.dataclose = self.datas[0].close
# To keep track of pending orders and buy price/commission
self.order = None
self.buyprice = None
self.buycomm = None
def notify_order(self, order):
if order.status in [order.Submitted, order.Accepted]:
# Buy/Sell order submitted/accepted to/by broker - Nothing to do
return
# Check if an order has been completed
# Attention: broker could reject order if not enough cash
if order.status in [order.Completed]:
if order.isbuy():
self.log(
'BUY EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' %
(order.executed.price,
order.executed.value,
order.executed.comm))
self.buyprice = order.executed.price
self.buycomm = order.executed.comm
else: # Sell
self.log('SELL EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' %
(order.executed.price,
order.executed.value,
order.executed.comm))
self.bar_executed = len(self)
elif order.status in [order.Canceled, order.Margin, order.Rejected]:
self.log('Order Canceled/Margin/Rejected')
self.order = None
def notify_trade(self, trade):
if not trade.isclosed:
return
self.log('OPERATION PROFIT, GROSS %.2f, NET %.2f' %
(trade.pnl, trade.pnlcomm))
""
# Set the commission - 0.1% ... divide by 100 to remove the %
cerebro.broker.setcommission(commission=0.001)
""
cerebri,broker.setcommission(수수료)함수는 수수료를 결정합니다. 위의 경우 1/1000으로 매매수수료를 결정하였습니다.
order.executed.price 매도가격
order.executed.value 매수가격
order.executed.comm 매매비용
notify_trade(self, trade)함수의 경우 거래가 완료될 시 수익률과 수수료를 출력해 줍니다.
Quickstart Guide - Backtrader
Quickstart Note The data files used in the quickstart guide are updated from time to time, which means that the adjusted close changes and with it the close (and the other components). That means that the actual output may be different to what was put in t
www.backtrader.com
다음글
Backtrader 튜토리얼 | 매개변수, 매매 단위설정, 다양한 지표추가, 매매전략 최적화
Backtrader 매개변수 설정 params = ( ('myparam', 27), ('exitbars', 5), ) Backtrader 매매단위 설정 cerebro = bt.Cerebro() cerebro.addsizer(bt.sizers.SizerFix, stake=20) # default sizer for strategies stake는 한번에 매수할 단위 사용할
stockfinancediary.tistory.com
Backtrader 튜토리얼 | 매개변수, 매매 단위설정, 다양한 지표추가, 매매전략 최적화 (0) | 2023.02.13 |
---|---|
Backtrader 튜토리얼 | 설치, 기본설정, 금액설정, 데이터입력 (0) | 2023.02.11 |