-
-
Notifications
You must be signed in to change notification settings - Fork 3.2k
/
PaperBrokerage.cs
92 lines (84 loc) · 3.54 KB
/
PaperBrokerage.cs
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
81
82
83
84
85
86
87
88
89
90
91
92
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using System;
using System.Collections.Generic;
using QuantConnect.Brokerages.Backtesting;
using QuantConnect.Interfaces;
using QuantConnect.Packets;
using QuantConnect.Securities;
namespace QuantConnect.Brokerages.Paper
{
/// <summary>
/// Paper Trading Brokerage
/// </summary>
public class PaperBrokerage : BacktestingBrokerage
{
private DateTime _lastScanTime;
private readonly LiveNodePacket _job;
/// <summary>
/// Creates a new PaperBrokerage
/// </summary>
/// <param name="algorithm">The algorithm under analysis</param>
/// <param name="job">The job packet</param>
public PaperBrokerage(IAlgorithm algorithm, LiveNodePacket job)
: base(algorithm, "Paper Brokerage")
{
_job = job;
}
/// <summary>
/// Gets the current cash balance for each currency held in the brokerage account
/// </summary>
/// <returns>The current cash balance for each currency available for trading</returns>
public override List<CashAmount> GetCashBalance()
{
return GetCashBalance(_job.BrokerageData, Algorithm.Portfolio.CashBook);
}
/// <summary>
/// Gets all holdings for the account
/// </summary>
/// <returns>The current holdings from the account</returns>
public override List<Holding> GetAccountHoldings()
{
return base.GetAccountHoldings(_job.BrokerageData, Algorithm.Securities.Values);
}
/// <summary>
/// Scans all the outstanding orders and applies the algorithm model fills to generate the order events.
/// This override adds dividend detection and application
/// </summary>
public override void Scan()
{
// Scan is called twice per time loop, this check enforces that we only check
// on the first call for each time loop
if (Algorithm.UtcTime != _lastScanTime && Algorithm.CurrentSlice != null)
{
_lastScanTime = Algorithm.UtcTime;
// apply each dividend directly to the quote cash holdings of the security
// this assumes dividends are paid out in a security's quote cash (reasonable assumption)
foreach (var dividend in Algorithm.CurrentSlice.Dividends.Values)
{
Security security;
if (Algorithm.Securities.TryGetValue(dividend.Symbol, out security))
{
// compute the total distribution and apply as security's quote currency
var distribution = security.Holdings.Quantity * dividend.Distribution;
security.QuoteCurrency.AddAmount(distribution);
}
}
}
base.Scan();
}
}
}