using System;
using System.Data;
using System.Windows.Forms;
using Concord.API.Future.Client;
using System.Reflection;
using System.Threading;
using System.Collections;
using System.Xml;
using Concord.SDK.Logging;
using System.Collections.Generic;
using Concord.API.Future.ClientSample.Elves;
using System.Linq;
using System.Diagnostics;

namespace Concord.API.Future.ClientSample
{
    public partial class frmSample : Form
    {
        #region 定義參數
        private ucClient API = new ucClient();

        //private DataTable dtFFExchange = new DataTable();
        //private DataTable dtFFCommo = new DataTable();
        //private DataTable dtFFCommoYM = new DataTable();
        private DataTable dtFFCurrencyRate = new DataTable();
        private DataTable dtFCommo = new DataTable();
        private DataTable dtFCommoYM = new DataTable();
        private Hashtable htSvc = new Hashtable();
        #endregion
        #region 內期
        private SortedDictionary<string, FCommodityElf> g_listFCommodity = new SortedDictionary<string, FCommodityElf>();
        //private SortedDictionary<string, SortedDictionary<FCommoymKeyElf, FCommoymElf>> g_listFCommoYM = new SortedDictionary<string, SortedDictionary<FCommoymKeyElf, FCommoymElf>>();
        private SortedDictionary<string, SortedDictionary<string, FCommoymElf>> g_listFCommoYM = new SortedDictionary<string, SortedDictionary<string, FCommoymElf>>();
        #endregion 內期

        #region 外期
        private SortedDictionary<string, FFExchangeElf> g_listFFExchange = new SortedDictionary<string, FFExchangeElf>();
        private SortedDictionary<string, SortedDictionary<string, FFCommodityElf>> g_listFFCommodity = new SortedDictionary<string, SortedDictionary<string, FFCommodityElf>>();
        private SortedDictionary<string, SortedDictionary<string, SortedDictionary<FFCommoymKeyElf, FFCommoymElf>>> g_listFFCommoYM = new SortedDictionary<string, SortedDictionary<string, SortedDictionary<FFCommoymKeyElf, FFCommoymElf>>>();
        #endregion 外期

        public frmSample()
        {
            InitializeComponent();

        }

        private void frmSample_Load(object sender, EventArgs e)
        {
            ConcordLogger.Logger.Debug("程式啟動");
            Thread.CurrentThread.Name = "Main";

            API.OnFFGeneralReport += API_OnFFGeneralReport;
            API.OnFFErrorReport += API_OnFFErrorReport;
            API.OnFFOrderReport += API_OnFFOrderReport;
            API.OnFFBulletinReport += API_OnFFBulletinReport;

            API.OnFGeneralReport += API_OnFGeneralReport;
            API.OnFErrorReport += API_OnFErrorReport;
            API.OnFOrderReport += API_OnFOrderReport;
            API.OnFBulletinReport += API_OnFBulletinReport;

            #region 初始化ComboBox
            cbFFMsgType.SelectedIndex = 0;
            cbFFOTYPE.SelectedIndex = 0;
            cbFFOCond.SelectedIndex = 0;
            cbFFBS.SelectedIndex = 0;
            cbFMsgType.SelectedIndex = 0;
            cbFOTYPE.SelectedIndex = 0;
            cbFFIR.SelectedIndex = 0;
            cbFBS.SelectedIndex = 0;
            #endregion

            #region 初始化DataTable
            FieldInfo[] afi;
            // FieldInfo[] afi = typeof(FFExchange).GetFields();
            //foreach (FieldInfo fi in afi)
            //{
            //    dtFFExchange.Columns.Add(fi.Name, fi.FieldType);
            //}

            //afi = typeof(FFCommo).GetFields();
            //foreach (FieldInfo fi in afi)
            //{
            //    dtFFCommo.Columns.Add(fi.Name, fi.FieldType);
            //}

            //afi = typeof(FFCommoYM).GetFields();
            //foreach (FieldInfo fi in afi)
            //{
            //    dtFFCommoYM.Columns.Add(fi.Name, fi.FieldType);
            //}

            afi = typeof(FFCurrencyRate).GetFields();
            foreach (FieldInfo fi in afi)
            {
                dtFFCurrencyRate.Columns.Add(fi.Name, fi.FieldType);
            }

            afi = typeof(FCommo).GetFields();
            foreach (FieldInfo fi in afi)
            {
                dtFCommo.Columns.Add(fi.Name, fi.FieldType);
            }

            afi = typeof(FCommoYM).GetFields();
            foreach (FieldInfo fi in afi)
            {
                dtFCommoYM.Columns.Add(fi.Name, fi.FieldType);
            }

            #endregion

            #region toolTip 設定
            toolTip1.SetToolTip(cbFFMsgType, "01：新\n02：減\n03：刪");
            toolTip1.SetToolTip(cbFFOCond, "1：CBT 、CME 、CMX 、NYM 、TIM\n0：HKF 、LIF 、MAT 、OSE 、REX 、 TCE 、TGE\n7：HKF_ETS 、OSE_ETS 、 TCE_ETS 、TGE_ETS\n5：NYB\n3：SMX\n6：SMX_ETS");
            toolTip1.SetToolTip(cbFFOTYPE, "MKT：市價\nLMT：限價\nSTP：停損市價\nSWL：停損限價");
            #endregion

            #region 取得SvcList存入ht
            XmlDocument xldInfo = new XmlDocument();
            xldInfo.Load("SvcList.xml");
            XmlNodeList xnl = xldInfo.SelectNodes("//SvcInfo");
            foreach (XmlNode xn in xnl)
            {
                string SvcToken = xn.ChildNodes[0].InnerText;
                string SvcResult = xn.ChildNodes[1].InnerText;
                htSvc.Add(SvcToken, SvcResult);
            }
            #endregion
        }

        #region 公告事件
        private void API_OnFBulletinReport(string strMsgCode, string strMsg)
        {
            lsFOrderRcv.Items.Add(strMsgCode + "：" + strMsg);
        }

        private void API_OnFFBulletinReport(string strMsgCode, string strMsg)
        {
            lsFFOrderRcv.Items.Add(strMsgCode + "：" + strMsg);
        }
        #endregion

        #region 主動回報事件
        private void API_OnFFOrderReport(string strMsgCode, string strMsg)
        {
            Invoke((Action)(() =>
            {
                lsFFOrderRcv.Items.Add(strMsgCode + "：" + strMsg);
            }));
        }

        private void API_OnFFGeneralReport(string strMsgCode, string strMsg)
        {
            lsFFStatus.Items.Insert(0,
$"{DateTime.Now.ToString("yyyyMMdd-HH:mm:ss.fff")}:{strMsgCode}:{strMsg}");

            //if (strMsgCode == "102")
            //{
            //    btnFFAccList_Click(null, null);
            //    btnFFQueryInfo_Click(null, null);
            //}
        }

        private void API_OnFFErrorReport(string strMsgCode, string strMsg)
        {
            lsFFStatus.Items.Insert(0,
$"{DateTime.Now.ToString("yyyyMMdd-HH:mm:ss.fff")}:{strMsgCode}:{strMsg}");
        }

        private void API_OnFGeneralReport(string strMsgCode, string strMsg)
        {
            lsFStatus.Items.Insert(0,
$"{DateTime.Now.ToString("yyyyMMdd-HH:mm:ss.fff")}:{strMsgCode}:{strMsg}");

            //if (strMsgCode == "102")
            //{
            //    btnFAccList_Click(null, null);
            //    btnFQueryInfo_Click(null, null);
            //}
        }

        private void API_OnFErrorReport(string strMsgCode, string strMsg)
        {
            lsFStatus.Items.Insert(0,
$"{DateTime.Now.ToString("yyyyMMdd-HH:mm:ss.fff")}:{strMsgCode}:{strMsg}");
        }

        private void API_OnFOrderReport(string strMsgCode, string strMsg)
        {
            Invoke((Action)(() =>
            {
                lsFOrderRcv.Items.Add(strMsgCode + "：" + strMsg);
            }));
        }
        #endregion

        #region 按鍵事件
        private void btnLogin_Click(object sender, EventArgs e)
        {
            String strMsg = "";
            String strMsgCode = "";
            strMsgCode = API.Login(txtIDNO.Text.ToUpper(), txtPWD.Text, txtOrderIP.Text, out strMsg);
            lsFStatus.Items.Insert(0,
$"{DateTime.Now.ToString("yyyyMMdd-HH:mm:ss.fff")}:{strMsgCode}:{strMsg}");
        }
        private void btnAccountLogin_Click(object sender, EventArgs e)
        {
            string strMsg = "";
            string strMsgCode = "";
            strMsgCode = API.LoginAccount(txtBHNO.Text, txtAccount.Text, txtPWD.Text, txtOrderIP.Text, out strMsg);
            lsFStatus.Items.Insert(0,
$"{DateTime.Now.ToString("yyyyMMdd-HH:mm:ss.fff")}:{strMsgCode}:{strMsg}");
        }
        private void btnSubLogin_Click(object sender, EventArgs e)
        {
            String strMsg = "";
            String strMsgCode = "";
            strMsgCode = API.LoginSubAccount(txtIDNO.Text, txbSubAccount.Text, txtPWD.Text, txtOrderIP.Text, out strMsg);
            lsFFStatus.Items.Insert(0,
$"{DateTime.Now.ToString("yyyyMMdd-HH:mm:ss.fff")}:{strMsgCode}:{strMsg}");
        }
        private void btnLogout_Click(object sender, EventArgs e)
        {
            String strMsg = "";
            String strMsgCode = "";
            strMsgCode = API.Logout(out strMsg);
            lsFFStatus.Items.Insert(0,
$"{DateTime.Now.ToString("yyyyMMdd-HH:mm:ss.fff")}:{strMsgCode}:{strMsg}");
        }

        private void btnFGetCertStatus_Click(object sender, EventArgs e)
        {
            String strSDate = "";
            String strEDate = "";
            String strMsg = "";
            String strMsgCode = "";
            strMsgCode = API.GetCertStatus(txtIDNO.Text, out strSDate, out strEDate, out strMsg);

            if (strMsgCode == "000")
            {
                MessageBox.Show("起始日：" + strSDate + "結束日：" + strEDate);
            }
            else
            {
                lsFStatus.Items.Insert(0,
$"{DateTime.Now.ToString("yyyyMMdd-HH:mm:ss.fff")}:{strMsgCode}:{strMsg}");

            }
        }

        private void btnFFGetCertStatus_Click(object sender, EventArgs e)
        {
            String strSDate = "";
            String strEDate = "";
            String strMsg = "";
            String strMsgCode = "";
            strMsgCode = API.GetCertStatus(txtIDNO.Text, out strSDate, out strEDate, out strMsg);

            if (strMsgCode == "000")
            {
                MessageBox.Show("起始日：" + strSDate + "結束日：" + strEDate);
            }
            else
            {
                lsFFStatus.Items.Insert(0,
$"{DateTime.Now.ToString("yyyyMMdd-HH:mm:ss.fff")}:{strMsgCode}:{strMsg}");
            }
        }

        #region 外期
        private void btnFFCheckConnect_Click(object sender, EventArgs e)
        {
            String strMsg = "";
            String strMsgCode = "";
            strMsgCode = API.FFCheckConnect(out strMsg);
            lsFFStatus.Items.Insert(0,
$"{DateTime.Now.ToString("yyyyMMdd-HH:mm:ss.fff")}:{strMsgCode}:{strMsg}");
        }

        private void btnFFStatusClear_Click(object sender, EventArgs e)
        {
            lsFFStatus.Items.Clear();
        }

        private void btnFFOrderClear_Click(object sender, EventArgs e)
        {
            lsFFOrderRcv.Items.Clear();
        }

        private void btnFFAccList_Click(object sender, EventArgs e)
        {
            String strMsg = "";
            String strMsgCode = "";
            strMsgCode = API.FFQueryAccountInfo(out strMsg);
            cbFFOrderCseq.Items.Clear();
            cbFFBillCseq.Items.Clear();
            String[] strList = strMsg.Split((Char)0x0a);

            foreach (String s in strList)
            {
                cbFFOrderCseq.Items.Add(s.Split(',')[1] + "-" + s.Split(',')[3] + "-" + s.Split(',')[4] + "-" + s.Split(',')[5]);
                cbFFBillCseq.Items.Add(s.Split(',')[3] + "-" + s.Split(',')[4]);
            }

            cbFFOrderCseq.SelectedIndex = 0;
            cbFFBillCseq.SelectedIndex = 0;
        }

        private void btnFFQueryInfo_Click(object sender, EventArgs e)
        {
            //String strMsg = "";
            //String strMsgCode = "";
            //strMsgCode = API.FFQueryExchange(out strMsg);

            //if (strMsgCode == "000")
            //{
            //    String[] strList = strMsg.Split((Char)0x0a);
            //    foreach (String s in strList)
            //    {
            //        dtFFExchange.Rows.Add(s.Split(','));
            //    }

            //    foreach (DataRow dr in dtFFExchange.Rows)
            //    {
            //        cbFFExchange.Items.Add(dr["Exh"].ToString());
            //    }
            //}

            //strMsgCode = API.FFQueryCommo(out strMsg);
            //if (strMsgCode == "000")
            //{
            //    String[] strList = strMsg.Split((Char)0x0a);
            //    foreach (String s in strList)
            //    {
            //        dtFFCommo.Rows.Add(s.Split(','));
            //    }
            //}

            //strMsgCode = API.FFQueryCommoYM(out strMsg);
            //if (strMsgCode == "000")
            //{
            //    String[] strList = strMsg.Split((Char)0x0a);
            //    foreach (String s in strList)
            //    {
            //        dtFFCommoYM.Rows.Add(s.Split(','));
            //    }
            //}

            //strMsgCode = API.FFQueryCurrencyRate(out strMsg);
            //if (strMsgCode == "000")
            //{
            //    String[] strList = strMsg.Split((Char)0x0a);
            //    foreach (String s in strList)
            //    {
            //        dtFFCurrencyRate.Rows.Add(s.Split(','));
            //    }
            //}

            //cbFFExchange.SelectedIndex = 0;
            String strMsg = "";
            String strMsgCode = "";

            g_listFFExchange.Clear();
            g_listFFCommodity.Clear();
            g_listFFCommoYM.Clear();

            cbFFExchange.Items.Clear();

            strMsgCode = API.FFQueryExchange(out strMsg);
            if (strMsgCode == "000")
            {
                String[] strList = strMsg.Split('\n');
                foreach (String s in strList)
                {
                    string[] f = s.Split(',');
                    FFExchangeElf elf = new FFExchangeElf()
                    {
                        國內外別 = f[0],
                        交易所代號 = f[1],
                        交易所中文 = f[2],
                        國家 = f[3],
                        可否交易 = f[4],
                        可否顯示 = f[5],
                        開盤時間 = f[6],
                        收盤時間 = f[7],
                        限價別 = f[8],
                        市價別 = f[9],
                        停損市價 = f[10],
                        停損限價 = f[11],
                        交易日期 = f[12]
                    };
                    g_listFFExchange.Add(elf.交易所代號, elf);
                    g_listFFCommodity.Add(elf.交易所代號, new SortedDictionary<string, FFCommodityElf>());
                    g_listFFCommoYM.Add(elf.交易所代號, new SortedDictionary<string, SortedDictionary<FFCommoymKeyElf, FFCommoymElf>>());
                }
            }
            else
            {
                lsFFStatus.Items.Insert(0,
$"{DateTime.Now.ToString("yyyyMMdd-HH:mm:ss.fff")}:FFQueryExchange:{strMsgCode}:{strMsg}");
            }
            strMsgCode = API.FFQueryCommo(out strMsg);
            if (strMsgCode == "000")
            {
                String[] strList = strMsg.Split('\n');

                foreach (String s in strList)
                {
                    string[] f = s.Split(',');
                    FFCommodityElf elf = new FFCommodityElf()
                    {
                        交易所代碼 = f[0],
                        商品代號 = f[1],
                        商品中文 = f[2],
                        契約規格 = f[3],
                        價格分母 = f[4],
                        最小跳動點 = f[5],
                        最大口數 = f[6],
                        開盤時間 = f[7],
                        幣別 = f[8],
                        可否交易 = f[9],
                        可否顯示 = f[10],
                        可否當沖 = f[11],
                        當沖結束時間 = f[12],
                        價格轉換倍率 = f[13],
                        啟用狀態 = f[14],
                        商品別 = f[15],
                        限價別 = f[16],
                        市價別 = f[17],
                        停損市價 = f[18],
                        停損限價 = f[19]
                    };
                    g_listFFCommodity[elf.交易所代碼].Add(elf.商品代號, elf);
                    g_listFFCommoYM[elf.交易所代碼].Add(elf.商品代號, new SortedDictionary<FFCommoymKeyElf, FFCommoymElf>(new FFCommoymKeyElfComparer()));
                }
            }
            else
            {
                lsFFStatus.Items.Insert(0,
$"{DateTime.Now.ToString("yyyyMMdd-HH:mm:ss.fff")}:FFQueryCommo:{ strMsgCode}:{strMsg}");
            }
            // #商品年月
            strMsgCode = API.FFQueryCommoYM(out strMsg);
            if (strMsgCode == "000")
            {
                String[] strList = strMsg.Split('\n');
                foreach (String s in strList)
                {
                    string[] f = s.Split(',');
                    FFCommoymElf elf = new FFCommoymElf()
                    {
                        交易所代碼 = f[0],
                        商品代號 = f[1],
                        月份 = f[2],
                        交割月份 = f[3],
                        熱門月份 = f[4],
                        最後交易日 = f[5],
                        商品別 = f[6],
                        買賣權 = f[7],
                        履約價 = f[8]
                    };
                    if (g_listFFCommoYM[elf.交易所代碼].ContainsKey(elf.商品代號))
                    {
                        g_listFFCommoYM[elf.交易所代碼][elf.商品代號].Add(new FFCommoymKeyElf(elf.月份, elf.履約價, elf.買賣權), elf);
                    }
                    else
                    {
                        // Console.WriteLine($"不存在{elf.商品代號}");
                    }
                }
            }
            else
            {
                lsFFStatus.Items.Insert(0,
$"{DateTime.Now.ToString("yyyyMMdd-HH:mm:ss.fff")}:FFQueryCommoYM:{strMsgCode}:{strMsg}");
            }
            cbFFExchange.Items.AddRange(g_listFFExchange.Keys.ToArray());
            if (cbFFExchange.Items.Count > 0)
            {
                cbFFExchange.SelectedIndex = 0;
            }
        }

        private void btnFFOrder_Click(object sender, EventArgs e)
        {
            String strMsg = "";
            String strMsgCode = "";
            String strSig = "";
            String strCert = "";
            String strData = "TestData";
            //String strGUID = "";
            strMsgCode = API.GetSignature(txtIDNO.Text.ToUpper(), strData, out strSig, out strCert, out strMsg);

            lsFFStatus.Items.Insert(0,
$"{DateTime.Now.ToString("yyyyMMdd-HH:mm:ss.fff")}:{strMsgCode}:{strMsg}");
            String strGUID = Guid.NewGuid().ToString();
            if (strMsgCode == "120")
            {
#if COMMON
                switch (cbFFMsgType.SelectedItem.ToString())
                {
                    case "新單": // #新單
                #region 物件格式
                        Client.OrderFormat.FFOrderNew ffNew = new Client.OrderFormat.FFOrderNew
                        {
                            bhno = cbFFOrderCseq.SelectedItem.ToString().Split('-')[1],
                            cseq = cbFFOrderCseq.SelectedItem.ToString().Split('-')[2],
                            exchange = cbFFExchange.SelectedItem.ToString(),
                            bs1 = cbFFBS.SelectedItem.ToString(),
                            commtype1 = "F",
                            commo1 = cbFFCommo.SelectedItem.ToString(),
                            commym1 = cbFFCommoYM.Text.Split(',')[0],
                            stkPrice1 = Convert.ToDecimal(000000.000000),
                            cp1 = "N",
                            bs2 = "",
                            commtype2 = "",
                            commo2 = "",
                            commym2 = "",
                            stkPrice2 = 0,
                            cp2 = "",
                            otype = cbFFOTYPE.SelectedItem.ToString(),
                            price = decimal.Parse(txtFFPrice.Text.Trim()),
                            price_numerator = 0,
                            price_denominator = 0,
                            stopPrice = 0,
                            stopPrice_numerator = 0,
                            stopPrice_denominator = 0,
                            qty = int.Parse(txtFFQty.Text.Trim()),
                            dtFlag = txtFFDTrade.Text,
                            rtype = txtFFOffset.Text,
                            idno = txtIDNO.Text
                        };
                #endregion
                        strMsgCode = API.FFOrderNew(ffNew, out strMsg, ref strGUID);
                        break;
                    case "改量": // #改量
                #region 物件格式
                        Client.OrderFormat.FFOrderChangeQty ffChangeQty = new Client.OrderFormat.FFOrderChangeQty
                        {
                            tdate = DateTime.Now.ToString("yyyyMMdd"),
                            dseq = txtFFDseq.Text,
                            bhno = cbFFOrderCseq.SelectedItem.ToString().Split('-')[1],
                            cseq = cbFFOrderCseq.SelectedItem.ToString().Split('-')[2],
                            exchange = cbFFExchange.SelectedItem.ToString(),
                            sflag = "N",
                            bs1 = cbFFBS.SelectedItem.ToString(),
                            commtype1 = "F",
                            commo1 = cbFFCommo.SelectedItem.ToString(),
                            commym1 = cbFFCommoYM.Text.Split(',')[0],
                            stkPrice1 = Convert.ToDecimal(000000.000000),
                            cp1 = "N",
                            bs2 = "",
                            commtype2 = "",
                            commo2 = "",
                            commym2 = "",
                            stkPrice2 = 0,
                            cp2 = "",
                            otype = cbFFOTYPE.SelectedItem.ToString(),
                            price = decimal.Parse(txtFFPrice.Text.Trim()),
                            price_numerator = 00.00m,
                            price_denominator = 0,
                            stopPrice = 0,
                            stopPrice_numerator = 0,
                            stopPrice_denominator = 0,
                            oqty = int.Parse(txtFFQty.Text.Trim()),
                            dtFlag = txtFFDTrade.Text,
                            rtype = txtFFOffset.Text,
                            qty = int.Parse(txtFFQty.Text.Trim()),
                            idno = txtIDNO.Text
                        };
                #endregion
                        strMsgCode = API.FFOrderChangeQty(ffChangeQty, out strMsg, ref strGUID);
                        break;
                    case "刪單": // #刪單
                #region 物件格式
                        Client.OrderFormat.FFOrderDelete ffDelete = new Client.OrderFormat.FFOrderDelete
                        {
                            tdate = DateTime.Now.ToString("yyyyMMdd"),
                            dseq = txtFFDseq.Text,
                            bhno = cbFFOrderCseq.SelectedItem.ToString().Split('-')[1],
                            cseq = cbFFOrderCseq.SelectedItem.ToString().Split('-')[2],
                            exchange = cbFFExchange.SelectedItem.ToString(),
                            sflag = "N",
                            bs1 = cbFFBS.SelectedItem.ToString(),
                            commtype1 = "F",
                            commo1 = cbFFCommo.SelectedItem.ToString(),
                            commym1 = cbFFCommoYM.Text.Split(',')[0],
                            stkPrice1 = Convert.ToDecimal(000000.000000),
                            cp1 = "N",
                            bs2 = "",
                            commtype2 = "",
                            commo2 = "",
                            commym2 = "",
                            stkPrice2 = 0,
                            cp2 = "",
                            otype = cbFFOTYPE.SelectedItem.ToString(),
                            price = decimal.Parse(txtFFPrice.Text.Trim()),
                            price_numerator = 00.00m,
                            price_denominator = 0,
                            stopPrice = 0,
                            stopPrice_numerator = 0,
                            stopPrice_denominator = 0,
                            oqty = int.Parse(txtFFQty.Text.Trim()),
                            dtFlag = txtFFDTrade.Text,
                            rtype = txtFFOffset.Text,
                            idno = txtIDNO.Text
                        };
                #endregion
                        strMsgCode = API.FFOrderDelete(ffDelete, out strMsg, ref strGUID);
                        break;
                    case "改價": // #改價
                #region 物件格式
                        Client.OrderFormat.FFOrderChangePrice ffChangePrice = new Client.OrderFormat.FFOrderChangePrice
                        {
                            dseq = txtFFDseq.Text,
                            bhno = cbFFOrderCseq.SelectedItem.ToString().Split('-')[1],
                            cseq = cbFFOrderCseq.SelectedItem.ToString().Split('-')[2],
                            exchange = cbFFExchange.SelectedItem.ToString(),
                            sflag = "N",
                            bs1 = cbFFBS.SelectedItem.ToString(),
                            commtype1 = "F",
                            commo1 = cbFFCommo.SelectedItem.ToString(),
                            commym1 = cbFFCommoYM.Text.Split(',')[0],
                            stkPrice1 = Convert.ToDecimal(000000.000000),
                            cp1 = "N",
                            bs2 = "",
                            commtype2 = "",
                            commo2 = "",
                            commym2 = "",
                            stkPrice2 = 0,
                            cp2 = "",
                            otype = cbFFOTYPE.SelectedItem.ToString(),
                            price = decimal.Parse(txtFFPrice.Text.Trim()),
                            price_numerator = 00.00m,
                            price_denominator = 0,
                            stopPrice = 0,
                            stopPrice_numerator = 0,
                            stopPrice_denominator = 0,
                            oqty = int.Parse(txtFFQty.Text.Trim()),
                            dtFlag = txtFFDTrade.Text,
                            rtype = txtFFOffset.Text,
                        };
                #endregion
                        strMsgCode = API.FFOrderChangePrice(ffChangePrice, out strMsg, ref strGUID);
                        break;
                }
                lsFFStatus.Items.Insert(0,
$"{DateTime.Now.ToString("yyyyMMdd-HH:mm:ss.fff")}:{strMsgCode}:{strMsg}");
                ConcordLogger.Logger.Debug("GUID=" + strGUID);
#else
                #region 組下單字串，送下單

                String strBody = "";
                double price = double.Parse(txtFFPrice.Text);
                switch (cbFFMsgType.SelectedItem.ToString())
                {
                    case "新單":
                        strBody = "20103=" + strGUID + 
                                  "|60=" + DateTime.Now.ToString("yyyyMMdd") +
                                  "|50=" + cbFFOrderCseq.SelectedItem.ToString().Split('-')[1] + 
                                  "|1=" + cbFFOrderCseq.SelectedItem.ToString().Split('-')[2] +
                                  "|20025=O|20026=" + cbFFExchange.SelectedItem.ToString() + 
                                  "|20003=N|20012=" + cbFFBS.SelectedItem.ToString() + 
                                  "|20015=F|20011=" + cbFFCommo.SelectedItem.ToString() +
                                  "|20021=" + cbFFCommoYM.Text.Split(',')[0] + 
                                  "|20044=0|20022=N|20017=|20020=|20016=|20023=|20045=0|20024=|40=" + cbFFOTYPE.SelectedItem.ToString() + 
                                  "|20004=" + txtFFSign.Text + "|44=" + txtFFPrice.Text + 
                                  "|20027=0|20028=0|99=0|20029=0|20030=0|38=" + txtFFQty.Text +
                                  "|20032=" + txtFFDTrade.Text + "|20031=" + cbFFOCond.SelectedItem.ToString() + "|77=" + txtFFOffset.Text +
                                  "|10000=" + txtOrign.Text + "|20001=|21001=" + strData + "|21002=" + strSig + "|21003=" + strCert + "|21004=" + txtIDNO.Text;
                        strMsgCode = API.FFOrderNew(strBody, out strMsg);
                        break;
                    case "改量":
                        strBody = "20103=" + strGUID + 
                                  "|60=" + DateTime.Now.ToString("yyyyMMdd") +
                                  "|37=" + txtFFDseq.Text + 
                                  "|50=" + cbFFOrderCseq.SelectedItem.ToString().Split('-')[1] + 
                                  "|1=" + cbFFOrderCseq.SelectedItem.ToString().Split('-')[2] +
                                  "|20025=O|20026=" + cbFFExchange.SelectedItem.ToString() + 
                                  "|20003=N|20012=" + cbFFBS.SelectedItem.ToString() + 
                                  "|20015=F|20011=" + cbFFCommo.SelectedItem.ToString() +
                                  "|20021=" + cbFFCommoYM.Text.Split(',')[0] + 
                                  "|20044=0|20022=N|20017=|20020=|20016=|20023=|20045=0|20024=|40=" + cbFFOTYPE.SelectedItem.ToString() + 
                                  "|20004=" + txtFFSign.Text + "|44=" + txtFFPrice.Text + 
                                  "|20027=0|20028=0|99=0|20029=0|20030=0|20046=" + txtFFQty.Text +
                                  "|20032=" + txtFFDTrade.Text + "|20031=" + cbFFOCond.SelectedItem.ToString() + "|77=" + txtFFOffset.Text +
                                  "|20001=|20033=|10000=" + txtOrign.Text + "|38=" + txtFFQty.Text + "|20040=0|20042=0|20000=127.0.0.1|20034=0000000000|21001=" + strData + "|21002=" + strSig + "|21003=" + strCert + "|21004=" + txtIDNO.Text;
                        strMsgCode = API.FFOrderChangeQty(strBody, out strMsg);
                        break;
                    case "刪單":
                        strBody = "20103=" + strGUID + 
                                  "|60=" + DateTime.Now.ToString("yyyyMMdd") +
                                  "|37=" + txtFFDseq.Text + 
                                  "|50=" + cbFFOrderCseq.SelectedItem.ToString().Split('-')[1] + 
                                  "|1=" + cbFFOrderCseq.SelectedItem.ToString().Split('-')[2] +
                                  "|20025=O|20026=" + cbFFExchange.SelectedItem.ToString() + 
                                  "|20003=N|20012=" + cbFFBS.SelectedItem.ToString() + 
                                  "|20015=F|20011=" + cbFFCommo.SelectedItem.ToString() +
                                  "|20021=" + cbFFCommoYM.Text.Split(',')[0] + 
                                  "|20044=0|20022=N|20017=|20020=|20016=|20023=|20045=0|20024=|40=" + cbFFOTYPE.SelectedItem.ToString() + 
                                  "|20004=" + txtFFSign.Text + "|44=" + txtFFPrice.Text + 
                                  "|20027=0|20028=0|99=0|20029=0|20030=0|20046=" + txtFFQty.Text +
                                  "|20032=" + txtFFDTrade.Text + "|20031=" + cbFFOCond.SelectedItem.ToString() + 
                                  "|77=" + txtFFOffset.Text +
                                  "|20001=|20033=|10000=" + txtOrign.Text + 
                                  "|20041=0|20042=0|20034=0000000000|21001=" + strData + 
                                  "|21002=" + strSig + "|21003=" + strCert + "|21004=" + txtIDNO.Text;
                        strMsgCode = API.FFOrderDelete(strBody, out strMsg);
                        break;
                    case "改價":
                        strBody = "20103=" + strGUID +
                              "|60=" + DateTime.Now.ToString("yyyyMMdd") +
                              "|37=" + txtFFDseq.Text +
                              "|50=" + cbFFOrderCseq.SelectedItem.ToString().Split('-')[1] +
                              "|1=" + cbFFOrderCseq.SelectedItem.ToString().Split('-')[2] +
                              "|20025=O|20026=" + cbFFExchange.SelectedItem.ToString() +
                              "|20003=N|20012=" + cbFFBS.SelectedItem.ToString() +
                              "|20015=F|20011=" + cbFFCommo.SelectedItem.ToString() +
                              "|20021=" + cbFFCommoYM.Text.Split(',')[0] +
                              "|20044=0|20022=N|20017=|20020=|20016=|20023=|20045=0|20024=|40=" + cbFFOTYPE.SelectedItem.ToString() +
                              "|20004=" + txtFFSign.Text + "|44=" + txtFFPrice.Text +
                              "|20027=0|20028=0|99=0|20029=0|20030=0|20046=" + txtFFQty.Text +
                              "|20032=" + txtFFDTrade.Text +
                              "|77=" + txtFFOffset.Text +
                              "|10000=" + txtOrign.Text +
                              "|20001=|21001=" + strData +
                              "|21002=" + strSig + "|21003=" + strCert + "|21004=" + txtIDNO.Text + "|20048=";
                        strMsgCode = API.FFOrderChangePrice(strBody, out strMsg);
                        break;
                }
                lsFFStatus.Items.Insert(0,
$"{DateTime.Now.ToString("yyyyMMdd-HH:mm:ss.fff")}:{strMsgCode}:{strMsg}");
                #endregion
#endif
            }
        }

        private void btnFFQuery_Click(object sender, EventArgs e)
        {
            String strMsg = "";
            String strMsgCode = "";
            String strBhno = cbFFBillCseq.SelectedItem.ToString().Split('-')[0];
            String strCseq = cbFFBillCseq.SelectedItem.ToString().Split('-')[1];
            String strQuery = cbFFBillItems.SelectedItem.ToString().Split('-')[1];
            String strSubCSEQ = txbSubAccount.Text;
            String strSDate = txtFFBillSDate.Text;
            String strEDate = txtFFBillEDate.Text;

            switch (strQuery)
            {
                case "FFQueryTOrder":
                    strMsgCode = API.FFQueryTOrder(strBhno, strCseq, out strMsg);
                    break;
                case "FFQueryHOrder":
                    strMsgCode = API.FFQueryHOrder(strBhno, strCseq, strSDate, strEDate, out strMsg);
                    break;
                case "FFQueryTDeal":
                    strMsgCode = API.FFQueryTDeal(strBhno, strCseq, out strMsg);
                    break;
                case "FFQueryHDeal":
                    strMsgCode = API.FFQueryHDeal(strBhno, strCseq, strSDate, strEDate, out strMsg);
                    break;
                case "FFSQueryTOrder":
                    strMsgCode = API.FFSQueryTOrder(strBhno, strCseq, strSubCSEQ, out strMsg);
                    break;
                case "FFSQueryHOrder":
                    strMsgCode = API.FFSQueryHOrder(strBhno, strCseq, strSubCSEQ, strSDate, strEDate, out strMsg);
                    break;
                case "FFSQueryTDeal":
                    strMsgCode = API.FFSQueryTDeal(strBhno, strCseq, strSubCSEQ, out strMsg);
                    break;
                case "FFSQueryHDeal":
                    strMsgCode = API.FFSQueryHDeal(strBhno, strCseq, strSubCSEQ, strSDate, strEDate, out strMsg);
                    break;
                case "FFQueryMargin":
                    strMsgCode = API.FFQueryMargin(strBhno, strCseq, out strMsg);
                    break;
                case "FFQueryPosition":
                    strMsgCode = API.FFQueryPosition(strBhno, strCseq, out strMsg);
                    break;
                case "FFQueryPositionIndex":
                    strMsgCode = API.FFQueryPositionIndex(strBhno, strCseq, out strMsg);
                    break;
                case "FFQueryOffset":
                    strMsgCode = API.FFQueryOffset(strBhno, strCseq, out strMsg);
                    break;
                case "FFQueryHisOffset":
                    strMsgCode = API.FFQueryHisOffset(strBhno, strCseq, strSDate, strEDate, out strMsg);
                    break;
                case "FFQueryDeposit":
                    strMsgCode = API.FFQueryDeposit(strBhno, strCseq, out strMsg);
                    break;
                case "FFQueryHisDeposit":
                    strMsgCode = API.FFQueryHisDeposit(strBhno, strCseq, strSDate, strEDate, out strMsg);
                    break;
                case "FFQueryBulletin":
                    strMsgCode = API.FFQueryBulletin(DateTime.Now.ToString("yyyyMMdd"), out strMsg);
                    break;
#if (SPEEDY)
                case "FFSQueryTDealDetailByAccount":
                    strMsgCode = API.FFSQueryTDealDetailByAccount(strBhno, strCseq, out strMsg);
                    break;
#endif

            }

            lsFFBill.Items.Clear();
            ConcordLogger.Logger.Debug($"查詢回報:{strMsg}");
            if (strMsgCode == "000")
            {
                foreach (String s in strMsg.Split((Char)0x0a))
                {
                    lsFFBill.Items.Add(s);
                }
            }
            else
            {
                lsFFStatus.Items.Insert(0,
$"{DateTime.Now.ToString("yyyyMMdd-HH:mm:ss.fff")}:{strMsgCode}:{strMsg}");
            }

        }

        private void btnFFRecover_Click(object sender, EventArgs e)
        {
            if (cbFFOrderCseq.SelectedItem == null)
            {
                MessageBox.Show("當未輸入帳號");
                return;
            }

            String strMsg = "";
            String strMsgCode = "";
            String strBhno = cbFFOrderCseq.SelectedItem.ToString().Split('-')[1];
            String strCseq = cbFFOrderCseq.SelectedItem.ToString().Split('-')[2];
            strMsgCode = API.FFOrderRecover(strBhno, strCseq, txtFFSeqStart.Text, txtFFSeqEnd.Text, out strMsg);

            lsFFStatus.Items.Insert(0,
$"{DateTime.Now.ToString("yyyyMMdd-HH:mm:ss.fff")}:{strMsgCode}:{strMsg}");
        }

        private void btnFFQOrder_Click(object sender, EventArgs e)
        {
            dgvFFOrder.DataSource = null;
            DataTable dtResult = new DataTable();

            foreach (string str in htSvc["FF_QTOrder"].ToString().Split(','))
            {
                dtResult.Columns.Add(str);
            }

            String strMsg = "";
            String strMsgCode = "";
            String strBhno = cbFFOrderCseq.SelectedItem.ToString().Split('-')[1];
            String strCseq = cbFFOrderCseq.SelectedItem.ToString().Split('-')[2];
            strMsgCode = API.FFQueryTOrder(strBhno, strCseq, out strMsg);

            if (strMsgCode == "000")
            {
                foreach (String s in strMsg.Split((Char)0x0a))
                {
                    dtResult.Rows.Add(s.Split(','));
                }
            }
            else
            {
                lsFFStatus.Items.Insert(0,
$"{DateTime.Now.ToString("yyyyMMdd-HH:mm:ss.fff")}:{strMsgCode}:{strMsg}");
            }

            dgvFFOrder.DataSource = dtResult;
        }

        private void btnSubOrder_Click(object sender, EventArgs e)
        {
            String strMsg = "";
            String strMsgCode = "";
            String strSig = "";
            String strCert = "";
            String strData = "TestData";
            strMsgCode = API.GetSignature(txtIDNO.Text, strData, out strSig, out strCert, out strMsg);

            lsFStatus.Items.Insert(0,
$"{DateTime.Now.ToString("yyyyMMdd-HH:mm:ss.fff")}:{strMsgCode}:{strMsg}");

            if (strMsgCode == "120")
            {
#if !(COMMON || COMMON64)
                #region 組下單字串，送下單
                String strGUID = Guid.NewGuid().ToString();
                String strBody = "";
                switch (cbFFMsgType.SelectedItem.ToString())
                {
                    case "01":
                        strBody = "20103=" + strGUID + "|60=" + DateTime.Now.ToString("yyyyMMdd") +
                                  "|50=" + cbFFOrderCseq.SelectedItem.ToString().Split('-')[1] + "|1=" + cbFFOrderCseq.SelectedItem.ToString().Split('-')[2] + "|20048=" + txbSubAccount.Text +
                                  "|20025=O|20026=" + cbFFExchange.SelectedItem.ToString() + "|20003=N|20012=" + cbFFBS.SelectedItem.ToString() + "|20015=F|20011=" + cbFFCommo.SelectedItem.ToString() +
                                  "|20021=" + cbFFCommoYM.SelectedItem.ToString() + "|20044=000000.000000|20022=N|20017=|20020=" +
                                  "|20016=|20023=|20045=0|20024=|40=" + cbFFOTYPE.SelectedItem.ToString() + "|20004=" + txtFFSign.Text + "|44=" + txtFFPrice.Text + "|20027=0|20028=0|99=0|20029=0|20030=0|38=" + txtFFQty.Text +
                                  "|20032=" + txtFFDTrade.Text + "|20031=" + cbFFOCond.SelectedItem.ToString() + "|77=" + txtFFOffset.Text +
                                  "|10000=X|20001=|21001=" + strData + "|21002=" + strSig + "|21003=" + strCert + "|21004=" + txtIDNO.Text;
                        //strHead = String.Format(strHead, Encoding.GetEncoding("Big5").GetBytes(strBody).Length.ToString().PadLeft(5, '0'));
                        strMsgCode = API.FFOrderNew(strBody, out strMsg);
                        break;
                    case "02":
                        strBody = "20103=" + strGUID + "|60=" + DateTime.Now.ToString("yyyyMMdd") +
                                  "|37=" + txtFFDseq.Text + "|50=" + cbFFOrderCseq.SelectedItem.ToString().Split('-')[1] + "|1=" + cbFFOrderCseq.SelectedItem.ToString().Split('-')[2] + "|20048=" + txbSubAccount.Text +
                                  "|20025=O|20026=" + cbFFExchange.SelectedItem.ToString() + "|20003=N|20012=" + cbFFBS.SelectedItem.ToString() + "|20015=F|20011=" + cbFFCommo.SelectedItem.ToString() +
                                  "|20021=" + cbFFCommoYM.SelectedItem.ToString() + "|20044=000000.000000|20022=N|20017=|20020=" +
                                  "|20016=|20023=|20045=0|20024=|40=" + cbFFOTYPE.SelectedItem.ToString() + "|20004=" + txtFFSign.Text + "|44=" + txtFFPrice.Text + "|20027=0|20028=0|99=0|20029=0|20030=0|20046=" + txtFFQty.Text +
                                  "|20032=" + txtFFDTrade.Text + "|20031=" + cbFFOCond.SelectedItem.ToString() + "|77=" + txtFFOffset.Text +
                                  "|20001=|20033=|10000=" + txtOrign.Text + "|38=" + txtFFQty.Text + "|20040=0|20042=0|20000=127.0.0.1|20034=0000000000|21001=" + strData + "|21002=" + strSig + "|21003=" + strCert + "|21004=" + txtIDNO.Text;
                        //strHead = String.Format(strHead, Encoding.GetEncoding("Big5").GetBytes(strBody).Length.ToString().PadLeft(5, '0'));
                        strMsgCode = API.FFOrderChangeQty(strBody, out strMsg);
                        break;
                    case "03":
                        strBody = "20103=" + strGUID + "|60=" + DateTime.Now.ToString("yyyyMMdd") +
                                  "|37=" + txtFFDseq.Text + "|50=" + cbFFOrderCseq.SelectedItem.ToString().Split('-')[1] + "|1=" + cbFFOrderCseq.SelectedItem.ToString().Split('-')[2] + "|20048=" + txbSubAccount.Text +
                                  "|20025=O|20026=" + cbFFExchange.SelectedItem.ToString() + "|20003=N|20012=" + cbFFBS.SelectedItem.ToString() + "|20015=F|20011=" + cbFFCommo.SelectedItem.ToString() +
                                  "|20021=" + cbFFCommoYM.SelectedItem.ToString() + "|20044=000000.000000|20022=N|20017=|20020=" +
                                  "|20016=|20023=|20045=0|20024=|40=" + cbFFOTYPE.SelectedItem.ToString() + "|20004=" + txtFFSign.Text + "|44=" + txtFFPrice.Text + "|20027=0|20028=0|99=0|20029=0|20030=0|20046=" + txtFFQty.Text +
                                  "|20032=" + txtFFDTrade.Text + "|20031=" + cbFFOCond.SelectedItem.ToString() + "|77=" + txtFFOffset.Text +
                                  "|20001=|20033=|10000=" + txtOrign.Text + "|20041=0|20042=0|20034=0000000000|21001=" + strData + "|21002=" + strSig + "|21003=" + strCert + "|21004=" + txtIDNO.Text;
                        //strHead = String.Format(strHead, Encoding.GetEncoding("Big5").GetBytes(strBody).Length.ToString().PadLeft(5, '0'));
                        strMsgCode = API.FFOrderDelete(strBody, out strMsg);
                        break;
                }
                lsFFStatus.Items.Insert(0,
$"{DateTime.Now.ToString("yyyyMMdd-HH:mm:ss.fff")}:{strMsgCode}:{strMsg}");
                #endregion
#else
#endif
            }
        }
        #endregion

        #region 國內期
        private void btnFCheckConnect_Click(object sender, EventArgs e)
        {
            String strMsg = "";
            String strMsgCode = "";
            strMsgCode = API.FCheckConnect(out strMsg);
            lsFStatus.Items.Insert(0,
$"{DateTime.Now.ToString("yyyyMMdd-HH:mm:ss.fff")}:{strMsgCode}:{strMsg}");
        }

        private void btnFAccList_Click(object sender, EventArgs e)
        {
            String strMsg = "";
            String strMsgCode = "";
            strMsgCode = API.FQueryAccountInfo(out strMsg);
            cbFOrderCseq.Items.Clear();
            cbFBillCseq.Items.Clear();
            String[] strList = strMsg.Split((Char)0x0a);

            foreach (String s in strList)
            {
                cbFOrderCseq.Items.Add(s.Split(',')[1] + "-" + s.Split(',')[3] + "-" + s.Split(',')[4] + "-" + s.Split(',')[5]);
                cbFBillCseq.Items.Add(s.Split(',')[3] + "-" + s.Split(',')[4]);
            }

            cbFOrderCseq.SelectedIndex = 0;
            cbFBillCseq.SelectedIndex = 0;
        }

        private void btnFQueryInfo_Click(object sender, EventArgs e)
        {
            //Stopwatch stopWatch = new Stopwatch();
            String strMsg = "";
            String strMsgCode = "";
            g_listFCommodity.Clear();
            g_listFCommoYM.Clear();

            //stopWatch.Start();
            strMsgCode = API.FQueryCommo(out strMsg);
            //stopWatch.Stop();
            //TimeSpan ts = stopWatch.Elapsed;
            //string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10);
            //Console.WriteLine($"API.FQueryCommo:{elapsedTime}");
            //stopWatch.Restart();
            if (strMsgCode == "000")
            {
                String[] strList = strMsg.Split((Char)0x0a);
                foreach (String s in strList)
                {
                    string[] f = s.Split(',');
                    // dtFCommo.Rows.Add(f);
                    FCommodityElf elf = new FCommodityElf()
                    {
                        交易所 = f[0],
                        商品 = f[1],
                        類別 = f[2],
                        交易幣別 = f[3],
                        中文名稱 = f[4],
                        契約規格 = f[5],
                        交易稅率 = f[6],
                        股票代號 = f[7],
                        股數 = f[8],
                        中文簡稱 = f[9],
                        期權對應期貨代號 = f[10],
                        最小跳動點 = f[11]
                    };
                    g_listFCommodity.Add(elf.商品, elf);
                    g_listFCommoYM.Add(elf.商品, new SortedDictionary<string, FCommoymElf>());
                }
                //ts = stopWatch.Elapsed;
                //elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10);
                //Console.WriteLine($"API.FQueryCommo處理時間:{elapsedTime}");

                //foreach (DataRow dr in dtFCommo.Rows)
                //{
                //    cbFCommo.Items.Add(dr["COMMO"].ToString());
                //}
            }
            //stopWatch.Restart();
            strMsgCode = API.FQueryCommoYM(out strMsg);
            //stopWatch.Stop();
            //ts = stopWatch.Elapsed;
            //elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10);
            //Console.WriteLine($"API.FQueryCommoYM:{elapsedTime}");
            //stopWatch.Restart();
            if (strMsgCode == "000")
            {
                String[] strList = strMsg.Split((Char)0x0a);
                foreach (String s in strList)
                {
                    string[] f = s.Split(',');
                    dtFCommoYM.Rows.Add(f);
                    FCommoymElf elf = new FCommoymElf()
                    {
                        商品代號 = f[0],
                        交割年月 = f[1],
                        履約價 = f[2],
                        期權CP = f[3],
                        上市日期 = f[4],
                        下市日期 = f[5],
                        漲停價 = f[6],
                        跌停價 = f[7],
                        權利金 = f[8],
                        第二漲停價 = f[9],
                        第二跌停價 = f[10],
                        第三漲停價 = f[11],
                        第三跌停價 = f[12],
                        契約種類 = f[13],
                        是否可報價 = f[14],
                        價格欄位小數位 = f[15],
                        商品序號 = f[16],
                        流程群組 = f[17],
                        最後結算日 = f[18],
                        履約價格小數位數 = f[19]
                    };
                    string 商品 = elf.商品代號.Substring(0, 3);
                    if (g_listFCommoYM.ContainsKey(商品))
                    {
                        g_listFCommoYM[商品].Add(elf.商品代號, elf);
                    }
                    else
                    {
                        // Console.WriteLine($"不存在{elf.商品代號}");
                    }
                }
                //stopWatch.Stop();
                //ts = stopWatch.Elapsed;
                //elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10);
                //Console.WriteLine($"API.FQueryCommoYM處理時間:{elapsedTime}");
            }

            cbFMType.SelectedIndex = 0;
        }

        private void btnFOrderClear_Click(object sender, EventArgs e)
        {
            lsFOrderRcv.Items.Clear();
        }

        private void btnFOrder_Click(object sender, EventArgs e)
        {
            String strMsg = "";
            String strMsgCode = "";
            String strSig = "";
            String strCert = "";
            String strData = "TestData";
            //String strGUID = "";
            strMsgCode = API.GetSignature(txtIDNO.Text.ToUpper(), strData, out strSig, out strCert, out strMsg);

            lsFStatus.Items.Insert(0,
$"{DateTime.Now.ToString("yyyyMMdd-HH:mm:ss.fff")}:{strMsgCode}:{strMsg}");
            string comno = txtComno.Text;
            String strGUID = Guid.NewGuid().ToString();
            if (strMsgCode == "120")
            {
#if !(COMMON || COMMON64)
                #region 組下單字串，送下單

                String strBody = "";
                switch (cbFMsgType.SelectedItem.ToString())
                {
                    case "新單":
                        strBody = "20103=" + strGUID + "|60=" + DateTime.Now.ToString("yyyyMMdd") +
                                  "|50=" + cbFOrderCseq.SelectedItem.ToString().Split('-')[1] + "|1=" + cbFOrderCseq.SelectedItem.ToString().Split('-')[2] +
                                  "|56=" + cbFMType.SelectedItem.ToString() + "|20003=" + cbFSingleFlag.SelectedItem.ToString() + "|55=" + comno + "|59=" + cbFFIR.SelectedItem.ToString() + "|77=" + txtFOffset.Text +
                                  "|40=" + cbFOTYPE.SelectedItem.ToString() + "|54=" + cbFBS.SelectedItem.ToString() + "|38=" + txtFQty.Text + "|20004=" + txtFSign.Text + "|44=" + txtFPrice.Text +
                                  "|10000=X|20001=" + cbFOrderCseq.SelectedItem.ToString().Split('-')[3] + "|21001=" + strData + "|21002=" + strSig + "|21003=" + strCert + "|21004=" + txtIDNO.Text;
                        //"|10000=X|20001=" + cbFOrderCseq.SelectedItem.ToString().Split('-')[3] + "|21001=" + strData + "|21002=" + strSig + "|21003=" + strCert + "|21004=";
                        strMsgCode = API.FOrderNew(strBody, out strMsg);
                        break;
                    case "改量":
                        strBody = "20103=" + strGUID + "|60=" + DateTime.Now.ToString("yyyyMMdd") + "|41=" + txtFSeqno.Text + "|37=" + txtFDseq.Text +
                                  "|50=" + cbFOrderCseq.SelectedItem.ToString().Split('-')[1] + "|1=" + cbFOrderCseq.SelectedItem.ToString().Split('-')[2] +
                                  "|56=" + cbFMType.SelectedItem.ToString() + "|20003=" + cbFSingleFlag.SelectedItem.ToString() + "|55=" + comno + "|59=" + cbFFIR.SelectedItem.ToString() + "|77=" + txtFOffset.Text +
                                  "|40=" + cbFOTYPE.SelectedItem.ToString() + "|54=" + cbFBS.SelectedItem.ToString() + "|38=" + txtFQty.Text + "|20004=" + txtFSign.Text + "|44=" + txtFPrice.Text +
                                  "|10000=X|20001=" + cbFOrderCseq.SelectedItem.ToString().Split('-')[3] + "|21001=" + strData + "|21002=" + strSig + "|21003=" + strCert + "|21004=" + txtIDNO.Text;
                        strMsgCode = API.FOrderChangeQty(strBody, out strMsg);
                        break;
                    case "刪單":
                        strBody = "20103=" + strGUID + "|60=" + DateTime.Now.ToString("yyyyMMdd") + "|41=" + txtFSeqno.Text + "|37=" + txtFDseq.Text +
                                  "|50=" + cbFOrderCseq.SelectedItem.ToString().Split('-')[1] + "|1=" + cbFOrderCseq.SelectedItem.ToString().Split('-')[2] +
                                  "|56=" + cbFMType.SelectedItem.ToString() + "|20003=" + cbFSingleFlag.SelectedItem.ToString() + "|55=" + comno + "|59=" + cbFFIR.SelectedItem.ToString() + "|77=" + txtFOffset.Text +
                                  "|40=" + cbFOTYPE.SelectedItem.ToString() + "|54=" + cbFBS.SelectedItem.ToString() + "|38=" + txtFQty.Text + "|20004=" + txtFSign.Text + "|44=" + txtFPrice.Text +
                                  "|10000=X|20001=" + cbFOrderCseq.SelectedItem.ToString().Split('-')[3] + "|21001=" + strData + "|21002=" + strSig + "|21003=" + strCert + "|21004=" + txtIDNO.Text;
                        strMsgCode = API.FOrderDelete(strBody, out strMsg);
                        break;
                    case "改價":
                        strBody = "20103=" + strGUID + "|60=" + DateTime.Now.ToString("yyyyMMdd") + "|41=" + txtFSeqno.Text + "|37=" + txtFDseq.Text +
                                  "|50=" + cbFOrderCseq.SelectedItem.ToString().Split('-')[1] + "|1=" + cbFOrderCseq.SelectedItem.ToString().Split('-')[2] +
                                  "|56=" + cbFMType.SelectedItem.ToString() + "|20003=" + cbFSingleFlag.SelectedItem.ToString() + "|55=" + comno + "|59=" + cbFFIR.SelectedItem.ToString() + "|77=" + txtFOffset.Text +
                                  "|40=" + cbFOTYPE.SelectedItem.ToString() + "|54=" + cbFBS.SelectedItem.ToString() + "|38=" + txtFQty.Text + "|20004=" + txtFSign.Text + "|44=" + txtFPrice.Text +
                                  "|10000=X|20001=" + cbFOrderCseq.SelectedItem.ToString().Split('-')[3] + "|21001=" + strData + "|21002=" + strSig + "|21003=" + strCert + "|21004=" + txtIDNO.Text;
                        strMsgCode = API.FOrderDelete(strBody, out strMsg);
                        break;
                }
                lsFStatus.Items.Insert(0,
$"{DateTime.Now.ToString("yyyyMMdd-HH:mm:ss.fff")}:{strMsgCode}:{strMsg}");
                #endregion
#else
                switch (cbFMsgType.SelectedItem.ToString())
                {
                    case "新單":
                #region 物件格式
                        //string commo = "";
                        //switch (cbFSingleFlag.SelectedItem.ToString())
                        //{
                        //    case "1":
                        //    case "2":
                        //        commo = cbFCommo1.SelectedItem.ToString();
                        //        break;
                        //    case "3":
                        //        break;
                        //    case "4":
                        //        break;
                        //}
                        Client.OrderFormat.FOrderNew fNew = new Client.OrderFormat.FOrderNew
                        {
                            bhno = cbFOrderCseq.SelectedItem.ToString().Split('-')[1],
                            cseq = cbFOrderCseq.SelectedItem.ToString().Split('-')[2],
                            mtype = cbFMType.SelectedItem.ToString(),
                            sflag = cbFSingleFlag.SelectedItem.ToString(),
                            commo = comno,
                            fir = cbFFIR.SelectedItem.ToString(),
                            rtype = txtFOffset.Text,
                            otype = cbFOTYPE.SelectedItem.ToString(),
                            bs = cbFBS.SelectedItem.ToString(),
                            qty = int.Parse(txtFQty.Text.Trim()),
                            price = decimal.Parse(txtFPrice.Text.Trim())
                        };
                #endregion
                        strMsgCode = API.FOrderNew(fNew, out strMsg, ref strGUID);
                        break;
                    case "改量":
                #region 物件格式
                        Client.OrderFormat.FOrderChangeQty fChangeQty = new Client.OrderFormat.FOrderChangeQty
                        {
                            tdate = DateTime.Now.ToString("yyyyMMdd"),
                            netno = txtFSeqno.Text,
                            dseq = txtFDseq.Text,
                            bhno = cbFOrderCseq.SelectedItem.ToString().Split('-')[1],
                            cseq = cbFOrderCseq.SelectedItem.ToString().Split('-')[2],
                            mtype = cbFMType.SelectedItem.ToString(),
                            sflag = cbFSingleFlag.SelectedItem.ToString(),
                            commo = comno,
                            fir = cbFFIR.SelectedItem.ToString(),
                            rtype = txtFOffset.Text,
                            otype = cbFOTYPE.SelectedItem.ToString(),
                            bs = cbFBS.SelectedItem.ToString(),
                            qty = int.Parse(txtFQty.Text.Trim()),
                            price = decimal.Parse(txtFPrice.Text.Trim())
                        };
                #endregion
                        strMsgCode = API.FOrderChangeQty(fChangeQty, out strMsg, ref strGUID);
                        break;
                    case "刪單":
                #region 物件格式
                        Client.OrderFormat.FOrderDelete fDelete = new Client.OrderFormat.FOrderDelete
                        {
                            tdate = DateTime.Now.ToString("yyyyMMdd"),
                            netno = txtFSeqno.Text,
                            dseq = txtFDseq.Text,
                            bhno = cbFOrderCseq.SelectedItem.ToString().Split('-')[1],
                            cseq = cbFOrderCseq.SelectedItem.ToString().Split('-')[2],
                            mtype = cbFMType.SelectedItem.ToString(),
                            sflag = cbFSingleFlag.SelectedItem.ToString(),
                            commo = comno,
                            fir = cbFFIR.SelectedItem.ToString(),
                            rtype = txtFOffset.Text,
                            otype = cbFOTYPE.SelectedItem.ToString(),
                            bs = cbFBS.SelectedItem.ToString(),
                            qty = int.Parse(txtFQty.Text.Trim()),
                            price = decimal.Parse(txtFPrice.Text.Trim())
                        };
                #endregion
                        strMsgCode = API.FOrderDelete(fDelete, out strMsg, ref strGUID);
                        break;
                    case "改價":
                #region 物件格式
                        Client.OrderFormat.FOrderChangePrice fChangePrice = new Client.OrderFormat.FOrderChangeQty
                        {
                            tdate = DateTime.Now.ToString("yyyyMMdd"),
                            netno = txtFSeqno.Text,
                            dseq = txtFDseq.Text,
                            bhno = cbFOrderCseq.SelectedItem.ToString().Split('-')[1],
                            cseq = cbFOrderCseq.SelectedItem.ToString().Split('-')[2],
                            mtype = cbFMType.SelectedItem.ToString(),
                            sflag = cbFSingleFlag.SelectedItem.ToString(),
                            commo = comno,
                            fir = cbFFIR.SelectedItem.ToString(),
                            rtype = txtFOffset.Text,
                            otype = cbFOTYPE.SelectedItem.ToString(),
                            bs = cbFBS.SelectedItem.ToString(),
                            qty = int.Parse(txtFQty.Text.Trim()),
                            price = decimal.Parse(txtFPrice.Text.Trim())
                        };
                #endregion
                        strMsgCode = API.FOrderChangePrice(fChangePrice, out strMsg, ref strGUID);
                        break;
                }
                lsFStatus.Items.Insert(0,
$"{DateTime.Now.ToString("yyyyMMdd-HH:mm:ss.fff")}:{strMsgCode}:{strMsg}");
                ConcordLogger.Logger.Debug("GUID=" + strGUID);
#endif
            }
        }

        private void btnFStatusClear_Click(object sender, EventArgs e)
        {
            lsFStatus.Items.Clear();
        }

        private void btnFQuery_Click(object sender, EventArgs e)
        {
            String strMsg = "";
            String strMsgCode = "";
            String strBhno = cbFBillCseq.SelectedItem.ToString().Split('-')[0];
            String strCseq = cbFBillCseq.SelectedItem.ToString().Split('-')[1];
            String strQuery = cbFBillItems.SelectedItem.ToString().Split('-')[1];
            String strSDate = txtFBillSDate.Text;
            String strEDate = txtFBillEDate.Text;
            string strDesq = txtDseq.Text.Trim();

            switch (strQuery)
            {
                case "FQueryTOrder":
                    strMsgCode = API.FQueryTOrder(strBhno, strCseq, out strMsg);
                    break;
                case "FQueryHOrder":
                    strMsgCode = API.FQueryHOrder(strBhno, strCseq, strSDate, strEDate, out strMsg);
                    break;
                case "FQueryTDeal":
                    strMsgCode = API.FQueryTDeal(strBhno, strCseq, out strMsg);
                    break;
                case "FQueryHDeal":
                    strMsgCode = API.FQueryHDeal(strBhno, strCseq, strSDate, strEDate, out strMsg);
                    break;
                case "FQueryMargin":
                    strMsgCode = API.FQueryMargin(strBhno, strCseq, "ALL", "", "", out strMsg);
                    break;
                case "FQueryPosition":
                    strMsgCode = API.FQueryPosition(strBhno, strCseq, "", "", "3", out strMsg);
                    break;
                case "FQueryPositionSummary":
                    strMsgCode = API.FQueryPositionSummary(strBhno, strCseq, "3", out strMsg);
                    break;
                case "FQueryPositionIndex":
                    strMsgCode = API.FQueryPositionIndex(strBhno, strCseq, out strMsg);
                    break;
                case "FQueryOffset":
                    strMsgCode = API.FQueryOffset(strBhno, strCseq, out strMsg);
                    break;
                case "FQueryHisOffset":
                    strMsgCode = API.FQueryHisOffset(strBhno, strCseq, strSDate, strEDate, out strMsg);
                    break;
                case "FQueryDeposit":
                    strMsgCode = API.FQueryDeposit(strBhno, strCseq, out strMsg);
                    break;
                case "FQueryHisDeposit":
                    strMsgCode = API.FQueryHisDeposit(strBhno, strCseq, strSDate, strEDate, out strMsg);
                    break;
                case "FQueryBulletin":
                    strMsgCode = API.FQueryBulletin(DateTime.Now.ToString("yyyyMMdd"), out strMsg);
                    break;
#if (SPEEDY || SPEEDY64)
                case "FQOrderCost":
                    strMsgCode = API.FQOrderCost(strCseq, cbFCommo.SelectedItem.ToString(), "201903", " ", " ", cbFBS.SelectedItem.ToString(), "9950", " ", " ", " ", " ", " ", " ", out strMsg);
                    break;
                case "FQPreOrderSetting":
                    strMsgCode = API.FQPreOrderSetting(out strMsg);
                    break;
                case "FQueryTDealDetail":
                    strMsgCode = API.FQueryTDealDetail(strBhno, strCseq, strDesq, out strMsg);
                    break;
                case "FQueryTDealDetailByAccount":
                    strMsgCode = API.FQueryTDealDetailByAccount(strBhno, strCseq, out strMsg);
                    break;
#endif
            }

            lsFBill.Items.Clear();
            ConcordLogger.Logger.Debug($"查詢回報:{strMsg}");

            if (strMsgCode == "000")
            {
                foreach (String s in strMsg.Split((Char)0x0a))
                {
                    lsFBill.Items.Add(s);
                }
            }
            else
            {
                lsFStatus.Items.Insert(0,
$"{DateTime.Now.ToString("yyyyMMdd-HH:mm:ss.fff")}:{strMsgCode}:{strMsg}");
            }
        }

        private void btnFRecover_Click(object sender, EventArgs e)
        {
            String strMsg = "";
            String strMsgCode = "";
            String strBhno = cbFOrderCseq.SelectedItem.ToString().Split('-')[1];
            String strCseq = cbFOrderCseq.SelectedItem.ToString().Split('-')[2];
            strMsgCode = API.FOrderRecover(strBhno, strCseq, txtFSeqStart.Text, txtFSeqEnd.Text, out strMsg);

            lsFStatus.Items.Insert(0,
$"{DateTime.Now.ToString("yyyyMMdd-HH:mm:ss.fff")}:{strMsgCode}:{strMsg}");
        }

        private void btnFQOrder_Click(object sender, EventArgs e)
        {
            dgvFOrder.DataSource = null;
            DataTable dtResult = new DataTable();

            foreach (string str in htSvc["F_QTOrder"].ToString().Split(','))
            {
                dtResult.Columns.Add(str);
            }

            String strMsg = "";
            String strMsgCode = "";
            String strBhno = cbFOrderCseq.SelectedItem.ToString().Split('-')[1];
            String strCseq = cbFOrderCseq.SelectedItem.ToString().Split('-')[2];
            strMsgCode = API.FQueryTOrder(strBhno, strCseq, out strMsg);

            if (strMsgCode == "000")
            {
                foreach (String s in strMsg.Split((Char)0x0a))
                {
                    dtResult.Rows.Add(s.Split(','));
                }
            }
            else
            {
                lsFStatus.Items.Insert(0,
$"{DateTime.Now.ToString("yyyyMMdd-HH:mm:ss.fff")}:{strMsgCode}:{strMsg}");
            }

            dgvFOrder.DataSource = dtResult;
        }
        #endregion
        #endregion

        #region ComboBox事件
        #region 外期
        private void cbFFExchange_SelectedIndexChanged(object sender, EventArgs e)
        {
            //cbFFCommo.Items.Clear();
            //String strExh = cbFFExchange.SelectedItem.ToString();

            //foreach (DataRow dr in dtFFCommo.Select("Exh = '" + strExh + "'"))
            //{
            //    cbFFCommo.Items.Add(dr["CommoID"].ToString());
            //}

            //if (cbFFCommo.Items.Count > 0)
            //{
            //    cbFFCommo.SelectedIndex = 0;
            //}
            ComboBox control = sender as ComboBox;
            cbFFCommo.Items.Clear();
            cbFFCommo.Items.AddRange(g_listFFCommodity[control.Text].Keys.ToArray());
            if (cbFFCommo.Items.Count > 0)
            {
                cbFFCommo.SelectedIndex = 0;
            }
        }

        private void cbFFCommo_SelectedIndexChanged(object sender, EventArgs e)
        {
            //String strExh = cbFFExchange.SelectedItem.ToString();
            //String strCommo = cbFFCommo.SelectedItem.ToString();
            //cbFFCommoYM.Items.Clear();
            //foreach (DataRow dr in dtFFCommoYM.Select("Exh = '" + strExh + "' AND CommoID = '" + strCommo + "'"))
            //{
            //    cbFFCommoYM.Items.Add(dr["YM"].ToString());
            //}

            //if (cbFFCommoYM.Items.Count > 0)
            //{
            //    cbFFCommoYM.SelectedIndex = 0;
            //}
            ComboBox control = sender as ComboBox;
            cbFFCommoYM.Items.Clear();
            cbFFCommoYM.Items.AddRange(g_listFFCommoYM[cbFFExchange.Text][control.Text].Keys.Select(o => o.月份 + "," + o.履約價 + "," + o.買賣權).ToArray());
        }
        #endregion

        #region 內期
        private void cbFMType_SelectedIndexChanged(object sender, EventArgs e)
        {
            String strMType = cbFMType.SelectedItem.ToString();
            cbFCommo.Items.Clear();
            cbFSingleFlag.Items.Clear();
            if (strMType == "F")
            {
                //foreach (DataRow dr in dtFCommo.Select("TYPE = '1'"))
                //{
                //    cbFCommo.Items.Add(dr["COMMO"].ToString());
                //}
                cbFCommo.Items.AddRange(g_listFCommodity.Where(o => o.Value.類別 == "1").Select(o => o.Key).ToArray());

                cbFSingleFlag.Items.Add("1");
                cbFSingleFlag.Items.Add("4");
            }
            else
            {
                //foreach (DataRow dr in dtFCommo.Select("TYPE = '2'"))
                //{
                //    cbFCommo.Items.Add(dr["COMMO"].ToString());
                //}
                cbFCommo.Items.AddRange(g_listFCommodity.Where(o => o.Value.類別 == "2").Select(o => o.Key).ToArray());
                cbFSingleFlag.Items.Add("2");
                cbFSingleFlag.Items.Add("3");
            }
        }

        private void cbFSingleFlag_SelectedIndexChanged(object sender, EventArgs e)
        {
            String strSingleFlag = cbFSingleFlag.SelectedItem.ToString();
            String strCommo = cbFCommo.SelectedItem.ToString();
            ConcordLogger.Logger.Debug("strCommo=" + strCommo);
            //MessageBox.Show("strCommo=" + strCommo);
            switch (strSingleFlag)
            {
                case "1":
                case "2":
                    cbFCommo1.Items.Clear();
                    //foreach (DataRow dr in dtFCommoYM.Select("COMMO LIKE '" + strCommo + "%'"))
                    //{
                    //    cbFCommo1.Items.Add(dr["COMMO"].ToString());
                    //}
                    cbFCommo1.Items.AddRange(g_listFCommoYM[strCommo].Keys.ToArray());
                    //txtComno.Text = cbFCommo1.Text;
                    break;
                case "3":
                    cbFSingleType.Items.Clear();
                    cbFSingleType.Items.Add("1.價格價差");
                    cbFSingleType.Items.Add("2.跨月價差");
                    cbFSingleType.Items.Add("3.跨式");
                    cbFSingleType.Items.Add("4.勒式");
                    cbFSingleType.Items.Add("5.逆轉/轉換");
                    cbFCommo1.Items.Clear();
                    foreach (DataRow dr in dtFCommoYM.Select("COMMO LIKE '" + strCommo + "%'"))
                    {
                        cbFCommo1.Items.Add(dr["COMMO"].ToString());
                    }
                    cbFCommo2.Items.Clear();
                    foreach (DataRow dr in dtFCommoYM.Select("COMMO LIKE '" + strCommo + "%'"))
                    {
                        cbFCommo2.Items.Add(dr["COMMO"].ToString());
                    }
                    break;
                case "4":
                    cbFSingleType.Items.Clear();
                    cbFSingleType.Items.Add("6.期貨價差");
                    cbFCommo1.Items.Clear();
                    foreach (DataRow dr in dtFCommoYM.Select("COMMO LIKE '" + strCommo + "%'"))
                    {
                        cbFCommo1.Items.Add(dr["COMMO"].ToString());
                    }
                    cbFCommo2.Items.Clear();
                    foreach (DataRow dr in dtFCommoYM.Select("COMMO LIKE '" + strCommo + "%'"))
                    {
                        cbFCommo2.Items.Add(dr["COMMO"].ToString());
                    }
                    break;
            }
        }
        #endregion
        #endregion

        #region 多帳號事件
        private void btnFFMultiFlag_Click(object sender, EventArgs e)
        {
            if (API.FFQueryMultiFlag())
            {
                MessageBox.Show("多帳號下單");
            }
            else
            {
                MessageBox.Show("非多帳號下單");
            }
        }

        private void btnFMultiFlag_Click(object sender, EventArgs e)
        {
            if (API.FQueryMultiFlag())
            {
                MessageBox.Show("多帳號下單");
            }
            else
            {
                MessageBox.Show("非多帳號下單");
            }
        }

        private void btnFMultiOrder_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < int.Parse(txtFMulti.Text); i++)
            {
                String strMsg = "";
                String strMsgCode = "";
                String strSig = "";
                String strCert = "";
                String strData = "TestData";
                strMsgCode = API.GetSignature(txtIDNO.Text, strData, out strSig, out strCert, out strMsg);

                lsFStatus.Items.Insert(0,
$"{DateTime.Now.ToString("yyyyMMdd-HH:mm:ss.fff")}:{strMsgCode}:{strMsg}");
                String strGUID = Guid.NewGuid().ToString();
                if (strMsgCode == "120")
                {
#if !(COMMON || COMMON64)
                    #region 組下單字串，送下單

                    String strBody = "";
                    switch (cbFMsgType.SelectedItem.ToString())
                    {
                        case "新單":
                            strBody = "20103=" + strGUID + "|60=" + DateTime.Now.ToString("yyyyMMdd") +
                                      "|50=" + cbFOrderCseq.SelectedItem.ToString().Split('-')[1] + "|1=" + cbFOrderCseq.SelectedItem.ToString().Split('-')[2] +
                                      "|56=" + cbFMType.SelectedItem.ToString() + "|20003=" + cbFSingleFlag.SelectedItem.ToString() + "|55=" + cbFCommo1.SelectedItem.ToString() + "|59=" + cbFFIR.SelectedItem.ToString() + "|77=" + txtFOffset.Text +
                                      "|40=" + cbFOTYPE.SelectedItem.ToString() + "|54=" + cbFBS.SelectedItem.ToString() + "|38=" + txtFQty.Text + "|20004=" + txtFSign.Text + "|44=" + txtFPrice.Text +
                                      "|10000=X|20001=" + cbFOrderCseq.SelectedItem.ToString().Split('-')[3] + "|21001=" + strData + "|21002=" + strSig + "|21003=" + strCert + "|21004=" + txtIDNO.Text;
                            strMsgCode = API.FOrderNew(strBody, out strMsg);
                            break;
                        case "改量":
                            strBody = "20103=" + strGUID + "|60=" + DateTime.Now.ToString("yyyyMMdd") + "|41=" + txtFSeqno.Text + "|37=" + txtFDseq.Text +
                                      "|50=" + cbFOrderCseq.SelectedItem.ToString().Split('-')[1] + "|1=" + cbFOrderCseq.SelectedItem.ToString().Split('-')[2] +
                                      "|56=" + cbFMType.SelectedItem.ToString() + "|20003=" + cbFSingleFlag.SelectedItem.ToString() + "|55=" + cbFCommo1.SelectedItem.ToString() + "|59=" + cbFFIR.SelectedItem.ToString() + "|77=" + txtFOffset.Text +
                                      "|40=" + cbFOTYPE.SelectedItem.ToString() + "|54=" + cbFBS.SelectedItem.ToString() + "|38=" + txtFQty.Text + "|20004=" + txtFSign.Text + "|44=" + txtFPrice.Text +
                                      "|10000=X|20001=" + cbFOrderCseq.SelectedItem.ToString().Split('-')[3] + "|21001=" + strData + "|21002=" + strSig + "|21003=" + strCert + "|21004=" + txtIDNO.Text;
                            strMsgCode = API.FOrderChangeQty(strBody, out strMsg);
                            break;
                        case "刪單":
                            strBody = "20103=" + strGUID + "|60=" + DateTime.Now.ToString("yyyyMMdd") + "|41=" + txtFSeqno.Text + "|37=" + txtFDseq.Text +
                                      "|50=" + cbFOrderCseq.SelectedItem.ToString().Split('-')[1] + "|1=" + cbFOrderCseq.SelectedItem.ToString().Split('-')[2] +
                                      "|56=" + cbFMType.SelectedItem.ToString() + "|20003=" + cbFSingleFlag.SelectedItem.ToString() + "|55=" + cbFCommo1.SelectedItem.ToString() + "|59=" + cbFFIR.SelectedItem.ToString() + "|77=" + txtFOffset.Text +
                                      "|40=" + cbFOTYPE.SelectedItem.ToString() + "|54=" + cbFBS.SelectedItem.ToString() + "|38=" + txtFQty.Text + "|20004=" + txtFSign.Text + "|44=" + txtFPrice.Text +
                                      "|10000=X|20001=" + cbFOrderCseq.SelectedItem.ToString().Split('-')[3] + "|21001=" + strData + "|21002=" + strSig + "|21003=" + strCert + "|21004=" + txtIDNO.Text;
                            strMsgCode = API.FOrderDelete(strBody, out strMsg);
                            break;
                        case "改價":
                            strBody = "20103=" + strGUID + "|60=" + DateTime.Now.ToString("yyyyMMdd") + "|41=" + txtFSeqno.Text + "|37=" + txtFDseq.Text +
                                      "|50=" + cbFOrderCseq.SelectedItem.ToString().Split('-')[1] + "|1=" + cbFOrderCseq.SelectedItem.ToString().Split('-')[2] +
                                      "|56=" + cbFMType.SelectedItem.ToString() + "|20003=" + cbFSingleFlag.SelectedItem.ToString() + "|55=" + cbFCommo1.SelectedItem.ToString() + "|59=" + cbFFIR.SelectedItem.ToString() + "|77=" + txtFOffset.Text +
                                      "|40=" + cbFOTYPE.SelectedItem.ToString() + "|54=" + cbFBS.SelectedItem.ToString() + "|38=" + txtFQty.Text + "|20004=" + txtFSign.Text + "|44=" + txtFPrice.Text +
                                      "|10000=X|20001=" + cbFOrderCseq.SelectedItem.ToString().Split('-')[3] + "|21001=" + strData + "|21002=" + strSig + "|21003=" + strCert + "|21004=" + txtIDNO.Text;
                            strMsgCode = API.FOrderDelete(strBody, out strMsg);
                            break;
                    }
                    lsFStatus.Items.Insert(0,
$"{DateTime.Now.ToString("yyyyMMdd-HH:mm:ss.fff")}:{strMsgCode}:{strMsg}");
                    #endregion
#else
#endif
                }
            }
        }
        #endregion

        #region struct宣告
        //[Serializable]
        //private struct FFExchange
        //{
        //    public String OI;
        //    public String Exh;
        //    public String ExhName;
        //    public String Nation;
        //    public String Trade;
        //    public String Show;
        //    public String Open;
        //    public String Close;
        //    public String LMT;
        //    public String MKT;
        //    public String STP;
        //    public String SWL;
        //    public String TDATE;
        //}

        //[Serializable]
        //private struct FFCommo
        //{
        //    public String Exh;
        //    public String CommoID;
        //    public String CommoName;
        //    public String Contract;
        //    public String Denominator;
        //    public String TickUnit;
        //    public String Qty;
        //    public String Open;
        //    public String Close;
        //    public String Currency;
        //    public String Trade;
        //    public String Show;
        //    public String DTrade;
        //    public String DCloseTime;
        //    public String CusRate;
        //    public String CusEnable;
        //    public String CommoType;
        //    public String LMT;
        //    public String MKT;
        //    public String STP;
        //    public String SWL;
        //}

        //[Serializable]
        //private struct FFCommoYM
        //{
        //    public String Exh;
        //    public String CommoID;
        //    public String YM;
        //    public String DeliveryYM;
        //    public String HotYM;
        //    public String LastTDate;
        //    public String CommoType;
        //    public String CallPut;
        //    public String StkPrice;
        //}

        [Serializable]
        private struct FFCurrencyRate
        {
            public String TDate;
            public String Cur;
            public String CName;
            public String Rate;
        }

        [Serializable]
        private struct FCommo
        {
            public String Exh;
            public String COMMO;
            public String TYPE;
            public String CURRENCY;
            public String CNAME;
            public String CONTRACT;
            public String TAX;
            public String STOCK;
            public String QTY;
            public String SNAME;
            public String CODE;
            public String TICK;
        }

        [Serializable]
        private struct FCommoYM
        {
            public String COMMO;
            public String COMYM;
            public String STKPRICE;
            public String CALLPUT;
            public String SDATE;
            public String EDATE;
            public String UPRICE;
            public String DPRICE;
            public String PREMIUM;
            public String SECONDUPRICE;
            public String SECONDDPRICE;
            public String THIRDUPRICE;
            public String THIRDDPRICE;
            public String TYPE;
            public String ISQUOTE;
            public String DEC;
            public String COMSEQ;
            public String GROUPSEQ;
            public String TRDDATE;
            public String STKPRCDECIMAL;
        }
        #endregion

        private void cbFSingleType_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void cbFCommo1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cbFSingleFlag.SelectedItem.ToString() == "1" || cbFSingleFlag.SelectedItem.ToString() == "2")
            {
                txtComno.Text = cbFCommo1.SelectedItem.ToString();
            }
            else
            {
                if (cbFCommo2.SelectedItem != null)
                {
                    txtComno.Text = cbFCommo1.SelectedItem.ToString() + "/" + cbFCommo2.SelectedItem.ToString();
                }
            }
        }

        private void cbFCommo2_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cbFSingleFlag.SelectedItem.ToString() == "3" || cbFSingleFlag.SelectedItem.ToString() == "4")
            {
                txtComno.Text = cbFCommo1.SelectedItem.ToString() + "/" + cbFCommo2.SelectedItem.ToString().Substring(3, 2);
            }
        }

        private void lsFOrderRcv_KeyDown(object sender, KeyEventArgs e)
        {
            ListBox listBox = (ListBox)sender;
            if (e.Control == true && e.KeyCode == Keys.C)
            {
                string s = listBox.SelectedItem.ToString();
                Clipboard.SetData(DataFormats.StringFormat, s);
            }
        }

        private void lsFBill_KeyDown(object sender, KeyEventArgs e)
        {
            ListBox listBox = (ListBox)sender;
            if (e.Control == true && e.KeyCode == Keys.C)
            {
                string s = listBox.SelectedItem.ToString();
                Clipboard.SetData(DataFormats.StringFormat, s);
            }
        }

        private void lsFFOrderRcv_KeyDown(object sender, KeyEventArgs e)
        {
            ListBox listBox = (ListBox)sender;
            if (e.Control == true && e.KeyCode == Keys.C)
            {
                string s = listBox.SelectedItem.ToString();
                Clipboard.SetData(DataFormats.StringFormat, s);
            }
        }

        private void lsFFStatus_KeyDown(object sender, KeyEventArgs e)
        {
            ListBox listBox = (ListBox)sender;
            if (e.Control == true && e.KeyCode == Keys.C)
            {
                string s = listBox.SelectedItem.ToString();
                Clipboard.SetData(DataFormats.StringFormat, s);
            }
        }

        private void lsFStatus_KeyDown(object sender, KeyEventArgs e)
        {
            ListBox listBox = (ListBox)sender;
            if (e.Control == true && e.KeyCode == Keys.C)
            {
                string s = listBox.SelectedItem.ToString();
                Clipboard.SetData(DataFormats.StringFormat, s);
            }
        }

        private void lsFFBill_KeyDown(object sender, KeyEventArgs e)
        {
            ListBox listBox = (ListBox)sender;
            if (e.Control == true && e.KeyCode == Keys.C)
            {
                string s = listBox.SelectedItem.ToString();
                Clipboard.SetData(DataFormats.StringFormat, s);
            }
        }
    }
}
