Compressor
|
Date: 3/25/2013
|
|
|
|
Код, в котором добавляется индикатор Code
namespace Lesson7
{
/// <summary>
/// Логика взаимодействия для MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
//создаем лог менеджер
_logManager= new LogManager();
//добавляем источник информации трейдера
_logManager.Sources.Add(Connection.Trader);
//добавляем отображение с помощью монитора
_logManager.Listeners.Add(new GuiLogListener(_monitor));
_candleManager = new CandleManager(Connection.Trader);
_monitor.Show();
Connection.Trader.NewMyTrades += DrawTradesOnChart;
}
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
if (Connection.Trader != null && Connection.Trader.IsConnected)
{
Connection.Trader.Dispose();
}
Thread.CurrentThread.Abort();
base.OnClosing(e);
}
/// <summary>
/// Окно для отображения графика со свечками
/// </summary>
private ChartWindow _chartWindow;
private readonly LogManager _logManager;
private readonly MonitorWindow _monitor= new MonitorWindow();
/*----------Элементы для графика------------*/
private ChartCandleElement _candlesElem;
private ChartTradeElement _tradeElement;
private ChartArea _area;
private ChartIndicatorElement _indichElem;
private ChartIndicatorElement _indiclElem;
private ChartIndicatorElement _step1Elem;
private ChartIndicatorElement _bollingerElem;
/*------------------------------------------*/
/*--Получение свечек из торговой платформы-*/
private CandleSeries _series;
private readonly CandleManager _candleManager;
/*-----------------------------------------*/
private void ChartClick(object sender, RoutedEventArgs e)
{
//создаем окно с графиком со всеми элементами
InitChart();
//передаем исторически свечки на график
GethistoryCandles().ForEach(Draw);
//запускаем стратегию
InitStrategy();
//подписываемся на свечки из торговой платформы
_series.ProcessCandle += Draw;
//запускаем получение свечек из торговой платформы
_candleManager.Start(_series);
}
/// <summary>
/// Исторические свечки
/// </summary>
/// <returns></returns>
private IEnumerable<Candle> GethistoryCandles()
{
//закачка из текстового файла
/* return CultureInfo.InvariantCulture.DoInCulture(() => File.ReadAllLines("RIZ2.txt").Select(line =>
{
var timeFrame = (TimeSpan)_series.Arg;
var parts = line.Split(',');
var time = (parts[0] + parts[1]).ToDateTime("yyyyMMddHHmmss");
return (Candle)new TimeFrameCandle
{
OpenPrice = parts[2].To<decimal>(),
HighPrice = parts[3].To<decimal>(),
LowPrice = parts[4].To<decimal>(),
ClosePrice = parts[5].To<decimal>(),
TimeFrame = timeFrame,
OpenTime = time,
CloseTime = time + timeFrame,
TotalVolume = parts[6].To<decimal>(),
Security = Connection.SelectedSecurity,
State = CandleStates.Finished,
};
}).ToArray());*/
//var candles = Finam.History.GetCandles(Connection.SelectedSecurity, DateTime.Now - TimeSpan.FromDays(1), DateTime.Now - TimeSpan.FromDays(1), (TimeSpan) _series.Arg);
return Finam.History.GetHistoryCandles(Connection.SelectedSecurity, TimeSpan.FromMinutes(1), DateTime.Now - TimeSpan.FromDays(10), DateTime.Now - TimeSpan.FromDays(1)).ToArray();
}
/// <summary>
/// Инициализируем чарт
/// </summary>
private void InitChart()
{
var security = Connection.SelectedSecurity;
_series = new CandleSeries(typeof(TimeFrameCandle), security, TimeSpan.FromSeconds(20) /*TimeFrame.Value.Value.TimeOfDay*/);
_series.WorkingTime.Times[0].Min = TimeSpan.FromHours(4);
_series.WorkingTime.Times[0].Max = TimeSpan.FromHours(23);
//создаем окно с графиком свечек
_chartWindow = new ChartWindow
{
Title = "{0} {1}".Put(security.Code, _series.Arg)
};
_chartWindow.MakeHideable();
/* ----- Добавляем все нужные участки для нашего графика*/
_area = new ChartArea();
_chartWindow.Chart.Areas.Add(_area);
_candlesElem = new ChartCandleElement();
_area.Elements.Add(_candlesElem);
_tradeElement= new ChartTradeElement();
_area.Elements.Add(_tradeElement);
_indichElem = new ChartIndicatorElement() { Title = "Moving", Indicator = new Highest() { Name = "Moving", Length = 2} };
_area.Elements.Add(_indichElem);
_indiclElem = new ChartIndicatorElement() { Title = "Moving", Indicator = new Lowest() { Name = "Moving", Length = 2 } };
_area.Elements.Add(_indiclElem);
_step1Elem = new ChartIndicatorElement() { Title = "Moving", Indicator = new Step1() { Name = "Moving", Length = 2 } };
_area.Elements.Add(_step1Elem);
_bollingerElem = new ChartIndicatorElement() { Title = "Bollinger", Indicator = new BollingerBands() { Name = "Bollinger", Length = 20, Width = 2 } };
_area.Elements.Add(_bollingerElem);
/*----------------------------------------------------*/
_chartWindow.Show();
}
/// <summary>
/// отрисовываем сделки стратегии
/// </summary>
/// <param name="mytrades"></param>
private void DrawTradesOnChart(IEnumerable<MyTrade> mytrades)
{
if (_tradeElement == null) return;
this.GuiAsync(() => mytrades.ForEach(t => _chartWindow.Chart.ProcessValues(t.Trade.Time,new Dictionary<IChartElement, object>()
{
{_tradeElement,t}
})));
}
/// <summary>
/// создаем и запускаем стратегию
/// </summary>
private void InitStrategy()
{
var bs = new BollingerStrategy((BollingerBands) _bollingerElem.Indicator, _series)
{
Trader = Connection.Trader,
Security = Connection.SelectedSecurity,
Portfolio = Connection.SelectedPortfolio,
Volume = 1,
};
bs.NewMyTrades += DrawTradesOnChart;
bs.Start();
}
/// <summary>
/// Основной алгоритм прорисовки он-лайн и законченных свечек
/// </summary>
/// <param name="candle"></param>
private void Draw(Candle candle)
{
if (candle.State == CandleStates.Finished || candle.State==CandleStates.Changed)
{
var final = candle.State == CandleStates.Finished;
//значения у индикаторы в данный момент времени(finished,changed)
var val = _bollingerElem.Indicator.Process(new DecimalIndicatorValue(candle.ClosePrice) {IsFinal =final});
var bollingerValue = new ChartIndicatorValue(_bollingerElem.Indicator, val);
var valh = _indichElem.Indicator.Process(new DecimalIndicatorValue(candle.HighPrice) { IsFinal = final });
var indichValue = new ChartIndicatorValue(_indichElem.Indicator, valh);
var vall = _indiclElem.Indicator.Process(new DecimalIndicatorValue(candle.LowPrice) { IsFinal = final });
var indiclValue = new ChartIndicatorValue(_indiclElem.Indicator, vall);
var st1 = _step1Elem.Indicator.Process(new DecimalIndicatorValue(candle.HighPrice) { IsFinal = final });
var stValue = new ChartIndicatorValue(_indichElem.Indicator, st1);
//определеяем время последней свечки
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},
// {_bollingerElem, bollingerValue},
{_indichElem, indichValue},
{_indiclElem, indiclValue},
{_step1Elem, stValue},
}));
}
}
}
}
}
Код добавляемого индикатора Step1 Code
namespace Swing
{
public class Step1 : LengthIndicator<decimal>
{
// private readonly CandleSeries _series;
// private bool NoActiveOrders { get { return Orders.Count(o => o.State == OrderStates.Active) == 0; } }
// public Step1(CandleSeries series)
// {
// _series = series;
// }
/// <summary>
/// Создать <see cref="Highest"/>.
/// </summary>
public Step1()
: base(typeof(decimal))
{
}
/// <summary>
/// Обработать входное значение.
/// </summary>
/// <param name="input">Входное значение.</param>
/// <returns>Результирующее значение.</returns>
public override decimal OnProcess(IIndicatorValue input)
{
var newValue = input.GetValue<decimal>();
var lastValue = LastValue;
if (Buffer.Count == 0)
{
// Инициализируем при добавлении первого значения
lastValue = newValue;
}
// добавляем новое начало
Buffer.Add(newValue);
if (newValue > lastValue)
{
// Новое значение и есть экстремум
lastValue = newValue;
}
if (Buffer.Count > Length)
{
// удаляется экстремум, для поиска нового значения необходим проход по всему буфферу
if (Buffer[0] == lastValue && lastValue != newValue)
{
Buffer.RemoveAt(0);
// ищем новый экстремум
lastValue = Buffer.Aggregate(newValue, (current, t) => Math.Max(t, current));
}
else
{
// удаляем хвостовое значение
Buffer.RemoveAt(0);
}
}
return lastValue;
}
}
}
Его отличие от Highest в том, что он добавляется из своей библиотеки, а не из библиотеки StoskSharp'а.
|
IvanB
|
Date: 3/25/2013
Просмотрев код, видно, что есть ошибка в следующих строках: Code
var st1 = _step1Elem.Indicator.Process(new DecimalIndicatorValue(candle.HighPrice) { IsFinal = final });
var stValue = new ChartIndicatorValue(_indichElem.Indicator, st1);
Во второй строке Вы хотели бы получить значение индикатора _step1Elem.Indicator, но используете индикатор _indichElem.Indicator. Так правильно: Code
var st1 = _step1Elem.Indicator.Process(new DecimalIndicatorValue(candle.HighPrice) { IsFinal = final });
var stValue = new ChartIndicatorValue(_step1Elem.Indicator, st1);
Даже если выполнить проект с Вашим кодом и без исправления указанной выше ошибки, то проект выполняется успешно. Есть предположение, что Вы используете разные версии модулей S# в разных сборках своего приложения, это может привести к исключению о котором Вы писали. Проверьте версии подключенных модулей, если ошибку не удастся устранить, пришлите архив с проектами.
|