/// <summary> /// Получить текущую фазу рынка /// </summary> /// <returns></returns> private MarketFaze GetMarketFaze() { MarketFaze currentMarketFaze = MarketFaze.Nothing; // если индекс выше канала, то фазы рынка "Upper" if (_lastIndexPrice > _lastMA + _lastIvashov * Multiply.ValueDecimal) { currentMarketFaze = MarketFaze.Upper; } // если индекс выше средней, но ниже верхней границы канала, то фаза рынка "Up" else if (_lastIndexPrice > _lastMA && _lastIndexPrice <= _lastMA + _lastIvashov * Multiply.ValueDecimal) { currentMarketFaze = MarketFaze.Up; } // если индекс ниже средней, но выше нижней границы канала, то фаза рынка "Low" else if (_lastIndexPrice <= _lastMA && _lastIndexPrice >= _lastMA - _lastIvashov * Multiply.ValueDecimal) { currentMarketFaze = MarketFaze.Low; } // если индекс ниже канала, то фаза рынка "Lower" else if (_lastIndexPrice < _lastMA - _lastIvashov * Multiply.ValueDecimal) { currentMarketFaze = MarketFaze.Lower; } else { currentMarketFaze = MarketFaze.Nothing; } return(currentMarketFaze); }
private void _bot_MarketFazeChangeEvent(MarketFaze marketFaze) { if (lblMarketFaze.Dispatcher.CheckAccess() == false) { lblMarketFaze.Dispatcher.Invoke(new Action <MarketFaze>(_bot_MarketFazeChangeEvent), marketFaze); return; } lblMarketFaze.Content = marketFaze.ToString(); }
private void CheckClosingPositions(int bar, MarketFaze currentMarketFaze) { // получаем все открытые позиции var positions = _sec1.Positions.GetActiveForBar(bar).ToList(); // для каждой позиции проверяем условия её закрытия for (int i = 0; positions != null && i < positions.Count; i++) { // если позиция уже закрывается, то ничего с ней не делаем (применимо только для реальной торговли) if (positions[i].PositionState == PositionState.HaveCloseSignal) { continue; } // если позиция лонг if (positions[i].IsLong) { if (MethodExit_0_Center_1_Boundary.Value == 1 && currentMarketFaze == MarketFaze.Lower) { // закрываем позицию по лимиту CloseLong(bar, positions[i]); } else if (MethodExit_0_Center_1_Boundary.Value == 0 && currentMarketFaze == MarketFaze.Low) { // закрываем позицию по лимиту CloseLong(bar, positions[i]); } } // если позиция шорт else if (positions[i].IsShort) { if (MethodExit_0_Center_1_Boundary.Value == 1 && currentMarketFaze == MarketFaze.Upper) { // закрываем позицию по лимиту CloseShort(bar, positions[i]); } else if (MethodExit_0_Center_1_Boundary.Value == 0 && currentMarketFaze == MarketFaze.Up) { // закрываем позицию по лимиту CloseShort(bar, positions[i]); } } } }
private void CheckClosingPositions(MarketFaze currentMarketFaze) { // получаем все открытые и открывающиеся позиции var positions = _tabSec.PositionsOpenAll; // для каждой позиции проверяем условия её закрытия for (int i = 0; positions != null && i < positions.Count; i++) { // если позиция не имеет статус Open, то ничего с ней не делаем if (positions[i].State != PositionStateType.Open) { continue; } // если позиция лонг if (positions[i].Direction == Side.Buy) { if (MethodOfExit == MethodOfExit.BoundaryChannel && currentMarketFaze == MarketFaze.Lower) { // закрываем позицию по лимиту CloseLong(positions[i]); } else if (MethodOfExit == MethodOfExit.CenterChannel && currentMarketFaze == MarketFaze.Low) { // закрываем позицию по лимиту CloseLong(positions[i]); } } // если позиция шорт else if (positions[i].Direction == Side.Sell) { if (MethodOfExit == MethodOfExit.BoundaryChannel && currentMarketFaze == MarketFaze.Upper) { // закрываем позицию по лимиту CloseShort(positions[i]); } else if (MethodOfExit == MethodOfExit.CenterChannel && currentMarketFaze == MarketFaze.Up) { // закрываем позицию по лимиту CloseShort(positions[i]); } } } }
private void _tab_ServerTimeChangeEvent(DateTime time) { // запускаем торговую логику только через периоды времени _tradeTimePeriod if (_lastTradeTime.AddSeconds(TradeTimePeriod) > time) { return; } _lastTradeTime = time; // проверяем, что вкладка индекса и вкладка для торговли подключены if (_tabIndex.IsConnected == false || _tab.IsConnected == false) { return; } // проверка на включение робота выполняется позже // для возможности вывода текущей фазы рынка в окно настроечных параметров // сохраняем шаг цены для вывода в окно настроечных параметров PriceStep = _tab.Securiti.PriceStep; // проверяем наличие свечей в индексе и вкладке для торговли // и их достаточность для расчета индикаторов List <Candle> candlesIndex = _tabIndex.Candles; List <Candle> candlesTab = _tab.CandlesFinishedOnly; if (candlesIndex == null || candlesIndex.Count < _ma.Lenght + 30 || candlesIndex.Count < _ivashov.LenghtMa + 30 || candlesIndex.Count < _ivashov.LenghtAverage + 30 || candlesTab == null || candlesTab.Count < _ma.Lenght + 30 || _ma.Values.Count < 30 || _ivashov.Values.Count < 30) { return; } // сохраняем последнее значение индекса и индикаторов (для упрощения кода) _lastIndexPrice = candlesIndex[candlesIndex.Count - 1].Close; _lastMA = _ma.Values[_ma.Values.Count - 1]; _lastIvashov = _ivashov.Values[_ivashov.Values.Count - 1]; // определяем текущую фазу рынка MarketFaze currentMarketFaze = GetMarketFaze(); // если кто-то подписан на событие изменения фазы рынка, то выдаем ему текущую фазу рынка if (MarketFazeChangeEvent != null) { MarketFazeChangeEvent(currentMarketFaze); } // если фазы рынка не определилась, то ничего не делаем if (currentMarketFaze == MarketFaze.Nothing) { return; } // проверяем, что робот включен if (IsOn == false) { return; } // в зависимости от фазы рынка пробуем войти в позицию if (currentMarketFaze == MarketFaze.Upper) { TryOpenLongPositions(); TryCloseShortPositions(); } else if (currentMarketFaze == MarketFaze.Lower) { TryOpenShortPositions(); TryCloseLongPositions(); } else if (currentMarketFaze == MarketFaze.Up || currentMarketFaze == MarketFaze.Low) { CheckClosingPositions(); } CheckDistanceToOrder(); }
private void TradeLogic(List <Candle> candlesIndex, List <Candle> candlesTab) { // проверка, что робот включен делается позже, // для возможности вывода текущей фазы рынка в окно настроечных параметров // проверка на достаточность свечей if (candlesIndex.Count < _ma.Lenght + 10 || candlesIndex.Count < _bollinger.Lenght + 10 || candlesIndex.Count < _atr.Lenght + 10) { return; } // получаем последние значения инструментов и индикаторов _lastIndex = candlesIndex[candlesIndex.Count - 1].Close; _lastPrice = candlesTab[candlesTab.Count - 1].Close; _lastMa = _ma.Values[_ma.Values.Count - 1]; _lastUpBollinger = _bollinger.ValuesUp[_bollinger.ValuesUp.Count - 1]; _lastDownBollinger = _bollinger.ValuesDown[_bollinger.ValuesDown.Count - 1]; _lastAtr = _atr.Values[_atr.Values.Count - 1]; //Проверка на допустимый диапазон значений цен инструментов if (_lastPrice <= 0 || _lastIndex <= 0) { _tabSec.SetNewLogMessage("TradeLigic: цена или индекс меньше или равны нулю.", LogMessageType.Error); return; } // получаем последние значения канала индекса (спреда) GetLastChannel(); // получаем текущую фазу рынка MarketFaze currentMarketFaze = GetMarketFaze(); // если кто-то подписан на событие изменения фазы рынка, // то передаем ему текущую фазу рынка if (MarketFazeChangeEvent != null) { MarketFazeChangeEvent(currentMarketFaze); } // проверяем, что робот включен if (IsOn == false) { return; } // проверка условий закрытия позиций CheckClosingPositions(currentMarketFaze); // в зависимости от фазы рынка проверка условий открытия позиций if (currentMarketFaze == MarketFaze.Upper) { TryOpenLong(); } else if (currentMarketFaze == MarketFaze.Lower) { TryOpenShort(); } }