Skip to content

Code doesn't compile #21

Description

@olivierace

Hi, i would like your help for compile my code please 👍

// =============================================
// INDICATEUR DEMAND & SUPPLY POUR QUANTOWER
// Optimisé pour le scalping sur NQ/ES (1min, 10min, 30min)
// Auteur : Adapté pour Boudigue
// =============================================

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using TradingPlatform.BusinessLayer;

namespace CustomIndicators
{
[DisplayName("Zones Demand & Supply (Scalping)")]
public class DemandSupplyZones : Indicator
{
// ========== PARAMÈTRES UTILISATEUR ==========
[InputParameter("Lookback Bars", 50)]
public int LookbackBars { get; set; }

    [InputParameter("Volume Multiplier", 2)]
    public double VolumeMultiplier { get; set; }

    [InputParameter("Zone Validity Bars", 200)]
    public int ZoneValidityBars { get; set; }

    [InputParameter("Use Trend Filter", 1)]
    public bool UseTrendFilter { get; set; }

    [InputParameter("EMA Fast Période", 9)]
    public int EmaFastPeriod { get; set; }

    [InputParameter("EMA Slow Période", 21)]
    public int EmaSlowPeriod { get; set; }

    // --- Paramètres d'affichage ---
    [InputParameter("Show Demand Zones", 1)]
    public bool ShowDemandZones { get; set; }

    [InputParameter("Show Supply Zones", 1)]
    public bool ShowSupplyZones { get; set; }

    [InputParameter("Demand Zone Color", (int)KnownColor.LimeGreen)]
    public Color DemandColor { get; set; }

    [InputParameter("Supply Zone Color", (int)KnownColor.OrangeRed)]
    public Color SupplyColor { get; set; }

    [InputParameter("Zone Opacity", 40)]
    public int ZoneOpacity { get; set; }

    [InputParameter("Show Zone Prices", 1)]
    public bool ShowZonePrices { get; set; }

    [InputParameter("Show Alerts", 1)]
    public bool ShowAlerts { get; set; }
    public object NotificationType { get; private set; }

    // ========== VARIABLES GLOBALES ==========
    private List<Zone> demandZones = new List<Zone>();
    private List<Zone> supplyZones = new List<Zone>();
    private Indicator emaFast;
    private Indicator emaSlow;
    private double avgVolume;

    // Classe pour stocker les zones
    private class Zone
    {
        public double High { get; set; }
        public double Low { get; set; }
        public int StartBar { get; set; }
        public int EndBar { get; set; }
        public bool IsActive { get; set; }

        public Zone(double high, double low, int startBar, int endBar)
        {
            High = high;
            Low = low;
            StartBar = startBar;
            EndBar = endBar;
            IsActive = true;
        }
    }

    // ========== INITIALISATION ==========
    //public override void OnInitialize()
    protected override void OnInit()
    {
        //emaFast = new EMA(EmaFastPeriod);
        //emaSlow = new EMA(EmaSlowPeriod);

        emaFast = Core.Instance.Indicators.BuiltIn.EMA(EmaFastPeriod, PriceType.Close);
        this.AddIndicator(emaFast);

        emaSlow = Core.Instance.Indicators.BuiltIn.EMA(EmaSlowPeriod, PriceType.Close);
        this.AddIndicator(emaSlow);
        demandZones.Clear();
        supplyZones.Clear();
    }

    // ========== CALCULS ==========
    public override void OnCalculate(int index, IBar bar)
    {
        // Calculer les EMA
        emaFast.Calculate(index, bar.Close);
        emaSlow.Calculate(index, bar.Close);

        // Détecter les nouvelles zones
        DetectDemandZone(index, bar);
        DetectSupplyZone(index, bar);

        // Vérifier la validité des zones existantes
        CheckZoneValidity(index);

        // Dessiner les zones sur la dernière barre
        if (index == this.Count - 1)
        {
            DrawZones();
        }
    }

    // ========== DÉTECTION DES ZONES DE DEMAND ==========
    private void DetectDemandZone(int index, IBar bar)
    {
        if (index < 2) return;

        // Condition : Mouvement baissier suivi d'un rebond fort avec volume
        if (bar.Close > bar.Open && // Bougie haussière
            this.GetBar(index - 1).Close < this.GetBar(index - 1).Open && // Bougie baissière précédente
            bar.Close > this.GetBar(index - 1).Close && // Rebond
            IsVolumeValid(index) &&
            (IsUptrend(index) || !UseTrendFilter)) // Filtre de tendance
        {
            double zoneHigh = bar.High;
            double zoneLow = this.GetBar(index - 1).Low;

            // Éviter les doublons
            foreach (var zone in demandZones)
            {
                if (Math.Abs(zone.High - zoneHigh) < 0.0001 * zoneHigh &&
                    Math.Abs(zone.Low - zoneLow) < 0.0001 * zoneLow)
                {
                    return;
                }
            }

            // Ajouter la nouvelle zone
            demandZones.Add(new Zone(zoneHigh, zoneLow, index - 1, index));

            if (ShowAlerts)
            {
                this.Notify(
                $"NOUVELLE ZONE DE DEMAND détectée entre {zoneLow:0.00} et {zoneHigh:0.00}",
                NotificationType.Alert);
                //Alert($"NOUVELLE ZONE DE DEMAND détectée entre {zoneLow:0.00} et {zoneHigh:0.00}");
            }
        }
    }

    private void Notify(string v, object alert) => throw new NotImplementedException();

    // ========== DÉTECTION DES ZONES DE SUPPLY ==========
    private void DetectSupplyZone(int index, IBar bar)
    {
        if (index < 2) return;

        // Condition : Mouvement haussier suivi d'un rejet fort avec volume
        if (bar.Close < bar.Open && // Bougie baissière
            this.GetBar(index - 1).Close > this.GetBar(index - 1).Open && // Bougie haussière précédente
            bar.Close < this.GetBar(index - 1).Close && // Rejet
            IsVolumeValid(index) &&
            (IsDowntrend(index) || !UseTrendFilter)) // Filtre de tendance
        {
            double zoneHigh = this.GetBar(index - 1).High;
            double zoneLow = bar.Low;

            // Éviter les doublons
            foreach (var zone in supplyZones)
            {
                if (Math.Abs(zone.High - zoneHigh) < 0.0001 * zoneHigh &&
                    Math.Abs(zone.Low - zoneLow) < 0.0001 * zoneLow)
                {
                    return;
                }
            }

            // Ajouter la nouvelle zone
            supplyZones.Add(new Zone(zoneHigh, zoneLow, index - 1, index));

            if (ShowAlerts)
            {
                Alerts($"NOUVELLE ZONE DE SUPPLY détectée entre {zoneLow:0.00} et {zoneHigh:0.00}");
            }
        }
    }

    private void Alerts(string v) => throw new NotImplementedException();

    // ========== VÉRIFIER LA VALIDITÉ DES ZONES ==========
    private void CheckZoneValidity(int index)
    {
        // Vérifier les zones de Demand
        for (int i = 0; i < demandZones.Count; i++)
        {
            if (demandZones[i].IsActive && index - demandZones[i].EndBar > ZoneValidityBars)
            {
                demandZones[i].IsActive = false;
            }
        }

        // Vérifier les zones de Supply
        for (int i = 0; i < supplyZones.Count; i++)
        {
            if (supplyZones[i].IsActive && index - supplyZones[i].EndBar > ZoneValidityBars)
            {
                supplyZones[i].IsActive = false;
            }
        }
    }

    // ========== MÉTHODES AUXILIAIRES ==========
    private bool IsUptrend(int index)
    {
        if (!UseTrendFilter || index < EmaSlowPeriod) return true;
        return emaFast.Result[index] > emaSlow.Result[index];
    }

    private bool IsDowntrend(int index)
    {
        if (!UseTrendFilter || index < EmaSlowPeriod) return true;
        return emaFast.Result[index] < emaSlow.Result[index];
    }

    private bool IsVolumeValid(int index)
    {
        avgVolume = CalculateAvgVolume(index);
        return this.GetBar(index).Volume > VolumeMultiplier * avgVolume;
    }

    private double CalculateAvgVolume(int index)
    {
        double sum = 0;
        int start = Math.Max(0, index - LookbackBars + 1);
        for (int i = start; i <= index; i++)
        {
            sum += this.GetBar(i).Volume;
        }
        return sum / (index - start + 1);
    }

    // ========== DESSIN DES ZONES ==========
    private void DrawZones()
    {
        // Dessiner les zones de Demand
        if (ShowDemandZones)
        {
            foreach (var zone in demandZones)
            {
                if (zone.IsActive)
                {
                    int x1 = this.Chart.BarToX(zone.StartBar);
                    int x2 = this.Chart.BarToX(zone.EndBar);
                    int y1 = this.Chart.PriceToY(zone.High);
                    int y2 = this.Chart.PriceToY(zone.Low);

                    // Créer une couleur transparente
                    Color transparentColor = Color.FromArgb(ZoneOpacity * 255 / 100, DemandColor);

                    // Dessiner le rectangle
                    this.Chart.DrawRectangle(
                        $"DemandZone_{zone.StartBar}_{zone.EndBar}",
                        x1, y2, x2 - x1, y1 - y2,
                        transparentColor, DemandColor, 1);

                    // Afficher les niveaux de prix
                    if (ShowZonePrices)
                    {
                        this.Chart.DrawText(
                            $"Demand: {zone.Low:0.00}-{zone.High:0.00}",
                            x2 + 5, (y1 + y2) / 2,
                            DemandColor, "Arial", 8);
                    }
                }
            }
        }

        // Dessiner les zones de Supply
        if (ShowSupplyZones)
        {
            foreach (var zone in supplyZones)
            {
                if (zone.IsActive)
                {
                    int x1 = this.Chart.BarToX(zone.StartBar);
                    int x2 = this.Chart.BarToX(zone.EndBar);
                    int y1 = this.Chart.PriceToY(zone.High);
                    int y2 = this.Chart.PriceToY(zone.Low);

                    // Créer une couleur transparente
                    Color transparentColor = Color.FromArgb(ZoneOpacity * 255 / 100, SupplyColor);

                    // Dessiner le rectangle
                    this.Chart.DrawRectangle(
                        $"SupplyZone_{zone.StartBar}_{zone.EndBar}",
                        x1, y1, x2 - x1, y2 - y1,
                        transparentColor, SupplyColor, 1);

                    // Afficher les niveaux de prix
                    if (ShowZonePrices)
                    {
                        this.Chart.DrawText(
                            $"Supply: {zone.Low:0.00}-{zone.High:0.00}",
                            x2 + 5, (y1 + y2) / 2,
                            SupplyColor, "Arial", 8);
                    }
                }
            }
        }
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions