Algorithmischer Handel für .NET und Python✦86+ Konnektoren · Börsen · Broker · Krypto✦S#.Designer · Backtest · optimieren · live gehen✦Eine Community von 31,446+ Tradern und Entwicklern✦Algorithmischer Handel für .NET und Python✦86+ Konnektoren · Börsen · Broker · Krypto✦S#.Designer · Backtest · optimieren · live gehen✦Eine Community von 31,446+ Tradern und Entwicklern✦
При формировании свечек, хочу сделать генерацию коллекции таймфреймов и внесение этой коллекции в комбобокс.
А затем передавать выбранное значение таймфрейма из комбобокса для создания серии свечек.
Пишу код в конструктор MainWindow()
var candleManger = new CandleManager(InterfaceConnection.SafeConnection.Trader);
TimeFrameComboBox.ItemsSource = candleManger.GetSupportedRanges(null); //здесь в качестве аргумента надо указать серию свечек, я ставлю по совету решайпера null, но это не правильно, при запуске выпадает Exception, аргумент вызываемого метода не может быть null.
В обработчик события по нажатию кнопки пишу
var candleManger = new CandleManager(InterfaceConnection.SafeConnection.Trader);
var candleSeries = new CandleSeries(typeof (TimeFrameCandle), InterfaceConnection.SelectedSecurity,TimeFrameComboBox.SelectedValue);
if (BeginDatePicker != null && EndDatePicker != null)
{
if (BeginDatePicker.SelectedDate != null) candleSeries.From = (DateTime) BeginDatePicker.SelectedDate;
if (EndDatePicker.SelectedDate != null) candleSeries.To = (DateTime) EndDatePicker.SelectedDate;
}
Приложение вообще не запускается.
UsilaDobry:
...
Пишу код в конструктор MainWindow()
var candleManger = new CandleManager(InterfaceConnection.SafeConnection.Trader);
TimeFrameComboBox.ItemsSource = candleManger.GetSupportedRanges(null); //здесь в качестве аргумента надо указать серию свечек, я ставлю по совету решайпера null, но это не правильно, при запуске выпадает Exception, аргумент вызываемого метода не может быть null.
Как вариант создал обработчик события
private void TimeFrameComboBox_ContextMenuOpening(object sender, System.Windows.Controls.ContextMenuEventArgs e)
{
var candleManger = new CandleManager(InterfaceConnection.SafeConnection.Trader);
TimeFrameComboBox.ItemsSource = candleManger.GetSupportedRanges(candleSeries);
}
Все равно программа просит конкретное значение candleSeries, в таком виде воспринимает как null.
UsilaDobry:
Как вариант создал обработчик события
private void TimeFrameComboBox_ContextMenuOpening(object sender, System.Windows.Controls.ContextMenuEventArgs e)
{
var candleManger = new CandleManager(InterfaceConnection.SafeConnection.Trader);
TimeFrameComboBox.ItemsSource = candleManger.GetSupportedRanges(candleSeries);
}
Все равно программа просит конкретное значение candleSeries, в таком виде воспринимает как null.
На сколько я теперь понимаю, Вы не правильно пытаетесь использовать метод GetSupportedRanges. Вы пытаетесь получить из него коллекцию таймфреймов свечей, но этот метод возвращает не это, он возвращает "временные диапазоны, для которых у данного источниках для передаваемой серии свечек есть данные.". Подробнее здесь
UsilaDobry:
Тогда как можно получить значения таймфреймов, которые есть в Quik?
Я думаю, что из Квика никак не извлечь значения таймфреймов, которые используются в его выпадающем списке.
Обычно, если надо выбирать значение таймфрейма из списка, то используют специальный компонент (Xceed:TimePicker) или в ручную, в цикле заполняют стандартный компонент выпадающего списка.
Я в ручную занес значения через ComboBoxItem, потом вызываю значение в следующем коде
var candleSeries = new CandleSeries(typeof (TimeFrameCandle), InterfaceConnection.SelectedSecurity, TimeSpan.FromMinutes((double) TimeFrameComboBox.SelectedItem));
Выдает exception - Заданное приведение является недопустимым. Где-то явное приведение типов не сделал?
UsilaDobry:
Я в ручную занес значения через ComboBoxItem, потом вызываю значение в следующем коде
var candleSeries = new CandleSeries(typeof (TimeFrameCandle), InterfaceConnection.SelectedSecurity, TimeSpan.FromMinutes((double) TimeFrameComboBox.SelectedItem));
> Выдает exception - Заданное приведение является недопустимым. Где-то явное приведение типов не сделал?
Всего скорее Вы поместили в TimeFrameComboBox значения не типа double.
:::
>
> Здесь значения int32. Как здесь в коде указать тип значения double? Просто поставить 1.0; 5.0... Это не помогает...
Предлагаю заполнять в коде C#:
```csharp
TimeFrameComboBox.Items.Add(1);
TimeFrameComboBox.Items.Add(5);
...
Это все сложно...
Хорошо, поставлю элемент TimePicker, он передает значения типа DateTime, а нам надо передать значение типа TimeSpan.
Явное преобразование в этой строке не катит, как тогда обратиться к TimePicker в строке:
не правильно... Exception
Строка не распознана как действительный TimeSpan.
TimeSpan.Parse(TfTimePicker.Value.ToString()), что здесь не так? берем значение типа DateTime, преобразуем его методом ToString в строку, а потом парсим в тип TimeSpan...
Я дописал создание candleManager в обработчик события ChartButton_Click. Ошибка не вылетает, но свечи не выводятся на график, появляется только сетка координат
using System;
using System.Collections.Generic;
using System.Threading;
using System.Windows;
using Ecng.Xaml;
using StockSharp.Algo.Candles;
using StockSharp.Logging;
using StockSharp.Quik;
using StockSharp.TraderConnection;
using StockSharp.Xaml;
namespace My_FirstROBOT
{
/// <summary>
/// Логика взаимодействия для MainWindow.xaml
/// </summary>
public partial class MainWindow
{
private readonly MonitorWindow _monitor = new MonitorWindow();
private readonly LogManager _logmanager = new LogManager();
public MainWindow()
{
InitializeComponent();
InterfaceConnection.SafeConnection = new SafeConnection(new QuikTrader(QuikTerminal.GetDefaultPath()));
//////////////////////////////////Блок получения информации///////////////////////////////////////////////////////
InterfaceConnection.SafeConnection.Trader.NewSecurities += securities => this.GuiAsync(() =>
{
TabMyTools.ItemsSource = InterfaceConnection.SafeConnection.Trader.Securities;
});
InterfaceConnection.SafeConnection.Trader.NewPortfolios += portfolios => this.GuiAsync(() =>
{
TabMyPortfolios.ItemsSource = InterfaceConnection.SafeConnection.Trader.Portfolios;
});
InterfaceConnection.SafeConnection.Trader.NewPositions += positions => this.GuiAsync(() =>
{
TabMyPosition.ItemsSource = InterfaceConnection.SafeConnection.Trader.Positions;
});
InterfaceConnection.SafeConnection.Trader.NewOrders += orders => this.GuiAsync(() =>
{
TabMyOrders.ItemsSource = InterfaceConnection.SafeConnection.Trader.Orders;
});
InterfaceConnection.SafeConnection.Trader.NewStopOrders += orders => this.GuiAsync(() =>
{
TabMyOrdersStop.ItemsSource = InterfaceConnection.SafeConnection.Trader.StopOrders;
});
InterfaceConnection.SafeConnection.Trader.NewMyTrades += trades => this.GuiAsync(() =>
{
TabMyTrades.ItemsSource = InterfaceConnection.SafeConnection.Trader.MyTrades;
});
////////////////////////////////////////////Блок логирования////////////////////////////////////////////////////
_logmanager.Listeners.Add(new GuiLogListener(_monitor));
_logmanager.Listeners.Add(new FileLogListener("log.txt"));
_logmanager.Sources.Add(InterfaceConnection.SafeConnection.Trader);
}
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
if (InterfaceConnection.SafeConnection.Trader != null &&
InterfaceConnection.SafeConnection.Trader.IsConnected)
{
InterfaceConnection.SafeConnection.Trader.Dispose();
}
Thread.CurrentThread.Abort();
base.OnClosing(e);
}
/// <summary>
/// Менеджер свечек
/// </summary>
private readonly CandleManager _candleManager;
/// <summary>
/// Основная площадь
/// </summary>
private ChartArea _area;
/// <summary>
/// Элемент свечек на графике
/// </summary>
private ChartCandleElement _candlesElem;
/// <summary>
/// Серия для свечек
/// </summary>
private CandleSeries _series;
/// <summary>
/// Создать и добавить все нужные нам элементы
/// </summary>
private void InitAreas()
{
try
{
//добавляем первую площадь(на которой будем все отмечать)
_area = new ChartArea();
Chart.Areas.Add(_area);
//свечки
_candlesElem = new ChartCandleElement();
_area.Elements.Add(_candlesElem);
if (InterfaceConnection != null)
_series = new CandleSeries(typeof(TimeFrameCandle), InterfaceConnection.SelectedSecurity, TimeSpan.FromMinutes(1));
}
catch (Exception exc)
{
MessageBox.Show(exc.ToString());
}
}
private void CandlesChartStart()
{
try
{
//отрабатываем поступление новых свечек
_series.ProcessCandle += candle =>
{
//законченные свечки используются для расчета индикатора
if (candle.State == CandleStates.Finished)
{
this.GuiAsync(() => Chart.ProcessValues(candle.OpenTime, new Dictionary<IChartElement, object>
{
{_candlesElem, candle},//свечка
}));
}
else
{
var timeFrame = (TimeSpan)_series.Arg;
var time = timeFrame.GetCandleBounds(_series.Security).Min - timeFrame; //находим последнее время свечки
//добавляем только последние измененные свечки
if (candle.OpenTime >= time)
Chart.ProcessCandle(_candlesElem, candle);
}
};
}
catch (Exception exc)
{
MessageBox.Show(exc.ToString());
}
}
private void ChartButton_Click(object sender, RoutedEventArgs e)
{
try
{
var _candleManager = new CandleManager(InterfaceConnection.SafeConnection.Trader);
//инициализация графика
InitAreas();
//прорисовка свечек
CandlesChartStart();
//запускаем получение свечек
_candleManager.Start(_series);
}
catch (Exception exc)
{
MessageBox.Show(exc.ToString());
}
}
/// <summary>
/// Блок работы торговой стратегии
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TakrProfitCheckBox_Checked(object sender, RoutedEventArgs e)
{
WidthBbLabel.IsEnabled = true;
WidthBbTextBox.IsEnabled = true;
SpradTpLabel.IsEnabled = true;
SpradTpTextBox.IsEnabled = true;
}
private void LevelSARCheckBox_Checked(object sender, RoutedEventArgs e)
{
SignalsLevelSarLabel.IsEnabled = true;
Signal1SarCheckBox.IsEnabled = true;
Signal2SarCheckBox.IsEnabled = true;
StartTradingButton.IsEnabled = true;
}
private void StartTradingButton_Click(object sender, RoutedEventArgs e)
{
StopTradingButton.IsEnabled = true;
StartTradingButton.IsEnabled = false;
}
private void StopTradingButton_Click(object sender, RoutedEventArgs e)
{
StopTradingButton.IsEnabled = false;
StartTradingButton.IsEnabled = true;
}
}
}
Compressor:
По какой причине CancelActiveOrders() не работает?
Всего скорее Вы вызываете этот метод, где он в принципе не может работать, например если Вы вызываете CancelActiveOrders в переопределенном методе OnStopping, этот метод вызывается когда стратегия уже перешла в остановку и по этому не воспринимает торговые команды.
Информация из логирования должна помочь в определении причины не работы CancelActiveOrders.
Compressor:
Он работает в ProcessCandle(Candle candle), в стандартной схеме (как в болинджере). Какие параметры надо выводить в лог, чтобы понять в чем причина?
Перед вызовом метода CancelActiveOrders() надо проверить есть ли активные заявки, примерно так:
Orders.Count(o => o.State == OrderStates.Active)
И если Вы используете старую версию S#, то желательно перейти на одну из последних, если это ошибка в S# старой версии, то переход на новую версию поможет ее решить.
А как переписать данную конструкцию с учетом введения Messages?
Wir verwenden Cookies, um die beste Erfahrung auf unserer Website zu gewährleisten. Durch die weitere Nutzung unserer Seite stimmen Sie der Verwendung von Cookies zu.
Kommentare (22)
Anmelden oder Konto erstellen, Melden Sie sich an oder registrieren Sie sich, um einen Kommentar zu hinterlassen
Каким образом можно внедрить монитор логирования в форму Wpf, чтобы он открывался не отдельным окном, а в приложении?
При формировании свечек, хочу сделать генерацию коллекции таймфреймов и внесение этой коллекции в комбобокс. А затем передавать выбранное значение таймфрейма из комбобокса для создания серии свечек.
Пишу код в конструктор MainWindow()
var candleManger = new CandleManager(InterfaceConnection.SafeConnection.Trader); TimeFrameComboBox.ItemsSource = candleManger.GetSupportedRanges(null); //здесь в качестве аргумента надо указать серию свечек, я ставлю по совету решайпера null, но это не правильно, при запуске выпадает Exception, аргумент вызываемого метода не может быть null.
В обработчик события по нажатию кнопки пишу
var candleManger = new CandleManager(InterfaceConnection.SafeConnection.Trader); var candleSeries = new CandleSeries(typeof (TimeFrameCandle), InterfaceConnection.SelectedSecurity,TimeFrameComboBox.SelectedValue); if (BeginDatePicker != null && EndDatePicker != null) { if (BeginDatePicker.SelectedDate != null) candleSeries.From = (DateTime) BeginDatePicker.SelectedDate; if (EndDatePicker.SelectedDate != null) candleSeries.To = (DateTime) EndDatePicker.SelectedDate; } Приложение вообще не запускается.
в аргумент нужно указывать серию свечей, для которой хотите получить данные.
Как вариант создал обработчик события private void TimeFrameComboBox_ContextMenuOpening(object sender, System.Windows.Controls.ContextMenuEventArgs e) { var candleManger = new CandleManager(InterfaceConnection.SafeConnection.Trader); TimeFrameComboBox.ItemsSource = candleManger.GetSupportedRanges(candleSeries); } Все равно программа просит конкретное значение candleSeries, в таком виде воспринимает как null.
Тогда как можно получить значения таймфреймов, которые есть в Quik?
Я в ручную занес значения через ComboBoxItem, потом вызываю значение в следующем коде
Выдает exception - Заданное приведение является недопустимым. Где-то явное приведение типов не сделал?
var candleSeries = new CandleSeries(typeof (TimeFrameCandle), InterfaceConnection.SelectedSecurity, TimeSpan.FromMinutes((double) TimeFrameComboBox.SelectedItem));
<ComboBox x:Name="TimeFrameComboBox" Width="50" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="144,-22,0,0" SelectedIndex="0" > <ComboBoxItem>1</ComboBoxItem> <ComboBoxItem>5</ComboBoxItem> <ComboBoxItem>10</ComboBoxItem> <ComboBoxItem>15</ComboBoxItem> <ComboBoxItem>30</ComboBoxItem> <ComboBoxItem>60</ComboBoxItem> </ComboBox>
Здесь значения int32. Как здесь в коде указать тип значения double? Просто поставить 1.0; 5.0... Это не помогает...
<ComboBox x:Name="TimeFrameComboBox" Width="50" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="144,-22,0,0" SelectedIndex="0" > <ComboBoxItem>1</ComboBoxItem> <ComboBoxItem>5</ComboBoxItem> <ComboBoxItem>10</ComboBoxItem> <ComboBoxItem>15</ComboBoxItem> <ComboBoxItem>30</ComboBoxItem> <ComboBoxItem>60</ComboBoxItem> </ComboBox>
И можно в цикле это сделать.
Это все сложно... Хорошо, поставлю элемент TimePicker, он передает значения типа DateTime, а нам надо передать значение типа TimeSpan. Явное преобразование в этой строке не катит, как тогда обратиться к TimePicker в строке:
Finam.History.GetHistoryCandles(InterfaceConnection.SelectedSecurity, TfTimePicker.Value, (DateTime)BeginDatePicker.SelectedDate, (DateTime)EndDatePicker.SelectedDate).ToArray();
Вот так правильно
Finam.History.GetHistoryCandles(InterfaceConnection.SelectedSecurity, TimeSpan.Parse(TfTimePicker.Value.ToString()), (DateTime)BeginDatePicker.SelectedDate, (DateTime)EndDatePicker.SelectedDate).ToArray();
не правильно... Exception Строка не распознана как действительный TimeSpan.
TimeSpan.Parse(TfTimePicker.Value.ToString()), что здесь не так? берем значение типа DateTime, преобразуем его методом ToString в строку, а потом парсим в тип TimeSpan...
Убрал вывод исторических данных, на старте candleManager выдает Exception- Значение не может быть неопределенным
Я дописал создание candleManager в обработчик события ChartButton_Click. Ошибка не вылетает, но свечи не выводятся на график, появляется только сетка координат
Вопросы отпали после просмотра видео-урока CandleChartsProject. Сразу надо было мне смотреть видео-урок.
По какой причине CancelActiveOrders() не работает?
Он работает в ProcessCandle(Candle candle), в стандартной схеме (как в болинджере). Какие параметры надо выводить в лог, чтобы понять в чем причина?
Перед вызовом метода CancelActiveOrders() надо проверить есть ли активные заявки, примерно так:
И если Вы используете старую версию S#, то желательно перейти на одну из последних, если это ошибка в S# старой версии, то переход на новую версию поможет ее решить.
А как переписать данную конструкцию с учетом введения Messages?