量化策略系列教程:06技術指標MA策略

哈哈~注意到沒,今天的圖是小哥最愛的酷玩的專輯封面~

回歸正題~今天小哥再給來個不錯的策略~大家好好學習哦~

重要的事情再說三遍~新來的知友們喲~小哥的代碼是要在掘金運行的哈~別忘了哈~忘了哈~哈~

1. 策略原理:

移動平均線:Moving Average,簡稱MA,原本的意思是移動平均,由於我們將其製作成線形,所以一般稱之為移動平均線,簡稱均線。它是將某一段時間的收盤價之和除以該周期。 比如日線MA5指5天內的收盤價除以5 。

移動平均線常用線有5天、10天、30天、60天、120天和240天的指標。其中,5天和10天的短期移動平均線,是短線操作的參照指標,稱做日均線指標;30天和60天的是中期均線指標,稱做季均線指標;120天、240天的是長期均線指標,稱做年均線指標。移動平均線的計算方式有多種,最常用而簡單的是算術移動平均,又稱為簡單移動平均(SMA),計算公式為:ma=(c1+c2+....+cn)/n。

基於ta-lib的MA策略。如果當前價格高於MA,買入股票;如果當前價格低於MA,賣出股票。

2. 代碼解讀:

2.1 ma.ini

[strategy]nusername=npassword=n;回測模式nmode=4ntd_addr=localhost:8001nstrategy_id=n;訂閱代碼注意及時更新nsubscribe_symbols=SHFE.ag1705.tick,SHFE.ag1705.bar.60nn[backtest]nstart_time=2017-02-15 21:00:00nend_time=2017-03-07 16:00:00nn;策略初始資金ninitial_cash=10000000nn;委託量成交比率,默認=1(每個委託100%成交)ntransaction_ratio=1nn;手續費率,默認=0(不計算手續費)ncommission_ratio=0.0004nn;滑點比率,默認=0(無滑點)nslippage_ratio=0nnprice_type=1nn;基準nbench_symbol=SHSE.000300nn[para]ntrade_exchange=SHFEntrade_symbol=ag1705nwindow_size=200nbar_type=60ntick_size=1nsignificant_diff=21ntimeperiod=20nnn##############################################################n# logger settingsn##############################################################n[loggers]nkeys=rootnn[logger_root]nlevel=DEBUGnhandlers=console,filenn[handlers]nkeys=console,filenn[handler_file]nclass=handlers.RotatingFileHandlernargs=(ma.log,a,maxBytes=10000,backupCount=5)nformatter=simplenn[handler_console]nclass=StreamHandlernargs = (sys.stdout,)nformatter=simplenn[formatters]nkeys = simplenn[formatter_simple]nformat=%(asctime)s - %(name)s - %(levelname)s - %(message)sndatefmt=n複製代碼n 2.2 ma.pyn#!/usr/bin/env pythonn# encoding: utf-8nnnimport numpy as npnfrom collections import dequenfrom gmsdk import *nfrom talib import SMAnn# 演算法用到的一些常量,閥值,主要用於信號過濾neps = 1e-6nthreshold = 0.235ntick_size = 0.2nhalf_tick_size = tick_size / 2nsignificant_diff = tick_size * 2.6nnclass MA(StrategyBase):nn strategy example1: MA decision price cross long MA, then place a order, temporary reverse trends place more orders nn def __init__(self, *args, **kwargs):n #import pdb; pdb.set_trace()n super(MA, self).__init__(*args, **kwargs)n # 策略初始化工作在這裡寫,從外部讀取靜態數據,讀取策略配置參數等工作,只在策略啟動初始化時執行一次。nn # 從配置文件中讀取配置參數n self.exchange = self.config.get(para, trade_exchange)n self.sec_id = self.config.get(para, trade_symbol)n self.symbol = ".".join([self.exchange, self.sec_id])n self.last_price = 0.0n self.trade_unit = [3, 1, 2, 0]n # self.trade_count = 0n self.trade_limit = len(self.trade_unit)n self.window_size = self.config.getint(para, window_size) or 200n self.timeperiod = self.config.getint(para, timeperiod) or 20n self.bar_type = self.config.getint(para, bar_type) or 60n self.close_buffer = deque(maxlen=self.window_size)n self.significant_diff = self.config.getfloat(para, significant_diff) or significant_diffnn # prepare historical bars for MA calculatingn # 從數據服務中準備一段歷史數據,使得收到第一個bar後就可以按需要計算man last_closes = [bar.close for bar in self.get_last_n_bars(self.symbol, self.bar_type, self.window_size,end_time=self.start_time)]n last_closes.reverse() #因為查詢出來的時間是倒序排列,需要倒一下順序n self.close_buffer.extend(last_closes)nn # 響應bar數據到達事件n def on_bar(self, bar):n # 確認下bar數據是訂閱的分時n if bar.bar_type == self.bar_type:n # 把數據加入緩存n self.close_buffer.append(bar.close)n # 調用策略計算n self.algo_action()nn # 響應tick數據到達事件n def on_tick(self, tick):n # 更新市場最新成交價n self.last_price = tick.last_pricenn def on_execution(self, execution):n #列印訂單成交回報信息n print(("received execution: %s" % execution.exec_type))nn #策略的演算法函數,策略的交易邏輯實現部分n def algo_action(self):n # type: () -> objectn #數據轉換,方便調用ta-lib函數進行技術指標的計算,這裡用SMA指標n close = np.asarray(self.close_buffer)n ma = SMA(close, timeperiod=self.timeperiod)n delta = round(close[-1] - ma[-1],4) # 最新數據點,bar的收盤價跟ma的差n cross = (close[-1] - ma[-1]) * (close[-3] - ma[-3]) < 0 ## 判斷有否交叉n last_ma = round(ma[-1], 4) # 均線ma的最新值n momentum = round(self.last_price - last_ma,4) # 當前最新價格跟ma之間的差,成交價相對ma偏離n #print close: , closen print((close ma delta: {0}, last_ma: {1}, momentum: {2}.format(delta, last_ma, momentum)))nn a_p = self.get_position(self.exchange, self.sec_id, OrderSide_Ask) #查詢策略所持有的空倉n b_p = self.get_position(self.exchange, self.sec_id, OrderSide_Bid) #查詢策略所持有的多倉n # 列印持倉信息n print((pos long: {0} vwap: {1}, pos short: {2}, vwap: {3}.format(b_p.volume if b_p else 0.0,n round(b_p.vwap,2) if b_p else 0.0,n a_p.volume if a_p else 0.0,n round(a_p.vwap,2) if a_p else 0.0)))nn if cross and delta > threshold and momentum >= significant_diff: ## 收盤價上穿均線,且當前價格偏離滿足門限過濾條件,多信號n # 沒有空倉,開多n if (a_p is None or a_p.volume < eps):n # 依次獲取下單的交易量,下單量是配置的一個整數數列,用於倉位管理,可用配置文件中設置n vol = self.trade_unit[0]n # 如果本次下單量大於0, 發出買入委託交易指令n if vol > eps:n self.open_long(self.exchange, self.sec_id, self.last_price, vol)n else:n # 如果有空倉,平掉空倉n if a_p and a_p.volume > eps:n self.close_short(self.exchange, self.sec_id, self.last_price, a_p.volume)nn elif cross and delta < -threshold and momentum <= - significant_diff: ## bar 收盤價下穿ma均線,且偏離滿足信號過濾條件n # 沒有多倉時,開空n if (b_p is None or b_p.volume < eps):n vol = self.trade_unit[0]n if vol > eps:n self.open_short(self.exchange, self.sec_id, self.last_price, vol)n else:n # 已有多倉,平掉多倉n if b_p and b_p.volume > eps:n self.close_long(self.exchange, self.sec_id, self.last_price, b_p.volume)n else: ## 其他情況,忽略不處理n passnn ## 訂單完全成交n def on_order_filled(self, order):n print((n received order filled: sec_id: {0}, side: {1}, volume: {2}, filled price: {3}, filled: {4}n .format(order.sec_id, order.side, order.volume, order.filled_vwap, order.filled_volume)))nn# 策略啟動入口nif __name__ == __main__:n # 初始化策略n ma = MA(config_file=ma.ini)n #import pdb; pdb.set_trace() # python調試開關n print(strategy ready, waiting for market data ......)n # 策略進入運行,等待數據事件n ret = ma.run()n # 列印策略退出狀態nprint(("MA exit: {}".format(ma.get_strerror(ret))))n

如果想了解相關的python函數和掘金介面函數,走下方通道:

zjshe.cn/q/forum.php?

有不了解的可以給小編留言哦,小編會細心為大家解答~

推薦閱讀:

量化策略系列教程:19AR-MA 策略
雪球殺豬榜里的趨勢突破策略
哈工大智能薦股靠譜嗎?你怎麼看?
Python入門到精通視頻課程(11)
【翻譯搬運】Matplotlib - 用Python繪製2D和3D圖像

TAG:量化 | 宽客Quant | 代码 |