Skip to main content

【程式交易實戰 04】網格交易 - 了解市場震盪的利潤收割機

· 9 min read

歡迎來到 程式交易實戰 的第四堂課,還記得上週學到衡量策略績效的方法嗎?我們從中觀察到大部分策略都有 MDD 過大的問題,原因可能是個股走勢疲弱或是沒有停利停損的機制。本週我們將藉由「網格交易策略」的實作來看看有停損停利、加減碼機制的策略表現如何?

讀完本篇文,您將學會...

  • 熟悉網格交易原理
  • 實作網格交易策略

網格交易的運作模式

網格交易是一種較頻繁買賣的策略,適合用在上下波動較大的商品上,將投入的資金切為多份,當價格下跌一定比例時買進一單位,上漲一定比例時賣出一單位,隨著商品的波動不斷執行。

week4_01

如上圖所示,第一次進場時買進 50% 資金作為起始部位,當股價上漲 1x% 時就賣出 10% 的部位,當股價往下回跌 1x% 時就補回 10% 的部位。

此方法為網格交易的核心概念,細節上可以調整的參數、方法,以下將一一介紹。

  • 設定網格的上下限

上圖的演示我們發現最後漲到 5x% 時就會將部位清空,那如果部位清空後繼續漲...該怎麼辦呢?沒有部位就失去了獲利的機會,所以我們需要設定合理的價格上下限才不會時常發生這種狀況,可以藉由統計方法來將較常發生的連續上漲值設為上限;連續下跌設為下限。

  • 設定網格大小

有了上下限以後,就可以決定如何分批進出場,可以設定波動達一定 % 數或是一定的價格就交易。

網格交易優勢

高勝率,因為交易都是低買高賣,雖然部位不大報酬率不高,但可在震盪行情中穩定獲利。

網格交易劣勢

與波段策略相比報酬率可能較低,當走勢由震盪行情轉為一段上漲趨勢時,策略會逐步出場減碼,若賣完所有部位後還持續上漲,就無法在後續的行情中獲利;反之,若遇到一段下跌趨勢,策略會逐步進場加碼,若已經用光所有資金後還持續下跌,就會因為資金用盡而被套牢,如下圖的情況。

week4_02

網格交易實作

看完網格的基本介紹後是不是很好奇實作網格交易的策略結果如何呢?

以下將手把手帶大家實現日內網格交易策略,這次使用今日成交金額較大的元太(8069.tw)作為範例並以富果的 Candles API 進行實作,並以首根 k 棒的收盤價作為基數,將網格區間設定為 0.5%。

# 載入相關套件
from fugle_marketdata import RestClient
import numpy as np
import pandas as pd

# 透過自己的行情 API key 取得行情資料
client = RestClient(api_key = 'INPUT_YOUR_API_KEY')
stock = client.stock

# 取得分 k 資料
candles_data = stock.intraday.candles(symbol = "8069", timeframe = "1")

# 取得分 k 收盤價
close_price_list = list(map(lambda x:x['close'], candles_data["data"]))

相信大部分讀者都有資金上的考量,因此先將最大部位的上限設定為十張,並設定首次進場買進 50% 部位(5 張),每上漲 0.5% 就買進 1 張、每下跌 0.5% 就賣出 1 張! 我們目前的 demo 以每分 k 的收盤價當作現價進行實作,若想要進行實際交易,也可考慮使用 Quote API 的最新價格搭配交易 API 進行實作,範例如下:

# 記錄部位成本
position_list = []

# 記錄損益
profit_record = []

# 記錄第一根 K 棒的收盤價格當作基準價
base_price = close_price_list[0]

# 網格區間 -> 設置 0.5%
grid_range = 0.005

# 第一根 K 棒買進 n 張 -> 設 n = 5
n = 5
for i in range(n):
position_list.append(close_price_list[0])

# 跑每一筆紀錄
for price in close_price_list[1:]:
# 判斷該日是否該執行加碼 or 減碼 or 不動作
# 如果漲 1% 且還有部位,賣一張
if price >= base_price*(1+(1-len(position_list)+n)*grid_range) and len(position_list) > 0:
print('sell', price, price - position_list[0], len(position_list))

profit_record.append((price - position_list[0])*1000)
del position_list[0]

# 如果跌 1% 且部位尚未買滿,買一張
elif price <= base_price*(1-(len(position_list)+1-n)*grid_range) and len(position_list) < 10:
position_list.append(price)
print('buy', price, len(position_list), position_list)

# 尾盤清空所有部位
for pos in position_list:

print('sell', close_price_list[-1], close_price_list[-1]-pos, len(position_list), position_list)
profit_record.append((close_price_list[-1]-pos)*1000)

print("每筆報酬結果:",profit_record)

Response Example

sell 204 1.5 5 [202.5, 202.5, 202.5, 202.5, 202.5]
buy 202.5 5 [202.5, 202.5, 202.5, 202.5, 202.5]
sell 205 2.5 5 [202.5, 202.5, 202.5, 202.5, 202.5]
sell 206 3.5 4 [202.5, 202.5, 202.5, 202.5]
sell 206 3.5 3 [202.5, 202.5, 202.5]
buy 204.5 3 [202.5, 202.5, 204.5]
sell 206 3.5 3 [202.5, 202.5, 204.5]
sell 207 4.5 2 [202.5, 204.5]
buy 205.5 2 [204.5, 205.5]
sell 207 2.5 2 [204.5, 205.5]
sell 208 2.5 1 [205.5]
buy 206.5 1 [206.5]
buy 205.5 2 [206.5, 205.5]
sell 207.5 1.0 2 [206.5, 205.5]
sell 208 2.5 1 [205.5]
每筆報酬結果: [1500.0, 2500.0, 3500.0, 3500.0, 3500.0, 4500.0, 2500.0, 2500.0, 1000.0, 2500.0]
acc = np.cumsum(profit_record,axis=0)
print("累計報酬:", acc.tolist())

Response Example

累計報酬: [1500.0, 4000.0, 7500.0, 11000.0, 14500.0, 19000.0, 21500.0, 24000.0, 25000.0, 27500.0]

以 2022-09-30 的元太為例,透過上述的模擬日內網格交易實作,以不考慮交易成本的情況下,報酬為 27500 元,根據結果整理以下重點:

  1. 每筆交易的獲利相對固定,當遇到上漲行情時網格只能夠抓住格內的獲利,超出的部分無法賺取。例如今天若股票漲幅超過 2 %,以設定的網格區間接近 2% 時就即將清空部位了。
  2. 網格交易較適合上下震盪頻繁的標的,若遇到持續上漲或下跌的行情,較難持續參與其中。
  3. 針對波動不劇烈的商品可以透過調整網格大小使得部位的出場及進場能夠比較容易觸發。

因網格只適合用在來回波動的商品上,我們無法準確預估某檔股票今天是否適合使用網格交易,也許可透過一次在多商品上同時使用網格策略來解決,或透過篩選前一日的振幅作為當日執行網格策略的依據以增加成功率。

推薦延伸閱讀:【關鍵報告】震盪市場適用!認識簡單又有高勝率的程式交易策略:網格交易

結語

本週演示了網格策略的交易邏輯及特點,不同於其他交易策略使用技術指標作為進出場訊號,網格策略使用「價格」來觸發並分批買進,這也是一種不錯的分散風險方法。當然,網格交易實作有百百種方法,本文拋出一個容易實作的方法供讀者能夠身歷其境,我們只介紹了網格交易策略的冰山一角,還有許多方法等著讀者去挖掘,快去試試吧!

下週我們也將介紹另一種類似的策略,使用「時間」來觸發進場的「定期定額」策略,請大家敬請期待!