void updateGraphData(KLine _curK)
        {
            //上下Range 45根高低點 + 10%
            int min_rr = 9999999;
            int max_rr = -9999999;

            if (m_KLdata_30Min.Count >= parent.m_numBarFocused)
            {
                for (int k = 1; k < (parent.m_numBarFocused + 1); k++)
                {
                    KLine curKL = m_KLdata_30Min[m_KLdata_30Min.Count - k];
                    if (curKL.highest > max_rr)
                    {
                        max_rr = curKL.highest;
                    }
                    if (curKL.lowest < min_rr)
                    {
                        min_rr = curKL.lowest;
                    }
                }

                int    rng       = Math.Abs(max_rr - min_rr);
                double rng10perc = rng * 0.1;
                max_rr += (int)rng10perc;
                min_rr -= (int)rng10perc;
            }
            else
            {
                min_rr = 16000;
                max_rr = 19000;
            }
            parent.BeginUpdGraph(_curK, EMA11.Value(), EMA22.Value(), min_rr, max_rr);
        }
        public void doCleanupInventory()
        {
            if (g_curDeposite == 0)
            {
                return;
            }
            if (m_KLdata_1Hour.Count < 22)
            {
                return;
            }

            bool b30minPositive     = m_ema11_30Min.Value() > m_ema22_30Min.Value();
            bool b30minMacdPositive = m_macd_30Min.HistRecords[m_macd_30Min.HistRecords.Count - 1] > 0;

            // 任一條件,均線破線 or macd 翻轉
            if ((g_bTradePositive != b30minMacdPositive) || (g_bTradePositive != b30minMacdPositive))
            {
                KLine _curKL30min = m_KLdata_30Min[m_KLdata_30Min.Count - 1];
                g_curDeposite--;
                if (g_bTradePositive)
                {
                    totalWinPnt += _curKL30min.close - g_lastDealPrice - 20;
                    Console.WriteLine("平倉賣出 時間:" + _curKL30min.datetime.ToString() + "賺賠:" + totalWinPnt.ToString());
                }
                else
                {
                    totalWinPnt += g_lastDealPrice - _curKL30min.close - 20;
                    Console.WriteLine("平倉買進 時間:" + _curKL30min.datetime.ToString() + "賺賠:" + totalWinPnt.ToString());
                }
            }
        }
        public void RecordMACD(KLine _curKL, ref iEMA ema11, ref iEMA ema22, ref iMACD macd)
        {
            ema11.ReceiveTick(_curKL.close);
            ema22.ReceiveTick(_curKL.close);

            double DI = ((double)_curKL.close * 2 + _curKL.highest + _curKL.lowest) / 4.0;

            macd.ReceiveTick(DI / 100);
        }
        bool insertNewKLine(TICK tTick, DateTime _time, List <KLine> madata, double interval)
        {
            bool bNewKLineInserted = false;

            //最後一根分k的時間轉 time_t
            int cnt = madata.Count;

            if (cnt > historyKLCnt)
            {
                KLine    lastK         = madata[(cnt - 1)];
                DateTime lastKLineTime = lastK.datetime;

                //現在已超出最後一根k棒的時間
                double timedif = Math.Abs((_time - lastKLineTime).TotalSeconds);

                if (timedif >= interval)
                {
                    DateTime tdate = lastKLineTime.AddSeconds(interval);
                    bNewKLineInserted = true;
                    KLine kl = new KLine(interval, tdate, tTick.m_nClose, tTick.m_nClose,
                                         tTick.m_nClose, tTick.m_nClose, tTick.m_nQty);

                    madata.Add(kl);
                }
                else
                {
                    lastK.close   = tTick.m_nClose;
                    lastK.amount += tTick.m_nQty;
                    if (tTick.m_nClose < lastK.lowest)
                    {
                        lastK.lowest = tTick.m_nClose;
                    }
                    else if (tTick.m_nClose > lastK.highest)
                    {
                        lastK.highest = tTick.m_nClose;
                    }

                    // 上下檔壓力記錄
                    if (tTick.m_nClose == lastK.open)
                    {
                        lastK.OpenCloseHitTime++;
                    }
                    lastK.tickAmount++;
                }
            }
            else //一根k棒都沒有
            {
                //算出當前tick最靠近的一個區間時間,可以在任意時間開啟監看
                DateTime curbaseTime = date_RoundDown(_time, TimeSpan.FromSeconds(interval));
                KLine    kl          = new KLine(interval, curbaseTime, tTick.m_nClose, tTick.m_nClose,
                                                 tTick.m_nClose, tTick.m_nClose, tTick.m_nQty);
                madata.Add(kl);
            }

            return(bNewKLineInserted);
        }
        public void RecordMACD(KLine _curKL)
        {
            EMA11.ReceiveTick(_curKL.close);
            EMA22.ReceiveTick(_curKL.close);

            double DI = ((double)_curKL.close * 2 + _curKL.highest + _curKL.lowest) / 4.0;

            m_iMACD.ReceiveTick(DI / 100);

            //Console.WriteLine(_curKL.datetime +  " Histogram:" + his.ToString());
        }
 void insertTodayKLine(TICK tTick, KLine _KL)
 {
     if (_KL.open == 0)
     {
         _KL.open = tTick.m_nClose;
     }
     _KL.close   = tTick.m_nClose;
     _KL.amount += tTick.m_nQty;
     if (tTick.m_nClose < _KL.lowest)
     {
         _KL.lowest = tTick.m_nClose;
     }
     else if (tTick.m_nClose > _KL.highest)
     {
         _KL.highest = tTick.m_nClose;
     }
 }
        void doBuildInventory(KLine newestKL, bool bAttackKLPositive, KLine prevKL = null, bool bAddOn = false)
        {
            if (bOrderSent)
            {
                return;
            }
            // 新倉
            if ((g_CurDeposit == 0) && (!bAddOn))
            {
                if (isDuringMarketTime(g_CurTime))
                {
                    if (bAttackKLPositive)
                    {
                        SendOrder(newestKL, tBuySell.Buy, true, prevKL);
                    }
                    else
                    {
                        SendOrder(newestKL, tBuySell.Sell, true, prevKL);
                    }

                    g_b1MinTradePositive = bAttackKLPositive;
                    g_LastTradeTime      = g_CurTime;
                    lastMovLossTime      = newestKL.datetime;
                }
            }
            // 加碼
            else if ((g_CurDeposit > 0) && (g_CurDeposit < g_AvailableDeposit)) //&& bAddOn
            {
                if (isDuringMarketTime(g_CurTime))
                {
                    if (g_b1MinTradePositive)
                    {
                        SendOrder(newestKL, tBuySell.Buy, true, prevKL);
                    }
                    else
                    {
                        SendOrder(newestKL, tBuySell.Sell, true, prevKL);
                    }

                    g_LastTradeTime = g_CurTime;
                    lastMovLossTime = newestKL.datetime;
                }
            }
        }
        private void DoDayTradeMACD(List <KLine> KLineData)
        {
            if (!bDoTrading)
            {
                return;
            }
            if (g_bWaitingDeal != waitDealMode.notWaiting)
            {
                return;
            }
            KLine  _KL   = KLineData[KLineData.Count - 2];
            double tdiff = (g_CurTime - _KL.datetime).TotalSeconds;

            // 發現已經有新K棒剛剛成形
            if ((tdiff < (THIRTY_MINUTE + 3)) && (tdiff >= THIRTY_MINUTE))
            {
                double _ema11        = EMA11.Value();
                double _ema22        = EMA22.Value();
                double _his          = m_iMACD.HistRecords[m_iMACD.HistRecords.Count - 1];
                bool   bEmaPositive  = _ema11 > _ema22;
                bool   bMACDPositive = _his > 0;

                if (g_CurDeposit > 0)
                {
                    // 出場,只要macd方向變就出
                    if (g_b1MinTradePositive != bMACDPositive)
                    {
                        doCleanInventory(_KL, cleanupMode.cleanupMode_KLEnd);
                    }
                }
                else
                {
                    // 進場,macd方向跟均線皆同向
                    if (bMACDPositive == bEmaPositive)
                    {
                        doBuildInventory(_KL, bMACDPositive);
                    }
                }
            }
        }
        public void doCleanInventory(KLine newestKL, cleanupMode __mode__ = cleanupMode.cleanupMode_DayEnd)
        {
            if (g_CurDeposit == 0)
            {
                return;
            }
            if (bOrderSent)
            {
                return;
            }

            g_cleanUpMode = __mode__;

            if (g_b1MinTradePositive)
            {
                SendOrder(newestKL, tBuySell.Sell, false);
            }
            else
            {
                SendOrder(newestKL, tBuySell.Buy, false);
            }
        }
        public bool ReceiveData(ref int cnt, ref KLine _KL, ref List <KLine> _lst,
                                ref iEMA _ema11, ref iEMA _ema22, ref iMACD _macd,
                                int period, DateTime _CurTime,
                                int open, int highest, int lowest, int close, int amount)
        {
            cnt++;
            if (cnt == 1)
            {
                _KL = new KLine(FIFTEEN_MINUTES, _CurTime, open, highest, lowest, close, amount);
            }
            else
            {
                _KL.amount += amount;
                if (lowest < _KL.lowest)
                {
                    _KL.lowest = lowest;
                }
                else if (highest > _KL.highest)
                {
                    _KL.highest = highest;
                }

                if (cnt == period / ONE_MINUTE)
                {
                    _KL.close    = close;
                    _KL.datetime = g_CurTime;
                    _lst.Add(_KL);
                    cnt = 0;

                    //記錄MACD
                    RecordMACD(_KL, ref _ema11, ref _ema22, ref _macd);

                    //K棒收集完成
                    return(true);
                }
            }
            return(false);
        }
        // 當沖最後平倉時間
        void dayTradCleanInventory_EndDay(List <KLine> KLineData)
        {
            if (KLineData == null)
            {
                return;
            }
            if (g_bWaitingDeal != waitDealMode.notWaiting)
            {
                return;
            }

            // 有倉位,而且到接近收盤時間
            if ((isTimeToCleanInventory1MinK(g_CurTime)) && (g_CurDeposit > 0))
            {
                int cnt = KLineData.Count;
                if (cnt < 1)
                {
                    return;
                }
                KLine newestKL = KLineData[cnt - 1];
                doCleanInventory(newestKL, cleanupMode.cleanupMode_DayEnd);
            }
        }
        void collectKLineData(TICK tTick, DateTime curT, bool bTicksGet = true)
        {
            insertTodayKLine(tTick, KLineToday);
            if (insertNewKLine(tTick, curT, m_KLdata_30Min, THIRTY_MINUTE))
            {
                KLine _curK = m_KLdata_30Min[m_KLdata_30Min.Count - 2];
                //Console.WriteLine("KL: [op:" + _curK.open.ToString() + "] [cl:" + _curK.close.ToString() + "]");
                RecordMACD(_curK);
                updateGraphData(_curK);
            }

            if (!bTicksGet)
            {
                // K棒結束後2秒內出手(盤中要送單測試暫時關閉)
                //DoDayTradeMACD(m_KLdata_30Min);

                // 不用平倉
                //dayTradCleanInventory_EndDay(m_KLdata_30Min);
            }

            //如果等不到回報,表示上次的order沒有成交,應該要繼續嘗試強制平倉
            if (m_KLdata_30Min.Count > 0)
            {
                if ((ServMain.quoteProgramMode == QuoteProgramModeOS.QPM_MarketPM) || (ServMain.quoteProgramMode == QuoteProgramModeOS.QPM_MarketAM))
                {
                    if (g_bWaitingDeal == waitDealMode.waitToCleanInventory)
                    {
                        doCleanInventory(m_KLdata_30Min[m_KLdata_30Min.Count - 1], g_cleanUpMode);
                    }
                    else if (g_bWaitingDeal == waitDealMode.waitToBuildInventory)
                    {
                        doBuildInventory(AttackKL, g_b1MinTradePositive);
                    }
                }
            }
        }
        void updateGraphData(KLine _curK)
        {
            //上下Range 45根高低點 + 10%
            int min_rr = 9999999;
            int max_rr = -9999999;

            if (m_KLdata_30Min.Count >= parent.m_numBarFocused)
            {
                for (int k = 1; k < (parent.m_numBarFocused+1); k++)
                {
                    KLine curKL = m_KLdata_30Min[m_KLdata_30Min.Count - k];
                    if (curKL.highest > max_rr)
                        max_rr = curKL.highest;
                    if (curKL.lowest < min_rr)
                        min_rr = curKL.lowest;
                }

                int rng = Math.Abs(max_rr - min_rr);
                double rng10perc = rng * 0.1;
                max_rr += (int)rng10perc;
                min_rr -= (int)rng10perc;
            }
            else
            {
                min_rr = 16000;
                max_rr = 19000;
            }
            parent.BeginUpdGraph(_curK, EMA11.Value(), EMA22.Value(),min_rr,max_rr);
        }
        public void startSim()
        {
            using (StreamReader sr = new StreamReader(m_histPth, Encoding.Default, true))
            {
                int Cnt_15min = 0;
                int Cnt_30min = 0;
                int Cnt_1Hour = 0;

                KLine _KL_15min = new KLine(FIFTEEN_MINUTES, g_CurTime, 0, 0, 0, 0, 0);
                KLine _KL_30min = new KLine(THIRTY_MINUTES, g_CurTime, 0, 0, 0, 0, 0);
                KLine _KL_1hour = new KLine(ONE_HOUR, g_CurTime, 0, 0, 0, 0, 0);

                while (sr.Peek() != -1)
                {
                    string _tkstr = sr.ReadLine();
                    if ( _tkstr.Contains(':') && (!_tkstr.Contains('#')) && (!ContainStr(_tkstr , "Tick")) )
                    {
                        #region  Parsing Text
                        string[] klspl1 = _tkstr.Split(':');
                        //:17445.:17445.:17445.:17445.:1 :20141125 21:01
                        int open = int.Parse(klspl1[1].Split('.')[0]);
                        int close = int.Parse(klspl1[2].Split('.')[0]);
                        int highest = int.Parse(klspl1[3].Split('.')[0]);
                        int lowest = int.Parse(klspl1[4].Split('.')[0]);
                        int amount = int.Parse(klspl1[5].Split('.')[0]);

                        int ymd = int.Parse(klspl1[6].Split(' ')[0]);
                        int year = 2015;
                        int month = 1;
                        int day = 1;
                        if (ymd > 20100000)
                        {
                            year = ymd / 10000;
                            month = (ymd - year * 10000) / 100;
                            day = (ymd - year * 10000 - month * 100);
                        }
                        int hour = int.Parse(klspl1[6].Split(' ')[1]);
                        int minute = int.Parse(klspl1[7].Split('=')[0]);

                        g_CurTime = new DateTime(year, month, day, hour, minute, 0);
                        #endregion

                        if (ReceiveData(ref Cnt_15min, ref _KL_15min, ref m_KLdata_15Min,
                                     ref m_ema11_15Min, ref m_ema22_15Min, ref m_macd_15Min,
                                     FIFTEEN_MINUTES, g_CurTime,
                                     open, highest, lowest, close, amount))

                        ReceiveData(ref Cnt_1Hour, ref _KL_1hour, ref m_KLdata_1Hour,
                                     ref m_ema11_1Hour, ref m_ema22_1Hour, ref m_macd_1Hour,
                                     ONE_HOUR, g_CurTime,
                                     open, highest, lowest, close, amount);

                        if( ReceiveData( ref Cnt_30min, ref _KL_30min, ref m_KLdata_30Min,
                                     ref m_ema11_30Min, ref m_ema22_30Min, ref m_macd_30Min,
                                     THIRTY_MINUTES, g_CurTime,
                                     open, highest, lowest, close, amount) )
                        {
                            DoTrendFollowingTrade();
                            doCleanupInventory();
                        }
                    }
                }
            }
            Console.WriteLine("============================================================================");
            //Console.WriteLine(" Total Win Point =" + (totalWinPnt).ToString());
            //Console.WriteLine(" money earned =" + ((totalWinPnt / 5) * 140 - (totalTradTimes * 136)).ToString());
        }
        public void RecordMACD(KLine _curKL ,ref iEMA ema11 ,ref iEMA ema22 ,ref iMACD macd )
        {
            ema11.ReceiveTick(_curKL.close);
            ema22.ReceiveTick(_curKL.close);

            double DI = ((double)_curKL.close * 2 + _curKL.highest + _curKL.lowest) / 4.0;
            macd.ReceiveTick(DI / 100);
        }
        public bool ReceiveData(ref int cnt , ref KLine _KL , ref List<KLine> _lst ,
             ref iEMA _ema11, ref iEMA _ema22, ref iMACD _macd ,
             int period , DateTime _CurTime ,
             int open , int highest , int lowest , int close , int amount)
        {
            cnt++;
            if (cnt == 1)
            {
                _KL = new KLine(FIFTEEN_MINUTES, _CurTime, open, highest, lowest, close, amount);
            }
            else
            {
                _KL.amount += amount;
                if (lowest < _KL.lowest)
                    _KL.lowest = lowest;
                else if (highest > _KL.highest)
                    _KL.highest = highest;

                if (cnt == period / ONE_MINUTE)
                {
                    _KL.close = close;
                    _KL.datetime = g_CurTime;
                    _lst.Add(_KL);
                    cnt = 0;

                    //記錄MACD
                    RecordMACD(_KL, ref _ema11, ref _ema22, ref _macd);

                    //K棒收集完成
                    return true;
                }
            }
            return 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
        }
 void insertTodayKLine(TICK tTick, KLine _KL)
 {
     if (_KL.open == 0) _KL.open = tTick.m_nClose;
     _KL.close = tTick.m_nClose;
     _KL.amount += tTick.m_nQty;
     if (tTick.m_nClose < _KL.lowest)
         _KL.lowest = tTick.m_nClose;
     else if (tTick.m_nClose > _KL.highest)
         _KL.highest = tTick.m_nClose;
 }
        bool insertNewKLine(TICK tTick, DateTime _time, List<KLine> madata, double interval)
        {
            bool bNewKLineInserted = false;

            //最後一根分k的時間轉 time_t
            int cnt = madata.Count;
            if (cnt > historyKLCnt)
            {
                KLine lastK = madata[(cnt - 1)];
                DateTime lastKLineTime = lastK.datetime;

                //現在已超出最後一根k棒的時間
                double timedif = Math.Abs((_time - lastKLineTime).TotalSeconds);

                if (timedif >= interval)
                {
                    DateTime tdate = lastKLineTime.AddSeconds(interval);
                    bNewKLineInserted = true;
                    KLine kl = new KLine(interval, tdate, tTick.m_nClose, tTick.m_nClose,
                        tTick.m_nClose, tTick.m_nClose, tTick.m_nQty);

                    madata.Add(kl);
                }
                else
                {
                    lastK.close = tTick.m_nClose;
                    lastK.amount += tTick.m_nQty;
                    if (tTick.m_nClose < lastK.lowest)
                        lastK.lowest = tTick.m_nClose;
                    else if (tTick.m_nClose > lastK.highest)
                        lastK.highest = tTick.m_nClose;

                    // 上下檔壓力記錄
                    if (tTick.m_nClose == lastK.open)
                        lastK.OpenCloseHitTime++;
                    lastK.tickAmount++;

                }
            }
            else //一根k棒都沒有
            {
                //算出當前tick最靠近的一個區間時間,可以在任意時間開啟監看
                DateTime curbaseTime = date_RoundDown(_time, TimeSpan.FromSeconds(interval));
                KLine kl = new KLine(interval, curbaseTime, tTick.m_nClose, tTick.m_nClose,
                    tTick.m_nClose, tTick.m_nClose, tTick.m_nQty);
                madata.Add(kl);
            }

            return bNewKLineInserted;
        }
        void doBuildInventory(KLine newestKL, bool bAttackKLPositive, KLine prevKL = null, bool bAddOn = false)
        {
            if (bOrderSent) return;
            // 新倉
            if ((g_CurDeposit == 0) && (!bAddOn))
            {
                if (isDuringMarketTime(g_CurTime))
                {
                    if (bAttackKLPositive)
                        SendOrder(newestKL, tBuySell.Buy, true, prevKL);
                    else
                        SendOrder(newestKL, tBuySell.Sell, true, prevKL);

                    g_b1MinTradePositive = bAttackKLPositive;
                    g_LastTradeTime = g_CurTime;
                    lastMovLossTime = newestKL.datetime;
                }
            }
            // 加碼
            else if ((g_CurDeposit > 0) && (g_CurDeposit < g_AvailableDeposit)) //&& bAddOn
            {
                if (isDuringMarketTime(g_CurTime))
                {
                    if (g_b1MinTradePositive)
                        SendOrder(newestKL, tBuySell.Buy, true, prevKL);
                    else
                        SendOrder(newestKL, tBuySell.Sell, true, prevKL);

                    g_LastTradeTime = g_CurTime;
                    lastMovLossTime = newestKL.datetime;
                }
            }
        }
        public void RecordMACD(KLine _curKL)
        {
            EMA11.ReceiveTick(_curKL.close);
            EMA22.ReceiveTick(_curKL.close);

            double DI = ((double)_curKL.close * 2 + _curKL.highest + _curKL.lowest) / 4.0;
            m_iMACD.ReceiveTick(DI / 100);

            //Console.WriteLine(_curKL.datetime +  " Histogram:" + his.ToString());
        }
        public void readHistoryKLData(string exeRootPth="")
        {
            string ff = mAppPath + @"\HistoryKLine1Min.xml";
            if (exeRootPth.Length > 0)
                ff = exeRootPth;
            using (StreamReader sr = new StreamReader(ff, Encoding.Default, true))
            {
                int Cnt = 0;
                KLine _KL = new KLine(THIRTY_MINUTE, g_CurTime, 0, 0, 0, 0, 0);
                while (sr.Peek() != -1)
                {
                    string _tkstr = sr.ReadLine();
                    if ( _tkstr.Contains(':') && (!_tkstr.Contains('#')) && (!ContainStr(_tkstr , "Tick")) )
                    {
                        string[] klspl1 = _tkstr.Split(':');
                        //:17445.:17445.:17445.:17445.:1 :20141125 21:01
                        int open = int.Parse(klspl1[1].Split('.')[0]);
                        int close = int.Parse(klspl1[2].Split('.')[0]);
                        int highest = int.Parse(klspl1[3].Split('.')[0]);
                        int lowest = int.Parse(klspl1[4].Split('.')[0]);
                        int amount = int.Parse(klspl1[5].Split('.')[0]);

                        int ymd = int.Parse(klspl1[6].Split(' ')[0]);
                        int year = 2015;
                        int month = 1;
                        int day = 1;
                        if (ymd > 20100000)
                        {
                            year = ymd / 10000;
                            month = (ymd - year * 10000) / 100;
                            day = (ymd - year * 10000 - month * 100);
                        }
                        int hour = int.Parse(klspl1[6].Split(' ')[1]);
                        int minute = int.Parse(klspl1[7].Split('=')[0]);

                        g_CurTime = new DateTime(year, month, day, hour, minute, 0);

                        Cnt++;
                        if (Cnt == 1)
                        {
                            _KL = new KLine(THIRTY_MINUTE, g_CurTime, open, highest, lowest, close, amount);
                        }
                        else
                        {
                            _KL.amount += amount;
                            if (lowest < _KL.lowest)
                                _KL.lowest = lowest;
                            else if (highest > _KL.highest)
                                _KL.highest = highest;

                            if (Cnt == THIRTY_MINUTE/ONE_MINUTE)
                            {
                                _KL.close = close;
                                _KL.datetime = g_CurTime;
                                m_KLdata_30Min.Add(_KL);
                                Cnt = 0;

                                //記錄MACD
                                RecordMACD(_KL);

                            }
                        }
                    }
                    else if (_tkstr.IndexOf("JNM") != -1)
                    {
                        if (_tkstr.IndexOf("PM") != -1)
                            ServMain.OSEJNIPM_ID_CAP = _tkstr;
                        else
                        {
                            ServMain.OSEJNI_ID_CAP = _tkstr;
                            string strProdYM = ServMain.OSEJNI_ID_CAP.Substring(ServMain.OSEJNI_ID_CAP.IndexOf("JNM") + 3, 4);
                        }
                    }
                }
            }
            historyKLCnt = m_KLdata_30Min.Count;

            g_CurTime = DateTime.Now;

            //上午開盤時間,日本時間上午9:00 (台灣時間晚日本1小時)
            g_marketStartTime_AM = new DateTime(g_CurTime.Year, g_CurTime.Month, g_CurTime.Day, 9, 0, 0);

            //上午收盤時間,日本時間下午3:15
            g_marketEndTime_AM = new DateTime(g_CurTime.Year, g_CurTime.Month, g_CurTime.Day, 15, 15, 59);

            //下午開盤時間,日本時間下午4:30
            g_marketStartTime_PM = new DateTime(g_CurTime.Year, g_CurTime.Month, g_CurTime.Day, 16, 29, 59);

            DateTime nxDate = g_CurTime.AddDays(1);

            //下午收盤時間,日本時間上午3:00
            g_marketEndTime_PM = new DateTime(nxDate.Year, nxDate.Month, nxDate.Day, 3, 0, 0);

            //收盤強制平倉時間,日本時間上午2:50
            g_cleanIntrestTime = new DateTime(nxDate.Year, nxDate.Month, nxDate.Day, 2, 40, 00);

            if ((ServMain.quoteProgramMode == QuoteProgramModeOS.QPM_MarketAM) || (ServMain.quoteProgramMode == QuoteProgramModeOS.QPM_MarketPM))
            {
                g_marketStartTime_AM = new DateTime(todate.Year, todate.Month, todate.Day, 9, 0, 0);
                g_marketEndTime_AM = new DateTime(todate.Year, todate.Month, todate.Day, 15, 15, 59);
                g_marketStartTime_PM = new DateTime(todate.Year, todate.Month, todate.Day, 16, 29, 59);
                nxDate = todate.AddDays(1);
                g_marketEndTime_PM = new DateTime(nxDate.Year, nxDate.Month, nxDate.Day, 3, 0, 0);
                g_cleanIntrestTime = new DateTime(nxDate.Year, nxDate.Month, nxDate.Day, 2, 40, 00);
            }
        }
        public void updGraph(KLine newKL, double newEma11, double newEma22 , int min_rr , int max_rr )
        {
            GraphPane myPane = this.zg1.GraphPane;

            //Console.WriteLine("KL: [op:" + newKL.open.ToString() + "] [cl:" + newKL.close.ToString() + "]");
            // K 棒更新
            //KLine newKL = KLLst[KLLst.Count - 2];
            List<StockPt> KLPnts = (List<StockPt>)jpnCandle.Points;
            XDate xDate = new XDate(newKL.datetime.Year, newKL.datetime.Month, newKL.datetime.Day, newKL.datetime.Hour, newKL.datetime.Minute, 0);
            StockPt pt_kl = new StockPt(xDate.XLDate, newKL.highest, newKL.lowest, newKL.open, newKL.close, newKL.amount);
            KLPnts.Add(pt_kl);

            // Ema 11 更新
            List<StockPt> Ema11Pnts = (List<StockPt>)ema11LineGr.Points;
            StockPt pt_ema11 = new StockPt(xDate.XLDate, newEma11, newEma11, newEma11, newEma11, newEma11);
            Ema11Pnts.Add(pt_ema11);

            // Ema 11 更新
            List<StockPt> Ema22Pnts = (List<StockPt>)ema22LineGr.Points;
            StockPt pt_ema22 = new StockPt(xDate.XLDate, newEma22, newEma22, newEma22, newEma22, newEma22);
            Ema22Pnts.Add(pt_ema22);

            #region Range 更新 : Update

            myPane.YAxis.Scale.Min = min_rr;
            myPane.YAxis.Scale.Max = max_rr;
            //Console.WriteLine(min_rr.ToString());

            #endregion

            zg1.AxisChange();
            zg1.Invalidate();
        }
        public void readHistoryKLData(string exeRootPth = "")
        {
            string ff = mAppPath + @"\HistoryKLine1Min.xml";

            if (exeRootPth.Length > 0)
            {
                ff = exeRootPth;
            }
            using (StreamReader sr = new StreamReader(ff, Encoding.Default, true))
            {
                int   Cnt = 0;
                KLine _KL = new KLine(THIRTY_MINUTE, g_CurTime, 0, 0, 0, 0, 0);
                while (sr.Peek() != -1)
                {
                    string _tkstr = sr.ReadLine();
                    if (_tkstr.Contains(':') && (!_tkstr.Contains('#')) && (!ContainStr(_tkstr, "Tick")))
                    {
                        string[] klspl1 = _tkstr.Split(':');
                        //:17445.:17445.:17445.:17445.:1 :20141125 21:01
                        int open    = int.Parse(klspl1[1].Split('.')[0]);
                        int close   = int.Parse(klspl1[2].Split('.')[0]);
                        int highest = int.Parse(klspl1[3].Split('.')[0]);
                        int lowest  = int.Parse(klspl1[4].Split('.')[0]);
                        int amount  = int.Parse(klspl1[5].Split('.')[0]);

                        int ymd   = int.Parse(klspl1[6].Split(' ')[0]);
                        int year  = 2015;
                        int month = 1;
                        int day   = 1;
                        if (ymd > 20100000)
                        {
                            year  = ymd / 10000;
                            month = (ymd - year * 10000) / 100;
                            day   = (ymd - year * 10000 - month * 100);
                        }
                        int hour   = int.Parse(klspl1[6].Split(' ')[1]);
                        int minute = int.Parse(klspl1[7].Split('=')[0]);

                        g_CurTime = new DateTime(year, month, day, hour, minute, 0);


                        Cnt++;
                        if (Cnt == 1)
                        {
                            _KL = new KLine(THIRTY_MINUTE, g_CurTime, open, highest, lowest, close, amount);
                        }
                        else
                        {
                            _KL.amount += amount;
                            if (lowest < _KL.lowest)
                            {
                                _KL.lowest = lowest;
                            }
                            else if (highest > _KL.highest)
                            {
                                _KL.highest = highest;
                            }

                            if (Cnt == THIRTY_MINUTE / ONE_MINUTE)
                            {
                                _KL.close    = close;
                                _KL.datetime = g_CurTime;
                                m_KLdata_30Min.Add(_KL);
                                Cnt = 0;

                                //記錄MACD
                                RecordMACD(_KL);
                            }
                        }
                    }
                    else if (_tkstr.IndexOf("JNM") != -1)
                    {
                        if (_tkstr.IndexOf("PM") != -1)
                        {
                            ServMain.OSEJNIPM_ID_CAP = _tkstr;
                        }
                        else
                        {
                            ServMain.OSEJNI_ID_CAP = _tkstr;
                            string strProdYM = ServMain.OSEJNI_ID_CAP.Substring(ServMain.OSEJNI_ID_CAP.IndexOf("JNM") + 3, 4);
                        }
                    }
                }
            }
            historyKLCnt = m_KLdata_30Min.Count;

            g_CurTime = DateTime.Now;

            //上午開盤時間,日本時間上午9:00 (台灣時間晚日本1小時)
            g_marketStartTime_AM = new DateTime(g_CurTime.Year, g_CurTime.Month, g_CurTime.Day, 9, 0, 0);

            //上午收盤時間,日本時間下午3:15
            g_marketEndTime_AM = new DateTime(g_CurTime.Year, g_CurTime.Month, g_CurTime.Day, 15, 15, 59);

            //下午開盤時間,日本時間下午4:30
            g_marketStartTime_PM = new DateTime(g_CurTime.Year, g_CurTime.Month, g_CurTime.Day, 16, 29, 59);

            DateTime nxDate = g_CurTime.AddDays(1);

            //下午收盤時間,日本時間上午3:00
            g_marketEndTime_PM = new DateTime(nxDate.Year, nxDate.Month, nxDate.Day, 3, 0, 0);

            //收盤強制平倉時間,日本時間上午2:50
            g_cleanIntrestTime = new DateTime(nxDate.Year, nxDate.Month, nxDate.Day, 2, 40, 00);

            if ((ServMain.quoteProgramMode == QuoteProgramModeOS.QPM_MarketAM) || (ServMain.quoteProgramMode == QuoteProgramModeOS.QPM_MarketPM))
            {
                g_marketStartTime_AM = new DateTime(todate.Year, todate.Month, todate.Day, 9, 0, 0);
                g_marketEndTime_AM   = new DateTime(todate.Year, todate.Month, todate.Day, 15, 15, 59);
                g_marketStartTime_PM = new DateTime(todate.Year, todate.Month, todate.Day, 16, 29, 59);
                nxDate             = todate.AddDays(1);
                g_marketEndTime_PM = new DateTime(nxDate.Year, nxDate.Month, nxDate.Day, 3, 0, 0);
                g_cleanIntrestTime = new DateTime(nxDate.Year, nxDate.Month, nxDate.Day, 2, 40, 00);
            }
        }
        // 送出委託 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
        }
        public void DoTrendFollowingTrade()
        {
            // 小時線要有方向才做
            if (m_KLdata_1Hour.Count < 22)
            {
                return;
            }
            if (g_curDeposite > 0)
            {
                return;
            }

            KLine _curKL30min = m_KLdata_30Min[m_KLdata_30Min.Count - 1];

            // 研判趨勢多空
            bool b30minPositive     = m_ema11_30Min.Value() > m_ema22_30Min.Value();
            bool b30minMacdPositive = m_macd_30Min.HistRecords[m_macd_30Min.HistRecords.Count - 1] > 0;
            bool b1hourPositive     = m_ema11_1Hour.Value() > m_ema22_1Hour.Value();

            bool bTrendFound = (b30minPositive == b30minMacdPositive) && (b30minMacdPositive == b1hourPositive);

            // 如果30分K棒發生逆趨勢線生長,進場
            bool bDoTrading = false;

            if (bTrendFound)
            {
                double oneThrd = Math.Abs(m_ema11_30Min.Value() - m_ema22_30Min.Value()) / 3.0;

                if (b30minPositive)
                {
                    if (_curKL30min.close < m_ema11_30Min.Value() - oneThrd)
                    {
                        bDoTrading = true;
                    }
                }
                else
                {
                    if (_curKL30min.close > m_ema11_30Min.Value() + oneThrd)
                    {
                        bDoTrading = true;
                    }
                }
            }

            if (bDoTrading)
            {
                g_curDeposite++;
                g_lastDealPrice  = _curKL30min.close;
                g_lastDealTime   = _curKL30min.datetime;
                g_bTradePositive = b30minPositive;
                totalTradTimes++;

                if (g_bTradePositive)
                {
                    Console.WriteLine("建倉買進 時間:" + _curKL30min.datetime.ToString());
                }
                else
                {
                    Console.WriteLine("建倉賣出 時間:" + _curKL30min.datetime.ToString());
                }
            }
        }
        public void doCleanInventory(KLine newestKL, cleanupMode __mode__ = cleanupMode.cleanupMode_DayEnd)
        {
            if (g_CurDeposit == 0) return;
            if (bOrderSent) return;

            g_cleanUpMode = __mode__;

            if (g_b1MinTradePositive)
                SendOrder(newestKL, tBuySell.Sell, false);
            else
                SendOrder(newestKL, tBuySell.Buy, false);
        }
        public void startSim()
        {
            using (StreamReader sr = new StreamReader(m_histPth, Encoding.Default, true))
            {
                int Cnt_15min = 0;
                int Cnt_30min = 0;
                int Cnt_1Hour = 0;

                KLine _KL_15min = new KLine(FIFTEEN_MINUTES, g_CurTime, 0, 0, 0, 0, 0);
                KLine _KL_30min = new KLine(THIRTY_MINUTES, g_CurTime, 0, 0, 0, 0, 0);
                KLine _KL_1hour = new KLine(ONE_HOUR, g_CurTime, 0, 0, 0, 0, 0);

                while (sr.Peek() != -1)
                {
                    string _tkstr = sr.ReadLine();
                    if (_tkstr.Contains(':') && (!_tkstr.Contains('#')) && (!ContainStr(_tkstr, "Tick")))
                    {
                        #region  Parsing Text
                        string[] klspl1 = _tkstr.Split(':');
                        //:17445.:17445.:17445.:17445.:1 :20141125 21:01
                        int open    = int.Parse(klspl1[1].Split('.')[0]);
                        int close   = int.Parse(klspl1[2].Split('.')[0]);
                        int highest = int.Parse(klspl1[3].Split('.')[0]);
                        int lowest  = int.Parse(klspl1[4].Split('.')[0]);
                        int amount  = int.Parse(klspl1[5].Split('.')[0]);

                        int ymd   = int.Parse(klspl1[6].Split(' ')[0]);
                        int year  = 2015;
                        int month = 1;
                        int day   = 1;
                        if (ymd > 20100000)
                        {
                            year  = ymd / 10000;
                            month = (ymd - year * 10000) / 100;
                            day   = (ymd - year * 10000 - month * 100);
                        }
                        int hour   = int.Parse(klspl1[6].Split(' ')[1]);
                        int minute = int.Parse(klspl1[7].Split('=')[0]);

                        g_CurTime = new DateTime(year, month, day, hour, minute, 0);
                        #endregion

                        if (ReceiveData(ref Cnt_15min, ref _KL_15min, ref m_KLdata_15Min,
                                        ref m_ema11_15Min, ref m_ema22_15Min, ref m_macd_15Min,
                                        FIFTEEN_MINUTES, g_CurTime,
                                        open, highest, lowest, close, amount))
                        {
                            ReceiveData(ref Cnt_1Hour, ref _KL_1hour, ref m_KLdata_1Hour,
                                        ref m_ema11_1Hour, ref m_ema22_1Hour, ref m_macd_1Hour,
                                        ONE_HOUR, g_CurTime,
                                        open, highest, lowest, close, amount);
                        }

                        if (ReceiveData(ref Cnt_30min, ref _KL_30min, ref m_KLdata_30Min,
                                        ref m_ema11_30Min, ref m_ema22_30Min, ref m_macd_30Min,
                                        THIRTY_MINUTES, g_CurTime,
                                        open, highest, lowest, close, amount))
                        {
                            DoTrendFollowingTrade();
                            doCleanupInventory();
                        }
                    }
                }
            }
            Console.WriteLine("============================================================================");
            //Console.WriteLine(" Total Win Point =" + (totalWinPnt).ToString());
            //Console.WriteLine(" money earned =" + ((totalWinPnt / 5) * 140 - (totalTradTimes * 136)).ToString());
        }
 public IAsyncResult BeginUpdGraph( KLine _KL, double newEma11, double newEma22,int min,int max )
 {
     return m_updGraphDelegate.BeginInvoke(_KL, newEma11, newEma22, min, max, EndUpdGraph, m_updGraphDelegate);
 }