UsilaDobry
|
Дата: 01.05.2013
Увидел в Вас в примере код свойства: Код
private bool NoActiveOrders
{ get { return Orders.Count(o => o.State != OrderStates.Done) == 0 && PendingOrders.Count() == 0; } }
Я бы его написал вот так Код
private bool NoActiveOrders { get { return Orders.Count(o => o.State == OrderStates.Active) == 0; } }
А в чем замысел?
|
|
|
|
UsilaDobry
|
Дата: 21.05.2013
|
|
|
|
Что-то я не пойму, как мне коллекцию свечей из метода GetHistoryCandles(); передать в метод ProcessCandle(CandleSeries series, Candle candle)?.. В уроке метод Draw(Candle), принимает только свечи, а у меня при выводе на график ProcessCandle(CandleSeries series, Candle candle) принимает еще и серию свечей... В моем варианте использовать метод GetHistoryCandles() не получится? Код
private void ChartButton_Click(object sender, RoutedEventArgs e)
{
if (TpTimeFrame.Value == null)
{
MessageBox.Show("Введите значение таймфрейм");
return;
}
var timeFrame = TpTimeFrame.Value.Value.TimeOfDay;
GetHistoryCandles();???????
RunProcessGetCandles(timeFrame);
ChartButton.Content = "Очистить график";
}
/// <summary>
/// Исторические свечки
/// </summary>
/// <returns>Коллекция свечей</returns>
private IEnumerable<Candle> GetHistoryCandles()
{
try
{
if (SourceHistoryComboBox.SelectedIndex == 0)
{
//закачка с сайта финама
return Finam.History.GetHistoryCandles(
ConnectionInterface.SelectedSecurity,
TpTimeFrame.Value.Value.TimeOfDay,
BeginDataPicker.SelectedDate.Value,
EndDataPicker.SelectedDate.Value);
}
else
return new Candle[0];
}
catch (Exception ex)
{
MessageBox.Show("Unable to retrive historical candles. " + ex.Message);
return new Candle[0];
}
}
/// <summary>
/// Метод инициирования среды для получения свечей и дальнейшей отрисовки
/// </summary>
/// <param name="timeFrame">Тайм-фрейм для свечей</param>
private void RunProcessGetCandles(TimeSpan timeFrame)
{
_candleManager = new CandleManager(ConnectionInterface.SafeConnection.Trader);
var security = ConnectionInterface.SelectedSecurity;
var series = new CandleSeries(typeof(TimeFrameCandle), security, timeFrame);
series.WorkingTime.Times[0].Min = TimeSpan.FromHours(0);
series.WorkingTime.Times[0].Max = TimeSpan.FromHours(23);
_candleManager.Processing += ProcessCandle;
_candleManager.Start(series);
}
private void ProcessCandle(CandleSeries series, Candle candle)
{
try
{
if (candle.State == CandleStates.Finished)
{
var valueSar = _chartParabolicElement.Indicator.Process(new CandleIndicatorValue(candle) { IsFinal = true });
var valueBb = _chartBollingerElement.Indicator.Process(new CandleIndicatorValue(candle) { IsFinal = true });
this.GuiAsync(() => Chart.ProcessValues(candle.OpenTime, new Dictionary<IChartElement, object>
{
{_chartCandleElement, candle},
{_chartParabolicElement, new ChartIndicatorValue(_chartParabolicElement.Indicator, valueSar)},
{_chartBollingerElement, new ChartIndicatorValue(_chartBollingerElement.Indicator, valueBb)}
}));
}
else
{
this.GuiAsync(() => Chart.ProcessCandle(_chartCandleElement, candle));
}
}
catch (Exception exc)
{
MessageBox.Show(exc.ToString());
}
}
|
|
|
|
IvanB
|
Дата: 21.05.2013
|
|
|
|
UsilaDobry  Что-то я не пойму, как мне коллекцию свечей из метода GetHistoryCandles(); передать в метод ProcessCandle(CandleSeries series, Candle candle)?.. В уроке метод Draw(Candle), принимает только свечи, а у меня при выводе на график ProcessCandle(CandleSeries series, Candle candle) принимает еще и серию свечей... В моем варианте использовать метод GetHistoryCandles() не получится? Код
private void ChartButton_Click(object sender, RoutedEventArgs e)
{
if (TpTimeFrame.Value == null)
{
MessageBox.Show("Введите значение таймфрейм");
return;
}
var timeFrame = TpTimeFrame.Value.Value.TimeOfDay;
GetHistoryCandles();???????
RunProcessGetCandles(timeFrame);
ChartButton.Content = "Очистить график";
}
/// <summary>
/// Исторические свечки
/// </summary>
/// <returns>Коллекция свечей</returns>
private IEnumerable<Candle> GetHistoryCandles()
{
try
{
if (SourceHistoryComboBox.SelectedIndex == 0)
{
//закачка с сайта финама
return Finam.History.GetHistoryCandles(
ConnectionInterface.SelectedSecurity,
TpTimeFrame.Value.Value.TimeOfDay,
BeginDataPicker.SelectedDate.Value,
EndDataPicker.SelectedDate.Value);
}
else
return new Candle[0];
}
catch (Exception ex)
{
MessageBox.Show("Unable to retrive historical candles. " + ex.Message);
return new Candle[0];
}
}
/// <summary>
/// Метод инициирования среды для получения свечей и дальнейшей отрисовки
/// </summary>
/// <param name="timeFrame">Тайм-фрейм для свечей</param>
private void RunProcessGetCandles(TimeSpan timeFrame)
{
_candleManager = new CandleManager(ConnectionInterface.SafeConnection.Trader);
var security = ConnectionInterface.SelectedSecurity;
var series = new CandleSeries(typeof(TimeFrameCandle), security, timeFrame);
series.WorkingTime.Times[0].Min = TimeSpan.FromHours(0);
series.WorkingTime.Times[0].Max = TimeSpan.FromHours(23);
_candleManager.Processing += ProcessCandle;
_candleManager.Start(series);
}
private void ProcessCandle(CandleSeries series, Candle candle)
{
try
{
if (candle.State == CandleStates.Finished)
{
var valueSar = _chartParabolicElement.Indicator.Process(new CandleIndicatorValue(candle) { IsFinal = true });
var valueBb = _chartBollingerElement.Indicator.Process(new CandleIndicatorValue(candle) { IsFinal = true });
this.GuiAsync(() => Chart.ProcessValues(candle.OpenTime, new Dictionary<IChartElement, object>
{
{_chartCandleElement, candle},
{_chartParabolicElement, new ChartIndicatorValue(_chartParabolicElement.Indicator, valueSar)},
{_chartBollingerElement, new ChartIndicatorValue(_chartBollingerElement.Indicator, valueBb)}
}));
}
else
{
this.GuiAsync(() => Chart.ProcessCandle(_chartCandleElement, candle));
}
}
catch (Exception exc)
{
MessageBox.Show(exc.ToString());
}
}
Можно сделать так: Код
foreach (var candle in GetHistoryCandles())
{
ProcessCandle(null, candle);
}
В методе ProcessCandle Вы не используете аргумент CandleSeries series, можно подписаться на получение свечей так: series.ProcessCandle += ProcessCandle; в место этого: _candleManager.Processing += ProcessCandle; и изменить заголовок метода: private void ProcessCandle(Candle candle) тогда получать свечи можно так: Код
foreach (var candle in GetHistoryCandles())
{
ProcessCandle(candle);
}
|
Автор топика
|
|
|
UsilaDobry
|
Дата: 23.05.2013
IvanB  В методе ProcessCandle Вы не используете аргумент CandleSeries series, можно подписаться на получение свечей так: series.ProcessCandle += ProcessCandle; в место этого: _candleManager.Processing += ProcessCandle; и изменить заголовок метода: private void ProcessCandle(Candle candle) тогда получать свечи можно так: Код
foreach (var candle in GetHistoryCandles())
{
ProcessCandle(candle);
}
Может в таком случае можно не использовать foreach, а сделать как в видео-уроке Код
GetHistoryCandles().ForEach(ProcessCandle);
но я не могу этого сейчас испробовать, поскольку срок на демосервер истек, а новые ключи вчера получил, но они не прокатывают. Написал письмо в техподдержку Квика, пока молчат... Процесс остановился Наконец-то подключили... Проверил, такой вариант работает, но график индикаторов выводит не корректно...
|
|
|
|
UsilaDobry
|
Дата: 24.05.2013
И таким способом Код
foreach (var candle in GetHistoryCandles())
{
ProcessCandle(null, candle);
}
и таким способом Код
GetHistoryCandles().ForEach(ProcessCandle);
история выводится корректно, и свечи и индикаторы, но склейка получается неправильная... например при выводе реальной свечи на 10 минутном графике после свечи 12:10 рисуется свеча 12:45, потом после Finished становится свечой 12:20. Также в месте склейки искажаются индикаторы...На истории индикаторы переходят из одного дня в другой плавно, а в месте склейки идёт явный разрыв значений... Что можно придумать...?
|
|
|
|
IvanB
|
Дата: 24.05.2013
UsilaDobry  И таким способом Код
foreach (var candle in GetHistoryCandles())
{
ProcessCandle(null, candle);
}
и таким способом Код
GetHistoryCandles().ForEach(ProcessCandle);
история выводится корректно, и свечи и индикаторы, но склейка получается неправильная... например при выводе реальной свечи на 10 минутном графике после свечи 12:10 рисуется свеча 12:45, потом после Finished становится свечой 12:20. Также в месте склейки искажаются индикаторы...На истории индикаторы переходят из одного дня в другой плавно, а в месте склейки идёт явный разрыв значений... Что можно придумать...? Если учесть то, что в демо квике данные поступают со сдвигом во времени, и учесть что исторические данные мы качаем реальные, которые были, то тогда становится понятно почему склейка получается "кривая". Т.е. причина в демо данных, которые никак не состыкуются с реальной историей.
|
Автор топика
|
|
|
pft_man
|
Дата: 25.05.2013
А какие ещё темы есть в SciChart.ChartTheme, кроме ExpressionDark? Я искал в документации и на форуме, но ничего не нашёл.
|
|
|
|
UsilaDobry
|
Дата: 26.05.2013
pft_man  А какие ещё темы есть в SciChart.ChartTheme, кроме ExpressionDark? Я искал в документации и на форуме, но ничего не нашёл. Доступные темы: ExpressionLight, ExpressionDark, BlackSteel, BrightSpark, Chrome, Electric, Oscilloscope
|
|
|
|
pft_man
|
Дата: 26.05.2013
Спасибо.
|
|
|
|
pft_man
|
Дата: 27.05.2013
А как нарисовать на графике свой трейлинг-стоп так, чтобы он ещё и на истории показывался? В Wealth-Lab для этого существует метод PlotStops(), который просто рисует стопы, а я рассчитываю сами значения стопов.
Единственный вариант - сделать свой индикатор, рассчитывающий трейлинг-стоп, так? Такой индикатор будет иметь значение IsFormed, когда есть позиция. То есть он привязан к стратегии. Как лучше это в коде организовать?
И есть ли свойство у ChartIndicatorElement, позволяющее рисовать не линии, а точки, например. Если нет, то как можно это сделать?
|
|
|
|
IvanB
|
Дата: 27.05.2013
pft_man  А как нарисовать на графике свой трейлинг-стоп так, чтобы он ещё и на истории показывался? В Wealth-Lab для этого существует метод PlotStops(), который просто рисует стопы, а я рассчитываю сами значения стопов.
Единственный вариант - сделать свой индикатор, рассчитывающий трейлинг-стоп, так? Такой индикатор будет иметь значение IsFormed, когда есть позиция. То есть он привязан к стратегии. Как лучше это в коде организовать?
И есть ли свойство у ChartIndicatorElement, позволяющее рисовать не линии, а точки, например. Если нет, то как можно это сделать? Можно использовать метки заявок и сделок. Для отрисовки индикатора можно выбирать стиль, свойство ChartIndicatorElement.DrawStyle, можно попробовать использовать тип ChartIndicatorDrawStyles.Dot для Вашей цели. Можно создать свой графический элемент (метка, аналог метке-заявке или метке-сделке)
|
Автор топика
|
|
|
pft_man
|
Дата: 28.05.2013
Ещё один вопрос. Cледующий код по событию изменения свечки: Код
if ((candle.State == CandleStates.Finished) && (_series.GetCandle<Candle>(0).HighPrice > _series.GetCandle<Candle>(1).HighPrice))
Когда придёт новая цена, которая закроет текущую свечку (возвратит ей статуc finished), какая свечка будет считаться текущей: которая получила статус finished или следующая с первой ценой. Ведь по сути эта цена должна уже начать формировать следующую свечку. То есть обращаться к завершившейся свечке нужно будет через индекс 0 (как у меня в коде) или уже через 1? В общем, мне нужно, чтобы как только свечка завершится, её High сравнивался с High предыдущей свечки. Мой код будет правильно работать?
|
|
|
|
IvanB
|
Дата: 30.05.2013
pft_man  Ещё один вопрос. Cледующий код по событию изменения свечки: Код
if ((candle.State == CandleStates.Finished) && (_series.GetCandle<Candle>(0).HighPrice > _series.GetCandle<Candle>(1).HighPrice))
Когда придёт новая цена, которая закроет текущую свечку (возвратит ей статуc finished), какая свечка будет считаться текущей: которая получила статус finished или следующая с первой ценой. Ведь по сути эта цена должна уже начать формировать следующую свечку. То есть обращаться к завершившейся свечке нужно будет через индекс 0 (как у меня в коде) или уже через 1? В общем, мне нужно, чтобы как только свечка завершится, её High сравнивался с High предыдущей свечки. Мой код будет правильно работать? Да, Ваш код будет работать, учитывайте что событие обработки свечей передает в обработчик последовательно все свечи, в том числе, как только заканчивается свеча, она передается в обработчик, и только при следующем вызове обработчика будет передана новая открытая свеча.
|
Автор топика
|
|
|
UsilaDobry
|
Дата: 03.06.2013
|
|
|
|
Доброго вечера Иван. Столкнулся с такой ошибкой при закачке истории с Финама "Элемент с таким ключом уже был запущен". Такая ошибка у меня появляется, когда я запускаю два графика с историей с разными таймфреймами. Первый график выводит историю и реал корректно, а второй график выдает такую ошибку и выводит только реал... Почему, ведь происходит обращение к сайту Финама для получения свечек с разным таймфреймом...? Код
private IEnumerable<Candle> GetHistoryCandles1()
{
try
{
//закачка с сайта финама
if (TpTimeFrame1.Value != null)
if (BeginDataPicker.SelectedDate != null)
if (EndDataPicker.SelectedDate != null)
return Finam.History.GetHistoryCandles(
ConnectionInterface.SelectedSecurity,
TpTimeFrame1.Value.Value.TimeOfDay,
BeginDataPicker.SelectedDate.Value,
EndDataPicker.SelectedDate.Value);
}
catch (Exception ex)
{
MessageBox.Show("Unable to retrive historical candles. " + ex.Message);
return new Candle[0];
}
return null;
}
private IEnumerable<Candle> GetHistoryCandles2()
{
try
{
//закачка с сайта финама
if (TpTimeFrame2.Value != null)
if (BeginDataPicker.SelectedDate != null)
if (EndDataPicker.SelectedDate != null)
return Finam.History.GetHistoryCandles(
ConnectionInterface.SelectedSecurity,
TpTimeFrame2.Value.Value.TimeOfDay,
BeginDataPicker.SelectedDate.Value,
EndDataPicker.SelectedDate.Value);
}
catch (Exception ex)
{
MessageBox.Show("Unable to retrive historical candles. " + ex.Message);
return new Candle[0];
}
return null;
}
|
|
|
|
UsilaDobry
|
Дата: 06.06.2013
Еще вопрос по обработке исторических свечей. Для того, чтобы обработать свечи с начала торговой сессии и до времени запуска стратегии я использую вот такое условие: Код
if (candle.CloseTime <= StartedTime && _parabolic.IsFormed &&
candle.State == CandleStates.Finished)
Необходимо получить исторические свечи + свечи с начала торговой сессии и до времени старта стратегии для обработки и определения торговых моделей. А как передать исторические свечи в стратегию?
|
|
|
|
IvanB
|
Дата: 06.06.2013
UsilaDobry  Еще вопрос по обработке исторических свечей. Для того, чтобы обработать свечи с начала торговой сессии и до времени запуска стратегии я использую вот такое условие: Код
if (candle.CloseTime <= StartedTime && _parabolic.IsFormed &&
candle.State == CandleStates.Finished)
Необходимо получить исторические свечи + свечи с начала торговой сессии и до времени старта стратегии для обработки и определения торговых моделей. А как передать исторические свечи в стратегию? Вообще, зависит от того, как Вы реализовали стратегию. Думаю, лучшим вариантом будет - создать специальный метод в стратегии, который будет принимать свечи, и этот метод будет реализовывать то, что нужно делать с переданными свечами в Вашей стратегии.
|
Автор топика
|
|
|
IvanB
|
Дата: 06.06.2013
|
|
|
|
UsilaDobry  Доброго вечера Иван. Столкнулся с такой ошибкой при закачке истории с Финама "Элемент с таким ключом уже был запущен". Такая ошибка у меня появляется, когда я запускаю два графика с историей с разными таймфреймами. Первый график выводит историю и реал корректно, а второй график выдает такую ошибку и выводит только реал... Почему, ведь происходит обращение к сайту Финама для получения свечек с разным таймфреймом...? Код
private IEnumerable<Candle> GetHistoryCandles1()
{
try
{
//закачка с сайта финама
if (TpTimeFrame1.Value != null)
if (BeginDataPicker.SelectedDate != null)
if (EndDataPicker.SelectedDate != null)
return Finam.History.GetHistoryCandles(
ConnectionInterface.SelectedSecurity,
TpTimeFrame1.Value.Value.TimeOfDay,
BeginDataPicker.SelectedDate.Value,
EndDataPicker.SelectedDate.Value);
}
catch (Exception ex)
{
MessageBox.Show("Unable to retrive historical candles. " + ex.Message);
return new Candle[0];
}
return null;
}
private IEnumerable<Candle> GetHistoryCandles2()
{
try
{
//закачка с сайта финама
if (TpTimeFrame2.Value != null)
if (BeginDataPicker.SelectedDate != null)
if (EndDataPicker.SelectedDate != null)
return Finam.History.GetHistoryCandles(
ConnectionInterface.SelectedSecurity,
TpTimeFrame2.Value.Value.TimeOfDay,
BeginDataPicker.SelectedDate.Value,
EndDataPicker.SelectedDate.Value);
}
catch (Exception ex)
{
MessageBox.Show("Unable to retrive historical candles. " + ex.Message);
return new Candle[0];
}
return null;
}
Измените класс History на это: Код
public class History : FinamHistorySource
{
public History(ISecurityStorage securityStorage) : base(securityStorage)
{
}
/// <summary>
/// Все инструменты у источника финама
/// </summary>
private IEnumerable<FinamSecurityInfo> Securities { get { return DownloadSecurityInfo(); } }
public IEnumerable<Candle> GetHistoryCandles(Security security, TimeSpan timeFrame, DateTime from, DateTime to)
{
//находим финамовский инструмент по коду инструмента
var fi = Securities.FirstOrDefault(f => f.Code == security.Code);
var marketId = new KeyValuePair<object, object>(FinamMarketIdField, fi.FinamMarketId);
var securityId = new KeyValuePair<object, object>(FinamSecurityIdField, fi.FinamSecurityId);
if (!security.ExtensionInfo.Contains(marketId) && !security.ExtensionInfo.Contains(securityId))
{
//добавляем дополнительную информацию в инструмент, чтобы получить свечки через основной метод GetCandles()
security.ExtensionInfo.Add(marketId); //идентификатор секции рынка
security.ExtensionInfo.Add(securityId); //идентификатор инструмента
}
//запрашиваем свечки
return GetCandles(security, from, to, timeFrame);
}
|
Автор топика
|
|
|
UsilaDobry
|
Дата: 18.06.2013
|
|
|
|
Доброго дня! Пробую добавить вывод реальных свечей от Альфа-коннектора, появляется ошибка "Параметр свечки 00-10-00 неправильный" в строке _candleManager.Start(series); Причем здесь параметр свечки, если в менеджер свечей передается серия свечей, и почему параметр серии 10 минут неправильный?.. Код
using System;
using System.Collections.Generic;
using System.Windows;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Globalization;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
using Ecng.Common;
using Ecng.Collections;
using Ecng.ComponentModel;
using Ecng.Xaml;
using StockSharp.Algo.Candles;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Indicators.Trend;
using StockSharp.BusinessEntities;
using StockSharp.AlfaDirect;
using StockSharp.Logging;
using StockSharp.Xaml;
using StockSharp.Xaml.Charting;
namespace MARKET_SUCCESS_ALFA
{
/// <summary>
/// Логика взаимодействия для MainWindow.xaml
/// </summary>
public partial class MainWindow
{
private AlfaTrader _trader;
private CandleManager _candleManager;
private CandleSeries _series;
private bool _isExportStarted;
private readonly ObservableCollection<Security> _securitiesSource = new ObservableCollection<Security>();
private readonly ObservableCollection<Portfolio> _portfoliosSource = new ObservableCollection<Portfolio>();
private readonly LogManager _logManager = new LogManager();
private readonly MonitorWindow _monitor = new MonitorWindow();
//окно для отображения графика со свечками
private ChartWindow _chartWindow;
private ChartCandleElement _candlesElem;
private ChartIndicatorElement _chartBollingerElement;
public MainWindow()
{
InitializeComponent();
var items = HistoryInterval.Items;
items.Add(new ComboBoxItem { Content = "1 минута", Tag = AlfaTimeFrames.Minute1 });
items.Add(new ComboBoxItem { Content = "5 минут", Tag = AlfaTimeFrames.Minute5 });
items.Add(new ComboBoxItem { Content = "10 минут", Tag = AlfaTimeFrames.Minute10 });
items.Add(new ComboBoxItem { Content = "15 минут", Tag = AlfaTimeFrames.Minute15 });
items.Add(new ComboBoxItem { Content = "30 минут", Tag = AlfaTimeFrames.Minute30 });
items.Add(new ComboBoxItem { Content = "1 час", Tag = AlfaTimeFrames.Hour });
items.Add(new ComboBoxItem { Content = "День", Tag = AlfaTimeFrames.Day });
items.Add(new ComboBoxItem { Content = "Неделя", Tag = AlfaTimeFrames.Week });
items.Add(new ComboBoxItem { Content = "Месяц", Tag = AlfaTimeFrames.Month });
items.Add(new ComboBoxItem { Content = "Год", Tag = AlfaTimeFrames.Year });
HistoryInterval.SelectedIndex = 2;
From.Value = DateTime.Today - TimeSpan.FromDays(7);
To.Value = DateTime.Today;
Security.ItemsSource = _securitiesSource;
Portfolio.ItemsSource = _portfoliosSource;
_logManager.Listeners.Add(new FileLogListener());
_logManager.Listeners.Add(new GuiLogListener(_monitor));
_monitor.Show();
}
private void ConnectClick(object sender, RoutedEventArgs e)
{
// создаем шлюз
_trader = new AlfaTrader();
_logManager.Sources.Add(_trader);
_trader.ProcessDataError += error => this.GuiAsync(() => MessageBox.Show(this, error.ToString(), "Ошибка обработки данных"));
_trader.NewSecurities += securities =>
{
this.GuiAsync(() => _securitiesSource.AddRange(securities));
// начинаем получать текущие сделки (для построения свечек в реальном времени)
securities.ForEach(_trader.RegisterTrades);
};
_trader.NewPortfolios += portfolios => this.GuiAsync(() => _portfoliosSource.AddRange(portfolios));
_trader.Connected += () => this.GuiAsync(() =>
{
ExportBtn.IsEnabled = true;
ConnectBtn.IsEnabled = false;
});
_trader.Connect();
}
protected override void OnClosing(CancelEventArgs e)
{
if (_trader != null)
{
if (_isExportStarted)
StopExport();
_logManager.Sources.Remove(_trader);
_trader.Dispose();
}
base.OnClosing(e);
}
private void StartExport()
{
_isExportStarted = true;
_trader.StartExport();
}
private void StopExport()
{
_trader.StopExport();
_isExportStarted = false;
}
private void ExportClick(object sender, RoutedEventArgs e)
{
if (_isExportStarted)
StopExport();
else
StartExport();
}
private Security SelectedSecurity
{
get { return (Security)Security.SelectedValue; }
}
private Portfolio SelectedPortfolio
{
get { return (Portfolio)Portfolio.SelectedValue; }
}
private void SecuritySelectionChanged(object sender, SelectionChangedEventArgs e)
{
ShowChart.IsEnabled = SelectedSecurity != null;
}
private void PortfolioSelectionChanged(object sender, SelectionChangedEventArgs e)
{
TradingBtn.IsEnabled = SelectedPortfolio != null;
}
private void ShowChartClick(object sender, RoutedEventArgs e)
{
var security = SelectedSecurity;
var timeFrame = (AlfaTimeFrames)((ComboBoxItem)HistoryInterval.SelectedItem).Tag;
if (From.Value != null)
{
var from = From.Value.Value;
if (To.Value != null)
{
var to = To.Value.Value;
if (@from > to)
{
return;
}
var candles = _trader.GetHistoryData(security, timeFrame, new Range<DateTime>(@from, to));
_chartWindow = new ChartWindow
{
Title = "{0}, {1}, {2} - {3}".Put(security.Code,
((ComboBoxItem)HistoryInterval.SelectedItem).Content,
@from.ToString(CultureInfo.InvariantCulture), to.ToString(CultureInfo.InvariantCulture))
};
var area = new ChartArea();
_chartWindow.Chart.ChartTheme = "ExpressionDark";
_chartWindow.Chart.IsAutoScroll = true;
_chartWindow.Chart.Areas.Add(area);
_candlesElem = new ChartCandleElement
{
Antialiasinig = false,
UpBodyColor = Colors.Chartreuse,
UpWickColor = Colors.Chartreuse,
DownBodyColor = Colors.Red,
DownWickColor = Colors.Red,
IsLegend = true,
};
_chartBollingerElement = new ChartIndicatorElement
{
Antialiasinig = false,
Color = Colors.DeepSkyBlue,
IsLegend = true,
Indicator = new BollingerBands
{
Length = 20,
Width = 2
},
Title = "Bollinger Bands",
DrawStyle = ChartIndicatorDrawStyles.Line,
};
_chartBollingerElement.DrawTemplate.VisualTree.SetValue(Shape.FillProperty, new SolidColorBrush(Colors.DeepSkyBlue));
area.Elements.Add(_candlesElem);
area.Elements.Add(_chartBollingerElement);
this.GuiAsync(() => DrawCandles(candles));
_candleManager = new CandleManager(_trader);
_series = new CandleSeries(typeof(TimeFrameCandle), security, timeFrame);
_series.ProcessCandle += Draw;
_candleManager.Start(_series);
_chartWindow.Show();
}
}
}
private void DrawCandles(IEnumerable<Candle> candles)
{
foreach (var candle in candles)
_chartWindow.Chart.ProcessCandle(_candlesElem, candle);
}
private void Draw(Candle obj)
{
if (obj.State == CandleStates.Finished || obj.State == CandleStates.Changed)
{
var final = obj.State == CandleStates.Finished;
//значения у индикаторов в данный момент времени(finished,changed)
var val = _chartBollingerElement.Indicator.Process(new DecimalIndicatorValue(obj.ClosePrice) {IsFinal = final});
var bollingerValue = new ChartIndicatorValue(_chartBollingerElement.Indicator, val);
//определеяем время последней свечки
var timeFrame = (TimeSpan)_series.Arg;
var time = timeFrame.GetCandleBounds(_series.Security).Min - timeFrame;
//добавляем свечки и график индикаторов на чарт
if (obj.State == CandleStates.Finished || (obj.State == CandleStates.Changed && obj.OpenTime >= time))
{
this.GuiAsync(() => _chartWindow.Chart.ProcessValues(obj.OpenTime, new Dictionary<IChartElement, object>
{
{_candlesElem, obj},
{_chartBollingerElement, bollingerValue},
}));
}
}
}
}
}
|
|
|
|
IvanB
|
Дата: 18.06.2013
|
|
|
|
UsilaDobry  Доброго дня! Пробую добавить вывод реальных свечей от Альфа-коннектора, появляется ошибка "Параметр свечки 00-10-00 неправильный" в строке _candleManager.Start(series); Причем здесь параметр свечки, если в менеджер свечей передается серия свечей, и почему параметр серии 10 минут неправильный?.. Код
using System;
using System.Collections.Generic;
using System.Windows;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Globalization;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
using Ecng.Common;
using Ecng.Collections;
using Ecng.ComponentModel;
using Ecng.Xaml;
using StockSharp.Algo.Candles;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Indicators.Trend;
using StockSharp.BusinessEntities;
using StockSharp.AlfaDirect;
using StockSharp.Logging;
using StockSharp.Xaml;
using StockSharp.Xaml.Charting;
namespace MARKET_SUCCESS_ALFA
{
/// <summary>
/// Логика взаимодействия для MainWindow.xaml
/// </summary>
public partial class MainWindow
{
private AlfaTrader _trader;
private CandleManager _candleManager;
private CandleSeries _series;
private bool _isExportStarted;
private readonly ObservableCollection<Security> _securitiesSource = new ObservableCollection<Security>();
private readonly ObservableCollection<Portfolio> _portfoliosSource = new ObservableCollection<Portfolio>();
private readonly LogManager _logManager = new LogManager();
private readonly MonitorWindow _monitor = new MonitorWindow();
//окно для отображения графика со свечками
private ChartWindow _chartWindow;
private ChartCandleElement _candlesElem;
private ChartIndicatorElement _chartBollingerElement;
public MainWindow()
{
InitializeComponent();
var items = HistoryInterval.Items;
items.Add(new ComboBoxItem { Content = "1 минута", Tag = AlfaTimeFrames.Minute1 });
items.Add(new ComboBoxItem { Content = "5 минут", Tag = AlfaTimeFrames.Minute5 });
items.Add(new ComboBoxItem { Content = "10 минут", Tag = AlfaTimeFrames.Minute10 });
items.Add(new ComboBoxItem { Content = "15 минут", Tag = AlfaTimeFrames.Minute15 });
items.Add(new ComboBoxItem { Content = "30 минут", Tag = AlfaTimeFrames.Minute30 });
items.Add(new ComboBoxItem { Content = "1 час", Tag = AlfaTimeFrames.Hour });
items.Add(new ComboBoxItem { Content = "День", Tag = AlfaTimeFrames.Day });
items.Add(new ComboBoxItem { Content = "Неделя", Tag = AlfaTimeFrames.Week });
items.Add(new ComboBoxItem { Content = "Месяц", Tag = AlfaTimeFrames.Month });
items.Add(new ComboBoxItem { Content = "Год", Tag = AlfaTimeFrames.Year });
HistoryInterval.SelectedIndex = 2;
From.Value = DateTime.Today - TimeSpan.FromDays(7);
To.Value = DateTime.Today;
Security.ItemsSource = _securitiesSource;
Portfolio.ItemsSource = _portfoliosSource;
_logManager.Listeners.Add(new FileLogListener());
_logManager.Listeners.Add(new GuiLogListener(_monitor));
_monitor.Show();
}
private void ConnectClick(object sender, RoutedEventArgs e)
{
// создаем шлюз
_trader = new AlfaTrader();
_logManager.Sources.Add(_trader);
_trader.ProcessDataError += error => this.GuiAsync(() => MessageBox.Show(this, error.ToString(), "Ошибка обработки данных"));
_trader.NewSecurities += securities =>
{
this.GuiAsync(() => _securitiesSource.AddRange(securities));
// начинаем получать текущие сделки (для построения свечек в реальном времени)
securities.ForEach(_trader.RegisterTrades);
};
_trader.NewPortfolios += portfolios => this.GuiAsync(() => _portfoliosSource.AddRange(portfolios));
_trader.Connected += () => this.GuiAsync(() =>
{
ExportBtn.IsEnabled = true;
ConnectBtn.IsEnabled = false;
});
_trader.Connect();
}
protected override void OnClosing(CancelEventArgs e)
{
if (_trader != null)
{
if (_isExportStarted)
StopExport();
_logManager.Sources.Remove(_trader);
_trader.Dispose();
}
base.OnClosing(e);
}
private void StartExport()
{
_isExportStarted = true;
_trader.StartExport();
}
private void StopExport()
{
_trader.StopExport();
_isExportStarted = false;
}
private void ExportClick(object sender, RoutedEventArgs e)
{
if (_isExportStarted)
StopExport();
else
StartExport();
}
private Security SelectedSecurity
{
get { return (Security)Security.SelectedValue; }
}
private Portfolio SelectedPortfolio
{
get { return (Portfolio)Portfolio.SelectedValue; }
}
private void SecuritySelectionChanged(object sender, SelectionChangedEventArgs e)
{
ShowChart.IsEnabled = SelectedSecurity != null;
}
private void PortfolioSelectionChanged(object sender, SelectionChangedEventArgs e)
{
TradingBtn.IsEnabled = SelectedPortfolio != null;
}
private void ShowChartClick(object sender, RoutedEventArgs e)
{
var security = SelectedSecurity;
var timeFrame = (AlfaTimeFrames)((ComboBoxItem)HistoryInterval.SelectedItem).Tag;
if (From.Value != null)
{
var from = From.Value.Value;
if (To.Value != null)
{
var to = To.Value.Value;
if (@from > to)
{
return;
}
var candles = _trader.GetHistoryData(security, timeFrame, new Range<DateTime>(@from, to));
_chartWindow = new ChartWindow
{
Title = "{0}, {1}, {2} - {3}".Put(security.Code,
((ComboBoxItem)HistoryInterval.SelectedItem).Content,
@from.ToString(CultureInfo.InvariantCulture), to.ToString(CultureInfo.InvariantCulture))
};
var area = new ChartArea();
_chartWindow.Chart.ChartTheme = "ExpressionDark";
_chartWindow.Chart.IsAutoScroll = true;
_chartWindow.Chart.Areas.Add(area);
_candlesElem = new ChartCandleElement
{
Antialiasinig = false,
UpBodyColor = Colors.Chartreuse,
UpWickColor = Colors.Chartreuse,
DownBodyColor = Colors.Red,
DownWickColor = Colors.Red,
IsLegend = true,
};
_chartBollingerElement = new ChartIndicatorElement
{
Antialiasinig = false,
Color = Colors.DeepSkyBlue,
IsLegend = true,
Indicator = new BollingerBands
{
Length = 20,
Width = 2
},
Title = "Bollinger Bands",
DrawStyle = ChartIndicatorDrawStyles.Line,
};
_chartBollingerElement.DrawTemplate.VisualTree.SetValue(Shape.FillProperty, new SolidColorBrush(Colors.DeepSkyBlue));
area.Elements.Add(_candlesElem);
area.Elements.Add(_chartBollingerElement);
this.GuiAsync(() => DrawCandles(candles));
_candleManager = new CandleManager(_trader);
_series = new CandleSeries(typeof(TimeFrameCandle), security, timeFrame);
_series.ProcessCandle += Draw;
_candleManager.Start(_series);
_chartWindow.Show();
}
}
}
private void DrawCandles(IEnumerable<Candle> candles)
{
foreach (var candle in candles)
_chartWindow.Chart.ProcessCandle(_candlesElem, candle);
}
private void Draw(Candle obj)
{
if (obj.State == CandleStates.Finished || obj.State == CandleStates.Changed)
{
var final = obj.State == CandleStates.Finished;
//значения у индикаторов в данный момент времени(finished,changed)
var val = _chartBollingerElement.Indicator.Process(new DecimalIndicatorValue(obj.ClosePrice) {IsFinal = final});
var bollingerValue = new ChartIndicatorValue(_chartBollingerElement.Indicator, val);
//определеяем время последней свечки
var timeFrame = (TimeSpan)_series.Arg;
var time = timeFrame.GetCandleBounds(_series.Security).Min - timeFrame;
//добавляем свечки и график индикаторов на чарт
if (obj.State == CandleStates.Finished || (obj.State == CandleStates.Changed && obj.OpenTime >= time))
{
this.GuiAsync(() => _chartWindow.Chart.ProcessValues(obj.OpenTime, new Dictionary<IChartElement, object>
{
{_candlesElem, obj},
{_chartBollingerElement, bollingerValue},
}));
}
}
}
}
}
Если Вы используете свечи типа TimeFrameCandle, то подобное сообщение говорит о том, что параметр Arg свечи (для типа TimeFrameCandle) имеет тип отличный от TimeSpan.
|
Автор топика
|
|
|
UsilaDobry
|
Дата: 19.06.2013
Действительно, поменял тип серии свечей, вместо TimeFrameCandle указал AlfaTimeFrames в строке Код
_series = new CandleSeries(typeof(AlfaTimeFrames), security, timeFrame);
ошибка пропала, но выводятся только исторические свечи, реальные не хотят...
|
|
|
|
IvanB
|
Дата: 19.06.2013
UsilaDobry  Действительно, поменял тип серии свечей, вместо TimeFrameCandle указал AlfaTimeFrames в строке Код
_series = new CandleSeries(typeof(AlfaTimeFrames), security, timeFrame);
ошибка пропала, но выводятся только исторические свечи, реальные не хотят... Посмотрите пример SampleAlfaCandles и обновите библиотеки S#.
|
Автор топика
|
|
|
UsilaDobry
|
Дата: 19.06.2013
|
|
|
|
IvanB  Посмотрите пример SampleAlfaCandles и обновите библиотеки S#. Я именно этот пример и пытаюсь доработать. В этом примере выводятся только исторические свечи. А я хочу притулить туда candleManager, но почитав ветку форума AlfaDirect понял, что Аlfa не дружит с candleManager. Видимо по этой причине и пример сделан только с историческими свечами. Я работаю сейчас с библиотекой 4.1.13.2, скачал 4.1.14.1, там пример SampleAlfaCandles нисколько не изменился. Кстати, пример из предыдущей библиотеки работает корректно, а сейчас запустил из новой библиотеки, выдает ошибку обработки данных, при этом код идентичный. Не знаю чем это объяснить... Ну да ладно, меня интересуют больше реальные свечи из Alfa. Я взял вот этот блок вывода исторических свечей Код
private void ShowChartClick(object sender, RoutedEventArgs e)
{
var security = SelectedSecurity;
var timeFrame = (AlfaTimeFrames)((ComboBoxItem)HistoryInterval.SelectedItem).Tag;
if (From.Value != null)
{
var from = From.Value.Value;
if (To.Value != null)
{
var to = To.Value.Value;
if (@from > to)
{
return;
}
var candles = _trader.GetHistoryData(security, timeFrame, new Range<DateTime>(@from, to));
_chartWindow = new ChartWindow
{
Title = "{0}, {1}, {2} - {3}".Put(security.Code,
((ComboBoxItem)HistoryInterval.SelectedItem).Content,
@from.ToString(CultureInfo.InvariantCulture), to.ToString(CultureInfo.InvariantCulture))
};
this.GuiAsync(() => DrawCandles(candles));
И добавил к нему блок обработки реальных свечей через candleManager Код
_candleManager = new CandleManager(_trader);
_series = new CandleSeries(typeof(TimeFrameCandle), security, (TimeSpan)AlfaTimeFrames.Minute10);
_series.ProcessCandle += Draw;
_candleManager.Start(_series);
private void Draw(Candle candle)
{
if (candle.State == CandleStates.Finished || candle.State == CandleStates.Changed)
{
var final = candle.State == CandleStates.Finished;
var val = _chartBollingerElement.Indicator.Process(new DecimalIndicatorValue(candle.ClosePrice) {IsFinal = final});
var bollingerValue = new ChartIndicatorValue(_chartBollingerElement.Indicator, val);
var timeFrame = (TimeSpan)_series.Arg;
var time = timeFrame.GetCandleBounds(_series.Security).Min - timeFrame;
if (candle.State == CandleStates.Finished || (candle.State == CandleStates.Changed && candle.OpenTime >= time))
{
this.GuiAsync(() => _chartWindow.Chart.ProcessValues(candle.OpenTime, new Dictionary<IChartElement, object>
{
{_candlesElem, candle},
{_chartBollingerElement, bollingerValue},
}));
}
}
}
Вроде бы все как учили, но появляется ошибка
|
|
|
|
UsilaDobry
|
Дата: 24.06.2013
|
|
|
|
Доброго вечера Иван! Может Вы мне подскажете, а то разработчики на форуме заняты более серьезными задачами или мои вопросы слишком глупы...:-) К примеру в Quik мы выводили реальные свечи вот так..., причем реальные свечи получаем с 10-00, а историю можно было получить только за прошлые дни Код
_candleManager = new CandleManager(ConnectionInterFace.SafeConnection.Trader);
var security = ConnectionInterFace.SelectedSecurity;
_candleSeries = new CandleSeries(typeof(TimeFrameCandle), security, timeFrame);
_candleSeries.ProcessCandle += Draw;
_candleManager.Start(_candleSeries);
private void Draw(Candle candle)
{
//Временные рамки свечи
var candleBounds = ((TimeSpan) candle.Arg).GetCandleBounds(_candleSeries.Security);
//Работаем только с завершенными свечами и одной последней свечей с произвольным состоянием
if (candle.State == CandleStates.Finished || candle.OpenTime >= candleBounds.Min)
{
//Выводим значения на график
this.GuiAsync(() => Chart.ProcessValues(candle.OpenTime, new Dictionary<IChartElement, object>
{
{_chartCandleElement, candle},
}));
}
}
Из терминала AlfaDirect реальные свечи получаются гораздо проще, при этом историю можно получить вплоть до предпоследней завершенной свечки торговой сессии Код
_candleManager = new CandleManager(_trader);
_series = new CandleSeries(typeof(TimeFrameCandle), security, (TimeSpan)AlfaTimeFrames.Minute10);
_series.ProcessCandle += candle => this.GuiAsync(() => _chartWindow.Chart.ProcessCandle(_candlesElem, candle));
_candleManager.Start(_series);
Но...если в Quik легко отделить завершенные реальные свечи от последней незавершенной, например убрать условие candle.OpenTime >= candleBounds.Min и на график будут выводится только завершенные реальные свечи, то в AlfaDirect такой прием не катит... Не могу дать ума, как отделить завершенные реальный свечи от последней незавершенной. Банальная проверка на finished не помогает... Всё равно выводятся завершенные свечи и последняя незавершенная... Код
_candleManager = new CandleManager(_trader);
_series = new CandleSeries(typeof(TimeFrameCandle), security, (TimeSpan)AlfaTimeFrames.Minute10);
_series.ProcessCandle += candle =>
{
if (candle.State == CandleStates.Finished)
{
this.GuiAsync(() =>_chartWindow.Chart.ProcessValues(candle.OpenTime, new Dictionary<IChartElement, object>
{
{_candlesElem, candle},
}));
};
_candleManager.Start(_series);
|
|
|
|
Самунджян Артем
|
Дата: 25.06.2013
UsilaDobry  Может Вы мне подскажете..
Разбирательства переносятся в Skype, для более оперативного решения проблемы
|
|
|
|
Bond
|
Дата: 04.09.2013
На картинке в начале урока цвета свечей должны быть в точности наоборот. Или поменяйте местами цены открытия и закрытия свечи.
|
|
|