Михаил Сухов:
Rebelion:
Вот, хотелось бы понять, как именно, т.е. что нужно прописать в коде, чтобы RealTimeEmulationTrader работал как в 4.1.19.1...
Давайте еще раз определимся с вашей проблемой. Вы в своем роботе запускаете экпорт? Потому как если вы этого не делаете, то работать, конечно же, ничего не будет.
Михаил, сделаем проще. Вот мой нубокод, полученный катом SampleSMA кода. Скоро перепишу нормально, по-папски. :-)
namespace HFTBot
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.ComponentModel;
using System.IO;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Controls;
using System.Windows.Media;
using MessageBox = System.Windows.MessageBox;
using Ecng.Collections;
using Ecng.Common;
using Ecng.Xaml;
using StockSharp.Algo.Candles;
using StockSharp.BusinessEntities;
using StockSharp.Logging;
using StockSharp.Quik;
using StockSharp.Xaml.Charting;
using StockSharp.Algo.Testing;
using System.Xml;
public class StrategyParameters : ICloneable
{
public double candleSize;
public double epsEntryBounds;
public double epsEntryMA;
public double epsStopLoss;
public int period;
public double stdevCount;
public string name;
public string exchange;
public StrategyParameters()
{
candleSize = 1.0;
epsEntryBounds = 100.0;
epsEntryMA = 100.0;
epsStopLoss = 100.0;
period = 10;
stdevCount = 2.65;
name = "noname";
exchange = "Forts";
}
public object Clone()
{
StrategyParameters result = new StrategyParameters();
result.candleSize = candleSize;
result.epsEntryBounds = epsEntryBounds;
result.epsEntryMA = epsEntryMA;
result.epsStopLoss = epsStopLoss;
result.period = period;
result.stdevCount = stdevCount;
result.name = name;
result.exchange = exchange;
return result;
}
}
public class InstrumentDescription
{
public StockBotStrategy strategy;
public Portfolio portfolio;
public Security security;
public StrategyParameters strategyParams;
public Chart chart;
public ChartArea area;
public ChartCandleElement candleElem;
public ChartTradeElement tradesIndicator;
public CandleSeries series;
public bool isFormed = false;
}
public partial class MainWindow
{
private List<InstrumentDescription> instruments = new List<InstrumentDescription>();
private RealTimeEmulationTrader realTimeTradeEmulation;
private CandleManager realtimeCandleManager;
private DateTime stockBotTimeStarting;
private List<string> mails = new List<string>();
//private System.Threading.Timer refresherTimer = new System.Threading.Timer(() => {}
private void OnLog(LogMessage message)
{
if (message.Level != LogLevels.Info && message.Level != LogLevels.Debug)
this.GuiAsync(() => MessageBox.Show(this, message.Message));
}
private void CreateStrategyFromInstrument(Security currentSecurity, StrategyParameters currentParams, InstrumentDescription instrument)
{
instrument.portfolio = new Portfolio()
{
Name = "TEST " + instrument.strategyParams.name,
BeginValue = 500000m,
CurrentValue = 500000m,
//ExchangeBoard = ExchangeBoard.GetBoard(instrument.strategyParams.exchange),
};
instrument.series = new CandleSeries(typeof(RangeCandle), currentSecurity, new Unit((decimal)instrument.strategyParams.candleSize));
instrument.strategy = new StockBotStrategy(instrument.series, currentParams)
{
Volume = 1,
Security = currentSecurity,
Portfolio = instrument.portfolio,
Trader = realTimeTradeEmulation,
};
instrument.strategy.Log += OnLog;
TabItem addedItem;
stockCharts.Items.Add(addedItem = new TabItem() { Header = currentParams.name, Content = new Chart() });
instrument.chart = (Chart)addedItem.Content;
if (((Chart)addedItem.Content).Areas.IsEmpty())
((Chart)addedItem.Content).Areas.Add(new ChartArea());
instrument.area = ((Chart)addedItem.Content).Areas.Last();
instrument.area.Elements.Add(instrument.candleElem = new ChartCandleElement());
#region new filters
instrument.area.Elements.Add(instrument.tradesIndicator = new ChartTradeElement()
{
BuyColor = Colors.Green,
SellColor = Colors.Red,
IsLegend = true,
});
#endregion
((TabItem)(stockCharts.Items.GetItemAt(0))).Focus();
instrument.strategy.strategyTimeStarting = stockBotTimeStarting;
instrument.isFormed = true;
}
private void GetStrategyParameters()
{
XmlDocument config = new XmlDocument();
config.Load(XmlReader.Create(new FileStream(@"c:\hftConfig.xml", FileMode.Open, FileAccess.Read)));
XmlNodeList dataNodes = config.GetElementsByTagName("Root").Item(0).ChildNodes;
foreach (XmlNode elem in dataNodes)
{
instruments.Add(new InstrumentDescription()
{
strategyParams = new StrategyParameters()
{
name = elem.Attributes["Name"].Value,
candleSize = double.Parse(elem.Attributes["Price"].Value),
epsEntryBounds = double.Parse(elem.Attributes["epsEntryBounds"].Value),
epsEntryMA = double.Parse(elem.Attributes["epsEntryMA"].Value),
epsStopLoss = double.Parse(elem.Attributes["epsStopLoss"].Value),
period = int.Parse(elem.Attributes["period"].Value),
stdevCount = double.Parse(elem.Attributes["stdevCount"].Value),
//exchange = elem.Attributes["Exchange"].Value,
},
});
}
}
private void OnStrategyPropertyChanged(object sender, PropertyChangedEventArgs e)
{
instruments.ForEach((elem) => this.GuiAsync(() =>
{
PnL.Content = elem.strategy.PnL;
Position.Content = elem.strategy.Position;
}));
}
public MainWindow()
{
InitializeComponent();
instruments = new List<InstrumentDescription>();
stockBotTimeStarting = DateTime.Now;
// попробовать сразу найти месторасположение Quik по запущенному процессу
Path.Text = QuikTerminal.GetDefaultPath();
GetStrategyParameters();
}
protected override void OnClosing(CancelEventArgs e)
{
if (realTimeTradeEmulation != null)
realTimeTradeEmulation.Dispose();
base.OnClosing(e);
}
private void FindPathClick(object sender, RoutedEventArgs e)
{
var dlg = new FolderBrowserDialog();
if (!Path.Text.IsEmpty())
dlg.SelectedPath = Path.Text;
if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
Path.Text = dlg.SelectedPath;
}
}
private void ConnectClick(object sender, RoutedEventArgs e)
{
if (Path.Text.IsEmpty())
{
MessageBox.Show(this, "Путь к Quik не выбран.");
return;
}
realTimeTradeEmulation = new RealTimeEmulationTrader(new QuikTrader(Path.Text));
realTimeTradeEmulation.Connected += (() =>
{
realtimeCandleManager = new CandleManager(realTimeTradeEmulation);
realTimeTradeEmulation.NewSecurities += securities => this.GuiAsync(() =>
{
securities.ForEach(stock =>
{
var instrument = instruments.FirstOrDefault(x => x.strategyParams.name.CompareTo(stock.Code) == 0);
if (instrument != null)
{
realTimeTradeEmulation.RegisterSecurity(stock);
realTimeTradeEmulation.RegisterMarketDepth(stock);
realTimeTradeEmulation.RegisterTrades(stock);
CreateStrategyFromInstrument(stock, instrument.strategyParams, instrument);
realTimeTradeEmulation.RegisterPortfolio(instrument.portfolio);
}
});
});
realTimeTradeEmulation.NewPortfolios += myPortfolios => this.GuiAsync(() => _portfolios.Portfolios.AddRange(myPortfolios));
realTimeTradeEmulation.NewOrders += orders => this.GuiAsync(() =>
{
_orders.Orders.AddRange(orders);
});
realTimeTradeEmulation.NewMyTrades += trades =>
{
instruments.ForEach(elem =>
{
if (elem.isFormed)
{
var currentElemTrades = trades.Where(t => elem.strategy.Orders.Any(o => o == t.Order));
this.GuiAsync(() => _trades.Trades.AddRange(currentElemTrades));
currentElemTrades.ForEach(strategyTrade =>
{
var tradeTime = elem.strategy.lastWorkedCandle == null ? strategyTrade.Order.Time : elem.strategy.lastWorkedCandle.OpenTime;
this.GuiAsync(() => elem.chart.ProcessValues(tradeTime, new Dictionary<IChartElement, object> { { elem.tradesIndicator, strategyTrade } }));
});
}
});
};
realtimeCandleManager.Processing += (series, candle) =>
{
if (candle.State == CandleStates.Finished)
ProcessCandle(candle);
};
realTimeTradeEmulation.StartExport();
this.GuiAsync(() => { Start.IsEnabled = true; });
});
realTimeTradeEmulation.Connect();
}
private void StartClick(object sender, RoutedEventArgs e)
{
instruments.ForEach(elem =>
{
if (elem.isFormed)
{
realtimeCandleManager.Start(elem.series, DateTime.Today + new TimeSpan(10, 0, 0), DateTime.Today + new TimeSpan(23, 50, 00));
elem.strategy.Start();
}
});
instruments.ForEach((elem) => elem.strategy.PropertyChanged += OnStrategyPropertyChanged);
Start.Content = "Стоп";
}
private void ProcessCandle(Candle candle)
{
var currentInstrument = instruments.FirstOrDefault(elem => elem.strategyParams.name.CompareTo(candle.Security.Code) == 0);
if (currentInstrument != null)
{
#region new chart painter
this.GuiAsync(() =>
{
currentInstrument.chart.ProcessValues(candle.OpenTime, new Dictionary<IChartElement, object>
{
{ currentInstrument.candleElem, candle },
});
});
#endregion
}
}
}
}
Собственно, он не пашет - не отрисовываются свечки и т.п., хотя в 4.1.19.1 всё пахало. Что я тут делаю не так? При этом меняем эмуляшку на торговую систему QuikTrader - всё пашет, но на "живую".