Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

addon de backtest

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    addon de backtest

    Estoy intentando desarrollar un addon para la ultima version de ninja para hacer backtest y aunque compila bien, cuando lo hago trabajar siempre me sale el mismo error​Click image for larger version

Name:	image.png
Views:	191
Size:	11.5 KB
ID:	1341018OS dejo aqui el codigo a ver si podeis decirme donde puede estar el error:
    using System;
    using System.IO;
    using System.Linq;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Input;
    using NinjaTrader.Gui;
    using NinjaTrader.Gui.Chart;
    using NinjaTrader.Gui.Tools;
    using NinjaTrader.NinjaScript;

    namespace NinjaTrader.NinjaScript.AddOns
    {
    public class ClickCaptureTool : AddOnBase
    {
    private NTWindow mainWindow;
    private ChartControl chartControl;
    private bool capturingEntry;

    private TextBox txtEntryPrice, txtEntryTime, txtExitPrice, txtExitTime, txtResultado;
    private ComboBox comboDirection, comboTarget;
    private CheckBox chkMecha, chkColores, chkCamino, chkAutoSave;
    private Button btnCaptureEntry, btnCaptureExit, btnSave, btnReset;

    private readonly string csvPath = Path.Combine(
    Environment.GetFolderPath(Environment.SpecialFolde r.MyDocuments),
    "NinjaTrader 8", "OperacionesCapturadas.csv");

    protected override void OnStateChange()
    {
    if (State == State.SetDefaults)
    Name = "ClickCaptureTool";
    }

    protected override void OnWindowCreated(Window window)
    {
    if (window is ControlCenter)
    {
    InitWindow();
    AddMenuItem();
    }

    var pi = window.GetType().GetProperty("ChartControl");
    if (pi != null && chartControl == null)
    chartControl = pi.GetValue(window) as ChartControl;
    }

    private void AddMenuItem()
    {
    var controlCenter = Application.Current.Windows.OfType<ControlCenter>( ).FirstOrDefault();
    if (controlCenter == null) return;

    var toolsMenu = controlCenter.FindResource("MainMenu.Tools") as MenuItem;
    if (toolsMenu == null) return;

    var item = new MenuItem { Header = "ClickCaptureTool" };
    item.Click += (_, __) => InitWindow();
    toolsMenu.Items.Add(item);
    }

    private void InitWindow()
    {
    if (mainWindow != null && mainWindow.IsVisible)
    {
    mainWindow.Activate();
    return;
    }

    mainWindow = new NTWindow
    {
    Caption = "Captura de Operación",
    Width = 360,
    Height = 480,
    Topmost = true
    };
    mainWindow.Closed += (_, __) => mainWindow = null;

    var grid = new Grid { Margin = new Thickness(10) };
    for (int i = 0; i < 15; i++)
    grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });

    txtEntryPrice = NewTextBox("Nivel Entrada");
    txtEntryTime = NewTextBox("Hora Entrada");
    txtExitPrice = NewTextBox("Nivel Salida");
    txtExitTime = NewTextBox("Hora Salida");
    txtResultado = NewTextBox("Resultado (pts)");

    comboDirection = NewCombo(new[] { "Largo", "Corto" });
    comboTarget = NewCombo(new[] { "Stop", "Profit" });

    chkMecha = NewCheck("Mecha No Echa");
    chkColores = NewCheck("Colores");
    chkCamino = NewCheck("Camino Limpio 50%");
    chkAutoSave = NewCheck("Guardar automáticamente al capturar salida");

    btnCaptureEntry = NewButton("Capturar Entrada", (_, __) => StartCapture(true));
    btnCaptureExit = NewButton("Capturar Salida", (_, __) => StartCapture(false));
    btnSave = NewButton("Guardar en CSV", (_, __) => SaveToCSV());
    btnReset = NewButton("Reset", (_, __) => ResetCampos());

    AddToGrid(grid, txtEntryPrice, 0);
    AddToGrid(grid, txtEntryTime, 1);
    AddToGrid(grid, btnCaptureEntry, 2);
    AddToGrid(grid, txtExitPrice, 3);
    AddToGrid(grid, txtExitTime, 4);
    AddToGrid(grid, btnCaptureExit, 5);
    AddToGrid(grid, comboDirection, 6);
    AddToGrid(grid, comboTarget, 7);
    AddToGrid(grid, chkMecha, 8);
    AddToGrid(grid, chkColores, 9);
    AddToGrid(grid, chkCamino, 10);
    AddToGrid(grid, chkAutoSave, 11);
    AddToGrid(grid, txtResultado, 12);
    AddToGrid(grid, btnSave, 13);
    AddToGrid(grid, btnReset, 14);

    mainWindow.Content = grid;
    mainWindow.Show();
    }

    private TextBox NewTextBox(string placeholder) =>
    new TextBox { Text = placeholder, IsReadOnly = true, Margin = new Thickness(5) };

    private Button NewButton(string content, RoutedEventHandler handler)
    {
    var b = new Button { Content = content, Margin = new Thickness(5) };
    b.Click += handler;
    return b;
    }

    private ComboBox NewCombo(string[] items) =>
    new ComboBox { ItemsSource = items, SelectedIndex = 0, Margin = new Thickness(5) };

    private CheckBox NewCheck(string label) =>
    new CheckBox { Content = label, Margin = new Thickness(5) };

    private void AddToGrid(Grid grid, UIElement element, int row)
    {
    Grid.SetRow(element, row);
    grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
    grid.Children.Add(element);
    }

    private void StartCapture(bool isEntry)
    {
    if (chartControl == null)
    {
    chartControl = Application.Current.Windows
    .OfType<Window>()
    .Select(w => w.GetType().GetProperty("ChartControl")?.GetValue( w) as ChartControl)
    .FirstOrDefault(c => c != null);
    }

    if (chartControl == null)
    {
    MessageBox.Show("Abre un gráfico primero.");
    return;
    }

    capturingEntry = isEntry;

    Application.Current.Dispatcher.Invoke(() =>
    {
    chartControl.MouseDown -= OnChartClick;
    chartControl.MouseDown += OnChartClick;
    });

    MessageBox.Show(isEntry ? "Haz clic para capturar ENTRADA" : "Haz clic para capturar SALIDA");
    }

    // ✅ Método 100% seguro con Dispatcher
    private void OnChartClick(object sender, MouseButtonEventArgs e)
    {
    ChartPanel panel = null;
    double yCanvas = 0;
    double xCanvas = 0;

    // 1. Ejecutar el acceso al gráfico dentro del Dispatcher
    Application.Current.Dispatcher.Invoke(() =>
    {
    try
    {
    panel = chartControl?.ChartPanels?.FirstOrDefault();
    if (panel == null)
    throw new Exception("No se encontró el panel del gráfico.");

    Point pt = e.GetPosition(panel); // ← seguro aquí
    yCanvas = pt.Y;
    xCanvas = pt.X + panel.X;

    chartControl.MouseDown -= OnChartClick;

    double price = panel.Scales.First().GetValueByYWpf(yCanvas);
    DateTime time = chartControl.GetTimeByX((int)xCanvas);

    if (capturingEntry)
    {
    txtEntryPrice.Text = price.ToString("F5");
    txtEntryTime.Text = time.ToString("HH:mm:ss");
    }
    else
    {
    txtExitPrice.Text = price.ToString("F5");
    txtExitTime.Text = time.ToString("HH:mm:ss");
    CalcularResultado();

    if (chkAutoSave.IsChecked == true)
    SaveToCSV();
    }

    MessageBox.Show(capturingEntry ? "Entrada capturada." : "Salida capturada.");
    }
    catch (Exception ex)
    {
    MessageBox.Show("Error durante la captura del clic:\n" + ex.Message);
    }
    });
    }

    private void CalcularResultado()
    {
    try
    {
    double entry = double.Parse(txtEntryPrice.Text);
    double exit = double.Parse(txtExitPrice.Text);
    double result = (comboDirection.SelectedItem.ToString() == "Largo")
    ? exit - entry
    : entry - exit;

    txtResultado.Text = result.ToString("F5");
    }
    catch
    {
    txtResultado.Text = "Error";
    }
    }

    private void SaveToCSV()
    {
    if (string.IsNullOrWhiteSpace(txtEntryPrice.Text) || string.IsNullOrWhiteSpace(txtExitPrice.Text))
    {
    MessageBox.Show("Debes capturar entrada y salida.");
    return;
    }

    string line = string.Join(",",
    DateTime.Now.ToString("s"),
    txtEntryPrice.Text,
    txtEntryTime.Text,
    txtExitPrice.Text,
    txtExitTime.Text,
    comboDirection.SelectedItem?.ToString(),
    comboTarget.SelectedItem?.ToString(),
    chkMecha.IsChecked == true ? "Sí" : "No",
    chkColores.IsChecked == true ? "Sí" : "No",
    chkCamino.IsChecked == true ? "Sí" : "No",
    txtResultado.Text
    );

    try
    {
    File.AppendAllText(csvPath, line + Environment.NewLine);
    MessageBox.Show("Guardado correctamente.");
    }
    catch (Exception ex)
    {
    MessageBox.Show("Error al guardar: " + ex.Message);
    }
    }

    private void ResetCampos()
    {
    txtEntryPrice.Text = "Nivel Entrada";
    txtEntryTime.Text = "Hora Entrada";
    txtExitPrice.Text = "Nivel Salida";
    txtExitTime.Text = "Hora Salida";
    txtResultado.Text = "Resultado (pts)";

    comboDirection.SelectedIndex = 0;
    comboTarget.SelectedIndex = 0;

    chkMecha.IsChecked = false;
    chkColores.IsChecked = false;
    chkCamino.IsChecked = false;
    chkAutoSave.IsChecked = false;
    }
    }
    }


    #2
    Hello,

    Thank you for your post.

    I would recommend debugging to identify which line of code in the script is hitting this error.

    Comment out code until the error stops. Once the error is gone, uncomment out the last line commented out and see if the error returns. If it does, then you've confirmed which line is hitting the error.

    Once you've identified which line of code is creating the the error, please let us know.

    Comment

    Latest Posts

    Collapse

    Topics Statistics Last Post
    Started by Geovanny Suaza, 02-11-2026, 06:32 PM
    0 responses
    557 views
    0 likes
    Last Post Geovanny Suaza  
    Started by Geovanny Suaza, 02-11-2026, 05:51 PM
    0 responses
    324 views
    1 like
    Last Post Geovanny Suaza  
    Started by Mindset, 02-09-2026, 11:44 AM
    0 responses
    101 views
    0 likes
    Last Post Mindset
    by Mindset
     
    Started by Geovanny Suaza, 02-02-2026, 12:30 PM
    0 responses
    545 views
    1 like
    Last Post Geovanny Suaza  
    Started by RFrosty, 01-28-2026, 06:49 PM
    0 responses
    547 views
    1 like
    Last Post RFrosty
    by RFrosty
     
    Working...
    X