【答读者问19】backtrader的python基础-写给python初学者
作者:yunjinqi   类别:    日期:2021-12-23 17:58:16    阅读:1745 次   消耗积分:0 分    

backtrader是以python为基础的量化投资框架,想要使用backtrader,至少需要掌握python的基础。最好能够对python有足够的了解,并且能够达到精通的程度(虽然说很难对一门语言达到精通的程度,但是我们可以有这样一个目标),这样在后期的学习中,能够起到事半功倍的效果。这篇文章仅仅局限在如何掌握python的基础,以便在使用backtrader的时候,因为python基础不足被卡住。

网上有很多关于python基础的教程,推荐廖雪峰的python教程菜鸟教程。如果大家对python的基础没什么了解的话,建议先看一遍菜鸟的python教程,再看一遍廖雪峰的python教程。

我这篇文章目的是让大家能够尽快学会使用backtrader,但是照本宣科去讲python语法也没有太大意思,相当于重复造轮子了。我结合实际的backtrader使用过程中的需要,梳理下python的一些关键语法。

python的数据类型及操作

在看到这个标题的时候,正常情况下,您需要知道python的数据类型有哪些,以及这些数据类型的常用操作要搞清楚。

在编写策略逻辑中,经常使用到的数据类型有:字符串(str),浮点数(float),整数(int),数据结构:元组(tuple),列表(list),集合(set),字典(dict),还有经常需要判断的是否是缺失数据(NaN),是否是空值(None)。

1.字符串(str)

字符串的使用主要是涉及到数据名称处理与时间处理。

  • 数据名称处理

正常在加载数据的时候,会给数据设置一个名称,这样在使用的时候,就比较方便在strategy中编写策略的时候进行调用。很多时候传入的数据的名称是存在特定的意义的。比如平安银行的数据名称(“000001.XSHE”,字符串"."后面的字母代表不同的交易所,某数据商提供,因数据商不同,交易所标识可能不同),可以通过对这个名称进行处理,以便区分是那个交易所。

stock_name = "000001.XSHE"
name,exchange = stock_name.split(".")
print(exchange)

如果回测的是期权合约,想要知道这个数据是看涨期权还是看跌期权。根据期权命名的规则,中间字母是C的,代表是看涨期权,中间字母是P的,代表是看跌期权。大家自行尝试一下。

option_name = "M1705-C-2500"
  • 时间处理

最常用的处理时间字符串格式的用法是截取与格式转换。

时间字符串的截取,可以直接根据需要截取相应的值,比如某个数据的时间"2016-03-20 11:45:39",想要获取现在是哪一个交易日,包含年、月、日,该如何操作

# 截取包含年月日的信息
data_datatime = "2016-03-20 11:45:39"
print(data_datetime[:10])

时间格式的转换也是特别重要的,经常会用到。从时间格式转变为字符串格式,从字符串格式转变为时间格式,都有用到过。

# 把字符串时间转变为datetime的事件
data_datatime = "2016-03-20 11:45:39"
print(data_datetime[:10])

还有其他的很多需要使用字符串的地方,这里只是总结了两类使用比较多的场景。python语法中关于字符串的操作方法一定要掌握,这样在写策略的时候可以做到游刃有余。

  1. 浮点数与整数

在使用过程中,关于数字,经常需要使用的就是浮点数与整数。一般情况下,使用backtrader传入进来的高开低收成交量及持仓量都是数字。关于数字的简单处理要掌握,包括但不限于数字大小的对比(>,<,>=,<=,!=),数字的加减乘除幂次方,相除求余数等。

比如判断某个数据的持有的仓位是多还是空,可以使用

data_size = self.getposition(data).size

# 如果是多头
if data_size > 0:
    pass 
    # 去掉pass可以进行某些操作
    
# 如果是空头
if data_size < 0:
    pass
    # 去掉pass可以进行某些操作

3.元组

backtrader在实现整体框架的时候,使用了不少的元组,比如在编写策略的时候使用的参数params就是一个元组的数据类型,这个元组里面包含了三个小的元组。

params = (  ("period",256),
            ("mult",2),                  
            ("symbol","RB"),
            )

谨记一点的是元组相比于列表,是一种不可变的数据类型,这在某些场景下是非常有用的。大部分情况下,大家更习惯使用的还是列表与字典。

4.列表

重点来了,列表是使用python的重点,也是可能会犯错的地方,对于列表的使用方法一定要熟练掌握。

列表是一个python内置的数据结构,里面的每个元素都有一个index,从0依次增加,列表里面的元素可以是任意的数据类型,包括但不限于字符串,数字,列表,元组,字典等。

列表有一些常用的操作方法,下面的11种方法大家需要掌握,如果看到了并不能立刻知道用法,需要大家再去学一下list的操作。除了上面的两个python教程之外,还可以参考一下下面的这篇文章,详细讲解了列表的操作方法。

# 使用这行命令可以找到列表的常用方法
[i for i in dir([]) if "__" not in i]

list_method = [ 'append',
                 'clear',
                 'copy',
                 'count',
                 'extend',
                 'index',
                 'insert',
                 'pop',
                 'remove',
                 'reverse',
                 'sort']

下面我结合自己在使用过程中的经验,分享一些使用列表的场景及关键代码。仔细想了想,发现要使用列表的地方实在是太多了,就重点分享几个使用技巧。

python中的拷贝问题,这个是初学者特别容易错的问题,这也是量化研究或者量化开发的面试常见题目之一,用于筛选python基础薄弱的应聘者。说实话,如果这个问题答错了,让我招聘一个研究员或者开发者,我也不敢用。当理解了这个问题之后,可以避免很多不必要的错误。

python中的直接赋值,浅拷贝,深拷贝有什么区别?

这题的答案可以参考下文的链接,如果您回答不出来,需要重新复习下python的基础语法。

如何按照列表元素的第二位从小到大进行排序?比如下面的列表 a=[(“xiaoming”,95),(“xiaowang”,80),(“xiaoqiang”,99)]

答案可以参考下面的链接,也可以去阅读我写的策略代码,几乎每个策略都会有很多使用列表的地方。

字典

字典也是特别重要的,使用频率特别高,有时候使用字典,能够极大程度上简化代码。

照例使用一行代码获取字典的常用方法:

dict_method = [i for i in dir({}) if "__" not in i]
print(dict_method)

"""
['clear',
 'copy',
 'fromkeys',
 'get',
 'items',
 'keys',
 'pop',
 'popitem',
 'setdefault',
 'update',
 'values']
 """

这里面的每个方法最好都能够熟练掌握。字典在编写策略的时候,有很多的地方可以用到,尤其是我们使用多个数据的时候,使用每个数据的名称作为key,特定的值作为value,可以极大简化代码,使得代码逻辑更加清晰。

看到字典里面的copy方法,又涉及到浅拷贝与深拷贝的问题,我建议直接使用copy.deepcopy()直接深拷贝吧,完全忽略浅拷贝的问题,避免犯错。此建议只限于初学者使用,如果您python水平比较好,可以忽略,因为在特定的场合下,使用浅拷贝确实有优势。

如何判断数据是否是nan

这个也是有可能会用到的,我们使用的数据质量如果不高的话,经常会碰到缺失数据的场景。

import numpy as np
# 如果a是nan,就忽略
if np.isnan(a):
    pass
if not np.isnan(a):
    # do something
    print("a is not np.NaN")
# 这个代码写的很初级,运行效率并没有达到最好,您知道如何改进吗?

判断是否是空值(None)

这个往往和python函数的默认参数与默认的返回值有关。

# 根据b是否是None进行不同的处理
if b is None:
    # do something
    print("b is None")
if b is not None:
    # do something else
    print("b is not None")

循环、条件语句与异常处理

1.循环

最基本的for循环,基本上就可以满足大家的循环需求。比如在backtrader的next中常用的for循环:

# 对加载到backtrader中的每个数据进行判断
for data in self.datas:
    # 对data进行处理,每个data代表一个不同的数据
    print(f"当前数据的收盘价为:{data.close[0]}")
  1. 条件语句

在上个问题中,判断是否是NaN和None,分别进行不同的处理就是使用的条件语句。除了单独使用if之外,还经常使用的是if else的联合使用,还有更多条件判断的联合使用,比如if elif else,需要提醒的是,当使用条件判断的时候,尽可能对各个条件判断全,避免遗漏情况。

  1. 异常处理

以try except 为代表的异常处理机制,不太推荐初学者写策略的时候使用,容易漏掉一些细节。

python的函数与类

掌握了python的数据类型及操作基本上就算是基本上能够在backtrader中写一些简单的策略了,实际上,想要更有效率的编写策略,还是需要进一步掌握python的函数相关的语法,进而需要掌握backtrader类等高级一些的语法。

前面推荐的两份教程,要尽可能多读几遍,如果有足够的时间和精力,可以考虑读几本python语法相关的书,python官网上的文档,python的一些面试题,练习题。


一周就这样快过去了,这周前六天断断续续凑时间把这份简单的教程写出来了,这份教程很不全面,只是一个补充,学习python语法应以python官网上的文档为准,只是希望这份python语法的分享能够和上面的两份教程一样,能够节省大家的一些学习时间。

预告:最近要写的答读者问写完了,并且已经考试结束了,最近一段时间准备把已经拖了很久的股票策略写完,然后开始写期货策略,准备的第一个策略就是常见的海龟交易法,我会用backtrader做一个海龟交易法的完整版策略,让大家看下,真正的期货策略(偷笑)该怎么去实现!!!


智慧、心灵、财富,总要有一个在路上,愿我们能在人生的道路上,不断成长、不断成熟~~~

感兴趣可以关注我的专栏:

my_quant_study_note:分享一些关于量化投资、量化交易相关的思考

backtrader量化投资回测与交易:本专栏免费,分享backtrader相关的内容。

量化投资神器-backtrader源码解析-从入门到精通:本专栏目前收费299元,预计更新100篇策略(更新中)+36篇backtrader讲解(已完成)+backtrader源码分析。


版权所有,转载本站文章请注明出处:云子量化, http://www.woniunote.com/article/48
上一篇:【答读者问18】学习backtrader的捷径-写给backtrader初学者
下一篇:【答读者问20】从baostock中获取股票行情数据(尽可能避免了幸存者偏差)