[內容介紹]上一篇介紹了K線圖的基本繪制方法,但很不完善,本篇增加了它直接讀取數據的功能,這對於金融市場的數據量大且又需要動態刷新功能的實現很重要.
[實現方法]
1.需要一個數據文件,這里用的是直接讀取由另一個CTP程序從上期交易所接收的期貨合約RB1609所寫的行情文件日線數據rb1609_d1.txt
文件格式如下:
日期 時間 開盤 最高 最低 收盤 成交量 持倉量
20160810 0.100000 2555.00 2606.00 2540.00 2563.00 3114 6858 20160812 0.100000 2548.00 2554.00 2532.00 2539.00 908 8184 20160812 0.100000 2548.00 2565.00 2461.00 2557.00 5706 6472 20160815 0.100000 2533.00 2546.00 2528.00 2541.00 492 6302 20160815 0.100000 2533.00 2574.00 2492.00 2560.00 3960 5384 20160816 0.100000 2560.00 2594.00 2558.00 2568.00 800 5124 20160816 0.000000 2560.00 2647.00 2558.00 2613.00 4208 5558 20160817 0.000000 2607.00 2626.00 2548.00 2553.00 2104 5266 20160818 0.000000 2550.00 2561.00 2531.00 2545.00 404 5190 20160817 0.000000 2607.00 2626.00 2578.00 2601.00 1244 5438 20160819 0.000000 2549.00 2549.00 2525.00 2533.00 136 4538 20160819 0.000000 2549.00 2549.00 2520.00 2527.00 464 4394 20160819 0.000000 2549.00 2549.00 2520.00 2527.00 540 4350 20160819 0.000000 2549.00 2549.00 2519.00 2519.00 546 4350 20160819 0.000000 2549.00 2549.00 2519.00 2523.00 574 4348 20160819 0.000000 2549.00 2549.00 2519.00 2523.00 574 4348 20160819 0.000000 2549.00 2549.00 2485.00 2515.00 1274 4382 20160822 0.000000 2519.00 2521.00 2498.00 2509.00 208 4342 20160822 0.000000 2519.00 2522.00 2462.00 2480.00 1988 4280 20160823 0.000000 2475.00 2480.00 2465.00 2480.00 162 4210 20160823 0.000000 2475.00 2515.00 2465.00 2512.00 1054 3966 20160824 0.000000 2502.00 2515.00 2495.00 2498.00 160 3972 20160825 0.000000 2519.00 2537.00 2466.00 2486.00 732 3198 20160826 0.000000 2508.00 2509.00 2506.00 2508.00 8 3200 20160826 0.000000 2508.00 2521.00 2476.00 2476.00 844 3038 20160829 0.000000 2478.00 2478.00 2442.00 2453.00 94 3024 20160829 0.000000 2478.00 2478.00 2442.00 2468.00 388 2958 20160830 0.000000 2452.00 2484.00 2452.00 2469.00 102 2922 20160830 0.000000 2452.00 2484.00 2442.00 2442.00 308 2788 20160831 0.000000 2437.00 2452.00 2420.00 2425.00 92 2692 20160831 0.000000 2437.00 2452.00 2420.00 2425.00 92 2692 20160831 0.000000 2437.00 2452.00 2420.00 2425.00 92 2692 20160831 0.000000 2437.00 2452.00 2420.00 2425.00 92 2692 20160831 0.000000 2437.00 2452.00 2420.00 2424.00 154 2644 20160831 0.000000 2437.00 2452.00 2405.00 2424.00 210 2642 20160831 0.000000 2437.00 2452.00 2320.00 2325.00 550 2524 20160901 0.000000 2325.00 2415.00 2325.00 2415.00 64 2520 20160902 0.000000 2407.00 2407.00 2407.00 2407.00 120 2460
2.讓程序加載后默認打開這個rb1609_d1.txt文件
使用4個函數:
⑴窗體加載函數
1 private void FormCtp_Load(object sender, EventArgs e) 2 { 3 4 OpenChartFile(file); 5 6 this.MouseWheel += new MouseEventHandler(FormCtp_MouseWheel); 7 timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed); 8 timer.Enabled = true; 9 timer.AutoReset = true; //是否不斷重復定時器操作 10 11 12 }
⑵打開圖表函數,獲得合約名稱,同時調用讀取文件數據函數
1 private void OpenChartFile(string fileName) 2 { 3 this.textBox1.Focus(); 4 if (!String.IsNullOrEmpty(fileName)) 5 { 6 //獲取股票合約代碼名稱 7 int m1 = fileName.LastIndexOf(@"\"); 8 int m2 = fileName.LastIndexOf(@"_"); 9 int m3 = fileName.IndexOf(@".txt"); 10 pathCtp = file.Substring(0, file.LastIndexOf(@"\")); 11 // string[] subLines = pathCtp.Split('\\'); 12 stockName = fileName.Substring(m1 + 1, m2 - m1 - 1); 13 period = fileName.Substring(m2 + 1, m3 - m2 - 1); 14 label_symbol.Text = stockName + @" 周期: " + period; 15 file = fileName; 16 //MessageBox.Show(fileName); 17 DataStock = LoadCtpInfo(file);//讀取文件數據到listp 18 DataStock.Reverse();//反轉list容器上元素 19 xEnd = 0; 20 xBegin = Math.Min(xInitShowBars, DataStock.Count - 1); 21 xShowBars = xInitShowBars; 22 ReFreshMe(ref xBegin, ref xEnd, ref xShowBars, 0); 23 } 24 }
⑶讀取文件數據函數:
1 private List<StockInfo> LoadCtpInfo(string fileName) 2 { 3 //MessageBox.Show(fileName); 4 using (Stream resourceStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) 5 { 6 using (StreamReader reader = new StreamReader(resourceStream, Encoding.GetEncoding("GB2312"))) 7 { 8 //一次讀入所有行到一個string[] 9 var strings = reader.ReadToEnd().Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries); 10 textBox1.Text = strings.Length.ToString(); 11 //根據數據文件行數動態構建一個list 12 var res = new List<StockInfo>(strings.Length); 13 //List<Double> DataOpen = new List<Double>(strings.Length); 14 //List<Double> DataHigh = new List<Double>(strings.Length); 15 //List<Double> DataLow = new List<Double>(strings.Length); 16 //List<Double> DataClose = new List<Double>(strings.Length); 17 ////DataVolume = new List<Double>(strings.Length); 18 ////DataHold = new List<Double>(strings.Length); 19 //List<DateTime> DataTime = new List<DateTime>(strings.Length); 20 //List<int> Time = new List<int>(strings.Length); 21 22 //針對每一行文本按<StockInfo>結構添加成股票圖數據 23 for (int i = 0; i < strings.Length; i++) 24 { 25 //string line = strings[i]; 26 string[] subLines = strings[i].Split(new char[] { '\t' }, StringSplitOptions.RemoveEmptyEntries); 27 CtpInfo data = new CtpInfo(); 28 //對每一行文本按<StockInfo>結構進行數據轉換 29 CtpTxt2AmCharts(subLines, out data); 30 DateTime date = data.date; 31 Double open = data.open; 32 Double high = data.high; 33 Double low = data.low; 34 Double close = data.close; 35 Double volume = data.volume; 36 Double hold = data.hold; 37 //MessageBox.Show(DataOpen[i].ToString()); 38 //DataHigh.Add(high); 39 //DataLow.Add(low); 40 //DataClose.Add(close); 41 //DataOpen.Add(open); 42 //DataTime.Add(date); 43 //Time.Add(i); 44 res.Add( 45 new StockInfo 46 { 47 date = date, 48 open = open, 49 high = high, 50 low = low, 51 close = close, 52 volume = volume 53 }); 54 } 55 return res; 56 } 57 } 58 }
⑷對每一行文本按<StockInfo>結構進行數據轉換函數
1 void CtpTxt2AmCharts(string[] vitems, out CtpInfo data) 2 { 3 //vitems[0]=20160101; 4 data = new CtpInfo(); 5 data.open = Double.Parse(vitems[2].Trim()); 6 data.high = Double.Parse(vitems[3].Trim()); 7 data.low = Double.Parse(vitems[4].Trim()); 8 data.close = Double.Parse(vitems[5].Trim()); 9 data.volume = Double.Parse(vitems[6].Trim()); 10 data.hold = Double.Parse(vitems[7].Trim()); 11 int year = Int32.Parse(vitems[0].Trim().Substring(0, 4)); 12 int month = Int32.Parse(vitems[0].Trim().Substring(4, 2)); 13 int day = Int32.Parse(vitems[0].Trim().Substring(6, 2)); 14 //vitems[1]=0.121212; 15 16 int time = (int)(Double.Parse(vitems[1].Trim()) * 1000000); 17 int h = time / 10000; 18 // MessageBox.Show(vitems[1].Trim()); 19 int m = Int32.Parse(vitems[1].Trim().Substring(4, 2)); 20 // MessageBox.Show(vitems[1].Trim().Substring(4, 2)); 21 // MessageBox.Show(vitems[1].Trim().Substring(6, 2)); 22 int s = Int32.Parse(vitems[1].Trim().Substring(6, 2)); 23 DateTime date1 = new DateTime(year, month, day, h, m, s); 24 //DateTime date0 = new DateTime(1970, 1, 1, 0, 0, 0); 25 //System.TimeSpan timeSpan = date1 - date0; 26 //int timeSign = (int)timeSpan.TotalMinutes; 27 data.date = date1; 28 }
3.上述程序需要使用的一個數據結構文件
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 ///<數據結構文件> 6 ///stockinfo.cs 7 ///<> 8 9 namespace StockAnalyse 10 { 11 /// <summary> 12 /// 股票數據結構信息 13 /// </summary> 14 public class StockInfo 15 { 16 /// <summary> 17 /// 時間 18 /// </summary> 19 public DateTime date { get; set; } 20 21 /// <summary> 22 /// 開盤價 23 /// </summary> 24 public double open { get; set; } 25 /// <summary> 26 /// 最高價 27 /// </summary> 28 public double high { get; set; } 29 /// <summary> 30 /// 最低價 31 /// </summary> 32 public double low { get; set; } 33 /// <summary> 34 /// 收盤價 35 /// </summary> 36 public double close { get; set; } 37 38 /// <summary> 39 /// 成交量 40 /// </summary> 41 public double volume { get; set; } 42 } 43 /// <summary> 44 /// 商品合約列表結構信息 45 /// </summary> 46 public class QuotesInfo 47 { 48 ///////////////////////////// 49 /// 商品名稱 50 /////////////////////// 51 public string symbol { get; set; } 52 /// <summary> 53 /// 時間 54 /// </summary> 55 public DateTime date { get; set; } 56 public string time { get; set; } 57 /// <summary> 58 /// 開盤價 59 /// </summary> 60 public double open { get; set; } 61 /// <summary> 62 /// 最高價 63 /// </summary> 64 public double high { get; set; } 65 /// <summary> 66 /// 最低價 67 /// </summary> 68 public double low { get; set; } 69 /// <summary> 70 /// 收盤價 71 /// </summary> 72 public double close { get; set; } 73 74 /// <summary> 75 /// 成交量 76 /// </summary> 77 public double volume { get; set; } 78 } 79 /// <summary> 80 /// Ctp期貨數據結構 81 /// </summary> 82 public class CtpInfo 83 { 84 /// <summary> 85 /// 時間 86 /// </summary> 87 public DateTime date { get; set; } 88 89 /// <summary> 90 /// 開盤價 91 /// </summary> 92 public double open { get; set; } 93 /// <summary> 94 /// 最高價 95 /// </summary> 96 public double high { get; set; } 97 /// <summary> 98 /// 最低價 99 /// </summary> 100 public double low { get; set; } 101 /// <summary> 102 /// 收盤價 103 /// </summary> 104 public double close { get; set; } 105 106 /// <summary> 107 /// 成交量 108 /// </summary> 109 public double volume { get; set; } 110 /// <summary> 111 /// 持倉量 112 /// </summary> 113 public double hold { get; set; } 114 } 115 public enum TimeFrame { tick = 0, M1, M5, M15, M30, H1, D1, W1, Mn1, Y1 }; 116 117 }
限於篇幅,有關更多的窗口類的定義,將在下篇中說明.