├── ConsoleApp ├── packages.config ├── App.config ├── Properties │ └── AssemblyInfo.cs ├── Program.cs ├── Data │ ├── Day │ │ ├── vtbr.csv │ │ └── sber.csv │ ├── Custom │ │ └── sber.csv │ └── Hour │ │ ├── vtbr.csv │ │ └── sber.csv └── ConsoleApp.csproj ├── BackTesting.Model ├── packages.config ├── Events │ ├── IEventBus.cs │ ├── Event.cs │ ├── MarketEvent.cs │ ├── QueuedEventBus.cs │ ├── SignalEvent.cs │ ├── OrderEvent.cs │ └── FillEvent.cs ├── Enums │ ├── OrderType.cs │ ├── TransactionDirection.cs │ ├── SignalType.cs │ └── EventType.cs ├── MarketData │ ├── Symbols.cs │ ├── IMarketData.cs │ ├── Bar.cs │ ├── BarCsvMap.cs │ ├── ComposedMarketData.cs │ └── CsvDataSource.cs ├── DataHandlers │ ├── IDataHandler.cs │ └── HistoricDataHandler.cs ├── Portfolio │ ├── IPortfolio.cs │ ├── Holding.cs │ └── NaivePortfolio.cs ├── Utils │ ├── Extensions.cs │ ├── String2DateTime.cs │ └── Csv2Frame.cs ├── Strategies │ ├── IStrategy.cs │ └── BuyAndHoldStrategy.cs ├── ExecutionHandlers │ ├── IExecutionHandler.cs │ └── SimulatedExecutionHandler.cs ├── Properties │ └── AssemblyInfo.cs ├── BackTesting.Model.csproj └── BackTests │ └── BackTest.cs ├── readme.md ├── BackTesting.Tests ├── packages.config ├── Csv2FrameTests.cs ├── String2DateTimeTests.cs ├── CsvDataSourceTests.cs ├── Properties │ └── AssemblyInfo.cs ├── HistoricDataHandlerTests.cs ├── ComposedMarketDataTests.cs ├── BackTesting.Tests.csproj └── Mother.cs ├── EventDrivenBacktesting.sln ├── .gitattributes └── .gitignore /ConsoleApp/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /BackTesting.Model/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /BackTesting.Model/Events/IEventBus.cs: -------------------------------------------------------------------------------- 1 | namespace BackTesting.Model.Events 2 | { 3 | public interface IEventBus 4 | { 5 | void Put(Event message); 6 | Event Get(); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /BackTesting.Model/Enums/OrderType.cs: -------------------------------------------------------------------------------- 1 | namespace BackTesting.Model 2 | { 3 | public enum OrderType 4 | { 5 | Undefined = 0, 6 | Market = 1, 7 | Limit = 2 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /ConsoleApp/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /BackTesting.Model/Enums/TransactionDirection.cs: -------------------------------------------------------------------------------- 1 | namespace BackTesting.Model 2 | { 3 | public enum TransactionDirection 4 | { 5 | Undefined = 0, 6 | Buy = 1, 7 | Sell = 2 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | Event-Driven Backtesting 2 | 3 | From: http://www.quantstart.com/articles/Event-Driven-Backtesting-with-Python-Part-I 4 | 5 | To: http://www.quantstart.com/articles/Event-Driven-Backtesting-with-Python-Part-VIII 6 | 7 | -------------------------------------------------------------------------------- /BackTesting.Model/Enums/SignalType.cs: -------------------------------------------------------------------------------- 1 | namespace BackTesting.Model 2 | { 3 | public enum SignalType 4 | { 5 | Undefined = 0, 6 | Long = 1, 7 | Short = 2, 8 | Exit = 3 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /BackTesting.Model/Enums/EventType.cs: -------------------------------------------------------------------------------- 1 | namespace BackTesting.Model 2 | { 3 | public enum EventType 4 | { 5 | Undefined = 0, 6 | Market = 1, 7 | Signal = 2, 8 | Order = 3, 9 | Fill = 4 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /BackTesting.Tests/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /BackTesting.Model/MarketData/Symbols.cs: -------------------------------------------------------------------------------- 1 | namespace BackTesting.Model.MarketData 2 | { 3 | public static class Symbols 4 | { 5 | public static readonly string Sber = "sber"; 6 | public static readonly string Vtbr = "vtbr"; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /BackTesting.Model/MarketData/IMarketData.cs: -------------------------------------------------------------------------------- 1 | namespace BackTesting.Model.MarketData 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | 6 | public interface IMarketData 7 | { 8 | IDictionary> Bars { get; } 9 | IList RowKeys { get; } 10 | ICollection Symbols { get; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /BackTesting.Model/Events/Event.cs: -------------------------------------------------------------------------------- 1 | namespace BackTesting.Model.Events 2 | { 3 | /// 4 | /// Event is base class providing an interface for all subsequent 5 | /// (inherited) events, that will trigger further events in the 6 | /// trading infrastructure. 7 | /// 8 | public abstract class Event 9 | { 10 | public abstract EventType EventType { get; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /BackTesting.Model/DataHandlers/IDataHandler.cs: -------------------------------------------------------------------------------- 1 | namespace BackTesting.Model.DataHandlers 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using BackTesting.Model.MarketData; 6 | 7 | public interface IDataHandler 8 | { 9 | ICollection Symbols { get; } 10 | bool ContinueBacktest { get; } 11 | DateTime? CurrentTime { get; } 12 | Bar GetLast(string symbol); 13 | decimal? GetLastClosePrice(string symbol); 14 | void Update(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /BackTesting.Model/Portfolio/IPortfolio.cs: -------------------------------------------------------------------------------- 1 | namespace BackTesting.Model.Portfolio 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using BackTesting.Model.Events; 6 | 7 | public interface IPortfolio 8 | { 9 | void UpdateSignal(SignalEvent signal); 10 | void UpdateFill(FillEvent fill); 11 | void UpdateTimeIndex(MarketEvent market); 12 | IDictionary HoldingHistory { get; } 13 | IDictionary GetEquityCurve(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /BackTesting.Model/Events/MarketEvent.cs: -------------------------------------------------------------------------------- 1 | namespace BackTesting.Model.Events 2 | { 3 | using System; 4 | 5 | /// 6 | /// Handles the event of receiving a new market update with corresponding bars. 7 | /// 8 | public class MarketEvent : Event 9 | { 10 | public override EventType EventType => EventType.Market; 11 | 12 | public DateTime CurrentTime { get; } 13 | 14 | public MarketEvent(DateTime currentTime) 15 | { 16 | this.CurrentTime = currentTime; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /BackTesting.Model/Utils/Extensions.cs: -------------------------------------------------------------------------------- 1 | namespace BackTesting.Model.Utils 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using BackTesting.Model.MarketData; 6 | 7 | public static class Extensions 8 | { 9 | public static void Print(this IDictionary bars) 10 | { 11 | foreach (var kvp in bars) 12 | { 13 | Console.WriteLine($"{kvp.Key} => {kvp.Value}"); 14 | } 15 | } 16 | 17 | public static void Print(this Bar bar) 18 | { 19 | Console.WriteLine(bar); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /BackTesting.Tests/Csv2FrameTests.cs: -------------------------------------------------------------------------------- 1 | namespace BackTesting.Tests 2 | { 3 | using System; 4 | using BackTesting.Model.MarketData; 5 | using BackTesting.Model.Utils; 6 | using NUnit.Framework; 7 | 8 | [TestFixture] 9 | public class Csv2FrameTests 10 | { 11 | [Test] 12 | public void CanLoadBarsFromCsvString() 13 | { 14 | var bars = Csv2Frame.LoadBarsFromString(Mother.GenericCsvData[Symbols.Sber]); 15 | 16 | Assert.IsTrue(bars.Count > 0); 17 | 18 | foreach (var kvp in bars) 19 | { 20 | Console.WriteLine($"{kvp.Key} => {kvp.Value}"); 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /BackTesting.Model/MarketData/Bar.cs: -------------------------------------------------------------------------------- 1 | namespace BackTesting.Model.MarketData 2 | { 3 | using System; 4 | 5 | public class Bar 6 | { 7 | public DateTime DateTime { get; set; } 8 | public string Symbol { get; set; } 9 | public string Period { get; set; } 10 | public decimal Open { get; set; } 11 | public decimal High { get; set; } 12 | public decimal Low { get; set; } 13 | public decimal Close { get; set; } 14 | public long Volume { get; set; } 15 | 16 | public override string ToString() 17 | { 18 | return string.Format($"{this.DateTime} S={this.Symbol} P={this.Period} O={this.Open} H={this.High} L={this.Low} C={this.Close} V={this.Volume}"); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /BackTesting.Model/Events/QueuedEventBus.cs: -------------------------------------------------------------------------------- 1 | namespace BackTesting.Model.Events 2 | { 3 | using System.Collections.Generic; 4 | 5 | public class QueuedEventBus : IEventBus 6 | { 7 | private readonly Queue queue; 8 | private static readonly object sync = new object(); 9 | 10 | public QueuedEventBus() 11 | { 12 | this.queue = new Queue(); 13 | } 14 | 15 | public Event Get() 16 | { 17 | lock (sync) 18 | { 19 | return this.queue.Count <= 0 ? null : this.queue.Dequeue(); 20 | } 21 | } 22 | 23 | public void Put(Event message) 24 | { 25 | lock (sync) 26 | { 27 | this.queue.Enqueue(message); 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /BackTesting.Model/MarketData/BarCsvMap.cs: -------------------------------------------------------------------------------- 1 | namespace BackTesting.Model.MarketData 2 | { 3 | using BackTesting.Model.Utils; 4 | using CsvHelper.Configuration; 5 | 6 | public sealed class BarCsvMap : CsvClassMap 7 | { 8 | // ,,,