简介
在前一篇已经实现了数据的本土化,能自定义喂数据了。下一步就跟着BackTrader官方的quickstart开始按照文档逐步实践,逐步掌握各个模块。
原理
看了下文档quickstart,现自己的策略只需要自己继承bt.Strategy,让子类实现父类对应的方法即可。官方样例给出了子类实现的三个函数:log(日志输出函数), init(子类构造函数),next(数据循环处理函数) ,看了下Strategy类有将近2k行代码,算是最核心的一个类了,里面还有很多重要的方法:
- next() :This method will be called for all remaining data points when the minimum period for all datas/indicators have been meet.
- nextstart():This method will be called once, exactly when the minimum period for all datas/indicators have been meet. The default behavior is to call next
- prenext():This method will be called before the minimum period of all datas/indicators have been meet for the strategy to start executing
- start():Called right before the backtesting is about to be started.
- stop():Called right before the backtesting is about to be stopped
- notify_order(order):Receives an order whenever there has been a change in one
- notify_trade(trade):Receives a trade whenever there has been a change in one
- notify_cashvalue(cash, value):Receives the current fund value, value status of the strategy’s broker
- notify_fund(cash, value, fundvalue, shares):Receives the current cash, value, fundvalue and fund shares
- notify_store(msg, *args, **kwargs):Receives a notification from a store provider
- buy(data=None, size=None, price=None, plimit=None, exectype=None, valid=None, tradeid=0, oco=None, trailamount=None, trailpercent=None, parent=None, transmit=True, **kwargs)
- sell(data=None, size=None, price=None, plimit=None, exectype=None, valid=None, tradeid=0, oco=None, trailamount=None, trailpercent=None, parent=None, transmit=True, **kwargs)
- close(data=None, size=None, **kwargs):Counters a long/short position closing it
实践策略
增加第一个简单的策略,用来显示收盘价
# -*- coding: utf-8 -*-
"""
实践第一个简单的策略 打印出每天的收盘价
"""
#############################################################
#import
#############################################################
from __future__ import (absolute_import, division, print_function,
unicode_literals)
import os,sys
import pandas as pd
import backtrader as bt
#############################################################
#global const values
#############################################################
#############################################################
#static function
#############################################################
#############################################################
#class
#############################################################
# 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) 加载多个股票价格数据。在策略类中的 __ init __ 方法中,通过self.datas类访问到所有的价格数据。其中self.datas以列表形式保存的价格数据,列表的顺序就是价格数据加载的顺序。self.datas[0] 即是加载的第一条价格数据,它被框架默认使用。
本次的功能是输出收盘价,将第一条价格数据的收盘价赋值给self.dataclose = self.datas[0].close。
当开始cerebro开始执行run的时候,会循环处理股票价格数据,每经过一个K线价格的时候,next()方法就会被调用一次。主要的处理逻辑都在这里函数里面实现。
完全代码到github上clone即可:[qtbt](https://github.com/horacepei/qtbt.git)