Ejemplo n.º 1
0
        public static string SimulateEaOrders()
        {
            string eaOrderFileName = eaOrderFileName = string.Format("{0}\\ea_order_{1}.txt", TestParameters.BaseDir, TestParameters2.CandidateParameter.MainSymbol);

            int nTpsl = TestParameters2.nTpsl;
            long[, , ,] costs = new long[2, TestParameters.TpMaxCount, TestParameters.SlMaxCount, 2];
            long[, , ,] dealCnts = new long[2, TestParameters.TpMaxCount, TestParameters.SlMaxCount, 2];
            long[, , ,] dealTimes = new long[2, TestParameters.TpMaxCount, TestParameters.SlMaxCount, 2];
            List<Tuple<DateTime, long[]>> historyCostTF2 = new List<Tuple<DateTime, long[]>>();
            List<Tuple<DateTime, long[]>> historyCostBS2 = new List<Tuple<DateTime, long[]>>();

            IHpData hpDatas = new HpDbData(TestParameters2.CandidateParameter.MainSymbol);
            long nowMoney = 3000000000;

            using (StreamReader sr1 = new StreamReader(eaOrderFileName))
            {
                while (true)
                {
                    if (sr1.EndOfStream)
                        break;
                    string s = sr1.ReadLine();
                    string[] ss = s.Split(new char[] { ',' });

                    DateTime nowDate = Convert.ToDateTime(ss[2]).AddMinutes(-WekaUtils.GetMinuteofPeriod(TestParameters2.CandidateParameter.MainPeriod));
                    //nowDate = nowDate.AddMinutes((new Random()).Next(15) * 15);

                    var hps = hpDatas.GetHpData(nowDate);
                    if (hps == null)
                        continue;
                    long nowTime = WekaUtils.GetTimeFromDate(nowDate);
                    int selectedDeal = 2;
                    if (ss[1].Trim() == "Sell")
                        selectedDeal = 1;
                    else if (ss[1].Trim() == "Buy")
                        selectedDeal = 0;
                    else
                        throw new ArgumentException("invalid deal type.");

                    {
                        int tpp = TestParameters.GetTpSlMinDelta(TestParameters2.CandidateParameter.MainSymbol) * nTpsl;

                        int tp1 = Convert.ToInt32(ss[3]);
                        int sl1 = Convert.ToInt32(ss[4]);

                        int selectedDealVol = 1;
                        int tp = tp1 / tpp - 1;
                        int sl = sl1 / tpp - 1;
                        int v = (int)(selectedDealVol * 100);
                        //v = maxPoint / sl1;
                        v = 1;
                        //v = (int)(nowMoney / 300000);
                        //v = v / Math.Min(tp, sl); //sl

                        int cv = v * hps.Item1[selectedDeal, tp, sl, 0];
                        int tpv = tp1 * cv;
                        costs[selectedDeal, tp, sl, 0] -= tpv;
                        dealCnts[selectedDeal, tp, sl, 0] += cv;
                        dealTimes[selectedDeal, tp, sl, 0] += cv * (hps.Item2[selectedDeal, tp, sl] - nowTime);

                        cv = v * hps.Item1[selectedDeal, tp, sl, 1];
                        int slv = sl1 * cv;
                        costs[selectedDeal, tp, sl, 1] += slv;
                        dealCnts[selectedDeal, tp, sl, 1] += cv;
                        dealTimes[selectedDeal, tp, sl, 1] += cv * (hps.Item2[selectedDeal, tp, sl] - nowTime);

                        nowMoney = nowMoney + tpv - slv;
                    }

                    // Stat
                    {
                        long[] costsTF2 = new long[2];
                        long[] dealCntTF2 = new long[2];
                        long[] dealTimeTF2 = new long[2];

                        long[] costsBS2 = new long[2];
                        long[] dealCntBS2 = new long[2];

                        for (int t = 0; t < 2; ++t)
                            for (int m = 0; m < 2; ++m)
                            {
                                for (int tp1 = 0; tp1 < TestParameters.TpMaxCount; ++tp1)
                                    for (int sl1 = 0; sl1 < TestParameters.SlMaxCount; ++sl1)
                                    {
                                        costsTF2[t] += costs[m, tp1, sl1, t];
                                        dealCntTF2[t] += dealCnts[m, tp1, sl1, t];
                                        dealTimeTF2[t] += dealTimes[m, tp1, sl1, t];

                                        costsBS2[m] += costs[m, tp1, sl1, t];
                                        dealCntBS2[m] += dealCnts[m, tp1, sl1, t];
                                    }
                            }

                        string ret = string.Format("{0}, {1},{2},{3}\t{4},{5},{6}\t{7},{8},{9}\t{10},{11},{12}\t{13},{14},{15}\t{16}",
                            nowDate.ToString(Parameters.DateTimeFormat),
                            (costsTF2[0] / 1e4).ToString("F2"), (costsTF2[1] / 1e4).ToString("F2"), ((costsTF2[0] + costsTF2[1]) / 1e4).ToString("F2"),
                            (costsBS2[0] / 1e4).ToString("F2"), (costsBS2[1] / 1e4).ToString("F2"), ((costsBS2[0] + costsBS2[1]) / 1e4).ToString("F2"),
                            dealCntBS2[0] == 0 ? "0" : (costsBS2[0] / dealCntBS2[0]).ToString("F0"),
                            dealCntBS2[1] == 0 ? "0" : (costsBS2[1] / dealCntBS2[1]).ToString("F0"),
                            (dealCntBS2[0] + dealCntBS2[1]) == 0 ? "0" : ((costsBS2[0] + costsBS2[1]) / (dealCntBS2[0] + dealCntBS2[1])).ToString("F0"),
                            dealCntTF2[0], dealCntTF2[1], (dealCntTF2[0] + dealCntTF2[1]) == 0 ? "0" : ((double)dealCntTF2[0] / (dealCntTF2[0] + dealCntTF2[1])).ToString("F2"),
                            dealTimeTF2[0] == 0 ? "0" : (costsTF2[0] * 1e8 / dealTimeTF2[0]).ToString("F0"),
                            dealTimeTF2[1] == 0 ? "0" : (costsTF2[1] * 1e8 / dealTimeTF2[1]).ToString("F0"),
                            (dealTimeTF2[0] + dealTimeTF2[1]) == 0 ? "0" : ((costsTF2[0] + costsTF2[1]) * 1e8 / (dealTimeTF2[0] + dealTimeTF2[1])).ToString("F0"),
                            selectedDeal);
                        //if (nowDate.Hour == 10)
                        {
                            WekaUtils.Instance.WriteLog(ret);
                        }

                        historyCostTF2.Add(new Tuple<DateTime, long[]>(nowDate, costsTF2));
                        historyCostBS2.Add(new Tuple<DateTime, long[]>(nowDate, costsBS2));
                    }
                }
            }

            string figureFileName = TestParameters.GetBaseFilePath("figure.txt");
            if (System.IO.File.Exists(figureFileName))
            {
                System.IO.File.Delete(figureFileName);
            }
            List<double> allCosts = new List<double>();
            int nnn = historyCostBS2.Count / 2000;
            nnn = Math.Max(1, nnn);
            using (StreamWriter sw = new StreamWriter(figureFileName))
            {
                for (int j = 0; j < historyCostBS2.Count; ++j)
                {
                    sw.Write(historyCostBS2[j].Item1.ToString(Parameters.DateTimeFormat));
                    sw.Write(", ");
                    double sum = 0;
                    for (int i = 0; i < 2; ++i)
                    {
                        sw.Write(historyCostBS2[j].Item2[i]);
                        sw.Write(", ");
                        sum += historyCostBS2[j].Item2[i];
                    }
                    sw.WriteLine(sum);
                    if (j % nnn == 0)
                    {
                        allCosts.Add(-sum);
                    }
                }
            }

            var maxDrawdown = GetMaximumDrawdown(allCosts);
            var linearCLC = GetNumericCLC(allCosts);
            string summary = string.Format("TotalProfit = {0}, MaxDrawdown = {1}, ProfitFactor = {2}, CLC = {3}",
                allCosts[allCosts.Count - 1], maxDrawdown, (double)historyCostTF2[historyCostTF2.Count - 1].Item2[0] / -historyCostTF2[historyCostTF2.Count - 1].Item2[1],
                linearCLC);
            WekaUtils.Instance.WriteLog(summary);
            return summary;
        }
Ejemplo n.º 2
0
        public string SimulateAccordDealLog(bool writeEaOrderFileName = true, bool testMode = true)
        {
            string ret = string.Empty;
            WekaUtils.Instance.WriteLog("Now SimulateAccordDealLog");

            int nTpsl = TestParameters2.nTpsl;
            int tpStart = TestParameters2.tpStart;
            int slStart = TestParameters2.slStart;
            int tpCount = TestParameters2.tpCount;
            int slCount = TestParameters2.slCount;

            int symbolIdx = 0;
            var symbols = new string[] { TestParameters2.CandidateParameter.MainSymbol };
            var weeks = new string[] { TestParameters2.lastWeek };

            string eaOrderFileName = null;

            StreamWriter swEaOrderFile = null;
            if (writeEaOrderFileName)
            {
                eaOrderFileName = string.Format("{0}\\ea_order_{1}.txt", TestParameters.BaseDir, TestParameters2.CandidateParameter.MainSymbol);
                swEaOrderFile = new StreamWriter(eaOrderFileName, true);
            }

            // DateTime, DealType, Tp, Sl, Cost, num, ccScores
            //Dictionary<DateTime, Tuple<int[, , ,], long[, ,]>>[] hpDatas = new Dictionary<DateTime, Tuple<int[, , ,], long[, ,]>>[symbols.Length];
            IHpData hpDatas = null;
            SortedDictionary<DateTime, Tuple<int, int, int, int, int, double[, ,]>>[,] dealsList = new SortedDictionary<DateTime, Tuple<int, int, int, int, int, double[, ,]>>[symbols.Length, weeks.Length];

            List<Dictionary<DateTime, Tuple<int, long>>> incrementTests = new List<Dictionary<DateTime, Tuple<int, long>>>();
            //incrementTests.Add(ReadTestResult(TestParameters.GetBaseFilePath(string.Format("IncrementTest_{0}_CCScores_w8.txt", symbols[symbolIdx]))));
            //incrementTests.Add(ReadTestResult(TestParameters.GetBaseFilePath(string.Format("IncrementTest_{0}_CCScores_w6.txt", symbols[symbolIdx]))));
            //incrementTests.Add(ReadTestResult(TestParameters.GetBaseFilePath(string.Format("IncrementTest_{0}_CCScores_w4.txt", symbols[symbolIdx]))));
            //incrementTests.Add(ReadTestResult(TestParameters.GetBaseFilePath(string.Format("IncrementTest_{0}_CCScores_w2.txt", symbols[symbolIdx]))));
            //incrementTests.Add(ReadTestResult(TestParameters.GetBaseFilePath(string.Format("IncrementTest_{0}_CCScores_w1.txt", symbols[symbolIdx]))));

            //incrementTests.Add(ReadTestResult(TestParameters.GetBaseFilePath(string.Format("IncrementTest_{0}_CandlePattern_D1.txt", symbols[symbolIdx])), 6));
            //incrementTests.Add(ReadTestResult(TestParameters.GetBaseFilePath(string.Format("IncrementTest_{0}_CandlePattern_H4.txt", symbols[symbolIdx])), 1));

            //incrementTests.Add(ReadTestResult(TestParameters.GetBaseFilePath(string.Format("IncrementTest_{0}_Price_D1.txt", symbols[symbolIdx])), 6));
            //incrementTests.Add(ReadTestResult(TestParameters.GetBaseFilePath(string.Format("IncrementTest_{0}_Price_H4.txt", symbols[symbolIdx])), 1));

            //incrementTests.Add(ReadTestResult(TestParameters.GetBaseFilePath(string.Format("IncrementTest_{0}_ccScores_D1_w4.txt", symbols[symbolIdx])), 6));
            //incrementTests.Add(ReadTestResult(TestParameters.GetBaseFilePath(string.Format("IncrementTest_{0}_ccScores_H4_w4.txt", symbols[symbolIdx])), 1));

            //incrementTests.Add(ReadTestResult(TestParameters.GetBaseFilePath(string.Format("IncrementTest_{0}_ccScores_D1_w8.txt", symbols[symbolIdx])), 6));
            //incrementTests.Add(ReadTestResult(TestParameters.GetBaseFilePath(string.Format("IncrementTest_{0}_ccScores_D1_w2.txt", symbols[symbolIdx])), 6));
            //incrementTests.Add(ReadTestResult(TestParameters.GetBaseFilePath(string.Format("IncrementTest_{0}_ccScores_D1_w1.txt", symbols[symbolIdx])), 6));

            //incrementTests.Add(InvertIncrementTest(ReadTestResult(TestParameters.GetBaseFilePath(string.Format("IncrementTest_USDX_Price_D1.txt", symbols[symbolIdx])), 6)));
            //incrementTests.Add(InvertIncrementTest(ReadTestResult(TestParameters.GetBaseFilePath(string.Format("IncrementTest_USDX_CandlePattern_D1.txt", symbols[symbolIdx])), 6)));

            //AddToIncrementTests(incrementTests, string.Format("IncrementTest_{0}_Price_{1}.txt", symbols[symbolIdx], TestParameters2.CandidateParameter.MainPeriod));
            //AddToIncrementTests(incrementTests, string.Format("IncrementTest_{0}_CandlePattern_{1}.txt", symbols[symbolIdx], TestParameters2.CandidateParameter.MainPeriod));
            //AddToIncrementTests(incrementTests, string.Format("IncrementTest_{0}_ccScores_{1}_w{2}.txt", symbols[symbolIdx], TestParameters2.CandidateParameter.MainPeriod, TestParameters2.lastWeek));

            //incrementTests[0] = InvertIncrementTest(incrementTests[0]);

            string herePeriod = "";
            int minPeriod = int.MaxValue;
            foreach (string incrementFile in Directory.GetFiles(TestParameters.BaseDir, string.Format("IncrementTest_{0}_*.txt", TestParameters2.CandidateParameter.MainSymbol)))
            {
                string file = Path.GetFileName(incrementFile);
                foreach (string p in Parameters.AllPeriodsFull)
                {
                    if (file.Contains(string.Format("_{0}.txt", p)))
                    {
                        if (WekaUtils.GetMinuteofPeriod(p) < minPeriod)
                        {
                            minPeriod = WekaUtils.GetMinuteofPeriod(p);
                            herePeriod = p;
                        }
                    }
                }
            }

            foreach (string incrementFile in Directory.GetFiles(TestParameters.BaseDir, string.Format("IncrementTest_{0}_*.txt", TestParameters2.CandidateParameter.MainSymbol)))
            {
                string file = Path.GetFileName(incrementFile);
                int n = 0;
                foreach (string p in Parameters.AllPeriodsFull)
                {
                    if (p != TestParameters2.CandidateParameter.MainPeriod)
                        continue;

                    if (file.Contains(string.Format("_{0}.txt", p)))
                    {
                        n = WekaUtils.GetMinuteofPeriod(p) / minPeriod;
                        incrementTests.Add(ReadTestResult(incrementFile, n, minPeriod));
                    }
                }
            }

            if (incrementTests.Count == 0)
            {
                if (swEaOrderFile != null)
                    swEaOrderFile.Close();
                return ret;
            }

            string ccScoreFileName = TestParameters.GetBaseFilePath(string.Format("{0}_ccScores_w{2}_{1}.txtnnn",
                symbols[symbolIdx], herePeriod, weeks[0]));
            if (System.IO.File.Exists(ccScoreFileName))
            {
                dealsList[symbolIdx, 0] = CCScoreData.GetDetailDeals(ccScoreFileName, nTpsl);
            }
            else
            {
                dealsList[symbolIdx, 0] = new SortedDictionary<DateTime, Tuple<int, int, int, int, int, double[, ,]>>();
            }

            if (testMode)
            {
                hpDatas = new HpDbData(symbols[symbolIdx]);
                //hpDatas[symbolIdx] = HpData.Instance.GetHpDateFromTxt(TestParameters.GetBaseFilePath(
                //    string.Format("{0}_{1}_hpdata.txt", symbols[symbolIdx], herePeriod)), nTpsl);
            }

            List<Tuple<DateTime, long[]>> historyCostTF2 = new List<Tuple<DateTime, long[]>>();
            List<Tuple<DateTime, long[]>> historyCostBS2 = new List<Tuple<DateTime, long[]>>();
            List<Tuple<DateTime, int, int>> timedCost = new List<Tuple<DateTime, int, int>>();

            DateTime nextDealDate = DateTime.MinValue;

            long[, , ,] costs = new long[2, TestParameters.TpMaxCount, TestParameters.SlMaxCount, 2];
            long[, , ,] dealCnts = new long[2, TestParameters.TpMaxCount, TestParameters.SlMaxCount, 2];
            long[, , ,] dealTimes = new long[2, TestParameters.TpMaxCount, TestParameters.SlMaxCount, 2];

            foreach (var nowDate in incrementTests[0].Keys)
            {
                if (nowDate < nextDealDate)
                    continue;

                Tuple<int[, , ,], long[, ,]> hps = null;
                if (testMode)
                {
                    hps = hpDatas.GetHpData(nowDate);
                    if (hps == null)
                        continue;
                }

                int selectedSl = -1;
                int selectedDeal = -1;
                double selectedDealVol = 0;

                int selectedDeal1 = -1;
                {
                    if (dealsList[symbolIdx, 0].ContainsKey(nowDate))
                    {
                        var ccScores = dealsList[symbolIdx, 0][nowDate].Item6;

                        double[] sum = new double[Parameters.AllDealTypes.Length];
                        double[] oscsum = new double[Parameters.AllDealTypes.Length];
                        int oscCnt = 0;
                        for (int k = 0; k < 2; ++k)
                            for (int i = 0; i < ccScores.GetLength(1); ++i)
                                for (int j = 0; j < ccScores.GetLength(2); ++j)
                                {
                                    sum[k] += ccScores[k, i, j];
                                }
                        for (int i = 0; i < ccScores.GetLength(1); ++i)
                            for (int j = 0; j < ccScores.GetLength(2); ++j)
                            {
                                if (ccScores[0, i, j] < 0 && ccScores[1, i, j] < 0)
                                {
                                    oscsum[0] += ccScores[0, i, j];
                                    oscsum[1] += ccScores[1, i, j];
                                    oscCnt++;
                                }
                            }

                        if (sum[0] < sum[1] && sum[0] < 0)
                        {
                            selectedDeal1 = 0;
                        }
                        else if (sum[1] < sum[0] && sum[1] < 0)
                        {
                            selectedDeal1 = 1;
                        }
                        //if (oscCnt > 400 / 16)
                        //{
                        //    selectedDeal1 = -1;
                        //}
                    }
                }

                int selectedDeal2 = -1;
                {
                    int clsRet = incrementTests[0][nowDate].Item1;
                    bool incrementTestAllSame = true;
                    foreach (var iii in incrementTests)
                    {
                        if (!iii.ContainsKey(nowDate) || clsRet != iii[nowDate].Item1)
                        {
                            incrementTestAllSame = false;
                            break;
                        }
                    }
                    if (incrementTestAllSame)
                    {
                        selectedDeal2 = clsRet;
                        selectedDealVol = 1;
                    }
                }

                int selectedDeal3 = -1;
                {
                    double minCount = incrementTests.Count / 2.0;
                    int[] clsResults = new int[3];
                    foreach (var iii in incrementTests)
                    {
                        if (iii.ContainsKey(nowDate))
                        {
                            clsResults[iii[nowDate].Item1]++;
                        }
                    }
                    if (clsResults[0] >= minCount)
                        selectedDeal3 = 0;
                    else if (clsResults[1] >= minCount)
                        selectedDeal3 = 1;
                }

                selectedDeal = selectedDeal2;
                if (selectedDeal == -1 || selectedDeal == 2)
                    continue;

                // Select min sl
                {
                    if (dealsList[symbolIdx, 0].ContainsKey(nowDate))
                    {
                        var ccScores = dealsList[symbolIdx, 0][nowDate].Item6;

                        for (int m = 0; m < weeks.Length; ++m)
                        {
                            int selectedSl1 = -1;
                            double[] tpSumccScores = new double[slCount];

                            for (int tp1 = tpStart; tp1 < tpCount; ++tp1)
                                for (int sl1 = slStart; sl1 < slCount; ++sl1)
                                {
                                    tpSumccScores[sl1] += ccScores[selectedDeal, tp1, sl1];
                                }
                            for (int sl1 = slStart; sl1 < slCount; ++sl1)
                            {
                                if (tpSumccScores[sl1] < 0)
                                {
                                    selectedSl1 = sl1;
                                    break;
                                }
                            }

                            if (selectedSl1 == -1)
                                break;
                            selectedSl = Math.Max(selectedSl, selectedSl1);
                        }

                        //if (selectedSl == -1)
                        //    continue;
                        //selectedSl = 0;
                    }
                }

                bool isFiltered = false;
                isFiltered = TestManager.Filter(nowDate);
                if (isFiltered)
                    continue;

                //selectedDeal = 1 - selectedDeal;

                //var atr = Feng.Data.DbHelper.Instance.ExecuteScalar("SELECT ATR_14 FROM USDJPY_D1 WHERE TIME = " + WekaUtils.GetTimeFromDate(new DateTime(nowDate.Year, nowDate.Month, nowDate.Day)));
                //if (atr == null)
                //    continue;
                //int x = (int)((double)atr * 10000 * 4);
                //x /= 100;
                //x = x / 40 - 1;
                //selectedSl = x;

                selectedSl = Math.Max(selectedSl, tpStart);
                selectedSl = Math.Min(selectedSl, tpCount - 1);
                selectedSl = 5;
                selectedSl = -1;

                int selectedTp = -1;

                int maxPoint = TestParameters.TpMaxCount * TestParameters.GetTpSlMinDelta(symbols[symbolIdx]);
                long nowTime = WekaUtils.GetTimeFromDate(nowDate);

                int allDealCnt = 1;
                if (selectedTp == -1)
                    allDealCnt *= (tpCount - tpStart);
                if (selectedSl == -1)
                    allDealCnt *= (slCount - slStart);
                double stepHour = 6;
                stepHour = Math.Min(stepHour, WekaUtils.GetMinuteofPeriod(herePeriod) / 60.0);
                int secondPerDeal = (int)(3600 * stepHour / allDealCnt);
                for (double tt = 0; tt < WekaUtils.GetMinuteofPeriod(herePeriod) / 60.0; tt += stepHour)
                {
                    int n = 0;
                    for (int tp = tpStart; tp < tpCount; ++tp)
                    {
                        if (selectedTp != -1 && tp != selectedTp)
                            continue;
                        for (int sl = slStart; sl < slCount; ++sl)
                        {
                            if (selectedSl != -1 && sl != selectedSl)
                                continue;

                            int tpp = TestParameters.GetTpSlMinDelta(symbols[symbolIdx]) * nTpsl;

                            int tp1 = tpp * (tp + 1);
                            int sl1 = tpp * (sl + 1);

                            DateTime closeDate = nowDate.AddSeconds(incrementTests[0][nowDate].Item2);
                            long closeTime = WekaUtils.GetTimeFromDate(closeDate);

                            if (testMode)
                            {
                                int v = (int)(selectedDealVol * 100);
                                //v = maxPoint / sl1;
                                v = 1;

                                if (closeTime >= hps.Item2[selectedDeal, tp, sl] || true)
                                {
                                    int cv = v * hps.Item1[selectedDeal, tp, sl, 0];
                                    int tpv = tp1 * cv;
                                    costs[selectedDeal, tp, sl, 0] -= tpv;
                                    dealCnts[selectedDeal, tp, sl, 0] += cv;
                                    dealTimes[selectedDeal, tp, sl, 0] += cv * (hps.Item2[selectedDeal, tp, sl] - nowTime);

                                    cv = v * hps.Item1[selectedDeal, tp, sl, 1];
                                    int slv = sl1 * cv;
                                    costs[selectedDeal, tp, sl, 1] += slv;
                                    dealCnts[selectedDeal, tp, sl, 1] += cv;
                                    dealTimes[selectedDeal, tp, sl, 1] += cv * (hps.Item2[selectedDeal, tp, sl] - nowTime);

                                    if (swEaOrderFile != null)
                                    {
                                        swEaOrderFile.WriteLine(string.Format("{0}, {1}, {2}, {3}, {4}, 0, 0, {5}, {6}",
                                                TestParameters2.CandidateParameter.MainSymbol,
                                                selectedDeal == 0 ? "Buy" : "Sell",
                                                nowDate.AddMinutes(WekaUtils.GetMinuteofPeriod(TestParameters2.CandidateParameter.MainPeriod))
                                                    .AddHours(tt).AddSeconds(n * secondPerDeal).ToString(Parameters.DateTimeFormat),
                                                tp1, sl1,
                                                WekaUtils.GetDateFromTime(hps.Item2[selectedDeal, tp, sl]).ToString(Parameters.DateTimeFormat),
                                                tpv > slv ? "Right" : "Wrong"));
                                    }
                                }
                                else
                                {
                                    //continue;

                                    double? openPrice = (double?)Feng.Data.DbHelper.Instance.ExecuteScalar(string.Format(
                                        "SELECT TOP 1 [CLOSE] FROM {0}_M1 WHERE TIME = {1} ORDER BY TIME", symbols[symbolIdx], WekaUtils.GetTimeFromDate(nowDate)));
                                    double? closePrice = (double?)Feng.Data.DbHelper.Instance.ExecuteScalar(string.Format(
                                        "SELECT TOP 1 [CLOSE] FROM {0}_M1 WHERE TIME = {1} ORDER BY TIME", symbols[symbolIdx], closeTime));
                                    if (!openPrice.HasValue || !closePrice.HasValue)
                                        continue;

                                    double delta = closePrice.Value - openPrice.Value;
                                    if (delta == 0)
                                        continue;

                                    int t = (int)(Math.Abs(delta) * 10000);
                                    if ((selectedDeal == 0 && delta > 0)
                                        || (selectedDeal == 1 && delta < 0))
                                    {
                                        System.Diagnostics.Debug.Assert(t < tp1);

                                        int cv = v * 1;
                                        int tpv = t * cv - 2;
                                        costs[selectedDeal, tp, sl, 0] -= tpv;
                                        dealCnts[selectedDeal, tp, sl, 0] += cv;
                                        dealTimes[selectedDeal, tp, sl, 0] += cv * (closeTime - nowTime);
                                    }
                                    else if ((selectedDeal == 1 && delta > 0)
                                        || (selectedDeal == 0 && delta < 0))
                                    {
                                        System.Diagnostics.Debug.Assert(t < sl1);

                                        int cv = v * 1;
                                        int slv = t * cv + 2;
                                        costs[selectedDeal, tp, sl, 1] += slv;
                                        dealCnts[selectedDeal, tp, sl, 1] += cv;
                                        dealTimes[selectedDeal, tp, sl, 1] += cv * (closeTime - nowTime);
                                    }
                                    else
                                    {
                                        throw new ArgumentException("");
                                    }
                                }

                                //nextDealDate = WekaUtils.GetDateFromTime(hps.Item2[selectedDeal, tp, sl]);
                            }
                            else
                            {
                                if (swEaOrderFile != null)
                                {
                                    swEaOrderFile.WriteLine(string.Format("{0}, {1}, {2}, {3}, {4}, 0, 0, {5}, {6}",
                                            TestParameters2.CandidateParameter.MainSymbol,
                                            selectedDeal == 0 ? "Buy" : "Sell",
                                            nowDate.AddMinutes(WekaUtils.GetMinuteofPeriod(TestParameters2.CandidateParameter.MainPeriod))
                                                .AddHours(tt).AddSeconds(n * secondPerDeal).ToString(Parameters.DateTimeFormat),
                                            tp1, sl1,
                                            "Unknown", "Unknown"));
                                }
                            }

                            n++;
                        }
                    }
                }

                if (testMode)
                {
                    long[] costsTF2 = new long[2];
                    long[] dealCntTF2 = new long[2];
                    long[] dealTimeTF2 = new long[2];

                    long[] costsBS2 = new long[2];
                    long[] dealCntBS2 = new long[2];

                    for (int t = 0; t < 2; ++t)
                        for (int m = 0; m < 2; ++m)
                        {
                            for (int tp1 = 0; tp1 < TestParameters.TpMaxCount; ++tp1)
                                for (int sl1 = 0; sl1 < TestParameters.SlMaxCount; ++sl1)
                                {
                                    costsTF2[t] += costs[m, tp1, sl1, t];
                                    dealCntTF2[t] += dealCnts[m, tp1, sl1, t];
                                    dealTimeTF2[t] += dealTimes[m, tp1, sl1, t];

                                    costsBS2[m] += costs[m, tp1, sl1, t];
                                    dealCntBS2[m] += dealCnts[m, tp1, sl1, t];
                                }
                        }

                    ret = string.Format("{0}, {1},{2},{3}\t{4},{5},{6}\t{7},{8},{9}\t{10},{11},{12}\t{13},{14},{15}\t{16}",
                        nowDate.ToString(Parameters.DateTimeFormat),
                        (costsTF2[0] / 1e4).ToString("F2"), (costsTF2[1] / 1e4).ToString("F2"), ((costsTF2[0] + costsTF2[1]) / 1e4).ToString("F2"),
                        (costsBS2[0] / 1e4).ToString("F2"), (costsBS2[1] / 1e4).ToString("F2"), ((costsBS2[0] + costsBS2[1]) / 1e4).ToString("F2"),
                        dealCntBS2[0] == 0 ? "0" : (costsBS2[0] / dealCntBS2[0]).ToString("F0"),
                        dealCntBS2[1] == 0 ? "0" : (costsBS2[1] / dealCntBS2[1]).ToString("F0"),
                        (dealCntBS2[0] + dealCntBS2[1]) == 0 ? "0" : ((costsBS2[0] + costsBS2[1]) / (dealCntBS2[0] + dealCntBS2[1])).ToString("F0"),
                        dealCntTF2[0], dealCntTF2[1], (dealCntTF2[0] + dealCntTF2[1]) == 0 ? "0" : ((double)dealCntTF2[0] / (dealCntTF2[0] + dealCntTF2[1])).ToString("F2"),
                        dealTimeTF2[0] == 0 ? "0" : (costsTF2[0] * 1e8 / dealTimeTF2[0]).ToString("F0"),
                        dealTimeTF2[1] == 0 ? "0" : (costsTF2[1] * 1e8 / dealTimeTF2[1]).ToString("F0"),
                        (dealTimeTF2[0] + dealTimeTF2[1]) == 0 ? "0" : ((costsTF2[0] + costsTF2[1]) * 1e8 / (dealTimeTF2[0] + dealTimeTF2[1])).ToString("F0"),
                        selectedDeal);
                    //if (nowDate.Hour == 10)
                    {
                        WekaUtils.Instance.WriteLog(ret);
                    }
                    historyCostTF2.Add(new Tuple<DateTime, long[]>(nowDate, costsTF2));
                    historyCostBS2.Add(new Tuple<DateTime, long[]>(nowDate, costsBS2));
                }
            }
            if (swEaOrderFile != null)
                swEaOrderFile.Close();

            string figureFileName = TestParameters.GetBaseFilePath("figure.txt");
            if (System.IO.File.Exists(figureFileName))
            {
                System.IO.File.Delete(figureFileName);
            }
            List<double> allCosts = new List<double>();
            int nnn = historyCostBS2.Count / 2000;
            nnn = Math.Max(1, nnn);
            using (StreamWriter sw = new StreamWriter(figureFileName))
            {
                for (int j = 0; j < historyCostBS2.Count; ++j)
                {
                    sw.Write(historyCostBS2[j].Item1.ToString(Parameters.DateTimeFormat));
                    sw.Write(", ");
                    double sum = 0;
                    for (int i = 0; i < 2; ++i)
                    {
                        sw.Write(historyCostBS2[j].Item2[i]);
                        sw.Write(", ");
                        sum += historyCostBS2[j].Item2[i];
                    }
                    sw.WriteLine(sum);

                    if (j % nnn == 0)
                    {
                        allCosts.Add(-sum);
                    }
                }
            }

            var maxDrawdown = GetMaximumDrawdown(allCosts);
            var linearCLC = GetNumericCLC(allCosts);

            string summary = string.Format("TotalProfit = {0}, MaxDrawdown = {1}, ProfitFactor = {2}, CLC = {3}",
                allCosts.Count == 0 ? 0 : allCosts[allCosts.Count - 1], maxDrawdown,
                historyCostTF2.Count <= 1 ? 0 : (double)historyCostTF2[historyCostTF2.Count - 1].Item2[0] / -historyCostTF2[historyCostTF2.Count - 1].Item2[1],
                linearCLC);
            WekaUtils.Instance.WriteLog(summary);
            return ret + System.Environment.NewLine + summary;
        }