Skip to content

Commit

Permalink
Brokerage models improvements (QuantConnect#5267)
Browse files Browse the repository at this point in the history
* fix Atreyu brokerage type full name

* improve brokerage models

-AtreyuBrokerageModel
-TradingTechnologiesBrokerageModel

* remove Limit price checks
  • Loading branch information
AdalyatNazirov authored Feb 5, 2021
1 parent aef2a47 commit c02ad0a
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 10 deletions.
111 changes: 111 additions & 0 deletions Common/Brokerages/AtreyuBrokerageModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,17 @@
* limitations under the License.
*/

using System.Linq;
using System.Collections.Generic;
using QuantConnect.Benchmarks;
using QuantConnect.Data.Shortable;
using QuantConnect.Interfaces;
using QuantConnect.Orders;
using QuantConnect.Orders.Fees;
using QuantConnect.Orders.TimeInForces;
using QuantConnect.Securities;
using QuantConnect.Util;
using static QuantConnect.StringExtensions;

namespace QuantConnect.Brokerages
{
Expand All @@ -26,6 +33,25 @@ namespace QuantConnect.Brokerages
public class AtreyuBrokerageModel : DefaultBrokerageModel
{
private readonly IShortableProvider _shortableProvider;
private readonly System.Type[] _supportedTimeInForces =
{
typeof(DayTimeInForce)
};

private readonly OrderType[] _supportedOrderTypes =
{
OrderType.Limit,
OrderType.Market,
OrderType.MarketOnClose
};

/// <summary>
/// The default markets for Trading Technologies
/// </summary>
public new static readonly IReadOnlyDictionary<SecurityType, string> DefaultMarketMap = new Dictionary<SecurityType, string>
{
{SecurityType.Equity, Market.USA}
}.ToReadOnlyDictionary();

/// <summary>
/// Creates a new instance
Expand All @@ -35,6 +61,11 @@ public AtreyuBrokerageModel(AccountType accountType = AccountType.Margin) : base
_shortableProvider = new AtreyuShortableProvider(SecurityType.Equity, Market.USA);
}

/// <summary>
/// Gets a map of the default markets to be used for each security type
/// </summary>
public override IReadOnlyDictionary<SecurityType, string> DefaultMarkets => DefaultMarketMap;

/// <summary>
/// Provides Atreyu fee model
/// </summary>
Expand All @@ -53,5 +84,85 @@ public override IShortableProvider GetShortableProvider()
{
return _shortableProvider;
}

/// <summary>
/// Get the benchmark for this model
/// </summary>
/// <param name="securities">SecurityService to create the security with if needed</param>
/// <returns>The benchmark for this brokerage</returns>
public override IBenchmark GetBenchmark(SecurityManager securities)
{
// Equivalent to no benchmark
return new FuncBenchmark(x => 0);
}

/// <summary>
/// Returns true if the brokerage could accept this order.
/// </summary>
/// <param name="security">The security being ordered</param>
/// <param name="order">The order to be processed</param>
/// <param name="message">If this function returns false, a brokerage message detailing why the order may not be submitted</param>
/// <returns>True if the brokerage could process the order, false otherwise</returns>
public override bool CanSubmitOrder(Security security, Order order, out BrokerageMessageEvent message)
{
message = null;

// validate security type
if (!DefaultMarketMap.ContainsKey(security.Type))
{
message = new BrokerageMessageEvent(BrokerageMessageType.Warning, "NotSupported",
Invariant($"The {nameof(AtreyuBrokerageModel)} does not support {security.Type} security type.")
);

return false;
}

// validate order type
if (!_supportedOrderTypes.Contains(order.Type))
{
message = new BrokerageMessageEvent(BrokerageMessageType.Warning, "NotSupported",
Invariant($"The {nameof(AtreyuBrokerageModel)} does not support {order.Type} order type.")
);

return false;
}

// validate time in force
if (!_supportedTimeInForces.Contains(order.TimeInForce.GetType()))
{
message = new BrokerageMessageEvent(BrokerageMessageType.Warning, "NotSupported",
Invariant($"The {nameof(AtreyuBrokerageModel)} does not support {order.TimeInForce.GetType().Name} time in force.")
);

return false;
}

// validate orders quantity
if (order.AbsoluteQuantity % 1 != 0)
{
message = new BrokerageMessageEvent(BrokerageMessageType.Warning, "NotSupported",
Invariant($"Order Quantity must be Integer, but provided {order.Quantity}.")
);

return false;
}

return true;
}

/// <summary>
/// Returns true if the brokerage would allow updating the order as specified by the request
/// </summary>
/// <param name="security">The security of the order</param>
/// <param name="order">The order to be updated</param>
/// <param name="request">The requested update to be made to the order</param>
/// <param name="message">If this function returns false, a brokerage message detailing why the order may not be updated</param>
/// <returns>True if the brokerage would allow updating the order, false otherwise</returns>
public override bool CanUpdateOrder(Security security, Order order, UpdateOrderRequest request, out BrokerageMessageEvent message)
{
message = null;

return true;
}
}
}
12 changes: 3 additions & 9 deletions Common/Brokerages/TradingTechnologiesBrokerageModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ public override bool CanSubmitOrder(Security security, Order order, out Brokerag
if (security.Type != SecurityType.Future)
{
message = new BrokerageMessageEvent(BrokerageMessageType.Warning, "NotSupported",
Invariant($"The {nameof(InteractiveBrokersBrokerageModel)} does not support {security.Type} security type.")
Invariant($"The {nameof(TradingTechnologiesBrokerageModel)} does not support {security.Type} security type.")
);

return false;
Expand All @@ -120,19 +120,13 @@ public override bool CanSubmitOrder(Security security, Order order, out Brokerag
if (!_supportedTimeInForces.Contains(order.TimeInForce.GetType()))
{
message = new BrokerageMessageEvent(BrokerageMessageType.Warning, "NotSupported",
Invariant($"The {nameof(InteractiveBrokersBrokerageModel)} does not support {order.TimeInForce.GetType().Name} time in force.")
Invariant($"The {nameof(TradingTechnologiesBrokerageModel)} does not support {order.TimeInForce.GetType().Name} time in force.")
);

return false;
}

// validate stop/limit orders prices
var limit = order as LimitOrder;
if (limit != null)
{
return IsValidOrderPrices(security, OrderType.Limit, limit.Direction, security.Price, limit.LimitPrice, ref message);
}

// validate stop orders prices
var stopMarket = order as StopMarketOrder;
if (stopMarket != null)
{
Expand Down
2 changes: 1 addition & 1 deletion Launcher/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@
"live-mode": true,

// real brokerage implementations require the BrokerageTransactionHandler
"live-mode-brokerage": "QuantConnect.Brokerages.Atreyu.AtreyuBrokerage",
"live-mode-brokerage": "QuantConnect.Atreyu.AtreyuBrokerage",
"data-queue-handler": "QuantConnect.Lean.Engine.DataFeeds.Queues.LiveDataQueue",
"setup-handler": "QuantConnect.Lean.Engine.Setup.BrokerageSetupHandler",
"result-handler": "QuantConnect.Lean.Engine.Results.LiveTradingResultHandler",
Expand Down

0 comments on commit c02ad0a

Please sign in to comment.