在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)
最終回測結果:
該策略在一個較短的回測期內獲得了正的收益。
聲明:本文觀點僅供交流探討,不構成任何投資建議,否則後果!!!