/// <summary> /// logic close position /// логика закрытия позиции /// </summary> private void LogicClosePosition(List <Candle> candles, Position openPosition) { if (openPosition.Direction == Side.Buy) { if (_lastPriceC > _pivotR3) { _tab.CloseAtLimit(openPosition, _lastPriceC - Slipage, openPosition.OpenVolume); } if (_lastPriceC < openPosition.EntryPrice - openPosition.EntryPrice / 100m * Stop) { _tab.CloseAtMarket(openPosition, openPosition.OpenVolume); } } if (openPosition.Direction == Side.Sell) { if (_lastPriceC < _pivotS3) { _tab.CloseAtLimit(openPosition, _lastPriceC + Slipage, openPosition.OpenVolume); } if (_lastPriceC > openPosition.EntryPrice + openPosition.EntryPrice / 100m * Stop) { _tab.CloseAtMarket(openPosition, openPosition.OpenVolume); } } }
private void LogicClosePosition(List <Position> positions, List <Candle> candles) { if (positions == null || positions.Count == 0) { return; } for (int i = 0; i < positions.Count; i++) { if (positions[i].State != PositionStateType.Open) { continue; } if (positions[i].State == PositionStateType.Closing) { continue; } if (ExitType.ValueString == "Sma") { if (positions[i].Direction == Side.Buy) { if (candles[candles.Count - 1].Close < _sma.DataSeries[0].Last) { _tab.CloseAtMarket(positions[i], positions[i].OpenVolume); } } else { if (candles[candles.Count - 1].Close > _sma.DataSeries[0].Last) { _tab.CloseAtMarket(positions[i], positions[i].OpenVolume); } } } else if (ExitType.ValueString == "Traling") { if (positions[i].Direction == Side.Buy) { _tab.CloseAtTrailingStop(positions[i], candles[candles.Count - 1].Close - candles[candles.Count - 1].Close * TralingStopLength.ValueDecimal / 100, candles[candles.Count - 1].Close - candles[candles.Count - 1].Close * TralingStopLength.ValueDecimal / 100); } else { _tab.CloseAtTrailingStop(positions[i], candles[candles.Count - 1].Close + candles[candles.Count - 1].Close * TralingStopLength.ValueDecimal / 100, candles[candles.Count - 1].Close + candles[candles.Count - 1].Close * TralingStopLength.ValueDecimal / 100); } } } }
private void _tabToTrade_CandleFinishedEvent(List <Candle> candles) { // покупаем если находимся под самым большим объёма на продажу за последние 10 свечек // продаём если находимся над самым большим объёма на покупку за последние 10 свечек if (Regime.ValueString == "Off") { return; } if (_tabCluster.VolumeClusters.Count <= BackLook.ValueInt) { return; } HorizontalVolumeCluster maxBuyCluster = _tabCluster.FindMaxVolumeCluster(candles.Count - BackLook.ValueInt, candles.Count, ClusterType.BuyVolume); if (candles[candles.Count - 1].Close > maxBuyCluster.MaxBuyVolumeLine.Price) { // продаём и выходим из позиции лонг List <Position> myPosShort = _tabToTrade.PositionOpenShort; if (myPosShort.Count == 0) { _tabToTrade.SellAtLimit(Volume.ValueDecimal, candles[candles.Count - 1].Close); } List <Position> myPosLong = _tabToTrade.PositionOpenLong; if (myPosLong.Count != 0 && myPosLong[0].State == PositionStateType.Open) { _tabToTrade.CloseAtMarket(myPosLong[0], myPosLong[0].OpenVolume); } } HorizontalVolumeCluster maxSellCluster = _tabCluster.FindMaxVolumeCluster(candles.Count - BackLook.ValueInt, candles.Count, ClusterType.SellVolume); if (candles[candles.Count - 1].Close < maxSellCluster.MaxSellVolumeLine.Price) { // покупаем и выходим из позиции шорт List <Position> myPosLong = _tabToTrade.PositionOpenLong; if (myPosLong.Count == 0) { _tabToTrade.BuyAtLimit(Volume.ValueDecimal, candles[candles.Count - 1].Close); } List <Position> myPosShort = _tabToTrade.PositionOpenShort; if (myPosShort.Count != 0 && myPosShort[0].State == PositionStateType.Open) { _tabToTrade.CloseAtMarket(myPosShort[0], myPosShort[0].OpenVolume); } } }
/// <summary> /// the position is not closed and warrants are withdrawn from it /// позиция не закрылась и у неё отозваны ордера /// </summary> void _tab_PositionClosingFailEvent(Position position) { if (position.CloseActiv) { return; } _tab.CloseAtMarket(position, position.OpenVolume); }
/// <summary> /// close position logic /// логика закрыти¤ позиции /// </summary> private void LogicClosePosition(List <Candle> candles, List <Position> position) { List <Position> openPositions = _tab2.PositionsOpenAll; for (int i = 0; openPositions != null && i < openPositions.Count; i++) { if (openPositions[i].Direction == Side.Buy) { if (_lastIndex < _lastMa) { if (Regime.ValueString == "OnlyClosePosition") { _tab2.CloseAtMarket(openPositions[i], openPositions[i].OpenVolume); } else { _tab2.CloseAtMarket(openPositions[i], openPositions[i].OpenVolume); if (openPositions.Count < 2) { _tab2.SellAtLimit(Volume.ValueDecimal, _lastPrice - _tab2.Securiti.PriceStep * Slippage.ValueInt); } } } } else { if (_lastIndex > _lastMa) { if (Regime.ValueString == "OnlyClosePosition") { _tab2.CloseAtMarket(openPositions[i], openPositions[i].OpenVolume); } else { _tab2.CloseAtMarket(openPositions[i], openPositions[i].OpenVolume); if (openPositions.Count < 2) { _tab2.BuyAtLimit(Volume.ValueDecimal, _lastPrice + _tab2.Securiti.PriceStep * Slippage.ValueInt); } } } } } }
/// <summary> /// Обработка события не удачного закрытия позиции /// </summary> /// <param name="position">позиция, которая не закрылась</param> private void Tab_PositionClosingFailEvent(Position position) { // если позиция еще не полностью закрылась и у неё остались ордера на закрытие, то закрываем их if (position.CloseActiv) { _tab.CloseAllOrderToPosition(position); _tab.SetNewLogMessage($"Tab_PositionClosingFailEvent: у позиции остались активные ордера. Закрываем их.", Logging.LogMessageType.User); System.Threading.Thread.Sleep(4000); } // не закрытую со второго раза позицию закрываем по маркету if (position.SignalTypeClose == "reclosing") { _tab.CloseAtMarket(position, position.OpenVolume); _tab.SetNewLogMessage($"Tab_PositionClosingFailEvent: закрытие позиции {position.Number}" + " по маркету: объем - {position.OpenVolume}.", Logging.LogMessageType.User); return; } // повторно пытаемся закрыть позицию по лимиту else { if (OnDebug.ValueBool) { _tab.SetNewLogMessage($"Отладка. Tab_PositionClosingFailEvent: повторная попытка закрыть позицию {position.Number}" + " по лимиту.", Logging.LogMessageType.User); } position.SignalTypeClose = "reclosing"; if (position.Direction == Side.Buy) { CloseLong(position); } else if (position.Direction == Side.Sell) { CloseShort(position); } } return; }
private void LogicClosePosition(List <Candle> candles, Position position) { if (position.State != PositionStateType.Open) { return; } System.DateTime timeExit = Convert.ToDateTime(position.SignalTypeOpen); if (timeExit < candles[candles.Count - 1].TimeStart) { _tab.CloseAtMarket(position, position.OpenVolume); } }
private void CloseAllPositions() { List <Position> positions1 = _tab1.PositionsOpenAll; List <Position> positions2 = _tab2.PositionsOpenAll; if (positions1.Count != 0 && positions1[0].State == PositionStateType.Open) { _tab1.CloseAtMarket(positions1[0], positions1[0].OpenVolume); } if (positions2.Count != 0 && positions2[0].State == PositionStateType.Open) { _tab2.CloseAtMarket(positions2[0], positions2[0].OpenVolume); } }
/// <summary> /// logic close position /// логика зыкрытия позиции /// </summary> private void LogicClosePosition(List <Candle> candles, Position position) { //if (position.Direction == Side.Buy) //{ // _tab.CloseAtTrailingStop(position, // _lastClose - _lastClose * TrailStop.ValueDecimal / 100, // _lastClose - _lastClose * TrailStop.ValueDecimal / 100); //} //if (position.Direction == Side.Sell) //{ // _tab.CloseAtTrailingStop(position, // _lastClose + _lastClose * TrailStop.ValueDecimal / 100, // _lastClose + _lastClose * TrailStop.ValueDecimal / 100); //} //decimal lastClose = candles[candles.Count - 1].Close; if (position.Direction == Side.Buy) { //if (_lastRsiD > 60 && _lastMacdUp > 0 && _lastRsiK <= _lastRsiD && _prevRsiD < _prevRsiK // if (_lastMacdUp > 0 && Regime.ValueString != "OnlyLong") // if (((_lastTrixHi < _prevTrixHi && _lastTrixHi > paramTrixHi.ValueDecimal) || (_lastTrixHi > paramTrixHi.ValueDecimal * 1.5m)) if (_TrixLow_max_pos == candles.Count && Regime.ValueString != "OnlyLong") { //_tab.CloseAtLimit(position, _lastClose - Slippage.ValueInt * _tab.Securiti.PriceStep, Volume.ValueDecimal); _tab.CloseAtMarket(position, Volume.ValueDecimal); } // if (lastClose < _lastMa || _lastRsi > Upline.Value) // { // _tab.CloseAtLimit(position, _lastPrice - Slipage, position.OpenVolume); // } } //if (position.Direction == Side.Sell) //{ // if (lastClose > _lastMa || _lastRsi < Downline.Value) // { // _tab.CloseAtLimit(position, _lastPrice + Slipage, position.OpenVolume); // } //} }
public void TryEmergencyClosePosition(BotTabSimple bot, Position position) { if (TypeDoubleExitOrder == OrderPriceType.Market) { bot.CloseAtMarket(position, position.OpenVolume); } else if (TypeDoubleExitOrder == OrderPriceType.Limit) { decimal price; if (position.Direction == Side.Buy) { price = bot.PriceBestBid - GetEmergencyExitDistance(bot, position); } else { price = bot.PriceBestAsk + GetEmergencyExitDistance(bot, position); } bot.CloseAtLimit(position, price, position.OpenVolume); } }
/// <summary> /// логика торговли /// </summary> /// <param name="candles"></param> private void LogicOpenPosition(List <Candle> candles) { if (_lines == null || _lines.Count == 0) { return; } // 1 выясняем каким объёмом и в какую сторону нам надо заходить decimal totalDeal = 0; decimal lastPrice = candles[candles.Count - 2].Close; decimal nowPrice = candles[candles.Count - 1].Close; for (int i = 0; i < _lines.Count; i++) { if (lastPrice < _lines[i] && nowPrice > _lines[i]) { // пробой снизу вверх totalDeal--; } if (lastPrice > _lines[i] && nowPrice < _lines[i]) { // пробой сверху вниз totalDeal++; } } if (totalDeal == 0) { return; } // 2 заходим в нужную сторону if (totalDeal > 0) { // нужно лонговать List <Position> positionsShort = _tab.PositionOpenShort; if (positionsShort != null && positionsShort.Count != 0) { if (positionsShort[0].OpenVolume <= totalDeal) { _tab.CloseAtMarket(positionsShort[0], positionsShort[0].OpenVolume); totalDeal -= positionsShort[0].OpenVolume; } else { _tab.CloseAtMarket(positionsShort[0], totalDeal); totalDeal = 0; } } if (totalDeal > 0 && totalDeal != 0) { List <Position> positionsLong = _tab.PositionOpenLong; if (positionsLong != null && positionsLong.Count != 0) { _tab.BuyAtMarketToPosition(positionsLong[0], totalDeal); } else { _tab.BuyAtMarket(totalDeal); } } } if (totalDeal < 0) { // нужно шортить totalDeal = Math.Abs(totalDeal); List <Position> positionsLong = _tab.PositionOpenLong; if (positionsLong != null && positionsLong.Count != 0) { if (positionsLong[0].OpenVolume <= totalDeal) { _tab.CloseAtMarket(positionsLong[0], positionsLong[0].OpenVolume); totalDeal -= positionsLong[0].OpenVolume; } else { _tab.CloseAtMarket(positionsLong[0], totalDeal); totalDeal = 0; } } if (totalDeal > 0) { List <Position> positionsShort = _tab.PositionOpenShort; if (positionsShort != null && positionsShort.Count != 0) { _tab.SellAtMarketToPosition(positionsShort[0], totalDeal); } else { _tab.SellAtMarket(totalDeal); } } } }
/// <summary> /// trade logic / /// логика торговли /// </summary> /// <param name="candles"></param> private void LogicOpenPosition(List <Candle> candles) { if (_lines == null || _lines.Count == 0) { return; } // 1 find out how much and in what direction we need to go // 1 выясняем каким объёмом и в какую сторону нам надо заходить decimal totalDeal = 0; decimal lastPrice = candles[candles.Count - 2].Close; decimal nowPrice = candles[candles.Count - 1].Close; for (int i = 0; i < _lines.Count; i++) { if (lastPrice < _lines[i] && nowPrice > _lines[i]) { totalDeal--; } if (lastPrice > _lines[i] && nowPrice < _lines[i]) { totalDeal++; } } if (totalDeal == 0) { return; } // 2 go in the right direction // 2 заходим в нужную сторону if (totalDeal > 0) { List <Position> positionsShort = _tab.PositionOpenShort; if (positionsShort != null && positionsShort.Count != 0) { if (positionsShort[0].OpenVolume <= totalDeal) { _tab.CloseAtMarket(positionsShort[0], positionsShort[0].OpenVolume); totalDeal -= positionsShort[0].OpenVolume; } else { _tab.CloseAtMarket(positionsShort[0], totalDeal); totalDeal = 0; } } if (totalDeal > 0 && totalDeal != 0) { List <Position> positionsLong = _tab.PositionOpenLong; if (positionsLong != null && positionsLong.Count != 0) { _tab.BuyAtMarketToPosition(positionsLong[0], totalDeal); } else { _tab.BuyAtMarket(totalDeal); } } } if (totalDeal < 0) { totalDeal = Math.Abs(totalDeal); List <Position> positionsLong = _tab.PositionOpenLong; if (positionsLong != null && positionsLong.Count != 0) { if (positionsLong[0].OpenVolume <= totalDeal) { _tab.CloseAtMarket(positionsLong[0], positionsLong[0].OpenVolume); totalDeal -= positionsLong[0].OpenVolume; } else { _tab.CloseAtMarket(positionsLong[0], totalDeal); totalDeal = 0; } } if (totalDeal > 0) { List <Position> positionsShort = _tab.PositionOpenShort; if (positionsShort != null && positionsShort.Count != 0) { _tab.SellAtMarketToPosition(positionsShort[0], totalDeal); } else { _tab.SellAtMarket(totalDeal); } } } }