diff --git a/test/integration/quote_test.go b/test/integration/quote_test.go
index 2a983f4..2d50c5f 100644
--- a/test/integration/quote_test.go
+++ b/test/integration/quote_test.go
@@ -22,7 +22,7 @@ func TestQuote_DownloadTpex(t *testing.T) {
client := twstock.NewClient()
_, err := client.Quote.DownloadTpex("3374", 2022, 12)
if err != nil {
- t.Fatalf("DownloadTwse returned error: %v", err)
+ t.Fatalf("DownloadTpex returned error: %v", err)
}
_, err = client.Quote.DownloadTpex("2330", 2022, 12)
if err != twstock.ErrNoData {
diff --git a/twstock/marketdata.go b/twstock/marketdata.go
index 510c054..b153f32 100644
--- a/twstock/marketdata.go
+++ b/twstock/marketdata.go
@@ -18,7 +18,7 @@ const (
twseMarketDataPath = "/exchangeReport/FMTQIK"
// 上櫃每日市場成交資訊
- tpexMarketDataPath = "/web/stock/aftertrading/daily_trading_index/st41_result.php"
+ tpexMarketDataPath = "/www/zh-tw/afterTrading/tradingIndex"
)
type MarketData struct {
@@ -130,8 +130,8 @@ func (s *MarketDataService) DownloadTpex(year int, month time.Month) ([]MarketDa
}
url, _ := s.client.tpexBaseURL.Parse(tpexMarketDataPath)
opts := tpexOptions{
- // 需要將西元年轉為民國年
- Date: fmt.Sprintf("%d/%02d", date.Year-1911, date.Month),
+ Response: "json",
+ Date: fmt.Sprintf("%04d/%02d/%02d", date.Year, date.Month, date.Day),
}
url, _ = addOptions(url, opts)
req, _ := s.client.NewRequest("GET", url.String(), nil)
@@ -140,18 +140,26 @@ func (s *MarketDataService) DownloadTpex(year int, month time.Month) ([]MarketDa
if err != nil {
return nil, err
}
- if resp.DataLength != len(resp.Data) {
- return nil, fmt.Errorf("failed parsing market data length returned %d, want %d", resp.DataLength, len(resp.Data))
- }
- if resp.DataLength == 0 {
+ if len(resp.Tables) != 1 || resp.Tables[0].TotalCount == 0 {
return nil, ErrNoData
}
+ if resp.Tables[0].TotalCount != len(resp.Tables[0].Data) {
+ return nil, fmt.Errorf("failed parsing market data length returned %d, want %d", resp.Tables[0].TotalCount, len(resp.Tables[0].Data))
+ }
result := []MarketData{}
- for _, data := range resp.Data {
- marketData, err := s.parse(data)
+ for _, data := range resp.Tables[0].Data {
+ stringData := make([]string, len(data))
+ for i, v := range data {
+ stringData[i] = string(v)
+ }
+ marketData, err := s.parse(stringData)
if err != nil {
return nil, err
}
+ // 成交股數(仟股)
+ marketData.TradeVolume *= 1000
+ // 金額(仟元)
+ marketData.TradeValue = marketData.TradeValue.Mul(decimal.NewFromInt(1000))
result = append(result, marketData)
}
return result, nil
diff --git a/twstock/marketdata_test.go b/twstock/marketdata_test.go
index 1265b1e..52c8db5 100644
--- a/twstock/marketdata_test.go
+++ b/twstock/marketdata_test.go
@@ -304,50 +304,70 @@ func TestMarketDataService_DownloadTpex(t *testing.T) {
mux.HandleFunc(tpexMarketDataPath, func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{
- "reportDate": "111/08",
- "iTotalRecords": 5,
- "aaData": [
- [
- "111/08/01",
- "630,222,871",
- "46,240,795,178",
- "436,953",
- "182.75",
- "-0.83"
- ],
- [
- "111/08/02",
- "694,614,949",
- "51,249,692,749",
- "484,905",
- "179.30",
- "-3.45"
- ],
- [
- "111/08/03",
- "683,637,182",
- "50,799,048,121",
- "473,344",
- "178.17",
- "-1.13"
- ],
- [
- "111/08/04",
- "677,879,834",
- "51,578,056,349",
- "458,468",
- "178.18",
- "0.01"
- ],
- [
- "111/08/05",
- "651,963,371",
- "57,144,930,041",
- "435,858",
- "182.37",
- "4.19"
- ]
- ]
+ "tables": [
+ {
+ "title": "日成交量值指數",
+ "date": "20220801",
+ "data": [
+ [
+ "111/08/01",
+ "630,223",
+ "46,240,795",
+ "436,953",
+ 182.75,
+ -0.83
+ ],
+ [
+ "111/08/02",
+ "694,615",
+ "51,249,693",
+ "484,905",
+ 179.30,
+ -3.45
+ ],
+ [
+ "111/08/03",
+ "683,637",
+ "50,799,048",
+ "473,344",
+ 178.17,
+ -1.13
+ ],
+ [
+ "111/08/04",
+ "677,880",
+ "51,578,056",
+ "458,468",
+ 178.18,
+ 0.01
+ ],
+ [
+ "111/08/05",
+ "651,963",
+ "57,144,930",
+ "435,858",
+ 182.37,
+ 4.19
+ ]
+ ],
+ "fields": [
+ "日期",
+ "成交股數(仟股)",
+ "金額(仟元)",
+ "筆數",
+ "櫃買指數",
+ "漲/跌"
+ ],
+ "notes": [
+ "上表為於等價、零股、盤後定價等交易系統交易之上櫃股票成交資訊。",
+ "每日下午6:00另行產製於等價、零股、盤後定價、鉅額等交易系統交易之上櫃股票、權證、TDR、ETF、ETN、受益證券等上櫃有價證券之成交資訊,但不含轉(交)換公司債之成交統計報表,如連結"
+ ],
+ "totalCount": 5,
+ "summary": []
+ }
+ ],
+ "date": "20220801",
+ "stat": "ok"
}`)
})
@@ -358,40 +378,40 @@ func TestMarketDataService_DownloadTpex(t *testing.T) {
want := []MarketData{
{
Date: civil.Date{Year: 2022, Month: time.August, Day: 1},
- TradeVolume: 630222871,
- TradeValue: decimal.NewFromInt(46240795178),
+ TradeVolume: 630223000,
+ TradeValue: decimal.NewFromInt(46240795000),
Transaction: 436953,
Index: decimal.NewFromFloat(182.75),
Change: decimal.NewFromFloat(-0.83),
},
{
Date: civil.Date{Year: 2022, Month: time.August, Day: 2},
- TradeVolume: 694614949,
- TradeValue: decimal.NewFromInt(51249692749),
+ TradeVolume: 694615000,
+ TradeValue: decimal.NewFromInt(51249693000),
Transaction: 484905,
Index: decimal.NewFromFloat(179.30),
Change: decimal.NewFromFloat(-3.45),
},
{
Date: civil.Date{Year: 2022, Month: time.August, Day: 3},
- TradeVolume: 683637182,
- TradeValue: decimal.NewFromInt(50799048121),
+ TradeVolume: 683637000,
+ TradeValue: decimal.NewFromInt(50799048000),
Transaction: 473344,
Index: decimal.NewFromFloat(178.17),
Change: decimal.NewFromFloat(-1.13),
},
{
Date: civil.Date{Year: 2022, Month: time.August, Day: 4},
- TradeVolume: 677879834,
- TradeValue: decimal.NewFromInt(51578056349),
+ TradeVolume: 677880000,
+ TradeValue: decimal.NewFromInt(51578056000),
Transaction: 458468,
Index: decimal.NewFromFloat(178.18),
Change: decimal.NewFromFloat(0.01),
},
{
Date: civil.Date{Year: 2022, Month: time.August, Day: 5},
- TradeVolume: 651963371,
- TradeValue: decimal.NewFromInt(57144930041),
+ TradeVolume: 651963000,
+ TradeValue: decimal.NewFromInt(57144930000),
Transaction: 435858,
Index: decimal.NewFromFloat(182.37),
Change: decimal.NewFromFloat(4.19),
@@ -430,9 +450,36 @@ func TestMarketDataService_DownloadTpexErrNoData(t *testing.T) {
mux.HandleFunc(tpexMarketDataPath, func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{
- "reportDate": "111/08",
- "iTotalRecords": 0,
- "aaData": []
+ "date": "20220801",
+ "stat": "ok",
+ "tables": []
+ }`)
+ })
+
+ _, err := client.MarketData.DownloadTpex(2022, 8)
+ if err == nil {
+ t.Error("MarketData.DownloadTpex returned nil; expected error")
+ }
+ if !errors.Is(err, ErrNoData) {
+ t.Errorf("MarketData.DownloadTpex returned %v, want %v", err, ErrNoData)
+ }
+}
+
+func TestMarketDataService_DownloadTpexErrNoData2(t *testing.T) {
+ client, mux, teardown := setup()
+ defer teardown()
+
+ mux.HandleFunc(tpexMarketDataPath, func(w http.ResponseWriter, r *http.Request) {
+ testMethod(t, r, "GET")
+ fmt.Fprint(w, `{
+ "date": "20220801",
+ "stat": "ok",
+ "tables": [
+ {
+ "data": [],
+ "totalCount": 0
+ }
+ ]
}`)
})
@@ -452,9 +499,14 @@ func TestMarketDataService_DownloadTpexBadDataLength(t *testing.T) {
mux.HandleFunc(tpexMarketDataPath, func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{
- "reportDate": "111/08",
- "iTotalRecords": 1,
- "aaData": []
+ "tables": [
+ {
+ "data": [],
+ "totalCount": 1
+ }
+ ],
+ "date": "20220801",
+ "stat": "ok"
}`)
})
@@ -471,18 +523,38 @@ func TestMarketDataService_DownloadTpexBadData(t *testing.T) {
mux.HandleFunc(tpexMarketDataPath, func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{
- "reportDate": "111/08",
- "iTotalRecords": 1,
- "aaData": [
- [
- "111/30/01",
- "630,222,871",
- "46,240,795,178",
- "436,953",
- "182.75",
- "-0.83"
- ]
- ]
+ "tables": [
+ {
+ "title": "日成交量值指數",
+ "date": "20220801",
+ "data": [
+ [
+ "111/08/01",
+ "BADDATA",
+ "46,240,795",
+ "436,953",
+ 182.75,
+ -0.83
+ ]
+ ],
+ "fields": [
+ "日期",
+ "成交股數(仟股)",
+ "金額(仟元)",
+ "筆數",
+ "櫃買指數",
+ "漲/跌"
+ ],
+ "notes": [
+ "上表為於等價、零股、盤後定價等交易系統交易之上櫃股票成交資訊。",
+ "每日下午6:00另行產製於等價、零股、盤後定價、鉅額等交易系統交易之上櫃股票、權證、TDR、ETF、ETN、受益證券等上櫃有價證券之成交資訊,但不含轉(交)換公司債之成交統計報表,如連結"
+ ],
+ "totalCount": 1,
+ "summary": []
+ }
+ ],
+ "date": "20220801",
+ "stat": "ok"
}`)
})
diff --git a/twstock/quote.go b/twstock/quote.go
index f66c80c..8cd67ef 100644
--- a/twstock/quote.go
+++ b/twstock/quote.go
@@ -30,7 +30,7 @@ const (
twseQuotesPath = "/rwd/zh/afterTrading/STOCK_DAY"
// 上櫃個股日成交資訊
- tpexQuotesPath = "/web/stock/aftertrading/daily_trading_info/st43_result.php"
+ tpexQuotesPath = "/www/zh-tw/afterTrading/tradingStock"
// 個股即時交易行情
realtimeQuotesPath = "/stock/api/getStockInfo.jsp"
@@ -214,16 +214,43 @@ func (s *QuoteService) DownloadTwse(code string, year int, month time.Month) ([]
}
type tpexOptions struct {
- Date string `url:"d"`
- Code string `url:"stkno,omitempty"`
+ Response string `url:"response"`
+ Date string `url:"date"`
+ Code string `url:"code,omitempty"`
+}
+
+type StringOrNumber string
+
+func (s *StringOrNumber) UnmarshalJSON(data []byte) error {
+ // Try unmarshaling as string first
+ var str string
+ if err := json.Unmarshal(data, &str); err == nil {
+ *s = StringOrNumber(str)
+ return nil
+ }
+
+ // If that fails, try as number
+ var num float64
+ if err := json.Unmarshal(data, &num); err == nil {
+ *s = StringOrNumber(strconv.FormatFloat(num, 'f', -1, 64))
+ return nil
+ }
+
+ return fmt.Errorf("value must be string or number")
}
type tpexResponse struct {
- Code string `json:"stkNo"`
- Name string `json:"stkName"`
- Date string `json:"reportDate"`
- DataLength int `json:"iTotalRecords"`
- Data [][]string `json:"aaData"`
+ Stat string `json:"stat"`
+ Date string `json:"date"`
+ Code string `json:"code"`
+ Tables []struct {
+ Title string `json:"title"`
+ Date string `json:"date"`
+ Data [][]StringOrNumber `json:"data"`
+ Fields []string `json:"fields"`
+ Notes []string `json:"notes"`
+ TotalCount int `json:"totalCount"`
+ } `json:"tables"`
}
// 從證券櫃檯買賣中心下載盤後個股日成交資訊
@@ -234,9 +261,9 @@ func (s *QuoteService) DownloadTpex(code string, year int, month time.Month) ([]
}
url, _ := s.client.tpexBaseURL.Parse(tpexQuotesPath)
opts := tpexOptions{
- // 需要將西元年轉為民國年
- Date: fmt.Sprintf("%d/%02d", date.Year-1911, date.Month),
- Code: code,
+ Response: "json",
+ Date: fmt.Sprintf("%04d/%02d/%02d", date.Year, date.Month, date.Day),
+ Code: code,
}
url, _ = addOptions(url, opts)
req, _ := s.client.NewRequest("GET", url.String(), nil)
@@ -248,18 +275,22 @@ func (s *QuoteService) DownloadTpex(code string, year int, month time.Month) ([]
if resp.Code != code {
return nil, fmt.Errorf("invalid tpex code returned %s, want %s", resp.Code, code)
}
- if resp.DataLength != len(resp.Data) {
- return nil, fmt.Errorf("failed parsing quote data length returned %d, want %d", resp.DataLength, len(resp.Data))
- }
- if resp.DataLength == 0 {
+ if len(resp.Tables) != 1 || resp.Tables[0].TotalCount == 0 {
return nil, ErrNoData
}
+ if resp.Tables[0].TotalCount != len(resp.Tables[0].Data) {
+ return nil, fmt.Errorf("failed parsing quote data length returned %d, want %d", resp.Tables[0].TotalCount, len(resp.Tables[0].Data))
+ }
quotes := []Quote{}
- for _, data := range resp.Data {
+ for _, data := range resp.Tables[0].Data {
if len(data) != 9 {
return nil, fmt.Errorf("failed parsing quote fields")
}
- quote, err := s.parse(data)
+ stringData := make([]string, len(data))
+ for i, v := range data {
+ stringData[i] = string(v)
+ }
+ quote, err := s.parse(stringData)
if err != nil {
if errors.Is(err, errSuspendedTrading) {
continue
diff --git a/twstock/quote_test.go b/twstock/quote_test.go
index dff18e6..de97213 100644
--- a/twstock/quote_test.go
+++ b/twstock/quote_test.go
@@ -362,70 +362,93 @@ func TestQuoteService_DownloadTpex(t *testing.T) {
testMethod(t, r, "GET")
fmt.Fprint(w, `
{
- "stkNo": "3374",
- "stkName": "精材 ",
+ "tables": [
+ {
+ "title": "個股日成交資訊",
+ "subtitle": "3374 精材 111年08月",
+ "date": "20220801",
+ "data": [
+ [
+ "111/08/01",
+ "1,328",
+ "168,265",
+ "127.50",
+ "128.00",
+ "125.50",
+ "127.00",
+ "-2.00",
+ "1,272"
+ ],
+ [
+ "111/08/02",
+ "1,593",
+ "199,305",
+ "125.00",
+ "127.00",
+ "123.00",
+ "127.00",
+ "0.00",
+ "1,078"
+ ],
+ [
+ "111/08/03",
+ "1,603",
+ "201,304",
+ "124.50",
+ "127.00",
+ "124.00",
+ "126.00",
+ "-1.00",
+ "1,124"
+ ],
+ [
+ "111/08/04",
+ "3,920",
+ "500,389",
+ "126.50",
+ "130.00",
+ "124.50",
+ "129.50",
+ "3.50",
+ "2,474"
+ ],
+ [
+ "111/08/05",
+ "7,244",
+ "940,126",
+ "129.50",
+ "132.00",
+ "126.50",
+ "129.50",
+ "0.00",
+ "5,073"
+ ]
+ ],
+ "fields": [
+ "日 期",
+ "成交仟股",
+ "成交仟元",
+ "開盤",
+ "最高",
+ "最低",
+ "收盤",
+ "漲跌",
+ "筆數"
+ ],
+ "notes": [
+ "以上資料不含上櫃股票鉅額交易"
+ ],
+ "totalCount": 5,
+ "summary": []
+ }
+ ],
+ "date": "20220801",
+ "code": "3374",
+ "name": "精材",
"showListPriceNote": false,
"showListPriceLink": false,
- "reportDate": "111/08",
- "iTotalRecords": 5,
- "aaData": [
- [
- "111/08/01",
- "1,328",
- "168,265",
- "127.50",
- "128.00",
- "125.50",
- "127.00",
- "-2.00",
- "1,272"
- ],
- [
- "111/08/02",
- "1,593",
- "199,305",
- "125.00",
- "127.00",
- "123.00",
- "127.00",
- "0.00",
- "1,078"
- ],
- [
- "111/08/03",
- "1,603",
- "201,304",
- "124.50",
- "127.00",
- "124.00",
- "126.00",
- "-1.00",
- "1,124"
- ],
- [
- "111/08/04",
- "3,920",
- "500,389",
- "--",
- "130.00",
- "124.50",
- "129.50",
- "3.50",
- "2,474"
- ],
- [
- "111/08/05",
- "7,244",
- "940,126",
- "129.50",
- "132.00",
- "126.50",
- "129.50",
- "0.00",
- "5,073"
- ]
- ]
- }`)
+ "stat": "ok"
+ }`)
})
quotes, err := client.Quote.Download("3374", 2022, 8)
@@ -457,6 +480,14 @@ func TestQuoteService_DownloadTpex(t *testing.T) {
Close: decimal.NewFromFloat(126),
Volume: 1603000,
},
+ {
+ Date: civil.Date{Year: 2022, Month: time.August, Day: 4},
+ Open: decimal.NewFromFloat(126.5),
+ High: decimal.NewFromFloat(130),
+ Low: decimal.NewFromFloat(124.5),
+ Close: decimal.NewFromFloat(129.5),
+ Volume: 3920000,
+ },
{
Date: civil.Date{Year: 2022, Month: time.August, Day: 5},
Open: decimal.NewFromFloat(129.5),
@@ -505,12 +536,63 @@ func TestQuoteService_DownloadTpexErrNoData(t *testing.T) {
testMethod(t, r, "GET")
fmt.Fprint(w, `
{
- "stkNo": "3374",
- "stkName": "精材 ",
+ "tables": [],
+ "date": "20220801",
+ "code": "3374",
+ "name": "精材",
"showListPriceNote": false,
"showListPriceLink": false,
- "reportDate": "111/08",
- "iTotalRecords": 0
+ "stat": "ok"
+ }`)
+ })
+
+ _, err := client.Quote.Download("3374", 2022, 8)
+ if err == nil {
+ t.Errorf("Quote.Download returned nil; expected error")
+ }
+ if !errors.Is(err, ErrNoData) {
+ t.Errorf("Quote.Download returned %v, want %v", err, ErrNoData)
+ }
+}
+
+func TestQuoteService_DownloadTpexErrNoData2(t *testing.T) {
+ client, mux, teardown := setup()
+ defer teardown()
+
+ mux.HandleFunc(tpexQuotesPath, func(w http.ResponseWriter, r *http.Request) {
+ testMethod(t, r, "GET")
+ fmt.Fprint(w, `
+ {
+ "tables": [
+ {
+ "title": "個股日成交資訊",
+ "subtitle": "3374 精材 111年08月",
+ "date": "20220801",
+ "data": [],
+ "fields": [
+ "日 期",
+ "成交仟股",
+ "成交仟元",
+ "開盤",
+ "最高",
+ "最低",
+ "收盤",
+ "漲跌",
+ "筆數"
+ ],
+ "notes": [
+ "以上資料不含上櫃股票鉅額交易"
+ ],
+ "totalCount": 0,
+ "summary": []
+ }
+ ],
+ "date": "20220801",
+ "code": "3374",
+ "name": "精材",
+ "showListPriceNote": false,
+ "showListPriceLink": false,
+ "stat": "ok"
}`)
})
@@ -531,14 +613,14 @@ func TestQuoteService_DownloadBadCode(t *testing.T) {
testMethod(t, r, "GET")
fmt.Fprint(w, `
{
- "stkNo": "3375",
- "stkName": "精材 ",
+ "tables": [],
+ "date": "20220801",
+ "code": "3375",
+ "name": "精材",
"showListPriceNote": false,
"showListPriceLink": false,
- "reportDate": "111/08",
- "iTotalRecords": 5,
- "aaData": []
- }`)
+ "stat": "ok"
+ }`)
})
_, err := client.Quote.DownloadTpex("3374", 2022, 8)
@@ -555,14 +637,37 @@ func TestQuoteService_DownloadBadDataLength(t *testing.T) {
testMethod(t, r, "GET")
fmt.Fprint(w, `
{
- "stkNo": "3374",
- "stkName": "精材 ",
+ "tables": [
+ {
+ "title": "個股日成交資訊",
+ "subtitle": "3374 精材 111年08月",
+ "date": "20220801",
+ "data": [],
+ "fields": [
+ "日 期",
+ "成交仟股",
+ "成交仟元",
+ "開盤",
+ "最高",
+ "最低",
+ "收盤",
+ "漲跌",
+ "筆數"
+ ],
+ "notes": [
+ "以上資料不含上櫃股票鉅額交易"
+ ],
+ "totalCount": 23,
+ "summary": []
+ }
+ ],
+ "date": "20220801",
+ "code": "3374",
+ "name": "精材",
"showListPriceNote": false,
"showListPriceLink": false,
- "reportDate": "111/08",
- "iTotalRecords": 5,
- "aaData": []
- }`)
+ "stat": "ok"
+ }`)
})
_, err := client.Quote.DownloadTpex("3374", 2022, 8)
@@ -579,27 +684,50 @@ func TestQuoteService_DownloadBadFieldCount(t *testing.T) {
testMethod(t, r, "GET")
fmt.Fprint(w, `
{
- "stkNo": "3374",
- "stkName": "精材 ",
+ "tables": [
+ {
+ "title": "個股日成交資訊",
+ "subtitle": "3374 精材 111年08月",
+ "date": "20220801",
+ "data": [
+ [
+ "111/08/01",
+ "1,328",
+ "168,265",
+ "127.50",
+ "128.00",
+ "125.50",
+ "127.00",
+ "-2.00",
+ "1,272",
+ ""
+ ]
+ ],
+ "fields": [
+ "日 期",
+ "成交仟股",
+ "成交仟元",
+ "開盤",
+ "最高",
+ "最低",
+ "收盤",
+ "漲跌",
+ "筆數"
+ ],
+ "notes": [
+ "以上資料不含上櫃股票鉅額交易"
+ ],
+ "totalCount": 1,
+ "summary": []
+ }
+ ],
+ "date": "20220801",
+ "code": "3374",
+ "name": "精材",
"showListPriceNote": false,
"showListPriceLink": false,
- "reportDate": "111/08",
- "iTotalRecords": 1,
- "aaData": [
- [
- "111/08/01",
- "1,328",
- "168,265",
- "127.50",
- "128.00",
- "125.50",
- "127.00",
- "-2.00",
- "1,272",
- ""
- ]
- ]
- }`)
+ "stat": "ok"
+ }`)
})
_, err := client.Quote.DownloadTpex("3374", 2022, 8)
@@ -616,25 +744,49 @@ func TestQuoteService_DownloadBadData(t *testing.T) {
testMethod(t, r, "GET")
fmt.Fprint(w, `
{
- "stkNo": "3374",
- "stkName": "精材 ",
+ "tables": [
+ {
+ "title": "個股日成交資訊",
+ "subtitle": "3374 精材 111年08月",
+ "date": "20220801",
+ "data": [
+ [
+ "111/08/01",
+ "1,328",
+ "168,265",
+ "BADDATA",
+ "128.00",
+ "125.50",
+ "127.00",
+ "-2.00",
+ "1,272",
+ ""
+ ]
+ ],
+ "fields": [
+ "日 期",
+ "成交仟股",
+ "成交仟元",
+ "開盤",
+ "最高",
+ "最低",
+ "收盤",
+ "漲跌",
+ "筆數"
+ ],
+ "notes": [
+ "以上資料不含上櫃股票鉅額交易"
+ ],
+ "totalCount": 1,
+ "summary": []
+ }
+ ],
+ "date": "20220801",
+ "code": "3374",
+ "name": "精材",
"showListPriceNote": false,
"showListPriceLink": false,
- "reportDate": "111/08",
- "iTotalRecords": 1,
- "aaData": [
- [
- "111/08/01",
- "1,328",
- "168,265",
- "BADDATA",
- "128.00",
- "125.50",
- "127.00",
- "-2.00",
- "1,272"
- ]
- ]
+ "stat": "ok"
}`)
})