예제 #1
0
        private void AddRobotHintLineOnChart(RobotHint hint, ChartForm chart)
        {
            var pivotIndex = chart.chart.chart.StockSeries.GetIndexByCandleOpen(
                hint.Time.Value);

            var line = new TrendLine
                {
                    Comment = hint.Text,
                    DateStart = hint.Time.Value,
                    LineColor = hint.ColorLine ?? chart.chart.chart.visualSettings.SeriesForeColor,
                    ShapeFillColor = hint.ColorFill ?? chart.chart.chart.visualSettings.SeriesBackColor,
                    LineStyle = TrendLine.TrendLineStyle.Отрезок,
                    Owner = chart.chart.seriesTrendLine
                };
            if (!string.IsNullOrEmpty(hint.HintCode))
                line.Name = hint.HintCode;
            line.AddPoint(pivotIndex, hint.Price.Value);
            // точку конца отрезка сместить вправо на N свечек
            line.AddPoint(pivotIndex + 10, hint.Price.Value);
            chart.chart.seriesTrendLine.data.Add(line);
        }
        public override List <string> OnQuotesReceived(string[] names, QuoteData[] quotes, bool isHistoryStartOff)
        {
            if (formulaResolver == null || packer == null)
            {
                return(null);
            }
            curTime = quotes[0].time;

            // обновить табличку цен
            for (var i = 0; i < names.Length; i++)
            {
                if (lastBids.ContainsKey(names[i]))
                {
                    lastBids[names[i]] = quotes[i].bid;
                }
                else
                {
                    lastBids.Add(names[i], quotes[i].bid);
                }
            }

            QuoteData curQuote = null;

            for (var i = 0; i < names.Length; i++)
            {
                if (names[i] == ticker)
                {
                    curQuote = quotes[i];
                    break;
                }
            }

            if (curQuote == null)
            {
                return(null);                  // нет торгуемой котировки
            }
            // обновить свечки
            var candle = packer.UpdateCandle(curQuote.bid, curQuote.time);
            Dictionary <string, double> varValues = null;

            if (candle != null)
            {
                candles.Add(candle);
                countCandles++;
                // обновить очереди (для индекса, переменные вида usdjpy#15)
                if (lastBidLists.Count > 0)
                {
                    foreach (var listTicker in lastBidLists)
                    {
                        float price;
                        if (!lastBids.TryGetValue(listTicker.Key, out price))
                        {
                            price = 0;
                        }
                        listTicker.Value.Add(price);
                    }
                }
                // посчитать индекс
                double index;
                varValues = GetVariableValues();
                if (formulaResolver.Calculate(varValues, out index))
                {
                    lastIndexValue = double.IsNaN(index) ? 0 : (float)index;
                }
                lastIndicies.Add(lastIndexValue ?? 0);
            }

            // если это период "разгона" конвейера
            if (isHistoryStartOff)
            {
                return(null);
            }

            RobotHint hint = null;

            // получить знак дивергенции
            if (candle != null)
            {
                string             commentOnDivergence = string.Empty;
                var                divergenceSign      = GetDivergenceSign(out commentOnDivergence);
                List <MarketOrder> orders;
                robotContext.GetMarketOrders(robotContext.accountInfo.ID, out orders);
                if (divergenceSign != 0)
                {
                    var hintText = new StringBuilder();
                    hintText.AppendLine(commentOnDivergence);
                    hintText.AppendLine("Переменные:");
                    // ReSharper disable PossibleNullReferenceException)
                    foreach (var pair in varValues)
                    // ReSharper restore PossibleNullReferenceException
                    {
                        hintText.AppendLine(string.Format("{1}{0}{2:f4}", (char)9, pair.Key, pair.Value));
                    }

                    hint = new RobotHint(Graphics[0].a, Graphics[0].b.ToString(),
                                         hintText.ToString(), divergenceSign > 0 ? "BUY" : "SELL", "e", curQuote.bid)
                    {
                        Time = candle.timeOpen,
                        //curTime
                        ColorFill     = divergenceSign > 0 ? Color.Green : Color.Red,
                        ColorLine     = Color.Black,
                        RobotHintType = divergenceSign > 0
                                                       ? RobotHint.HintType.Покупка
                                                       : RobotHint.HintType.Продажа
                    };

                    // если получен сигнал на покупку - купить, закрыв продажи
                    // наоборот, если получен сигнал на продажу - продать, закрыв покупки
                    var ordersToClose = orders.FindAll(o => o.Side != divergenceSign);
                    foreach (var order in ordersToClose)
                    {
                        robotContext.SendCloseRequest(CurrentProtectedContext.Instance.MakeProtectedContext(),
                                                      robotContext.accountInfo.ID, order.ID, PositionExitReason.ClosedByRobot);
                    }

                    // открыть позу в направлении знака дивера
                    decimal?stop = StopLossPoints == 0
                                        ? (decimal?)null
                                        : (decimal)curQuote.bid -
                                   divergenceSign * DalSpot.Instance.GetAbsValue(ticker, (decimal)StopLossPoints);
                    decimal?take = TakeProfitPoints == 0
                                        ? (decimal?)null
                                        : (decimal)curQuote.bid +
                                   divergenceSign * DalSpot.Instance.GetAbsValue(ticker, (decimal)TakeProfitPoints);

                    robotContext.SendNewOrderRequest(CurrentProtectedContext.Instance.MakeProtectedContext(),
                                                     RequestUniqueId.Next(), robotContext.accountInfo.ID, Magic, ticker, Volume,
                                                     divergenceSign, OrderType.Market, 0, 0,
                                                     stop, take, null, null, string.Empty, "OscillatorBasedRobot");
                }
            }

            return(hint != null ? new List <string> {
                hint.ToString()
            } : null);
        }
예제 #3
0
        public override List<string> OnQuotesReceived(string[] names, QuoteData[] quotes, bool isHistoryStartOff)
        {
            if (formulaResolver == null || packer == null) return null;
            curTime = quotes[0].time;

            // обновить табличку цен
            for (var i = 0; i < names.Length; i++)
            {
                if (lastBids.ContainsKey(names[i]))
                    lastBids[names[i]] = quotes[i].bid;
                else
                    lastBids.Add(names[i], quotes[i].bid);
            }

            QuoteData curQuote = null;
            for (var i = 0; i < names.Length; i++)
                if (names[i] == ticker)
                {
                    curQuote = quotes[i];
                    break;
                }

            if (curQuote == null) return null; // нет торгуемой котировки

            // обновить свечки
            var candle = packer.UpdateCandle(curQuote.bid, curQuote.time);
            Dictionary<string, double> varValues = null;
            if (candle != null)
            {
                candles.Add(candle);
                countCandles++;
                // обновить очереди (для индекса, переменные вида usdjpy#15)
                if (lastBidLists.Count > 0)
                {
                    foreach (var listTicker in lastBidLists)
                    {
                        float price;
                        if (!lastBids.TryGetValue(listTicker.Key, out price)) price = 0;
                        listTicker.Value.Add(price);
                    }
                }
                // посчитать индекс
                double index;
                varValues = GetVariableValues();
                if (formulaResolver.Calculate(varValues, out index))
                    lastIndexValue = double.IsNaN(index) ? 0 : (float)index;
                lastIndicies.Add(lastIndexValue ?? 0);
            }

            // если это период "разгона" конвейера
            if (isHistoryStartOff) return null;

            RobotHint hint = null;

            // получить знак дивергенции
            if (candle != null)
            {
                string commentOnDivergence = string.Empty;
                var divergenceSign = GetDivergenceSign(out commentOnDivergence);
                List<MarketOrder> orders;
                robotContext.GetMarketOrders(robotContext.accountInfo.ID, out orders);
                if (divergenceSign != 0)
                {
                    var hintText = new StringBuilder();
                    hintText.AppendLine(commentOnDivergence);
                    hintText.AppendLine("Переменные:");
                    // ReSharper disable PossibleNullReferenceException)
                    foreach (var pair in varValues)
                        // ReSharper restore PossibleNullReferenceException
                    {
                        hintText.AppendLine(string.Format("{1}{0}{2:f4}", (char) 9, pair.Key, pair.Value));
                    }

                    hint = new RobotHint(Graphics[0].a, Graphics[0].b.ToString(),
                        hintText.ToString(), divergenceSign > 0 ? "BUY" : "SELL", "e", curQuote.bid)
                               {
                                   Time = candle.timeOpen,
                                   //curTime
                                   ColorFill = divergenceSign > 0 ? Color.Green : Color.Red,
                                   ColorLine = Color.Black,
                                   RobotHintType = divergenceSign > 0
                                                       ? RobotHint.HintType.Покупка
                                                       : RobotHint.HintType.Продажа
                               };

                    // если получен сигнал на покупку - купить, закрыв продажи
                    // наоборот, если получен сигнал на продажу - продать, закрыв покупки
                    var ordersToClose = orders.FindAll(o => o.Side != divergenceSign);
                    foreach (var order in ordersToClose)
                    {
                        robotContext.SendCloseRequest(CurrentProtectedContext.Instance.MakeProtectedContext(),
                            robotContext.accountInfo.ID, order.ID, PositionExitReason.ClosedByRobot);
                    }

                    // открыть позу в направлении знака дивера
                    decimal? stop = StopLossPoints == 0
                                        ? (decimal?) null
                                        : (decimal)curQuote.bid -
                                          divergenceSign*DalSpot.Instance.GetAbsValue(ticker, (decimal)StopLossPoints);
                    decimal? take = TakeProfitPoints == 0
                                        ? (decimal?) null
                                        : (decimal)curQuote.bid +
                                          divergenceSign*DalSpot.Instance.GetAbsValue(ticker, (decimal)TakeProfitPoints);

                    robotContext.SendNewOrderRequest(CurrentProtectedContext.Instance.MakeProtectedContext(),
                                                     RequestUniqueId.Next(), robotContext.accountInfo.ID, Magic, ticker, Volume,
                                                     divergenceSign, OrderType.Market, 0, 0,
                                                     stop, take, null, null, string.Empty, "OscillatorBasedRobot");
                }
            }

            return hint != null ? new List<string> {hint.ToString()} : null;
        }
예제 #4
0
        private List<string> UpdateOrders(DateTime now, List<MarketOrder> orders)
        {
            var result = new List<string>();
            foreach (var order in orders.Where(o => o.Magic == Magic))
            {
                var sign = order.Side > 0 ? 1 : -1;
                var updateOrder = false;

                // sl
                var slPointsDecrease = InitialSlPoints - (int)((now - order.TimeEnter).TotalMinutes / SlTpPeriodMinutes) * SlTpPointsDecrease;
                var slDecrease = DalSpot.Instance.GetAbsValue(order.Symbol, (float)slPointsDecrease);
                var slValue = order.PriceEnter - sign * slDecrease;
                var slPointsDeviation = GetPointsDeviation(order, slValue, true);
                if (Math.Abs((int)slPointsDeviation) >= 1)
                    updateOrder = true;

                // tp
                var tpPointsDecrease = InitialTpPoints - (int)((now - order.TimeEnter).TotalMinutes / SlTpPeriodMinutes) * SlTpPointsDecrease;
                var tpDecrease = DalSpot.Instance.GetAbsValue(order.Symbol, (float)tpPointsDecrease);
                var tpValue = order.PriceEnter + sign * tpDecrease;
                var tpPointsDeviation = GetPointsDeviation(order, tpValue, false);
                if (Math.Abs((int)tpPointsDeviation) >= 1)
                    updateOrder = true;

                // update
                if (!updateOrder) // sl/tp changes are < 1 points - not updating
                    continue;
                order.StopLoss = slValue;
                order.TakeProfit = tpValue;
                var status = robotContext.SendEditMarketRequest(protectedContext.MakeProtectedContext(), order);
                if (status != RequestStatus.OK)
                {
                    var hint = new RobotHint(order.Symbol, "",
                                                "SendEditMarketRequest error: " +
                                                EnumFriendlyName<RequestStatus>.GetString(status),
                                                order.Side > 0 ? "BUY SL" : "SELL SL", "e", order.StopLoss.Value)
                    {
                        Time = now,
                        RobotHintType = RobotHint.HintType.Поджатие,
                        ColorFill = Color.Red
                    };
                    result.Add(hint.ToString());
                    hint = new RobotHint(order.Symbol, "",
                                         "SendEditMarketRequest error: " +
                                         EnumFriendlyName<RequestStatus>.GetString(status),
                                         order.Side > 0 ? "BUY TP" : "SELL TP", "e", order.TakeProfit.Value)
                    {
                        Time = now,
                        RobotHintType = RobotHint.HintType.Поджатие,
                        ColorFill = Color.Red
                    };
                    result.Add(hint.ToString());
                }
                /*else
                {
                    // 4 debug
                    var hint = new RobotHint(order.Symbol, "", "SendEditMarketRequest Ok",
                                             order.Side > 0 ? "BUY SL" : "SELL SL", "i", order.StopLoss.Value)
                                   {
                                       Time = now,
                                       RobotHintType = RobotHint.HintType.Поджатие,
                                   };
                    result.Add(hint.ToString());
                    hint = new RobotHint(order.Symbol, "", "SendEditMarketRequest Ok",
                                         order.Side > 0 ? "BUY TP" : "SELL TP", "i", order.TakeProfit.Value)
                               {
                                   Time = now,
                                   RobotHintType = RobotHint.HintType.Поджатие,
                               };
                    result.Add(hint.ToString());
                }*/
            }
            return result;
        }
예제 #5
0
        private List<string> ProcessQuotes(string[] names, CandleDataBidAsk[] quotes, bool isHistoryStartOff)
        {
            var result = new List<string>();

            // дописываем лог
            foreach (var m in pendingLogMessages.Where(e => !logMessages.Contains(e)))
            {
                logMessages.Add(m);
                result.Add(MakeLog(m));
            }

            // проверяем инициализацию
            var message = "не инициализирован, остановлен";
            if (newsSettings == null || currencySettings == null)
            {
                if (!logMessages.Contains(message))
                {
                    logMessages.Add(message);
                    result.Add(MakeLog(message));
                }
                return result;
            }

            // all ok inform
            // информируем о начале работы
            message = "запущен";
            if (!logMessages.Contains(message))
            {
                logMessages.Add(message);
                result.Add(MakeLog(message));
            }

            // saving to cache
            // сохраняем кэш котировок
            for (var i = 0; i < names.Length; i++)
            {
                var name = names[i];
                if(!quoteStorage.ContainsKey(name))
                    quoteStorage.Add(name, new List<QuoteData>());
                quoteStorage[name].Add(quotes[i].GetCloseQuote());
            }

            // if this call is used for caching quotes - exiting
            // если мы в режиме наполнения кэша - выходим
            if (isHistoryStartOff)
                return result;

            // detemining model time
            // определение модельного времени
            if (quotes.Length == 0)
                return result;
            var now = quotes[0].timeClose;

            // update orders' SL & TP
            // обновляем сделки
            List<MarketOrder> orders;
            robotContext.GetMarketOrders(robotContext.AccountInfo.ID, out orders);
            result.AddRange(UpdateOrders(now, orders));

            // working with news
            // make GrabNews calls unfrequent
            // сокращаем частоту вызовов GrabNews
            if ((now - lastGrabNewsCall.GetLastHit()).TotalSeconds < PauseForNewsReadingSeconds)
                return result;
            var grab = true; // in present - grab each PauseForNewsReadingSeconds
            if (now.Date < DateTime.Today) // working in the past (testing)
                if (now.Date == lastGrabNewsCall.GetLastHit().Date) // grabbing only once in day
                    grab = false;
            // grabbing
            // извлечение с Alpari
            if (grab)
            {
                List<string> parseErrors;
                var news = GrabNews(new DateTime(now.Year, now.Month, now.Day), out parseErrors);
                foreach (var m in parseErrors.Where(e => !logMessages.Contains(e)))
                {
                    logMessages.Add(m);
                    result.Add(MakeLog(m));
                }
                if (news.Count == 0)
                    logNoFlood.LogMessageFormatCheckFlood(LogEntryType.Error,
                                                          LogMsgNoNewsParsed, 1000 * 60 * 5, "Прочитано 0 новостей");
                else
                    logNoFlood.LogMessageFormatCheckFlood(LogEntryType.Info,
                                                          LogMsgNewsParsed, 1000 * 60 * 5, "Прочитано {0} новостей",
                                                          news.Count);
                freshNews.AddRange(news);
                lastGrabNewsCall.SetTime(now);
            }
            // processing
            // обработка новостей (внешний цикл)
            foreach (var curNews in freshNews)
            {
                var currentNews = curNews;

                // сверяем время
                if (oldNews.Contains(currentNews)) // news already processed
                    continue;
                // news obsolete
                // новость устарела
                if ((now - currentNews.Time - new TimeSpan(0, NewsProcessingDelayMinutes, 0)).TotalMinutes > NewsObsolescenceTimeMinutes)
                {
                    oldNews.Add(currentNews);
                    continue;
                }
                // news in future; skip processing
                // придержим новость на будущее
                if (currentNews.Time + new TimeSpan(0, NewsProcessingDelayMinutes, 0) > now)
                    continue;

                var timeNear = currentNews.Time.AddMinutes(TimeNearMinutes);
                var timeFar = currentNews.Time.AddMinutes(-TimeFarMinutes);

                result.Add(MakeLog("обрабатывается " + currentNews));
                var chatMessage = "\n"; // здесь формируется сообщение в чат
                chatMessage += string.Format("Обрабатывается новость: [{0}] {1}\nВремя: {2}, прогноз: {3}, фактическое: {4}\n",
                                  currentNews.CountryCode, currentNews.Title, currentNews.Time,
                                  currentNews.ProjectedValue, currentNews.Value);

                // calc weights
                // вычисляем веса, определяем знак
                int valueWeight;
                if(currentNews.ProjectedValue > currentNews.Value)
                    valueWeight = -1;
                else if((currentNews.ProjectedValue < currentNews.Value))
                    valueWeight = 1;
                else
                    valueWeight = 0;
                var delta = currentNews.ProjectedValue == 0
                                ? 100
                                : (int)Math.Abs((currentNews.Value - currentNews.ProjectedValue) / currentNews.ProjectedValue * 100);
                var newsWeight = GetWeight(currentNews.CountryCode, currentNews.Title, delta);
                // 4 debug
                /*if (newsWeight == 0)
                {
                    message = string.Format("Valuable news not processed: [{0}] {1}", currentNews.CountryCode,
                                                currentNews.Title);
                    if (!logMessages.Contains(message))
                    {
                        logMessages.Add(message);
                        result.AddRange(MakeLog(message));
                    }
                }*/
                var sign = valueWeight * newsWeight;
                if(sign == 0)
                {
                    oldNews.Add(currentNews);
                    chatMessage += "Результат: нет входа в рынок\n";
                    chatMessage += "Причина: " +
                                   (newsWeight == 0
                                        ? "вес новости равен 0\n"
                                        : "отклонение экономического показателя равно 0\n");
                    if (SendMessageInRoom != null)
                        SendMessageInRoom(chatMessage, chatRoom);
                    continue;
                }

                // gathering tickers for affected currecncies
                // определяем затронутые новостью валютные пары и их знак новостного сигнала
                var tickersAndSigns = new List<Cortege2<string, int>>();
                var currencies = currencySettings.Where(c => c.CountryCode == currentNews.CountryCode).Select(c => c.CurrencyCode);
                foreach (var currency in currencies)
                {
                    var cur = currency;
                    var tickersWithBaseCur = Graphics.Where(g => g.a.StartsWith(cur)).Select(g => g.a);
                    tickersAndSigns.AddRange(tickersWithBaseCur.Select(t => new Cortege2<string, int>(t, sign)).ToList());
                    var tickersWithQuoteCur = Graphics.Where(g => g.a.EndsWith(cur)).Select(g => g.a);
                    tickersAndSigns.AddRange(
                        tickersWithQuoteCur.Select(t => new Cortege2<string, int>(t, -sign)).ToList());
                }

                // processing tickers
                // работаем с выбранными валютными парами (внутренний цикл)
                foreach (var tickerAndSign in tickersAndSigns)
                {
                    var ticker = tickerAndSign.a;
                    var curSign = tickerAndSign.b;

                    // определение действующей на этот момент котировки
                    var data = GetDataFromStorage(ticker, currentNews.Time, currentNews.Time.AddMinutes(5));
                    if(data.Count == 0)
                    {
                        chatMessage += "Результат: нет входа в рынок с " + ticker + "\n";
                        chatMessage += "Причина: нет котировки для " + ticker + " в диапазоне от " +
                                       currentNews.Time + " до " + currentNews.Time.AddMinutes(5) + "\n";
                        if (SendMessageInRoom != null)
                            SendMessageInRoom(chatMessage, chatRoom);
                        continue;
                    }

                    // опорное значение для определения трендов и величины сделки - цена спроса
                    var value = data[0].bid;

                    // определение тренда
                    int signNear = 0, signFar = 0;
                    data = GetDataFromStorage(ticker, timeNear, timeNear.AddMinutes(5));
                    if (data.Count == 0)
                    {
                        // 4 debug
                        var hint = new RobotHint(ticker, "", "insufficient data for near-trend",
                                                    curSign > 0 ? "BUY no near-data" : "SELL no near-data", "e", value)
                                        {Time = now, ColorFill = Color.Red};
                        result.Add(hint.ToString());
                        chatMessage += "Результат: нет входа в рынок с " + ticker + "\n";
                        chatMessage += "Причина: недостаточно данных для определения тренда после выхода новости\n";
                        if (SendMessageInRoom != null)
                            SendMessageInRoom(chatMessage, chatRoom);
                        continue;
                    }
                    var valueNear = data[0].bid;
                    if (value > valueNear)
                        signNear = 1;
                    else if (value < valueNear)
                        signNear = -1;
                    data = GetDataFromStorage(ticker, timeFar, timeFar.AddMinutes(5));
                    if (data.Count == 0)
                    {
                        // 4 debug
                        var hint = new RobotHint(ticker, "", "insufficient data for far-trend",
                                                    curSign > 0 ? "BUY no far-data" : "SELL no far-data", "e", value)
                                        {Time = now, ColorFill = Color.Red};
                        result.Add(hint.ToString());
                        chatMessage += "Результат: нет входа в рынок с " + ticker + "\n";
                        chatMessage += "Причина: недостаточно данных для определения тренда до выхода новости\n";
                        if (SendMessageInRoom != null)
                            SendMessageInRoom(chatMessage, chatRoom);
                        continue;
                    }
                    var valueFar = data[0].bid;
                    if (value > valueFar)
                        signFar = 1;
                    else if (value < valueFar)
                        signFar = -1;

                    // определяем необходимость входа в рынок
                    var values = new Dictionary<string, double>();
                    values.Add("tn", curSign);
                    values.Add("tba", signFar);
                    values.Add("tcb", signNear);
                    double formulaResult;
                    var resultFlag = expressionResolver.Calculate(values, out formulaResult);
                    if (!resultFlag)
                    {
                        result.Add(MakeLog("Ошибка в расчете по формуле для входа в рынок"));
                        chatMessage += "Результат: нет входа в рынок с " + ticker + "\n";
                        chatMessage += "Причина: ошибка в расчете по формуле для входа в рынок\n";
                        if(SendMessageInRoom != null)
                            SendMessageInRoom(chatMessage, chatRoom);
                        continue;
                    }

                    // вход в рынок
                    var tradeSign = 0;
                    switch (EnterSign)
                    {
                        case EnterSignEnum.Tn:
                            tradeSign = curSign;
                            break;
                        case EnterSignEnum.NotTn:
                            tradeSign = -curSign;
                            break;
                        case EnterSignEnum.Tba:
                            tradeSign = signFar;
                            break;
                        case EnterSignEnum.NotTba:
                            tradeSign = -signFar;
                            break;
                        case EnterSignEnum.Tcb:
                            tradeSign = signNear;
                            break;
                        case EnterSignEnum.NotTcb:
                            tradeSign = -signNear;
                            break;
                    }
                    if (formulaResult != 0)
                    {
                        // если получен сигнал на покупку - купить, закрыв продажи
                        // наоборот, если получен сигнал на продажу - продать, закрыв покупки
                        robotContext.GetMarketOrders(robotContext.AccountInfo.ID, out orders);
                        var ordersToClose = orders.Where(o => o.Symbol == ticker && o.Side != tradeSign).ToList();
                        foreach (var order in ordersToClose)
                        {
                            robotContext.SendCloseRequest(protectedContext.MakeProtectedContext(),
                                robotContext.AccountInfo.ID, order.ID, PositionExitReason.ClosedByRobot);
                        }
                        // создаем ордер
                        var decreaseSl = DalSpot.Instance.GetAbsValue(ticker, (float)InitialSlPoints);
                        var slValue = value - tradeSign * decreaseSl;
                        var decreaseTp = DalSpot.Instance.GetAbsValue(ticker, (float)InitialTpPoints);
                        var tpValue = value + tradeSign * decreaseTp;
                        var newOrder = new MarketOrder
                            {
                                AccountID = robotContext.AccountInfo.ID,
                                Magic = Magic,
                                Symbol = ticker,
                                Volume = Volume,
                                Side = tradeSign,
                                StopLoss = slValue,
                                TakeProfit = tpValue,
                                ExpertComment = currentNews.Title
                            };

                        var status = robotContext.SendNewOrderRequest(protectedContext.MakeProtectedContext(),
                                                            RequestUniqueId.Next(),
                                                            newOrder,
                                                            OrderType.Market, (decimal)value, 0);
                        if (status != RequestStatus.OK)
                        {
                            var hint = new RobotHint(ticker, "",
                                                     "SendNewOrderRequest error: " +
                                                     EnumFriendlyName<RequestStatus>.GetString(status) + " news: " +
                                                     currentNews,
                                                     tradeSign > 0 ? "BUY error" : "SELL error", "e", value)
                                {
                                    Time = now,
                                    ColorFill = Color.Red
                                };
                            result.Add(hint.ToString());
                        }
                        else
                        {
                            var hint = new RobotHint(ticker, "", "SendNewOrderRequest Ok, news: " + currentNews,
                                                        tradeSign > 0 ? "BUY" : "SELL", "i", value) { Time = now, ColorFill = Color.Red };
                            result.Add(MakeLog("вход в рынок по новости " + currentNews));
                            result.Add(hint.ToString());
                            chatMessage += "Результат: вход в рынок: " + (tradeSign > 0 ? "покупка " : "продажа ") + ticker + "\n";
                        }
                    }
                    else
                    {
                        var hint = new RobotHint(ticker, "", "Market condition fulfill failed, news: " + currentNews,
                                                    tradeSign > 0 ? "BUY no condition" : "SELL no condition", "e", value)
                                        {
                                            Time = now, RobotHintType = RobotHint.HintType.Стоп
                                        };
                        result.Add(hint.ToString());
                        chatMessage += "Результат: нет входа в рынок с " + ticker + "\n";
                        chatMessage += "Причина: не выполнено условие входа\n";
                    }
                    if (SendMessageInRoom != null)
                        SendMessageInRoom(chatMessage, chatRoom);
                }
                oldNews.Add(currentNews);
            }
            return result;
        }
예제 #6
0
        private void AddRobotHintOnChart(RobotHint hint, ChartForm chart)
        {
            // добавить отрезочек с комментарием
            if (hint.RobotHintType == RobotMark.HintType.Линия)
            {
                AddRobotHintLineOnChart(hint, chart);
                return;
            }

            // добавить звездочку
            var toolTip = new AsteriskTooltip(hint.Title, hint.Text)
                              {
                                  Owner = chart.chart.seriesAsteriks,
                                  Price = hint.Price.Value,
                                  CandleIndex =
                                      chart.chart.chart.StockSeries.GetIndexByCandleOpen(
                                          hint.Time.Value),
                                  DateStart = hint.Time.Value,
                                  Sign = hint.Sign,
                                  Radius = 5,
                                  Shape =
                                      hint.RobotHintType == RobotMark.HintType.Стоп
                                          ? AsteriskTooltip.ShapeType.Квадрат
                                          : hint.RobotHintType == RobotMark.HintType.Тейк
                                                ? AsteriskTooltip.ShapeType.Квадрат
                                                : hint.RobotHintType == RobotMark.HintType.Покупка
                                                      ? AsteriskTooltip.ShapeType.СтрелкаВверх
                                                      : hint.RobotHintType == RobotMark.HintType.Продажа
                                                            ? AsteriskTooltip.ShapeType.СтрелкаВниз
                                                            : hint.RobotHintType ==
                                                              RobotMark.HintType.Поджатие
                                                                  ? AsteriskTooltip.ShapeType.Звезда
                                                                  : AsteriskTooltip.ShapeType.Круг
                              };
            if (!string.IsNullOrEmpty(hint.HintCode))
                toolTip.Name = hint.HintCode;
            if (hint.ColorFill.HasValue) toolTip.ColorFill = hint.ColorFill.Value;
            if (hint.ColorLine.HasValue) toolTip.ColorLine = hint.ColorLine.Value;
            if (hint.ColorText.HasValue) toolTip.ColorText = hint.ColorText.Value;

            chart.chart.seriesAsteriks.data.Add(toolTip);
        }
예제 #7
0
        private bool CheckEnterCondition(CandleData candle, List<MarketOrder> openedOrders, List<string> events, bool isHistoryStartOff)
        {
            if (side == 0) return false;

            // проверить количество сделок
            var ownOrders = FiboRobotPosition.GetRobotPositions(ticker, openedOrders, timeframe, PriceA, null);
            var ordersCount = ownOrders.Count;
            if (ordersCount >= MaxDealsInSeries) return false;

            // обновить цену B?
            var bWasUpdated = false;
            if ((side > 0 && candle.close > (float)PriceB) ||
                (side < 0 && candle.close < (float)PriceB))
            {
                // удалить старую отметку - цена В обновлена
                events.Add(new RobotMarkClear(ticker, timeframe, HintPriceBIsUpdated)
                {
                    RobotHintType = RobotMark.HintType.Тейк
                }.ToString());

                // и добавить новую
                var msg = string.Format("Цена \"B\" обновлена с {0} на {1}",
                                        PriceB.ToStringUniformPriceFormat(), candle.close.ToStringUniformPriceFormat());
                var hint = MakeRobotComment(
                    candle.close, msg,
                    candle.timeClose, Color.Crimson,
                    RobotMark.HintType.Тейк);
                hint.HintCode = HintPriceBIsUpdated;
                events.Add(hint.ToString());
                events.Add(msg);

                PriceB = (decimal)candle.close;
                bWasUpdated = true;
                priceBwasUpdated = true;
            }

            if (isHistoryStartOff) return false;

            // проверить, преодолен ли уровень входа
            var levelBroken =
                IsPriceInsideTargetLevels(candle.close, PriceA, PriceB, false);
            if (!levelBroken) return false;

            var level = PriceB + KoefEnter * (PriceA - PriceB);
            var msgLevelBroken = string.Format("Уровень {0} преодолен, направление - {1}",
                                    level.ToStringUniformPriceFormat(), Side);

            // получить закрытые ордера
            var closedOrders = GetLastClosedOrders();
            var orders = openedOrders.Union(closedOrders).OrderByDescending(o => o.TimeEnter).ToList();
            var openedAndClosedFiboOrders = FiboRobotPosition.GetRobotPositions(ticker, orders, timeframe, PriceA, null);

            // если цена B не была обновлена свечкой, проверить, нет ли сделок
            // по данному расширению A-B, открытых "лучше" этой цены
            if (!bWasUpdated)
            {
                if (openedAndClosedFiboOrders.Count > 0)
                {
                    if ((side > 0 && openedAndClosedFiboOrders.Any(d => d.order.PriceEnter < candle.close)) ||
                        (side < 0 && openedAndClosedFiboOrders.Any(d => d.order.PriceEnter > candle.close)))
                    {
                        msgLevelBroken += ", есть сделки по \"лучшей\" цене";
                        events.Add(msgLevelBroken);
                        return false;
                    }
                }
            }

            // второй уровень Фибо преодолен?
            if (!CheckEnterThenFiboCondition(candle, side, openedAndClosedFiboOrders.Select(o => o.order).ToList()))
            {
                // создать отметку на графике и выйти
                var hint = new RobotHint(ticker, timeframe.ToString(),
                    "Уровень ФБ-II не преодолен", "ФБ-II", "Ф", candle.close)
                {
                    Time = candle.timeClose,
                    ColorFill = Color.Coral,
                    ColorLine = Color.DarkRed,
                    RobotHintType = RobotHint.HintType.Коментарий,
                    Timeframe = BarSettingsStorage.Instance.GetBarSettingsFriendlyName(timeframe)
                };
                events.Add(hint.ToString());

                return false;
            }

            if (CloseOtherSides)
                CloseOtherSideDeals(ownOrders.Select(o => o.order).ToList());

            msgLevelBroken += ", вход в рынок";
            events.Add(msgLevelBroken);
            // таки войти в рынок
            var enterIsOk = OpenDeal(orders);
            if (enterIsOk && (ordersCount >= maxDealsInSeries - 1))
                events.Add(string.Format("Робот \"FX\" {0} осуществил {1} входов в рынок",
                    HumanRTickers, maxDealsInSeries));
            return true;
        }
예제 #8
0
        private void AddRobotHintOnPriceUpdated(string pricePreffix, 
            decimal priceOld, decimal priceNew, DateTime eventTime)
        {
            if (eventTime == default(DateTime))
                eventTime = DateTime.Now;

            var hint = new RobotHint(ticker, timeframe.ToString(),
                "Цена " + pricePreffix + " обновлена с " + priceOld.ToStringUniformPriceFormat() +
                " на " + priceNew.ToStringUniformPriceFormat(), "цена " + pricePreffix, pricePreffix, (float)priceNew)
            {
                Time = eventTime,
                ColorFill = Color.Moccasin,
                ColorLine = Color.DarkGoldenrod,
                RobotHintType = RobotHint.HintType.Тейк,
                Timeframe = BarSettingsStorage.Instance.GetBarSettingsFriendlyName(timeframe)
            };
            recentRobotHints.Add(hint);
        }
예제 #9
0
 private RobotHint MakeRobotComment(float price, string text, DateTime time,
     Color? colorLine = null, RobotMark.HintType hintType = RobotMark.HintType.Линия)
 {
     var hint = new RobotHint(ticker, BarSettingsStorage.Instance.GetBarSettingsFriendlyName(timeframe), text,
                              GetUniqueName(), "*", price)
         {
             Time = time,
             ColorFill = Color.LightGray,
             ColorLine = colorLine ?? Color.DarkBlue,
             RobotHintType = hintType
         };
     return hint;
 }
예제 #10
0
        /// <summary>
        /// проверить условия повторного входа (в другом направлении)
        /// </summary>
        private void CheckVersaEnterCondition(CandleData candle, List<MarketOrder> orders, List<string> events)
        {
            List<FiboRobotPosition> allOrders;
            FiboRobotPosition lastOrder;
            decimal a;
            decimal b;

            if (!GetVersaEnterAandB(orders, out allOrders, out lastOrder, out a, out b)) return;
            var doubleSide = a < b ? DealType.Buy : DealType.Sell;

            var shouldEnter = IsPriceInsideTargetLevels(candle.close, a, b, true);
            if (!shouldEnter) return;

            // проверить - нет ли повторных ("второй серии") входов по "лучшей" цене?
            // не слишком ли много повторных входов?
            var doubledDeals = allOrders.Where(d => d.Sequence > 1).ToList();
            if (doubledDeals.Count(d => d.order.IsOpened) >= MaxDealsInSeries) return;
            var hasBetterDoubledDeal = doubleSide > 0
                                           ? doubledDeals.Any(d => d.order.PriceEnter < candle.close)
                                           : doubledDeals.Any(d => d.order.PriceEnter > candle.close);
            if (hasBetterDoubledDeal) return;

            // проверить - есть ли N свечек и M пунктов с момента последней сделки?
            var deltaPoints = DalSpot.Instance.GetPointsValue(ticker, Math.Abs((decimal)candle.close - b));
            if (deltaPoints < MinPointsForDoubleEnter)
            {
                if (VerboseLogging)
                    Logger.InfoFormat(RobotNamePreffix + ": повторный вход ({0} {1}) невозможен - расстояние [C, D] слишком мало",
                        doubleSide, ticker);
                return;
            }

            // добавить отметку - повторный вход в рынок
            var hint = new RobotHint(ticker, timeframe.ToString(),
                "Повторный вход, цена A: " + a.ToStringUniformPriceFormat() + ", цена B: " + b.ToStringUniformPriceFormat() +
                " (из сделки #" + lastOrder.order.ID + ")",
                "повторный " + doubleSide, "d", candle.close)
            {
                Time = candle.timeClose,
                ColorFill = Color.LawnGreen,
                ColorLine = Color.MediumSeaGreen,
                RobotHintType = RobotHint.HintType.Коментарий,
                Timeframe = BarSettingsStorage.Instance.GetBarSettingsFriendlyName(timeframe)
            };
            events.Add(hint.ToString());

            // войти в рынок повторно
            OpenDeal(orders, a, b, 2, (int)doubleSide);
        }