网站建设教程 三级分销/seo搜索引擎优化工作内容
Backtrader 文档学习-Platform Concepts
1.开始之前
导入backtrader ,以及backtrader 的指示器、数据反馈的模块 。
import backtrader as bt
import backtrader.indicators as btind
import backtrader.feeds as btfeeds
看看btind模块下有什么方法和属性:
obj_str = ''
for i in dir(btind):if i[:1] != '_' :obj_str += i + ','
print(obj_str)
指示器中的指标函数很多,方法属性如下:
ADX,ADXR,AO,APO,ATR,AbsPriceOsc,AbsolutePriceOscillator,AccDeOsc,AccelerationDecelerationOscillator,Accum,AdaptiveMovingAverage,AdaptiveMovingAverageEnvelope,AdaptiveMovingAverageOsc,AdaptiveMovingAverageOscillator,All,AllN,And,Any,AnyN,ApplyN,ArithmeticMean,AroonDown,AroonIndicator,AroonOsc,AroonOscillator,AroonUp,AroonUpDown,AroonUpDownOsc,AroonUpDownOscillator,Average,AverageDirectionalMovementIndex,AverageDirectionalMovementIndexRating,AverageTrueRange,AverageWeighted,AwesomeOsc,AwesomeOscillator,BBands,BaseApplyN,BollingerBands,BollingerBandsPct,CCI,Cmp,CmpEx,CointN,CommodityChannelIndex,CrossDown,CrossOver,CrossUp,CumSum,CumulativeSum,DEMA,DEMAEnvelope,DEMAOsc,DEMAOscillator,DI,DM,DMA,DMAEnvelope,DMAOsc,DMAOscillator,DMI,DPO,DV2,DemarkPivotPoint,DetrendedPriceOscillator,DicksonMA,DicksonMAEnvelope,DicksonMAOsc,DicksonMAOscillator,DicksonMovingAverage,DicksonMovingAverageEnvelope,DicksonMovingAverageOsc,DicksonMovingAverageOscillator,DirectionalIndicator,DirectionalMovement,DirectionalMovementIndex,DivByZero,DivZeroByZero,DoubleExponentialMovingAverage,DoubleExponentialMovingAverageEnvelope,DoubleExponentialMovingAverageOsc,DoubleExponentialMovingAverageOscillator,DownDay,DownDayBool,DownMove,EC,ECEnvelope,ECOsc,ECOscillator,EMA,EMAEnvelope,EMAOsc,EMAOscillator,Envelope,EnvelopeMixIn,ErrorCorrecting,ErrorCorrectingEnvelope,ErrorCorrectingOsc,ErrorCorrectingOscillator,ExpSmoothing,ExpSmoothingDynamic,ExponentialMovingAverage,ExponentialMovingAverageEnvelope,ExponentialMovingAverageOsc,ExponentialMovingAverageOscillator,ExponentialSmoothing,ExponentialSmoothingDynamic,FibonacciPivotPoint,FindFirstIndex,FindFirstIndexHighest,FindFirstIndexLowest,FindLastIndex,FindLastIndexHighest,FindLastIndexLowest,HMA,HMAEnvelope,HMAOsc,HMAOscillator,HeikinAshi,Highest,HullMA,HullMAEnvelope,HullMAOsc,HullMAOscillator,HullMovingAverage,HullMovingAverageEnvelope,HullMovingAverageOsc,HullMovingAverageOscillator,Hurst,HurstExponent,Ichimoku,If,Indicator,KAMA,KAMAEnvelope,KAMAOsc,KAMAOscillator,KST,KnowSureThing,LAGF,LRSI,LaguerreFilter,LaguerreRSI,LineActions,List,Logic,Lowest,MACD,MACDHisto,MACDHistogram,MAXINT,Max,MaxN,Mean,MeanDev,MeanDeviation,MetaMovAvBase,Min,MinN,MinusDI,MinusDirectionalIndicator,ModifiedMovingAverage,ModifiedMovingAverageEnvelope,ModifiedMovingAverageOsc,ModifiedMovingAverageOscillator,Momentum,MomentumOsc,MomentumOscillator,MovAv,MovingAverage,MovingAverageAdaptive,MovingAverageAdaptiveEnvelope,MovingAverageAdaptiveOsc,MovingAverageAdaptiveOscillator,MovingAverageBase,MovingAverageDoubleExponential,MovingAverageDoubleExponentialEnvelope,MovingAverageDoubleExponentialOsc,MovingAverageDoubleExponentialOscillator,MovingAverageExponential,MovingAverageExponentialEnvelope,MovingAverageExponentialOsc,MovingAverageExponentialOscillator,MovingAverageSimple,MovingAverageSimpleEnvelope,MovingAverageSimpleOsc,MovingAverageSimpleOscillator,MovingAverageSmoothed,MovingAverageSmoothedEnvelope,MovingAverageSmoothedOsc,MovingAverageSmoothedOscillator,MovingAverageTripleExponential,MovingAverageTripleExponentialEnvelope,MovingAverageTripleExponentialOsc,MovingAverageTripleExponentialOscillator,MovingAverageWeighted,MovingAverageWeightedEnvelope,MovingAverageWeightedOsc,MovingAverageWeightedOscillator,MovingAverageWilder,MovingAverageWilderEnvelope,MovingAverageWilderOsc,MovingAverageWilderOscillator,MultiLogic,MultiLogicReduce,NZD,NonZeroDifference,OLS_BetaN,OLS_Slope_InterceptN,OLS_TransformationN,OperationN,Or,Oscillator,OscillatorMixIn,PGO,PPO,PPOShort,PSAR,ParabolicSAR,PctChange,PctRank,PercPriceOsc,PercPriceOscShort,PercentChange,PercentRank,PercentagePriceOscillator,PercentagePriceOscillatorShort,PeriodN,PivotPoint,PlusDI,PlusDirectionalIndicator,PrettyGoodOsc,PrettyGoodOscillator,PriceOsc,PriceOscillator,RMI,ROC,ROC100,RSI,RSI_Cutler,RSI_EMA,RSI_SMA,RSI_SMMA,RSI_Safe,RSI_Wilder,RateOfChange,RateOfChange100,Reduce,ReduceN,RelativeMomentumIndex,RelativeStrengthIndex,SMA,SMAEnvelope,SMAOsc,SMAOscillator,SMMA,SMMAEnvelope,SMMAOsc,SMMAOscillator,SimpleMovingAverage,SimpleMovingAverageEnvelope,SimpleMovingAverageOsc,SimpleMovingAverageOscillator,SmoothedMovingAverage,SmoothedMovingAverageEnvelope,SmoothedMovingAverageOsc,SmoothedMovingAverageOscillator,StandardDeviation,StdDev,Stochastic,StochasticFast,StochasticFull,StochasticSlow,Sum,SumN,TEMA,TEMAEnvelope,TEMAOsc,TEMAOscillator,TR,TRIX,TSI,TripleExponentialMovingAverage,TripleExponentialMovingAverageEnvelope,TripleExponentialMovingAverageOsc,TripleExponentialMovingAverageOscillator,Trix,TrixSignal,TrueHigh,TrueLow,TrueRange,TrueStrengthIndicator,UltimateOscillator,UpDay,UpDayBool,UpMove,Vortex,WMA,WMAEnvelope,WMAOsc,WMAOscillator,WeightedAverage,WeightedMovingAverage,WeightedMovingAverageEnvelope,WeightedMovingAverageOsc,WeightedMovingAverageOscillator,WilderMA,WilderMAEnvelope,WilderMAOsc,WilderMAOscillator,WilliamsAD,WilliamsR,ZLEMA,ZLEMAEnvelope,ZLEMAOsc,ZLEMAOscillator,ZLInd,ZLIndEnvelope,ZLIndOsc,ZLIndOscillator,ZLIndicator,ZLIndicatorEnvelope,ZLIndicatorOsc,ZLIndicatorOscillator,ZeroLagEma,ZeroLagEmaEnvelope,ZeroLagEmaOsc,ZeroLagEmaOscillator,ZeroLagExponentialMovingAverage,ZeroLagExponentialMovingAverageEnvelope,ZeroLagExponentialMovingAverageOsc,ZeroLagExponentialMovingAverageOscillator,ZeroLagIndicator,ZeroLagIndicatorEnvelope,ZeroLagIndicatorOsc,ZeroLagIndicatorOscillator,absolute_import,accdecoscillator,alias,aroon,atr,awesomeoscillator,basicops,bollinger,bt,cci,cmp,contrib,crossover,dema,deviation,directionalmove,division,dma,dpo,dv2,ema,envelope,functools,haD,haDelta,hadelta,heikinashi,hma,hurst,ichimoku,kama,kst,linename,lrsi,mabase,macd,map,math,module,momentum,movav,movname,newaliases,newcls,newclsdct,newclsdoc,newclsname,ols,operator,oscillator,percentchange,percentrank,pivotpoint,prettygoodoscillator,priceoscillator,print_function,psar,range,rmi,rsi,sma,smma,stochastic,suffix,sys,trix,tsi,ultimateoscillator,unicode_literals,williams,with_metaclass,wma,zlema,zlind,
也可以直接通过bt导入下面的模块feeds indicators
import backtrader as bt
thefeed = bt.feeds.OneOfTheFeeds(...)
theind = bt.indicators.SimpleMovingAverage(...)
2.数据读入-无处不在
所有的策略都基于数据,平台端用户不用考虑如何接收数据。
Data Feeds are automagically provided member variables to the strategy in the form of an array and shortcuts to the array positions
数据源是以数组的形式或者对数组位置快捷访问的方式提供给strategy(策略)作为成员变量使用的。
这句话需要好好理解。
数组的形式: self.datas[0].close
数组位置快捷访问:self.data0.close
class MyStrategy(bt.Strategy):params = dict(period=20)def __init__(self):sma = btind.SimpleMovingAverage(self.datas[0], period=self.params.period)print(sma)# Keep a reference to the "close" line in the data[0] dataseriesself.dataclose = self.datas[0].closeself.dataclosetest = self.data0.closeprint('-'* 20,'close','-' * 20 )print(self.dataclose[0])print(self.dataclosetest[0])
执行结果
sma 的数据类型backtrader.indicators.sma.SimpleMovingAverage
<backtrader.indicators.sma.SimpleMovingAverage object at 0x7f616bd7c820>
-------------------- close --------------------
133.01
133.01
Data Feeds get added to the platform and they will show up inside the strategy in the sequential order in which they were added to the system.
SQL语句按日期排序,不论是正序还是逆序desc ,到BackTrader中,都是按时间倒序排列,[0]是最后的日期。
3.快捷访问数据
self.datas数组项可以通过自动成员变量直接访问:
self.data targets self.datas[0]
self.dataX targets self.datas[X]
下面好好测试一下BackTrader的数据访问,数据之间的关系。
#<class 'backtrader.linebuffer.LineBuffer'>
print(type(cerebro.datas[0].close))#<class 'backtrader.feeds.pandafeed.PandasData'>
print(type(cerebro.datas[0]))#<class 'list'>
print(type(cerebro.datas))# ('close', 'low', 'high', 'open', 'volume', 'openinterest', 'datetime')
print(cerebro.datas[0].getlinealiases())
结果如下:
<class 'backtrader.linebuffer.LineBuffer'>
<class 'backtrader.feeds.pandafeed.PandasData'>
<class 'list'>
('close', 'low', 'high', 'open', 'volume', 'openinterest', 'datetime')
说明:
- 1、cerebro.datas数据集的类型是 <class ‘list’> ,对应载入cerebro的股票数据,可以是多个股票,就是股票的集合。
- 2、cerebro.datas[0]是<class ‘backtrader.feeds.pandafeed.PandasData’>,其实与dataframe类似,包括以下列:(‘close’, ‘low’, ‘high’, ‘open’, ‘volume’, ‘openinterest’, ‘datetime’)的集合。
-3、cerebro.datas[0].close就是dataframe的一列数据,BackTrader称之为Line <class ‘backtrader.linebuffer.LineBuffer’> 。 - 4、cerebro.datas[0].close[0] 就是访问到数据的元素,实际数据值。
- 5、cerebro.datas[0]都是按时间顺序逆序的,第一个元素index是0 ,下一个是-1 ,以此类推。
- 6、时间序列必须用内置方法处理
print(cerebro.datas[0].datetime[0])
print(pd.to_datetime(cerebro.datas[0].datetime[0],unit='s'))
print(bt.num2date(cerebro.datas[0].datetime[0]))
结果如下:
737424.0
1970-01-09 12:50:24
2019-12-31 00:00:00
直接访问datetime列 ,是浮点数。
开始用pd.to_datetime 函数,转换的时间是1970年,迷惑很长时间。
重要:必须用自带的函数转换时间 bt.num2date()!!!
4.默认数据载入
class MyStrategy(bt.Strategy):params = dict(period=20)def __init__(self):sma = btind.SimpleMovingAverage(period=self.params.period)...
self.data has been completely removed from the invocation of SimpleMovingAverage. If this is done, the indicator (in this case the SimpleMovingAverage) receives the first data of the object in which is being created (the Strategy), which is self.data (aka self.data0 or self.datas[0])
默认使用的self是什么?
如果只有一个数据源,cerebro只载入一个股票数据,不用显式指定,系统会缺省使用self.datas[0],self.data=self.data0=self.datas[0] ,也就是第一个加入的数据源 。所以说self.data 就没有显式出现在调用SMA指示器 。
如果有多个载入数据,还是注明好,清晰可读。
5. 一切都是数据载入
class MyStrategy(bt.Strategy):#定义策略全局参数params = dict(period1=20, period2=25, period3=10, period4)def __init__(self):# 使用SMA指示器载入datas[0],使用参数1sma1 = btind.SimpleMovingAverage(self.datas[0], period=self.p.period1)# This 2nd Moving Average operates using sma1 as "data"# 使用第一个SMA指示器数据再次作为SMA的数据载入,使用参数2sma2 = btind.SimpleMovingAverage(sma1, period=self.p.period2)# New data created via arithmetic operation# 随意的计算 something = sma2 - sma1 + self.data.close# This 3rd Moving Average operates using something as "data"# 随意计算的结果作为第三次SMA数据载入,使用参数3sma3 = btind.SimpleMovingAverage(something, period=self.p.period3)# Comparison operators work too ...# 比较后取大值 ,有点疑问 ?greater = sma3 > sma1# Pointless Moving Average of True/False values but valid# This 4th Moving Average operates using greater as "data"# 比较后结果第四次载入SMA指示器,使用参数4sma3 = btind.SimpleMovingAverage(greater, period=self.p.period4)...
总而言之,所有的数据转换变化后,都可以作为数据载入,再次进行运算。
6. 参数
在backtrader中,所有的类都按照如下方法来使用参数:
1、声明一个带有缺省值的参数作为类的一个属性(元组或者字典结构)。
2、关键字类型参数(kwargs)会扫描匹配的参数,将值赋值给对应的参数,完成后从kwargs删除。
3、这些参数都可以在类实例中通过访问成员变量self.params(可以简写为self.p)来使用。
使用元组 tuple
class MyStrategy(bt.Strategy):params = (('period', 20),)def __init__(self):sma = btind.SimpleMovingAverage(self.data, period=self.p.period)
使用字典dict
class MyStrategy(bt.Strategy):params = dict(period=20)def __init__(self):sma = btind.SimpleMovingAverage(self.data, period=self.p.period)
7.Lines 关键的概念
从使用用户(通常是strategy)的角度来说,就是包括一个或多个line,这些line是一系列的数据,在图中可以形成一条线(line)。line是数组,不是pd.series ,没有index 。
class MyStrategy(bt.Strategy):params = dict(period=20)def __init__(self):self.movav = btind.SimpleMovingAverage(self.data, period=self.p.period)def next(self):if self.movav.lines.sma[0] > self.data.lines.close[0]:print(round(self.movav.lines.sma[0],2),self.data.lines.close[0],'Simple Moving Average is greater than the closing price')
执行结果:
83.34 74.4 Simple Moving Average is greater than the closing price
83.16 75.1 Simple Moving Average is greater than the closing price
83.01 76.6 Simple Moving Average is greater than the closing price
82.92 80.1 Simple Moving Average is greater than the closing price
82.82 79.64 Simple Moving Average is greater than the closing price
82.69 78.52 Simple Moving Average is greater than the closing price
82.36 76.1 Simple Moving Average is greater than the closing price
81.87 74.28 Simple Moving Average is greater than the closing price
... ...
self.movav:这个是一个SimpleMovingAverage的指标(indicator),本身就包含一个具有lines属性的sma。这里特殊注意一下,计算SimpleMovingAverage使用的self.data,没有指定具体Line的话,缺省用的是close价进行计算。
简单的方法访问lines:
xxx.lines 可以简化为 xxx.l
xxx.lines.name可以简化为xxx.lines_name
一些复杂的对象也可以通过如下方法访问:
self.data_name 等于 self.data.lines.name
如果有多个变量的话,也可以self.data1_name 替代self.data1.lines.name
此外,Line的名字也可以通过如下方式访问:
self.data.close and self.movav.sma
class MyStrategy(bt.Strategy):params = dict(period=20)def __init__(self):self.movav = btind.SimpleMovingAverage(self.data, period=self.p.period)def next(self):# 数据集0 收盘价在110和120if (self.datas[0].close[0] > 110.0) & (self.datas[0].close[0] < 120.0):print(bt.num2date(self.datas[0].datetime[0]),'self.datas[0].close[0] > 110.0')# 数据集1 收盘价在110和120 if self.datas[1].close[0] > 9.0:print(bt.num2date(self.datas[1].datetime[0]),'self.datas[1].close[0] > 9.0')# 数据集SMA 收盘价在88和90if (self.movav.lines.sma[0] > 88) & (self.movav.sma[0] < 90) :print(round(self.movav.lines.sma[0],2),'self.movav.lines.sma[0] > 88')print(self.movav.getlinealiases())#print(cerebro.datas[0].getlinealiases())
结果如下:
2018-04-18 00:00:00 self.datas[1].close[0] > 9.0
2018-04-24 00:00:00 self.datas[1].close[0] > 9.0
2018-04-25 00:00:00 self.datas[1].close[0] > 9.0
2018-04-26 00:00:00 self.datas[1].close[0] > 9.0
2019-04-09 00:00:00 self.datas[0].close[0] > 110.0
88.78 self.movav.lines.sma[0] > 88
('sma',)
89.64 self.movav.lines.sma[0] > 88
('sma',)
2019-06-20 00:00:00 self.datas[0].close[0] > 110.0
2019-06-21 00:00:00 self.datas[0].close[0] > 110.0
2019-06-24 00:00:00 self.datas[0].close[0] > 110.0
2019-06-25 00:00:00 self.datas[0].close[0] > 110.0
2019-06-26 00:00:00 self.datas[0].close[0] > 110.0
2019-06-27 00:00:00 self.datas[0].close[0] > 110.0
2019-06-28 00:00:00 self.datas[0].close[0] > 110.0
2019-07-24 00:00:00 self.datas[0].close[0] > 110.0
2019-08-01 00:00:00 self.datas[0].close[0] > 110.0
2019-08-02 00:00:00 self.datas[0].close[0] > 110.0
2019-08-05 00:00:00 self.datas[0].close[0] > 110.0
2019-08-07 00:00:00 self.datas[0].close[0] > 110.0
2019-08-09 00:00:00 self.datas[0].close[0] > 110.0
需要好好说明一下:
- 简写示例
if (self.movav.lines.sma[0] > 88) & (self.movav.sma[0] < 90) :
- 多数据源
两种方式引用
self.movav.lines.sma[0] = self.movav.sma[0]
cerebro载入两个股票数据。
特别注意:调用datas ,有s
self.datas[0].close[0]
self.datas[0].close[0]
self.datas[0].close[0]
- SMA指示器调用后,是数组,没有日期字段!!!
开始也想增加打印日期,
print(bt.num2date(self.movav.datetime[0]) 无日期
只有一列
print(self.movav.getlinealiases())
('sma',)
未完待续!!!
8.访问Lines
data = btfeeds.BacktraderCSVData(dataname='mydata.csv')...class MyStrategy(bt.Strategy):...def next(self):if self.data.close[0] > 30.0:...
两个表达式等价
if self.data.close[0] > 30.0:
if self.data.lines.close[0] > 30.0:
9. Lines长度
Lines是随时变化的,run的时候,next不断改变Lines的长度,在数据载入,策略,指示器应用中,需要测量Lines的长度。
两个函数:len和buflen之间的区别:
- len已处理了Lines
- buflen为数据加载Lines的总数 ,buflen是
还是载入的两个数据集,验证一下:
class MyStrategy1(bt.Strategy):params = dict(period=20)def __init__(self):self.movav0 = btind.SimpleMovingAverage(self.data0, period=self.p.period)self.movav1 = btind.SimpleMovingAverage(self.data1, period=self.p.period)print('self.p.period:',self.p.period)def next(self):print('self.datas[0].lines.buflen()',self.datas[0].lines.buflen())print('self.datas[1].buflen()',self.datas[1].buflen())print('len(self.datas[0])',len(self.datas[0]))print('len(self.datas[1])',len(self.datas[1]))cerebro.addstrategy(MyStrategy1,period=30)# Run over everything
cerebro.run()
结果如下:
self.p.period: 30
self.p.period: 30
self.datas[0].lines.buflen() 244
self.datas[1].buflen() 244
len(self.datas[0]) 30
len(self.datas[1]) 30
self.datas[0].lines.buflen() 244
self.datas[1].buflen() 244
len(self.datas[0]) 31
len(self.datas[1]) 31
... ...
len(self.datas[0]) 243
len(self.datas[1]) 243
self.datas[0].lines.buflen() 244
self.datas[1].buflen() 244
len(self.datas[0]) 244
len(self.datas[1]) 244
分析说明:
- self.datas[0].lines.buflen() 和self.datas[1].buflen() 一样,可以忽略lines对象。
print('self.datas[0].lines.buflen()',self.datas[0].lines.buflen())print('self.datas[1].buflen()',self.datas[1].buflen())
- 在init中print(‘self.p.period:’,self.p.period)执行了两次,因为每次加载策略的时候,不同的数据集都执行init() 。
- print(‘self.p.period:’,self.p.period) 打印值是30 ,非默认的20 。
- buflen()是lines的方法
10.Lines和参数的继承
- 支持多重继承
- 继承基类的参数
- 如果多个基类定义相同的参数,则使用继承列表中最后一个类的默认值
- 如果在子类中重新定义了相同的参数,则新的默认值将接管基类的默认值
lines还有什么方法属性:
class MyStrategy2(bt.Strategy):params = dict(period=20)def __init__(self):self.movav0 = btind.SimpleMovingAverage(self.data0, period=self.p.period)self.movav1 = btind.SimpleMovingAverage(self.data1, period=self.p.period)print('self.p.period:',self.p.period)obj_str = ''for i in dir(self.datas[0].lines):if i[:1] != '_' :obj_str += i + ',' print(obj_str)def next(self):passcerebro.addstrategy(MyStrategy2,period=30)# Run over everything
cerebro.run()
结果如下:
self.p.period: 30
advance,backwards,buflen,close,datetime,extend,extrasize,forward,fullsize,get,getlinealiases,high,home,itersize,lines,low,open,openinterest,reset,rewind,size,volume,
11.索引0和-1
重点:
0指的是系统当前正在处理的数据,而不是第一个数据。
strategy类只会进行取值操作,而indicator只会进行赋值操作。
在backtrader中,-1指的是当前处理数据(索引为0)的上一个数据。
def next(self):if self.data.close[0] > self.data.close[-1]:print('Closing price is higher today')
以当前值0为基准,上一个值索引-1,上上一个值为-2,还可以继续-3,-4…
12.切片
BackTrader的切片和Python的概念不同:
用Python的list切片从头到尾的切片,在BackTrader不能用。
myslice = self.my_sma[0:] # slice from the beginning til the end
myslice = self.my_sma[0:-1] # slice from the beginning til the end
按逆序也不行
myslice = cerebro.datas[0].close[-1:-3] # from last value backwards to the 3rd last value
myslice = cerebro.datas[0].close[-3:-1] # from last value backwards to the 3rd last value
BackTrader的切片用函数:
myslice = self.my_sma.get(ago=0, size=1) # default values shown
测试一下:
cerebro.datas[1].close.get(ago=0, size=3)
结果:
array('d', [5.82, 5.85, 5.78])
遍历处理日期:
for i in cerebro.datas[1].datetime.get(ago=0, size=3) :print(bt.num2date(i))
结果:2019-12-27 00:00:00
2019-12-30 00:00:00
2019-12-31 00:00:00
数组是支持Python的切片:
cerebro.datas[1].datetime.get(ago=0, size=5)[0:3]
结果:
array('d', [737418.0, 737419.0, 737420.0])
需要注意返回值的顺序:
最左的值对应离ago最远的值,最右的是ago索引对应的值。
例如如下是返回5最新的个值(不包括正在处理的值),通过下图理解一下:
13.Lines 的索引延迟
文档上的有点小瑕疵
self.movav = btind.SimpleMovingAverage(self.data, period=self.p.period)
定义变量应该是 self.sma
class MyStrategy4(bt.Strategy):params = dict(period=20)def __init__(self):self.sma = btind.SimpleMovingAverage(self.datas[1], period=self.p.period)self.cmpval = self.datas[1].close(-1) > self.smadef next(self):if self.cmpval[0]:print(self.cmpval[0],self.sma[0],self.datas[1].close[0],self.datas[1].close[-1])cerebro.addstrategy(MyStrategy4)# Run over everything
cerebro.run()
分析说明:
关键是close(-1) 是圆括号,不是取值的方括号!!!
对象类型是:<backtrader.linebuffer._LineDelay object at 0x7f616a25e1c0>
self.datas[1].close(-1)
重新简化,测试:
class MyStrategy5(bt.Strategy):params = dict(period=20)def __init__(self):self.cmpval = self.datas[1].close(-1) def next(self):print(self.datas[1].close[0],self.cmpval[0])cerebro.addstrategy(MyStrategy5)# Run over everything
cerebro.run()
结果 ,第一列第一个 = 第二列第二个,以此类推,
5.12 5.03
5.49 5.12
5.79 5.49
5.79 5.79
5.8 5.79
5.84 5.8
14. Lines 耦合
应用场景:
耦合主要用于将时间窗口不同的两个line建立关系。比如:
不同时间窗口的数据源具有不同的长度,indcator在使用这些数据的时候会复制这个长度。
股票的日线数据,每年大约250个(bar,对应250个工作日)
股票的周线数据,每年大约52个(bar,对应52周)
原文:
The reader could imagine a date comparison taking place in the background to find out a day - week correspondence, but:
- Indicators are just mathematical formulas and have no datetime information
They know nothing about the environment, just that if the data provides enough values, a calculation can take place.
读者可以想象一个日期比较的场景,找出日和星期的通信 ,但是:
指示器可以调整数学公式,没有(不考虑)日期信息
读者对于场景一无所知,如能够提供足够的数据,就可以计算 。
测试一下效果:
class MyStrategy6(bt.Strategy):params = dict(period=20)def __init__(self):# data0 是日线数据self.sma0 = btind.SMA(self.data1.close, period=5) # 5 日线的平均# data1 是周线数据self.sma1 = btind.SMA(self.data1.close, period=5) # 5 周线的平均self.couplesma = self.sma1()self.buysig = self.sma0 > self.couplesma#print(type(sma1())) # <class 'backtrader.metabase.LinesCoupler_14'>#print(self.sma1.get(ago=0, size=5)) # <class 'backtrader.indicators.sma.SMA'>def next(self):print('sma1:',self.sma1.get(ago=0,size = len(self.sma1)))print('self.couplesma:',self.couplesma.get(ago=0,size = len(self.sma1)))if self.buysig[0] :print(self.buysig[0],'日均线大于周均线!')# 初始化一个空的cerebor
cerebro = declare_cerebar()
# 加入策略
cerebro.addstrategy(MyStrategy6)# Run over everything
cerebro.run()
sma1通过加一个括号()将数据适配到每日的时间窗口
程序做了调整,说明如下:
- 新的数据类型
#print(type(sma1())) # <class ‘backtrader.metabase.LinesCoupler_14’>
sma1()就是耦合,数据类型:<class 'backtrader.metabase.LinesCoupler> ,是一个新的数据类型 !
self.couplesma也应该是<class 'backtrader.metabase.LinesCoupler>
-
没有触发判断语句
按说明补齐长度,应该能够进行比较,有是1的值。 -
输出结果,报错,超出:IndexError: array index out of range
日线的bar远远大于周线的bar,做SMA ,都用5个周期做,效果一样,还是应该长度不一致。
改日再看看,是数据问题,还是没有理解 line耦合的概念
15. 自然构造 操作符
第一步:用操作符创建对象
在Indicators(指标)和strategy(策略)的初始化阶段init函数,通过操作符创建对象 。
class MyStrategy7(bt.Strategy):def __init__(self):sma = btind.SimpleMovingAverage(self.data, period=20)close_over_sma = self.data.close > smasma_dist_to_high = self.data.high - smasma_dist_small = sma_dist_to_high < 3.5# Unfortunately "and" cannot be overridden in Python being# a language construct and not an operator and thus a# function has to be provided by the platform to emulate itsell_sig = bt.And(close_over_sma, sma_dist_small)print('sell_sig',type(sell_sig))print('close_over_sma',type(close_over_sma),'sma_dist_small',type(sma_dist_small))cerebro = declare_cerebar()# 加入策略
cerebro.addstrategy(MyStrategy7)
cerebro.run()
结果:
sell_sig <class 'backtrader.functions.And'>
close_over_sma <class 'backtrader.linebuffer.LinesOperation'> sma_dist_small <class 'backtrader.linebuffer.LinesOperation'>
还有<class ‘backtrader.functions.And’>数据类型!
第二步:用操作符创建对象
if self.sma > 30.0: 比较的是self.sma[0] to 30.0 (第一个Line 的当前值)
if self.sma > self.data.close: 比较 self.sma[0] 和self.data.close[0]。
class MyStrategy7(bt.Strategy):def __init__(self):self.sma = sma = btind.SimpleMovingAverage(self.data0, period=20)close_over_sma = self.data0.close > smaself.sma_dist_to_high = self.data0.high - smasma_dist_small = self.sma_dist_to_high < 3.5print(type(sma),type(close_over_sma))print(type(self.sma_dist_to_high),type(self.data0.high))# Unfortunately "and" cannot be overridden in Python being# a language construct and not an operator and thus a# function has to be provided by the platform to emulate itself.sell_sig = bt.And(close_over_sma, sma_dist_small)def next(self):# Although this does not seem like an "operator" it actually is# in the sense that the object is being tested for a True/False# responseif self.sma > 30.0:print('sma is greater than 30.0!',self.sma[0])if self.sma > self.data.close:print('sma is above the close price!',self.sma,self.data.close,self.data.close[0])if self.sell_sig: # if sell_sig == True: would also be validprint('sell sig is True!',self.sell_sig[0])else:print('sell sig is False!',self.sell_sig[0])if self.sma_dist_to_high > 5.0:print('distance from sma to hig is greater than 5.0!',self.sma_dist_to_high[0])
self.sma_dist_to_high = self.data0.high - sma
说明:
LineBuffer 类型 减 SimpleMovingAverage 类型 结果是 LinesOperation 类型,也是数值!
有点迷惑 ?!
self.sma_dist_to_high <class ‘backtrader.linebuffer.LinesOperation’>
self.data0.high <class ‘backtrader.linebuffer.LineBuffer’>
sma <class ‘backtrader.indicators.sma.SimpleMovingAverage’>
结果:
<class 'backtrader.indicators.sma.SimpleMovingAverage'> <class 'backtrader.linebuffer.LinesOperation'>
<class 'backtrader.linebuffer.LinesOperation'> <class 'backtrader.linebuffer.LineBuffer'>
sma is greater than 30.0! 52.5345
sell sig is False! 0.0
distance from sma to hig is greater than 5.0! 6.045499999999997
sma is greater than 30.0! 52.9015
sell sig is False! 0.0
... ...
不可重写的操作符/函数
如下操作符/函数以及对应重写的函数。
操作符:
- and -> And
- or -> Or
逻辑控制:
- if -> If
函数:
- any -> Any
- all -> All
- cmp -> Cmp
- max -> Max
- min -> Min
- sum -> Sum(Sum实际上是使用math.fsum作为底层操作,因为backtrader应用中需要处理大量浮点数据,而普通的sum函数精度会有影响。)
- reduce -> Reduce
操作符/函数针对迭代器运行。迭代器中的元素可以是常规的Python数值类型(int、float等),也可以是Lines的对象。
bt.And示例:
class MyStrategy(bt.Strategy):def __init__(self):sma1 = btind.SMA(self.data.close, period=15)self.buysig = bt.And(sma1 > self.data.close, sma1 > self.data.high)def next(self):if self.buysig[0]:pass # do something here
bt.If示例:
class MyStrategy(bt.Strategy):def __init__(self):sma1 = btind.SMA(self.data.close, period=15)high_or_low = bt.If(sma1 > self.data.close, self.data.low, self.data.high)sma2 = btind.SMA(high_or_low, period=15)
相关文章:

Backtrader 文档学习-Platform Concepts
Backtrader 文档学习-Platform Concepts 1.开始之前 导入backtrader ,以及backtrader 的指示器、数据反馈的模块 。 import backtrader as bt import backtrader.indicators as btind import backtrader.feeds as btfeeds看看btind模块下有什么方法和属性&#x…...

策略模式(常用)
策略模式的简介 在软件开发中,设计模式是为了解决常见问题而提供的一套可重用的解决方案。策略模式(Strategy Pattern)是其中一种常见的设计模式,它属于行为型模式。该模式的核心思想是将不同的算法封装成独立的策略类,…...

Express中使用Swagger
Swagger Swagger 是一种规范,用于描述 API 的结构,功能和参数。使用 Swagger 可以提供清晰的可视化 API 文档,可用于 API 交互的文档驱动开发,以及 API 的自动化测试和集成。 使用 npm 或 yarn 下载。 npm install swagger-jsdo…...

【C++】单一职责模式
目录 一、简介1. 含义2. 特点 二、实现1. 将类拆分成多个类2. 使用命名空间(Namespace)3. 使用组合而不是继承 三、总结如果这篇文章对你有所帮助,渴望获得你的一个点赞! 一、简介 1. 含义 在面向对象设计中,单一职责…...

GPT4-隐者地址
网址 https://evo.ninja/测试是否是GPT4 https://blog.csdn.net/fyfugoyfa/article/details/130254735...

教师考编需要什么条件
教师考编,了解考编需要什么条件是非常重要的。接下来,我来介绍几点教师考编的条件。 需要具备相应的学历背景。一般来说,考编需要具备本科或以上学历,并且所学专业与所报考的岗位相关。在某些特殊情况下,如报考幼儿园教…...

刘家窑中医医院鲁卫星主任:冬季守护心脑血管,为社区居民送去健康关爱
随着冬季的来临,气温逐渐降低,心脑血管疾病的风险也随之增加。为了提高公众对心脑血管疾病的认知和预防意识,北京刘家窑中医医院于近日成功举办了冬季守护心脑血管公益义诊活动。 本次义诊活动主要针对社区居民中的中老年人,特别是…...

专家级定位咨询:打造不可复制的市场地位
在这个快速变化的商业环境中,每个品牌都渴望在市场中占据一个独一无二的位置。但是,真正实现这一点并非易事。这就是为什么专家级定位咨询如此重要:它不仅帮助品牌发现其独特之处,还能指导它们如何有效地利用这一优势来在市场中脱…...

为什么说代码注释是程序员必备的技能?
代码注释是对代码中的特定部分或整体功能的解释和说明。注释添加在代码中,是给程序员看的,当系统运行程序,读取注释时会越过不执行。随着技术的发展,现在具有百万行代码的程序已经很常见了,在这样一个大型的代码中&…...

日期——年月日星期时间封装和年月日时间封装
年月日星期时间 function nowDate(time) {var getTime new Date().getTime(); //获取到当前时间戳var time new Date(getTime); //创建一个日期对象var year time.getFullYear(); // 年let wk new Date().getDay()var month (time.getMonth() 1).toString().padStart(2, …...

RK3568全国产化多网口板卡带poe供电,支持鸿蒙麒麟系统
信迈XM-3568-01主板采用瑞芯微RK3568四核Cortex-A55 处理器,主频最高可达2.0GHz,效能有大幅提升最高可配8GB内存容量,频率高达1600MHz;支持全链路ECC,让数据更安全可靠配置双千兆自适应RJ45以太网口,并扩展…...

UI卡顿问题
1、 监测卡顿的方式 a、Xcode 层级关系是否有异常 b、 instruments 的Animation Hitch工具检测:碰到问题,录制完了无数据(用iphone7录制有数据的,iphne14录制无数据?) 2、可能导致的卡顿的原因 a、 直播广…...

Linux操作系统的ECS云服务器上搭建WordPress网站教程
WordPress是使用PHP语言开发的博客平台,在支持PHP和MySQL数据库的服务器上,您可以用WordPress架设自己的网站,也可以用作内容管理系统(CMS)。本教程介绍如何在Linux操作系统的ECS实例上搭建WordPress网站。 前提条件 已创建Linux操作系统的ECS实例,并且手动部署LNMP环境…...

【Linux】多线程相关问题
判断题 不论是系统支持线程还是用户级线程,其切换都需要内核的支持(F) 用户态线程的切换在用户态实现,不需要内核支持。 线程包含CPU现场,可以独立执行程序(F) 线程包含cpu现场,但是…...

GPS北斗卫星时空信号安全防护装置(授时)介绍
GPS北斗卫星时空信号安全防护装置(授时)介绍 GPS北斗卫星时空信号安全防护装置(授时)介绍 当前,我国电力系统普遍采用北斗卫星或者GPS卫星授时来实现时间同步,但不加防护的授时装置存在卫星信号被干扰或欺…...

redis:一、面试题常见分类+缓存穿透的定义、解决方案、布隆过滤器的原理和误判现象、面试回答模板
redis面试题常见分类 缓存穿透 定义 缓存穿透是一种现象,引发这种现象的原因大概率是遭到了恶意攻击。具体就是查询一个一定不存在的数据,mysql查询不到数据也不会直接写入缓存,就会导致这个数据的每次请求都需要查DB,数据库压力…...

智慧公交:提高城市出行效率的数字化之路
随着城市化进程的不断加速,公共交通成为人们日常出行的主要方式之一。为了提高公共交通的效率和服务质量,智慧公交应运而生。智慧公交是一种基于物联网、大数据、人工智能等技术,对公共交通进行数字化、智能化改造的新型公共交通系统。 以此为…...

Linux - 内存 - memblock 分配器
说明 memblock是Linux内核启动早期用于管理物理内存的机制,在伙伴系统(Buddy System)接管内存管理之前为系统提供物理内存分配、释放等功能。相对于伙伴系统,memblock功能和实现较为简单。本文基于:linux_5.10 arm64平…...

SQL、Jdbc、JdbcTemplate、Mybatics
数据库:查询(show、select)、创建(create)、使用(use)、删除(drop)数据库 表:创建(【字段】约束、数据类型)、查询、修改(alter *add)、删除 DML:增加(inse…...

四六级高频词组8
目录 词组 其他链接 词组 301. in fashion(stylish, most modern)时兴,流行 302. after the fashion (of) 依照… 303. find fault with(complain about;criticize)找…...

fastapi-amis-admin快速创建一个后台管理系统增加音乐管理功能(3)
感觉为了实现maui的效果。准备了一个后端及restful项目 ,如同想吃鱼就健个鲁塘一下,但还是写一下吧。 fastapi_amis_admin 是一个功能强大的框架,旨在帮助开发者在使用 FastAPI 进行 web 开发时,能够快速创建一个高效且易于管理的…...

全球化需要先搬离中国?中国公司出海不应失去“模式自信”
中国企业出海近期热闹非凡,其中以短剧为代表的文化内容产业和跨境电商产业都吸引了大量关注。例如亚马逊在12月12日公布一组最新数据,亚马逊过去一年销售额超过1000万美金的中国卖家数量,同比增长接近30%。中国跨境电商平台在刚刚过去的“黑五…...

三大维度解码剑南春“高质量发展”丨年度盘点
执笔 | 洪大大 编辑 | 扬 灵 2023年即将画上句点,当我们回首这一年为行业带来惊喜的品牌,剑南春是其中之一。 回顾剑南春今年一整年的动作,从新品频发到双节(618、双11)热销,从全国巡展到荣誉满载&…...

外包干了3个月,技术退步明显.......
先说一下自己的情况,大专生,18年通过校招进入武汉某软件公司,干了接近4年的功能测试,今年年初,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落! 而我已经在一个企业干了四年的功能测…...

思福迪运维安全管理系统 test_qrcode_b RCE漏洞复现
0x01 产品简介 思福迪运维安全管理系统是思福迪开发的一款运维安全管理堡垒机。 0x02 漏洞概述 由于思福迪运维安全管理系统 test_qrcode_b路由存在命令执行漏洞,攻击者可通过该漏洞在服务器端任意执行代码,写入后门,获取服务器权限&#…...

Salesforce×阿里云,影响几何?
实际上,从这个视角来看,Salesforce和阿里云的合作也恰在成为着这个市场的一个新催化剂。“期待Salesforce能给中国市场带来一些新的增量,包括对合作伙伴的态度,对产品的态度等等。”一位CRM相关人士告诉我们。 那么,阿…...

Qt对excel操作
Qt库中自带对excel操作的模块QAxObject,QAxObject是Qt提供给程序员从代码中访问Office的对象类,其本质上是一个面向微软操作系统的COM接口。 QAxObject将所有Office的工作簿、表格、文档等都作为其子对象,程序员通过调用querySubObject()这个…...

每日一练 | 华为认证真题练习Day148
1、关于RSTP协议提供的保护功能说法正确的有?(多选) A. Root保护功能只能在指定端口上配置生效 B. 环路保护功能只能在根端口或Alternate端口上配置生效 C. 启用防TC— BPDU报文攻击功能后,可以避免频繁的删除HAC地址表项 D. 交换设备上…...

ES6学习(二):解构赋值
前言 解构赋值是ES6中新提出的语法,简单并且实用,数组和对象都可以使用 数组解构赋值 规则 1.其实是按照顺序一一匹配的,就像排队领取物资一样,你领到什么就是什么,没有挑的份,你排的晚了什么都没领到,那就是undifined。 2.如果给分配的是一个数组,那可以在命名时外部嵌套…...

kubebuilder开发operator
安装kubebuilder前 需要有kubernetes环境和golang环境 官网:https://go.kubebuilder.io/ 安装kubebuilder #下载 wget https://go.kubebuilder.io/dl/latest/$(go env GOOS)/$(go env GOARCH) #改名kubebuilder后加权限 chmod x kubebuilder #放到环境变量里 mv k…...