avatarAI StockBoy

总结

本网页主要介绍了如何使用Python编程串联网络券商Interactive Brokers(IB)进行全自动化的美股交易,包括下单、查询账务信息以及修改和取消委托单等功能。

摘要

网页标题为《Python 串接网路券商 IB 进行全自动美股程序交易》,文章首先介绍了作者被朋友称为“最懒惰的投资人”背后的原因,即通过AI和量化交易策略自动化地完成股票投资决策,以及通过程序自动执行交易的过程。作者强调,虽然这种投资方式看似懒惰,但实际上背后付出了大量的时间和精力去学习和编写代码。

文章接着详细说明了进行自动化交易所需的前置作业,包括下载并安装IB的Trader Workstation(TWS)软件、开辦IB的虚拟户头、完成TWS的API设置、安装ib-insync模块以及通过Python连接TWS。

在此基础上,文章进一步指导如何通过Python了解IB户头中的账务信息,包括现金、持有资产的账面价值和净清算价值等。然后详细演示了如何编写程序来提交市价单和限价单,以及如何查询交易执行情况、修改和取消委托单。

最后,文章讲解了如何更新和掌握自己投资组合的账面状况,并提醒读者在熟悉基础操作后,可以结合自己的投资策略,开发出完整的自动化交易系统。

观点

  • 自动化交易可以大幅提高投资效率:通过Python串联IB券商,可以实现股票交易的自动化,包括资金管理、投资决策和交易执行等环节。
  • 前置作业是自动化交易的基础:包括安装TWS软件、设置API、安装ib-insync模块等,这些是进行自动化交易的必要准备。
  • 精确控制交易流程:通过编程方式,投资者可以精确地控制交易流程,包括下单、查询账务、修改和取消委托等操作。
  • 自动化交易需要深厚的技术基础和不断的学习:虽然自动化交易带来了投资生活的便利,但要达到这一点,需要投资者具备编程、AI、量化交易等多方面的知识和技能,并且需要不断学习和更新知识。
  • 自动化交易系统的开发是一个持续的过程:文章鼓励读者在掌握基础后,继续深入学习TWS API和ib-insync模块,不断优化和完善自己的交易系统。

Python 串接網路券商 IB 進行全自動美股程式交易

Python + A.I. 股市應用系列;串接券商更新帳務數據、下美股買賣委託單;Interactive Brokers 盈透證券

股仔與新創夥伴合作打造的美股資訊站 — FinGuider,歡迎前往體驗!

小小前言

最近被朋友笑稱是:

『最懶惰的投資人,沒有之一』

因為像是「要買賣哪些股票?」「什麼時候買賣?」「資金管理」這類的問題,我是透過 AI 以及量化交易策略去自動分析。

「交易執行」的部份,我是透過程式串接網路券商去自動完成。

所以在整個美股投資的過程,就只有在入金的時候才需要親自出馬,特地跑一趟銀行去寫麻煩的電匯單,入金之後就沒我的事了!

就結果而言,朋友們的形容確實沒有半點毛病。但他們沒想到的是,要得到這樣「輕鬆」的投資生活之前,必須先付出難以衡量的成本與代價!購買高品質的數據資料;投入大量時間鑽研投資學、美股、AI、程式等等的知識;再花更多的時間與力氣編寫一段又一段的 code,經過無數次的除錯與優化,最終才形成一套完整的投資系統。

熬過了前面那一大段辛苦的付出,後面確實得到了更效率(更懶惰)的生活!一勞永逸,大概就是自己「學程式」的最大動力!

廢話講完,本文要分享什麼?

“幫助大家成為另一個輕鬆愜意的投資人”

如果我們把股市投資的過程簡單地拆成三個環節:

1. 資訊更新 ↙ 2. 投資決策 ↙ 3. 執行交易 ↖ back to 1. 資訊更新

那麼過去寫過的兩篇文章,分別介紹了如何寫程式去自動完成『1. 資訊更新』&『2. 投資決策』的相關內容:

  1. 如何善用資源,打造出自己需要的股市資料庫傳送門);
  2. 如何做出一個能夠預測股價走勢的 AI傳送門)。

剩下的『3. 執行交易』,希望透過本文內容,幫助大家掌握如何透過 Python 串接網路券商 IB 進行美股全自動程式交易

本文架構

  1. 前置作業 a) 下載 IB 的 Trader Workstation(簡稱 TWS) b) 開辦 IB 虛擬戶頭 c) 完成 TWS 的設定 d) 安裝 ib-insync 模組 e) 透過 Python 連線 TWS
  2. 透過 Python 了解 IB 戶頭裡的帳務資訊
  3. 將投資決策,透過 Python 送出委託單至 IB 進行下單
  4. 確認交易執行的狀況,對委託單進行修改
  5. 更新自己投資組合的帳面狀況

學會以上的內容,理論上足以開發自己的自動化程式交易。其他細節,例如:

Q. 為什麼選 IB — Interactive Brokers 盈透證券
Q. 如何開 IB 真實戶以及如何電匯入金
Q. 投資策略怎麼寫?怎麼回測?
Q. 一整套的自動化要怎麼在 Windows 上排程運作

其實都是一些不錯的主題,但與本文主軸無關,再另找時間分享吧!

1. 前置作業

a) 下載 IB 的 Trader Workstation(簡稱 TWS)

☀ 前往 IB 的首頁

☀ 在 IB 首頁 Log In 的地方選擇 “Download Trader Workstation”

IB — Interactive Brokers 官方網站

☀ 選擇最新版即可。下載安裝後,執行 TWS

IB TWS 下載頁面

b) 開辦 IB 虛擬戶頭

☀ 沒有開 IB 的真實帳戶也沒關係,執行 TWS 後會彈出一個登入視窗。點擊下方 “Try the demo”,就可以馬上無痛開辦一個虛擬 demo 帳戶

IB TWS 登入視窗,右上還可以切換語言喔!

☀ 透過一個 email 無痛開通 demo 帳戶後,就可以啟動 TWS 囉!

IB TWS 介面

☀ TWS 初始介面的版塊:

TWS 各版塊做的事

c) 完成 TWS 的設定

☀ 點擊 TWS 左上 File 選單中的 “Global Configuration”

先去 Global Configuration 完成設定

☀ 在左選單中點選 “API” → “Settings”,並照著下圖完成設定,Socket port 以及 Master API client ID 內的參數可以修改

TWS API 的設定

d) 安裝 ib-insync 模組

☀ 安裝 ib-insync 模組,這是一個完善的第三方 API,直接幫大家省下極大量的 coding 工作

pip install ib-insync
* 如果是 python 3.6 以下的版本,需要再安裝 dataclasses,新版的 python 都不需要裝,已內含了!
pip install dataclasses

e) 透過 Python 連線 TWS

☀ TWS 必須「保持開啟」著的狀態,我們現在來試試連線吧!

# 匯入模組
from ib_insync import *
util.startLoop() # 開啟 Socket 線程
ib = IB()
ib.connect('127.0.0.1', 7497, clientId=123)

☀ 在 Console 看到下圖的回傳文字,就表示連線成功囉!

連線成功!

2. 透過 Python 了解 IB 戶頭裡的帳務資訊

☀ 從 TWS 右上的 MONITOR 區塊,切換至 “Portfolio” 分頁後,點擊 “ACCOUNT” 打開這個 demo 帳號的戶頭帳務狀況

在 TWS 上查看帳務資訊

☀ 從 TWS 右上的 MONITOR 區塊,切換至 “Portfolio” 分頁後,點擊 “ACCOUNT” 打開這個 demo 帳號的戶頭帳務狀況

Demo 的帳務狀況,如果是真實帳戶該有多好 xD ~

☀ 打開 “ACCOUNT” 後,右邊的每一個「+」號都可以展開該分類底下的詳細項目!這裡先介紹其中重要的 3 個項目:

  • Cash = 現金,此帳戶有 1,037,875 USD
  • Securities Gross Position Value = 持有中的資產的帳面價值,此 demo 是新開的還沒進行交易,目前自然就是 0 USD (註:如果有開期權戶,此項目還包含了期權的價值喔)
  • Net Liquidation Value = 就是前兩項的加總,帳戶清算的總價值

☀ 接下來我們就來嘗試透過 Python 下指令取得這 3 個數字吧!

import pandas as pd
# 先取得帳戶總覽,'DU228378'是我的 demo 帳號代碼,記得要改成你的 demo 帳號代碼,在 TWS 的右上方尋找
account_summary = ib.accountSummary(account='DU228378')
# 再透過 pandas 轉換為 DataFrame
account_summary_df = pd.DataFrame(account_summary).set_index('tag')
♠ 取得 Cash 現金的數字
account_summary_df.loc['AvailableFunds']
♠ 取得 Securities Gross Position Value 持有中資產的帳面價值
account_summary_df.loc['GrossPositionValue']
♠ 取得 Net Liquidation Value 帳戶清算的總價值
account_summary_df.loc['NetLiquidation']

☀ 如此就能輕鬆地掌握帳戶目前的狀況。不管是哪種交易策略,都一定會需要取得這些數字,來進行交易決策的判斷喔!

3. 將投資決策,透過 Python 送出委託單至 IB 進行下單交易

要成功送出委託單,我們要先定義﹝contract 合約﹞以及﹝order 委託單﹞這兩項變數。這裡透過幾個例子進行示範:

♦ 例1:「用市價買進 50 股 TSLA」 ♦ 例2:「用限價 370 買進 100 股 QQQ」

♦ 例1:「用市價買進 50 股 TSLA」
# 定義 contract 合約
contract = Contract(
    secType='STK',      # 買進的是「股票」,就鍵入「STK」
    symbol='TSLA',      # 鍵入股票代碼
    exchange='SMART',   # SMART 指的是 TWS 的智能路由,
                        # 它會根據以下條件找出最佳的交易所
                        # 1.交易所成本最小化
                        # 2.執行機率最大化
    currency='USD'      # 鍵入貨幣單位
)
# 定義 order 委託單
order = Order(
    action='BUY',       # 買進的話就是「BUY」,賣出/放空則是「SELL」
    totalQuantity=50,   # 這裡要鍵入的是「股」數喔!
    orderType='MKT'     # 例1下的是「市價單」,參數就是「MKT」
)
# 向 TWS 發送委託單!
ib.placeOrder(contract, order)

☀ 不到一秒,委託單就送出啦!Windows 右下角會彈出提示通知,這時回到 TWS,就能發現左下角的 ACTIVITY 區塊中,“Orders” 分頁內出現了我們剛剛設定的委託單

例1 的市價 TSLA 委託單成立!
♦ 例2:「用限價 360 買進 100 股 QQQ」
# 定義 contract 合約
contract = Contract(
    secType='STK',      # 買進「ETF」的話也是鍵入「STK」
    symbol='QQQ',       # 鍵入 ETF 代碼
    exchange='SMART',
    currency='USD'
)
# 定義 order 委託單
order = Order(
    action='BUY',
    totalQuantity=100,  # 這裡要鍵入的是「股」數喔!
    orderType='LMT',    # 例2下的是「限價單」,參數就是「LMT」
    lmtPrice=370,       # ★ 限價單會多一個參數,設定「掛單價格」★
)
# 向 TWS 發送委託單!
ib.placeOrder(contract, order)
例2 的限價 QQQ 委託單成立!

4. 確認交易執行的狀況,對委託單進行修改

☀ 先觀察一下 TWS。如果不是流動性太差的標的,基本上「市價單」執行成功的機會很高,我們就可以從右上 MONITOR 區塊的 “Portfolio” 中,看到帳面持股了!

剛剛的 TSLA 市價單幾乎馬上成交

☀ 而左下 ACTIVITY 區塊的 “Orders” 中,可以明顯看出兩筆委託單成交與否的差別。

只有未執行完畢的才會亮著

☀ 切至 “Trades” 分頁,可以得到更詳細的成交資訊

包含了成交價、手續費等詳細的成交資訊

看完了 TWS,接下來我們試試透過 Python API 來完成以下幾件事:

♦ 例3: 確認成交狀況 ♦ 例4: 掌握交易委託的資訊 ♦ 例5:「修改」一筆委託單 ♦ 例6:「取消」一筆委託單

♦ 例3: 確認成交狀況
# 透過這個函數,可以確認交易執行的情況
ib.executions()
備註:如果所有委託單都沒有成交,就會回傳一個空的 list
50 股 TSLA 成交均價 1062.98,清楚確認成交資訊
♦ 例4: 掌握交易委託的資訊
# 透過這個函數,可以取得未執行完畢的交易委託
open_trades = ib.openTrades()
檢視了一下 open_trades 會發現資訊量過多,各位針對自己所需去取值即可。這裡簡單做個示範,整理出一個記載重點資訊的 DataFrame
# 寫函數,從 open_trades 中的每一筆物件取值
def open_trade_info(trade_object):
    return {
        'orderId': trade_object.order.orderId,
        'action': trade_object.order.action,
        'totalQuantity': trade_object.order.totalQuantity,
        'orderType': trade_object.order.orderType,
        'lmtPrice': trade_object.order.lmtPrice,
        'secType': trade_object.contract.secType,
        'symbol': trade_object.contract.symbol
    }
# 整理成 DataFrame
open_trades_df = pd.DataFrame(list(map(lambda x: open_trade_info(x), open_trades)))
我們有一筆未執行委託,orderId 是 4,是這筆委託的專屬代號,等一下會用到
♦ 例5:「修改」一筆委託單
假設要修改剩下來的那筆委託單:
→ QQQ 買 80 股就好,不買 100 股了
→ 限價股價也從 370 改成 375 好了
以上要怎麼修改呢?
# 首先我們需要辨識出要修的這筆委託單的專屬代號
loc_index = open_trades_df.index[open_trades_df.symbol == 'QQQ'][0]
modify_id = open_trades_df.loc[loc_index, 'orderId']
# 跟前面一樣定義 contract 以及 order,但這次 order 裡要增加 orderId 這參數
contract = Contract(
    secType='STK',
    symbol='QQQ',
    exchange='SMART',
    currency='USD'
)
order = Order(
    orderId=modify_id,  # ★ 鍵入剛剛找到的專屬代號 ★
    action='BUY',
    totalQuantity=80,   # 從 100 股修改成 80 股
    orderType='LMT',
    lmtPrice=375,       # 從限價 370 修改成 375
)
# 向 TWS 發送,就能對正在掛著的委託單進行修改了!
ib.placeOrder(contract, order)
回到 TWS 查看,發現該筆委託單直接就修改好囉!
♦ 例6:「取消」一筆委託單
假設要把一筆委託單取消掉,該怎麼做呢?
# 記得要定期更新 open_trades_df(見例4)
# 一樣要先辨識出該筆委託單的專屬代號
cancel_id = open_trades_df
# 定義 order 委託單,這次只要指出要取消委託單的專屬代號即可
order = Order(
    orderId=cancel_id   # ★ 鍵入該筆委託單的專屬代號 ★
)
# 向 TWS 發送 cancelOrder,取消掉正在掛著的委託單!
ib.cancelOrder(order)
委託單成功取消!

5. 更新自己投資組合的帳面狀況

大家可以先多練習下一些交易委託,讓投組豐富起來,再進行下一步驟喔!

另外購入了一些股票

☀ 投資組合豐富起來後,我們現在就來試試看透過 Python 獲取投資組合的資訊吧!

♦ 例7: 更新取得投資組合的資訊
# 透過這個函數,可以輕鬆取得投資組合的資訊
portfolio_data = ib.portfolio()
跟例4 非常相似,我們針對自己需求,將 portfolio_data 的資訊整理成 DataFrame
# 寫函數,從 portfolio_data 中的每一筆物件取值
def portfolio_info(asset_object):
    return {
        'symbol': asset_object.contract.symbol,
        'primaryExchange': asset_object.contract.primaryExchange,
        'currency': asset_object.contract.currency,
        'position': asset_object.position,
        'marketPrice': asset_object.marketPrice,
        'marketValue': asset_object.marketValue,
        'averageCost': asset_object.averageCost,
        'unrealizedPNL': asset_object.unrealizedPNL,
        'realizedPNL': asset_object.realizedPNL
    }
# 整理成 DataFrame
portfolio_data_df = pd.DataFrame(list(map(lambda x: portfolio_info(x), portfolio_data)))
這樣就能掌握自己投資組合的狀況了!

本文 END

以上的內容,是程式交易當中幾個關鍵的基礎環節,希望可以有效幫助大家無痛進入程式交易的領域。

熟悉基本後,可以進一步閱讀 TWS API 的設計規則,以及 ib-insync 模組的參數內容。

最後就可以結合自己的投資策略邏輯,開發出完善的自動化程式交易系統,享受更愜意的投資生活囉!

感謝各位看完這篇教學文!希望內容對你有幫助!☀
如果覺得文章還不錯,希望可以幫我一個小忙,
那就是按下『拍拍手』以及『分享』出去啦~
感謝各位!♥
Python
Stock Market
API
美股
程式交易
Recommended from ReadMedium