歡迎來到 程式交易實戰 的第一堂課,若還不了解程式交易可以參考 此文章 ! 我們現在就來談談交易策略架構以及如何實作當沖策略吧!
讀完本篇文,您將學會...
- 熟悉交易策略的組成 - 指標、訊號、方法
- 開發出簡單的當沖策略:開盤買 / 收盤賣
- 開發出進階的當沖策略:ORB 策略
交易策略的組成 - 指標、訊號、方法
一個完整的量化交易策略是由「指標」、「訊號」、「方法」所組成,假設我們想要在「股價向上突破 5 日均線時買進」,那指標就是「 5 日均線」,訊號是「向上突破」,方法則是「買進」等買賣操作。如下圖所示:
策略通常是為了達成目標而制定的,再舉個更生活化的例子,若今天想要在門票開賣時搶購演唱會門票;目標是「買到演唱會門票」,所以為了達成這個目的,我們需要制定一個策略來達成,而這個策略按照上面的例子可能會是「一刻不差的在開賣第一時刻要按下購票 CTA 按鈕」。
所以假設張惠妹演唱會在 2022 年 9 月 1 日 00:00 在 KKTIX 開賣,那指摽是「開賣時間:2022 年 9 月 1 日 00:00 」,訊號是「到達開賣時間」,方法就是「按下購票按鈕」。看似很簡單的事件流程,但在量化交易的世界裡,這些都是可以做修改、驗證及分析的,在往後的課程裡我們會更具體的介紹策略開發的流程以及分析方法。
如何實作
廢話不多說,直接進入實作的部分吧!首先會需要先準備環境,若您尚未申請富果交易 API,可參考 事前準備。
若已完成申請,可直接執行以下 code 進行登入
from configparser import ConfigParser
from fugle_trade.sdk import SDK
# 讀取設定檔
config = ConfigParser()
config.read('./config.simulation.ini')
# 登入
sdk = SDK(config)
sdk.login()
開發簡單的當沖策略 - 開盤買/收盤賣
當登入完成後,就可以進行當沖策略開發的部分囉!
首先安裝最新版本的富果行情 API 套件
$ pip install fugle-marketdata -U
接著我們以曾經紅極一時的長榮(2603)這檔股票作為範例,但在開發當沖策略前,您也需要留意該檔股票是否可以當沖哦!我們可以透過 get_trade_status()
來確認是否有當沖權限以及 Fugle 的 Ticker API 來確認該股票的狀態,程式碼如下:
from fugle_marketdata import RestClient
api_key = "YOUR_API_KEY" # 至您的金鑰申請及管理頁取得,連結可參考:https://developer.fugle.tw/docs/key/
client = RestClient(api_key = api_key)
stock = client.stock # Stock REST API client
# 須確認您是否有當沖權限 -> 可參考:https://developer.fugle.tw/docs/trading/reference/python#get_trade_status
user_day_trade_status = sdk.get_trade_status()['day_trade_code']
symbol = "2603"
# 須先確認該股票是否可以先買後賣
symbol_can_day_trade = stock.intraday.ticker(symbol=symbol)['canBuyDayTrade']
若想了解如何開啟現股當沖權限可參考 此說明 !
確認有當沖權限及股票狀態可行後,我們直接實作一個簡單的策略:開盤買進、收盤賣出!
為了盡可能達成目的,我們需要...
- 開盤時買進,要在 08:59:00 以漲停價預掛買進。
- 收盤時賣出,要在 13:25:00 以跌停價賣出。
# 載入交易 API 相關套件
from fugle_trade.order import OrderObject
from fugle_trade.constant import (APCode, Trade, PriceFlag, BSFlag, Action)
import datetime
import time
# 用來記錄部位狀態
position = 0
# 確認是否有當沖權限:X -> 已開啟當沖權限、Y -> 已開啟先買後賣的當沖權限
if user_day_trade_status not in ['X','Y']:
raise Exception("您目前無法進行先買後賣的當沖操作!")
# 須確認該檔股票是否可以當沖
if symbol_can_day_trade == False:
raise Exception("您選擇的股票無法進行先買後賣操作,請換檔股票試試!")
# 首先我們必須要隨時檢查 目前的時間是否是這兩個時間點
while True:
# 時間是9點
if datetime.time(9, 0) > datetime.datetime.now().time() >= datetime.time(8, 59) and position == 0:
order = OrderObject(
buy_sell=Action.Buy,
price_flag=PriceFlag.LimitUp, # 漲停買進
price='',
stock_no=str(symbol),
quantity=1,
ap_code=APCode.Common,
trade=Trade.Cash,
)
sdk.place_order(order)
# 已經買進,避免重複下單
position = position + 1 # position 為 0 指沒有部位、position 為 1 指有部位
# 已經到收盤時間 且 有部位
if datetime.time(13, 26) >= datetime.datetime.now().time() >= datetime.time(13, 25) and position != 0:
order = OrderObject(
buy_sell=Action.Sell,
price_flag=PriceFlag.LimitDown, # 跌停賣出
price='',
stock_no=str(symbol),
quantity=1,
ap_code=APCode.Common,
trade=Trade.DayTradingSell, # 為現股當沖賣出,因此以交易類別來說需要設定為現股當沖賣(DayTradingSell)
)
sdk.place_order(order)
# 已經賣出,部位歸零
position = 0
break
請注意!! 若您使用 Colab 進行實作,因 Colab server 的時間與本機端時間可能不一致,因此您須自行調整開收盤時間!