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);
                    }
                }
            }
        }
    }
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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