Why is my cbot lagging a few candles than tradingview?
Created at 24 Jan 2025, 16:17
DU
Why is my cbot lagging a few candles than tradingview?
24 Jan 2025, 16:17
Hello,
I created a cBot (Full code below) based on an indicator on TradingView (Range Filter Buy and Sell 5min - @guikroth ver), but the signals on the cBot are delayed compared to those on TradingView. I have tried to figure it out but still can't understand the reason. Could anyone help me? Thank you!
Green lines are signal on TradingView, Yellow lines are signal on Cbot


using System;
using cAlgo.API;
using cAlgo.API.Indicators;
namespace cAlgo.Robots
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class RangeFilterProBot : Robot
{
[Parameter("Sampling Period", DefaultValue = 50, MinValue = 10)]
public int Period { get; set; }
[Parameter("Range Multiplier", DefaultValue = 3.0, MinValue = 0.5)]
public double Multiplier { get; set; }
[Parameter("Volume (Lots)", DefaultValue = 0.1, MinValue = 0.01)]
public double Volume { get; set; }
[Parameter("Stop Loss (pips)", DefaultValue = 300)]
public int StopLossInPips { get; set; }
[Parameter("Take Profit (pips)", DefaultValue = 600)]
public int TakeProfitInPips { get; set; }
private IndicatorDataSeries _absPriceDiff;
private ExponentialMovingAverage _ema1, _ema2;
private double _prevFilter;
private int _upward, _downward, _lastSignal;
protected override void OnStart()
{
_absPriceDiff = CreateDataSeries();
_ema1 = Indicators.ExponentialMovingAverage(_absPriceDiff, Period);
_ema2 = Indicators.ExponentialMovingAverage(_ema1.Result, Period * 2 - 1);
InitializeHistoricalData();
Print("Bot is ready!");
}
// Initialize historical data for all closed candles
private void InitializeHistoricalData()
{
for (int i = 1; i < Bars.Count; i++)
{
_absPriceDiff[i] = Math.Abs(Bars.ClosePrices[i] - Bars.ClosePrices[i - 1]);
}
_prevFilter = Bars.ClosePrices.Last(1); // Use previous candle's closing price
}
protected override void OnBar()
{
try
{
int currentIndex = Bars.Count - 1;
int lastClosedIndex = currentIndex - 1; // Index of the LAST CLOSED candle
// Skip if insufficient data for EMA stability
if (lastClosedIndex < Period * 2)
{
Print($"Initializing... ({lastClosedIndex}/{Period * 2})");
return;
}
// 1. Update price volatility for the CLOSED candle
_absPriceDiff[lastClosedIndex] = Math.Abs(
Bars.ClosePrices[lastClosedIndex] -
Bars.ClosePrices[lastClosedIndex - 1]
);
// 2. Calculate Smoothed Range from CLOSED candle data
double smrng = _ema2.Result[lastClosedIndex] * Multiplier;
// 3. Update the filter
double price = Bars.ClosePrices[lastClosedIndex];
double newFilter = price > _prevFilter
? Math.Max(_prevFilter, price - smrng)
: Math.Min(_prevFilter, price + smrng);
// 4. Determine trend direction
_upward = newFilter > _prevFilter ? _upward + 1 : 0;
_downward = newFilter < _prevFilter ? _downward + 1 : 0;
// 5. Trading conditions (processed immediately after candle closes)
bool shouldBuy = price > newFilter && _upward >= 1;
bool shouldSell = price < newFilter && _downward >= 1;
// 6. Execute trades immediately
ExecuteTrades(shouldBuy, shouldSell, price, newFilter, lastClosedIndex);
_prevFilter = newFilter;
}
catch (Exception ex)
{
Print($"Error: {ex.Message}");
}
}
private void ExecuteTrades(bool buy, bool sell, double price, double filter, int barIndex)
{
if (buy && _lastSignal != 1)
{
ClosePositions(TradeType.Sell);
OpenTrade(TradeType.Buy, price, filter, barIndex);
_lastSignal = 1;
}
else if (sell && _lastSignal != -1)
{
ClosePositions(TradeType.Buy);
OpenTrade(TradeType.Sell, price, filter, barIndex);
_lastSignal = -1;
}
}
private void OpenTrade(TradeType type, double price, double filter, int barIndex)
{
ExecuteMarketOrder(
type,
SymbolName,
Symbol.QuantityToVolumeInUnits(Volume),
$"RF_{type}",
StopLossInPips,
TakeProfitInPips
);
// Log the exact timestamp of the signal candle
Print($"{(type == TradeType.Buy ? "▲ BUY" : "▼ SELL")} @ {price:F5} | Filter: {filter:F5} | Time: {Bars.OpenTimes[barIndex]}");
}
private void ClosePositions(TradeType typeToClose)
{
foreach (var pos in Positions.FindAll($"RF_{typeToClose}", SymbolName))
ClosePosition(pos);
}
protected override void OnStop()
{
Print("Bot has stopped.");
}
}
}