/// <summary> /// 取消報價資訊訂閱 /// </summary> /// <param name="symbolId">商品代號</param> public override void RemoveSubscribe(string symbolId) { int iSerial = MitakeSymbolManager.ConvertToSerial(symbolId); if (iSerial > 0) { __cSubscribe.Remove(iSerial); __cSymbolIds.Add(symbolId); this.SendSubscribe(); } }
/// <summary> /// 更新商品代號資訊 /// </summary> public override void SymbolUpdate() { this.UpdateTime = DateTime.Today.AddDays(-2); //修改更新時間到兩天前(強迫更新) MitakeSymbolManager.Update(DateTime.UtcNow.AddHours(TIME_ZONE)); //更新所有商品資訊 LoadQuote cLoadQuote = new LoadQuote(); //請求所有股票代號表 cLoadQuote.InfoName = 0x38; this.Send(cLoadQuote); if (logger.IsInfoEnabled) logger.Info("[QuoteService.SymbolUpdate] Request symbol list..."); }
/// <summary> /// 新增報價資訊訂閱(可多商品訂閱) /// </summary> /// <param name="symbolList">商品代號列表</param> public override void AddSubscribe(List<string> symbolList) { bool bSubscribe = false; int iLength = symbolList.Count; for (int i = 0; i < iLength; i++) { int iSerial = MitakeSymbolManager.ConvertToSerial(symbolList[i]); if (iSerial > 0) { __cSubscribe.Add(iSerial); bSubscribe = true; } } if (bSubscribe) { this.SendSubscribe(); } }
/// <summary> /// 儲存即時報價服務的設定 /// </summary> public override void Save() { string sLocation = Assembly.GetExecutingAssembly().Location; string sPath = Path.GetDirectoryName(sLocation); string sTargetName = Path.GetFileNameWithoutExtension(sLocation) + ".set"; string sFileName = Path.Combine(sPath, sTargetName); this.UpdateTime = DateTime.Now; string sJSONSettings = JsonConvert.SerializeObject(this); string sJSONSymbolInfos = MitakeSymbolManager.Serialize(); int iStringCount = sJSONSettings.Length + sJSONSymbolInfos.Length; StringBuilder cBuilder = new StringBuilder(iStringCount + 128); cBuilder.AppendLine(sJSONSettings); cBuilder.AppendLine(sJSONSymbolInfos); File.WriteAllText(sFileName, cBuilder.ToString(), Encoding.UTF8); }
/// <summary> /// 重置並清除解碼後的所有資訊(只限於 TWSE 與 Mitake) /// </summary> /// <param name="date">設定日期(當天資料日期)</param> public static void Reset(DateTime date) { Time.SetToday(date); string sLocation = System.Reflection.Assembly.GetExecutingAssembly().Location; string sPath = Path.GetDirectoryName(sLocation); string sTargetName = Path.GetFileNameWithoutExtension(sLocation) + ".set"; string sFileName = Path.Combine(sPath, sTargetName); string[] sDatas = File.ReadAllLines(sFileName, Encoding.UTF8); MitakeSymbolManager.Deserialize(sDatas); MitakeSymbolManager.DataSource = "Mitake"; MitakeSymbolManager.ExchangeName = "TWSE"; MitakeSymbolManager.Update(date); MitakeStorage.Storage.Clear(); }
/// <summary> /// 讀取即時報價服務的設定 /// </summary> public override void Load() { string sLocation = Assembly.GetExecutingAssembly().Location; string sPath = Path.GetDirectoryName(sLocation); string sTargetName = Path.GetFileNameWithoutExtension(sLocation) + ".set"; string sFileName = Path.Combine(sPath, sTargetName); string[] sDatas = File.ReadAllLines(sFileName, Encoding.UTF8); JToken cQuoteService = JsonConvert.DeserializeObject<JToken>(sDatas[0]); this.DataSource = cQuoteService["DataSource"].Value<string>(); this.ExchangeName = cQuoteService["ExchangeName"].Value<string>(); this.IsDecode = cQuoteService["IsDecode"].Value<bool>(); this.Password = cQuoteService["Password"].Value<string>(); this.RemoteIP = cQuoteService["RemoteIP"].Value<string>(); this.RemotePort = cQuoteService["RemotePort"].Value<int>(); this.UpdateTime = cQuoteService["UpdateTime"].Value<DateTime>(); this.UserId = cQuoteService["UserId"].Value<string>(); MitakeSymbolManager.Deserialize(sDatas); }
/// <summary> /// 回補即時報價今天的所有歷史Tick /// </summary> /// <param name="symbolId">商品代號</param> public override void Complement(string symbolId) { int iSerial = MitakeSymbolManager.ConvertToSerial(symbolId); if (iSerial > 0) { switch (iSerial) { case 9998: //OTC上櫃指數 case 9999: //TWI加權指數 MitakeIndex cIndex = MitakeStorage.Storage.GetIndex(iSerial); cIndex.ComplementStatus = ComplementStatus.Complementing; break; default: MitakeQuote cQuote = MitakeStorage.Storage.GetQuote(iSerial); cQuote.ComplementStatus = ComplementStatus.Complementing; break; } Complement cComplement = new Complement(); cComplement.Serial = iSerial; this.Send(cComplement); } }
internal static void Decode(int serial, PacketBuffer buffer) { byte bSize = 0, bMark = 0, bFlag = 0, bTemp = 0; MitakeSymbolInformation cSymbolInfo = new MitakeSymbolInformation(); bSize = buffer.Data[3]; buffer.Position = 7; //移動至資料結構 //判斷股票別(如果為0 表示無此資料) bFlag = buffer[0]; //取得市場別(0=集中市場 1=上櫃 2=期貨 3=興櫃) cSymbolInfo.市場別 = BitConvert.GetValue(bFlag, 6, 2); //取得是否為警示股 bTemp = BitConvert.GetValue(bFlag, 5, 1); cSymbolInfo.警示 = ((bTemp == 1) ? true : false); //取得是否為下市股票(五個交易日後移除) bTemp = BitConvert.GetValue(bFlag, 4, 1); cSymbolInfo.市 = ((bTemp == 1) ? true : false); //取得市場分類(參閱解碼表代號) cSymbolInfo.市場分類 = BitConvert.GetValue(bFlag, 0, 4); ++buffer.Position; //取得股票代號(舊格式股票代號) cSymbolInfo.SymbolId = Encoding.UTF8.GetString(buffer.Data, buffer.Position, 5).Trim(); buffer.Position += 5; //取得股票名稱 cSymbolInfo.SymbolName = Encoding.UTF8.GetString(buffer.Data, buffer.Position, 9).Replace("\0", string.Empty); buffer.Position += 9; //期貨擴充(1:一般, 2:現月, 3:次月 PS:股票無使用) bMark = buffer[0]; cSymbolInfo.FutureMark = bMark; ++buffer.Position; string sSymbolId = string.Empty; if (cSymbolInfo.市場別 == 2) //判斷是否為期貨 { if (cSymbolInfo.市場分類 == 2) { //如果市場分類 == 2,則可能是選擇權(SID2 = 10Bytes) sSymbolId = Encoding.UTF8.GetString(buffer.Data, buffer.Position, 10).Trim('\0', ' '); buffer.Position += 10; } else { sSymbolId = Encoding.UTF8.GetString(buffer.Data, buffer.Position, 13).Trim('\0', ' '); buffer.Position += 13; } } else { //取得SID2 sSymbolId = Encoding.UTF8.GetString(buffer.Data, buffer.Position, 6).Trim('\0', ' '); buffer.Position += 6; //取得個股產業類別 cSymbolInfo.產業別 = Encoding.UTF8.GetString(buffer.Data, buffer.Position, 2); buffer.Position += 2; //取得個股證券類別 cSymbolInfo.證券別 = Encoding.UTF8.GetString(buffer.Data, buffer.Position, 2); buffer.Position += 2; } if (sSymbolId.Length > 0) { //轉換為標準台股商品代號格式 string[] sSymbolIds = MitakeSymbolManager.Convert(cSymbolInfo.SymbolId, sSymbolId, (cSymbolInfo.市場別 == 2) ? cSymbolInfo.市場分類 : 0); if (sSymbolIds != null) { cSymbolInfo.SymbolId = sSymbolIds[0]; if (!MitakeSymbolManager.IsExist(sSymbolIds[0])) { AddProductToExchange(cSymbolInfo, sSymbolIds[1]); //將股票代號更新至交易所內 } MitakeSymbolManager.AddQuoteSymbolInformation(serial, cSymbolInfo); //將基本資訊加入代號管理員內 } } }
private static void AddProductToExchange(MitakeSymbolInformation symbolInformation, string commodityId) { ESymbolCategory cCategory = ESymbolCategory.Stock; switch (symbolInformation.市場別) { case 0: //集中市場 case 1: //上櫃市場 string sType = ((symbolInformation.市場別 == 0) ? "TSE" : "OTC"); commodityId = string.Format("{0}_STOCK", sType); switch (symbolInformation.市場分類) { case 3: //基金 cCategory = ESymbolCategory.Spread; commodityId = string.Format("{0}_{1}", sType, "SPREAD"); break; case 4: //認股權證 cCategory = ESymbolCategory.Warrant; commodityId = string.Format("{0}_{1}", sType, "WARRANT"); break; case 9: //中央政府公債 cCategory = ESymbolCategory.Bond; commodityId = string.Format("{0}_{1}", sType, "BOND"); break; case 10: //富時指數(TW50) cCategory = ESymbolCategory.Index; commodityId = "INDEX"; break; } break; case 2: //期貨市場 switch (symbolInformation.市場分類) { case 1: //一般期貨 case 3: //期貨股票 cCategory = ESymbolCategory.Future; if (symbolInformation.市場分類 == 3) { commodityId = "STOCK_FUTURE"; } break; case 2: //選擇權 if (MitakeSymbolManager.IsIndexOption(commodityId)) { cCategory = ESymbolCategory.IndexOption; } else { cCategory = ESymbolCategory.StockOption; } break; } break; } if (commodityId == null) { commodityId = "UNKNOWN"; } string sExchangeName = MitakeSymbolManager.ExchangeName; AbstractExchange cExchange = ProductManager.Manager.GetExchange(sExchangeName); cExchange.AddProduct(new Product() { CommodityId = commodityId, Category = cCategory, SymbolId = symbolInformation.SymbolId, SymbolName = symbolInformation.SymbolName }); }