B站配套视频教程观看
PyAlgoTrade:交易策略可视化
PyAlgoTrade利用matplotlib进行交易策略可视化。它做了非常系统的工作,包括买入卖出的交易信号,以及整体的收益和单次收益都可以看到。
我们就来看一下SMA策略可视化的结果是怎么样的
上节课我们利用了backteststragedy里面的方法去跑了交易条件和回测、怎么基于实仓位的判断决定是否买卖股票、这节课就基于当前的SMA策略,来实现可视化 所以之后大家也可以基于现有的框架去测试其他策略,比如说双均线,动量策略的结果,并且将他们可视化。
一、官方示例讲解
来到官方文档的Plotting板块
http://gbeced.github.io/pyalgotrade/docs/v0.20/html/tutorial.html#plotting
from pyalgotrade import strategy
from pyalgotrade.technical import ma
from pyalgotrade.technical import cross
class SMACrossOver(strategy.BacktestingStrategy):
def __init__(self, feed, instrument, smaPeriod):
super(SMACrossOver, self).__init__(feed)
self.__instrument = instrument
self.__position = None
# We'll use adjusted close values instead of regular close values.
self.setUseAdjustedValues(True)
self.__prices = feed[instrument].getPriceDataSeries()
self.__sma = ma.SMA(self.__prices, smaPeriod)
def getSMA(self):
return self.__sma
def onEnterCanceled(self, position):
self.__position = None
def onExitOk(self, position):
self.__position = None
def onExitCanceled(self, position):
# If the exit was canceled, re-submit it.
self.__position.exitMarket()
def onBars(self, bars):
# If a position was not opened, check if we should enter a long position.
if self.__position is None:
if cross.cross_above(self.__prices, self.__sma) > 0:
shares = int(self.getBroker().getCash() * 0.9 / bars[self.__instrument].getPrice())
# Enter a buy market order. The order is good till canceled.
self.__position = self.enterLong(self.__instrument, shares, True)
# Check if we have to exit the position.
elif not self.__position.exitActive() and cross.cross_below(self.__prices, self.__sma) > 0:
self.__position.exitMarket()
这里它定义了一个策略叫做:SMACrossOver
。
它和上节课的策略基本是一样的。
它增加了方法:getSMA
,用于返回均价的数据。
def onBars(self, bars):
函数里面定义了一个策略 买入卖出的规则稍有不同。我们就不借用它的代码,还是用之前的策略。我们主要看它可视化的部分是怎么做的
from pyalgotrade import plotter
from pyalgotrade.barfeed import quandlfeed
from pyalgotrade.stratanalyzer import returns
import sma_crossover
# Load the bar feed from the CSV file
feed = quandlfeed.Feed()
feed.addBarsFromCSV("orcl", "WIKI-ORCL-2000-quandl.csv")
# Evaluate the strategy with the feed's bars.
myStrategy = sma_crossover.SMACrossOver(feed, "orcl", 20)
# Attach a returns analyzers to the strategy.
returnsAnalyzer = returns.Returns()
myStrategy.attachAnalyzer(returnsAnalyzer)
# Attach the plotter to the strategy.
plt = plotter.StrategyPlotter(myStrategy)
# Include the SMA in the instrument's subplot to get it displayed along with the closing prices.
plt.getInstrumentSubplot("orcl").addDataSeries("SMA", myStrategy.getSMA())
# Plot the simple returns on each bar.
plt.getOrCreateSubplot("returns").addDataSeries("Simple returns", returnsAnalyzer.getReturns())
# Run the strategy.
myStrategy.run()
myStrategy.info("Final portfolio value: $%.2f" % myStrategy.getResult())
# Plot the strategy.
plt.plot()
首先,他将sma_crossover作为回测的策略。接着创建数据,然后定义策略,和之前的内容差不多。
# Attach a returns analyzers to the strategy.
returnsAnalyzer = returns.Returns()
myStrategy.attachAnalyzer(returnsAnalyzer)
这里会引用returns
库,定义了returns.Returns()
,然后myStrategy.attachAnalyzer(returnsAnalyzer)
将收益相关的指标当作参数赋值给交易策略。
接下来是要去可视化的部分:
# Attach the plotter to the strategy.
plt = plotter.StrategyPlotter(myStrategy)
# Include the SMA in the instrument's subplot to get it displayed along with the closing prices.
plt.getInstrumentSubplot("orcl").addDataSeries("SMA", myStrategy.getSMA())
# Plot the simple returns on each bar.
plt.getOrCreateSubplot("returns").addDataSeries("Simple returns", returnsAnalyzer.getReturns())
plotter是引入的可视化的工具库。 通过交易策略构造出一个plotter对象。
接着创建一个subplot子画布,然后调用addDataSeries将每日的均价的曲线画出来。
接着创建一个subplot子画布,然后调用addDataSeries将每日的收益率的曲线画出来。
# Run the strategy.
myStrategy.run()
myStrategy.info("Final portfolio value: $%.2f" % myStrategy.getResult())
然后就开始跑这个策略。
# Plot the strategy.
plt.plot()
接着将所有的数据绘制出来。
蓝色的是价格曲线,SMA是淡绿色的线,就是它的20
天的平均价格。红色箭头是卖出标记 绿色箭头是买入标记。
可视化的好处是让非常直观的看到你的策略是合理的,如果都是低买高卖,那就很好对吧。、
接着画出simple return(单次收益),也就是每一次赚了或亏了多少。
接着是portfolio,你可以看作每次操作后的累计的总收益、。
二、实战
将可视化的代码复制过去即可。
#使用pyalgotrade进行数据回测
import pyalgotrade
from pyalgotrade import strategy
from pyalgotrade.barfeed import quandlfeed
from pyalgotrade_tushare import tools, barfeed
from pyalgotrade.technical import ma
from pyalgotrade import plotter
from pyalgotrade.barfeed import quandlfeed
from pyalgotrade.stratanalyzer import returns
def safe_round(value, digits):
if value is not None:
value = round(value, digits)
return value
class MyStrategy(strategy.BacktestingStrategy):
def __init__(self, feed, instrument, smaPeriod):
super(MyStrategy, self).__init__(feed, 10000)
self.__position = None
self.__instrument = instrument
# # We'll use adjusted close values instead of regular close values.
# self.setUseAdjustedValues(True)
self.__sma = ma.SMA(feed[instrument].getPriceDataSeries(), smaPeriod)
def getSMA(self):
return self.__sma
def onEnterOk(self, position):
execInfo = position.getEntryOrder().getExecutionInfo()
#self.info("BUY at $%.2f" % (execInfo.getPrice()))
def onEnterCanceled(self, position):
self.__position = None
def onExitOk(self, position):
execInfo = position.getExitOrder().getExecutionInfo()
#self.info("SELL at $%.2f" % (execInfo.getPrice()))
self.__position = None
def onExitCanceled(self, position):
# If the exit was canceled, re-submit it.
self.__position.exitMarket()
def onBars(self, bars):
# Wait for enough bars to be available to calculate a SMA.
if self.__sma[-1] is None:
return
bar = bars[self.__instrument]
# If a position was not opened, check if we should enter a long position.
if self.__position is None:
if bar.getPrice() > self.__sma[-1]:
# Enter a buy market order for 10 shares. The order is good till canceled.
self.__position = self.enterLong(self.__instrument, 100, True)
# Check if we have to exit the position.
elif bar.getPrice() < self.__sma[-1] and not self.__position.exitActive():
self.__position.exitMarket()
def run_strategy(smaPeriod):
# Load the bar feed from the CSV file
instruments = ["000001"]
feeds = tools.build_feed(instruments, 2016, 2018, "histdata")
#print(feeds)
# Evaluate the strategy with the feed's bars.
myStrategy = MyStrategy(feeds, instruments[0], smaPeriod)
# myStrategy.run()
# # 打印总持仓:(cash + shares * price) (持有现金 + 股数*价格)
# print("Final portfolio value: $%.2f" % myStrategy.getBroker().getEquity())
# Attach a returns analyzers to the strategy.
returnsAnalyzer = returns.Returns()
myStrategy.attachAnalyzer(returnsAnalyzer)
# Attach the plotter to the strategy.
plt = plotter.StrategyPlotter(myStrategy)
# Include the SMA in the instrument's subplot to get it displayed along with the closing prices.
plt.getInstrumentSubplot(instruments[0]).addDataSeries("SMA", myStrategy.getSMA())
# Plot the simple returns on each bar.
plt.getOrCreateSubplot("returns").addDataSeries("Simple returns", returnsAnalyzer.getReturns())
# Run the strategy.
myStrategy.run()
myStrategy.info("Final portfolio value: $%.2f" % myStrategy.getResult())
# Plot the strategy.
plt.plot()
# for i in range(10, 30):
run_strategy(11)
运行
可以看到获取到了可视化的内容。
我们将时间缩短,方便具体看一下交易策略的内容。将时间改为2020-2021:
feeds = tools.build_feed(instruments, 2020, 2021, "histdata")