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 import backtrader.analyzers as btanalyzers import math import pandas as pd import numpy as np # 데이터 넣기 # 주 지표 적용 # 보조 지표 적용 # 지표 혼합 적용 # 경우의 수에 따른 시뮬레이팅 PARAMS = ( ('maperiod', 15), # moving average period ('period', 15), # ('willperiod', 14), # moving average period ('sizer', None), ) class TestStrategy(bt.Strategy): params = PARAMS 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 and buy price/commission self.order = None # self.order = self.order_target_percent(target=0.1) self.buyprice = None self.buycomm = None # self.sma = bt.indicators.SimpleMovingAverage(self.datas[0], period=self.params.maperiod) self.sma = bt.indicators.ExponentialMovingAverage(self.datas[0], period=25) 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 enougth cash if order.status in [order.Completed, order.Canceled, order.Margin]: 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) # Write down: no pending order 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)) def next(self): # Simply log the closing price of the series from the reference # 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.sma[0]: # BUY, BUY, BUY!!! (with all possible default parameters) self.log('BUY CREATE, close : %.2f, sma25 : %.2f' % (self.dataclose[0], self.sma[0])) # Keep track of the created order to avoid a 2nd order self.order = self.buy() else: if self.dataclose[0] < self.sma[0]: # SELL, SELL, SELL!!! (with all possible default parameters) self.log('SELL CREATE, close : %.2f, sma25 : %.2f' % (self.dataclose[0], self.sma[0])) # Keep track of the created order to avoid a 2nd order self.order = self.sell() class LongOnly(bt.Sizer): params = (('stake', 1),) def _getsizing(self, comminfo, cash, data, isbuy): if isbuy: divide = math.floor(cash / data.close[0]) # divide = math.floor(cash/data.open[1]) self.p.stake = divide # print(self.p.stake) # print(math.floor(cash/data.close[0])) return self.p.stake # Sell situation position = self.broker.getposition(data) if not position.size: return 0 # do not sell if nothing is open return self.p.stake if __name__ == '__main__': cerebro = bt.Cerebro() # Add a strategy cerebro.addstrategy(TestStrategy) # Add Sizer cerebro.addsizer(LongOnly) # because it could have been called from anywhere modpath = os.path.dirname(os.path.abspath(sys.argv[0])) datapath = os.path.join(modpath, 'orcl-2014.txt') # Create a Data Feed data = bt.feeds.YahooFinanceCSVData( dataname=datapath, # Do not pass values before this date # Do not pass values before this date # 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(1000.0) # In order to buy on open you may want to # bt.filters.BarReplayer_Open(data) cerebro.broker.set_coc(True) # Set the commission cerebro.broker.setcommission(commission=0.005) # 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()) # Plot the result cerebro.plot()