Esempio n. 1
0
        public List <FXModes.MqlRates> RatesByPositions(string symbol, string timeframe, int startPosition, int count)
        {
            RetryConnecting();
            if (count <= 0 || startPosition < 0)
            {
                return(new List <FXModes.MqlRates>());
            }
            ENUM_TIMEFRAMES enumTimeframe = (ENUM_TIMEFRAMES)Enum.Parse(typeof(ENUM_TIMEFRAMES), timeframe);
            var             candles       = new MqlRates[count];

            mtApi5Client.CopyRates(symbol, enumTimeframe, startPosition, count, out candles);

            //This is done so that time is not ignored from xml
            var newCandles = new List <FXModes.MqlRates>();

            foreach (var m in candles)
            {
                newCandles.Add(new FXModes.MqlRates
                {
                    time        = m.time,
                    close       = m.close,
                    high        = m.high,
                    low         = m.low,
                    mt_time     = m.mt_time,
                    open        = m.open,
                    real_volume = m.real_volume,
                    spread      = m.spread,
                    tick_volume = m.tick_volume
                });
            }
            return(newCandles);
        }
Esempio n. 2
0
        // </summary>
        // <param name="timeframe">Timeframe to do scanning on</param>
        // <param name="startDateString">Lower bound date in format yyyyMMddHHmmss</param>
        // <param name="endDateString">Upper bound date in format yyyyMMddHHmmss</param>
        // <returns>List of Engulfings</returns>
        public List <FXModes.MqlRates> RatesByDates(string symbol, string timeframe, string startDateString, string endDateString)
        {
            RetryConnecting();
            var startDate = DateTime.ParseExact(startDateString, "yyyyMMddHHmmss", CultureInfo.InvariantCulture);
            var endDate   = DateTime.ParseExact(endDateString, "yyyyMMddHHmmss", CultureInfo.InvariantCulture);

            if ((endDate - startDate).TotalMinutes <= TimeframeHelper.GetMinutesFromForTimeframe(timeframe))
            {
                return(new List <FXModes.MqlRates>());
            }
            if ((mtApi5Client.TimeCurrent() - startDate).TotalMinutes <= TimeframeHelper.GetMinutesFromForTimeframe(timeframe))
            {
                return(new List <FXModes.MqlRates>());
            }

            ENUM_TIMEFRAMES enumTimeframe = (ENUM_TIMEFRAMES)Enum.Parse(typeof(ENUM_TIMEFRAMES), timeframe);
            int             size          = (int)((endDate - startDate).TotalMinutes / (TimeframeHelper.GetMinutesFromForTimeframe(timeframe)));
            var             candles       = new MqlRates[size];

            mtApi5Client.CopyRates(symbol, enumTimeframe, startDate, endDate, out candles);
            //This is done so that time is not ignored from xml
            var newCandles = new List <FXModes.MqlRates>();

            foreach (var m in candles)
            {
                newCandles.Add(new FXModes.MqlRates
                {
                    time        = m.time,
                    close       = m.close,
                    high        = m.high,
                    low         = m.low,
                    mt_time     = m.mt_time,
                    open        = m.open,
                    real_volume = m.real_volume,
                    spread      = m.spread,
                    tick_volume = m.tick_volume
                });
            }
            return(newCandles);
        }
Esempio n. 3
0
        public FXModes.MqlRates CurrentIncompleteCandle(string symbol, string timeframe)
        {
            RetryConnecting();
            ENUM_TIMEFRAMES enumTimeframe = (ENUM_TIMEFRAMES)Enum.Parse(typeof(ENUM_TIMEFRAMES), timeframe);
            var             candles       = new MqlRates[1];

            mtApi5Client.CopyRates(symbol, enumTimeframe, 0, 1, out candles);

            var m = candles[0];

            //This is done so that time is not ignored from xml
            return(new FXModes.MqlRates
            {
                time = m.time,
                close = m.close,
                high = m.high,
                low = m.low,
                mt_time = m.mt_time,
                open = m.open,
                real_volume = m.real_volume,
                spread = m.spread,
                tick_volume = m.tick_volume
            });
        }
Esempio n. 4
0
        // 注意修改rate.time(例如M15,需要加60*15)
        public static void ImportToDb(string symbol, string period, int periodTime_cnt, MqlRates[] rate, Dictionary<string, Dictionary<long, double>> inds)
        {
            string symbolPeriod = symbol + "_" + period;

            string symbolPeriodTime = symbol + "_" + period +
                (periodTime_cnt == 1 ? (period == "M5" ? "_3" : "_4") : string.Empty) +
                (periodTime_cnt == 2 ? (period == "M5" ? "_12" : "_16") : string.Empty) +
                (periodTime_cnt == 3 ? (period == "M5" ? "_48" : "_64") : string.Empty);

            //DateTime maxDate = (DateTime)DbHelper.Instance.ExecuteScalar(string.Format("SELECT ISNULL(MAX(Date), '2001.01.01') FROM {0}", m_symbolPeriod));
            //DateTime minDate = (DateTime)DbHelper.Instance.ExecuteScalar(string.Format("SELECT ISNULL(MIN(Date), '2012.01.01') FROM {0}", m_symbolPeriod));

            bool deleteFirst = false;
            if (deleteFirst)
            {
                DbHelper.Instance.ExecuteNonQuery(string.Format("TRUNCATE TABLE {0}", symbolPeriodTime));
            }

            System.Data.DataTable dt;
            try
            {
                dt = DbHelper.Instance.ExecuteDataTable(string.Format("SELECT Time FROM {0} WHERE Spread > 0 ORDER BY Time", symbolPeriodTime));
            }
            catch (Exception)
            {
                string sql = @"CREATE TABLE [dbo].[{0}](
            [Time] [bigint] NOT NULL,
            [Date] [datetime] NOT NULL,
            [hour] [int] NOT NULL,
            [dayofweek] [int] NOT NULL,
            [open] [float] NOT NULL,
            [close] [float] NOT NULL,
            [high] [float] NOT NULL,
            [low] [float] NOT NULL,
            [spread] [int] NULL,
            [AskVolume] [float] NULL,
            [BidVolume] [float] NULL,
            [AMA_9_2_30] [float] NULL,
            [ADX_14] [float] NULL,
            [ADX_14_P] [float] NULL,
            [ADX_14_M] [float] NULL,
            [ADXWilder_14] [float] NULL,
            [ADXWilder_14_P] [float] NULL,
            [ADXWilder_14_M] [float] NULL,
            [Bands_20_2] [float] NULL,
            [DEMA_14] [float] NULL,
            [FrAMA_14] [float] NULL,
            [MA_10] [float] NULL,
            [TEMA_14] [float] NULL,
            [VIDyA_9_12] [float] NULL,
            [ATR_14] [float] NULL,
            [BearsPower_13] [float] NULL,
            [BullsPower_13] [float] NULL,
            [CCI_14] [float] NULL,
            [DeMarker_14] [float] NULL,
            [MACD_12_26_9_M] [float] NULL,
            [MACD_12_26_9_S] [float] NULL,
            [RSI_14] [float] NULL,
            [RVI_10_M] [float] NULL,
            [RVI_10_S] [float] NULL,
            [Stochastic_5_3_3_M] [float] NULL,
            [Stochastic_5_3_3_S] [float] NULL,
            [TriX_14] [float] NULL,
            [WPR_14] [float] NULL,
             CONSTRAINT [PK_{0}] PRIMARY KEY CLUSTERED
            (
            [Time] ASC
            )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
            ) ON [PRIMARY]";

                string sql_m1 = @"CREATE TABLE [dbo].[{0}](
            [Time] [bigint] NOT NULL,
            [Date] [datetime] NOT NULL,
            [hour] [int] NOT NULL,
            [dayofweek] [int] NOT NULL,
            [open] [float] NOT NULL,
            [close] [float] NOT NULL,
            [high] [float] NOT NULL,
            [low] [float] NOT NULL,
            [spread] [int] NOT NULL,
             CONSTRAINT [PK_{0}] PRIMARY KEY CLUSTERED
            (
            [Time] ASC
            )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
            ) ON [PRIMARY]";

                if (period == "M1")
                {
                    DbHelper.Instance.ExecuteNonQuery(string.Format(sql_m1, symbolPeriod));
                }
                else
                {
                    DbHelper.Instance.ExecuteNonQuery(string.Format(sql, symbolPeriod));
                }

                dt = DbHelper.Instance.ExecuteDataTable(string.Format("SELECT Time FROM {0} WHERE Spread > 0 ORDER BY Time", symbolPeriodTime));
            }

            Dictionary<long, long> existRows = new Dictionary<long, long>();
            foreach (System.Data.DataRow row in dt.Rows)
            {
                long time = (long)row["Time"];
                existRows[time] = time;
            }

            dt = DbHelper.Instance.ExecuteDataTable(string.Format("SELECT * FROM {0} WHERE Time = -1", symbolPeriodTime));

            Dictionary<long, int> rateExist = new Dictionary<long, int>();
            for (int n = 0; n < rate.Length; ++n)
            {
                long newtime = rate[n].time;// 放在前面了 +60 * WekaUtils.GetMinuteofPeriod(period);
                DateTime newDate = WekaUtils.GetDateFromTime(newtime);
                if (rateExist.ContainsKey(newtime))
                {
                    continue;
                }
                rateExist[newtime] = 1;

                if (newDate.DayOfWeek == DayOfWeek.Saturday)
                {
                    //WekaUtils.DebugAssert(newDate.Hour == 0 && newDate.Minute == 0 && newDate.Second == 0, "newDate.Hour == 0 && newDate.Minute == 0 && newDate.Second == 0");
                    if (newDate.Hour == 0 && newDate.Minute == 0 && newDate.Second == 0)
                    {
                        newDate = newDate.AddDays(2);
                        newtime = newtime + (long)(new TimeSpan(2, 0, 0, 0).TotalSeconds);
                    }
                    else
                    {
                        continue;
                    }
                }
                else if (newDate.DayOfWeek == DayOfWeek.Sunday)
                {
                    Console.WriteLine(string.Format("{0} is Sunday", newDate.ToString(Parameters.DateTimeFormat)));
                    continue;
                }

                if (existRows.ContainsKey(newtime))// newDate >= minDate && newDate <= maxDate)
                {
                    continue;
                }

                if (rate[n].open == rate[n].close && rate[n].open == rate[n].low && rate[n].open == rate[n].high)
                {
                    Console.WriteLine(string.Format("{0} is all same price", newDate.ToString(Parameters.DateTimeFormat)));
                    //continue;
                }

                {
                    System.Data.DataRow row = dt.NewRow();
                    row["Time"] = newtime;
                    row["Date"] = newDate;
                    row["hour"] = newDate.Hour;
                    row["dayofweek"] = newDate.DayOfWeek;
                    row["open"] = rate[n].open;
                    row["close"] = rate[n].close;
                    row["high"] = rate[n].high;
                    row["low"] = rate[n].low;
                    row["spread"] = rate[n].spread;

                    if (period != "M1" && inds != null)
                    {
                        foreach (var kvp in inds)
                        {
                            if (kvp.Value.ContainsKey(rate[n].time))
                            {
                                row[kvp.Key] = kvp.Value[rate[n].time];
                            }
                            else
                            {
                                row[kvp.Key] = 0;
                            }
                        }
                    }
                    dt.Rows.Add(row);
                }
            }
            System.Console.WriteLine(string.Format("{0} has {1}, write {2}", symbolPeriodTime, existRows.Count, dt.Rows.Count));
            Feng.Data.DbHelper.Instance.BulkCopy(dt, symbolPeriodTime);

            //int n = 0;
            //Func<bool> f2 = () => n >= rate.Length;
            //Func<SqlCommand[]> f1 = () =>
            //{
            //    SqlCommand cmd = null;

            //    long newtime = rate[n].time + 60 * WekaUtils.GetMinuteofPeriod(period);
            //    DateTime newDate = WekaUtils.GetDateFromTime(newtime);

            //    if (existRows.ContainsKey(newtime))// newDate >= minDate && newDate <= maxDate)
            //    {
            //    }
            //    else
            //    {
            //        //if (!ind2.ContainsKey(rate[i].time / 3600 * 3600))
            //        //{
            //        //    WriteLog("No indicator of " + rate[i].time);
            //        //    continue;
            //        //}

            //        string sql = string.Format("INSERT INTO [{0}] ([time],[date],[hour],[dayofweek],[open],[close],[high],[low],[spread]", symbolPeriodTime);
            //        foreach (var kvp in inds)
            //        {
            //            sql += ",[" + kvp.Key + "]";
            //        }
            //        sql += ") VALUES (@time, @date, @hour,@dayofweek,@open, @close,@high,@low,@spread";
            //        foreach (var kvp in inds)
            //        {
            //            sql += ",@" + kvp.Key;
            //        }
            //        sql += ")";
            //        cmd = new SqlCommand(sql);

            //        cmd.Parameters.AddWithValue("@time", newtime);
            //        cmd.Parameters.AddWithValue("@date", newDate);
            //        cmd.Parameters.AddWithValue("@hour", newDate.Hour);
            //        cmd.Parameters.AddWithValue("@dayofweek", newDate.DayOfWeek);
            //        cmd.Parameters.AddWithValue("@open", rate[n].open);
            //        cmd.Parameters.AddWithValue("@close", rate[n].close);
            //        cmd.Parameters.AddWithValue("@high", rate[n].high);
            //        cmd.Parameters.AddWithValue("@low", rate[n].low);
            //        //cmd.Parameters.AddWithValue("@tick_volume", rate[i].tick_volume);
            //        cmd.Parameters.AddWithValue("@spread", rate[n].spread);
            //        //cmd.Parameters.AddWithValue("@real_volume", rate[i].real_volume);

            //        foreach (var kvp in inds)
            //        {
            //            if (kvp.Value.ContainsKey(rate[n].time))
            //            {
            //                cmd.Parameters.AddWithValue("@" + kvp.Key, kvp.Value[rate[n].time]);
            //            }
            //            else
            //            {
            //                cmd.Parameters.AddWithValue("@" + kvp.Key, 0);
            //            }
            //        }
            //    }

            //    n++;

            //    if (cmd != null)
            //    {
            //        return new SqlCommand[] { cmd };
            //    }
            //    else
            //    {
            //        return null;
            //    }
            //};

            //DbUtils.BatchDb(f1, f2);
        }
Esempio n. 5
0
        public static void GeneratePeriodData(string symbol, string period, int aheadHour)
        {
            //var rateM1 = MT5Data.ReadRates(symbol + "_M1");
            var rateM1 = DbData.Instance.ReadRates(symbol + "_M1");
            List<MqlRates> ratesNew = new List<MqlRates>();

            for(int i=0; i<rateM1.Length; ++i)
            {
                rateM1[i].time += aheadHour * 3600;
            }
            int newPeriodSecond = 60 * WekaUtils.GetMinuteofPeriod(period);
            MqlRates newRate = new MqlRates();
            newRate.low = double.MaxValue;
            newRate.open = rateM1[0].open;
            newRate.time = rateM1[0].time / newPeriodSecond * newPeriodSecond;

            int cnt = 0;
            for(int i=1; i<rateM1.Length; ++i)
            {
                if (rateM1[i].time - newRate.time >= newPeriodSecond)
                {
                    if (newRate.low != double.MaxValue && newRate.high != 0)
                    {
                        if (cnt > newPeriodSecond / 60 / 8)
                        {
                            ratesNew.Add(newRate);
                        }
                    }
                    else
                    {
                    }
                    newRate = new MqlRates();
                    newRate.low = double.MaxValue;
                    newRate.open = rateM1[i].open;
                    newRate.time = rateM1[i].time / newPeriodSecond * newPeriodSecond;
                    cnt = 0;
                }
                else
                {
                    newRate.high = Math.Max(newRate.high, rateM1[i].high);
                    newRate.low = Math.Min(newRate.low, rateM1[i].low);
                    newRate.real_volume += rateM1[i].real_volume;
                    newRate.spread = Math.Max(newRate.spread, rateM1[i].spread);
                    newRate.tick_volume += rateM1[i].tick_volume;
                    newRate.close = rateM1[i].close;

                    cnt++;
                }
            }

            var rate = ratesNew.ToArray();
            for (int n = 0; n < rate.Length; ++n)
            {
                long newtime = rate[n].time + 60 * WekaUtils.GetMinuteofPeriod(period);
                rate[n].time = newtime;
            }

            ImportToDb(symbol, period, 0, rate, null);
        }
Esempio n. 6
0
 private static bool CheckTimeIdx(long time, MqlRates[] rates, ref int idx)
 {
     if (idx >= 0)
         return true;
     idx = ~idx;
     if (idx >= 0 && idx < rates.Length && (rates[idx].time - time) / 60 <= 60 * 24)
         return true;
     return false;
 }
Esempio n. 7
0
        //private ParameterdCandidateStrategy _realDealsCandidate;
        public void RunOnTick(long nowTime, MqlRates nowRate)
        {
            // We now updateHpData on every bar
            //DateTime nowDate = WekaUtils.GetDateFromTime(nowTime);

            //if (!TestParameters2.UseFutureHpData)
            //{
            //    realDealsCandidate.ExecuteCandidateNowDeals(nowDate, nowRate);
            //}
        }
 private void ExecuteCandidateNowDeals(DateTime nowDate, MqlRates nowRate)
 {
     foreach (var kvp in m_classifierInfos)
     {
         var clsInfo = kvp.Value;
         clsInfo.Deals.NowDeals(nowDate, nowRate);
     }
 }
Esempio n. 9
0
        public void NowDeals(DateTime nowTime, MqlRates nowRate)
        {
            if (!TestParameters2.RealTimeMode)
            {
                WekaUtils.Instance.WriteLog("in not realTimeMode, NowDeals should not be called.");
                return;
            }

            m_nowTime = nowTime;

            m_nowPrice = nowRate;

            foreach (var i in m_deals)
            {
                if (i.OpenTime >= m_nowTime)
                    continue;

                if (!i.CloseTime.HasValue)
                {
                    CalculateDealCloseTimeOnly(i);
                }
            }
        }
Esempio n. 10
0
        public void OnTick(MqlRates mqlRate, double zigzag, ReturnActionInfo returnAction)
        {
            //if (mqlRate.time != (new DateTime(2010, 5, 3, 16, 25, 0) - this.MtStartTime).TotalSeconds)
            //    return;

            //if (mqlRate.time < (new DateTime(2009, 08, 10, 07, 25, 0) - this.MtStartTime).TotalSeconds)
            //    return;
            //if (mqlRate.time > (new DateTime(2010, 08, 10, 07, 25, 0) - this.MtStartTime).TotalSeconds)
            //    return;

            if (zigzag == 0)
                return;

            if (m_lastTime == mqlRate.time && m_lastZigzag == zigzag)
                return;

            if (m_isCalculating)
                return;

            m_isCalculating = true;
            m_lastTime = mqlRate.time;
            m_lastZigzag = zigzag;

            try
            {
                int nowRatePos = m_simulator.Rates.Count - 1;
                int nowZigzagPos = this.ZigzagValues.Count - 1;

                // Add Data
                if ((m_simulator.Rates[m_simulator.Rates.Count - 1].time - Parameters.MtStartTime).TotalSeconds < mqlRate.time)
                {
                    m_simulator.Rates.Add(new ZigzagRate
                    {
                        time = Parameters.MtStartTime.AddSeconds(mqlRate.time),
                        open = mqlRate.open,
                        high = mqlRate.high,
                        low = mqlRate.low,
                        close = mqlRate.close,
                        tick_volume = mqlRate.tick_volume,
                        spread = mqlRate.spread,
                        real_volume = mqlRate.real_volume,
                        zigzag = zigzag
                    });
                    nowRatePos++;

                    if (zigzag != 0)
                    {
                        this.ZigzagValues.Add(zigzag);
                        this.ZigzagToRatePos.Add(m_simulator.Rates.Count - 1);

                        nowZigzagPos++;
                    }
                }
                else if ((m_simulator.Rates[m_simulator.Rates.Count - 1].time - Parameters.MtStartTime).TotalSeconds == mqlRate.time)
                {
                    var v = m_simulator.Rates[m_simulator.Rates.Count - 1];
                    v.open = mqlRate.open;
                    v.high = mqlRate.high;
                    v.low = mqlRate.low;
                    v.close = mqlRate.close;
                    v.tick_volume = mqlRate.tick_volume;
                    v.spread = mqlRate.spread;
                    v.real_volume = mqlRate.real_volume;
                    v.zigzag = zigzag;

                    if (zigzag != this.ZigzagValues[this.ZigzagValues.Count - 1])
                    {
                        this.ZigzagValues[this.ZigzagValues.Count - 1] = zigzag;
                    }
                }
                else
                {
                    for (int i = 0; i < m_simulator.Rates.Count; ++i)
                    {
                        if ((m_simulator.Rates[i].time - Parameters.MtStartTime).TotalSeconds == mqlRate.time)
                        {
                            nowRatePos = i;
                            break;
                        }
                    }

                    for (int i = 0; i < this.ZigzagToRatePos.Count; ++i)
                    {
                        if (this.ZigzagToRatePos[i] > nowRatePos)
                        {
                            nowZigzagPos = i - 1;
                            break;
                        }
                    }
                    //throw new ArgumentException("Invalid mqlRate's Time in OnTick!");
                }

                if (nowZigzagPos < m_zigzagPatternLength)
                {
                    return;
                }

                if (nowZigzagPos == m_lastZigzagPos)
                {
                    return;
                }

                m_lastZigzagPos = nowZigzagPos;

                Dictionary<int, int> priceStatIn = new Dictionary<int, int>();
                Dictionary<int, int> priceStatOut = new Dictionary<int, int>();
                List<List<ZigzagRate>> likeRatesList = new List<List<ZigzagRate>>();

                double[] nowZigzag = new double[m_zigzagPatternLength];
                double[] prevZigzag = new double[m_zigzagPatternLength];

                for (int i = 0; i < m_zigzagPatternLength; ++i)
                {
                    nowZigzag[i] = this.ZigzagValues[nowZigzagPos + i + 1 - m_zigzagPatternLength]; //
                }
                Normalize(nowZigzag);

                for (int j = m_zigzagPatternLength - 1; j < nowZigzagPos; ++j)
                {
                    // 加 1 - m_zigzagPatternLength为朝后看
                    for (int i = 0; i < m_zigzagPatternLength; ++i)
                    {
                        prevZigzag[i] = this.ZigzagValues[j + i + 1 - m_zigzagPatternLength];
                    }
                    Normalize(prevZigzag);

                    double[] ret;
                    if (m_simiCache[nowZigzagPos, j, 0] != 0)
                    {
                        ret = new double[] { m_simiCache[nowZigzagPos, j, 0], m_simiCache[nowZigzagPos, j, 1] };
                    }
                    else
                    {
                        //ret = weka.timeseries.SimilarityAnalysis.GetSimilarity(nowZigzag, prevZigzag);
                        //m_simiCache[nowZigzagPos, j, 0] = ret[0];
                        //m_simiCache[nowZigzagPos, j, 1] = ret[1];
                        ret = new double[1] { 0 };
                    }

                    if (ret[0] < m_zigzagSimilarityFreqE && ret[1] < m_zigzagSimilarityTimeE)
                    {
                        //GetPriceStat(this.ZigzagToRatePos[j], 0, 50, priceStatIn);
                        //GetPriceStat(this.ZigzagToRatePos[j], 50, 200, priceStatOut);

                        var l = new List<ZigzagRate>();
                        likeRatesList.Add(l);
                        for (int i = 0; i < 120; ++i)
                        {
                            l.Add(m_simulator.Rates[this.ZigzagToRatePos[j] + i]);
                        }
                    }
                }

                if (likeRatesList.Count == 0)
                    return;

                double maxP = double.MinValue;
                int maxDealType = 0, maxBl = 0, maxTp = 0, maxSl = 0;

                for (int i = 0; i <= 20; i += 5)
                {
                    for (int tp = 20; tp <= 100; tp += 5)
                    {
                        for (int sl = 10; sl < 50; sl += 5)
                        {
                            double profit = 0;
                            foreach (List<ZigzagRate> l in likeRatesList)
                            {
                                bool hasPosition = false;
                                double dealPrice = 0;
                                double nowPrice = l[0].open;
                                foreach (ZigzagRate r in l)
                                {
                                    if (!hasPosition)
                                    {
                                        double price = nowPrice - i * 0.0001;
                                        if (price >= r.low && price < r.high)
                                        {
                                            hasPosition = true;
                                            dealPrice = price;
                                        }
                                    }
                                    else
                                    {
                                        if (dealPrice + tp * 0.0001 >= r.low && dealPrice + tp * 0.0001 < r.high)
                                        {
                                            profit += tp;
                                            break;
                                        }
                                        else if (dealPrice - sl * 0.0001 + this.Spread * 0.0001 >= r.low && dealPrice - sl * 0.0001 + this.Spread * 0.0001 < r.high)
                                        {
                                            profit -= sl;
                                            break;
                                        }
                                    }
                                }
                            }

                            if (profit > 0 && profit > maxP)
                            {
                                maxDealType = 1;
                                maxP = profit;
                                maxBl = i;
                                maxTp = tp;
                                maxSl = sl;
                            }

                            // sell
                            profit = 0;
                            foreach (List<ZigzagRate> l in likeRatesList)
                            {
                                bool hasPosition = false;
                                double dealPrice = 0;
                                double nowPrice = l[0].open;
                                foreach (ZigzagRate r in l)
                                {
                                    if (!hasPosition)
                                    {
                                        double price = nowPrice + i * 0.0001;
                                        if (price + this.Spread * 0.0001 >= r.low && price + this.Spread * 0.0001 < r.high)
                                        {
                                            hasPosition = true;
                                            dealPrice = price;
                                        }
                                    }
                                    else
                                    {
                                        if (dealPrice - tp * 0.0001 - this.Spread * 0.0001 >= r.low && dealPrice - tp * 0.0001 - this.Spread * 0.0001 < r.high)
                                        {
                                            profit += tp;
                                            break;
                                        }
                                        else if (dealPrice + sl * 0.0001 >= r.low && dealPrice + sl * 0.0001 < r.high)
                                        {
                                            profit -= sl;
                                            break;
                                        }
                                    }
                                }
                            }

                            if (profit > 0 && profit > maxP)
                            {
                                maxDealType = -1;
                                maxP = profit;
                                maxBl = i;
                                maxTp = tp;
                                maxSl = sl;
                            }
                        }
                    }
                }

                using (StreamWriter sw = new StreamWriter("c:\\forex\\ea_order_detail.txt", true))
                {
                    sw.WriteLine(string.Format("{0}, {1}, {2}, {3}, {4}, {5}, {6}", nowZigzagPos, maxDealType, maxBl, maxTp, maxSl, maxP, Parameters.MtStartTime.AddSeconds(mqlRate.time).ToString("yyyy.MM.dd HH:mm")));
                }

                using (StreamWriter sw = new StreamWriter("c:\\forex\\ea_order.txt", true))
                {
                    if (maxDealType == 1)
                    {
                        sw.WriteLine(string.Format("Buy, {0}, {1}, {2}, {3}, {4}", Parameters.MtStartTime.AddSeconds(mqlRate.time).ToString("yyyy.MM.dd HH:mm"), maxBl, maxTp, maxSl, maxP));
                    }
                    else if (maxDealType == -1)
                    {
                        sw.WriteLine(string.Format("Sell, {0}, {1}, {2}, {3}, {4}", Parameters.MtStartTime.AddSeconds(mqlRate.time).ToString("yyyy.MM.dd HH:mm"), maxBl, maxTp, maxSl, maxP));
                    }
                }

                //if (priceStatIn.Count == 0 && priceStatOut.Count == 0)
                //    return;

                //double count = 0, count2 = 0;
                //foreach (var dealIn in priceStatIn)
                //    count += dealIn.Value;
                //foreach (var dealOut in priceStatOut)
                //    count2 += dealOut.Value;

                //double maxPSell = double.MinValue, minPSell = double.MaxValue, allPSell = 0;
                //double maxPBuy = double.MinValue, minPBuy = double.MaxValue, allPBuy = 0;
                //int maxDealInBuy = 0, maxDealOutBuy = 0;
                //int maxDealInSell = 0, maxDealOutSell = 0;
                //foreach (var dealIn in priceStatIn)
                //{
                //    foreach (var dealOut in priceStatOut)
                //    {
                //        int profitSell = 0, profitBuy = 0;
                //        profitBuy = dealOut.Key - dealIn.Key - this.Spread;
                //        profitSell = dealIn.Key - dealOut.Key - this.Spread;

                //        double prob = (dealIn.Value / count) * (dealOut.Value / count2);
                //        double p1 = prob * profitBuy;
                //        double p2 = prob * profitSell;
                //        if (p1 > maxPBuy)
                //        {
                //            maxPBuy = p1;
                //            maxDealInBuy = dealIn.Key;
                //            maxDealOutBuy = dealOut.Key;
                //        }
                //        if (p1 < minPBuy)
                //        {
                //            minPBuy = p1;
                //        }

                //        if (p2 > maxPSell)
                //        {
                //            maxPSell = p2;
                //            maxDealInSell = dealIn.Key;
                //            maxDealOutSell = dealOut.Key;
                //        }
                //        if (p2 < minPSell)
                //        {
                //            minPSell = p2;
                //        }

                //        allPBuy += p1;
                //        allPSell += p2;
                //    }
                //}

                //if (allPBuy > allPSell && allPBuy > 0)
                ////if (maxPBuy > maxPSell && maxPBuy > 0)
                //{
                //    returnAction.DealType = 1;
                //    returnAction.DealIn = maxDealInBuy;
                //    returnAction.DealOut = maxDealOutBuy;
                //    returnAction.WinProb = allPBuy;
                //    returnAction.LoseProb = minPBuy;

                //    using (StreamWriter sw = new StreamWriter("c:\\forex\\ea_order.txt", true))
                //    {
                //        sw.WriteLine(string.Format("Buy, {0}, {1}, {2}, {3}, {4}", this.MtStartTime.AddSeconds(mqlRate.time).ToString("yyyy.MM.dd HH:mm"), maxDealInBuy, maxDealOutBuy, allPBuy.ToString("N2"), minPBuy.ToString("N2")));
                //    }
                //}
                //else if (allPSell > allPBuy && allPSell > 0)
                ////else if (maxPSell > maxPBuy && maxPSell > 0)
                //{
                //    returnAction.DealType = -1;
                //    returnAction.DealIn = maxDealInSell;
                //    returnAction.DealOut = maxDealOutSell;
                //    returnAction.WinProb = allPSell;
                //    returnAction.LoseProb = minPSell;

                //    using (StreamWriter sw = new StreamWriter("c:\\forex\\ea_order.txt", true))
                //    {
                //        sw.WriteLine(string.Format("Sell, {0}, {1}, {2}, {3}, {4}", this.MtStartTime.AddSeconds(mqlRate.time).ToString("yyyy.MM.dd HH:mm"), maxDealInSell, maxDealOutSell, allPSell.ToString("N2"), minPSell.ToString("N2")));
                //    }
                //}
                //else
                //{
                //    returnAction.DealType = 0;
                //}
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            finally
            {
                m_isCalculating = false;
            }
        }