日志用来记录Python量化炒股策略的状态、错误和信息消息,也经常作为调试程序的工具。
日志log
设定log级别
设定log级别语法格式如下:
log.set_level(name, level)
设置不同种类的log级别,低于这个级别的log不会输出。所有log的默认级别是debug。
各项参数意义如下:
参数name:字符串,但log种类只有3种,分别是“order” “history”和“strategy”。order表示调用order系列API产生的log;history表示调用history系列API产生的log;strategy表示程序员自己在策略代码中打的log。参数level:字符串,必须是“debug” ”info“ ”warning“ ”error“中的一个。级别是debug<info<warning<error。各级别打语法格式如下:
log.error(content)
log.warn(content)
log.info(content)
log.debug(content)
设定log级别的实例代码如下:
# 过滤掉order系列API产生的比error级别低的log
log.set_level('order', 'error')
log.info
日志log最常用的方法是info,该方法的语法格式如下:
log.info(content)
log.info等同于print输出的结果。
参数content,可以是字符串、对象等。log.info的实例代码如下:
log.info(history(10)) # 打印出history(10)返回的结果
log.info('Selling %s, amount=%s', security, amount) # 打印出一个格式化的字符串
print(history(10), data, context.portfolio)
Python量化炒股策略的定时函数
在Python量化炒股策略的初始化函数中,进行一些初始化设置后,最后运行了3个定时函数。
定时函数的定义及分类
定时函数是指,在回测和模拟交易中指定每月、每周或者每天要运行的函数。定时函数可以在具体每月或每周的第几个交易日(或者倒数第几天)的某一分钟执行。
定时函数可以分3种,分别是每日定时函数(run_daily),每周定时函数(run_weekly)和每月定时函数(run_monthly)。
定时函数的语法格式如下:
# 按月运行
run_monthly(func, monthday, time='open', reference_security)
# 按周运行
run_weekly(func, weekday, time='open', reference_security)
# 每天内何时运行
run_daily(func, time='open', reference_security)
需要注意的是,定时函数在日级模拟中使用时,如果设置time="open"或time=“9:30”,那么Python量化炒股策略的实际运行时间是9:27~9:30之间。Python量化炒股策略类取到逻辑时间(context.current_dt)仍然是9:30。
定时函数各项参数的意义
参数func:一个函数,并且该函数必须接受context参数,参数monthday:用来指定每月的第几个交易日,可以是负数,表示倒数第几个交易日。如果超出每月总交易日个数,则取临近的交易日执行。
参数weekday:用来指定每周的第几个交易日,可以是负数,表示倒数第几个交易日。如果超出每周总交易日个数,则取临近的交易日执行。参数time:一个字符串,可以是具体执行时间,支持time表达式。比如“10:00” “01:00”或者“every_bar" “open” “before_open” “after_close” “close” “morning” 和“night"。
(1)every_bar:只能在run_daily中调用;按天会在每天的开盘时调用一次,按分钟会在每天的每分钟运行。
(2)open:开盘时运行(等同于“9:30”)
(3)before_open:早上9:00运行
(4)after_close:下午15:30运行
(5)close:下午15:00运行
(6)morning:早上8:00运行
(7)night:晚上20:00运行
参数reference_security:表示时间的参照标的。例如,参照“000001.XSHG“,交易时间为9:30~15:00。
定时函数的注意事项
定时函数的注意事项有5项,具体如下:
第一,参数func必须是一个全局的函数,不能是类的成员函数,示例代码如下:
def on_week_start(context): # 定义一个全局函数pass
class MyObject(object):def on_weekstart2(self, context): # 在类中定义一个成员函数pass
def initialize(context): # 量化策略的初始化函数run_weekly(on_week_start, 1) # 正常运行# 错误,下面的语句会报错 run_weekly(MyObject().on_week_start2, 1)
第二,定时函数通过history或attribute_history获得每天数据时,是不包括当天的数据的。要获得当天数据,只能按分钟来获取。
第三,定时函数可以重复调用,即初始化函数中可以有两个或多个同名定时函数,示例代码如下:
def on_week_start(context):pass
def on_week_end(context):pass
def initialize(context): #初始化函数中有两个run_weekly定时函数# 在每周的第一个交易日和最后一个交易日分别调用两个函数run_weekly(on_week_start, 1)run_weekly(on_week_end, -1)
第四,每次调用这些定时函数都会产生一个新的定时任务。如果想修改或者删除旧的定时任务,就要调用unschedule_all(取消所有定时运行)来删除所有定时任务,然后添加新的。
提醒:取消所有定时运行的代码是(unschedule_all())
第五,如果定时函数在一个月或一周内交易日数不够,那么monthday或weekday就无法满足。这时,我们可以找这周内最近的一个日期来执行。
定时函数的实例
首先定义3个全局函数,分别是weekly()、monthly()和daily(),接着定义初始化函数,实现一次调用monthly(),4次调用daily(),具体代码如下:
def weekly(context):print('weekly %s %s' % (context.current_dt, context.current_dt.isoweekday()))
def monthly(context):print('monthly %s %s' % (context.current_dt, context.current_dt.month))
def daily(context):print('daily %s' % context.current_dt)def intialize(context):# 指定每月第一个交易日,在开盘后十分钟执行,即9:40run_monthly(monthly, 1, 'open+10m')# 指定每周倒数第一个交易日,在开盘前执行,即9:00run_montly(weekly, -1, 'before_open')# 指定每天收盘前10分钟运行,即14:50run_weekly(daily, 'close=-10m')# 指定每天收盘后执行,即15:30run_daily(daily, 'after_close')# 指定每天的10:00运行run_daily(daily, '10:00')# 指定每天的01:00运行run_daily(daily, '01:00')# 参照股指期货的时间没分钟运行一次,必须选择分钟回测,否则每天执行run_daily(daily, 'every_bar', reference_security='IF2003.CCFX')