Пишу каркас для торговой стратегии.
Вот так создаю свечи:
Код
public partial class MainWindow : Window
{
// Объявление переменных
private CandleManager _candleManager; // менеджер свечек
private void Connect_Click(object sender, RoutedEventArgs e) // жму на кнопку подключения
{
_candleManager = new CandleManager(_trader); // создаем менеджер свечек для Трейдера
_candleManager.Processing += DrawCandle; // подписываемся на событие
private void StartRobo_Click(object sender, RoutedEventArgs e) // жму на кнопку запуска страты
{
CandleSeries series;
series = new CandleSeries(typeof(TimeFrameCandle), _security, _timeFrame);
_candleManager.Start(series);
Label3.Content = Convert.ToString(series.GetCandle<TimeFrameCandle>(1).ClosePrice);
При запуске стратегии выскакивает вот такая ошибка
An unhandled exception of type 'System.NullReferenceException' occurred in WpfApplication1.exe
Additional information: Ссылка на объект не указывает на экземпляр объекта.Не знаю что и делать. Я так понял что свечи не экспортируются.
Какой экземпляр я не создал?
Что делать?
Код основного окна
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Configuration;
// using S#
using Ecng.Common;
using Ecng.ComponentModel;
using Ecng.Xaml;
using Ecng.Serialization;
using Ecng.Collections;
using StockSharp.Algo;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Indicators.Trend;
using StockSharp.Algo.Candles;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Quik;
using StockSharp.Logging;
using StockSharp.Xaml;
namespace WpfApplication1
{
public partial class MainWindow : Window
{
// Объявление переменных
private QuikTrader _trader; // квик трейдер
private TimeSpan _timeFrame = TimeSpan.FromMinutes(1); // таймфрейм
private TimeSpan _timeRefreshStrategy = TimeSpan.FromSeconds(1); // частота обновления стратегии
int _sharecount; // количество торгуемых контрактов
private DartWeiderStretegy _strategy; // обявляем стратегию
private Security _security; // инструмент
private Portfolio _portfolio; // портфель
private CandleManager _candleManager; // менеджер свечек
public MainWindow()
{
InitializeComponent();
}
// Кнопка "Подключение" - Метод подключения к квику
private void Connect_Click(object sender, RoutedEventArgs e)
{
if (_trader == null)
{
_trader = new QuikTrader(QuikTerminal.GetDefaultPath());
//Подписываемся на событие появления новых портфелей
_trader.NewPortfolios += portfolios => this.GuiAsync(() => {Portfolios.ItemsSource = _trader.Portfolios;});
//Подписываемся на событие появления новых инстументов
_trader.NewSecurities += securities => this.GuiAsync(() => {Securities.ItemsSource = _trader.Securities;});
}
try
{
// подключаем квик
_trader.Connect();
}
catch (System.IO.IOException err)
{
MessageBox.Show("Не удается подключиться к квику" + err.Message);
}
//Начинаем Экспорт данных
_trader.StartExport(); //получение он-лайн данных из квика Инструменты,Заявки , Портфели и так далее
_candleManager = new CandleManager(_trader); // создаем менеджер свечек для Трейдера
_candleManager.Processing += DrawCandle; // подписываемся на событие
}
private void DrawCandle(CandleSeries series, Candle candle)
{
this.GuiAsync(() =>
{
// _chart.ProcessCandle((ChartCandleElement)_chart.Areas[0].Elements[0], candle);
});
}
// Кнопка "Остановка" - Метод остановки робота
private void StopRobot_Click(object sender, RoutedEventArgs e)
{
if (_trader != null)
{
//отключаем экспорт со стакана и останавливаем стратегию
_trader.UnRegisterMarketDepth(_security);
if (_strategy.ProcessState == ProcessStates.Started) _strategy.Stop();
if (_trader.Orders != null) _trader.CancelOrders();
_trader.StopExport();
}
}
// Метод на случай закрытия окна робота
private void ProgramWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
if (_trader != null)
{
//отключаем экспорт со стакана и останавливаем стратегию
_trader.UnRegisterMarketDepth(_security);
if (_strategy.ProcessState == ProcessStates.Started) _strategy.Stop();
if (_trader.Orders != null) _trader.CancelOrders();
_trader.StopExport();
}
}
// Кнопка "Запуск робота" - метод запуск робота
private void StartRobo_Click(object sender, RoutedEventArgs e)
{
// проверяем подключен ли квик трейдер, задан ли портфель, инструмент
if (_trader == null)
{
MessageBox.Show("Терминал не задан");
return;
}
if (_trader.Portfolios == null)
{
MessageBox.Show("Портфель не задан");
return;
}
if (_trader.Securities == null)
{
MessageBox.Show("Инструмент не задан");
return;
}
// код запуска стратегии
if (_strategy == null)
{
CandleSeries series;
series = new CandleSeries(typeof(TimeFrameCandle), _security, _timeFrame);
_candleManager.Start(series);
Label3.Content = Convert.ToString(series.GetCandle<TimeFrameCandle>(1).ClosePrice);
this.GuiAsync(() =>
{
_strategy = new DartWeiderStretegy(_candleManager, _timeFrame)
{
Volume = _sharecount,
Security = _security,
Portfolio = _portfolio,
Trader = _trader,
Interval = _timeRefreshStrategy
};
});
}
if (_strategy.ProcessState == ProcessStates.Stopped)
{
// запускаем процесс получения стакана, необходимый для работы алгоритма котирования
//_trader.RegisterQuotes(_strategy.Security);
_trader.RegisterMarketDepth(_security);
_strategy.Start();
}
}
private void Securities_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
string sec = Convert.ToString(Securities.SelectedItem);
sec = sec.Replace("@RTS", string.Empty);
_security = _trader.Securities.First(s => s.Code == sec && s.Type == SecurityTypes.Future);
}
private void Portfolios_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
_portfolio = _trader.Portfolios.FirstOrDefault(p => p.Name == Convert.ToString(Portfolios.SelectedItem));
}
private void PositionSize_TextChanged(object sender, TextChangedEventArgs e)
{
try
{
_sharecount = Convert.ToInt32(PositionSize.Text);
}
catch
{
MessageBox.Show("Неправильный размер позиции");
}
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
}
}
}
Код стратегии
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using StockSharp.Algo;
using StockSharp.Algo.Strategies;
using StockSharp.Algo.Candles;
using Ecng.Xaml;
using StockSharp.Quik;
using StockSharp.BusinessEntities;
namespace WpfApplication1
{
class DartWeiderStretegy : TimeFrameStrategy
{
decimal openPrice; // цена открытия свечи
decimal lastPrice; // цена предПРЕДпоследней свечи
private Order _order; // текущая заявка
private TimeSpan _timeFrame; // таймфрейм
private CandleManager _candleManager;
// конструктор для работы стратегии
public DartWeiderStretegy(CandleManager candleManager, TimeSpan timeFrame) : base(timeFrame)
{
_candleManager = candleManager;
_timeFrame = TimeFrame;
}
/// <summary>
/// Запуск стратегии
/// </summary>
protected void OnStarting()
{
base.OnStarted();
}
// Выполнение стратегии
protected override ProcessResults OnProcess()
{
/*
//Определяем количество открытых позиций по инструменту
int openPos = Convert.ToInt32(this.MyTrades.GetPosition());
//Получаем цену открытия этой свечи
openPrice = _lastCandle1.ClosePrice;
//Получаем цену открытия предПРЕДпоследней свечи
lastPrice = _lastCandle2.ClosePrice;
//Если есть 2 свечи и нет открытых позиций
if (_lastCandle1!=null && _lastCandle2!=null && openPos == 0)
{
// Если свеча выше предыдущей открываем лонг
if (openPrice > lastPrice)
{
// создаем заявку на покупку
_order = this.CreateOrder(OrderDirections.Buy, base.Security.GetMarketPrice(OrderDirections.Buy), base.Volume);
// регистрируем ее
base.RegisterOrder(_order);
if (_order.IsMatched() == true)
{
//Выставляем стоп-лосс и тейкпрофит через метод
_order = this.CreateStopLimitAndTakeProfit(openPrice);
// регистрируем его
base.RegisterOrder(_order);
}
}
}
*
* */
return ProcessResults.Continue;
}
private Order CreateStopLimitAndTakeProfit(decimal openPrice2)
{
decimal stopPrice = Convert.ToDecimal(openPrice2) - 20;
decimal tpPrice = Convert.ToDecimal(openPrice2) + 20;
return new Order
{
Type = OrderTypes.Conditional,
Volume = base.Volume,
Price = Convert.ToDecimal(stopPrice),
Security = base.Security,
Portfolio = base.Portfolio,
Direction = OrderDirections.Sell,
StopCondition = new QuikStopCondition
{
Type = QuikStopConditionTypes.LinkedOrder,
LinkedOrderPrice = tpPrice,
},
};
}
}
}