難道台指期都不會有逆價差了嗎系統 – 3

前言

好久沒更新了啊~~

絕對不是因為最近行情好才又回來寫這個系統,只是在今年(2025 年)4 月初時,因為每天人工確認有無逆價差且又找不到讓人太洩氣,所以就怒轉倉到半年後(逆價差有 250 多點),所以沒有轉倉需求的我就沒在繼續開發了,但該來的還是得來,就把程式寫完吧!

進行期貨程式交易之前

一樣參考他們的文件 服務條款簽署 – Shioaji 去進行 API 下單測試,雖然文件沒寫要簽什麼,但就我的印象好像只要簽 API 期貨下單簽署 就好了,

然後 follow 文件的說明完成測試就好囉,測試完後會在 API 期貨下單簽署 頁下方看到相關資訊。

實做轉倉策略啦!

下一步就是要來繼續實作下圖紅框的部份啦!也就是取得歷史價格、執行轉單策略以及最後的下單。

程式架構

加入紅框後的程式架構長這樣,以下挑一些比較重要的程式來說明。

core/strategy.py – 策略細節

這裡就是存放所有策略的程式,目前共有 3 個策略:

  1. LowerThanMinOfXDaysStrategy 當累積超過 10 天的期貨資料後,判斷當下的價差是否低於歷史價差最小值。
  2. LowerThanMedianOfXDaysStrategy 當累積超過 10 天的期貨資料後,判斷當下的價差是否低於歷史價差中位數。
  3. MustBuyIfSettlementThisWeekStrategy 若當週是近月期貨合約結算週,就 return True,就給它轉倉下去。

lambda_function/future_rollover.py – lambda 程式進入點

future_rollover.py 就是我們的程式進入點,除了取得當下的期貨價格外,也用以下程式來判斷是否要執行轉倉,

    if is_hold_future(api, next_two_month_future_contract): # 是否持有次月期貨
        print("holding the next two month future contract, end the lambda")
        return

    check_days = os.getenv("check_days", 10)
    strategies = [MustBuyIfSettlementThisWeekStrategy(), LowerThanMedianOfXDaysStrategy(dynamodb_client, check_days)] # 預計要執行的策略們
    is_buy = is_buy_by_strategies(strategies, recently_future_contract, next_two_month_future_contract) # 執行策略邏輯判斷是否要轉倉
    print(f"do i rollover future? -> {is_buy}")

    if is_buy:
        if is_hold_future(api, recently_future_contract): # 檢查是否已經持有次月期貨
            trade(api, Action.Sell, recently_future_contract)   # 賣掉近月期貨
            trade(api, Action.Buy, next_two_month_future_contract) # 買入次月期貨
        else:
            print("not holding the recent future contract, end the trade")

function is_buy_by_strategies 判斷的方式是只要任一策略回傳 True,就直接回傳 True,

另外要留意的是這裡的邏輯都是來判斷全有或全沒有,意思是在我的情況下,並不會 同時 持有近月和次月期貨合約,要嘛就是全部都持有近月期貨合約,執行轉倉後就全部持有次月期貨合約。

future/trading.py – 交易程式

主要進行交易的程式,首先會判斷目前是否有委托中的期貨合約,若有,就依照目前的期貨價格改價,若無,就進行對應的交易。

def trade(api, action: Action, contract: Future):
    api.update_status(api.futopt_account)
    all_trades = api.list_trades()

    today = datetime.now().strftime('%Y-%m-%d')
    trades = [trade for trade in all_trades if
              (trade.status.status == Status.Submitted or trade.status.status == Status.PreSubmitted)
              and trade.status.order_datetime.strftime('%Y-%m-%d') == today
              and trade.contract.code == contract.code and trade.order.action == action]

    if trades:
        print(f"found [{len(trades)}] submitted trades need to be update price")
        for trade in trades:
            new_price = contract.reference
            api.update_order(
                trade,
                price=new_price
            )
            original_price = trade.status.modified_price or trade.order.price
            print(f"original price: {original_price}, updated price: {new_price}")
    else:
        print("no submitted trade, place order")

        if (action == Action.Buy and not is_hold_future(api, contract)) or \
                (action == Action.Sell and is_hold_future(api, contract)):
            order = api.Order(
                action=action,  # 買賣別
                price=contract.reference,  # 價格
                quantity=1,  # 數量
                price_type=FuturesPriceType.LMT,  # 委託價格類別
                order_type=OrderType.ROD,  # 委託條件
                octype=FuturesOCType.Auto,  # 倉別
                account=api.futopt_account  # 下單帳號
            )

            trade = api.place_order(contract, order)
            print("place order success")
            print(trade)
        else:
            if action == Action.Buy:
                print(f"you are holding future contract {contract.name}, does not need to buy")
            else:
                print(f"you are not holding future contract {contract.name}, does not need to sell")

執行程式

切換到專案目錄下後,一樣使用以下命令執行程式,

cd alpha-investment
PYTHONPATH=./ python ./lambda_function/future_rollover.py

執行後可看到 2 個策略回覆的結果,第 1 個策略 MustBuyIfSettlementThisWeekStrategy 因為執行的日期是 2025-11-05,非結算週,所以 return False

第 2 個策略 LowerThanMedianOfXDaysStrategy 查出來的歷史價差中位數是 -3,目前是正價差 21,所以也是 return False,最終就是判斷不需要轉倉。

今天這版的程式會放在我的 GitHub – tshine73/alpha-investment at v2 上。

下一步

就是要正式開始轉倉交易啦,我想把轉倉的執行放在 lambda 上做,所以下一篇會在來講講如何部署在 lambda 上!

tshine73
tshine73
文章: 70

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *