昨天我們介紹可以觀察三大法人臺股期貨的動向來瞭解法人對於臺股後市的看法。除了期貨外,選擇權也是另一個可以用來避險的衍生性金融商品,透過觀察法人在臺指選擇權的買賣方向,可以作為一個再確認的指標。
選擇權 (Options)是比期貨更複雜一點的衍生性金融商品,也是一種契約交易。買方支付 權利金 後,有 權利 在約定時間,以特定價格買進或賣出一定數量的約定標的;賣方則在買方執行選擇權時,有 義務 依約履行買進或賣出約定數量的標的。選擇權契約也會連結一個現貨標的,臺灣期貨交易所的「臺指選擇權」商品,交易標的就是「臺灣證券交易所發行量加權股價指數」。
選擇權有兩種權利型態,即「買權(Call Option)」與「賣權(Put Option)」,並可分為四種交易類型:
與期貨一樣,選擇權的交易單位也是「口」,每一口契約都有買方與賣方。根據選擇權履約價格與標的物價格的狀況,可以分為「價內」、「價外」及「價平」:
履約價 > 標的物價格
:買權 為價外;賣權 為價內。履約價 = 標的物價格
:買權 為價平;賣權 為價平。履約價 < 標的物價格
:買權 為價內;賣權 為價外。因為選擇權在不同的履約價格下,所需支付的權利金不同,因此每一口契約價值是不等的,所以我們觀察三大法人在臺指選擇權的未平倉餘額主要是參考 契約金額,而不是契約口數。
由於外資對臺股的影響力不言而喻,因此三大法人在選擇權市場我們仍然主要是觀察外資。選擇權分為 買權 及 賣權,因此需要分開計算它們的 未平倉淨金額:
買權未平倉淨金額 = 買權未平倉買方契約金額 - 買權未平倉賣方契約金額
賣權未平倉淨金額 = 買權未平倉買方契約金額 - 買權未平倉賣方契約金額
在買權方面,當買權未平倉淨金額為正數,代表站在買權買方,表示看大漲;當買權未平倉淨金額為負數,代表站在買權賣方,表示看不太漲。在賣權方面,當賣權未平倉淨金額為正數,代表站在賣權買方,表示看大跌;當賣權未平倉淨金額為負數,代表站在賣權賣方,表示看不太跌。
下圖表示 2022 年初至 8 月 31 日的加權指數與外資臺指選擇權買權未平倉淨金額與賣權未平倉淨金額的關係。我們可以發現,不論是買權未平倉淨金額或賣權未平倉淨金額,幾乎都在 0 軸之上,代表外資在臺指選擇權市場主要是做 買方。
Source:臺灣證券交易所、臺灣期貨交易所
瞭解外資臺指選擇權市場主要是做買方後,我們可以觀察 買權未平倉淨金額 與 賣權未平倉淨金額 的每日變化。如果買權未平倉淨金額增加,代表近期看漲;如果賣權未平倉淨金額增加,代表近期看跌。
我們還可以進一步將 買權未平倉淨金額 與 賣權未平倉淨金額 數字相減,計算出 選擇權未平倉淨金額
選擇權未平倉淨金額 = 買權未平倉淨金額 - 賣權未平倉淨金額
當選擇權未平倉淨金額為正數,表示選擇權部位是 淨買權,代表看漲;選擇權未平倉淨金額為負數,表示選擇權部位是 淨賣權,代表看跌。
Source:臺灣證券交易所、臺灣期貨交易所
如果外資在 臺股期貨 及 臺指選擇權 的佈局方向一致,表示對臺股後市的看法明確;如果佈局方向不一致,代表外資對後市看法沒有明確的方向,可能是採用選擇權避險策略:
因此,我們除了查看外資臺股期貨的佈局,還可以觀察外資臺指選擇權的方向,作為一個再確認的指標。
整理完三大法人臺股期貨交易資訊後,接下來我們也要取得三大法人在臺指選擇權的交易資訊。因選擇權又分為買權(Call Option)與賣權(Put Option),所以我們要取得的是選擇權買賣權分計資訊。
在期交所網站的 交易資訊-三大法人-查詢-選擇權買賣權分計-依日期 頁面,可以按日查詢三大法人在各選擇權契約買賣權分計的交易資訊。
期交所首頁 > 交易資訊 > 三大法人 > 查詢 > 選擇權買賣權分計 > 依日期
在「交易資訊-三大法人-查詢-選擇權買賣權分計-依日期」頁面,選取要查詢的「日期」,「契約」選擇「臺指選擇權」送出查詢後,就會列出該日三大法人在臺指選擇權依買賣權分計的交易資訊。
我們可以找到外資在臺指選擇權依買買權分計的交易口數與契約金額,其中「買權」列「未平倉餘額」的「買賣差額」「契約金額」,就是「買權未平倉淨金額」;「賣權」列「未平倉餘額」的「買賣差額」「契約金額」,就是「賣權未平倉淨金額」。
在期交所網站的 交易資訊-三大法人-下載-選擇權買賣權分計-依日期 頁面,可以按日期下載三大法人在各選擇權契約買賣權分計的交易資訊,期交所以 CSV 檔案格式提供。
期交所首頁 > 交易資訊 > 三大法人 > 下載 > 選擇權買賣權分計 > 依日期
在「交易資訊-三大法人-下載-選擇權買賣權分計-依日期」頁面,選取「日期(起)」、「日期(迄)」的日期範圍,「契約」選擇「臺指選擇權」後,然後點擊下載,就可以取得查詢結果的 CSV 檔案。實際上,這個 HTML Form 表單是使用 POST 方法,向以下位址提交表單請求:
https://www.taifex.com.tw/cht/3/callsAndPutsDateDown
這個表單可設定的欄位如下:
queryStartDate
:日期(起)。接受 yyyy/MM/dd
的日期格式,如 2022/07/01
。queryEndDate
:日期(迄),接受 yyyy/MM/dd
的日期格式,如 2022/07/01
。commodityId
:商品契約代號。臺指選擇權為 TXO
。我們可以打開終端機使用 curl
指令模擬表單請求:
$ curl --request POST \
--url https://www.taifex.com.tw/cht/3/callsAndPutsDateDown \
--header 'Content-Type: multipart/form-data' \
--form queryStartDate=2022/07/01 \
--form queryEndDate=2022/07/01 \
--form commodityId=TXO
瞭解下載 CSV 檔案的方式後,我們就可以實作程式取得資料。
開啟 src/scraper/taifex-scraper.service.ts
檔案,在 TaifexScraperService
實作 fetchInstInvestorsTxoTrades()
方法,取得三大法人臺指選擇權交易資訊:
import * as csvtojson from 'csvtojson';
import * as iconv from 'iconv-lite';
import * as numeral from 'numeral';
import { DateTime } from 'luxon';
import { Injectable } from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import { firstValueFrom } from 'rxjs';
@Injectable()
export class TaifexScraperService {
constructor(private httpService: HttpService) {}
...
async fetchInstInvestorsTxoTrades(date: string) {
// 將 `date` 轉換成 `yyyy/MM/dd` 格式
const queryDate = DateTime.fromISO(date).toFormat('yyyy/MM/dd');
// 建立 FormData
const form = new URLSearchParams({
queryStartDate: queryDate, // 日期(起)
queryEndDate: queryDate, // 日期(迄)
commodityId: 'TXO', // 契約-臺指選擇權
});
const url = 'https://www.taifex.com.tw/cht/3/callsAndPutsDateDown';
// 取得回應資料並將 CSV 轉換成 JSON 格式及正確編碼
const responseData = await firstValueFrom(this.httpService.post(url, form, { responseType: 'arraybuffer' }))
.then(response => csvtojson({ noheader: true, output: 'csv' }).fromString(iconv.decode(response.data, 'big5')));
// 若該日期非交易日或尚無資料則回傳 null
const [ fields, dealersCalls, sitcCalls, finiCalls, dealersPuts, sitcPuts, finiPuts ] = responseData;
if (fields[0] !== '日期') return null;
// 合併三大法人交易數據並將 string 型別數字轉換成 number
const raw = [
...dealersCalls.slice(4),
...sitcCalls.slice(4),
...finiCalls.slice(4),
...dealersPuts.slice(4),
...sitcPuts.slice(4),
...finiPuts.slice(4),
].map(data => numeral(data).value());
const [
dealersCallsLongTradeVolume, // 自營商-買權買方交易口數
dealersCallsLongTradeValue, // 自營商-買權買方交易契約金額(千元)
dealersCallsShortTradeVolume, // 自營商-買權賣方交易口數
dealersCallsShortTradeValue, // 自營商-買權賣方交易契約金額(千元)
dealersCallsNetTradeVolume, // 自營商-買權交易口數買賣淨額
dealersCallsNetTradeValue, // 自營商-買權交易契約金額買賣淨額(千元)
dealersCallsLongOiVolume, // 自營商-買權買方未平倉口數,
dealersCallsLongOiValue, // 自營商-買權買方未平倉契約金額(千元)
dealersCallsShortOiVolume, // 自營商-買權賣方未平倉口數
dealersCallsShortOiValue, // 自營商-買權賣方未平倉契約金額(千元)
dealersCallsNetOiVolume, // 自營商-買權未平倉口數買賣淨額
dealersCallsNetOiValue, // 自營商-買權未平倉契約金額買賣淨額(千元)
sitcCallsLongTradeVolume, // 投信-買權買方交易口數
sitcCallsLongTradeValue, // 投信-買權買方交易契約金額(千元)
sitcCallsShortTradeVolume, // 投信-買權賣方交易口數
sitcCallsShortTradeValue, // 投信-買權賣方交易契約金額(千元)
sitcCallsNetTradeVolume, // 投信-買權交易口數買賣淨額
sitcCallsNetTradeValue, // 投信-買權交易契約金額買賣淨額(千元)
sitcCallsLongOiVolume, // 投信-買權買方未平倉口數,
sitcCallsLongOiValue, // 投信-買權買方未平倉契約金額(千元)
sitcCallsShortOiVolume, // 投信-買權賣方未平倉口數
sitcCallsShortOiValue, // 投信-買權賣方未平倉契約金額(千元)
sitcCallsNetOiVolume, // 投信-買權未平倉口數買賣淨額
sitcCallsNetOiValue, // 投信-買權未平倉契約金額買賣淨額(千元)
finiCallsLongTradeVolume, // 外資-買權買方交易口數
finiCallsLongTradeValue, // 外資-買權買方交易契約金額(千元)
finiCallsShortTradeVolume, // 外資-買權賣方交易口數
finiCallsShortTradeValue, // 外資-買權賣方交易契約金額(千元)
finiCallsNetTradeVolume, // 外資-買權交易口數買賣淨額
finiCallsNetTradeValue, // 外資-買權交易契約金額買賣淨額(千元)
finiCallsLongOiVolume, // 外資-買權買方未平倉口數,
finiCallsLongOiValue, // 外資-買權買方未平倉契約金額(千元)
finiCallsShortOiVolume, // 外資-買權賣方未平倉口數
finiCallsShortOiValue, // 外資-買權賣方未平倉契約金額(千元)
finiCallsNetOiVolume, // 外資-買權未平倉口數買賣淨額
finiCallsNetOiValue, // 外資-買權未平倉契約金額買賣淨額(千元)
dealersPutsLongTradeVolume, // 自營商-賣權買方交易口數
dealersPutsLongTradeValue, // 自營商-賣權買方交易契約金額(千元)
dealersPutsShortTradeVolume, // 自營商-賣權賣方交易口數
dealersPutsShortTradeValue, // 自營商-賣權賣方交易契約金額(千元)
dealersPutsNetTradeVolume, // 自營商-賣權交易口數買賣淨額
dealersPutsNetTradeValue, // 自營商-賣權交易契約金額買賣淨額(千元)
dealersPutsLongOiVolume, // 自營商-賣權買方未平倉口數,
dealersPutsLongOiValue, // 自營商-賣權買方未平倉契約金額(千元)
dealersPutsShortOiVolume, // 自營商-賣權賣方未平倉口數
dealersPutsShortOiValue, // 自營商-賣權賣方未平倉契約金額(千元)
dealersPutsNetOiVolume, // 自營商-賣權未平倉口數買賣淨額
dealersPutsNetOiValue, // 自營商-賣權未平倉契約金額買賣淨額(千元)
sitcPutsLongTradeVolume, // 投信-賣權買方交易口數
sitcPutsLongTradeValue, // 投信-賣權買方交易契約金額(千元)
sitcPutsShortTradeVolume, // 投信-賣權賣方交易口數
sitcPutsShortTradeValue, // 投信-賣權賣方交易契約金額(千元)
sitcPutsNetTradeVolume, // 投信-賣權交易口數買賣淨額
sitcPutsNetTradeValue, // 投信-賣權交易契約金額買賣淨額(千元)
sitcPutsLongOiVolume, // 投信-賣權買方未平倉口數,
sitcPutsLongOiValue, // 投信-賣權買方未平倉契約金額(千元)
sitcPutsShortOiVolume, // 投信-賣權賣方未平倉口數
sitcPutsShortOiValue, // 投信-賣權賣方未平倉契約金額(千元)
sitcPutsNetOiVolume, // 投信-賣權未平倉口數買賣淨額
sitcPutsNetOiValue, // 投信-賣權未平倉契約金額買賣淨額(千元)
finiPutsLongTradeVolume, // 外資-賣權買方交易口數
finiPutsLongTradeValue, // 外資-賣權買方交易契約金額(千元)
finiPutsShortTradeVolume, // 外資-賣權賣方交易口數
finiPutsShortTradeValue, // 外資-賣權賣方交易契約金額(千元)
finiPutsNetTradeVolume, // 外資-賣權交易口數買賣淨額
finiPutsNetTradeValue, // 外資-賣權交易契約金額買賣淨額(千元)
finiPutsLongOiVolume, // 外資-賣權買方未平倉口數,
finiPutsLongOiValue, // 外資-賣權買方未平倉契約金額(千元)
finiPutsShortOiVolume, // 外資-賣權賣方未平倉口數
finiPutsShortOiValue, // 外資-賣權賣方未平倉契約金額(千元)
finiPutsNetOiVolume, // 外資-賣權未平倉口數買賣淨額
finiPutsNetOiValue, // 外資-賣權未平倉契約金額買賣淨額(千元)
] = raw;
return {
date,
finiCallsLongTradeVolume,
finiCallsLongTradeValue,
finiCallsShortTradeVolume,
finiCallsShortTradeValue,
finiCallsNetTradeVolume,
finiCallsNetTradeValue,
finiCallsLongOiVolume,
finiCallsLongOiValue,
finiCallsShortOiVolume,
finiCallsShortOiValue,
finiCallsNetOiVolume,
finiCallsNetOiValue,
finiPutsLongTradeVolume,
finiPutsLongTradeValue,
finiPutsShortTradeVolume,
finiPutsShortTradeValue,
finiPutsNetTradeVolume,
finiPutsNetTradeValue,
finiPutsLongOiVolume,
finiPutsLongOiValue,
finiPutsShortOiVolume,
finiPutsShortOiValue,
finiPutsNetOiVolume,
finiPutsNetOiValue,
sitcCallsLongTradeVolume,
sitcCallsLongTradeValue,
sitcCallsShortTradeVolume,
sitcCallsShortTradeValue,
sitcCallsNetTradeVolume,
sitcCallsNetTradeValue,
sitcCallsLongOiVolume,
sitcCallsLongOiValue,
sitcCallsShortOiVolume,
sitcCallsShortOiValue,
sitcCallsNetOiVolume,
sitcCallsNetOiValue,
sitcPutsLongTradeVolume,
sitcPutsLongTradeValue,
sitcPutsShortTradeVolume,
sitcPutsShortTradeValue,
sitcPutsNetTradeVolume,
sitcPutsNetTradeValue,
sitcPutsLongOiVolume,
sitcPutsLongOiValue,
sitcPutsShortOiVolume,
sitcPutsShortOiValue,
sitcPutsNetOiVolume,
sitcPutsNetOiValue,
dealersCallsLongTradeVolume,
dealersCallsLongTradeValue,
dealersCallsShortTradeVolume,
dealersCallsShortTradeValue,
dealersCallsNetTradeVolume,
dealersCallsNetTradeValue,
dealersCallsLongOiVolume,
dealersCallsLongOiValue,
dealersCallsShortOiVolume,
dealersCallsShortOiValue,
dealersCallsNetOiVolume,
dealersCallsNetOiValue,
dealersPutsLongTradeVolume,
dealersPutsLongTradeValue,
dealersPutsShortTradeVolume,
dealersPutsShortTradeValue,
dealersPutsNetTradeVolume,
dealersPutsNetTradeValue,
dealersPutsLongOiVolume,
dealersPutsLongOiValue,
dealersPutsShortOiVolume,
dealersPutsShortOiValue,
dealersPutsNetOiVolume,
dealersPutsNetOiValue,
};
}
}
在 fetchInstInvestorsTxoTrades()
方法中,需要指定 date
參數,表示要取得三大法人臺指選擇權交易資訊的日期。我們定義回傳的物件欄位包含如下:
date
:日期finiCallsLongTradeVolume
:外資-買權買方交易口數finiCallsLongTradeValue
:外資-買權買方交易契約金額(千元)finiCallsShortTradeVolume
:外資-買權賣方交易口數finiCallsShortTradeValue
:外資-買權賣方交易契約金額(千元)finiCallsNetTradeVolume
:外資-買權交易口數買賣淨額finiCallsNetTradeValue
:外資-買權交易契約金額買賣淨額(千元)finiCallsLongOiVolume
:外資-買權買方未平倉口數,finiCallsLongOiValue
:外資-買權買方未平倉契約金額(千元)finiCallsShortOiVolume
:外資-買權賣方未平倉口數finiCallsShortOiValue
:外資-買權賣方未平倉契約金額(千元)finiCallsNetOiVolume
:外資-買權未平倉口數買賣淨額finiCallsNetOiValue
:外資-買權未平倉契約金額買賣淨額(千元)finiPutsLongTradeVolume
:外資-賣權買方交易口數finiPutsLongTradeValue
:外資-賣權買方交易契約金額(千元)finiPutsShortTradeVolume
:外資-賣權賣方交易口數finiPutsShortTradeValue
:外資-賣權賣方交易契約金額(千元)finiPutsNetTradeVolume
:外資-賣權交易口數買賣淨額finiPutsNetTradeValue
:外資-賣權交易契約金額買賣淨額(千元)finiPutsLongOiVolume
:外資-賣權買方未平倉口數,finiPutsLongOiValue
:外資-賣權買方未平倉契約金額(千元)finiPutsShortOiVolume
:外資-賣權賣方未平倉口數finiPutsShortOiValue
:外資-賣權賣方未平倉契約金額(千元)finiPutsNetOiVolume
:外資-賣權未平倉口數買賣淨額finiPutsNetOiValue
:外資-賣權未平倉契約金額買賣淨額(千元)sitcCallsLongTradeVolume
:投信-買權買方交易口數sitcCallsLongTradeValue
:投信-買權買方交易契約金額(千元)sitcCallsShortTradeVolume
:投信-買權賣方交易口數sitcCallsShortTradeValue
:投信-買權賣方交易契約金額(千元)sitcCallsNetTradeVolume
:投信-買權交易口數買賣淨額sitcCallsNetTradeValue
:投信-買權交易契約金額買賣淨額(千元)sitcCallsLongOiVolume
:投信-買權買方未平倉口數,sitcCallsLongOiValue
:投信-買權買方未平倉契約金額(千元)sitcCallsShortOiVolume
:投信-買權賣方未平倉口數sitcCallsShortOiValue
:投信-買權賣方未平倉契約金額(千元)sitcCallsNetOiVolume
:投信-買權未平倉口數買賣淨額sitcCallsNetOiValue
:投信-買權未平倉契約金額買賣淨額(千元)sitcPutsLongTradeVolume
:投信-賣權買方交易口數sitcPutsLongTradeValue
:投信-賣權買方交易契約金額(千元)sitcPutsShortTradeVolume
:投信-賣權賣方交易口數sitcPutsShortTradeValue
:投信-賣權賣方交易契約金額(千元)sitcPutsNetTradeVolume
:投信-賣權交易口數買賣淨額sitcPutsNetTradeValue
:投信-賣權交易契約金額買賣淨額(千元)sitcPutsLongOiVolume
:投信-賣權買方未平倉口數,sitcPutsLongOiValue
:投信-賣權買方未平倉契約金額(千元)sitcPutsShortOiVolume
:投信-賣權賣方未平倉口數sitcPutsShortOiValue
:投信-賣權賣方未平倉契約金額(千元)sitcPutsNetOiVolume
:投信-賣權未平倉口數買賣淨額sitcPutsNetOiValue
:投信-賣權未平倉契約金額買賣淨額(千元)dealersPutsLongTradeVolume
:自營商-賣權買方交易口數dealersPutsLongTradeValue
:自營商-賣權買方交易契約金額(千元)dealersPutsShortTradeVolume
:自營商-賣權賣方交易口數dealersPutsShortTradeValue
:自營商-賣權賣方交易契約金額(千元)dealersPutsNetTradeVolume
:自營商-賣權交易口數買賣淨額dealersPutsNetTradeValue
:自營商-賣權交易契約金額買賣淨額(千元)dealersPutsLongOiVolume
:自營商-賣權買方未平倉口數,dealersPutsLongOiValue
:自營商-賣權買方未平倉契約金額(千元)dealersPutsShortOiVolume
:自營商-賣權賣方未平倉口數dealersPutsShortOiValue
:自營商-賣權賣方未平倉契約金額(千元)dealersPutsNetOiVolume
:自營商-賣權未平倉口數買賣淨額dealersPutsNetOiValue
:自營商-賣權未平倉契約金額買賣淨額(千元)dealersCallsLongTradeVolume
:自營商-買權買方交易口數dealersCallsLongTradeValue
:自營商-買權買方交易契約金額(千元)dealersCallsShortTradeVolume
:自營商-買權賣方交易口數dealersCallsShortTradeValue
:自營商-買權賣方交易契約金額(千元)dealersCallsNetTradeVolume
:自營商-買權交易口數買賣淨額dealersCallsNetTradeValue
:自營商-買權交易契約金額買賣淨額(千元)dealersCallsLongOiVolume
:自營商-買權買方未平倉口數,dealersCallsLongOiValue
:自營商-買權買方未平倉契約金額(千元)dealersCallsShortOiVolume
:自營商-買權賣方未平倉口數dealersCallsShortOiValue
:自營商-買權賣方未平倉契約金額(千元)dealersCallsNetOiVolume
:自營商-買權未平倉口數買賣淨額dealersCallsNetOiValue
:自營商-買權未平倉契約金額買賣淨額(千元)完成後,我們只要呼叫 TaifexScraperService
的 fetchInstInvestorsTxoTrades()
方法,就可以按日期取得三大法人臺指選擇權交易資訊。以日期 2022-07-01
為例:
{
date: '2022-07-01',
finiCallsLongTradeVolume: 88424,
finiCallsLongTradeValue: 414471,
finiCallsShortTradeVolume: 87750,
finiCallsShortTradeValue: 426385,
finiCallsNetTradeVolume: 674,
finiCallsNetTradeValue: -11914,
finiCallsLongOiVolume: 37835,
finiCallsLongOiValue: 65911,
finiCallsShortOiVolume: 21865,
finiCallsShortOiValue: 46644,
finiCallsNetOiVolume: 15970,
finiCallsNetOiValue: 19267,
finiPutsLongTradeVolume: 94000,
finiPutsLongTradeValue: 723218,
finiPutsShortTradeVolume: 94334,
finiPutsShortTradeValue: 734812,
finiPutsNetTradeVolume: -334,
finiPutsNetTradeValue: -11594,
finiPutsLongOiVolume: 38428,
finiPutsLongOiValue: 1834939,
finiPutsShortOiVolume: 14742,
finiPutsShortOiValue: 814502,
finiPutsNetOiVolume: 23686,
finiPutsNetOiValue: 1020437,
sitcCallsLongTradeVolume: 0,
sitcCallsLongTradeValue: 0,
sitcCallsShortTradeVolume: 0,
sitcCallsShortTradeValue: 0,
sitcCallsNetTradeVolume: 0,
sitcCallsNetTradeValue: 0,
sitcCallsLongOiVolume: 0,
sitcCallsLongOiValue: 0,
sitcCallsShortOiVolume: 0,
sitcCallsShortOiValue: 0,
sitcCallsNetOiVolume: 0,
sitcCallsNetOiValue: 0,
sitcPutsLongTradeVolume: 0,
sitcPutsLongTradeValue: 0,
sitcPutsShortTradeVolume: 0,
sitcPutsShortTradeValue: 0,
sitcPutsNetTradeVolume: 0,
sitcPutsNetTradeValue: 0,
sitcPutsLongOiVolume: 900,
sitcPutsLongOiValue: 22998,
sitcPutsShortOiVolume: 95,
sitcPutsShortOiValue: 8693,
sitcPutsNetOiVolume: 805,
sitcPutsNetOiValue: 14305,
dealersCallsLongTradeVolume: 147072,
dealersCallsLongTradeValue: 469839,
dealersCallsShortTradeVolume: 158102,
dealersCallsShortTradeValue: 486358,
dealersCallsNetTradeVolume: -11030,
dealersCallsNetTradeValue: -16520,
dealersCallsLongOiVolume: 66103,
dealersCallsLongOiValue: 117928,
dealersCallsShortOiVolume: 104279,
dealersCallsShortOiValue: 121884,
dealersCallsNetOiVolume: -38176,
dealersCallsNetOiValue: -3956,
dealersPutsLongTradeVolume: 117056,
dealersPutsLongTradeValue: 858705,
dealersPutsShortTradeVolume: 117513,
dealersPutsShortTradeValue: 1053093,
dealersPutsNetTradeVolume: -457,
dealersPutsNetTradeValue: -194388,
dealersPutsLongOiVolume: 49566,
dealersPutsLongOiValue: 1262483,
dealersPutsShortOiVolume: 34314,
dealersPutsShortOiValue: 1428216,
dealersPutsNetOiVolume: 15252,
dealersPutsNetOiValue: -165733
}
在期交所每日會公布最新的「臺指選擇權 Put/Call 比」(Put/Call Ratio),臺指選擇權 Put/Call Ratio,可以看作是衡量市場多空氣氛氣氛的指標。因為看多的人傾向交易買權,看空的人傾向交易賣權。但市場的氣氛不代表行情的實際走勢,因為行情總在悲觀時上漲,在樂觀時下跌。正如上個世紀著名的逆向投資者、鄧普頓集團的創始人約翰‧鄧普頓(John Templeton)所說:「行情總在絕望中誕生,在半信半疑中成長,在憧憬中成熟,在希望中毀滅。」
所以,當 Put/Call Ratio 數字往上,代表投資人操作方向偏空,大盤卻可能上漲;當 Put/Call Ratio 數字往下,代表投資人操作方向偏多,大盤卻可能下跌。Put/Call Ratio 以 100% 為分界,Put/Call Ratio 高於 100% 偏多,低於 100 % 偏空。
Source:臺灣證券交易所、臺灣期貨交易所
在期交所網站的 交易資訊-交易資訊-選擇權-臺指選擇權Put/Call比 頁面,可以按日查詢臺指選擇權 Put/Call Ratio。
期交所首頁 > 交易資訊 > 交易資訊 > 選擇權 > 臺指選擇權Put/Call比
在「交易資訊-交易資訊-選擇權-臺指選擇權Put/Call比」頁面,選取「日期(起)」、「日期(迄)」的日期範圍後按下「查詢」,就會列出該日期區間的臺指選擇權 Put/Call Ratio。
找到「買賣權未平倉量比率%」的數字,就是我們要查詢的「臺指選擇權 Put/Call Ratio」。
點擊「下載」,HTML Form 表單就會使用 POST 方法,向以下位址提交表單請求:
https://www.taifex.com.tw/cht/3/pcRatioDown
這個表單可設定的欄位如下:
queryStartDate
:日期(起)。接受 yyyy/MM/dd
的日期格式,如 2022/07/01
。queryEndDate
:日期(迄),接受 yyyy/MM/dd
的日期格式,如 2022/07/01
。我們可以打開終端機使用 curl
指令模擬表單請求:
$ curl --request POST \
--url https://www.taifex.com.tw/cht/3/pcRatioDown \
--header 'Content-Type: multipart/form-data' \
--form queryStartDate=2022/07/01 \
--form queryEndDate=2022/07/01
瞭解下載 CSV 檔案的方式後,我們就可以實作程式取得資料。
開啟 src/scraper/taifex-scraper.service.ts
檔案,在 TaifexScraperService
實作 fetchTxoPutCallRatio()
方法,取得臺指選擇權 Put/Call Ratio:
import * as csvtojson from 'csvtojson';
import * as iconv from 'iconv-lite';
import * as numeral from 'numeral';
import { DateTime } from 'luxon';
import { Injectable } from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import { firstValueFrom } from 'rxjs';
@Injectable()
export class TaifexScraperService {
constructor(private httpService: HttpService) {}
...
async fetchTxoPutCallRatio(date: string) {
// 將 `date` 轉換成 `yyyy/MM/dd` 格式
const queryDate = DateTime.fromISO(date).toFormat('yyyy/MM/dd');
// 建立 FormData
const form = new URLSearchParams({
queryStartDate: queryDate, // 日期(起)
queryEndDate: queryDate, // 日期(迄)
});
const url = 'https://www.taifex.com.tw/cht/3/pcRatioDown';
// 取得回應資料並將 CSV 轉換成 JSON 格式及正確編碼
const responseData = await firstValueFrom(this.httpService.post(url, form, { responseType: 'arraybuffer' }))
.then(response => csvtojson({ noheader: true, output: 'csv' }).fromString(iconv.decode(response.data, 'big5')));
// 若該日期非交易日或尚無資料則回傳 null
const [ fields, row ] = responseData;
if (!row) return null;
// 將 string 型別數字轉換成 number
const raw = row.slice(1).map(data => numeral(data).value());
const [
txoPutVolume, // 賣權成交量
txoCallVolume, // 買權成交量
txoPutCallVolumeRatioPercent, // 買賣權成交量比率%
txoPutOi, // 賣權未平倉量
txoCallOi, // 買權未平倉量
txoPutCallRatioPercent, // 買賣權未平倉量比率%
] = raw;
// 轉換為比率
const txoPutCallVolumeRatio = numeral(txoPutCallVolumeRatioPercent).divide(100).value();
const txoPutCallRatio = numeral(txoPutCallRatioPercent).divide(100).value();
return {
date,
txoPutVolume,
txoCallVolume,
txoPutCallVolumeRatio,
txoPutOi,
txoCallOi,
txoPutCallRatio,
};
}
}
在 fetchTxoPutCallRatio()
方法中,需要指定 date
參數,表示要取得臺指選擇權 Put/Call Ratio 的日期。我們定義回傳的物件欄位包含如下:
date
:日期txoPutVolume
:賣權成交量txoCallVolume
:買權成交量txoPutCallVolumeRatio
:買賣權成交量比率txoPutOi
:賣權未平倉量txoCallOi
:買權未平倉量txoPutCallRatio
:買賣權未平倉量比率完成後,我們只要呼叫 TaifexScraperService
的 fetchTxoPutCallRatio()
方法,就可以按日期取得臺指選擇權 Put/Call Ratio。以日期 2022-07-01
為例:
{
date: '2022-07-01',
txoPutVolume: 401513,
txoCallVolume: 508036,
txoPutCallVolumeRatio: 0.7903,
txoPutOi: 166126,
txoCallOi: 302167,
txoPutCallRatio: 0.5498
}
本系列文已正式出版為《Node.js 量化投資全攻略:從資料收集到自動化交易系統建構實戰》。本書新增了全新內容和實用範例,為你提供更深入的學習體驗!歡迎參考選購,開始你的量化投資之旅!
天瓏網路書店連結:https://www.tenlong.com.tw/products/9786263336070