public Trade CreateOrder(string broker, decimal entryOrder, Candle latestCandle, TradeDirection direction, decimal amount, string market, string baseAsset, DateTime?orderExpireTime, decimal?stop, decimal?limit, CalculateOptions calculateOptions = CalculateOptions.Default) { var orderDateTime = latestCandle.CloseTime(); var trade = new Trade { CalculateOptions = calculateOptions }; trade.SetOrder(orderDateTime, entryOrder, market, direction, amount, orderExpireTime); if (stop != null) { trade.AddStopPrice(orderDateTime, stop.Value); } if (limit != null) { trade.AddLimitPrice(orderDateTime, limit.Value); } trade.Broker = broker; trade.BaseAsset = baseAsset; if (direction == TradeDirection.Long) { trade.OrderType = (float)entryOrder <= latestCandle.CloseAsk ? OrderType.LimitEntry : OrderType.StopEntry; } else { trade.OrderType = (float)entryOrder <= latestCandle.CloseBid ? OrderType.StopEntry : OrderType.LimitEntry; } return(trade); }
public static void SetTradeEntryPrice(this Trade trade, Candle lastCandle, double price) { if (trade.CloseDateTime != null) { MessageBox.Show("Trade is now closed"); return; } if (trade.EntryPrice != null) { MessageBox.Show("Trade is now open so cannot set trade order price"); return; } trade.AddOrderPrice(lastCandle.CloseTime(), (decimal)price); if (trade.TradeDirection == TradeDirection.Long) { trade.OrderType = price < lastCandle.CloseAsk ? OrderType.LimitEntry : OrderType.StopEntry; } else { trade.OrderType = price < lastCandle.CloseBid ? OrderType.StopEntry : OrderType.LimitEntry; } }
private Candle?CreateCandle(IBinanceKline kline, string market, Timeframe timefame) { var c = new Candle { CloseTimeTicks = kline.CloseTime.Ticks, IsComplete = kline.CloseTime <= DateTime.UtcNow ? (byte)1 : (byte)0, CloseBid = (float)kline.CommonClose, HighBid = (float)kline.CommonHigh, LowBid = (float)kline.CommonLow, OpenTimeTicks = kline.OpenTime.Ticks, OpenBid = (float)kline.CommonOpen, Volume = (float)kline.CommonVolume, CloseAsk = (float)kline.CommonClose, HighAsk = (float)kline.CommonHigh, LowAsk = (float)kline.CommonLow, OpenAsk = (float)kline.CommonOpen }; var interval = (c.CloseTime() - c.OpenTime()).TotalSeconds; if ((int)timefame != Math.Round(interval)) { // throw new ApplicationException("Candle timeframe wrong"); // Some candles are wrong length (Seen some in 2018 date ranges) } if (c.OpenTimeTicks > c.CloseTimeTicks) { //throw new ApplicationException("Candle open time is later the close time"); Log.Warn($"Binance candle ignored {market} {c} {timefame}"); return(null); } return(c); }
public static void TrailIndicatorValues(Trade trade, Candle candle, IndicatorValues indicatorValues) { if (trade.EntryDateTime == null || trade.EntryPrice == null || !indicatorValues.HasValue || trade.InitialStop == null) { return; } // Get current var currentIndicatorValue = (decimal)indicatorValues.Value; // Get value at the time of the trade var index = indicatorValues.Values.BinarySearchGetItem(i => indicatorValues.Values[i].TimeTicks, 0, trade.EntryDateTime.Value.Ticks, BinarySearchMethod.PrevLowerValueOrValue); if (index == -1) { return; } var initialIndicator = indicatorValues[index]; if (initialIndicator == null) { return; } var initialIndicatorValue = initialIndicator.Value; var stopDist = Math.Abs((decimal)initialIndicatorValue - trade.InitialStop.Value); var newStop = trade.TradeDirection == TradeDirection.Long ? currentIndicatorValue - stopDist : currentIndicatorValue + stopDist; if (trade.StopPrice != newStop) { if (trade.TradeDirection == TradeDirection.Long && newStop > trade.StopPrice) { trade.AddStopPrice(candle.CloseTime(), newStop); } else if (trade.TradeDirection == TradeDirection.Short && newStop < trade.StopPrice) { trade.AddStopPrice(candle.CloseTime(), newStop); } } }
public static void ClearLimit(this Trade trade, Candle lastCandle) { if (trade.CloseDateTime != null) { MessageBox.Show("Trade is now closed"); return; } if (trade.EntryPrice != null) { MessageBox.Show("Trade is now open so cannot clear limit"); return; } if (trade.LimitPrices.Count > 0) { trade.AddLimitPrice(lastCandle.CloseTime(), null); } }
public static void ClearStop(this Trade trade, Candle lastCandle) { if (trade.CloseDateTime != null) { MessageBox.Show("Trade is now closed"); return; } if (trade.EntryPrice != null) { MessageBox.Show("Trade is now open so cannot clear stop"); return; } if (trade.StopPrices.Count > 0) { var date = lastCandle.CloseTime(); trade.AddStopPrice(date, null); } }
public static void SetTradeLimit(this Trade trade, Candle lastCandle, double price) { if (trade.CloseDateTime != null) { MessageBox.Show("Trade is now closed"); return; } if (trade.TradeDirection == TradeDirection.Long && ((trade.OrderPrice == null && price < lastCandle.CloseBid) || (trade.OrderPrice != null && trade.EntryPrice == null && (decimal)price < trade.OrderPrice.Value))) { MessageBox.Show("Invalid limit", "Invalid value", MessageBoxButton.OK); return; } if (trade.TradeDirection == TradeDirection.Short && ((trade.OrderPrice == null && price > lastCandle.CloseAsk) || (trade.OrderPrice != null && trade.EntryPrice == null && (decimal)price > trade.OrderPrice.Value))) { MessageBox.Show("Invalid limit", "Invalid value", MessageBoxButton.OK); return; } var date = lastCandle.CloseTime(); if (trade.EntryDateTime != null) { foreach (var limit in trade.LimitPrices.ToList()) { if (limit.Date == date) { trade.RemoveLimitPrice(trade.LimitPrices.IndexOf(limit)); } } trade.AddLimitPrice(date, (decimal)price); } else { trade.ClearLimitPrices(); trade.AddLimitPrice(date, (decimal)price); } }
public static void SetTradeStop(this Trade trade, Candle lastCandle, double price) { if (trade.CloseDateTime != null) { MessageBox.Show("Trade is now closed"); return; } if (trade.TradeDirection == TradeDirection.Long && ((trade.OrderPrice == null && price > lastCandle.CloseBid) || (trade.OrderPrice != null && trade.EntryPrice == null && (decimal)price > trade.OrderPrice.Value))) { MessageBox.Show("Invalid stop", "Invalid value", MessageBoxButton.OK); return; } if (trade.TradeDirection == TradeDirection.Short && ((trade.OrderPrice == null && price < lastCandle.CloseAsk) || (trade.OrderPrice != null && trade.EntryPrice == null && (decimal)price < trade.OrderPrice.Value))) { MessageBox.Show("Invalid stop", "Invalid value", MessageBoxButton.OK); return; } var date = lastCandle.CloseTime(); trade.AddStopPrice(date, (decimal)price); }