Code: Select all
using System;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
namespace cAlgo
{
[Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class LiquiditySweepRisk : Indicator
{
[Parameter("ATR & SMA Lookback", DefaultValue = 20)]
public int Lookback { get; set; }
[Parameter("Slippage Risk Multiplier", DefaultValue = 1.5)]
public double SlipMultiplier { get; set; }
[Parameter("Enable Terminal Print Alerts", DefaultValue = true)]
public bool EnableAlerts { get; set; }
[Output("Upper Risk Band", LineColor = "Gray", PlotType = PlotType.Line, Thickness = 1)]
public IndicatorDataSeries UpperBand { get; set; }
[Output("Lower Risk Band", LineColor = "Gray", PlotType = PlotType.Line, Thickness = 1)]
public IndicatorDataSeries LowerBand { get; set; }
[Output("Bull Sweep Risk", LineColor = "Red", PlotType = PlotType.Points, Thickness = 4)]
public IndicatorDataSeries BullSweep { get; set; }
[Output("Bear Sweep Risk", LineColor = "Red", PlotType = PlotType.Points, Thickness = 4)]
public IndicatorDataSeries BearSweep { get; set; }
private AverageTrueRange _atr;
private SimpleMovingAverage _sma;
private DateTime _lastAlertTime;
protected override void Initialize()
{
_atr = Indicators.AverageTrueRange(Lookback, MovingAverageType.Simple);
_sma = Indicators.SimpleMovingAverage(Bars.ClosePrices, Lookback);
}
public override void Calculate(int index)
{
if (index < Lookback)
return;
double atrValue = _atr.Result[index];
double smaValue = _sma.Result[index];
// Map stable execution zones
UpperBand[index] = smaValue + (atrValue * SlipMultiplier);
LowerBand[index] = smaValue - (atrValue * SlipMultiplier);
double lowestLow = double.MaxValue;
double highestHigh = double.MinValue;
// Define the structural boundaries
for (int i = 1; i <= Lookback; i++)
{
if (Bars.LowPrices[index - i] < lowestLow)
lowestLow = Bars.LowPrices[index - i];
if (Bars.HighPrices[index - i] > highestHigh)
highestHigh = Bars.HighPrices[index - i];
}
// Identify structural sweeps (Liquidity vacuums)
bool bullSweep = Bars.LowPrices[index] < lowestLow && Bars.ClosePrices[index] > Bars.OpenPrices[index];
bool bearSweep = Bars.HighPrices[index] > highestHigh && Bars.ClosePrices[index] < Bars.OpenPrices[index];
if (bullSweep)
BullSweep[index] = Bars.LowPrices[index] - (atrValue * 0.5);
if (bearSweep)
BearSweep[index] = Bars.HighPrices[index] + (atrValue * 0.5);
// Log high-risk environments directly to the cTrader journal
if (IsLastBar && EnableAlerts && (bullSweep || bearSweep) && Bars.OpenTimes[index] != _lastAlertTime)
{
Print("Liquidity Sweep Detected on {0} - LP withdrawal imminent. High slippage risk.", SymbolName);
_lastAlertTime = Bars.OpenTimes[index];
}
}
}
}