top of page

Free indicators

Public·5 members

Collude Pro


# ─────────────────────────────────────────────

# │ MarketFragments.com | DNA & Market │

# │ info@marketfragments.com │

# │ www.marketfragments.com │

# ──────────────────────────────────────────────

# Time →

# │

# █ █ █│ █

# █ █ █ │ █ █

# █ █ █ │ █ █ █ ╭─╮

# █ █ █ │ █ █ █ █ ╭─╯ ╰─╮

# █ █ █ │ █ █ █ █ █ █ ╭─╯ ╰─╮

# █ █ █ │ █ █ █ █ █ █ █ █ ╭─╯ ╰─╮

# █ █ █ │ █ █ █ █ █ █ █ █ █ █╭─╯ ╰─╮

# █ █ █ │ █ █ █ █ █ █ █ █ ╰─╮ ╭─╯

# █ █ █ │ █ █ █ █ █ █ ╰─╮ ╭─╯

# █ █ █ │ █ █ █ █ ╰─╮ ╭─╯

# █ █ █ │ █ █ ╰─╮ ╭─╯

# █ █ █ │ █ ╰─────╯

# ──────┴──────────────────────────────────────────────────────────────

# T1 T2 T3 T4 T5 T6

#

# Name: ColludeScan Pro

# Author: Market Fragments team



# Enhanced DBSCAN Logic for Detecting Collusive Trader Groups and HFT

# Improvements for Robustness:

# - Corrected the neighbor counting logic in DBSCAN to use proper Euclidean distance (squared to avoid sqrt) across multiple features.

# - Incorporated a third feature (price percent change) into the clustering for better multi-dimensional analysis, making detection less prone to noise in individual features.

# - Unified the anomaly score into a single, coherent metric based on proper neighbor counts, removing the flawed separate scores.

# - Adjusted collusion detection to use >= minPoints for consistency with standard DBSCAN core point definitions (includes self).

# - Added safeguards for division by zero in percent change calculations to prevent NaN or infinite values.

# - Utilized the unused trendLength to compute a moving average of the anomaly score, and integrated MoveThreshold to flag significant changes in the DBSCAN trend as an additional collusion signal.

# - Kept computational complexity in check but noted that large 'length' values may slow performance; consider reducing if needed.

# - No normalization applied to keep it simple and compatible with ThinkScript limitations, but distanceThreshold may need tuning based on asset volatility (e.g., increase for high-vol assets).

# - HFT detection remains similar but added a volume check for robustness against false positives in low-liquidity periods.


declare upper;


input distanceThreshold = 5.0; # Increased default for percentage-based features; tune based on backtesting

input minPoints = 7; # Minimum points for a core point/cluster detection

input length = 200; # Reduced look-back for efficiency; adjust as needed

input lengthPchange = 1; # Percent change calculation length

input MoveThreshold = 400; # Threshold for significant DBSCAN trend change (absolute)

input trendLength = 50; # Moving average period for DBSCAN score trend

input volumeThreshold = 1000; # Volume threshold for significant activity

input priceChangeThreshold = 0.1; # Price change threshold (in %) for significant moves

input hftThreshold = 500; # Tick count threshold for high-frequency trading

input hftPeriod = 5; # Look-back period for HFT detection


# Core definitions

def c = close;

def v = volume;

def tickcnt = tick_count;


# Safe percent change calculations (handle zero division)

def Data1 = if tickcnt[lengthPchange] != 0 then 100 * (tickcnt / tickcnt[lengthPchange] - 1) else 0;

def Data2 = if v[lengthPchange] != 0 then 100 * (v / v[lengthPchange] - 1) else 0;

def Data3 = if c[lengthPchange] != 0 then 100 * (c / c[lengthPchange] - 1) else 0;


# Calculate neighbors using proper Euclidean distance squared (for 3 features)

def distSqThreshold = Sqr(distanceThreshold);

def neighbors = fold i = 0 to length - 1 with count = 0 do

if Sqr(Data1 - GetValue(Data1, i)) +

Sqr(Data2 - GetValue(Data2, i)) +

Sqr(Data3 - GetValue(Data3, i)) <= distSqThreshold

then count + 1

else count;


# DBSCAN anomaly score (number of neighbors, including self)

def anomalyScore = neighbors;


# Trend analysis on anomaly score for robustness

def dbscanTrend = Average(anomalyScore, trendLength);

def significantTrendChange = AbsValue(dbscanTrend - dbscanTrend[1]) > MoveThreshold;


# Collusive Trader Groups Detection (high density + significant activity + trend change)

def priceChange = if c[1] != 0 then 100 * (c- c[1]) / c[1] else 0;

def significantVolume = v> volumeThreshold;

def significantPriceChange = AbsValue(priceChange) > priceChangeThreshold;

def collusionDetected = (anomalyScore >= minPoints) and significantVolume and significantPriceChange and significantTrendChange;


# Plot potential collusive activity

plot CollusiveActivity = if collusionDetected then high+5 else Double.NaN;

CollusiveActivity.SetPaintingStrategy(PaintingStrategy.POINTS);

CollusiveActivity.SetDefaultColor(Color.ORANGE);

CollusiveActivity.SetLineWeight(5);


# High-Frequency Trading Analysis (added volume check for robustness)

def highTickCount = tickcnt > hftThreshold and v > volumeThreshold / 2; # Avoid HFT flags in low-volume bars

def hftDetected = Sum(highTickCount, hftPeriod) >= hftPeriod * 0.8; # Allow some flexibility (80% of period)


# Plot high-frequency trading activity

plot HighFrequencyTrading = if hftDetected then low else Double.NaN;

HighFrequencyTrading.SetPaintingStrategy(PaintingStrategy.POINTS);

HighFrequencyTrading.SetDefaultColor(Color.MAGENTA);

HighFrequencyTrading.SetLineWeight(3);


plot CalmTrading = if !hftDetected then low else Double.NaN;

CalmTrading.SetPaintingStrategy(PaintingStrategy.POINTS);

CalmTrading.SetDefaultColor(Color.black);

CalmTrading.SetLineWeight(3);




# second version




# ─────────────────────────────────────────────

# │ MarketFragments.com | DNA & Market │

# │ info@marketfragments.com │

# │ www.marketfragments.com │

# ──────────────────────────────────────────────

# Time →

# │

# █ █ █│ █

# █ █ █ │ █ █

# █ █ █ │ █ █ █ ╭─╮

# █ █ █ │ █ █ █ █ ╭─╯ ╰─╮

# █ █ █ │ █ █ █ █ █ █ ╭─╯ ╰─╮

# █ █ █ │ █ █ █ █ █ █ █ █ ╭─╯ ╰─╮

# █ █ █ │ █ █ █ █ █ █ █ █ █ █╭─╯ ╰─╮

# █ █ █ │ █ █ █ █ █ █ █ █ ╰─╮ ╭─╯

# █ █ █ │ █ █ █ █ █ █ ╰─╮ ╭─╯

# █ █ █ │ █ █ █ █ ╰─╮ ╭─╯

# █ █ █ │ █ █ ╰─╮ ╭─╯

# █ █ █ │ █ ╰─────╯

# ──────┴──────────────────────────────────────────────────────────────

# T1 T2 T3 T4 T5 T6

#

# Name: ColludeScan Pro

# Author: Market Fragments team


# Enhanced DBSCAN Logic for Detecting Collusive Trader Groups and HFT

# Key Improvements (Oct 2025): Fixed lambda with script; reinforced NaN guards; tuned HFT avg; min cnt for layer signal.

# Robustness: Multi-feature Euclidean dist, trend smoothing, safeguards. Tune for asset (e.g., higher distThreshold for crypto).


declare upper;


# Core Inputs

input distanceThreshold = 5.0; # Euclidean threshold for % features; tune via backtest (higher for vol assets)

input minPoints = 7; # Min neighbors for core point/cluster

input length =50; # Overall lookback; kept for historical max but not for folds

input neighborLookback = 50; # Reduced fold lookback for perf (vs. full length)

input includeSelf = yes; # Include current bar in neighbor count (DBSCAN standard)

input lengthPchange = 1; # % change lookback

input MoveThreshold = 10.0; # Trend change threshold (realistic: ~5-20% of max anomaly)

input trendLength = 50; # Smoothing period for anomaly trend

input volumeThreshold = 1000; # Min volume for signals

input priceChangeThreshold = 0.1; # % price move threshold

input hftThreshold = 100; # Tick threshold for HFT (tuned lower for intraday)

input hftPeriod = 5; # HFT burst lookback

input normalize = yes; # Simple z-score normalize features? (reduces scale bias)

input densityVelocity = yes; # Require rising anomaly for collusion (emerging density)?

input layerSignal = yes; # Enable second-layer signal?

input quietVolumeMult = 0.5; # Volume multiplier below threshold for "calm" plots


# Core data

def c = close;

def v = volume;

def tickcnt = tick_count();


# Safe Division Script (TOS-compliant sub-routine)

script safeDiv {

input value = 0;

plot result = if value != 0 then value else 1;

}


# Safe % changes using script

def Data1_raw = 100 * (tickcnt / safeDiv(value = tickcnt[lengthPchange]) - 1);

def Data2_raw = 100 * (v / safeDiv(value = v[lengthPchange]) - 1);

def Data3_raw = 100 * (c / safeDiv(value = c[lengthPchange]) - 1);


# Optional simple normalization (z-score over short window for perf; guarded for zero std)

def normLen = 20;

def mean1 = Average(Data1_raw, normLen);

def std1 = StDev(Data1_raw, normLen);

def Data1 = if normalize and std1 > 0 then (Data1_raw - mean1) / std1 else Data1_raw;

def mean2 = Average(Data2_raw, normLen);

def std2 = StDev(Data2_raw, normLen);

def Data2 = if normalize and std2 > 0 then (Data2_raw - mean2) / std2 else Data2_raw;

def mean3 = Average(Data3_raw, normLen);

def std3 = StDev(Data3_raw, normLen);

def Data3 = if normalize and std3 > 0 then (Data3_raw - mean3) / std3 else Data3_raw;


# Neighbors via Euclidean dist squared (optimized fold)

def distSqThreshold = Sqr(distanceThreshold);

def startFold = if includeSelf then 0 else 1;

def neighbors = fold i = startFold to neighborLookback - 1 with count = (if includeSelf then 1 else 0)

do count + (if Sqr(Data1 - GetValue(Data1, i)) + Sqr(Data2 - GetValue(Data2, i)) + Sqr(Data3 - GetValue(Data3, i)) <= distSqThreshold then 1 else 0);


# Anomaly score (neighbor density)

def anomalyScore = neighbors;


# Trend smoothing & change detection

def dbscanTrend = Average(anomalyScore, trendLength);

def significantTrendChange = AbsValue(dbscanTrend - dbscanTrend[1]) > MoveThreshold;


def secondLayerSignal;


# Collusion: High density + activity + trend + optional velocity

def priceChange = if c[1] != 0 then 100 * (c - c[1]) / c[1] else 0;

def significantVolume = v > volumeThreshold;

def significantPriceChange = AbsValue(priceChange) > priceChangeThreshold;

def risingDensity = !densityVelocity or (anomalyScore > anomalyScore[1]);

def baseCollusion = (anomalyScore >= minPoints) and significantVolume and significantPriceChange and significantTrendChange and risingDensity;

def collusionDetected = baseCollusion or (layerSignal and secondLayerSignal == 100); # Boost with new layer


# HFT: Burst detection with volume gate & rate (using Average for TOS optimization)

def highTickCount = tickcnt > hftThreshold and v > volumeThreshold * 0.5;

def hftBurstRate = Average(highTickCount, hftPeriod);

def hftDetected = hftBurstRate >= 0.8;


# Calm periods: Sparse plot only in truly quiet zones

def quietVolume = v < volumeThreshold * quietVolumeMult;

def calmDetected = !hftDetected and quietVolume;


# Completed New Layer: Daily HFT-period anomaly average vs. historical highs (min cnt for reliability)

def nday = GetDay() != GetDay()[1];

def isAnchor = nday and !nday[1];

def startDay = isAnchor;

def cnt = CompoundValue(1, if startDay then 0 else if hftDetected and cnt[1] == 0 then 1 else if hftDetected then cnt[1] + 1 else cnt[1], 0);

def SumAnom = CompoundValue(1, if startDay then 0 else if hftDetected and cnt[1] == 0 then anomalyScore else if hftDetected then SumAnom[1] + anomalyScore else SumAnom[1], 0);

def anomAverage = if cnt > 0 then SumAnom / cnt else 0;

def shortTermAnom = Average(anomalyScore, 3);

def histMaxAnom = Highest(anomAverage, length); # Global historical max during HFT periods

secondLayerSignal = if hftDetected and cnt >= 3 and shortTermAnom > anomAverage * 1.2 and shortTermAnom > histMaxAnom then 100 else 0; # 20% above daily avg + beats history + min samples


# Plots

plot CollusiveActivity = if collusionDetected then high + (high * 0.01) else Double.NaN; # Slight offset for visibility

CollusiveActivity.SetPaintingStrategy(PaintingStrategy.POINTS);

CollusiveActivity.SetDefaultColor(Color.ORANGE);

CollusiveActivity.SetLineWeight(5);

Alert(collusionDetected, "Collusive Activity Detected", Alert.BAR, Sound.Ding);


plot HighFrequencyTrading = if hftDetected then low - (low * 0.01) else Double.NaN;

HighFrequencyTrading.SetPaintingStrategy(PaintingStrategy.POINTS);

HighFrequencyTrading.SetDefaultColor(Color.MAGENTA);

HighFrequencyTrading.SetLineWeight(3);

Alert(hftDetected, "HFT Burst Detected", Alert.BAR, Sound.Bell);


plot CalmTrading = if calmDetected then low else Double.NaN; # Now sparse

CalmTrading.SetPaintingStrategy(PaintingStrategy.POINTS);

CalmTrading.SetDefaultColor(Color.GRAY);

CalmTrading.SetLineWeight(1);


# Second-layer bubble (enhanced)

AddChartBubble(layerSignal and secondLayerSignal == 100, close,

"Escalating Collusion: " + Round((shortTermAnom / histMaxAnom - 1) * 100, 1) + "% > Hist Max",

Color.GREEN, yes);


# Info Label: Current metrics for scanning (added % over hist)

AddLabel(yes, "Anomaly: " + Round(anomalyScore, 0) + " | Trend: " + Round(dbscanTrend, 1) + " | HFT Rate: " + Round(hftBurstRate * 100, 0) + "%" +

(if secondLayerSignal == 100 then " | Layer Sig: +" + Round((shortTermAnom / histMaxAnom - 1) * 100, 0) + "%" else ""),

if collusionDetected then Color.ORANGE else if hftDetected then Color.MAGENTA else Color.GRAY);

59 Views
Brain with financial data analysis.

Inquiries at :

tel#: (843) 321-8514

Important Risk Notice: Trading involves substantial risk of loss. This is educational content only—not advice. Full details here  ------------>  

Proceed only if you're prepared.

bottom of page