using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Intelligence;
using Package;
using System.Windows.Forms;


namespace QuoteComExample
{

    delegate void SetAddInfoCallBack(string text);
    public partial class Form1: Form {
        Intelligence.QuoteCom quoteCom;
        Dictionary<string, int> RecoverMap = new Dictionary<string, int>();
        private UTF8Encoding encoding = new System.Text.UTF8Encoding();
        public Form1() {
            InitializeComponent();
            quoteCom = new Intelligence.QuoteCom(cbQuoteHost.Text, 8000, tbSID.Text, tbToken.Text);
            quoteCom.OnRcvMessage += OnQuoteRcvMessage;
            quoteCom.OnGetStatus += OnQuoteGetStatus;
            quoteCom.OnRecoverStatus += OnRecoverStatus;
            quoteCom.OnRcvServerTime += OnRcvServerTime;   //接收主機時間
            this.Text = "QuoteCom 範例程式 [ Version : " + quoteCom.version + " ]";
            quoteCom.ForeginDepthSnapShop = false; 
        }

        private void btnConnect_Click(object sender, EventArgs e)
        {
            quoteCom.Connect(cbQuoteHost.Text, ushort.Parse(tbQuotePort.Text));
        }
        private void btnDiscnt_Click(object sender, EventArgs e)
        {
            quoteCom.Logout();
        }

        private void btnLogin_Click(object sender, EventArgs e)
        {
            string IDNO = tbID.Text;
            string PWD = tbPwd.Text;
            quoteCom.SourceId = tbSID.Text;
            char area = ' ';
            //if (rbArea1.Checked) area = 'K';
            //if (rbArea2.Checked) area = 'T';
            //參數area 已無作用, 請帶入空值即可

            quoteCom.Login(IDNO, PWD, area);

        }


        private void AddInfo(string msg) {
            if (this.txtMsg.InvokeRequired) {
                SetAddInfoCallBack d = new SetAddInfoCallBack(AddInfo);
                this.Invoke(d, new object[] { msg });
            } else {
                string fMsg = String.Format("[{0}] {1} {2}", DateTime.Now.ToString("hh:mm:ss:ffff"), msg, Environment.NewLine);
                try {
                    if (txtMsg.TextLength > 5000) txtMsg.ResetText(); 
                    txtMsg.AppendText(fMsg);

                } catch { };
            }
        }
        
        private void AddInfoCover( string msg) {
            if (this.txtRecover.InvokeRequired) {
                SetAddInfoCallBack d = new SetAddInfoCallBack(AddInfoCover);
                this.Invoke(d, new object[] { msg });
            }
            else {
                string fMsg = msg; 
                try {
                  //  if (txtRecover.TextLength > 5000) txtRecover.ResetText();
                    txtRecover.AppendText(fMsg);
                }
                catch { };
            }
        }

        #region QuoteCom API 事件
        private void OnRecoverStatus(object sender, string Topic, RECOVER_STATUS status, uint RecoverCount) {
            if (this.InvokeRequired) {
                OnRecover_EvenHandler d = new OnRecover_EvenHandler(OnRecoverStatus);
                this.Invoke(d, new object[] { sender, Topic, status,RecoverCount  });
                return;
            }
            QuoteCom com = (QuoteCom)sender;
            switch (status) {
                case RECOVER_STATUS.RS_DONE:        //回補資料結束
                    AddInfo(String.Format("結束回補 Topic:[{0}]{1}", Topic,RecoverCount));
                    break;
                case RECOVER_STATUS.RS_BEGIN:       //開始回補資料
                    AddInfo(String.Format("開始回補 Topic:[{0}]", Topic));
                    break;
            }
        }

        private void OnRcvServerTime(Object sender, DateTime serverTime) {
            if (this.InvokeRequired) {
                OnRcvServerTime_EventHandler d = new OnRcvServerTime_EventHandler(OnRcvServerTime);
                this.Invoke(d, new object[] { sender, serverTime });
                return;
            }
           // AddInfo("OnRcvServerTime:" + serverTime); 
        }
        private void OnQuoteGetStatus(object sender, COM_STATUS staus, byte[] msg) {
            QuoteCom com = (QuoteCom)sender;
            string smsg = ""; 
            switch (staus)
            {
                case COM_STATUS.LOGIN_READY:
                    AddInfo(String.Format("LOGIN_READY:[{0}]", encoding.GetString(msg)));
                    AddInfo(smsg);
                    break;
                case COM_STATUS.LOGIN_FAIL:
                    AddInfo(String.Format("LOGIN FAIL:[{0}]", encoding.GetString(msg)));
                    break;
                case COM_STATUS.LOGIN_UNKNOW:
                    AddInfo(String.Format("LOGIN UNKNOW:[{0}]", encoding.GetString(msg)));
                    break;
                case COM_STATUS.CONNECT_READY:
                    smsg = "QuoteCom: [" + encoding.GetString(msg) + "] MyIP=" + quoteCom.MyIP;
                    break;
                case COM_STATUS.CONNECT_FAIL:
                    smsg = encoding.GetString(msg);
                    AddInfo("CONNECT_FAIL:" + smsg);
                    break;
                case COM_STATUS.DISCONNECTED:
                    smsg = encoding.GetString(msg);
                    AddInfo("DISCONNECTED:" + smsg);
                    AddInfo("quoteCom.ComStatus = " + quoteCom.ComStatus); 
                    break;
                case COM_STATUS.SUBSCRIBE:
                    smsg = encoding.GetString(msg, 0, msg.Length - 1);
                    AddInfo(String.Format("SUBSCRIBE:[{0}]", smsg));
                    break;
                case COM_STATUS.UNSUBSCRIBE:
                    smsg = encoding.GetString(msg, 0, msg.Length - 1);
                    AddInfo(String.Format("UNSUBSCRIBE:[{0}]", smsg));
                    break;
                case COM_STATUS.ACK_REQUESTID:
                    long RequestId = BitConverter.ToInt64(msg, 0);
                    byte status = msg[8];
                    AddInfo("Request Id BACK: " + RequestId + " Status=" + status);
                    break;
                case COM_STATUS.RECOVER_DATA:
                    smsg = encoding.GetString(msg, 1, msg.Length - 1);
                    if (!RecoverMap.ContainsKey(smsg))
                        RecoverMap.Add(smsg, 0);

                    if (msg[0] == 0)
                    {
                        RecoverMap[smsg] = 0;
                        AddInfo(String.Format("開始回補 Topic:[{0}]", smsg));
                    }

                    if (msg[0] == 1)
                    {
                        AddInfo(String.Format("結束回補 Topic:[{0} 筆數:{1}]", smsg, RecoverMap[smsg]));
                    }
                    break;
            }
           com.Processed();
        }

        private void OnQuoteRcvMessage(object sender, PackageBase package) {
            if (package.TOPIC != null)
                if (RecoverMap.ContainsKey(package.TOPIC))
                    RecoverMap[package.TOPIC]++;


            StringBuilder sb;
            switch (package.DT) {
                case (ushort)DT.LOGIN: 
                    P001503 _p001503 = (P001503)package;
                    if (_p001503.Code == 0) 
                        AddInfo("可註冊檔數：" + _p001503.Qnum);
                    break;
                #region 公告 2014.12.12 ADD
                case (ushort)DT.NOTICE_RPT:
                    P001701 p1701 = (P001701)package;
                    AddInfo(p1701.ToLog());
                    break;    //公告(被動查詢) 
                case (ushort)DT.NOTICE:   //公告(主動)
                    P001702 p1702 = (P001702)package;
                    AddInfo(p1702.ToLog());
                    break;
                #endregion 
                
                case (ushort)DT.QUOTE_I020:
                case (ushort)DT.QUOTE_I022:  //2014.4.2. ADD 20022 盤前揭示
                    if (!cb020.Checked) return; 
                    PI20020 i20020 = (PI20020)package;
                    sb = new StringBuilder(Environment.NewLine);
                    sb.Append("DT:[" + i20020.DT + "]"); 
                    sb.Append("資料時間:").Append(i20020.MatchTime);
                    sb.Append("資料時間:").Append(String.Format("{0:000000000}", i20020.MatchTime));
                    sb.Append(i20020.MatchTime.ToString()); 
                    sb.Append("    Tick序號:").Append(i20020.InfoSeq).Append(Environment.NewLine);
                    sb.Append("最後封包:").Append(i20020.LastItem).Append(Environment.NewLine);
                    sb.Append("期貨/選擇權:").Append(i20020.Market).Append("  [").Append(i20020.Symbol).Append("]").Append(Environment.NewLine);
                    sb.Append("成交 [價:").Append(i20020.Price).Append("   量:").Append(i20020.MatchQuantity).Append("]").Append(Environment.NewLine);
                    sb.Append("累計成交  [量:").Append(i20020.MatchTotalQty).Append("  買筆數:")
                        .Append(i20020.MatchBuyCnt).Append("  賣筆數:")
                        .Append(i20020.MatchSellCnt).Append("]").Append(Environment.NewLine);
                    sb.Append("=============================");
                    if (i20020.DT == 20020) AddInfo(sb.ToString());
                    else AddInfoCover(i20020.ToLog());//AddInfoCover(sb.ToString()); 
                    
                    break;
                case (ushort)DT.QUOTE_I020_RECOVER:   //I20 行情回補
                    if (!cb020.Checked) return; 
                    PI20020 i21020 = (PI20020)package;
                    sb = new StringBuilder(Environment.NewLine);
                    sb.Append("===I020 資料回補 =====").Append(Environment.NewLine); 
                    sb.Append("資料時間:").Append(String.Format("{0:00:00:00\\.00}", i21020.MatchTime));
                    sb.Append("    Tick序號:").Append(i21020.InfoSeq).Append(Environment.NewLine);
                    sb.Append("最後封包:").Append(i21020.LastItem).Append(Environment.NewLine);
                    sb.Append("期貨/選擇權:").Append(i21020.Market).Append("  [").Append(i21020.Symbol).Append("]").Append(Environment.NewLine);
                    sb.Append("成交 [價:").Append(i21020.Price).Append("   量:").Append(i21020.MatchQuantity).Append("]").Append(Environment.NewLine);
                    sb.Append("累計成交  [量:").Append(i21020.MatchTotalQty).Append("  買筆數:")
                        .Append(i21020.MatchBuyCnt).Append("  賣筆數:")
                        .Append(i21020.MatchSellCnt).Append("]").Append(Environment.NewLine);
                    AddInfoCover(i21020.ToLog());
                    break;
                case (ushort)DT.QUOTE_I060:   //2015.9.8 Add: 現貨標的 (人民幣 RTF$)
                    PI20060 i20060 = (PI20060)package;
                    sb = new StringBuilder();
                    sb.Append("******DataType:").Append(i20060.DT).Append("********").Append(Environment.NewLine)
                        .Append("商品代碼").Append(i20060.Symbol).Append("資料時間:")
                        .Append(String.Format("{0:00:00:00\\.00}", i20060.MatchTime))
                        .Append("成交價:").Append(i20060.MatchPrice )
                        .Append("買價:").Append(i20060.BidPrice)
                        .Append("賣價:").Append(i20060.AskPrice)
                        .Append("定盤價:").Append(i20060.FixPrice)
                        .Append("參考價:").Append(i20060.RefPrice)
                        .Append(Environment.NewLine);
                    AddInfo(sb.ToString());
                    break;
                case (ushort)DT.QUOTE_I021: //盤中最高(低)價揭示
                    PI20021 i20021 = (PI20021)package;
                    sb = new StringBuilder(Environment.NewLine);
                    sb.Append("******DataType:").Append(i20021.DT).Append("********");
                    sb.Append("資料時間:").Append(String.Format("{0:00:00:00\\.00}", i20021.MatchTime));
                    sb.Append("當日最高成交價格:").Append(i20021.DayHighPrice).Append("當日最低成交價格:").Append(i20021.DayLowPrice).Append(Environment.NewLine);
                    AddInfo(sb.ToString());
                    break;
                case (ushort)DT.QUOTE_I023: //定時開盤價量揭示
                    PI20023 i20023 = (PI20023)package;
                    sb = new StringBuilder(Environment.NewLine);
                    sb.Append("**********DataType:").Append(i20023.DT).Append("**********");
                    AddInfo(sb.ToString());
                    break;
                case (ushort)DT.QUOTE_I030:  //(單一商品委託量累計)
                    PI20030 i20030 = (PI20030)package;
                    //AddInfo(i20030.ToLog());
                    //2018.6.28 Lynn TestAddInfoCover(i20030.ToLog());
                    break;
                case (ushort)DT.QUOTE_BASE_P08:   //商品檔 :  RetriveQuoteList() :大量商品封包傳輸可能會造成斷線;不建議使用:
                    /*PI20008 pi20008 = (PI20008)package;
                    if (pi20008.Market == 'F') break; 
                    sb = new StringBuilder();
                    sb.Append("商品:").Append(pi20008.Symbol).Append(" 價格小數位:").Append(pi20008.PriceDecimal).Append(" 履約價格小數位:").Append(pi20008.StrikePriceDecimal);
                    AddInfo(sb.ToString());

                    sb = new StringBuilder(Environment.NewLine);
                    sb.Append("期貨/選擇權:").Append(pi20008.Market).Append(Environment.NewLine);
                    sb.Append("商品代號:").Append(pi20008.Symbol).Append(Environment.NewLine);
                    sb.Append("商品IDX:").Append(pi20008.SymbolIdx).Append(Environment.NewLine);
                    sb.Append("第一漲停價:").Append(pi20008._RISE_LIMIT_PRICE1).Append(Environment.NewLine);
                    sb.Append("參考價:").Append(pi20008._REFERENCE_PRICE).Append(Environment.NewLine);
                    sb.Append("第一漲停價:").Append(pi20008._RISE_LIMIT_PRICE1).Append(Environment.NewLine);
                    sb.Append("第二漲停價:").Append(pi20008._RISE_LIMIT_PRICE2).Append(Environment.NewLine);
                    sb.Append("第二跌停價:").Append(pi20008._FALL_LIMIT_PRICE2).Append(Environment.NewLine);
                    sb.Append("第三漲停價:").Append(pi20008._RISE_LIMIT_PRICE3).Append(Environment.NewLine);
                    sb.Append("第三跌停價:").Append(pi20008._FALL_LIMIT_PRICE3).Append(Environment.NewLine);
                    sb.Append("契約種類:").Append(pi20008._PROD_KIND).Append(Environment.NewLine);
                    sb.Append("價格欄位小數位數:").Append(pi20008.PriceDecimal).Append(Environment.NewLine);
                    sb.Append("商品名稱:").Append(pi20008._PROD_NAME).Append(Environment.NewLine);
                     sb.Append("下市日期:").Append(pi20008.END_DATE).Append(Environment.NewLine);
                    sb.Append("=================================");
                    AddInfo(sb.ToString());
                    */
                    break;
                case (ushort)DT.QUOTE_CLOSE_I070:  //收盤:  RetriveClosePrice() 
                    
                    PI20070 pb = (PI20070)package;
                    sb = new StringBuilder();
                    sb.Append("期貨/選擇權:").Append(pb.MESSAGE_KIND).Append(Environment.NewLine);
                    sb.Append("商品代號:").Append(pb.PROD_ID).Append(Environment.NewLine);
                    sb.Append("該期最高價:").Append(pb.TERM_HIGH_PRICE).Append(Environment.NewLine);
                    sb.Append("該期最低價:").Append(pb.TERM_LOW_PRICE).Append(Environment.NewLine);
                    sb.Append("該日最高價:").Append(pb.DAY_HIGH_PRICE).Append(Environment.NewLine);
                    sb.Append("該日最低價:").Append(pb.DAY_LOW_PRICE).Append(Environment.NewLine);
                    sb.Append("開盤價:").Append(pb.OPEN_PRICE).Append(Environment.NewLine);
                    sb.Append("最後買價:").Append(pb.BUY_PRICE).Append(Environment.NewLine);
                    sb.Append("最後賣價:").Append(pb.SELL_PRICE).Append(Environment.NewLine);
                    sb.Append("收盤價:").Append(pb.CLOSE_PRICE).Append(Environment.NewLine);
                    sb.Append("委託買進總筆數:").Append(pb.BO_COUNT_TAL).Append(Environment.NewLine);
                    sb.Append("委託買進總口數:").Append(pb.BO_QNTY_TAL).Append(Environment.NewLine);
                    sb.Append("委託賣出總筆數:").Append(pb.SO_COUNT_TAL).Append(Environment.NewLine);
                    sb.Append("委託賣出總口數:").Append(pb.SO_QNTY_TAL).Append(Environment.NewLine);
                    sb.Append("總成交筆數:").Append(pb.TOTAL_COUNT).Append(Environment.NewLine);
                    sb.Append("總成交量:").Append(pb.TOTAL_QNTY).Append(Environment.NewLine);
                    sb.Append("合併委託買進總筆數:").Append(pb.COMBINE_BO_COUNT_TAL).Append(Environment.NewLine);
                    sb.Append("合併委託買進總口數:").Append(pb.COMBINE_BO_QNTY_TAL).Append(Environment.NewLine);
                    sb.Append("合併委託賣出總筆數:").Append(pb.COMBINE_SO_COUNT_TAL).Append(Environment.NewLine);
                    sb.Append("合併委託賣出總口數:").Append(pb.COMBINE_SO_QNTY_TAL).Append(Environment.NewLine);
                    sb.Append("合併總成交量:").Append(pb.COMBINE_TOTAL_QNTY).Append(Environment.NewLine);
                    sb.Append("價格欄位小數點:").Append(pb.DECIMAL_LOCATOR).Append(Environment.NewLine);
                    sb.Append("=================");
                    AddInfo(sb.ToString());
                     
                    break;
                case (ushort)DT.QUOTE_I080:
                case (ushort)DT.QUOTE_I082: //case (ushort)DT.QUOTE_I082:   //2014.4.2 ADD 盤前揭示
                    if (!cb080.Checked) return; 
                    PI20080 i20080 = (PI20080)package;
                    sb = new StringBuilder(Environment.NewLine);
                    sb.Append("DT:[" + i20080.DT + "]"); 
                    sb.Append("商品代號:").Append(i20080.Symbol).Append(Environment.NewLine);
                    for (int i = 0; i < 5; i++)
                        sb.Append(String.Format("五檔[{0}] 買[價:{1:N} 量:{2:N}]    賣[價:{3:N} 量:{4:N}]", i + 1, i20080.BUY_DEPTH[i].PRICE, i20080.BUY_DEPTH[i].QUANTITY, i20080.SELL_DEPTH[i].PRICE, i20080.SELL_DEPTH[i].QUANTITY)).Append(Environment.NewLine);
                    sb.AppendLine("衍生委託第一檔買進價格:" + i20080.FIRST_DERIVED_BUY_PRICE);
                    sb.AppendLine("衍生委託第一檔買進數量:" + i20080.FIRST_DERIVED_BUY_QTY);
                    sb.AppendLine("衍生委託第一檔賣出價格:" + i20080.FIRST_DERIVED_SELL_PRICE);
                    sb.AppendLine("衍生委託第一檔賣出數量" + i20080.FIRST_DERIVED_SELL_QTY);
                    sb.AppendLine("資料時間" + i20080.DATA_TIME);
                    sb.AppendLine("小數位位:" + i20080.PriceDecimal); 
                    sb.Append("==============================");
                    //AddInfo(sb.ToString());
                    if (i20080.DT == 20080) AddInfo(sb.ToString());
                    else AddInfoCover(i20080.ToLog() ); //AddInfoCover(sb.ToString()); 
                    break;
                case (ushort)DT.QUOTE_I080_RECOVER :  //I080回補
                    if (!cb080.Checked) return; 
                    PI20080 i21080 = (PI20080)package;
                    sb = new StringBuilder(Environment.NewLine);
                    sb.Append("==I080 回補資料 ===");
                    sb.Append("商品代號:").Append(i21080.Symbol).Append(Environment.NewLine);
                    for (int i = 0; i < 5; i++)
                        sb.Append(String.Format("五檔[{0}] 買[價:{1:N} 量:{2:N}]    賣[價:{3:N} 量:{4:N}]", i + 1, i21080.BUY_DEPTH[i].PRICE, i21080.BUY_DEPTH[i].QUANTITY, i21080.SELL_DEPTH[i].PRICE, i21080.SELL_DEPTH[i].QUANTITY)).Append(Environment.NewLine);
                    sb.AppendLine("衍生委託第一檔買進價格:" + i21080.FIRST_DERIVED_BUY_PRICE);
                    sb.AppendLine("衍生委託第一檔買進數量:" + i21080.FIRST_DERIVED_BUY_QTY);
                    sb.AppendLine("衍生委託第一檔賣出價格:" + i21080.FIRST_DERIVED_SELL_PRICE);
                    sb.AppendLine("衍生委託第一檔賣出數量" + i21080.FIRST_DERIVED_SELL_QTY);
                    sb.AppendLine("資料時間" + i21080.DATA_TIME);
                    AddInfoCover(sb.ToString());
                    
                    break;
                case (ushort)DT.QUOTE_LAST_PRICE:   // 最後價格: RetriveLastPrice() 
                    PI20026 pi20026 = (PI20026)package;
                    sb = new StringBuilder(Environment.NewLine);
                    sb.Append("商品代號:").Append(pi20026.Symbol).Append(" 最後價格:").Append(pi20026.MatchPrice).Append(Environment.NewLine);
                    sb.Append("當日最高成交價格:").Append(pi20026.DayHighPrice).Append(" 當日最低成交價格:").Append(pi20026.DayLowPrice);
                    sb.Append("開盤價:").Append(pi20026.FirstMatchPrice ).Append(" 開盤量:").Append(pi20026.FirstMatchQty).Append(Environment.NewLine);
                    sb.Append("參考價:").Append(pi20026.ReferencePrice).Append("累計成交量:").Append(pi20026.MatchTotalQty)
                        .Append("盤別:").Append(pi20026.Session)
                        .Append(" 交易暫停否:").Append (pi20026.Break_Mark).Append(Environment.NewLine);
                    //2016.5  20026 封包 新增4欄位(衍生第一檔)
                    sb.Append("衍生委託第一檔買進價格:").Append(pi20026.FirstDerivedBuyPrice).Append(Environment.NewLine)
                       .Append("衍生委託第一檔買進數量:").Append(pi20026.FirstDerivedBuyQty).Append(Environment.NewLine)
                       .Append("衍生委託第一檔賣出價格:").Append(pi20026.FirstDerivedSellPrice).Append(Environment.NewLine)
                       .Append("衍生委託第一檔賣出數量:").Append(pi20026.FirstDerivedSellQty).Append(Environment.NewLine); 

                    for (int i = 0; i < 5; i++)
                        sb.Append(String.Format("五檔[{0}] 買[價:{1:N} 量:{2:N}]    賣[價:{3:N} 量:{4:N}]", i + 1, pi20026.BUY_DEPTH[i].PRICE, pi20026.BUY_DEPTH[i].QUANTITY, pi20026.SELL_DEPTH[i].PRICE, pi20026.SELL_DEPTH[i].QUANTITY)).Append(Environment.NewLine);
                    //2020.10.26 Lynn Add:盤中漲跌停價格
                    sb.Append("漲停價格階段:").Append(pi20026.Rise_Level).Append("漲停價格:").Append(pi20026.RiseStopPrice).Append(Environment.NewLine);
                    sb.Append("跌停價格階段:").Append(pi20026.Fall_Level).Append("跌停價格:").Append(pi20026.FallStopPrice).Append(Environment.NewLine); 
                    sb.Append("==========================");
                    AddInfo(sb.ToString());
                    break;
                case (ushort)DT.QUOTE_I101: //2020.10.26 Lynn Add:盤中漲跌停異動通知
                    PI20101 pi20101 = (PI20101)package;
                    AddInfo(pi20101.ToLog()); 
                    sb = new StringBuilder();
                    sb.Append("漲跌停異動通知: "); 
                    sb.Append(pi20101.ToLog());
                    sb.Append("==========================");
                    AddInfo(sb.ToString()); 
                    break; 
                case (ushort)DT.QUOTE_INFO :
                    PI20140 pi20140 = (PI20140)package;
                    sb = new StringBuilder(Environment.NewLine);
                    sb.Append("F/O :").Append(pi20140.Market).Append(" kind:").Append(pi20140.Kind).Append(" Reason:").Append(pi20140.Reason);
                    sb.Append(" Status:").Append(pi20140.Status).Append(" Count:").Append(pi20140.Count);
                    for (int i = 0; i < pi20140.Count; i++)
                        sb.Append(pi20140.Symbols[i]).Append(","); 
                    AddInfo(sb.ToString()); 
                    break; 
                case (ushort)DT.QUOTE_SESSION : //2017.4.10 Lynn Add: 盤別 FOR 盤後新制
                    PI05005 pi5005 = (PI05005)package;
                     sb = new StringBuilder(Environment.NewLine);
                     sb.Append("F/O :").Append(pi5005.Market).Append(" Symbol:").Append(pi5005.Symbol).Append(" FallLimitPrice:").Append(pi5005.FallLimitPrice);
                     sb.Append(" RiseLimitPrice:").Append(pi5005.RiseLimitPrice).Append(" RefPrice:").Append(pi5005.RefPrice)
                         .Append(" Session:").Append(pi5005.Session).Append(" Status:").Append(pi5005.Status);
                    AddInfo( sb.ToString()) ; 
                    break; 
                case (ushort)DT.QUOTE_FOREIGN_MATCH:
                    if (cb40020.Checked) {
                        PI40020 pi40020 = (PI40020)package;
                        sb = new StringBuilder(Environment.NewLine);
                        sb.Append("[40020]交易所:").Append(pi40020.ExchangeNm);
                        sb.Append(" 商品代號:").Append(pi40020.Symbol).Append(" 類別:").Append(pi40020.ComType);
                        sb.Append(" 盤別:").Append(pi40020.Session).Append(Environment.NewLine);
                        sb.Append(" 成交時間:").Append(pi40020.TradeTime).Append(" 價格:").Append(pi40020.Price).Append(" 口數:").Append(pi40020.Quantity).Append(Environment.NewLine);
                        sb.Append(" 總量:").Append(pi40020.TotalQty);
                        AddInfo(sb.ToString());
                    }
                    break;
                case (ushort)DT.QUOTE_FOREIGN_TOTALQTY : 
                    if (cb40020.Checked)
                    {
                        PI40023 pi40023 = (PI40023)package;
                        sb = new StringBuilder(Environment.NewLine);
                        sb.Append("[40020]交易所:").Append(pi40023.ExchangeNm);
                        sb.Append(" 商品代號:").Append(pi40023.Symbol).Append(" 類別:").Append(pi40023.ComType);
                        sb.Append(" 盤別:").Append(pi40023.Session).Append(Environment.NewLine);
                        sb.Append(" 總量:").Append(pi40023.TotalQty);
                        AddInfo(sb.ToString());
                    }
                    break;
                case (ushort)DT.QUOTE_FOREIGN_CLOSEINFO :
                    PI40021 pi40021 = (PI40021)package;
                    sb = new StringBuilder(Environment.NewLine);
                    sb.Append("[40021]交易所:").Append(pi40021.ExchangeNm);
                    sb.Append(" 商品代號:").Append(pi40021.Symbol).Append(" 類別:").Append(pi40021.ComType);
                    sb.Append(" 盤別:").Append(pi40021.Session).Append(Environment.NewLine);
                    sb.Append(" 收盤價:").Append(pi40021.ClosePrice).Append(" 收盤量:").Append(pi40021.CloseQty).Append(Environment.NewLine);
                    AddInfo(sb.ToString());
                    AddInfoCover(sb.ToString()); 
                    break;
                case (ushort)DT.QUOTE_FOREIGN_SETTLEMENTPRICE:
                    PI40022 pi40022 = (PI40022)package;
                    sb = new StringBuilder(Environment.NewLine);
                    sb.Append("[40022]交易所:").Append(pi40022.ExchangeNm);
                    sb.Append(" 商品代號:").Append(pi40022.Symbol).Append(" 類別:").Append(pi40022.ComType);
                    sb.Append(" 盤別:").Append(pi40022.Session);
                    sb.Append(" 結算價:").Append(pi40022.SettlementPrice).Append(Environment.NewLine); 
                    AddInfo(sb.ToString());
                    AddInfoCover(sb.ToString());
                    break;
                case (ushort)DT.QUOTE_FOREIGN_DEPTH:
                    PI40080 pi40080 = (PI40080)package;
                    if (cb40080.Checked) {
                        sb = new StringBuilder(Environment.NewLine);
                        sb.Append("[40080]交易所:").Append(pi40080.ExchangeNm).Append(" 來源:").Append(pi40080.Source);
                        sb.Append("商品代號:").Append(pi40080.Symbol).Append(" 類別:").Append(pi40080.ComType);
                        sb.Append(" 盤別:").Append(pi40080.Session).Append(" 買賣別:").Append(pi40080.Side).Append(Environment.NewLine);
                        sb.Append(" 頂端價:").Append(pi40080.TopMark).Append(" 價格:").Append(pi40080.Price);
                        sb.Append(" 口數:").Append(pi40080.Quantity).Append("檔位:").Append(pi40080.Position).Append(Environment.NewLine);
                        AddInfo(sb.ToString());
                    }
                    break;

                case (ushort)DT.QUOTE_FOREIGN_LASTPRICE:
                    PI40026 pi40026 = (PI40026)package;
                    sb = new StringBuilder(Environment.NewLine);
                    sb.Append("[40026]交易所:").Append(pi40026.ExchangeNm).Append(" 類別:").Append(pi40026.ComType).Append(" 盤別:").Append(pi40026.Session).Append(" 盤別狀態:").Append(pi40026.Status);
                    sb.Append("商品代號:").Append(pi40026.Symbol).Append(Environment.NewLine);
                    sb.Append(" 參考價:").Append(pi40026.ReferencePrice).Append(" 昨日成交量:").Append(pi40026.YesterdayQty).Append(Environment.NewLine);
                    sb.Append(" 當日最高價:").Append(pi40026.DayHighPrice).Append("當日最低價:").Append(pi40026.DayLowPrice).Append(Environment.NewLine);
                    sb.Append(" 開盤價:").Append(pi40026.OpenPrice).Append(" 開盤量:").Append(pi40026.OpenQty).Append(Environment.NewLine);
                    sb.Append(" 最新成交價:").Append(pi40026.LastPrice).Append(" 最新成交量:").Append(pi40026.LastQty).Append(" 當日成交量:").Append(pi40026.DayTradeQty).Append(Environment.NewLine); 
                   sb.Append("盤別狀態:").Append(pi40026.Status).Append(Environment.NewLine);
                    sb.Append("昨日收盤價:").Append(pi40026.ClosePrice ).Append(Environment.NewLine);   //2020.8.10 Add
                    sb.Append("買方檔數:" + pi40026.BuyDepthCount).Append(Environment.NewLine); 
                    for (int i = 0; i < pi40026.BuyDepthCount; i++)
                        sb.Append("價格:").Append(pi40026.BUY_DEPTH[i].PRICE).Append("數量:").Append(pi40026.BUY_DEPTH[i].QUANTITY).Append(Environment.NewLine) ;
                    sb.Append("賣方檔數:" + pi40026.SellDepthCount).Append(Environment.NewLine); 
                    for (int i = 0; i < pi40026.SellDepthCount; i++)
                        sb.Append("價格:").Append(pi40026.SELL_DEPTH[i].PRICE).Append("數量:").Append(pi40026.SELL_DEPTH[i].QUANTITY).Append(Environment.NewLine) ;
                    sb.Append("==========================");
                    AddInfo(sb.ToString());
                    break;
                //2015.12 Add: 現貨指數
                case (ushort)DT.QUOTE_FOREIGN_INDEX :
                        PI40060 pi40060 = (PI40060)package;
                        sb = new StringBuilder(Environment.NewLine);
                        sb.Append("[40060]交易所:").Append(pi40060.ExchangeNm);
                        sb.Append(" 商品代號:").Append(pi40060.Symbol).Append(" 類別:").Append(pi40060.ComType);
                        sb.Append(" 盤別:").Append(pi40060.Session).Append(Environment.NewLine);
                        sb.Append(" 成交時間:").Append(pi40060.TradeTime).Append(" 價格:").Append(pi40060.LastPrice).Append(Environment.NewLine);
                        AddInfo(sb.ToString());
                    break;
                //2023.4.24: LME OffBid / OffASK 特殊報價
                case (ushort)DT.QUOTE_FOREIGN_OBA:
                    PI40062 pi40062 = (PI40062)package;
                    sb = new StringBuilder(Environment.NewLine);
                    sb.Append("[40062]交易所:").Append(pi40062.ExchangeNm);
                    sb.Append(" 商品代號:").Append(pi40062.Symbol).Append(" 類別:").Append(pi40062.ComType);
                    sb.Append(" 盤別:").Append(pi40062.Session).Append(Environment.NewLine);
                    sb.Append(" 查詢時間:").Append(pi40062.TradeTime).Append(" OffBID:").Append(pi40062.OffBID);
                    sb.Append(" OffASK:").Append(pi40062.OffASK).Append(Environment.NewLine);
                    AddInfo(sb.ToString());
                    break;
                //2018.7.25 : (I90)  台灣期貨交易所編制指數資訊揭示訊息
                case (ushort)DT.QUOTE_I090 :
                    PI20090 pi20090 = (PI20090)package;
                    sb = new StringBuilder(Environment.NewLine);
                    sb.Append("[20090]").Append(pi20090.Market).Append("IndexID=").Append(pi20090.IndexID);
                    sb.Append(" IndexTime=").Append(pi20090.IndexTime).Append(" IndexPrice=").Append(pi20090.IndexPrice);
                    AddInfo(sb.ToString());
                    break;
                #region 2019.12.1 逐筆 五檔 , 成交
                case (ushort)DT.QUOTE_I081:
                    if (!cb081.Checked) return;
                    PI20081 i20081 = (PI20081)package;
                    AddInfo(i20081.ToLog() + Environment.NewLine);
                    break;
                case (ushort)DT.QUOTE_I024:
                    if (!cb081.Checked) return;
                    PI20024 i20024 = (PI20024)package;
                    AddInfo(i20024.ToLog() + Environment.NewLine);
                    break;
                #endregion 
                //2021.3.19 40090 測試
                case 40090 : 
                    if (!cb080.Checked) return; 
                    PI40090 i40090 = (PI40090)package;
                    sb = new StringBuilder(Environment.NewLine);
                    sb.Append("DT:[" + i40090.DT + "]");
                    sb.Append("商品代號:").Append(i40090.Symbol);
                    sb.Append(" 買[").Append(i40090.BidCount).Append("]檔  賣[").Append(i40090.AskCount).Append("]檔").Append(Environment.NewLine);
                    for (int i = 0; i < i40090.BidCount; i++)
                        sb.Append(String.Format("N檔[{0}] 買[價:{1:N} 量:{2:N}]", i + 1, i40090.BUY_DEPTH[i].PRICE, i40090.BUY_DEPTH[i].QUANTITY)).Append(Environment.NewLine);
                    for (int i = 0; i < i40090.AskCount; i++)
                        sb.Append(String.Format("N檔[{0}] 賣[價:{1:N} 量:{2:N}]", i + 1, i40090.SELL_DEPTH[i].PRICE, i40090.SELL_DEPTH[i].QUANTITY)).Append(Environment.NewLine); 
                    sb.Append("==============================");
                    AddInfo(sb.ToString());
                    break;
            }
        }


        #endregion

        
        private void btnQuoteList_Click(object sender, EventArgs e) {
            short istatus = quoteCom.RetriveQuoteList();
            if (istatus < 0)
                AddInfo(quoteCom.GetSubQuoteMsg(istatus)); 
        }

        private void btnCloseP_Click(object sender, EventArgs e) {
            short istatus = quoteCom.RetriveClosePrice();
            if (istatus < 0)
                AddInfo(quoteCom.GetSubQuoteMsg(istatus)); 
        }

        private void btnProdBase_Click(object sender, EventArgs e) {
            PI20008 pb = quoteCom.GetProdcutBase(textBox1.Text);
            if (pb != null) {
                StringBuilder sb = new StringBuilder();
                sb.Append("期貨/選擇權:").Append(pb.Market).Append(Environment.NewLine);
                sb.Append("可註冊商品代號:").Append(pb.Symbol).Append(Environment.NewLine);
                sb.Append("商品序號:").Append(pb.SymbolIdx).Append(Environment.NewLine);
                sb.Append("價格欄位小數位數:").Append(pb.PriceDecimal).Append(Environment.NewLine);
                //sb.Append("選擇權履約價格小數位數:").Append(pb.StrikePrice_Decimal).Append(Environment.NewLine);
                sb.Append("第一漲停價:").Append(pb._RISE_LIMIT_PRICE1).Append(Environment.NewLine);
                sb.Append("參考價:").Append(pb._REFERENCE_PRICE).Append(Environment.NewLine);
                sb.Append("第一跌停價:").Append(pb._FALL_LIMIT_PRICE1).Append(Environment.NewLine);
                sb.Append("第二漲停價:").Append(pb._RISE_LIMIT_PRICE2).Append(Environment.NewLine);
                sb.Append("第二跌停價:").Append(pb._FALL_LIMIT_PRICE2).Append(Environment.NewLine);
                sb.Append("第三漲停價:").Append(pb._RISE_LIMIT_PRICE3).Append(Environment.NewLine);
                sb.Append("第三跌停價:").Append(pb._FALL_LIMIT_PRICE3).Append(Environment.NewLine);
                sb.Append("商品名稱:").Append(pb._PROD_NAME).Append(Environment.NewLine);
                sb.Append("下市日期:").Append(pb.END_DATE).Append(Environment.NewLine);
                sb.Append("=========================================");
                AddInfo(sb.ToString());
            }
        }

        private void btnLastP_Click(object sender, EventArgs e) {
            short istatus = quoteCom.RetriveLastPrice(textBox3.Text);
            if (istatus < 0)   //
                AddInfo(quoteCom.GetSubQuoteMsg(istatus)); 

        }

        private void button9_Click(object sender, EventArgs e) {
            short istatus = quoteCom.SubQuote(txtQuoteId.Text);
            if (istatus < 0)   //
                AddInfo(quoteCom.GetSubQuoteMsg(istatus)); 
        }

        private void button10_Click(object sender, EventArgs e) {
            quoteCom.UnsubQuote(txtQuoteId.Text);
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e) {
            quoteCom.Dispose();
        }

        private void BtnOneStep_Click(object sender, EventArgs e) {
            //string Host, ushort Port, string id, string pwd, char center, string MultiQuoteId

            string host = cbQuoteHost.Text;
            ushort port = ushort.Parse(tbQuotePort.Text);
            string id = tbID.Text;
            string pwd = tbPwd.Text;
            char area = ' ';
            //不再區分 area , 請帶入空值即可
            //if (rbArea1.Checked) area = 'K';
            //if (rbArea2.Checked) area = 'T';
            string QuotedList = tbQuotes.Text; 
            quoteCom.SourceId = tbSID.Text;
            quoteCom.Connect2Quote(host,port,id,pwd,area,QuotedList);
          
        }

        private void btnSubQuotes_Click(object sender, EventArgs e) {
            short istatus = quoteCom.SubQuotes(tbQutoeA.Text);
            if (istatus < 0 ) 
                AddInfo(quoteCom.GetSubQuoteMsg(istatus)) ; 
        }

        private void btnUnSubQuotes_Click(object sender, EventArgs e) {
            quoteCom.UnsubQuotes(tbQutoeA.Text);
        }

        private void btnRecover_Click(object sender, EventArgs e) {
            short istatus = quoteCom.RetriveRecover(txtRecID.Text, txtStartTime.Text,txtEndTime.Text );
           // quoteCom.RetriveRecover(txtRecID.Text, "0902", "0902");
           // quoteCom.RetriveRecover(txtRecID.Text, "0902", "0903"); 
            if (istatus < 0)
                AddInfo(quoteCom.GetSubQuoteMsg(istatus)); 
            
        }
        private MARKET_EXCHANGE getexchange(string exchange) {
            MARKET_EXCHANGE me = MARKET_EXCHANGE.ME_SGX;
            switch (exchange) {
                case "SGX": me = MARKET_EXCHANGE.ME_SGX; break;
                case "HKEX": me = MARKET_EXCHANGE.ME_HK; break;
                case "HK": me = MARKET_EXCHANGE.ME_HK; break;
                case "CME": me = MARKET_EXCHANGE.ME_CME; break;
                case "CBOT": me = MARKET_EXCHANGE.ME_CBOT; break;
                case "EURX": me = MARKET_EXCHANGE.ME_EUREX; break;
                case "EUREX": me = MARKET_EXCHANGE.ME_EUREX; break;
                case "COMEX": me = MARKET_EXCHANGE.ME_COMEX; break;
                case "NYMEX": me = MARKET_EXCHANGE.ME_NYMEX; break;
                case "NYBOT": me = MARKET_EXCHANGE.ME_NYBOT; break;
                case "TOCOM": me = MARKET_EXCHANGE.ME_TOCOM; break;//東京商品交易所
                case "JPX": me = MARKET_EXCHANGE.ME_JPX; break;//大阪證交所
                case "ICE_EU": me = MARKET_EXCHANGE.ME_ICE_EU; break;//洲際期貨交易所
                case "ENXT": me = MARKET_EXCHANGE.ME_ENXT; break;//泛歐交易所
                case "CFE": me = MARKET_EXCHANGE.ME_CFE; break;
                case "ICE_SG": me = MARKET_EXCHANGE.ME_ICE_SG; break;
                case "TFEX": me = MARKET_EXCHANGE.ME_TFEX; break;//2019.4.1 Add
                case "KRX": me = MARKET_EXCHANGE.ME_KRX; break; //2019.4.1 Add
                case "LME": me = MARKET_EXCHANGE.ME_LME; break; //2019.5.22 Add
                case "CBOE": me = MARKET_EXCHANGE.ME_CBOE; break;
                case "HNX": me = MARKET_EXCHANGE.ME_HNX; break;   //2023.1.5 
                case "SHF": me = MARKET_EXCHANGE.ME_SHF; break;   //2023.1.5 
                case "ASX": me = MARKET_EXCHANGE.ME_ASX; break;   //2023.7.11
                case "NSE": me = MARKET_EXCHANGE.ME_NSE; break;   //2023.7.11
            }

            return me; 
        }
        private MARKET_FLAG getflag(string flag) {
            MARKET_FLAG mf = MARKET_FLAG.MF_FUT;
            char f = flag[0]; 
            switch (f) {
                case 'F': mf = MARKET_FLAG.MF_FUT; break;
                case 'O': mf = MARKET_FLAG.MF_OPT; break;
                    //2014.12.11 ADD 價差單
                case 'S': mf = MARKET_FLAG.MF_FUT_SPREAD; break;
                case 's': mf = MARKET_FLAG.MF_OPT_SPREAD; break; 
            }
            return mf; 
        }
        private FOREIGN_SESSION getsession(string session) {
            FOREIGN_SESSION fs = FOREIGN_SESSION.FS_EC; 
            switch (txtFSession.Text) {
                case "2": fs = FOREIGN_SESSION.FS_EC; break;         //T 電子盤
                case "3": fs = FOREIGN_SESSION.FS_EC1; break;        //T+1 電子盤
            }
            return fs; 
        }
        private void btnSGX_Click(object sender, EventArgs e) {
            string exchange = cbExchange.Text.Trim();
            MARKET_EXCHANGE me = getexchange(cbExchange.Text.Trim());
            MARKET_FLAG mf = getflag(cbMarket.Text);
            if ((mf == MARKET_FLAG.MF_FUT_SPREAD) && (tbFComym2.Text.Trim() == "")) {
                MessageBox.Show("價差單(SPREAD) 時商品月份2 必須需入");
                return;
            }
            short istatus = quoteCom.SubQuote(me, mf, tbFSymbol.Text, tbFComym.Text, tbDD.Text, tbFCP.Text, tbStrikePrice.Text, tbFComym2.Text); 
            if (istatus < 0)
                AddInfo(quoteCom.GetSubQuoteMsg(istatus)); 
            
        }

        private void btnUnSGX_Click(object sender, EventArgs e) {
            
            MARKET_EXCHANGE me = getexchange(cbExchange.Text.Trim());
            MARKET_FLAG mf = getflag(cbMarket.Text); 
            quoteCom.UnSubQuote(me, mf, tbFSymbol.Text, tbFComym.Text, tbDD.Text, tbFCP.Text, tbStrikePrice.Text,tbFComym2.Text) ; 
        }

        private void btnQSGX_Click(object sender, EventArgs e) {
            
            string exchange = cbExchange.Text.Trim();
            MARKET_EXCHANGE me = getexchange(cbExchange.Text.Trim());
            MARKET_FLAG mf = getflag(cbMarket.Text);
            FOREIGN_SESSION fs = getsession(txtFSession.Text.Trim()); 

            short istatus = quoteCom.RetriveLastPrice(me,mf,fs,tbFSymbol.Text,tbFComym.Text,tbDD.Text,tbFCP.Text,tbStrikePrice.Text,tbFComym2.Text ) ;
            if (istatus < 0)
                AddInfo(quoteCom.GetSubQuoteMsg(istatus)); 
        }

        private void btnSGXComm_Click(object sender, EventArgs e) {

            string exchange = cbExchange.Text.Trim();
            MARKET_EXCHANGE me = getexchange(cbExchange.Text.Trim());  
            MARKET_FLAG mf = getflag(cbMarket.Text) ;
            
        short istatus = quoteCom.RetriveQuoteList(me, mf); 
            if (istatus < 0)
                AddInfo(quoteCom.GetSubQuoteMsg(istatus)); 
        }

        private void button1_Click(object sender, EventArgs e) {

            string exchange = cbExchange.Text.Trim();
            MARKET_EXCHANGE me = getexchange(cbExchange.Text.Trim()); 
            MARKET_FLAG mf = getflag(cbMarket.Text.Trim()) ;

            FOREIGN_SESSION fs = getsession(txtFSession.Text); 
          
            List<PI40003> list40003 = new List<PI40003>();
            PI40003 p40003 = new PI40003();
            list40003 = quoteCom.GetProductList(me, mf, fs); 
            for (int i = 0; i < list40003.Count; i++) {
                p40003 = list40003[i];
                //AddInfo("交易所:" + p40003.ExchangeNm + " 盤別: " + p40003.Session + " 商品代碼: " + p40003.Symbol + " 到期日: " + p40003.ExpiredDate);
                AddInfo(p40003.Symbol + p40003.ComYM); 
            }
            AddInfo("Total Count:" + list40003.Count());
        }

        private void button5_Click(object sender, EventArgs e) {

            string exchange = cbExchange.Text.Trim();
            MARKET_EXCHANGE me = getexchange(cbExchange.Text.Trim());
            MARKET_FLAG mf = getflag(cbMarket.Text);
            FOREIGN_SESSION fs = getsession(txtFSession.Text);

            PI40003 pb = quoteCom.GetProdcutBase(me, mf, fs, tbFSymbol.Text.Trim(), tbFComym.Text.Trim(), tbDD.Text.Trim(), tbFCP.Text, tbStrikePrice.Text,tbFComym2.Text.Trim());
                
            if (pb != null) {
                StringBuilder sb = new StringBuilder();
                sb.Append("交易所:").Append(pb.ExchangeNm).Append(Environment.NewLine);
                sb.Append(" 盤別:").Append(pb.Session).Append(Environment.NewLine);
                sb.Append(" 商品:").Append(pb.Symbol).Append(Environment.NewLine);
                sb.Append(" 參考價(昨日收盤價):").Append(pb.ClosePrice).Append(Environment.NewLine);
                sb.Append(" 昨日交易量:").Append(pb.CloseQuantity).Append(Environment.NewLine);
                sb.Append("最近交易日:").Append(pb.LastTradeDate).Append(Environment.NewLine); 
                sb.Append(" 到期日:").Append(pb.ExpiredDate).Append(Environment.NewLine);
                sb.Append("=========================================");
                AddInfo(sb.ToString());
            }
            
        }

        private void Form1_Load(object sender, EventArgs e) {

        }

        private void btnGenSymbol_Click(object sender, EventArgs e) {
            MARKET_EXCHANGE me = getexchange(cbExchange.Text.Trim());
            MARKET_FLAG mf = getflag(cbMarket.Text);
            FOREIGN_SESSION fs = getsession(txtFSession.Text.Trim());
            if ((mf == MARKET_FLAG.MF_FUT_SPREAD) && (tbFComym2.Text.Trim() == "")) {
                tbfullid.Text = ""; 
                MessageBox.Show("價差單(SPREAD) 時商品月份2 必須需入");
                return; 
            }

            string fid = quoteCom.GenForeignFullComID(me, mf, tbFSymbol.Text.Trim(), tbFComym.Text.Trim(), tbDD.Text.Trim(), tbFCP.Text, tbStrikePrice.Text, tbFComym2.Text);
            tbfullid.Text = fid; 
        }

        private void button7_Click(object sender, EventArgs e) {
            MARKET_EXCHANGE me = getexchange(cbExchange.Text.Trim());
            MARKET_FLAG mf = getflag(cbMarket.Text);
            /*string comid; string comym; string day; string cp; string strikeprice ;
            short rtn = quoteCom.AnalysisFSymbol(me,mf,tbfullid.Text,out comid,out comym,out day,out cp, out strikeprice) ;
            if (rtn == 0)
                AddInfo(comid + "," + comym + "," + day + "," + cp + "," + strikeprice); 
            else AddInfo("Symbol ERROR") ; */
            //*****2014.12.10 Use New AnalysisFSymbol 
            BasicSymbol bs = new BasicSymbol(); 
            short rtn = quoteCom.AnalysisFSymbol(me,mf,tbfullid.Text,out bs ) ;
            string msg = ""; 
            if (rtn == 0) {
                msg = "comid=" + bs.ComID + " ,comym=" + bs.ComYM + " ,cp=" + bs.CP + " ,strikeprice=" + bs.StrikePrice;
                if (bs.isMulti) msg = msg + ",comym2=" + bs.ComYM2;
                AddInfo(msg);
            }
            else AddInfo("Symbol ERROR"); 

        }

        private void btnSub1_Click(object sender, EventArgs e) {
            string exchange = cbExchange.Text.Trim();
            MARKET_EXCHANGE me = getexchange(cbExchange.Text.Trim());
            MARKET_FLAG mf = getflag(cbMarket.Text);

            short istatus = quoteCom.SubQuote(me, mf, tbfullid.Text);  
            if (istatus < 0)
                AddInfo(quoteCom.GetSubQuoteMsg(istatus)); 
        }

        private void button11_Click(object sender, EventArgs e) {
            string exchange = cbExchange.Text.Trim();
            MARKET_EXCHANGE me = getexchange(cbExchange.Text.Trim());
            MARKET_FLAG mf = getflag(cbMarket.Text);

            short istatus = quoteCom.UnSubQuote(me, mf, tbfullid.Text);
            if (istatus < 0)
                AddInfo(quoteCom.GetSubQuoteMsg(istatus)); 

        }

        private void btnExch_Click(object sender, EventArgs e) {
            string s = "";
            for (int i = 0; i < quoteCom.List_Exchange.Count ; i++) {
                s = s + quoteCom.List_Exchange[i] + ", "; 
            }
            AddInfo("可註冊的交易所: " + s );
        }

        private void button12_Click(object sender, EventArgs e) {
            quoteCom.LoadProductForeighSvXML(); 
        }

        private void button13_Click(object sender, EventArgs e) {
            List<string> list = new List<string>();
            list = quoteCom.GetProductBaseList();
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < list.Count; i++) {
                sb.Append(list[i]).Append(Environment.NewLine); 
            }
            AddInfo(sb.ToString() );
            list = null; 

        }

        private void button15_Click(object sender, EventArgs e) {
            PT01805 p1805 = new PT01805();
            //2015.3 : 請使用新的GetProductBase, 交易所選帶入MARKET_EXCHANGE , 並增加flag 可查詢選擇權 ;
            //p1805 = quoteCom.GetProductBase(txtExchange.Text.Trim(), txtFComid.Text.Trim());
              
            MARKET_EXCHANGE me = getexchange(cbTradeExch.Text.Trim());
            MARKET_FLAG mf = getflag(cbTFlag.Text.Trim());
            p1805 = quoteCom.GetProductBase(me, mf, txtSymbol.Text.Trim()); 
            AddInfo(p1805.ToLog());
        }

        private void button14_Click(object sender, EventArgs e) {
            List<string> list = new List<string>();
            //2015.3. 請使用新的GetComYM,交易所選帶入MARKET_EXCHANGE , 並增加flag 可查詢選擇權 ;
            MARKET_EXCHANGE me = getexchange(cbTradeExch.Text.Trim());
            MARKET_FLAG mf = getflag(cbTFlag.Text.Trim());
            list = quoteCom.GetComYM(me, mf, txtSymbol.Text.Trim());
            for (int i = 0; i < list.Count; i++) {
                AddInfo(list[i]);
            }
            list = null; 
        }

        private void button18_Click(object sender, EventArgs e) {
            string exchange = cbExchange.Text.Trim();
            MARKET_EXCHANGE me = getexchange(cbExchange.Text.Trim());
            MARKET_FLAG mf = getflag(cbMarket.Text.Trim());

            FOREIGN_SESSION fs = getsession(txtFSession.Text);

            List<string> listym = new List<string>();

            listym = quoteCom.GetFProductListOfYM(me, mf, fs, tbFSymbol.Text);
            listym.Sort(); 
            for (int i = 0; i < listym.Count; i++) {
                
                AddInfo(listym[i]); 
            }
        }

        private void button19_Click(object sender, EventArgs e) {
        string exchange = cbExchange.Text.Trim();
            MARKET_EXCHANGE me = getexchange(cbExchange.Text.Trim());
            MARKET_FLAG mf = getflag(cbMarket.Text.Trim());

            FOREIGN_SESSION fs = getsession(txtFSession.Text);

            List<string> listsp = new List<string>();

            listsp = quoteCom.GetFProductListOfStrikePrice(me, mf, fs, tbFSymbol.Text, tbFComym.Text );
            for (int i = 0; i < listsp.Count; i++) {
                AddInfo(listsp[i]);
            }
        }

        private void button20_Click(object sender, EventArgs e) {
            
        }

        private void button21_Click(object sender, EventArgs e) {

            string exchange = cbExchange.Text.Trim();
            MARKET_EXCHANGE me = getexchange(cbExchange.Text.Trim());
            MARKET_FLAG mf = getflag(cbMarket.Text.Trim());

            FOREIGN_SESSION fs = getsession(txtFSession.Text);

            List<string> lrtn = new List<string>();
            

            lrtn = quoteCom.GetComidList(me, mf, fs);
            for (int i = 0; i < lrtn.Count; i++) {
                AddInfo(lrtn[i]); 
            }
        }

        private void btnNotice_Click(object sender, EventArgs e) {
            Notice_Market nm = Notice_Market.NM_ALL;
            if (cbNM.Text[0] == 'F') nm = Notice_Market.NM_FUT; else if (cbNM.Text[0] == 'S') nm = Notice_Market.NM_STK;
            Notice_Kind nk = Notice_Kind.NK_ALL;
            if (cbNK.Text[0] == 'N') nk = Notice_Kind.NK_NORMAL; else if (cbNK.Text[0] == 'E') nk = Notice_Kind.NK_EMERGENCY;
            quoteCom.RetriveNotice(nm, nk);
        }

       
     
        private void btnIndex_Click(object sender, EventArgs e) {
            string exchange = cbidxEx.Text.Trim();
            MARKET_EXCHANGE me = getexchange(cbidxEx.Text.Trim());
            MARKET_FLAG mf = getflag(cbidxMkt.Text);
            
            short istatus = quoteCom.SubQuoteIndex(me, mf, tbidxSym.Text);
            
            if (istatus < 0)
                AddInfo(quoteCom.GetSubQuoteMsg(istatus)); 
            
        }

        private void btnUnIdx_Click(object sender, EventArgs e) {
            string exchange = cbidxEx.Text.Trim();
            MARKET_EXCHANGE me = getexchange(cbidxEx.Text.Trim());
            MARKET_FLAG mf = getflag(cbidxMkt.Text);

            short istatus = quoteCom.UnSubQuoteIndex(me, mf, tbidxSym.Text);
            if (istatus < 0)
                AddInfo(quoteCom.GetSubQuoteMsg(istatus)); 
        }

        private void btnProdList_Click(object sender, EventArgs e) {
            MARKET_FLAG mf = (rbF.Checked) ? MARKET_FLAG.MF_FUT : MARKET_FLAG.MF_OPT; 
            List<string> rtn = quoteCom.GetProductBaseList(mf);
            for (int i = 0; i < rtn.Count; i++)
                AddInfo(rtn[i]); 
        }

        private void btnProList1_Click(object sender, EventArgs e) {
            List<string> rtn = quoteCom.GetProductBaseList(tbcomid.Text);
            for (int i = 0; i < rtn.Count; i++)
                AddInfo(rtn[i]); 
        }

        private void tbSID_TextChanged(object sender, EventArgs e)
        {

        }

        private void btnSession_Click(object sender, EventArgs e)
        {
            short istatus = quoteCom.AskTaifexSession(textBox3.Text);
            if (istatus < 0)   //
                AddInfo(quoteCom.GetSubQuoteMsg(istatus)); 
        }

        private void button3_Click(object sender, EventArgs e)
        {
            
        }

        private void btnQuoteListPM_Click(object sender, EventArgs e)
        {
            short istatus = quoteCom.RetriveQuoteListPM( );
            if (istatus < 0)
                AddInfo(quoteCom.GetSubQuoteMsg(istatus)); 
        }

        private void btnProdListP_Click(object sender, EventArgs e)
        {
            MARKET_FLAG mf = (rbFP.Checked) ? MARKET_FLAG.MF_FUT : MARKET_FLAG.MF_OPT;
            List<string> rtn = quoteCom.GetProductBaseListPM(mf);
            for (int i = 0; i < rtn.Count; i++)
                AddInfo(rtn[i]); 
        }

        private void btnProList1P_Click(object sender, EventArgs e)
        {
            List<string> rtn = quoteCom.GetProductBaseListPM(tbcomidP.Text);
            for (int i = 0; i < rtn.Count; i++)
                AddInfo(rtn[i]); 
        }

        private void btnProdBaseP_Click(object sender, EventArgs e)
        {
            PI20008 pb = quoteCom.GetProdcutBasePM(tbSymbolP.Text);
            if (pb != null)
            {
                StringBuilder sb = new StringBuilder();
                sb.Append("期貨/選擇權:").Append(pb.Market).Append(Environment.NewLine);
                sb.Append("可註冊商品代號:").Append(pb.Symbol).Append(Environment.NewLine);
                sb.Append("商品序號:").Append(pb.SymbolIdx).Append(Environment.NewLine);
                sb.Append("價格欄位小數位數:").Append(pb.PriceDecimal).Append(Environment.NewLine);
                //sb.Append("選擇權履約價格小數位數:").Append(pb.StrikePrice_Decimal).Append(Environment.NewLine);
                sb.Append("第一漲停價:").Append(pb._RISE_LIMIT_PRICE1).Append(Environment.NewLine);
                sb.Append("參考價:").Append(pb._REFERENCE_PRICE).Append(Environment.NewLine);
                sb.Append("第一跌停價:").Append(pb._FALL_LIMIT_PRICE1).Append(Environment.NewLine);
                sb.Append("第二漲停價:").Append(pb._RISE_LIMIT_PRICE2).Append(Environment.NewLine);
                sb.Append("第二跌停價:").Append(pb._FALL_LIMIT_PRICE2).Append(Environment.NewLine);
                sb.Append("第三漲停價:").Append(pb._RISE_LIMIT_PRICE3).Append(Environment.NewLine);
                sb.Append("第三跌停價:").Append(pb._FALL_LIMIT_PRICE3).Append(Environment.NewLine);
                sb.Append("商品名稱:").Append(pb._PROD_NAME).Append(Environment.NewLine);
                sb.Append("下市日期:").Append(pb.END_DATE).Append(Environment.NewLine);
                sb.Append("=========================================");
                AddInfo(sb.ToString());
            }
        }

        private void button4_Click(object sender, EventArgs e)
        {
            quoteCom.Connect(cbQIP.Text, ushort.Parse(tbQPort.Text));
        }

        private void button3_Click_1(object sender, EventArgs e)
        {
            string IDNO = tbSAcct.Text;
            string PWD = tbSPwd.Text;
            string tradeIP = tbTIP.Text.Trim(); 
            quoteCom.SourceId = tbSID.Text;
            quoteCom.Login2(IDNO, PWD, tradeIP);
        }

        
        #region 2018.11 交易商品下載 查詢
        private void btnDLProduct_Click(object sender, EventArgs e)
        {
            quoteCom.LoadTaifexProductXML();  
        }

        private void btnTaifexList_Click(object sender, EventArgs e)
        {
            MARKET_FLAG mf = (rbFut.Checked) ? MARKET_FLAG.MF_FUT : MARKET_FLAG.MF_OPT;
            List<string> rtn =quoteCom.GetTaifexProductList(mf); 
            for (int i = 0; i < rtn.Count; i++)
                AddInfo(rtn[i]); 
        }
        private void btnBase_Click(object sender, EventArgs e)
        {
            PT01805 rtn = quoteCom.GetTaifexProductBase(tbComid1.Text.Trim());
            if (rtn != null)
                AddInfo(rtn.ToLog());
        }
        private void btnTComid_Click(object sender, EventArgs e)
        {
            List<PT01802> rtn = quoteCom.GetTaifexProductDetailList(tbComid1.Text);
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < rtn.Count; i++)
            {
                sb.Append("ComType=").Append(rtn[i].ComType).Append("|");
                sb.Append("ComId=").Append(rtn[i].ComId).Append("|");
                sb.Append("RisePrice=").Append(rtn[i].RisePrice).Append("|");
                sb.Append("FallPrice=").Append(rtn[i].FallPrice).Append("|");
                sb.Append("EndDate=").Append(rtn[i].EndDate).Append("|").Append(Environment.NewLine); 
            }
            AddInfo(sb.ToString()); 
        }

        private void btnSymbol_Click(object sender, EventArgs e)
        {
            PT01802 rtn = quoteCom.GetTaifexProductDetail(textBox8.Text.Trim());
            if (rtn != null)
            {
                StringBuilder sb = new StringBuilder();
                sb.Append("ComType=").Append(rtn.ComType).Append("|");
                sb.Append("ComId=").Append(rtn.ComId).Append("|");
                sb.Append("RisePrice=").Append(rtn.RisePrice).Append("|");
                sb.Append("FallPrice=").Append(rtn.FallPrice).Append("|");
                sb.Append("EndDate=").Append(rtn.EndDate).Append("|");
                AddInfo(sb.ToString()); 
            }

        }

        

        private void btnDLProductT1_Click(object sender, EventArgs e)
        {
            quoteCom.LoadTaifexProductXMLT1();  
        }

        private void btnTaifexListT1_Click(object sender, EventArgs e)
        {
            MARKET_FLAG mf = (rbFutT1.Checked) ? MARKET_FLAG.MF_FUT : MARKET_FLAG.MF_OPT;
            List<string> rtn = quoteCom.GetTaifexProductListT1(mf);
            for (int i = 0; i < rtn.Count; i++)
                AddInfo(rtn[i]); 
        }
        private void BtnBaseT1_Click(object sender, EventArgs e)
        {
            PT01805 rtn = quoteCom.GetTaifexProductBaseT1(tbComid1.Text.Trim());
            if (rtn != null)
                AddInfo(rtn.ToLog());
        }


        private void btnTComidT1_Click(object sender, EventArgs e)
        {
            List<PT01802> rtn = quoteCom.GetTaifexProductDetailListT1(tbComidT1.Text);
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < rtn.Count; i++)
            {
                sb.Append("ComType=").Append(rtn[i].ComType).Append("|");
                sb.Append("ComId=").Append(rtn[i].ComId).Append("|");
                sb.Append("RisePrice=").Append(rtn[i].RisePrice).Append("|");
                sb.Append("FallPrice=").Append(rtn[i].FallPrice).Append("|");
                sb.Append("EndDate=").Append(rtn[i].EndDate).Append("|").Append(Environment.NewLine);
            }
            AddInfo(sb.ToString()); 
        }

        private void btnSymbolT1_Click(object sender, EventArgs e)
        {
            PT01802 rtn = quoteCom.GetTaifexProductDetailT1(textBox11.Text.Trim());
            if (rtn != null)
            {
                StringBuilder sb = new StringBuilder();
                sb.Append("ComType=").Append(rtn.ComType).Append("|");
                sb.Append("ComId=").Append(rtn.ComId).Append("|");
                sb.Append("RisePrice=").Append(rtn.RisePrice).Append("|");
                sb.Append("FallPrice=").Append(rtn.FallPrice).Append("|");
                sb.Append("EndDate=").Append(rtn.EndDate).Append("|");
                AddInfo(sb.ToString());
            }
        }
        #endregion

        private void button6_Click(object sender, EventArgs e)
        {
            List<cIndexComm> rtn = quoteCom.GetIndexList();
            StringBuilder sb = new StringBuilder();
            sb.Append("Index List:").Append(rtn.Count).Append(Environment.NewLine) ; 
            for (int i = 0; i < rtn.Count; i++)
            {
                sb.Append("Exchange=").Append(rtn[i].Exchange) ; 
                sb.Append(", IndexCode=").Append(rtn[i].IndexCode).Append(Environment.NewLine);
            }
            AddInfo(sb.ToString()); 
        }

        private void btnIdxQ_Click(object sender, EventArgs e)
        {
            string exchange = cbidxEx.Text.Trim();
            MARKET_EXCHANGE me = getexchange(cbidxEx.Text.Trim());
            MARKET_FLAG mf = getflag(cbidxMkt.Text);
            
            short istatus = quoteCom.RetrieveLastIndex(me,tbidxSym.Text);
            
            if (istatus < 0)
                AddInfo(quoteCom.GetSubQuoteMsg(istatus)); 
        }

        #region 2023.4.24 : LME OffASK / OffBID 報價
        private void btnOBA_Click(object sender, EventArgs e)
        {
            MARKET_EXCHANGE me = getexchange(cbExOBA.Text.Trim());
            MARKET_FLAG mf = getflag(cbidxMkt.Text);

            short istatus = quoteCom.SubQuoteOBA(me, tbOBASym.Text);

            if (istatus < 0)
                AddInfo(quoteCom.GetSubQuoteMsg(istatus)); 
        }

        private void btnUnOBA_Click(object sender, EventArgs e)
        {
            MARKET_EXCHANGE me = getexchange(cbExOBA.Text.Trim());

            short istatus = quoteCom.UnSubQuoteOBA(me, tbOBASym.Text);
            if (istatus < 0)
                AddInfo(quoteCom.GetSubQuoteMsg(istatus)); 
        }

        private void btnLastOBA_Click(object sender, EventArgs e)
        {
            MARKET_EXCHANGE me = getexchange(cbExOBA.Text.Trim());
            short istatus = quoteCom.RetrieveLastOBA(me, tbOBASym.Text);
            if (istatus < 0)
                AddInfo(quoteCom.GetSubQuoteMsg(istatus));
        }

        #endregion 

    }
}

