1.9.32.116版增加了对社区中一个有趣的用例的支持
与未来开始交易,包括实物交割
让指针告诉你一些事情
如果需要,通过以现货价格操作平仓,有效地取消实物交割,无论是接收货物还是必须交付货物(并希望获利)
期货在现货价格操作发生的同一天到期
这意味着:
该平台接收来自两种不同资产的数据点
平台必须以某种方式了解资产是相关的,并且现货价格操作将关闭未来未平仓头寸
现实中,未来没有封闭,只有实物交割得到补偿
使用该补偿概念, backtrader添加了一种方法,让用户与平台沟通,一个数据馈送上的事物将对另一个数据馈送产生补偿影响。使用模式
import backtrader as bt cerebro = bt.Cerebro() data0 = bt.feeds.MyFavouriteDataFeed(dataname='futurename') cerebro.adddata(data0) data1 = bt.feeds.MyFavouriteDataFeed(dataname='spotname') data1.compensate(data0) # let the system know ops on data1 affect data0 cerebro.adddata(data1) ... cerebro.run()
把它们放在一起
一个例子总是值一千个帖子,所以让我们把所有的部分放在一起。
使用来自
backtrader来源的标准示例提要之一。这将是未来通过重复使用相同的提要并添加一个过滤器来仿真相似但不同的价格,该过滤器将随机将价格移动到上方/下方一些点,以创建点差。很简单:
# The filter which changes the close price def close_changer(data, *args, **kwargs): data.close[0] += 50.0 * random.randint(-1, 1) return False # length of stream is unchanged在同一轴上绘图将混合默认包含的
BuyObserver标记,因此标准观察者将被禁用并手动读取以使用不同的每个数据标记进行绘图仓位随机入仓,10天后出仓
这与未来的到期期限不匹配,但这只是将功能落实到位,而不是检查交易日历
!!!笔记
A simulation including execution on the spot price on the day of future expiration would require activating `cheat-on-close` to make sure the orders are executed when the future expires. This is not needed in this sample, because the expiration is being chosen at random.
注意策略
buy操作在data0上运行sell操作在data1上运行
class St(bt.Strategy): def __init__(self): bt.obs.BuySell(self.data0, barplot=True) # done here for BuySellArrows(self.data1, barplot=True) # different markers per data def next(self): if not self.position: if random.randint(0, 1): self.buy(data=self.data0) self.entered = len(self) else: # in the market if (len(self) - self.entered) >= 10: self.sell(data=self.data1)
运行:
$ ./future-spot.py --no-comp
有了这个图形输出。
它有效:
buy操作用一个向上的绿色三角形表示,图例告诉我们它们属于预期的data0sell操作用一个向下的箭头表示,图例告诉我们它们按预期属于data1交易正在关闭,即使它们使用
data0打开并使用data1关闭,也达到了预期的效果(这在现实生活中避免了通过未来获得的货物的实物交付)
人们只能想像如果在没有补偿的情况下应用相同的逻辑会发生什么。我们开始做吧:
$ ./future-spot.py --no-comp
和输出
很明显,这会惨遭失败:
逻辑预期
data0上的仓位将通过data1上的操作关闭,并且仅在data0上未在市场上时打开仓位但补偿已被停用,对
data0的初始操作(绿色三角形)永远不会关闭,因此永远不会启动其他操作,并且data1上的空头头寸开始累积。
示例使用
$ ./future-spot.py --help usage: future-spot.py [-h] [--no-comp] Compensation example optional arguments: -h, --help show this help message and exit --no-comp
示例代码
from __future__ import (absolute_import, division, print_function,
unicode_literals)
import argparse
import random
import backtrader as bt
# The filter which changes the close price
def close_changer(data, *args, **kwargs):
data.close[0] += 50.0 * random.randint(-1, 1)
return False # length of stream is unchanged
# override the standard markers
class BuySellArrows(bt.observers.BuySell):
plotlines = dict(buy=dict(marker='$\u21E7$', markersize=12.0),
sell=dict(marker='$\u21E9$', markersize=12.0))
class St(bt.Strategy):
def __init__(self):
bt.obs.BuySell(self.data0, barplot=True) # done here for
BuySellArrows(self.data1, barplot=True) # different markers per data
def next(self):
if not self.position:
if random.randint(0, 1):
self.buy(data=self.data0)
self.entered = len(self)
else: # in the market
if (len(self) - self.entered) >= 10:
self.sell(data=self.data1)
def runstrat(args=None):
args = parse_args(args)
cerebro = bt.Cerebro()
dataname = '../../datas/2006-day-001.txt' # data feed
data0 = bt.feeds.BacktraderCSVData(dataname=dataname, name='data0')
cerebro.adddata(data0)
data1 = bt.feeds.BacktraderCSVData(dataname=dataname, name='data1')
data1.addfilter(close_changer)
if not args.no_comp:
data1.compensate(data0)
data1.plotinfo.plotmaster = data0
cerebro.adddata(data1)
cerebro.addstrategy(St) # sample strategy
cerebro.addobserver(bt.obs.Broker) # removed below with stdstats=False
cerebro.addobserver(bt.obs.Trades) # removed below with stdstats=False
cerebro.broker.set_coc(True)
cerebro.run(stdstats=False) # execute
cerebro.plot(volume=False) # and plot
def parse_args(pargs=None):
parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
description=('Compensation example'))
parser.add_argument('--no-comp', required=False, action='store_true')
return parser.parse_args(pargs)
if __name__ == '__main__':
runstrat()