-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathEngineRunner.cs
More file actions
80 lines (71 loc) · 2.63 KB
/
Copy pathEngineRunner.cs
File metadata and controls
80 lines (71 loc) · 2.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
using System.Diagnostics;
using ExecutionTcaEngine.Configuration;
using ExecutionTcaEngine.Execution;
using ExecutionTcaEngine.MarketData;
using ExecutionTcaEngine.Output;
namespace ExecutionTcaEngine;
public static class EngineRunner
{
public static void Run(EngineConfig config)
{
var events = EventSources.Load(config);
EnsureChronological(events);
var eventsPerSecond = BenchmarkReplay(events);
var parentOrders = BuildParentOrders(config.Parents);
var simulator = new VwapSimulator(config.Parents.SliceSeconds, config.FillModel);
var result = simulator.Simulate(events, parentOrders);
var outputDirectory = Path.Combine(config.Run.OutputDir, config.Run.Id);
CsvRecordWriter.Write(outputDirectory, result, events, config.Data.Label);
Console.WriteLine(
$"Replayed {events.Count:N0} events at {eventsPerSecond:N0} events/sec; " +
$"simulated {result.Parents.Count:N0} parents and {result.Fills.Count:N0} fills.");
Console.WriteLine($"Wrote CSV records to {Path.GetFullPath(outputDirectory)}");
}
public static double BenchmarkReplay(IReadOnlyList<MarketEvent> events)
{
var state = new TopOfBookState();
var stopwatch = Stopwatch.StartNew();
foreach (var marketEvent in events)
{
state.Update(marketEvent);
}
stopwatch.Stop();
return events.Count / Math.Max(stopwatch.Elapsed.TotalSeconds, 1e-9);
}
public static IReadOnlyList<ParentOrder> BuildParentOrders(ParentConfig config)
{
var orders = new List<ParentOrder>();
var sequence = 0;
foreach (var window in config.Windows)
{
foreach (var side in config.Sides)
{
foreach (var size in config.Sizes)
{
sequence++;
orders.Add(new ParentOrder(
$"P{sequence:0000}",
side,
size,
window.StartSeconds,
window.EndSeconds));
}
}
}
return orders;
}
private static void EnsureChronological(IReadOnlyList<MarketEvent> events)
{
if (events.Count == 0)
{
throw new InvalidOperationException("Event source returned no rows.");
}
for (var index = 1; index < events.Count; index++)
{
if (events[index].Timestamp < events[index - 1].Timestamp)
{
throw new InvalidDataException("Market events must be chronological.");
}
}
}
}