Beispiel #1
0
        public bool Compare(IndicatorValues p1, IndicatorValues p2)
        {
            bool r = true;

            foreach (string k in p1.parametrs.Keys)
            {
                if (!p2.parametrs.ContainsKey(k) || p2.parametrs[k] != p1.parametrs[k])
                {
                    r = false;
                    break;
                }
            }
            return(r);
        }
Beispiel #2
0
        private void OneThreadTester(object p)
        {
            //DateTime lastDtBadIndicator;
            GlassGraph                  threadGlassVisual = new GlassGraph();
            ResultOneThreadSumm         resTh = new ResultOneThreadSumm();
            List <int>                  oldGlassValue = new List <int>();
            List <int>                  tempListForIndicator = new List <int>();
            List <int>                  tempListForIndicatorAverage = new List <int>();
            SortedDictionary <int, int> glass = new SortedDictionary <int, int>();
            ParametrsForTest            paramTh = (p as ParametrsForTestObj).paramS;
            Dictionary <string, DataTableWithCalcValues> dictionaryDT = (p as ParametrsForTestObj).dictionaryDT;
            int priceEnterLong, priceEnterShort;
            //IndicatorValuesAggregate aggreValues = new IndicatorValuesAggregate(new TimeSpan(TimeSpan.TicksPerMillisecond * 100)); // 100 мс

            //TimeSpan timeLong = new TimeSpan();
            //TimeSpan timeShort = new TimeSpan();
            IndicatorValues calculatedIndidcator;
            bool            isCalculatedIndicator;
            DateTime        startThread = DateTime.Now;

            foreach (string k in dictionaryDT.Keys)
            {
                //aggreValues.Reset();
                lock (lockObj)
                {
                    isCalculatedIndicator = true;
                    IndicatorValues tempIval = new IndicatorValues(paramTh, ModeIndicator.glassInterest);
                    calculatedIndidcator = (p as ParametrsForTestObj).dictionaryDT[k].indicatorvalues.Find(x => x.Compare(x, tempIval));

                    if (calculatedIndidcator == null)
                    {
                        isCalculatedIndicator = false;
                        (p as ParametrsForTestObj).dictionaryDT[k].indicatorvalues.Add(tempIval);
                        calculatedIndidcator = (p as ParametrsForTestObj).dictionaryDT[k].indicatorvalues.Find(x => x.Compare(x, tempIval));
                    }
                }
                while (isCalculatedIndicator && !calculatedIndidcator.CalculatedFinish) // ждем, пока другой поток завершит рассчет и затем начинаем использовать прощитанные значения
                {
                }

                glass.Clear();
                oldGlassValue.Clear();
                tempListForIndicator.Clear();
                //lastDtBadIndicator = new DateTime();
                priceEnterLong = 0; priceEnterShort = 0;
                bool            indicatorGoToZero = false;
                int             lotCount = 1;
                int?            bid = 0, ask = 0;
                ResultOneThread resThTemp = new ResultOneThread();
                int             lossLongValueTemp = paramTh.lossLongValue, profitLongValueTemp = paramTh.profitLongValue;
                int             lossShortValueTemp = paramTh.lossShortValue, profitShortValueTemp = paramTh.profitShortValue;
                resThTemp.shortName = k;
                DealInfo  dealTemp    = null;
                DataTable dt          = dictionaryDT[k].datatable;//.Copy();
                threadGlassVisual.visualAllElements.levelstartglass  = (int)paramTh.averageValue;
                threadGlassVisual.visualAllElements.levelheightglass = paramTh.glassHeight;
                threadGlassVisual.visualAllElements.levelignoreval   = paramTh.indicatorEnterValue;
                threadGlassVisual.visualAllElements.levelrefilling   = paramTh.indicatorExitValue;

                int      indicator    = 0;
                int      iterationNum = 0; // счетчик строк в текущей DataTable
                int?     pricetick    = 0;
                byte?    actiontick   = 0;
                double?  volumetick   = 0;
                int      martinLevelTemp = 1;
                DateTime dtCurrentRow = new DateTime();

                foreach (DataRow dr in dt.Rows)
                {
                    #region торговля
                    if (DoVisualisation && iterationNum != 0)
                    {
                        if (OnInformation != null)
                        {
                            OnInformation(InfoElement.tbInformation, dr.Field <DateTime>("dtserver").ToString(@"hh\:mm\:ss\.fff"));
                            OnInformation(InfoElement.tbInfo2, "ind " + indicator.ToString());
                        }
                        if (speedvisual >= 0)
                        {
                            Thread.Sleep(new TimeSpan((int)(dr.Field <DateTime>("dtserver").Subtract(dtCurrentRow).TotalMilliseconds *(speedvisual + 1) * 10000)));
                        }
                        else
                        {
                            Thread.Sleep(new TimeSpan((int)(dr.Field <DateTime>("dtserver").Subtract(dtCurrentRow).TotalMilliseconds / Math.Abs(speedvisual) * 10000)));
                        }
                    }
                    dtCurrentRow = dr.Field <DateTime>("dtserver");
                    // совершена сделка
                    if (!dr.IsNull("priceTick") && (pricetick = (int?)dr.Field <float?>("priceTick")) > 0)// && pricetick != (int?)dr.Field<float?>("priceTick")) // вторая часть условия - если перед этим была таже цена - пропускаем
                    {
                        if (indicator == 0)
                        {
                            indicatorGoToZero = true;
                        }
                        actiontick = dr.Field <byte?>("idaction");
                        volumetick = dr.Field <float?>("volumetick");
                        if (DoVisualisation && OnAddTick != null)
                        {
                            OnAddTick(dtCurrentRow, (double)pricetick, (double)volumetick, actiontick == 2 ? ActionGlassItem.sell : ActionGlassItem.buy);
                        }
                        if (priceEnterShort != 0 && indicator > 0 && actiontick == 1)
                        {
                            indicatorGoToZero = false;
                            if (priceEnterShort - ask >= symbolStep)
                            {
                                resThTemp.countPDeal++;
                                resThTemp.profit += (priceEnterShort - (int)ask) * lotCount;
                            }
                            else
                            {
                                resThTemp.countLDeal++;
                                resThTemp.loss += ((int)ask - priceEnterShort) * lotCount;;
                            }
                            dealTemp.DoExit(dtCurrentRow, (float)ask);
                            resThTemp.lstAllDeals.Add(dealTemp);
                            priceEnterShort = 0;
                            // профит короткая
                            //if (priceEnterShort - profitShortValueTemp >= ask)
                            //{
                            //    resThTemp.countPDeal++;
                            //    resThTemp.profit += (priceEnterShort - (int)ask) * lotCount;
                            //    priceEnterShort = 0;
                            //    dealTemp.DoExit(dtCurrentRow, (float)ask);
                            //    //dealTemp.aggreeIndV = aggreValues.ResultAggregate;
                            //    resThTemp.lstAllDeals.Add(dealTemp);
                            //}
                            // лосс короткая
                            //else if (indicator > 0)
                            //{
                            //    resThTemp.countLDeal++;
                            //    int g = ((int)ask - priceEnterShort) * lotCount;
                            //    resThTemp.loss += g;
                            //    dealTemp.DoExit(dtCurrentRow, (float)ask);
                            //    resThTemp.lstAllDeals.Add(dealTemp);
                            //    priceEnterShort = 0;
                            //    priceEnterLong = (int)ask;
                            //    lotCount += 1;
                            //    dealTemp = new DealInfo(ActionDeal.buy, dtCurrentRow, lotCount, priceEnterLong, indicator);
                            //}
                            //else if (priceEnterShort + lossShortValueTemp <= ask)
                            //{
                            //if (paramTh.martingValue >= martinLevelTemp)// && indicator < 0)
                            //{
                            //martinLevelTemp++;
                            //lotCount += 1;
                            //dealTemp.lotsCount = lotCount;
                            //int delt = (int)Math.Truncate((double)((int)ask - priceEnterShort) / lotCount / 10) * 10;

                            //profitShortValueTemp = paramTh.profitShortValue + 2 * delt;
                            //lossShortValueTemp   = paramTh.lossShortValue + delt;

                            //priceEnterShort = priceEnterShort + (int)((int)ask - priceEnterShort) / lotCount;

                            //if (dealTemp.lstSubDeal.Count > 0)
                            //    dealTemp.lstSubDeal.Last().dtDealLength = dtCurrentRow.TimeOfDay.Subtract(dealTemp.lstSubDeal.Last().dtEnter);
                            //dealTemp.lstSubDeal.Add(new SubDealInfo(dtCurrentRow, lotCount, ActionDeal.subsell, (float)priceEnterShort, (float)ask, (float)delt, indicator, (float)lossShortValueTemp, (float)profitShortValueTemp));
                            //dealTemp.lstSubDeal.Last().aggreeIndV = aggreValues.ResultAggregate;
                            //}
                            //else
                            //{
                            //resThTemp.countLDeal++;
                            //int g = ((int)ask - priceEnterShort) * lotCount;
                            //resThTemp.loss += g;
                            //dealTemp.DoExit(dtCurrentRow, (float)ask);
                            //dealTemp.aggreeIndV = aggreValues.ResultAggregate;
                            //resThTemp.lstAllDeals.Add(dealTemp);
                            //priceEnterShort = 0;
                            //lotCount = 1;
                            //}
                            //}
                            // трейлим профит
                            //else if ((ask - paramTh.profitShortValue - 20 > priceEnterShort - profitShortValueTemp) && profitShortValueTemp > 20)
                            //{
                            //    profitShortValueTemp = priceEnterShort - (int)ask + paramTh.profitShortValue;
                            //}
                        }
                        else if (priceEnterLong != 0 && indicator < 0 && actiontick == 2)
                        {
                            indicatorGoToZero = false;
                            if (bid - priceEnterLong >= symbolStep)
                            {
                                resThTemp.countPDeal++;
                                resThTemp.profit += ((int)bid - priceEnterLong) * lotCount;
                            }
                            else
                            {
                                resThTemp.countLDeal++;
                                resThTemp.loss += (priceEnterLong - (int)bid) * lotCount;
                            }
                            dealTemp.DoExit(dtCurrentRow, (float)bid);
                            resThTemp.lstAllDeals.Add(dealTemp);
                            priceEnterLong = 0;
                            // профит длиная
                            //if (priceEnterLong + profitLongValueTemp <= bid)
                            //{
                            //    resThTemp.countPDeal++;
                            //    resThTemp.profit += ((int)bid - priceEnterLong) * lotCount;
                            //    priceEnterLong = 0;
                            //    dealTemp.DoExit(dtCurrentRow, (float)bid);
                            //    //dealTemp.aggreeIndV = aggreValues.ResultAggregate;
                            //    resThTemp.lstAllDeals.Add(dealTemp);
                            //}
                            // лосс длиная
                            //else if (indicator < 0)
                            //{
                            //    resThTemp.countLDeal++;
                            //    int g = (priceEnterLong - (int)bid) * lotCount;
                            //    resThTemp.loss += g;
                            //    dealTemp.DoExit(dtCurrentRow, (float)bid);
                            //    resThTemp.lstAllDeals.Add(dealTemp);
                            //    priceEnterLong = 0;
                            //    priceEnterShort = (int)bid;
                            //    lotCount += 1;
                            //    dealTemp = new DealInfo(ActionDeal.sell, dtCurrentRow, lotCount, priceEnterShort, indicator);
                            //}
                            //else if (priceEnterLong - lossLongValueTemp >= bid)
                            //{
                            //if (paramTh.martingValue >= martinLevelTemp) //&& indicator > 0)
                            //{
                            //martinLevelTemp++;
                            //lotCount += 1;
                            //dealTemp.lotsCount = lotCount;
                            //int delt = (int)Math.Truncate((double)(priceEnterLong - (int)bid) / lotCount / 10) * 10;

                            //profitLongValueTemp = paramTh.profitLongValue + 2 * delt;
                            //lossLongValueTemp   = paramTh.lossLongValue + delt;

                            //priceEnterLong = priceEnterLong - (int)(priceEnterLong - (int)bid) / lotCount;

                            //if (dealTemp.lstSubDeal.Count > 0)
                            //    dealTemp.lstSubDeal.Last().dtDealLength = dtCurrentRow.TimeOfDay.Subtract(dealTemp.lstSubDeal.Last().dtEnter);
                            //dealTemp.lstSubDeal.Add(new SubDealInfo(dtCurrentRow, lotCount, ActionDeal.subbuy, (float)priceEnterLong, (float)bid, (float)delt, indicator, (float)lossLongValueTemp, (float)profitLongValueTemp));
                            //dealTemp.lstSubDeal.Last().aggreeIndV = aggreValues.ResultAggregate;
                            //}
                            //else
                            //{
                            //resThTemp.countLDeal++;
                            //int g = (priceEnterLong - (int)bid) * lotCount;
                            //resThTemp.loss += g;
                            //dealTemp.DoExit(dtCurrentRow, (float)bid);
                            //dealTemp.aggreeIndV = aggreValues.ResultAggregate;
                            //resThTemp.lstAllDeals.Add(dealTemp);
                            //priceEnterLong = 0;
                            //lotCount = 1;
                            //}
                            //}
                            // трейлим профит
                            //else if ((bid + paramTh.profitLongValue < priceEnterLong + profitLongValueTemp - 20) && profitLongValueTemp > 20)
                            //{
                            //    profitLongValueTemp = (int)bid + paramTh.profitLongValue - priceEnterLong;
                            //}
                        }
                        if (indicator > 0 && priceEnterLong == 0 && priceEnterShort == 0 && indicatorGoToZero && actiontick == 1)
                        {
                            lossLongValueTemp   = paramTh.lossLongValue;
                            profitLongValueTemp = paramTh.profitLongValue;
                            priceEnterLong      = (int)ask;
                            lotCount            = 1;
                            martinLevelTemp     = 1;
                            dealTemp            = new DealInfo(ActionDeal.buy, dtCurrentRow, 1, priceEnterLong, indicator);
                        }
                        // вход шорт
                        else if (indicator < 0 && priceEnterLong == 0 && priceEnterShort == 0 && indicatorGoToZero && actiontick == 2)
                        {
                            lossShortValueTemp   = paramTh.lossShortValue;
                            profitShortValueTemp = paramTh.profitShortValue;
                            priceEnterShort      = (int)bid;
                            lotCount             = 1;
                            martinLevelTemp      = 1;
                            dealTemp             = new DealInfo(ActionDeal.sell, dtCurrentRow, 1, priceEnterShort, indicator);
                        }
                    }
                    // изменение в стакане
                    else if (!dr.IsNull("price"))
                    {
                        int updatepricegl  = (int)dr.Field <float?>("price");
                        int updatevolumegl = (int)dr.Field <float?>("volume");
                        int rownum         = (int)dr.Field <int?>("rownum");
                        int typeprice      = (int)dr.Field <int?>("typeprice");
                        if (rownum == 0)
                        {
                            if (typeprice == 1)
                            {
                                ask = updatepricegl;
                            }
                            else if (typeprice == 2)
                            {
                                bid = updatepricegl;
                            }
                        }
                        if (DoVisualisation && OnChangeGlass != null)
                        {
                            OnChangeGlass(dtCurrentRow, updatepricegl, updatevolumegl, rownum, typeprice == 1 ? ActionGlassItem.sell : ActionGlassItem.buy);
                        }
                        if (!glass.ContainsKey(updatepricegl))
                        {
                            glass.Add(updatepricegl, updatevolumegl);
                        }
                        else
                        {
                            glass[updatepricegl] = updatevolumegl;
                            if (glass.Count > 50)
                            {
                                DateTime dttemp = dtCurrentRow;
                                if (!isCalculatedIndicator)
                                {
                                    int sumGlass = 0;
                                    // среднее значение по стакану
                                    for (int i = 0; i < 50 /*threadGlassVisual.visualAllElements.LevelHeightGlass*/; i++)
                                    {
                                        sumGlass += glass.ContainsKey((int)(ask + i * symbolStep)) ? (int)glass[(int)(ask + i * symbolStep)] : 0;
                                        sumGlass += glass.ContainsKey((int)(bid - i * symbolStep)) ? (int)glass[(int)(bid - i * symbolStep)] : 0;
                                    }
                                    int averageGlass = (int)sumGlass / (50 /*threadGlassVisual.visualAllElements.LevelHeightGlass*/ * 2);
                                    int sumlong = 0, sumshort = 0;
                                    int sumlongAverage = 0, sumshortAverage = 0;
                                    tempListForIndicator.Clear();
                                    tempListForIndicatorAverage.Clear();
                                    // новая версия, более взвешенное значение (как год назад)
                                    for (int i = 0; i < 50 /*paramTh.glassHeight*/; i++)
                                    {
                                        if (glass.ContainsKey((int)(ask + i * symbolStep)))
                                        {
                                            sumlong += (int)glass[(int)(ask + i * symbolStep)];
                                        }
                                        if (glass.ContainsKey((int)(bid - i * symbolStep)))
                                        {
                                            sumshort += (int)glass[(int)(bid - i * symbolStep)];
                                        }
                                        sumlongAverage += glass.ContainsKey((int)(ask + i * symbolStep)) &&
                                                          glass[(int)(ask + i * symbolStep)] < averageGlass * 100  //paramTh.averageValue
                                            ? (int)glass[(int)(ask + i * symbolStep)] : averageGlass * 100;        //(int)paramTh.averageValue;
                                        sumshortAverage += glass.ContainsKey((int)(bid - i * symbolStep)) &&
                                                           glass[(int)(bid - i * symbolStep)] < averageGlass * 100 //paramTh.averageValue
                                            ? (int)glass[(int)(bid - i * symbolStep)] : averageGlass * 100;        // (int)paramTh.averageValue;
                                        if (sumlong + sumshort == 0)
                                        {
                                            continue;
                                        }
                                        tempListForIndicator.Add((int)(sumlong - sumshort) * 100 / (sumlong + sumshort));
                                        int tempsumavr = (sumlongAverage + sumshortAverage) == 0 ? 1 : sumlongAverage + sumshortAverage;
                                        tempListForIndicatorAverage.Add((int)(sumlongAverage - sumshortAverage) * 100 / tempsumavr);
                                    }

                                    lock (lockObj)
                                    {
                                        ResultOneTick r = new ResultOneTick();
                                        threadGlassVisual.visualAllElements.CalcSummIndicatorValue(tempListForIndicatorAverage.ToArray(), r);

                                        if (!calculatedIndidcator.values.ContainsKey(dttemp))
                                        {
                                            calculatedIndidcator.values.Add(dttemp, r.valPresetHeight);
                                        }
                                    }
                                }
                                else
                                {
                                    indicator = (int)calculatedIndidcator.values[dttemp];
                                }
                            }
                        }
                    }
                    // Обновление котировок
                    else if (!dr.IsNull("bid"))
                    {
                        bid = (int)dr.Field <float?>("bid");
                        ask = (int)dr.Field <float?>("ask");
                    }
                    iterationNum++;
                    if (iterationNum == dt.Rows.Count)
                    {
                        #region Закрыть последнюю сделку, если данные закончились (эмитируем отключение программы)
                        if (priceEnterLong != 0)
                        {
                            if (bid - priceEnterLong > 0)
                            {
                                resThTemp.countPDeal++;
                                resThTemp.profit += ((int)bid - priceEnterLong) * lotCount;
                            }
                            else
                            {
                                resThTemp.countLDeal++;
                                resThTemp.loss += (priceEnterLong - (int)bid) * lotCount;
                            }
                            dealTemp.DoExit(dtCurrentRow, (float)bid);
                            //dealTemp.aggreeIndV = aggreValues.ResultAggregate;
                            resThTemp.lstAllDeals.Add(dealTemp);
                            priceEnterLong = 0;
                            lotCount       = 1;
                        }
                        if (priceEnterShort != 0)
                        {
                            if (priceEnterShort - ask > 0)
                            {
                                resThTemp.countPDeal++;
                                resThTemp.profit += (priceEnterShort - (int)ask) * lotCount;
                            }
                            else
                            {
                                resThTemp.countLDeal++;
                                resThTemp.loss += ((int)ask - priceEnterShort) * lotCount;
                            }
                            dealTemp.DoExit(dtCurrentRow, (float)ask);
                            //dealTemp.aggreeIndV = aggreValues.ResultAggregate;
                            resThTemp.lstAllDeals.Add(dealTemp);
                            priceEnterShort = 0;
                            lotCount        = 1;
                        }
                        continue;
                        #endregion
                    }
                    #endregion торговля
                } // конец цикла по строка DataTable
                lock (lockObj)
                {
                    if (!calculatedIndidcator.CalculatedFinish)
                    {
                        calculatedIndidcator.CalculatedFinish = true;
                    }
                }

                resThTemp.margin    = resThTemp.profit - resThTemp.loss;
                resThTemp.profitFac = (float)resThTemp.profit / (float)resThTemp.loss;
                // математическое ожидание
                resThTemp.matExp = (1 + ((float)resThTemp.profit / (float)resThTemp.countPDeal) / ((float)resThTemp.loss / (float)resThTemp.countLDeal))
                                   * ((float)resThTemp.countPDeal / ((float)resThTemp.countPDeal + (float)resThTemp.countLDeal)) - 1;
                resTh.AddOneDayResult(resThTemp);
            }
            lock (lockObj)
            {
                resTh.idCycle        = (p as ParametrsForTestObj).numThread;
                resTh.mutC           = (p as ParametrsForTestObj).mutationCount.ToString() + "|" + DateTime.Now.Subtract(startThread).TotalSeconds.ToString() + "с";
                resTh.idParam        = paramTh.id;
                resTh.paramForTest   = paramTh;
                resTh.glassH         = paramTh.glassHeight;
                resTh.indicLongVal   = paramTh.indicatorEnterValue;
                resTh.indicShortVal  = paramTh.indicatorExitValue;
                resTh.profLongLevel  = paramTh.profitLongValue;
                resTh.lossLongLevel  = paramTh.lossLongValue;
                resTh.profShortLevel = paramTh.profitShortValue;
                resTh.lossShortLevel = paramTh.lossShortValue;
                resTh.martinLevel    = paramTh.martingValue;
                resTh.delay          = paramTh.delay;
                resTh.averageVal     = paramTh.averageValue;

                resTh.margin = resTh.profit - resTh.loss;
                resTh.matExp = (1 + ((float)resTh.profit / (float)resTh.countPDeal) / ((float)resTh.loss / (float)resTh.countLDeal))
                               * ((float)resTh.countPDeal / ((float)resTh.countPDeal + (float)resTh.countLDeal)) - 1;
                if (resTh.loss == 0 && resTh.profit == 0)
                {
                    resTh.profitFac = -1;
                }
                else if (resTh.loss == 0)
                {
                    resTh.profitFac = 999;
                }
                else
                {
                    resTh.profitFac = (float)resTh.profit / (float)resTh.loss;
                }

                ResultBestProfitFactor rp = new ResultBestProfitFactor(resTh.idParam, resTh.profitFac, resTh.margin, resTh.matExp);
                if (!dicAllProfitResult.ContainsKey(rp))
                {
                    dicAllProfitResult.Add(rp, resTh);
                }

                if (OnFinishOneThread != null)
                {
                    OnFinishOneThread(resTh);
                }
            }
        }