在2000年7月,日本举办了首次“ROBBINS-TAICOM期货冠军比赛”,总共比赛历时半年。从第一周起,一位名叫Fairy(菲阿里)的先生便位居首位,其后也进展顺利,不断增加收益率,结果位居首位的他一次也未将首位让于他人,从而创造了1089%的惊人战绩,荣获了比赛的冠军,此后菲阿里和本次比赛的亚军亚军炭谷道孝合著了一本书——《1000%的男人——期货冠军奇迹的买卖方法》,由于这本书是以日记的形式写作,所以你很难看到菲阿里总结的交易理论和交易方法。除非你研究他每笔交易和所配的图形,再根据他的文字提炼出他的方法。但由于日本人的写作风格和一些翻译问题,这也很难做的到。至于菲阿里四价,则是后人总结的菲阿里交易方法。
策略逻辑:日内突破可以获得盈利
策略内容:上轨=昨日最高点;下轨=昨日最低点;止损=今日开盘价;如果没有持仓,且现价大于了昨天最高价做多,小于昨天最低价做空。如果有多头持仓,当价格跌破了开盘价止损。如果有空头持仓,当价格上涨超过开盘价止损。
资金管理:一次买入一手
风险控制:无
源代码:
# coding=utf-8
from __future__ import print_function, absolute_import
from gm.api import *
"""
上轨=昨日最高点;
下轨=昨日最低点;
止损=今日开盘价;
如果没有持仓,且现价大于了昨天最高价做多,小于昨天最低价做空。
如果有多头持仓,当价格跌破了开盘价止损。
如果有空头持仓,当价格上涨超过开盘价止损。
选取SHFE的rb2010 在 2020-02-07 15:00:00 到 2020-04-15 15:00:00 进行了回测。
注意:
1:为回测方便,本策略使用了on_bar的一分钟来计算,实盘中可能需要使用on_tick。
2:实盘中,如果在收盘的那一根bar或tick触发交易信号,需要自行处理,实盘可能不会成交。
3:本策略使用在15点收盘时全平的方式来处理不持有隔夜单的情况,实际使用中15点是无法平仓的。
"""
# 策略中必须有init方法
def init(context):
""" init函数是在策略开始运行时被调用,进行初始化工作的函数"""
# 设置要进行回测的合约 合约名称写法详见 https://www.myquant.cn/docs/python/python_concept#44e233ec21d880c2
# 或者可以在掘金终端的仿真交易中输入这个代码看是否查询的是需要的标的
context.symbol = 'SHFE.rb2010' # 订阅&交易标的, 此处订阅的是上期所的螺纹钢 2010
# 订阅行情 第一个参数是标的, 第二个是时间周期,表示日线,第三个指指定设置count参数,表示需要的滑窗大
# 详见 https://www.myquant.cn/docs/python/python_subscribe#15ad56f8be8519c0
# 只需要最新价,所以只需要订阅一个, 如果用tick,次数太多,用一分钟线代替
subscribe(symbols=context.symbol, frequency='60s', count=1)
context.count = 0 # 记录开仓次数,确保一天只开一次,开多了会有一些问题
schedule(schedule_func=algo, date_rule='1d', time_rule='8:50:00')
def algo(context):
# 获取历史的n条信息,data是一个pandas的DataFrame详见
# https://www.myquant.cn/docs/python/python_select_api#6fb030ec42984aff
context.data = history_n(symbol=context.symbol, frequency='1d', end_time=context.now,
fields='symbol,open,high,low',count=2, df=True)
def on_bar(context, bars):
"""
当init中subscribe订阅过的标的有新tick的时候,on_tick 会被调用,用来处理计算和交易下单逻辑
详见 https://www.myquant.cn/docs/python/python_data_event#b198d6b609adb1d4
:context 是在多个函数直接传递变量的全局变量,所有的数据都可以通过context来传递
:tick 是当前触发on_tick的tick。参考https://www.myquant.cn/docs/python/python_object_data#29852bf1b0fd29bb
"""
# 取出订阅的这一分钟的bar
bar = bars[0]
data = context.data
# 获取现有持仓 返回的是一个list的各种合约的持仓对象 详见
# https://www.myquant.cn/docs/python/python_object_trade#Position%20-%20%E6%8C%81%E4%BB%93%E5%AF%B9%E8%B1%A1
position_long = context.account().position(symbol=context.symbol, side=PositionSide_Long)
position_short = context.account().position(symbol=context.symbol, side=PositionSide_Short)
# 交易逻辑部分
if position_long: # 多头持仓小于开盘价止损。
if bar.close < data.loc[1, 'open']:
order_volume(symbol=context.symbol, volume=1, side=OrderSide_Sell,
order_type=OrderType_Market, position_effect=PositionEffect_Close)
elif position_short: # 空头持仓大于开盘价止损。
if bar.close > data.loc[1, 'open']:
order_volume(symbol=context.symbol, volume=1, side=OrderSide_Buy,
order_type=OrderType_Market, position_effect=PositionEffect_Close)
else: # 没有持仓。
if bar.close > data.loc[0, 'high'] and not context.count: # 当前的最新价大于了前一天的最高价
# 开多
order_volume(symbol=context.symbol, volume=1, side=OrderSide_Buy,
order_type=OrderType_Market, position_effect=PositionEffect_Open)
context.count = 1
elif bar.close < data.loc[0, 'low'] and not context.count: # 当前最新价小于了前一天的最低价
# 开空
order_volume(symbol=context.symbol, volume=1, side=OrderSide_Sell,
order_type=OrderType_Market, position_effect=PositionEffect_Open)
context.count = 1
# context.now 返回运行时间, 详见 https://www.myquant.cn/docs/python/python_concept#8079e2e4dad05879
if context.now.hour == 15 : #每天收盘重新置0
print('close all')
order_close_all() # 时间超过下午2:55以后,全部平仓。
context.count = 0
if __name__ == '__main__':
run(strategy_id='strategy_id',
filename='main.py',
mode=MODE_BACKTEST,
token='token_id',
backtest_start_time='2020-02-07 15:00:00',
backtest_end_time='2020-04-15 15:00:00',
backtest_initial_cash=10000,
backtest_commission_ratio=0.0001,
backtest_slippage_ratio=0.0001)
最终回测结果:
该策略在一个较短的回测期内获得了正的收益。
声明:本文观点仅供交流探讨,不构成任何投资建议,否则后果!!!