[C#] 取得證交所台股價格的 3 種實用方法
想要在網路上取得台股最新的股價有許多種方式,其中一種免費的方式就是直接向證交所網站取得股價資料,這次我會分享 3 種用 C# 向證交所取得股價資料的實用方法。
- 取得即時的價格
- 取得每日收盤行情的 K 線資料
- 取得單一股票在當月各日成交資訊
這 3 種方式分別可以應用在不同的實務上,當了解基本取得資料的方式,就可以寫程式定期取得最新或是歷史的股價資料。
先看一次我這次範例的操作畫面。
範例建置環境
後端架構: C# ASP.Net MVC .Net Framework
前端架構: Vue.js, jQuery, Bootstrap
完整範例可至文末下載。
Contents
建立 MVC 專案
打開 Visual Studio 2022,選擇「ASP.NET Web 應用程式 (.NET Framework),按「下一步」,建立新 MVC 專案。
再輸入專案名稱及位置,選擇「MVC 範本」,即可建立新專案。
修改佈局頁
MVC 建立之後,開啟 \Views\Shared\_Layout.cshtml 先調整一下佈局頁,引用新的 JavaScript 。
在 @Scripts.Render("~/bundles/bootstrap")
下方加入 Vue.js 套件。
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
加入 jquery.blockUI 套件。
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.blockUI/2.70/jquery.blockUI.js"></script>
調整後畫面
調整首頁
此範例我直接改在首頁顯示,開啟 \Views\Home\Index.cshtml 頁面。
先清空原有的範本程式碼,加入以下語法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 |
<div id="VuePage"> <br /> <div class="panel panel-default"> <div class="panel-heading">範例1 即時股價</div> <div class="panel-body"> <div class="form-group"> <label class="control-label col-sm-2">股票:</label> <div class="col-sm-10"> <input type="text" class="form-control" v-model="form.Sample1_Symbol"> </div> </div> <button type="button" class="btn btn-primary" v-on:click="GetRealtimePrice()">查詢</button> </div> <div class="panel-footer"> <span v-html="realPrice"></span> </div> </div> <div class="panel panel-default"> <div class="panel-heading">範例2 每日收盤行情</div> <div class="panel-body"> <div class="form-group"> <label class="control-label col-sm-2">日期:</label> <div class="col-sm-10"> <input type="text" class="form-control" v-model="form.Sample2_Date"> </div> </div> <button type="button" class="btn btn-primary" v-on:click="GetDayPrice()">查詢</button> </div> <div class="panel-footer"> <div class="table-responsive" style="overflow-y:auto;height:400px;"> <table class="table"> <tr> <th>代碼</th> <th>名稱</th> <th>開盤價</th> <th>最高價</th> <th>最低價</th> <th>收盤價</th> <th>成交量</th> </tr> <tr v-for="(item, index) in gridDay"> <td> {{item.symbolCode}} </td> <td> {{item.symbolName}} </td> <td> {{item.open}} </td> <td>{{item.high}}</td> <td>{{item.low}}</td> <td>{{item.close}}</td> <td>{{item.volume}}</td> </tr> </table> </div> </div> </div> <div class="panel panel-default"> <div class="panel-heading">範例3 當月各日成交資訊</div> <div class="panel-body"> <div class="form-group"> <label class="control-label col-sm-2">股票:</label> <div class="col-sm-10"> <input type="text" class="form-control" v-model="form.Sample3_Symbol"> </div> </div> <div class="form-group"> <label class="control-label col-sm-2">日期:</label> <div class="col-sm-10"> <input type="text" class="form-control" v-model="form.Sample3_Date"> </div> </div> <button type="button" class="btn btn-primary" v-on:click="GetMonthPrice()">查詢</button> </div> <div class="panel-footer"> <div class="table-responsive"> <table class="table"> <tr> <th>日期</th> <th>開盤價</th> <th>最高價</th> <th>最低價</th> <th>收盤價</th> <th>成交量</th> </tr> <tr v-for="(item, index) in gridMonthPirce"> <td>{{item.date}}</td> <td>{{item.open}}</td> <td>{{item.high}}</td> <td>{{item.low}}</td> <td>{{item.close}}</td> <td>{{item.volume}}</td> </tr> </table> </div> </div> </div> </div> @section scripts{ <script> var VuePage = new Vue({ el: '#VuePage' , data: function () { var data = { form: { Sample1_Symbol: "" , Sample2_Date: "" , Sample3_Symbol: "" , Sample3_Date:"" } , gridDay: [] , realPrice: '' , gridMonthPirce: [] }; return data; } , created: function () { var self = this; // 預設股票代碼 self.form.Sample1_Symbol = "2330,0050"; self.form.Sample3_Symbol = "2330"; // 產生今天日期 var Today = new Date(); var year = "" + Today.getFullYear(); var month = "" + (Today.getMonth() + 1); if (month.length == 1) { month = "0" + month; } var day = "" + Today.getDate(); if (day.length == 1) { day = "0" + day; } self.form.Sample2_Date = year + month + day; self.form.Sample3_Date = year + month + day; } , methods: { // 即時股價 GetRealtimePrice: function () { var self = this; var postData = {}; postData['Sample1_Symbol'] = self.form.Sample1_Symbol; $.blockUI({ message: '處理中...' }); $.ajax({ url:'@Url.Content("~/Home/GetRealtimePrice")', method:'POST', dataType:'json', data: { inModel: postData}, success: function (datas) { if (datas.ErrMsg) { alert(datas.ErrMsg); return; } self.realPrice = datas.realPrice; // 解除畫面鎖定 $.unblockUI(); }, error: function (err) { alert(err.responseText); }, }); } // 每日收盤行情 , GetDayPrice: function () { var self = this; var postData = {}; postData['Sample2_Date'] = self.form.Sample2_Date; $.blockUI({ message: '處理中...' }); $.ajax({ url:'@Url.Content("~/Home/GetDayPrice")', method:'POST', dataType:'json', data: { inModel: postData }, success: function (datas) { if (datas.ErrMsg) { alert(datas.ErrMsg); return; } self.gridDay = []; // 顯示列表 for (var i in datas.gridList) { var gridData = {}; for (var key in datas.gridList[i]) { gridData[key] = datas.gridList[i][key]; } self.gridDay.push(gridData); } // 解除畫面鎖定 $.unblockUI(); }, error: function (err) { alert(err.responseText); }, }); } // 當月各日成交資訊 , GetMonthPrice: function () { var self = this; var postData = {}; postData['Sample3_Symbol'] = self.form.Sample3_Symbol; postData['Sample3_Date'] = self.form.Sample3_Date; $.blockUI({ message: '處理中...' }); $.ajax({ url:'@Url.Content("~/Home/GetMonthPrice")', method:'POST', dataType:'json', data: { inModel: postData }, success: function (datas) { if (datas.ErrMsg) { alert(datas.ErrMsg); return; } self.gridMonthPirce = []; // 顯示列表 for (var i in datas.gridList) { var gridData = {}; for (var key in datas.gridList[i]) { gridData[key] = datas.gridList[i][key]; } self.gridMonthPirce.push(gridData); } // 解除畫面鎖定 $.unblockUI(); }, error: function (err) { alert(err.responseText); }, }); } } }) </script> } |
修改 Controller 程式碼
在 View 會呼叫 Controller 的方法,
開啟 \Controllers\HomeController.cs 檔案,在方法內增加以下 3 個方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 |
/// <summary> /// 即時股價 /// </summary> /// <param name="inModel"></param> /// <returns></returns> public ActionResult GetRealtimePrice(GetRealtimePriceIn inModel) { GetRealtimePriceOut outModel = new GetRealtimePriceOut(); // 檢查輸入參數 if (string.IsNullOrEmpty(inModel.Sample1_Symbol)) { outModel.ErrMsg = "請輸入股票代碼"; return Json(outModel); } StringBuilder ExCode = new StringBuilder(); string[] symbols = inModel.Sample1_Symbol.Split(','); foreach (string symbol in symbols) { ExCode.Append("tse_" + symbol + ".tw|"); } // 呼叫網址 string url = "https://mis.twse.com.tw/stock/api/getStockInfo.jsp"; url += "?json=1&delay=0&ex_ch=" + ExCode; string downloadedData = ""; using (WebClient wClient = new WebClient()) { // 取得網頁資料 wClient.Encoding = Encoding.UTF8; downloadedData = wClient.DownloadString(url); } TwsePriceSchema jsonPrice = null; if (downloadedData.Trim().Length > 0) { jsonPrice = JsonConvert.DeserializeObject<TwsePriceSchema>(downloadedData); if (jsonPrice.rtcode != "0000") { throw new Exception("取商品價格失敗: " + jsonPrice.rtmessage); } } StringBuilder sbRealPrice = new StringBuilder(); for (int i = 0; i < jsonPrice.msgArray.Count; i++) { // 代碼 string code = jsonPrice.msgArray[i].c; // z = 收盤價 string close = jsonPrice.msgArray[i].z; // a = 最低委賣價 string ask = ""; if (jsonPrice.msgArray[i].a.IndexOf("_") > -1) { ask = jsonPrice.msgArray[i].a.Split('_')[0]; } // b = 最高委買價 string bid = ""; if (jsonPrice.msgArray[i].b.IndexOf("_") > -1) { bid = jsonPrice.msgArray[i].b.Split('_')[0]; } sbRealPrice.Append("代碼: " + code + " 收盤價: " + close + " 最低委賣價: " + ask + " 最高委買價: " + bid + "<br>"); } outModel.realPrice = sbRealPrice.ToString(); // 回傳 Json 給前端 return Json(outModel); } /// <summary> /// 每日收盤行情 /// </summary> /// <param name="inModel"></param> /// <returns></returns> public ActionResult GetDayPrice(GetDayPriceIn inModel) { GetDayPriceOut outModel = new GetDayPriceOut(); // 檢查輸入參數 if (string.IsNullOrEmpty(inModel.Sample2_Date)) { outModel.ErrMsg = "請輸入日期"; return Json(outModel); } // 呼叫網址 string twseUrl = "https://www.twse.com.tw/exchangeReport/MI_INDEX"; string download_url = twseUrl + "?response=csv&date=" + inModel.Sample2_Date + "&type=ALL"; string downloadedData = ""; using (WebClient wClient = new WebClient()) { // 網頁回傳 downloadedData = wClient.DownloadString(download_url); } if (downloadedData.Trim().Length > 0) { // 回傳前端的資料集 outModel.gridList = new List<StockPriceRow>(); string[] lineStrs = downloadedData.Split('\n'); for (int i = 0; i < lineStrs.Length; i++) { string strline = lineStrs[i]; if (strline.Trim().Length == 0) { continue; } // 排除非價格部份 if (strline.IndexOf("證券代號") > -1 || strline.IndexOf("(元,股)") > -1) { continue; } if (strline.Substring(0, 1) == "=") { strline = strline.TrimStart('='); } ArrayList resultLine = new ArrayList(); // 解析資料 this.ParseCSVData(resultLine, strline); string[] datas = (string[])resultLine.ToArray(typeof(string)); //檢查資料內容 if (datas.Length != 17) { continue; } // 股票代碼 string symbolCode = datas[0]; if (symbolCode.Length == 4) { // 輸出資料 StockPriceRow row = new StockPriceRow(); row.symbolCode = symbolCode; //股票代碼 row.symbolName = datas[1]; //股票名稱 row.open = datas[5]; //開盤價 row.high = datas[6]; //最高價 row.low = datas[7]; //最低價 row.close = datas[8]; //收盤價 row.volume = datas[2]; //成交量 outModel.gridList.Add(row); } } } // 回傳 Json 給前端 return Json(outModel); } /// <summary> /// 當月各日成交資訊 /// </summary> /// <param name="inModel"></param> /// <returns></returns> public ActionResult GetMonthPrice(GetMonthPriceIn inModel) { GetMonthPriceOut outModel = new GetMonthPriceOut(); // 檢查輸入參數 if (string.IsNullOrEmpty(inModel.Sample3_Symbol)) { outModel.ErrMsg = "請輸入股票代碼"; return Json(outModel); } if (string.IsNullOrEmpty(inModel.Sample3_Date)) { outModel.ErrMsg = "請輸入日期"; return Json(outModel); } // 呼叫網址 string download_url = "http://www.twse.com.tw/exchangeReport/STOCK_DAY?response=csv&date=" + inModel.Sample3_Date + "&stockNo=" + inModel.Sample3_Symbol; string downloadedData = ""; using (WebClient wClient = new WebClient()) { // 網頁回傳 downloadedData = wClient.DownloadString(download_url); } if (downloadedData.Trim().Length > 0) { outModel.gridList = new List<StockPriceRow>(); string[] lineStrs = downloadedData.Split('\n'); for (int i = 0; i < lineStrs.Length; i++) { string strline = lineStrs[i]; if (i == 0 || i == 1 || strline.Trim().Length == 0) { continue; } // 排除非價格部份 if (strline.IndexOf("說明") > -1 || strline.IndexOf("符號") > -1 || strline.IndexOf("統計") > -1 || strline.IndexOf("ETF") > -1) { continue; } ArrayList resultLine = new ArrayList(); // 解析資料 this.ParseCSVData(resultLine, strline); string[] datas = (string[])resultLine.ToArray(typeof(string)); //檢查資料內容 if (Convert.ToInt32(datas[1].Replace(",", "")) == 0 || datas[3] == "--" || datas[4] == "--" || datas[5] == "--" || datas[6] == "--") { continue; } // 輸出資料 StockPriceRow row = new StockPriceRow(); row.date = datas[0]; //日期 row.open = datas[3]; //開盤價 row.high = datas[4]; //最高價 row.low = datas[5]; //最低價 row.close = datas[6]; //收盤價 row.volume = datas[1]; //成交量 outModel.gridList.Add(row); } } // 回傳 Json 給前端 return Json(outModel); } private void ParseCSVData(ArrayList result, string data) { int position = -1; while (position < data.Length) result.Add(ParseCSVField(ref data, ref position)); } private string ParseCSVField(ref string data, ref int StartSeperatorPos) { if (StartSeperatorPos == data.Length - 1) { StartSeperatorPos++; return ""; } int fromPos = StartSeperatorPos + 1; if (data[fromPos] == '"') { int nextSingleQuote = GetSingleQuote(data, fromPos + 1); StartSeperatorPos = nextSingleQuote + 1; string tempString = data.Substring(fromPos + 1, nextSingleQuote - fromPos - 1); tempString = tempString.Replace("'", "''"); return tempString.Replace("\"\"", "\""); } int nextComma = data.IndexOf(',', fromPos); if (nextComma == -1) { StartSeperatorPos = data.Length; return data.Substring(fromPos); } else { StartSeperatorPos = nextComma; return data.Substring(fromPos, nextComma - fromPos); } } private int GetSingleQuote(string data, int SFrom) { int i = SFrom - 1; while (++i < data.Length) if (data[i] == '"') { if (i < data.Length - 1 && data[i + 1] == '"') { i++; continue; } else return i; } return -1; } |
建立 Model
剛剛在 HomeController 建立的方法,有定義新的參數及回傳類別,這些類別要放在 Model 裡面,
在 Models 目錄按右鍵選「加入」->「類別」。
輸入名稱為「HomeModel」,按「新增」。
然後在「HomeModel」的類別裡面,再加入新的類別。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
/// <summary> /// [即時股價]參數 /// </summary> public class GetRealtimePriceIn { public string Sample1_Symbol { get; set; } } /// <summary> /// [即時股價]回傳 /// </summary> public class GetRealtimePriceOut { public string ErrMsg { get; set; } public string realPrice { get; set; } } /// <summary> /// [每日收盤行情]參數 /// </summary> public class GetDayPriceIn { public string Sample2_Date { get; set; } } /// <summary> /// [每日收盤行情]回傳 /// </summary> public class GetDayPriceOut { public string ErrMsg { get; set; } public List<StockPriceRow> gridList { get; set; } } /// <summary> /// [當月各日成交資訊]參數 /// </summary> public class GetMonthPriceIn { public string Sample3_Symbol { get; set; } public string Sample3_Date { get; set; } } /// <summary> /// [當月各日成交資訊]回傳 /// </summary> public class GetMonthPriceOut { public string ErrMsg { get; set; } public List<StockPriceRow> gridList { get; set; } } public class StockPriceRow { public string symbolCode { get; set; } public string symbolName { get; set; } public string date { get; set; } public string open { get; set; } public string high { get; set; } public string low { get; set; } public string close { get; set; } public string volume { get; set; } } public class TwsePriceSchema { public QueryTime queryTime { get; set; } public string referer { get; set; } public string rtmessage { get; set; } public string exKey { get; set; } public IList<MsgArray> msgArray { get; set; } public int userDelay { get; set; } public string rtcode { get; set; } public int cachedAlive { get; set; } } public class QueryTime { public int stockInfoItem { get; set; } public string sessionKey { get; set; } public string sessionStr { get; set; } public string sysDate { get; set; } public int sessionFromTime { get; set; } public int stockInfo { get; set; } public bool showChart { get; set; } public int sessionLatestTime { get; set; } public string sysTime { get; set; } } public class MsgArray { public string n { get; set; } public string g { get; set; } public string u { get; set; } public string mt { get; set; } public string o { get; set; } public string ps { get; set; } public string tk0 { get; set; } public string a { get; set; } public string tlong { get; set; } public string t { get; set; } public string it { get; set; } public string ch { get; set; } public string b { get; set; } public string f { get; set; } public string w { get; set; } public string pz { get; set; } public string l { get; set; } public string c { get; set; } public string v { get; set; } public string d { get; set; } public string tv { get; set; } public string tk1 { get; set; } public string ts { get; set; } public string nf { get; set; } public string y { get; set; } public string p { get; set; } public string i { get; set; } public string ip { get; set; } public string z { get; set; } public string s { get; set; } public string h { get; set; } public string ex { get; set; } } |
範例1 取得即時股價解說
範例畫面輸入要查詢的股票代碼,可輸入單一股票或是用 , (逗號)分隔輸入代碼後按查詢。
按下查詢後,程式會組合查詢網址,例如
https://mis.twse.com.tw/stock/api/getStockInfo.jsp?json=1&delay=0&ex_ch=tse_2330.tw|tse_0050.tw|
網址中的 tse_2330.tw|tse_0050.tw| 就是要查詢的股票名稱,大家可以換成自己需要的股票。
如果要查加權指數可使用代碼: tse_t00.tw。
當此網址在瀏覽器查詢時,即會回傳 Json 格式的價格資料
1 |
{"msgArray":[{"tv":"-","ps":"-","pz":"-","a":"592.0000_593.0000_594.0000_595.0000_596.0000_","b":"591.0000_590.0000_589.0000_588.0000_587.0000_","c":"2330","d":"20210510","ch":"2330.tw","tlong":"1620614180000","f":"332_721_423_419_366_","ip":"0","g":"586_1044_261_577_263_","mt":"866821","h":"597.0000","i":"24","it":"12","l":"591.0000","n":"台積電","o":"596.0000","p":"0","ex":"tse","s":"-","t":"10:36:20","u":"658.0000","v":"8071","w":"540.0000","nf":"台灣積體電路製造股份有限公司","y":"599.0000","z":"-","ts":"0"},{"tv":"-","ps":"-","nu":"http://www.yuantaetfs.com/#/RtNav/Index","pz":"-","a":"138.7000_138.7500_138.8000_138.8500_138.9000_","b":"138.6500_138.6000_138.5500_138.5000_138.4500_","c":"0050","d":"20210510","ch":"0050.tw","tlong":"1620614179000","f":"13_5_8_120_100_","ip":"0","g":"5_97_4_25_104_","mt":"995922","h":"139.5000","it":"02","l":"138.1500","n":"元大台灣50","o":"139.5000","p":"0","ex":"tse","s":"-","t":"10:36:19","u":"153.3000","v":"2229","w":"125.5000","nf":"元大台灣卓越50證券投資信託基金","y":"139.4000","z":"-","ts":"0"}],"referer":"","userDelay":5000,"rtcode":"0000","queryTime":{"sysDate":"20210510","stockInfoItem":1201,"stockInfo":629093,"sessionStr":"UserSession","sysTime":"10:36:25","showChart":false,"sessionFromTime":-1,"sessionLatestTime":-1},"rtmessage":"OK"} |
接下來就可以用程式解析 Json 來取得價格資料。
我列出 Json 內容中價格資訊常用的欄位
在此範例中我只顯示「股票代號/當盤成交價/最低委賣價/最高委買價」做示範,
大家可以依自己的需求調整要顯示的資料。
2021-8-10 補充:
在呼叫證交所的即時價格時,如果是盤中呼叫,”偶爾” 會發生沒有當盤成交價的問題。
而這問題在逐筆交易上線(2020-3-23)以前,是不會發生的,當時是每 5 秒撮合一次,一定有成交價。
但在逐筆交易上線後,從證交所呼叫即時價格,其實是得到每 5 秒行情快照的結果,也就是 5 秒才會更新一個價格。
可能在快照那當下 0.1 秒時,就是沒有人成交,所以也就沒有看到當盤成交價。
如果沒有當盤成交價的話,只能從委買 1 或委賣 1 來推算可能的成交價了。
如果需要非常即時的逐筆交易價格,我是透過群益 API 來取得即時報價的,可參考這篇文章。
範例2 取得每日收盤行情解說
在範例畫面上輸入要查詢的日期,查詢後就會列出當日所有股價的 K 線價格。
當查詢之後,程式會組合查詢網址:
https://www.twse.com.tw/exchangeReport/MI_INDEX?response=csv&date=20210507&type=ALL
替換參數 「20210507」 後就可以改成需要查詢的日期
此查詢結果會回傳 csv 格式的內容,內容包含所有上市交易的清單,以及類股指數的價格,
此檔案比較大有 2 萬多筆資料回傳。
回傳資料分 2 部份,上半部是類股價格而下半部是個股價格,會在同一份檔案中。
我自己是用欄位數量來分辨類股或是個股的。
範例3 取得當月各日成交資訊解說
在範例畫面上輸入股票代碼及查詢日期,就可以查詢該股票當月的所有日期價格。
當查詢之後,程式會組合查詢網址:
http://www.twse.com.tw/exchangeReport/STOCK_DAY?response=csv&date=20210510&stockNo=2330
替換參數 「20210510」及「2330」 後就可以改變回傳內容。
此查詢結果會回傳 csv 格式的內容,內容包含股票當月各日成交資訊。
資料欄位包含日期/成交股數/成交金額/開盤價/最高價/最低價/收盤價/漲跌價差/成交筆數
以上就是 3 種向證交所取得股價的實用方式,網頁上的程式碼中有些方法寫在共用方法區內,沒有展示出來,若需要了解更多可以下載完整範例。
重點整理
- 取得證交所即時價格是每 5 秒更新一次
- 要取得逐筆交易的 Tick 價格可串接券商 API 取得證交所即時價格是每
- 知道證交所查詢網址即可自寫程式查詢
- 一天更新一次價格可利用查詢證交所每日收盤行情
- 當月各日成交資訊可回溯非常久的歷史資料
範例下載
實際網頁專案開發範例
此連結是我實際應用在網頁上呈現的範例: Winvest 雲投資
相關學習文章
- [C#] 取得證交所上市及上櫃的股票及ETF清單(附範例)
- [C#] 取得公開資訊觀測站股票基本資料(上市、上櫃、興櫃、公開發行) (附範例下載)
- 【C# 群益 API 開發教學】取得商品報價、Tick、最佳 5 檔教學 (附範例下載)
如果你在學習上有不懂的地方,需要諮詢服務,可以參考站長服務,我想辨法解決你的問題
如果文章內容有過時、不適用或錯誤的地方,幫我在下方留言通知我一下,謝謝
你好
下載的範例
沒有.sln 的檔案
請問要如何開啟
不好意思,我已經重新放檔案了,你再試試看。
之前做壓縮檔時沒注意到,謝謝你的提醒。
感謝大大 , 大大一生平安
謝謝你,能幫助到你,我很開心
MARS大想請教一下我目前用證交所API來取加權指數
雖然能取到但總是比看盤軟體慢了兩三秒
有時還會漏掉
不知道群益API你是否有研究能即時取得加權指數的方法
你好,證交所的即時報價是每 5 秒更新一次,所以你會覺得比較慢是正常的
然後偶爾會漏掉,會發生在個股的即時成交價,偶爾會出現當下 0.1 秒時,沒有出現成交價
然後我要準確取得即時價格,我都是用群益 API 來報價,會即時更新,不會有漏報的問題
群益取 api 方法,我有寫文章教學喔,可參考 https://blog.hungwin.com.tw/csharp-capital-api-quote-tick-best5/
只要更換商品代碼就行,群益加權指數的代碼是 TSEA
用您的程式加上了 cboCommID.Items.Add(new ComboboxItem(“TSWE”, “加權指數”)); 執行後取報價看起來失敗了, 不知是不是未開盤的原因, 總之我明天開盤再試
證交所的加權指數代碼不是 TSWE 喔,這個是群益的代碼
證交所的加權指數代碼是 tse_t00.tw
你可以以下這網址試試
https://mis.twse.com.tw/stock/api/getStockInfo.jsp?json=1&delay=0&ex_ch=tse_t00.tw|
你好,非常感謝您的分享,想請問是否可以得到周線月線的資料,因為網路上好像大多都只有教如何取得日線而已,還是說必須自己從這些日線資料推出周線資料。
謝謝您,祝萬事順心
我也很少看到週線月線這種資料,我都是自己寫程式計算的