Здравствуйте!
Разбирался как эмулятор исполняет заявки и получил интересную ситуацию.
В csv файле имеются следующие сделки:
14147947 +00:00 13476.5 200 Buy
14148513 +00:00 13476 198 Sell
14148580 +00:00 13476 2000 Sell
14148791 +00:00 13476.5 100 Buy
14149148 +00:00 13476.5 51 Buy
14149713 +00:00 13476 391 Sell
14150048 +00:00 13425 5386 Buy
14150140 +00:00 13424.5 500 Sell
14150574 +00:00 13425 2000 Buy
14150765 +00:00 13425 15000 Buy
14151864 +00:00 13431 8000 Buy
14152042 +00:00 13431 200 Buy
14152158 +00:00 13431 807 Buy
14152213 +00:00 13431 4800 Buy
В обработчике на NewTrade в момент прихода сделки под номером 14149713 с ценой 13476 регистрирую лимитную заявку(=ордер) на покупку по цене 13461 (была такая ситуация при тестировании и я воссоздал в упрощенном виде, чтобы понять, что происходит)
При этом генерируется НОВАЯ сделка с ценой 13425.2 (которой нет в файле, понятно, что это делается намеренно, по какому-то алгоритму и это наша сделка - сделка стратегии)
Как, возможно, уже понятно, заявка исполнилась по цене 13425,2 (как видно из скриншота в дебаг-окне).
Подскажите, пожалуйста, какая вообще логика у исполнения заявок вообще, и откуда взялась цена исполнения 13425.2 в частности? (полагаю, что бралось среднее из чего-то, но вот чего, какой алгоритм)
исходный код:
using System;
using Ecng.Common;
using StockSharp.Algo.Candles;
using StockSharp.Algo.Storages;
using StockSharp.Algo.Strategies;
using StockSharp.Algo.Testing;
using StockSharp.BusinessEntities;
using StockSharp.Logging;
using StockSharp.Messages;
namespace ConsoleApp1
{
class Program
{
private static HistoryEmulationConnector _connector;
private static CandleSeries _candleSeries;
private static int _trades_count=0;
private static Strategy _strategy;
private static Order _order;
private static MyTrade _myTrade;
private const string _logFile = "log.txt";
private static LogManager logManager = new LogManager();
static void Main(string[] args)
{
var storageRegistry = new StorageRegistry { DefaultDrive = new LocalMarketDataDrive(@"D:\StockSharp\Storage\".ToFullPath()) };
var security = new Security { Id = "XBTUSD@BMEX", Code = "XBTUSD", Board = ExchangeBoard.Bitmex };
var portfolio = new Portfolio { Name = "test account", BeginValue = 1000000 };
logManager.Listeners.Add(new FileLogListener(_logFile));
_connector = new HistoryEmulationConnector(new[] { security }, new[] { portfolio })
{
HistoryMessageAdapter =
{
StorageRegistry = storageRegistry,
StorageFormat = StorageFormats.Csv,
StartDate = new DateTimeOffset(2018, 1, 1, 1, 41, 49, TimeSpan.FromTicks(0)),
StopDate = new DateTimeOffset(2018, 1, 2, 0, 0, 0, TimeSpan.FromTicks(0))
},
LogLevel = LogLevels.Info
};
logManager.Sources.Add(_connector);
_candleSeries = new CandleSeries(typeof(TimeFrameCandle), security, TimeSpan.FromMinutes(1))
{
BuildCandlesMode = MarketDataBuildModes.Build,
BuildCandlesFrom = MarketDataTypes.Trades,
};
_connector.NewSecurity += Connector_NewSecurity;
_connector.NewTrade += Connector_NewTrade;
_connector.NewMyTrade += (t)=> _myTrade=t;
_strategy = new Strategy()
{
Connector = _connector,
Security = security,
Portfolio = portfolio
};
_connector.Connect();
while (Console.ReadKey().KeyChar.ToString() != "z")
{
Console.WriteLine($"Кол-во сделок = {_trades_count}");
};
}
private static void Connector_NewSecurity(Security security)
{
_connector.RegisterTrades(security);
//_connector.SubscribeCandles(_candleSeries);
_connector.Start();
}
private static void Connector_NewTrade(Trade trade)
{
_trades_count++;
if (_trades_count == 3)
{
_order = _strategy.CreateOrder(Sides.Buy, 13461, 1);
_connector.RegisterOrder(_order);
}
}
}
}