/// <inheritdoc /> protected override RangeCandleMessage CreateCandle(MarketDataMessage message, RangeCandleMessage currentCandle, ICandleBuilderValueTransform transform) { var time = transform.Time; return(FirstInitCandle(message, new RangeCandleMessage { PriceRange = message.GetArg <Unit>(), OpenTime = time, CloseTime = time, HighTime = time, LowTime = time, }, transform)); }
/// <inheritdoc /> protected override TickCandleMessage CreateCandle(MarketDataMessage message, TickCandleMessage currentCandle, ICandleBuilderValueTransform transform) { var time = transform.Time; return(FirstInitCandle(message, new TickCandleMessage { MaxTradeCount = message.GetArg <int>(), OpenTime = time, CloseTime = time, HighTime = time, LowTime = time, }, transform)); }
/// <inheritdoc /> public override void Process(MarketDataMessage message, CandleMessage currentCandle, ICandleBuilderValueTransform transform, IList <CandleMessage> changes) { var currentRenkoCandle = (RenkoCandleMessage)currentCandle; var price = transform.Price; var volume = transform.Volume; var time = transform.Time; var side = transform.Side; var oi = transform.OpenInterest; var boxSize = message.GetArg <Unit>(); var renkoStep = (decimal)(1 * boxSize); if (currentRenkoCandle == null) { var openPrice = price.Floor(renkoStep); changes.Add(CreateCandle(message, boxSize, openPrice, renkoStep, price, volume, side, time, oi)); } else { if (currentRenkoCandle.LowPrice <= price && price <= currentRenkoCandle.HighPrice) { currentRenkoCandle.TotalTicks++; if (volume != null) { currentRenkoCandle.TotalVolume += volume.Value; currentRenkoCandle.TotalPrice += volume.Value * price; currentRenkoCandle.RelativeVolume += side == Sides.Buy ? volume : -volume; } currentRenkoCandle.CloseVolume = volume; currentRenkoCandle.CloseTime = time; currentRenkoCandle.VolumeProfile?.Update(price, volume, side); currentRenkoCandle.OpenInterest = oi; changes.Add(currentRenkoCandle); } else { currentRenkoCandle.State = CandleStates.Finished; changes.Add(currentRenkoCandle); int times; bool isUp; decimal openPrice; if (price < currentRenkoCandle.LowPrice) { times = (int)((currentRenkoCandle.LowPrice - price) / renkoStep) + 1; isUp = false; openPrice = currentRenkoCandle.LowPrice; } else { times = (int)((price - currentRenkoCandle.HighPrice) / renkoStep) + 1; isUp = true; openPrice = currentRenkoCandle.HighPrice; } for (var i = 0; i < times; i++) { if (isUp) { currentRenkoCandle = CreateCandle(message, boxSize, openPrice, renkoStep, price, volume, side, time, oi); changes.Add(currentRenkoCandle); openPrice += renkoStep; } else { currentRenkoCandle = CreateCandle(message, boxSize, openPrice, -renkoStep, price, volume, side, time, oi); changes.Add(currentRenkoCandle); openPrice -= renkoStep; } currentRenkoCandle.State = CandleStates.Finished; } currentRenkoCandle.State = CandleStates.Active; } } }
/// <inheritdoc /> public override void Process(MarketDataMessage message, CandleMessage currentCandle, ICandleBuilderValueTransform transform, IList <CandleMessage> changes) { var currentPnFCandle = (PnFCandleMessage)currentCandle; var price = transform.Price; var volume = transform.Volume; var time = transform.Time; var side = transform.Side; var oi = transform.OpenInterest; var pnf = message.GetArg <PnFArg>(); var pnfStep = (decimal)(1 * pnf.BoxSize); if (currentPnFCandle == null) { var openPrice = price.Floor(pnfStep); var highPrice = openPrice + pnfStep; changes.Add(CreateCandle(message, pnf, openPrice, highPrice, openPrice, highPrice, price, volume, side, time, oi)); } else { if (currentPnFCandle.LowPrice <= price && price <= currentPnFCandle.HighPrice) { UpdateCandle(currentPnFCandle, price, volume, time, side, oi); changes.Add(currentPnFCandle); } else { var isX = currentPnFCandle.OpenPrice < currentPnFCandle.ClosePrice; if (isX) { if (price > currentPnFCandle.HighPrice) { currentPnFCandle.HighPrice = currentPnFCandle.ClosePrice = price.Floor(pnfStep) + pnfStep; UpdateCandle(currentPnFCandle, price, volume, time, side, oi); changes.Add(currentPnFCandle); } else if (price < (currentPnFCandle.HighPrice - pnfStep * pnf.ReversalAmount)) { currentPnFCandle.State = CandleStates.Finished; changes.Add(currentPnFCandle); var highPrice = currentPnFCandle.HighPrice - pnfStep; var lowPrice = price.Floor(pnfStep); currentPnFCandle = CreateCandle(message, pnf, highPrice, highPrice, lowPrice, lowPrice, price, volume, side, time, oi); changes.Add(currentPnFCandle); } else { UpdateCandle(currentPnFCandle, price, volume, time, side, oi); changes.Add(currentPnFCandle); } } else { if (price < currentPnFCandle.LowPrice) { currentPnFCandle.LowPrice = currentPnFCandle.ClosePrice = price.Floor(pnfStep); UpdateCandle(currentPnFCandle, price, volume, time, side, oi); changes.Add(currentPnFCandle); } else if (price > (currentPnFCandle.LowPrice + pnfStep * pnf.ReversalAmount)) { currentPnFCandle.State = CandleStates.Finished; changes.Add(currentPnFCandle); var highPrice = price.Floor(pnfStep) + pnfStep; var lowPrice = currentPnFCandle.LowPrice + pnfStep; currentPnFCandle = CreateCandle(message, pnf, lowPrice, highPrice, lowPrice, highPrice, price, volume, side, time, oi); changes.Add(currentPnFCandle); } else { UpdateCandle(currentPnFCandle, price, volume, time, side, oi); changes.Add(currentPnFCandle); } } } } }