Lean  $LEAN_TAG$
ExanteBrokerageModel.cs
1 /*
2  * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
3  * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14 */
15 
17 using QuantConnect.Orders;
21 
23 {
24  /// <summary>
25  /// Exante Brokerage Model Implementation for Back Testing.
26  /// </summary>
28  {
29  private const decimal EquityLeverage = 1.2m;
30 
31  /// <summary>
32  /// Constructor for Exante brokerage model
33  /// </summary>
34  /// <param name="accountType">Cash or Margin</param>
35  public ExanteBrokerageModel(AccountType accountType = AccountType.Cash)
36  : base(accountType)
37  {
38  }
39 
40  /// <summary>
41  /// Get the benchmark for this model
42  /// </summary>
43  /// <param name="securities">SecurityService to create the security with if needed</param>
44  /// <returns>The benchmark for this brokerage</returns>
45  public override IBenchmark GetBenchmark(SecurityManager securities)
46  {
47  var symbol = Symbol.Create("SPY", SecurityType.Equity, Market.USA);
48  return SecurityBenchmark.CreateInstance(securities, symbol);
49  }
50 
51  /// <summary>
52  /// Returns true if the brokerage could accept this order. This takes into account
53  /// order type, security type, and order size limits.
54  /// </summary>
55  /// <remarks>
56  /// For example, a brokerage may have no connectivity at certain times, or an order rate/size limit
57  /// </remarks>
58  /// <param name="security">The security being ordered</param>
59  /// <param name="order">The order to be processed</param>
60  /// <param name="message">If this function returns false, a brokerage message detailing why the order may not be submitted</param>
61  /// <returns>True if the brokerage could process the order, false otherwise</returns>
62  public override bool CanSubmitOrder(Security security, Order order, out BrokerageMessageEvent message)
63  {
64  message = null;
65 
66  if (order == null)
67  {
68  message = new BrokerageMessageEvent(BrokerageMessageType.Warning, "NotSupported", Messages.ExanteBrokerageModel.NullOrder);
69  return false;
70  }
71 
72  if (order.Price == 0m)
73  {
74  message = new BrokerageMessageEvent(BrokerageMessageType.Warning, "NotSupported", Messages.ExanteBrokerageModel.PriceNotSet);
75  return false;
76  }
77 
78  if (security.Type != SecurityType.Forex &&
79  security.Type != SecurityType.Equity &&
80  security.Type != SecurityType.Index &&
81  security.Type != SecurityType.Option &&
82  security.Type != SecurityType.Future &&
83  security.Type != SecurityType.Cfd &&
84  security.Type != SecurityType.Crypto &&
85  security.Type != SecurityType.Index)
86  {
87  message = new BrokerageMessageEvent(BrokerageMessageType.Warning, "NotSupported",
88  Messages.DefaultBrokerageModel.UnsupportedSecurityType(this, security));
89  return false;
90  }
91 
92  return true;
93  }
94 
95  /// <summary>
96  /// Gets a new fee model that represents this brokerage's fee structure
97  /// </summary>
98  /// <param name="security">The security to get a fee model for</param>
99  /// <returns>The new fee model for this brokerage</returns>
100  public override IFeeModel GetFeeModel(Security security) => new ExanteFeeModel();
101 
102  /// <summary>
103  /// Exante global leverage rule
104  /// </summary>
105  /// <param name="security">The security's whose leverage we seek</param>
106  /// <returns>The leverage for the specified security</returns>
107  public override decimal GetLeverage(Security security)
108  {
109  if (AccountType == AccountType.Cash || security.IsInternalFeed() || security.Type == SecurityType.Base)
110  {
111  return 1m;
112  }
113 
114  return security.Type switch
115  {
116  SecurityType.Forex => 1.05m,
117  SecurityType.Equity => EquityLeverage,
118  _ => 1.0m,
119  };
120  }
121  }
122 }