量化策略系列教程:09HANS123策略
你們可能覺得小哥有的策略有點長,明明可以很短就解決,這是因為,這個掘金介面函數需要調,小哥就是想要保護自己的知識產權,本地跑就是有安全感!證經社量化社區 - 證經社
一、策略介紹
作為外匯市場上廣為流行的一種突破交易策略,HANS123以其簡潔的開盤後N根K線的高低點突破,作為交易信號觸發的評判標準。這也是一種入場較早的交易模式,配合適當過濾技術,或可提高其勝算。
過濾原理:這個過濾是為了讓市場消化品種隔夜的各種信息,當有些突發信息公布,市場分歧很大的時候,開盤會呈現方向不明、寬幅震蕩的情況,此時,對任何突破策略都會是災難,所以忽略這段時間。
策略原理:
- 日內交易策略,收盤平倉;
- HANS123在開盤30分鐘後準備入場;
- 上軌=開盤後30分鐘高點;
- 下軌=開盤後30分鐘低點;
- 當價格突破上軌,買入開倉;
- 當價格跌穿下軌,賣出開倉。
二、策略代碼
2.1配置文件【HANS123.ini】(提示ini配置文件,需要保存成UTF8格式)
[strategy]ntd_addr=localhost:8001nusername= npassword= nstrategy_id= nmode=4n;訂閱代碼注意及時更新nsubscribe_symbols=CFFEX.IF1707.tick,CFFEX.IF1707.bar.60nn[backtest]nstart_time=2017-6-01 09:00:00nend_time=2017-7-16 15:15:00ninitial_cash=10000000ntransaction_ratio=1ncommission_ratio=0nslippage_ratio=0nn[para]ntrade_symbol=CFFEX.IF1707nopen_time=09:15:00nhans_time=09:45:00nex_time=15:10:00nlimit_times=3n
2.2策略文件【HANS123.py】
# encoding: utf-8nfrom gmsdk.api import StrategyBasenfrom gmsdk import mdnfrom gmsdk.enums import *nimport arrownimport timenn# 每次開倉量nOPEN_VOL = 5nn# 最大開倉次數nMAX_TRADING_TIMES = 50nnnclass Hans123(StrategyBase):n def __init__(self, *args, **kwargs):n super(Hans123, self).__init__(*args, **kwargs)nn # 是否已獲取當天時間標識n self.time_flag = Falsenn # 是否已獲取當天上、下軌數據n self.data_flag = Falsenn # 持倉量n self.long_holding = 0;n self.short_holding = 0;nn # 當天交易次數n self.trading_times = 0;nn self.__get_param()nn def __get_param(self):n n 獲取配置參數n n # 交易證券代碼n self.trade_symbol = self.config.get(para, trade_symbol)n pos = self.trade_symbol.find(.)n self.exchange = self.trade_symbol[:pos]n self.sec_id = self.trade_symbol[pos + 1:]nn # 開盤時間n self.open_time = self.config.get(para, open_time)nn # hans時間n self.hans_time = self.config.get(para, hans_time)nn # 強制平倉時間n self.ex_time = self.config.get(para, ex_time)nn def __get_time(self, cur_utc):n n 獲取當天的重要時間參數n n utc = arrow.get(cur_utc).replace(tzinfo=local)n cur_date = utc.format(YYYY-MM-DD)n FMT = %s %sn self.today_open_time = FMT % (cur_date, self.open_time)n print(today open time: %s % self.today_open_time)nn self.today_hans_time = FMT % (cur_date, self.hans_time)n print(today hans time: %s % self.today_hans_time)nn today_ex_time = FMT % (cur_date, self.ex_time)n print(today exit time:%s % today_ex_time)nn self.ex_time_utc = arrow.get(today_ex_time).replace(tzinfo=local).timestampn self.hans_time_utc = arrow.get(self.today_hans_time).replace(tzinfo=local).timestampnn def __init_band_data(self, bar_type):n n 獲取上、下軌數據n n bars = self.get_bars(self.trade_symbol, bar_type, self.today_open_time, self.today_hans_time)n close_list = [bar.close for bar in bars]nn # 上軌n self.upr_band = max(close_list)n print(upper band:%s % self.upr_band)nn # 下軌n self.dwn_band = min(close_list)n print(down band: %s % self.dwn_band)nn def on_tick(self, tick):n n tick行情事件n n # 獲取最新價n self.last_price = tick.last_pricenn def on_bar(self, bar):n n bar周期數據事件n n # 獲取當天的時間參數n if self.time_flag is False:n self.__get_time(bar.utc_time)n self.time_flag = Truenn # 計算上、下軌n if bar.utc_time < self.ex_time_utc and bar.utc_time > self.hans_time_utc:n if self.time_flag is True and self.data_flag is False:n self.__init_band_data(bar.bar_type)n self.data_flag = Truenn # 休市前強平當天倉位n if bar.utc_time > self.ex_time_utc:n if self.long_holding > 0:n self.close_long(self.exchange, self.sec_id, 0, self.long_holding)n print(exit time close long: %s, vol: %s % (self.trade_symbol, self.long_holding))n self.long_holding = 0nn elif self.short_holding > 0:n self.close_short(self.exchange, self.sec_id, 0, self.short_holding)n print(exit time close long: %s, vol: %s % (self.trade_symbol, self.short_holding))n self.short_holding = 0n returnnn if self.trading_times > MAX_TRADING_TIMES:n print(trading times more than max trading times, stop trading)n returnnn # 交易時間段n if bar.utc_time > self.hans_time_utc and bar.utc_time < self.ex_time_utc:n if bar.close > self.upr_band:n if self.short_holding > 0:n # 有空倉,先平空倉n self.close_short(self.exchange, self.sec_id, 0, self.short_holding)n print(close short: %s, vol:%s % (self.trade_symbol, self.short_holding))n self.short_holding = 0nn # 開多倉n self.open_long(self.exchange, self.sec_id, 0, OPEN_VOL)n print(open long: %s, vol:%s % (self.trade_symbol, OPEN_VOL))n self.long_holding += OPEN_VOLnn # 開倉次數+1n self.trading_times += 1n elif bar.close < self.dwn_band:n if self.long_holding > 0:n # 有多倉,先平多倉n self.close_long(self.exchange, self.sec_id, 0, self.long_holding)n print(close long: %s, vol:%s % (self.trade_symbol, self.long_holding))n self.long_holding = 0nn # 開空倉n self.open_short(self.exchange, self.sec_id, 0, OPEN_VOL)n print(open short: %s, vol:%s % (self.trade_symbol, OPEN_VOL))n self.short_holding += OPEN_VOLnn # 開倉次數+1n self.trading_times += 1nnif __name__ == __main__:n hans123 = Hans123(config_file=Hans123.ini)n ret = hans123.run()nprint(hans123.get_strerror(ret))n
三、回測結果
如果想了解相關的python函數和掘金介面函數,走下方通道:
http://zjshe.cn/q/forum.php?mod=viewthread&tid=57&extra=page%3D1
有不了解的可以給小編留言哦,小編會細心為大家解答~
推薦閱讀:
※哈工大智能薦股靠譜嗎?你怎麼看?
※PonderRNN對HS300指數預測
※2017年史上最全Quant資源補充整理 (完整版)
※機器學習——到底在量化投資中用的好嗎?