├── 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 | // ,,,