這篇文章將為大家詳細講解有關Python中怎么實現一個菲阿里四價策略,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。
菲阿里簡介
菲阿里是一位日本的交易者,主要偏向于商品期貨日內主觀交易。其大名遠揚是在2001年的羅賓斯(ROBBINS-TAICOM)期貨冠軍大賽中,以1098%的成績獲得冠軍。并且在之后的兩年里再以709%、1131%的成績奪冠。從成績就知道,菲阿里是一個非常優秀的交易者。
幸運的是,菲阿里在《1000%的男人》這本書中詳盡敘述了他的交易方法,菲阿里四價策略正是后人總結他的交易方法。雖然只是從外在形式加上自己的理解模仿了一部分,并不代表菲阿里全部交易精髓,但至少可以幫助我們在構建策略時拓展思路。
策略邏輯
菲阿里四價策略是一種比較簡單的趨勢性日內交易策略,四價分別是指:昨天高點、昨天低點、昨日收盤價、今天開盤價。從書中的交易筆記來看,菲阿里不使用任何分析工具,而是大量應用阻溢線的概念,也就是通常我們所說的阻力線和支撐線。
阻力線 = 昨日最高價
支撐線 = 昨日最低價
對于阻力線和支撐線的定義,他使用的是昨日最高價和昨日最低價,可以視為昨天價格的波動范圍,這也意味著多頭或空頭只有足夠的力量時,才會有效突破阻力線和支撐線。并且一旦有突破這個波動范圍,則說明價格背后的動能較大,后續走勢可能會沿最小阻力線運動的概率較大。
多頭開倉:價格突破阻力線
空頭開倉:價格突破支撐線
如果開盤價處于阻力線和支撐線之間,當價格向上突破阻力線就建立多頭,當價格向下突破支撐線就建立空頭。如果一切順利,則一直持倉到收盤。這樣做的好處是,符合了充分非必要條件,即突破不一定上漲/下跌,但上漲/下跌一定會突破,也就是始終守在行情發生的必經之路伺機而動,因為較大行情的上漲和下跌一旦出現,勢必要突破阻力線和支撐線的。
當然這也是出錯率最高的方法,因為很多時候價格只是暫時性的突破了關鍵位置,如果貿然開倉可能會面臨價格隨時反向運動的風險。這時就需要設置一些過濾條件,限制假突破造成的來回開平倉問題。另外在交易周期上也盡量避免波動過于混亂的5分鐘周期以下K線。
但是開倉后,盈利了還好,如果遇到虧損,總不能從小虧損一直積累到大虧損,才在收盤時平倉吧,這樣顯然不合理。所以我們對于平倉有兩種處理方式:收盤平倉和止損平倉。如果K線上破高點或下破低點后又回到原來的區間內,就要考慮止損了。
多頭平倉:收盤前5分鐘或達到多頭止損線
空頭平倉:收盤前5分鐘或達到空頭止損線
實際上菲阿里在主觀交易中,還有很多交易方法,包括:開盤后先漲后跌,跌破開盤價做空,止損設在之前上漲的最高點;開盤后先跌后漲,突破開盤價做多,止損設在之前下跌的最低點。動手能力強的朋友可以在自己的策略中增改。
到這里你會發現,對于一天的價格走勢來說,收盤價相對于開盤價的漲跌,其概率接近于50%。菲阿里的交易方法在勝率上就利于不敗之地,再加上行情順利的時候一直持倉到收盤,在行情不符合自己的預期時及時止損。形成了截斷虧損,讓利潤奔跑的正向交易方式,這也是長期交易下來積累利潤的原因。
策略編寫
第1步:編寫策略框架
# 策略主函數 def onTick(): pass # 程序入口 def main(): while True: # 進入無限循環模式 onTick() # 執行策略主函數 Sleep(1000) # 休眠1秒
定義一個main函數和一個onTick函數,然后再main函數中,寫入while循環,重復執行onTick函數。
第2步:導入庫
import time # 用于轉換時間格式
因為我們這個是日內策略,到時候需要判斷K線時間戳,如果有持倉,并且臨近收盤時平倉出局。那么我們就直接import time就可以了。
第3步:獲取基礎數據
bar_arr = _C(exchange.GetRecords, PERIOD_D1) # 獲取日線數組 if len(bar_arr) < 2: # 如果小于2根K線 return # 返回繼續等待數據 yesterday_high = bar_arr[-2]['High'] # 昨日最高價 yesterday_low = bar_arr[-2]['Low'] # 昨日最低價 yesterday_close = bar_arr[-2]['Close'] # 昨日收盤價 today_open = bar_arr[-1]['Open'] # 當日開盤價
菲阿里四價需要用到四個數據:昨日最高價、昨日最低價、昨日收盤價、當日開盤價。因為這些都是日線級別的數據,所以我們在使用GetRecords的時候,可以直接傳入PERIOD_D1參數,表明我們要獲取的是日K,這樣無論你的策略加載的是哪個周期的數據,它始終獲取的都是日線級別的數據。
另外,細心的朋友可能已經發現,為什么這一次在調用GetRecords的時候,代碼的寫法跟以前不一樣?這次我們使用的是發明者量化軟件內置的重試函數_C()。使用這個函數的好處是,該函數會一直調用指定函數到成功返回,這樣可以避免直接使用GetRecords函數時,沒有獲取到數據導致報錯的情況。
第4步:處理時間和獲取最新價格
bar_arr = _C(exchange.GetRecords) # 獲取當前設置周期K線數組 current_time = bar_arr[-1]['Time'] # 獲取當前K線時間戳 time_local = time.localtime(current_time / 1000) # 處理時間戳 hour = int(time.strftime("%H", time_local)) # 格式化時間戳,并獲取小時 minute = int(time.strftime("%M", time_local)) # 格式化時間戳,并獲取分鐘 current_close = bar_arr[-1]['Close'] # 獲取最新價格
既然是獲取當前的時間,那么肯定是使用獲取當前設置周期的K線數據更為合適,所以需要重新使用一次GetRecords,這次我們同樣也是使用_C()重試函數,在不傳入參數的情況下,就是默認獲取當前設置周期的K線數組。另外,獲取最新價格的目的是,計算交易邏輯和下單。
第5步:處理時間
def trade_time(hour, minute): hour = str(hour) minute = str(minute) if len(minute) == 1: minute = "0">
之所以創建這個函數,是因為我們在開倉之前,需要判斷當前時間,是否在我們規定的交易時間之內,以及有持倉的時候,當前時間是否臨近收盤。在第4步中,我們已經獲取到了當前K線小時和分鐘,為了方便比較,我們采用小時加分鐘的方法,比如:如果K線時間是9:05,那么trade_time返回的結果就是905;如果K線時間是14:30,那么trade_time返回的結果就是1430等等。
第6步:獲取持倉
real_position = _C(exchange.GetPosition) # 獲取持倉數組 if len(real_position) > 0: # 如果持倉數組長度大于0 real_position = real_position[0] if real_position['ContractType'] == 'rb888': # 如果持倉品種等于訂閱品種 if real_position['Type'] == 0 or real_position['Type'] == 2: # 如果是多單 mp = real_position['Amount'] # 賦值持倉為正數 elif real_position['Type'] == 1 or real_position['Type'] == 3: mp = -real_position['Amount'] # 賦值持倉為負數 else: mp = 0 # 賦值持倉為0
在之前的章節中,我們一直使用的是虛擬持倉,雖然編寫起來簡單,但只能適用于理想環境下。為了更貼近實戰,在之后的章節中,我們將使用真實的持倉數據。要獲取真實的持倉數據,其實也沒那么難,直接使用發明者量化軟件的GetPosition方法,就可以獲取到當前賬戶的所有持倉。
GetPosition返回的是一個包含字典的一維數組:
# 例子 [{'MarginLevel': 16, 'Amount': 1.0, 'FrozenAmount': 0.0, 'Price': 3540.0, 'Profit': -30.0, 'Margin': 2124.0, 'Type': 0, 'ContractType': 'rb888'}]
其中,Amount是持倉數量、Price是開倉價格、Profit是當前利潤、Type是多空方向(根據發明者量化API的定義,Type的值是0或2是代表多頭,1或3代表空頭)、ContractType是合約代碼。而我們把多頭持倉規整為正數,把空頭持倉規整為負數。
第7步:設置止損
# 設置多頭止損 if today_open / yesterday_high > 1.005: # 如果當天開盤價大于昨天最高價 long_stop_loss = yesterday_high # 設置多頭止損價為昨天最高價 elif today_open / yesterday_high < 0.995: # 如果當天開盤價小于昨天最高價 long_stop_loss = today_open # 設置多頭止損價為當天開盤價 else: # 如果當天開盤價接近于昨天最高價 long_stop_loss = (yesterday_high + yesterday_low) / 2 # 設置多頭止損為昨天中間價 # 設置空頭止損 if today_open / yesterday_low < 0.995: # 如果當天開盤價小于昨天最低價 short_stop_loss = yesterday_low # 設置空頭止損價為昨天最低價 elif today_open / yesterday_low > 1.005: # 如果當天開盤價大于昨天最低價 short_stop_loss = today_open # 設置空頭止損價為當天開盤價 else: # 如果當天開盤價接近于昨天最低價 short_stop_loss = (yesterday_high + yesterday_low) / 2 # 設置多頭止損為昨天中間價
在大多數情況下,價格突破阻力線和支撐線,就把止損設置到當前開盤價這個位置。但是這里面有個問題:如果當天開盤價大于阻力線,而價格往下走;或者當天開盤價小于支撐線,而價格往上走,會造成邏輯錯誤,導致頻繁開平倉。
為了解決這個問題,我們需要根據當天開盤與阻力線和支撐線的位置關系,分別設置不同的止損價格。如果當天開盤價大于昨天最高價0.5%,那么就把多頭的止損設置在昨天的最高價;如果當天開盤價在阻力線和支撐線之間,那么多頭的止損價格還是當天的開盤價;如果當天開盤價接近于昨天最高價,那么就把多頭的止損設置在昨天的中間價。設置空頭的止損也是根據這個道理。
第8步:下單交易
if mp > 0: # 如果當前持有多單 if current_close < long_stop_loss or trade_time(hour, minute) > 1450: # 如果當前價格小于多頭止損線,或者超過規定的交易時間 exchange.SetDirection("closebuy") # 設置交易方向和類型 exchange.Sell(current_close - 1, 1) # 平多單 if mp < 0: # 如果當前持有空單 if current_close > short_stop_loss or trade_time(hour, minute) > 1450: # 如果當前價格大于空頭止損線,或者超過規定的交易時間 exchange.SetDirection("closesell") # 設置交易方向和類型 exchange.Buy(current_close + 1, 1) # 平空單 if mp == 0 and 930 < trade_time(hour, minute) < 1450: # 如果當前無持倉,并且在規定的交易時間內 if current_close > yesterday_high: # 如果當前價格大于昨天最高價 exchange.SetDirection("buy") # 設置交易方向和類型 exchange.Buy(current_close + 1, 1) # 開多單 elif current_close < yesterday_low: # 如果價格小于昨天最低價 exchange.SetDirection("sell") # 設置交易方向和類型 exchange.Sell(current_close - 1, 1) # 開空單
關于Python中怎么實現一個菲阿里四價策略就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。