public void OnReply(DataItem _data)
        {
            String typ = _data.strAgent;

            bool bDeal     = (typ == "D");
            bool bCanceled = (typ == "C");



            if (bDeal)
            {
                tBuySell dealBuySell = (_data.strBuySell[0] == 'B') ? tBuySell.Buy : tBuySell.Sell;

                //成交價
                int dealPrice = 0;
                try
                {
                    long _dp = (long.Parse(_data.strPrice));
                    if (_dp < 999999)
                    {
                        dealPrice = (int)_dp;
                    }
                }
                catch { }

                //成交數量
                int __nqty = 0;
                try { __nqty = int.Parse(_data.strQty); }
                catch { }
                if (__nqty > 0)
                {
                    nQty = __nqty;
                }


                // 剛剛送出委託
                if (g_bWaitingDeal != waitDealMode.notWaiting)
                {
                    String _t     = _data.strTime;
                    int    hour   = int.Parse(_t.Substring(0, 2));
                    int    minute = int.Parse(_t.Substring(2, 2));
                    int    second = int.Parse(_t.Substring(4, 2));

                    DateTime dealtime = new DateTime(todate.Year, todate.Month, todate.Day, hour, minute, second);
                    if (DateTime.Compare(dealtime, g_lastOrderSentTime) >= 0)
                    {
                        // Write Log
                        String strRes = "";
                        if (g_bWaitingDeal == waitDealMode.waitToBuildInventory)
                        {
                            string strInventoryTyp = "建倉";
                            if (g_CurDeposit > 0) // 加碼倉
                            {
                                strInventoryTyp = "加碼";
                            }
                            strRes = strInventoryTyp + "賣出成交 , ";
                            if (dealBuySell == tBuySell.Buy)
                            {
                                strRes = strInventoryTyp + "買進成交 , ";
                            }


                            if (g_CurDeposit > 0) // 加碼倉
                            {
                                strRes += "時間:" + g_CurTime.ToString() + " 價格:" + dealPrice.ToString();
                            }
                            else
                            {
                                strRes += "時間:" + g_CurTime.ToString() + " 價格:" + dealPrice.ToString();
                            }

                            g_LastDealPrice = dealPrice;
                            g_CurDeposit   += nQty;

                            // 建立倉位價格配對表
                            for (int k = 0; k < nQty; k++)
                            {
                                TradeInOutPrice inout = new TradeInOutPrice();
                                inout.In  = dealPrice;
                                inout.Out = 0;
                                inOutPriceList.Add(inout);
                            }
                            g_bWaitingDeal = waitDealMode.notWaiting;

                            Console.WriteLine(strRes);
                        }
                        #region 平倉
                        else if (g_bWaitingDeal == waitDealMode.waitToCleanInventory)
                        {
                            g_CurDeposit -= nQty;
                            int _cnt = 0;
                            for (int j = 0; j < inOutPriceList.Count; j++)
                            {
                                if (inOutPriceList[j].Out == 0)
                                {
                                    inOutPriceList[j].Out = dealPrice;
                                    _cnt++;
                                    if (_cnt >= nQty)
                                    {
                                        break;
                                    }
                                }
                            }
                            #region 全部平倉完畢
                            // 全部平倉完畢才統計贏的點數
                            if (g_CurDeposit == 0)
                            {
                                g_bWaitingDeal = waitDealMode.notWaiting;

                                if (dealBuySell == tBuySell.Sell) // 平倉賣出
                                {
                                    //g_todayWinPoint += (dealPrice - g_LastDealPrice) * numContractPerTrade;
                                    //if (g_CurDeposit > numContractPerTrade) // 有加碼倉
                                    //    g_todayWinPoint += (dealPrice - g_LastAddOnDealPrice) * (g_CurDeposit - numContractPerTrade);
                                    for (int j = 0; j < inOutPriceList.Count; j++)
                                    {
                                        if ((inOutPriceList[j].Out != 0) && (inOutPriceList[j].In != 0))
                                        {
                                            g_todayWinPoint += inOutPriceList[j].Out - inOutPriceList[j].In;
                                        }
                                    }


                                    switch (g_cleanUpMode)
                                    {
                                    case (cleanupMode.cleanupMode_KLEnd):
                                        strRes = "INV 分K結束平倉賣出成交 時間:" + dealtime.ToString() + " 價格:" + dealPrice.ToString() + " 賺賠:" + (g_todayWinPoint).ToString();
                                        break;

                                    case (cleanupMode.cleanupMode_DayEnd):
                                        strRes = "INV 收盤平倉賣出成交 時間:" + dealtime.ToString() + " 價格:" + dealPrice.ToString() + " 賺賠:" + (g_todayWinPoint).ToString();
                                        break;
                                    }
                                }
                                else // 平倉買進
                                {
                                    for (int j = 0; j < inOutPriceList.Count; j++)
                                    {
                                        if ((inOutPriceList[j].Out != 0) && (inOutPriceList[j].In != 0))
                                        {
                                            g_todayWinPoint += inOutPriceList[j].In - inOutPriceList[j].Out;
                                        }
                                    }

                                    switch (g_cleanUpMode)
                                    {
                                    case (cleanupMode.cleanupMode_KLEnd):
                                        strRes = "INV 分K結束平倉買進成交 時間:" + dealtime.ToString() + " 價格:" + dealPrice.ToString() + " 賺賠:" + (g_todayWinPoint).ToString();
                                        break;

                                    case (cleanupMode.cleanupMode_DayEnd):
                                        strRes = "INV 收盤平倉買進成交 時間:" + dealtime.ToString() + " 價格:" + dealPrice.ToString() + " 賺賠:" + (g_todayWinPoint).ToString();
                                        break;
                                    }
                                }

                                // 配對清單清空
                                inOutPriceList.Clear();

                                Console.WriteLine(strRes);

                                // 停損
                                if (g_todayWinPoint < -100)
                                {
                                    bDoTrading = false;
                                    Console.WriteLine("停損,今日停單");
                                }
                            }
                            #endregion
                        }
                        #endregion
                        // 成交成功,代表送出委託結束
                        bOrderSent = false;
                    }
                }
                else // 不是我送出的單,可能遭到強制平倉
                {
                    bool bReluctClean = false;

                    //買進遭到平倉賣出 or 賣出遭到平倉買進
                    if (
                        ((dealBuySell == tBuySell.Sell) && (g_b1MinTradePositive)) ||
                        ((dealBuySell == tBuySell.Buy) && (!g_b1MinTradePositive))
                        )
                    {
                        bReluctClean = true;
                    }

                    if (!bReluctClean)
                    {
                        return;
                    }

                    #region 平倉

                    g_CurDeposit -= nQty;
                    int _cnt = 0;
                    for (int j = 0; j < inOutPriceList.Count; j++)
                    {
                        if (inOutPriceList[j].Out == 0)
                        {
                            inOutPriceList[j].Out = dealPrice;
                            _cnt++;
                            if (_cnt >= nQty)
                            {
                                break;
                            }
                        }
                    }

                    if (g_CurDeposit == 0)
                    {
                        string strRes = "";
                        g_bWaitingDeal = waitDealMode.notWaiting;

                        String _t     = _data.strTime;
                        int    hour   = int.Parse(_t.Substring(0, 2));
                        int    minute = int.Parse(_t.Substring(2, 2));
                        int    second = int.Parse(_t.Substring(4, 2));

                        DateTime dealtime = new DateTime(todate.Year, todate.Month, todate.Day, hour, minute, second);

                        if (dealBuySell == tBuySell.Sell) // 平倉賣出
                        {
                            for (int j = 0; j < inOutPriceList.Count; j++)
                            {
                                if ((inOutPriceList[j].Out != 0) && (inOutPriceList[j].In != 0))
                                {
                                    g_todayWinPoint += inOutPriceList[j].Out - inOutPriceList[j].In;
                                }
                            }
                            strRes = "遭到強制平倉賣出成交 時間:" + dealtime.ToString() + " 價格:" + dealPrice.ToString() + " 賺賠:" + (g_todayWinPoint).ToString();
                        }
                        else // 平倉買進
                        {
                            for (int j = 0; j < inOutPriceList.Count; j++)
                            {
                                if ((inOutPriceList[j].Out != 0) && (inOutPriceList[j].In != 0))
                                {
                                    g_todayWinPoint += inOutPriceList[j].In - inOutPriceList[j].Out;
                                }
                            }
                            strRes = "遭到強制平倉買進成交 時間:" + dealtime.ToString() + " 價格:" + dealPrice.ToString() + " 賺賠:" + (g_todayWinPoint).ToString();
                        }

                        // 配對清單清空
                        inOutPriceList.Clear();

                        Console.WriteLine(strRes);

                        // 停損
                        if (g_todayWinPoint < -100)
                        {
                            bDoTrading = false;
                            Console.WriteLine("停損,今日停單");
                        }
                    }
                    #endregion
                }
            }
            // 被取消單,嘗試繼續送單
            if ((bCanceled) && (g_bWaitingDeal != waitDealMode.notWaiting))
            {
                bOrderSent = false;
            }
        }
        //int nTradeType = 2,int nDayTrade = 0
        // 送出委託 nBuySell 0:買進 1:賣出 nTradeType = 0:ROD 1:IOC 2:FOK
        // nDayTrade 0:否 1:是
        private void SendOrder(KLine newestKL, tBuySell nBuySell, bool doStopLoss, KLine prevKL = null, int nTradeType = 4, int nDayTrade = 1)
        {
            todayTradeTimes++;
            if (todayTradeTimes > maxOneDayTradeTimes)
            {
                //Console.WriteLine("一日交易次數不超出" + maxOneDayTradeTimes.ToString() + "次");
                return;
            }
            #region 盤中真單
            if ((ServMain.quoteProgramMode == QuoteProgramModeOS.QPM_MarketAM) || (ServMain.quoteProgramMode == QuoteProgramModeOS.QPM_MarketPM))
            {
                int nCode = -1;
                int nNewClose = 2;//自動
                string _price;
                string _stoplossPrice;
                string strStockNo = "JNM";
                //if(ServMain.quoteProgramMode == QuoteProgramModeOS.QPM_MarketPM)
                //    strStockNo = "JNMPM";
                int nSpecialTradeType = 0;//限價
                int iBuySell = nBuySell == tBuySell.Buy ? 0 : 1;
                string strProdYM = "20" + ServMain.OSEJNI_ID_CAP.Substring(ServMain.OSEJNI_ID_CAP.IndexOf("JNM") + 3, 4);
                if (nBuySell == tBuySell.Sell)//要賣,看Bid(買入價)
                {
                    if (doStopLoss)
                    {
                        nNewClose = 0;
                        if (g_CurDeposit > 0) // 加碼倉
                            nQty = (m_best5.m_nBidQty1 >= numContractPerTrade) ? numContractPerTrade : m_best5.m_nBidQty1;
                        else
                            nQty = (m_best5.m_nBidQty1 >= numAddOnPerTime) ? numAddOnPerTime : m_best5.m_nBidQty1;
                    }
                    else  // 平倉,全部平掉
                    {
                        nNewClose = 1;
                        nQty = (m_best5.m_nBidQty1 >= g_CurDeposit) ? g_CurDeposit : m_best5.m_nBidQty1;
                    }

                    _price = (m_best5.m_nBid1 ).ToString();
                    _stoplossPrice = ((newestKL.open + g_MaxStopLoss) ).ToString();

                }
                else //要買,看Ask(買出價)
                {
                    if (doStopLoss)
                    {
                        nNewClose = 0;
                        nQty = (m_best5.m_nAskQty1 >= numContractPerTrade) ? numContractPerTrade : m_best5.m_nAskQty1;
                    }
                    else  // 平倉,全部平掉
                    {
                        nNewClose = 1;
                        nQty = (m_best5.m_nAskQty1 >= g_CurDeposit) ? g_CurDeposit : m_best5.m_nAskQty1;
                    }
                    _price = (m_best5.m_nAsk1 ).ToString();
                    _stoplossPrice = ((newestKL.open - g_MaxStopLoss) ).ToString();
                }

                if (nQty > 0)
                {

                    if (doStopLoss)
                    {
                        if((g_CurDeposit == 0)&&(todayTradeTimes>1)) // 新倉,設置停損點
                            g_LastPrice = 0;//newestKL.open;

                        StringBuilder strMessage = new StringBuilder();
                        strMessage.Length = 1024;
                        Int32 nSiz = 1024;

                        nCode = OrderReply.Functions.SendOverseaFutureOrderAsync(futureAccount, "OSE", strStockNo, strProdYM , iBuySell, nNewClose, nDayTrade, nTradeType, nSpecialTradeType, nQty, _price, "0", "0", "0");
                        if (nCode != 0)
                        {
                            //開啟等待成交回報,帶有停損單的委託一定是建立倉位的委託單
                            g_bWaitingDeal = waitDealMode.waitToBuildInventory;
                            g_lastOrderSentTime = g_CurTime;
                        }
                    }
                    bOrderSent = true;
                }
            }
            #endregion
            #region 盤後模擬單
            //送出模擬單,沒有Best5,直接用買賣盤
            else if (ServMain.quoteProgramMode == QuoteProgramModeOS.QPM_Neutural)
            {
                String strRes = "";
                if (doStopLoss) //新倉
                {
                    if ((g_CurDeposit == 0) && (todayTradeTimes > 1)) // 新倉,設置停損點
                        g_LastPrice = 0;//newestKL.open;
                    if (nBuySell == tBuySell.Sell)//要賣,看Bid(買入價)
                    {
                        g_LastDealPrice = m_tick.m_nClose;
                    }
                    else
                    {
                        g_LastDealPrice = m_tick.m_nClose;
                    }

                    string strInventoryTyp = "INV 建倉";
                    if (g_CurDeposit > 0) // 加碼倉
                        strInventoryTyp = "加碼";
                    strRes = strInventoryTyp + "賣出 , ";
                    if (nBuySell == tBuySell.Buy)
                        strRes = strInventoryTyp + "買進 , ";

                    strRes += "時間:" + g_CurTime.ToString() + " 價格:" + g_LastDealPrice.ToString();

                    g_CurDeposit += numContractPerTrade;

                    Console.WriteLine(strRes);
                }
                else //平倉
                {
                    if (nBuySell == tBuySell.Sell)
                    {
                        g_todayWinPoint += (m_tick.m_nClose - g_LastDealPrice) * numContractPerTrade;

                        g_CurDeposit = 0;

                        switch (g_cleanUpMode)
                        {
                            case (cleanupMode.cleanupMode_KLEnd):
                                strRes = "INV 分K結束平倉賣出 時間:" + g_CurTime.ToString() + " 價格:" + m_tick.m_nClose.ToString() + " 賺賠:" + (g_todayWinPoint).ToString();
                                break;
                            case (cleanupMode.cleanupMode_DayEnd):
                                strRes = "INV 收盤平倉賣出 時間:" + g_CurTime.ToString() + " 價格:" + m_tick.m_nClose.ToString() + " 賺賠:" + (g_todayWinPoint).ToString();
                                break;
                        }
                        Console.WriteLine(strRes);

                    }
                    else if (nBuySell == tBuySell.Buy)
                    {
                        g_todayWinPoint += (g_LastDealPrice - m_tick.m_nClose) * numContractPerTrade;
                        g_CurDeposit = 0;

                        switch (g_cleanUpMode)
                        {
                            case (cleanupMode.cleanupMode_KLEnd):
                                strRes = "INV 分K結束平倉買進 時間:" + g_CurTime.ToString() + " 價格:" + m_tick.m_nClose.ToString() + " 賺賠:" + (g_todayWinPoint).ToString();
                                break;
                            case (cleanupMode.cleanupMode_DayEnd):
                                strRes = "INV 收盤平倉買進 時間:" + g_CurTime.ToString() + " 價格:" + m_tick.m_nClose.ToString() + " 賺賠:" + (g_todayWinPoint).ToString();
                                break;
                        }
                        Console.WriteLine(strRes);
                    }

                    // 停損
                    if (g_todayWinPoint < -100)
                    {
                        bDoTrading = false;
                        Console.WriteLine("停損,今日停單");
                    }
                }
            }
            #endregion
        }
        // 送出委託 nBuySell 0:買進 1:賣出 nTradeType = 0:ROD 1:IOC 2:FOK
        // nDayTrade 0:否 1:是
        private void SendOrder(KLine newestKL, tBuySell nBuySell, bool doStopLoss, KLine prevKL = null, int nTradeType = 4, int nDayTrade = 1) //int nTradeType = 2,int nDayTrade = 0
        {
            todayTradeTimes++;
            if (todayTradeTimes > maxOneDayTradeTimes)
            {
                //Console.WriteLine("一日交易次數不超出" + maxOneDayTradeTimes.ToString() + "次");
                return;
            }
            #region 盤中真單
            if ((ServMain.quoteProgramMode == QuoteProgramModeOS.QPM_MarketAM) || (ServMain.quoteProgramMode == QuoteProgramModeOS.QPM_MarketPM))
            {
                int    nCode     = -1;
                int    nNewClose = 2;//自動
                string _price;
                string _stoplossPrice;
                string strStockNo = "JNM";
                //if(ServMain.quoteProgramMode == QuoteProgramModeOS.QPM_MarketPM)
                //    strStockNo = "JNMPM";
                int    nSpecialTradeType = 0;//限價
                int    iBuySell          = nBuySell == tBuySell.Buy ? 0 : 1;
                string strProdYM         = "20" + ServMain.OSEJNI_ID_CAP.Substring(ServMain.OSEJNI_ID_CAP.IndexOf("JNM") + 3, 4);
                if (nBuySell == tBuySell.Sell)//要賣,看Bid(買入價)
                {
                    if (doStopLoss)
                    {
                        nNewClose = 0;
                        if (g_CurDeposit > 0) // 加碼倉
                        {
                            nQty = (m_best5.m_nBidQty1 >= numContractPerTrade) ? numContractPerTrade : m_best5.m_nBidQty1;
                        }
                        else
                        {
                            nQty = (m_best5.m_nBidQty1 >= numAddOnPerTime) ? numAddOnPerTime : m_best5.m_nBidQty1;
                        }
                    }
                    else  // 平倉,全部平掉
                    {
                        nNewClose = 1;
                        nQty      = (m_best5.m_nBidQty1 >= g_CurDeposit) ? g_CurDeposit : m_best5.m_nBidQty1;
                    }

                    _price         = (m_best5.m_nBid1).ToString();
                    _stoplossPrice = ((newestKL.open + g_MaxStopLoss)).ToString();
                }
                else //要買,看Ask(買出價)
                {
                    if (doStopLoss)
                    {
                        nNewClose = 0;
                        nQty      = (m_best5.m_nAskQty1 >= numContractPerTrade) ? numContractPerTrade : m_best5.m_nAskQty1;
                    }
                    else  // 平倉,全部平掉
                    {
                        nNewClose = 1;
                        nQty      = (m_best5.m_nAskQty1 >= g_CurDeposit) ? g_CurDeposit : m_best5.m_nAskQty1;
                    }
                    _price         = (m_best5.m_nAsk1).ToString();
                    _stoplossPrice = ((newestKL.open - g_MaxStopLoss)).ToString();
                }

                if (nQty > 0)
                {
                    if (doStopLoss)
                    {
                        if ((g_CurDeposit == 0) && (todayTradeTimes > 1)) // 新倉,設置停損點
                        {
                            g_LastPrice = 0;                              //newestKL.open;
                        }
                        StringBuilder strMessage = new StringBuilder();
                        strMessage.Length = 1024;
                        Int32 nSiz = 1024;

                        nCode = OrderReply.Functions.SendOverseaFutureOrderAsync(futureAccount, "OSE", strStockNo, strProdYM, iBuySell, nNewClose, nDayTrade, nTradeType, nSpecialTradeType, nQty, _price, "0", "0", "0");
                        if (nCode != 0)
                        {
                            //開啟等待成交回報,帶有停損單的委託一定是建立倉位的委託單
                            g_bWaitingDeal      = waitDealMode.waitToBuildInventory;
                            g_lastOrderSentTime = g_CurTime;
                        }
                    }
                    bOrderSent = true;
                }
            }
            #endregion
            #region 盤後模擬單
            //送出模擬單,沒有Best5,直接用買賣盤
            else if (ServMain.quoteProgramMode == QuoteProgramModeOS.QPM_Neutural)
            {
                String strRes = "";
                if (doStopLoss)                                       //新倉
                {
                    if ((g_CurDeposit == 0) && (todayTradeTimes > 1)) // 新倉,設置停損點
                    {
                        g_LastPrice = 0;                              //newestKL.open;
                    }
                    if (nBuySell == tBuySell.Sell)                    //要賣,看Bid(買入價)
                    {
                        g_LastDealPrice = m_tick.m_nClose;
                    }
                    else
                    {
                        g_LastDealPrice = m_tick.m_nClose;
                    }

                    string strInventoryTyp = "INV 建倉";
                    if (g_CurDeposit > 0) // 加碼倉
                    {
                        strInventoryTyp = "加碼";
                    }
                    strRes = strInventoryTyp + "賣出 , ";
                    if (nBuySell == tBuySell.Buy)
                    {
                        strRes = strInventoryTyp + "買進 , ";
                    }

                    strRes += "時間:" + g_CurTime.ToString() + " 價格:" + g_LastDealPrice.ToString();

                    g_CurDeposit += numContractPerTrade;

                    Console.WriteLine(strRes);
                }
                else //平倉
                {
                    if (nBuySell == tBuySell.Sell)
                    {
                        g_todayWinPoint += (m_tick.m_nClose - g_LastDealPrice) * numContractPerTrade;

                        g_CurDeposit = 0;

                        switch (g_cleanUpMode)
                        {
                        case (cleanupMode.cleanupMode_KLEnd):
                            strRes = "INV 分K結束平倉賣出 時間:" + g_CurTime.ToString() + " 價格:" + m_tick.m_nClose.ToString() + " 賺賠:" + (g_todayWinPoint).ToString();
                            break;

                        case (cleanupMode.cleanupMode_DayEnd):
                            strRes = "INV 收盤平倉賣出 時間:" + g_CurTime.ToString() + " 價格:" + m_tick.m_nClose.ToString() + " 賺賠:" + (g_todayWinPoint).ToString();
                            break;
                        }
                        Console.WriteLine(strRes);
                    }
                    else if (nBuySell == tBuySell.Buy)
                    {
                        g_todayWinPoint += (g_LastDealPrice - m_tick.m_nClose) * numContractPerTrade;
                        g_CurDeposit     = 0;

                        switch (g_cleanUpMode)
                        {
                        case (cleanupMode.cleanupMode_KLEnd):
                            strRes = "INV 分K結束平倉買進 時間:" + g_CurTime.ToString() + " 價格:" + m_tick.m_nClose.ToString() + " 賺賠:" + (g_todayWinPoint).ToString();
                            break;

                        case (cleanupMode.cleanupMode_DayEnd):
                            strRes = "INV 收盤平倉買進 時間:" + g_CurTime.ToString() + " 價格:" + m_tick.m_nClose.ToString() + " 賺賠:" + (g_todayWinPoint).ToString();
                            break;
                        }
                        Console.WriteLine(strRes);
                    }

                    // 停損
                    if (g_todayWinPoint < -100)
                    {
                        bDoTrading = false;
                        Console.WriteLine("停損,今日停單");
                    }
                }
            }
            #endregion
        }