天天看點

量化分析基本架構示例量化分析基本架構示例

量化分析基本架構示例

Tushare ID: 434267

架構:Backtrader

資料:Tushare

安裝方式:金融量化分析基礎環境搭建

示例代碼:

import pandas as pd  
from datetime import datetime
import backtrader as bt
import tushare as ts 
import matplotlib.pyplot as plt

ts.set_token('Tushare賬戶token')#擷取方式請參考安裝方式連結
pro = ts.pro_api()

#使用tushare舊版接口擷取資料
def get_data(code,start,end):
    df = pro.daily(ts_code=code, start_date=start, end_date=end)
    df.index=pd.to_datetime(df.trade_date)
    df=df[['open', 'high', 'low', 'close', 'pre_close', 'change', 'pct_chg', 'vol', 'amount']]
    df = df.rename(columns={"vol": "volume"})
    df = df.iloc[::-1]
    return df

class my_strategy1(bt.Strategy):
    #全局設定交易政策的參數
    params=(
        ('maperiod',20),
           )

    def __init__(self):
        #指定價格序列
        self.dataclose=self.datas[0].close
        # 初始化交易指令、買賣價格和手續費
        self.order = None
        self.buyprice = None
        self.buycomm = None

        #添加移動均線名額,内置了talib子產品
        self.sma = bt.indicators.SimpleMovingAverage(
                      self.datas[0], period=self.params.maperiod)
        
    def log(self, txt, dt=None):
        ''' 輸出日志'''
        dt = dt or self.datas[0].datetime.date(0)
        print('%s, %s' % (dt.isoformat(), txt))
        
    def notify(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('訂單買入:成交價%.2f元' % order.executed.price)
            elif order.issell():
                self.log('訂單賣出:成交價%.2f元' % order.executed.price)
 
            self.bar_executed = len(self)
 
        # Write down: no pending order
        self.order = None
        
    def next(self):
        if self.order: # 檢查是否有指令等待執行, 
            return
        # 檢查是否持倉   
        if not self.position: # 沒有持倉
            #執行買入條件判斷:收盤價格上漲突破20日均線
            if self.dataclose[0] > self.sma[0]:
                #執行買入
                self.order = self.buy(size=500)         
        else:
            #執行賣出條件判斷:收盤價格跌破20日均線
            if self.dataclose[0] < self.sma[0]:
                #執行賣出
                self.order = self.sell(size=500)
    
if __name__ == '__main__':
    
    
    #回測期間
    start=datetime(2020, 1, 31)
    end=datetime(2020, 3, 31)
    
    d1=start.strftime('%Y%m%d')
    d2=end.strftime('%Y%m%d')
    
    # 加載資料
    dataframe=get_data('600000.SH', d1, d2)
    data = bt.feeds.PandasData(dataname=dataframe,fromdate=start,todate=end)
    
    # 初始化cerebro回測系統設定                           
    cerebro = bt.Cerebro()  
    #将資料傳入回測系統
    cerebro.adddata(data) 
    # 将交易政策加載到回測系統中
    cerebro.addstrategy(my_strategy1) 
    # 設定初始資本為10,000
    startcash = 10000
    cerebro.broker.setcash(startcash) 
    # 設定交易手續費為 0.2%
    cerebro.broker.setcommission(commission=0.002) 
    
    print(f'初始資金: {startcash}\n回測期間:{d1}:{d2}')
    #運作回測系統
    cerebro.run()
    #擷取回測結束後的總資金
    portvalue = cerebro.broker.getvalue()
    pnl = portvalue - startcash
    #列印結果
    print(f'總資金: {round(portvalue,2)}')   
    print(f'淨收益: {round(pnl,2)}')
    cerebro.plot()
    
               

注意事項:

1、Backtrader接收的DataFrame資料按時間由過去到現在進行排列,Tushare老版本的DataFrame資料也是按時間由過去到現在進行排列,是以可直接使用;但最新的Tushare接口是按照時間從現在到過去進行排列,是以需要df = df.iloc[::-1]進行倒序排列。

2、Backtrader預設作圖時需要DataFrame資料中有成交量資料,并且列名必須為volume,Tushare老版本資料中有volume列名,新版本已更換為vol,是以需要重新命名df = df.rename(columns={"vol": "volume"})。

其他:

金融量化分析最新動态和源代碼分享,請關注“量化之窗”公衆号。

量化分析基本架構示例量化分析基本架構示例

繼續閱讀