Thanks to visit codestin.com
Credit goes to Github.com

Skip to content
/ templar Public

臺灣證券交易所 (TWSE) TMP 傳輸協定訊息轉換工具

License

Notifications You must be signed in to change notification settings

LsYueh/templar

Repository files navigation

TeMPlar

TMP是臺灣證券交易所(TWSE)所使用的專屬傳輸協定,全名為Transaction Message Protocol,用於證券交易相關的訊息傳輸。此工具用於解析TMP提供的委託/成交/申報/檔案傳輸服務訊息內容,將序列化的字串資料轉為非序列化的資料物件後再加以利用。非序列化的資料亦可使用此工具轉換成COBOL可處理的序列化字串資料以用於系統間的資料交換。


流程圖 流程圖


使用方式

const templar = require('templar');

檔案傳輸

const message = templar.parse('20020508595900000084500003M01', { category: 'file-transfer' }

console.log(message);

// Message_t {
//   body: [ { FileCode: 'M01', ResponseMessage: '' } ],
//   raw: Uint8Array('20000008595900845000000011T3000000100'),
//   header: {
//     SubsystemName: '20',
//     FunctionCode: '02',
//     MessageType: '05',
//     MessageTime: 2025-08-17T00:59:59.000Z,
//     StatusCode: '00',
//     SourceId: '0000',
//     ObjectId: '8450',
//     BodyLength: 3
//   },
//   id: 'F060',
//   remained: Uint8Array('')
// }
const message = {
  id: 'F050',
  header: {
    SubsystemName: '20',
    FunctionCode: '02',
    MessageType: '05',
    MessageTime: new Date('2025-08-15T00:59:59.000Z'),
    StatusCode: '00',
    SourceId: '8450',
    ObjectId: '0000',
    // BodyLength: 3, // 會自動根據body變化
  },
  body: [ { FileCode: 'M01', RequestMessage: '' } ],
};

console.log(templar.stringify(message, { category: 'file-transfer' });

// 20020508595900845000000003M01

成交回報

const message = templar.parse('500000085959008450000001', { category: 'report' });

console.log(message);

// Message_t {
//   body: [ { BrokerId: '8450', StartSeq: 1 } ],
//   raw: Uint8Array('500000085959008450000001'),
//   header: {
//     SubsystemName: '50',
//     FunctionCode: '00',
//     MessageType: '00',
//     MessageTime: 2025-08-15T00:59:59.000Z,
//     StatusCode: '00'
//   },
//   id: 'R1',
//   remained: Uint8Array('')
// }
const message = {
  id: 'R1',
  header: {
    SubsystemName: '50',
    FunctionCode: '00',
    MessageType: '00',
    MessageTime: new Date('2025-08-15T00:59:59.000Z'),
    StatusCode: '00'
  },
  body: [ { BrokerId: '8450', StartSeq: 1 } ],
};

console.log(templar.stringify(message, { category: 'report' }));

// '500000085959008450000001'



訊息處理

中文字

交易所的TMP訊息採ASCII編碼,而中文字常用CP950的編碼方式傳入,故在字串切割上一個中文字實算兩個字元空間。

const { parse } = require('./lib/field/parse.js');

test('Parse CP950', async (t) => {
    const buffer = iconv.encode('中文字', 'cp950')
    t.equal(parse({ picStr: 'X(4)', dataType: DATA_TYPE.String, buffer }), '中文');
    t.equal(parse({ picStr: 'X(5)', dataType: DATA_TYPE.String, buffer }), '中文�');
    t.equal(parse({ picStr: 'X(6)', dataType: DATA_TYPE.String, buffer }), '中文字');
});

數字

復刻COBOL文字與數字不同的對齊方式 (文字靠左,數字靠右)。

const { parse } = require('./lib/field/parse.js');

test('Parse PIC 9', async (t) => {
    t.equal(parse({ picStr: '9(5)', dataType: DATA_TYPE.Unsigned, buffer: Buffer.from('12345') }), 12345);
    t.equal(parse({ picStr: '9(5)', dataType: DATA_TYPE.Unsigned, buffer: Buffer.from('123456') }), 23456);
});



COBOL PICTURE (PIC) 子句

目前支援的解析格式

基本:

  • PIC X
  • PIC X(4)
  • PIC 9999
  • PIC 9(4)

混合:

  • PIC 99V99
  • PIC 9(3)V9(2)
  • PIC 9(3)V99
  • PIC S99V99
  • PIC S9(3)V9(2)
  • PIC S9(3)V99



資料型態對照表

字串

COBOL PIC 說明 Node 對應
PIC X(n) 任意字元,長度 n String
PIC A(n) 只允許字母 String
PIC AN(n) 字母 + 數字 String
PIC G(n) 雙位元組字元 (DBCS, EBCDIC) String

整數/小數

COBOL PIC 說明 Node 對應
PIC 9(n) 無號小數,整數 n 位 Number
PIC S9(n) 有號小數,整數 n 位 Number
PIC 9(n)V9(m) 無號小數,整數 n 位,小數 m 位 Number
PIC S9(n)V9(m) 有號小數,整數 n 位,小數 m 位 Number

時間/日期

COBOL PIC 用途 Node 對應
PIC X(8) (YYYYMMDD) 日期 Date
PIC X(6) (HHmmss) 時間 Date
PIC X(9) (HHmmssSSS) 時間 Date
PIC X(14) (YYYYMMDDHHmmss) 時間戳記 Date

JS時間格式表示

在交易所提供的文件中,X(8)對應YYYYMMDDDATE型別,而X(6)X(9)分別對應HHmmss/HHmmssSSSTIME型別。目前Node 22尚未支援Temporal.PlainTimeTemporal.PlainDate,故對於上述資料型態的轉換會統一轉換至JS的Date型別,其中X(6)X(9)會自動補上當下執行的日期。



正負號數字S9字串轉換

Signed overpunch源自Hollerith(赫爾曼·何樂禮)打孔卡編碼,為解決正負號帶來的字元浪費與孔位長度變動的問題,將數字正負號整併至一個孔位解讀。目前已知COBOL的對應關係有:

數 字 ca,
cb,
cm,
cr
Positive
ci,
cn
Positive
ca,
ci,
cn
Negative
cb
Negative
cm
Negative
cr
Negative
0 '0' '{' '}' '@' 'p' ' ' (space)
1 '1' 'A' 'J' 'A' 'q' '!'
2 '2' 'B' 'K' 'B' 'r' '"' (double-quote)
3 '3' 'C' 'L' 'C' 's' '#'
4 '4' 'D' 'M' 'D' 't' '$'
5 '5' 'E' 'N' 'E' 'u' '%'
6 '6' 'F' 'O' 'F' 'v' '&'
7 '7' 'G' 'P' 'G' 'w' ''' (single-quote)
8 '8' 'H' 'Q' 'H' 'x' '('
9 '9' 'I' 'R' 'I' 'y' ')'

選 項 對 應 COBOL
ca RM/COBOL (not RM/COBOL-85)
cb MBP COBOL
ci IBM COBOL (RM/COBOL-85)
cm Micro Focus COBOL
cn NCR COBOL
cr Realia COBOL
cv VAX COBOL

COBOL的S9對正負號數字表示範例 (IBM COBOL)

PIC S9(3) VALUE -123.
TRAILING                 '1'   '2'   'L'
TRAILING SEPARATE  '1'   '2'   '3'   '-'
LEADING                  'J'   '2'   '3'
LEADING SEPARATE   '-'   '1'   '2'   '3'

PIC S9(5)V9 VALUE -12345.6.
TRAILING                '1'  '2'  '3'  '4'  '5'  'O'
TRAILING SEPARATE  '1'  '2'  '3'  '4'  '5'  '6'  '-'
LEADING                 'J'  '2'  '3'  '4'  '5'  '6'
LEADING SEPARATE   '-'  '1'  '2'  '3'  '4'  '5'  '6'

// IBM COBOL (-dci) and Trailing

'S9(3)V9': '12C' >> 12.3
'S9(3)V9': '12L' >> -12.3

'S9(1)V9': '12C' >> 2.3
'S9(1)V9': '12L' >> -2.3

雖然支援Leading解析,但是會跟某些Overpunch查表定義衝突

// IBM COBOL (-dci) and Leading

'S9(3)V9': 'J23' >> -12.3

'S9(1)V9': 'J23' >> `Exception: Unknown overpunch char: '2'`
// Micro Focus COBOL (-dcm) and Leading

'S9(1)V9': 'J23' >> 2.3



交易所TMP連線架構

PVC:Permanent Virtual Circuit(永久虛擬電路)

實體線

一條實體線上可建立多條PVC,每10條PVC為一組。

PVC

PORT NO
執行功能
01 FT送
02 FT收
03 成交回報
04 委託輸入
05 委託輸入
06 委託輸入
07 委託輸入
08 委託輸入
09 委託輸入

PVC作業時間表

PVC 時 間 執 行 業 務
(01)
FT 送
07:30-19:00 單筆訊息及檔案傳輸
(證券商的傳送線路)
(02)
FT 收
07:30-19:00 單筆訊息及檔案傳輸
(證券商的傳送線路)
(03)
成交回報
08:30-14:40 成交回報接收
(04~09)
委託輸入
08:30-13:30
09:00-12:10
09:00-13:30
13:40-14:30
14:00-14:30
14:30-15:00
15:00-16:00
15:00-16:00
普通股交易
標借交易
盤中零股交易
盤後零股交易
盤後定價交易
證金標購交易
拍賣交易
標購交易

連線子系統

時 間 證 券 商 與 證 交 所
07:30

08:20
1.開機通知作業
2.登錄作業
 準備進入連線狀態
08:20以後 完成連線進入各應用子統統
08:30

19:00
1.進行各項業務
2.若在各項業務處理中發現有任何異常狀況時
 (1)開機通知作業
 (2)登錄作業
  重新進入連線狀態
19:00以後 1.完成各項業務
2.離線作業
 雙方進入離線狀態

訊息格式

MESSAGE ID︰L010、L020、L030、L040、L050、L060、L070、L080


單筆訊息與檔案傳輸通訊協定

時 間 系 統 功 能
07:30

08:00
連線子系統 建立證交所與證券商的電腦連線作業,並進入業務系統。
08:00

19:00
單筆訊息與檔案傳輸子系統
結算作業
申購作業
投資人管理作業
提供交易報表。
補送成交回報資料給證券商。
申購作業。
處理結算業務。
處理申購業務。
處理與投資人管理有關之業務。
19:00 連線子系統 離線

訊息格式 (傳送功能)

MESSAGE ID︰F010、F020、F030(F210)、F040(F220)、F050、F060、F070、F080

訊息格式 (接收功能)

MESSAGE ID︰F090、F100、F110(F230)、F120(F240)、F130、F140、F150、F160

訊息格式

MESSAGE ID︰F170、F180、F190、F200


委託輸入通訊協定

時 間 系 統 功 能
08:00-08:30 連線子系統 建立證交所與證券商的電腦連線作業,並進入業務系統。
08:30-13:30
09:00-12:10
09:00-13:30
13:40-14:30
14:00-14:30
14:30-15:00
15:00-16:00
15:00-16:00
普通股交易子系統
標借交易子系統
盤中零股交易子系統
盤後零股交易子系統
盤後定價交易子系統
證金標購交易子系統
拍賣交易子系統
標購交易子系統
證券商輸入買賣委託,並接受證交所的委託回報。
16:00 連線子系統 結束委託輸入,回到連線子系統。
離線

訊息格式

MESSAGE ID︰T1、T2、T3、T4、T5、T6、T7


成交回報通訊協定

時 間 系 統 功 能
08:00

08:30
連線子系統 建立證交所與證券商的電腦連線作業,並進入業務系統。
08:30

14:00
成交回報接收子系統 接收普通股、盤中零股成交回報資料。
14:00

14:40
成交回報接收子系統 接收盤後定價、盤後零股成交回報資料。
14:40 連線子系統 結束委託輸入,回到連線子系統。
離線

訊息格式

MESSAGE ID︰R1、R2、R3、R4、R5、R6



專案結構

{project-root}
 ├─ cli <-------------------- CLI工具
 │   └─ ...
 ├─ lib
 │   ├─ copybook  <---------- 文件內容轉換
 │   ├─ field  <------------- 欄位轉換
 │   ├─ message  <----------- 訊息解析
 │   ├─ spec
 │   │   ├─ copybook  <------ 各類FILE-CODE檔案內容定義
 │   │   ├─ field  <--------- 欄位基本資料結構
 │   │   ├─ fields  <-------- 欄位組成後定義
 │   │   │   ├─ body
 │   │   │   └─ header.js
 │   │   └─ message  <------- 訊息種類定義
 │   │       ├─ otc.js
 │   │       └─ tse.js
 │   └─ meta.js
 └─ templar.js

結構圖



發布函式庫

  • 打包

    npm pack
    > npm pack
    ...
    ...
    npm notice Tarball Details
    npm notice name: templar
    npm notice version: X.Y.Z
    npm notice filename: templar-X.Y.Z.tgz
    npm notice package size: 374.7 kB
    npm notice unpacked size: 1.6 MB
    npm notice shasum: ba2890224935e4a6a0ecdf91d9585c287a4c3073
    npm notice integrity: sha512-3I975LfONtGXo[...]K22YKPtY5EZcQ==
    npm notice total files: 61
    npm notice
    templar-X.Y.Z.tgz
  • 安裝

    npm install ./templar-X.Y.Z.tgz



其他

參考資料