一位用户在QQ中向我们提了这样一个问题:
我想咨询一下,我有一个策略是在开盘前算出一个价格,如果高于这个价格就卖出,低于3%以上就买入,比如周日我关注万科,我打算的数字是10,如果万科价格是9.7我就买入,涨到10我就卖出。周一晚上我算出来12,如果周二价格是12*0.97=11.64我就买入
这个策略用你们的平台可以回测吗?有没有类似的案例代码,java或者python的都可以。我第一次用你们的平台,还有点不会用
其实这也是一个大家经常遇到的问题,我可能会编程,也懂一些策略思路,但是还是不知道如何从ricequant上开始呢?我们来看看这个问题作为一个范例来深入了解吧~
1. 分析一个策略的用到什么样的数据。从这个策略来看只需要判断前一天的收盘价是否大于或小于某个价格就进行买入或卖出的操作,因此只使用到了市场交易数据,并且是希望拿到“前一天”的收盘价。那么所有的历史市场交易数据我们都可以从 history_bars拿到就可以了。
2. 调仓频率。从这个策略来看是希望在开盘前计算出来是否买入或卖出,因此是最多每日调仓一次即可。那么配合使用before_trading (每天盘前) 运行一次计算判断需要做买入或卖出的操作即可。
3. 下单交易。首先需要了解的是需要做什么样的组合落单,Ricequant提供了较为丰富的下单API,从这个例子中是单独操作一个股票满仓杀入或平仓,注意每日都是满仓操作,因此使用order_target_percent就最为方便了,只需要声明是99%就可以成功将资金下单了,留下1%预留给手续费使用。
那么首先我们先制定一个小的目标(赚取1000万!),在before_trading中编写一个判断买入或卖出的逻辑,before_trading是ricequant的策略API中必带的一个回调函数,这里面的逻辑会在每日的开盘前运行(真实时间大概是早上8:30左右),这段代码的comment已经在解释了:
# before_trading此函数会在每天交易开始前被调用,当天只会被调用一次
def before_trading(context, bar_dict):
# 通过 history API 以及 只有1天来拿到前一天的历史收盘价
hist_series = history('万科A',1, '1d', 'close')
# 如果不清楚怎么使用的话,打印总是好的。这里返回的hist_series是一个series的类型,存储的是收盘价
logger.info(str(hist_series))
# 唯一的一个数据就是昨天的收盘价。
yesterday_close = hist_series[0]
# 利用context来储存一个全局变量 - 买入或卖出信号,这个信号由下面的逻辑来决定. 每天开盘前初始化变成‘’
context.signal = ''
# 将今日的操作重置为False
context.fired = False
# 假设计算出来的一个神奇数字是7.5, 那么如果低于3%以上就买入,高于7.5这个价格就卖出。
# 您可以任意修改这个数值或者通过一些复杂的公式来计算出来这个神奇数字
magic_number = 7.5
if yesterday_close <= magic_number * 0.97:
context.signal = 'buy'
elif yesterday_close > magic_number:
context.signal = 'sell'
# 保持良好的习惯继续打印吧:
if context.signal != '':
logger.info('获得调仓信号: ' + context.signal)
接着需要考虑下单执行了,这个逻辑只能在handle_bar中触发,因为before_trading的时候市场还没开始呢!
# 你选择的证券的数据更新将会触发此段逻辑,例如日或分钟历史数据切片或者是实时数据切片更新
def handle_bar(context, bar_dict):
# 开始编写你的主要的算法逻辑
# 如果您的策略今天没有下过单 (便于和分钟回测进行兼容)。
if not context.fired:
if context.signal == 'buy':
# 0.99 表示用现有资金 99% 全部买入,留一部分给手续费
order_target_percent(context.stock, 0.99)
# 今天已经调仓买入了,不再操作
context.fired = True
elif context.signal == 'sell':
# 设置成0就是清仓全部卖出了
order_target_percent(context.stock, 0)
# 今天已经调仓卖出了,不再操作
context.fired = True
那么这个策略就搞定了,您只需要后面再修改magic_number那部分的数值即可了。其实写一个策略并不难,可能难得只是写下第一行逻辑…
收益图:
风险指标:
源代码:
# 可以自己import我们平台支持的第三方python模块,比如pandas、numpy等。
# 在这个方法中编写任何的初始化逻辑。context对象将会在你的算法策略的任何方法之间做传递。
def init(context):
context.stock = "万科A"
# 实时打印日志
logger.info("Interested at stock: " + str(context.stock))
# 判断当日是否已经买过或卖出了
context.fired = False
# before_trading此函数会在每天交易开始前被调用,当天只会被调用一次
def before_trading(context, bar_dict):
# 通过 history API 以及 只有1天来拿到前一天的历史收盘价
hist_series = history_bars('万科A',1, '1d', 'close')
# 如果不清楚怎么使用的话,打印总是好的。这里返回的hist_series是一个series的类型,存储的是收盘价
logger.info(str(hist_series))
# 唯一的一个数据就是昨天的收盘价。
yesterday_close = hist_series[0]
# 利用context来储存一个全局变量 - 买入或卖出信号,这个信号由下面的逻辑来决定. 每天开盘前初始化变成‘’
context.signal = ''
# 将今日的操作重置为False
context.fired = False
# 假设计算出来的一个神奇数字是7.5, 那么如果低于3%以上就买入,高于7.5这个价格就卖出。
# 您可以任意修改这个数值或者通过一些复杂的公式来计算出来这个神奇数字
magic_number = 7.5
if yesterday_close <= magic_number * 0.97:
context.signal = 'buy'
elif yesterday_close > magic_number:
context.signal = 'sell'
# 保持良好的习惯继续打印吧:
if context.signal != '':
logger.info('获得调仓信号: ' + context.signal)
# 你选择的证券的数据更新将会触发此段逻辑,例如日或分钟历史数据切片或者是实时数据切片更新
def handle_bar(context, bar_dict):
# 开始编写你的主要的算法逻辑
# 如果您的策略今天没有下过单 (便于和分钟回测进行兼容)。
if not context.fired:
if context.signal == 'buy':
# 0.99 表示用现有资金 99% 全部买入,留一部分给手续费
order_target_percent(context.stock, 0.99)
# 今天已经调仓买入了,不再操作
context.fired = True
elif context.signal == 'sell':
# 设置成0就是清仓全部卖出了
order_target_percent(context.stock, 0)
# 今天已经调仓卖出了,不再操作
context.fired = True
Python策略范例系列目录:
1. Python策略范例1-一步一步找Alpha
2. Python策略范例2-一个简单的技术指标策略
3. Python策略范例3-了解米筐撮合机制
4. Python策略范例4-策略怎么样,米筐来分析
5. Python策略范例5-股息率策略
6. Python策略范例6-海龟交易的Python完全版
7. Python策略范例7-Dual Thrust 交易策略
8. Python策略范例8-止损/止盈的七种方法
当前阅读> 9. Python策略范例9-我有一个策略想法,如何一步步转化成策略代码?
10. Python策略范例10-参数优化框架