Skip to content

System.Drawing isn't working (I guess ?) #19

@afournierm42

Description

@afournierm42

Hello, everyone.

I am definitely not a coder. I have several indicators that are causing problems on OnPaintChart, from the QuantowerAlgo API.
Here is one of my codes that is supposed to display the volume profile.

Can anyone help me identify the errors? I would be very grateful. I would really like to learn how to code, as I am very curious but know nothing about the world of coding.

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

namespace CustomIndicators
{
public class VolumeProfileIndicator : Indicator, IVolumeAnalysisIndicator
{
[InputParameter("Position X", 0, 0, 1000, 10, 0)]
public int PositionX = 20;

    [InputParameter("Position Y", 1, 0, 1000, 10, 0)]
    public int PositionY = 30;

    [InputParameter("Espacement lignes", 2, 1, 50, 1, 0)]
    public int LineSpacing = 20;

    private Dictionary<double, double> volumeByPrice = new Dictionary<double, double>();

    public VolumeProfileIndicator()
    {
        this.Name = "Volume Profile Display";
        this.Description = "Affiche le volume total à chaque niveau de prix";
        this.SeparateWindow = false;
    }

    protected override void OnInit()
    {
        // Initialisation
    }

    protected override void OnUpdate(UpdateArgs args)
    {
        // Vérifier si les données de volume sont disponibles
        if (this.HistoricalData.VolumeAnalysisCalculationProgress == null ||
            this.HistoricalData.VolumeAnalysisCalculationProgress.State != VolumeAnalysisCalculationState.Finished)
            return;

        // Réinitialiser les données
        volumeByPrice.Clear();

        // Récupérer les données de volume pour la barre actuelle
        var currentItem = this.HistoricalData[0];

        if (currentItem.VolumeAnalysisData == null || currentItem.VolumeAnalysisData.PriceLevels == null)
            return;

        // Parcourir tous les niveaux de prix et accumuler le volume
        foreach (var priceLevel in currentItem.VolumeAnalysisData.PriceLevels)
        {
            double price = priceLevel.Key; // La clé du dictionnaire est le prix
            var volumeData = priceLevel.Value; // La valeur contient les données de volume
            double totalVolume = volumeData.AskVolume + volumeData.BidVolume;

            if (!volumeByPrice.ContainsKey(price))
            {
                volumeByPrice[price] = 0;
            }

            volumeByPrice[price] += totalVolume;
        }
    }

    // Implémentation de IVolumeAnalysisIndicator
    public bool IsRequirePriceLevelsCalculation => true;

    public void VolumeAnalysisData_Loaded()
    {
        this.Refresh();
    }

    public override void OnPaintChart(PaintChartEventArgs args)
    {
        base.OnPaintChart(args);

        if (volumeByPrice.Count == 0) return;

        Graphics gr = args.Graphics;

        // Créer une police
        Font font = new Font("Arial", 9);
        Font fontBold = new Font("Arial", 9, FontStyle.Bold);

        // Trier les prix par ordre décroissant pour affichage
        var sortedVolumes = volumeByPrice.OrderByDescending(kvp => kvp.Key).ToList();

        // Afficher les en-têtes
        gr.DrawString("Prix", fontBold, Brushes.Yellow, PositionX, PositionY - 20);
        gr.DrawString("Volume", fontBold, Brushes.Yellow, PositionX + 80, PositionY - 20);
        gr.DrawString("Ask", fontBold, Brushes.LightGreen, PositionX + 160, PositionY - 20);
        gr.DrawString("Bid", fontBold, Brushes.LightCoral, PositionX + 220, PositionY - 20);

        // Afficher chaque niveau de prix avec son volume
        int displayCount = Math.Min(sortedVolumes.Count, 30); // Limiter à 30 niveaux max

        for (int i = 0; i < displayCount; i++)
        {
            var priceVolumeEntry = sortedVolumes[i];
            double price = priceVolumeEntry.Key;
            double totalVolume = priceVolumeEntry.Value;

            int yPosition = PositionY + (LineSpacing * i);

            // Récupérer les détails Ask/Bid pour ce niveau de prix
            var currentItem = this.HistoricalData[0];
            double askVolume = 0;
            double bidVolume = 0;

            if (currentItem.VolumeAnalysisData != null &&
                currentItem.VolumeAnalysisData.PriceLevels != null &&
                currentItem.VolumeAnalysisData.PriceLevels.ContainsKey(price))
            {
                var volumeData = currentItem.VolumeAnalysisData.PriceLevels[price];
                askVolume = volumeData.AskVolume;
                bidVolume = volumeData.BidVolume;
            }

            // Afficher le prix
            gr.DrawString(price.ToString("F2"), font, Brushes.LightGray, PositionX, yPosition);

            // Afficher le volume total
            gr.DrawString(totalVolume.ToString("F0"), font, Brushes.White, PositionX + 80, yPosition);

            // Afficher le volume Ask (vert)
            gr.DrawString(askVolume.ToString("F0"), font, Brushes.LightGreen, PositionX + 160, yPosition);

            // Afficher le volume Bid (rouge)
            gr.DrawString(bidVolume.ToString("F0"), font, Brushes.LightCoral, PositionX + 220, yPosition);
        }

        // Trouver et afficher le POC (Point of Control - prix avec le plus de volume)
        if (sortedVolumes.Count > 0)
        {
            var pocEntry = volumeByPrice.OrderByDescending(kvp => kvp.Value).First();
            int pocIndex = sortedVolumes.FindIndex(kvp => kvp.Key == pocEntry.Key);

            if (pocIndex >= 0 && pocIndex < displayCount)
            {
                int pocY = PositionY + (LineSpacing * pocIndex);

                // Surligner le POC avec un rectangle
                using (var pen = new Pen(Color.Yellow, 2))
                {
                    gr.DrawRectangle(pen, PositionX - 5, pocY - 2, 280, LineSpacing - 2);
                }
            }
        }

        font.Dispose();
        fontBold.Dispose();
    }
}

}

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