Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Addition of Interactive Brokers Algorithmic orders #1203

Closed
wants to merge 5 commits into from
Closed
@@ -0,0 +1,70 @@
/*
* 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 QuantConnect.Data.Market;

namespace QuantConnect.Algorithm.Examples
{
/// <summary>
/// This algorithm is used to benchmark the Lean engine data points per second
/// </summary>
/// <remarks>
/// date | commit | time (s) | K points/sec | Total points | Description
/// 15.04.09 | 9924b0a | 47.50 | 338 | ~16M | Update all securities prices before any events
/// 15.04.13 | 9acf934 | 45.77 | 350 | ~16M | Forex portfolio modelling
/// 15.04.23 | 6fd357b | 44.38 | 361 | ~16M | Adds support for dividends and splits
/// 15.04.24 | d80b173 | 43.18 | 372 | ~16M | Pre IB launch review
/// 15.04.24 | 8b4fc17 | 43.43 | 369 | ~16M | AlgorithmManager clean up
/// 15.04.30 | 9918628 | 43.11 | 372 | ~16M | Improve ObjectActivator performance
/// 15.04.30 | 49b398f | 43.02 | 373 | ~16M | DataStream sync at end of bar
/// </remarks>
public class BenchmarkAlgorithm : QCAlgorithm
{
/// <summary>
/// Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.
/// </summary>
public override void Initialize()
{
SetStartDate(2013, 09, 15); //Set Start Date
SetEndDate(2013, 10, 11); //Set End Date
SetCash(100000); //Set Strategy Cash
// Find more symbols here: http://quantconnect.com/data
AddSecurity(SecurityType.Equity, "SPY", Resolution.Tick);
AddSecurity(SecurityType.Equity, "AAPL", Resolution.Second);
AddSecurity(SecurityType.Equity, "ADBE", Resolution.Minute);
AddSecurity(SecurityType.Equity, "IBM", Resolution.Tick);
AddSecurity(SecurityType.Equity, "JNJ", Resolution.Second);
AddSecurity(SecurityType.Equity, "MSFT", Resolution.Minute);
AddSecurity(SecurityType.Forex, "EURUSD", Resolution.Tick);
AddSecurity(SecurityType.Forex, "EURGBP", Resolution.Second);
AddSecurity(SecurityType.Forex, "GBPUSD", Resolution.Minute);
AddSecurity(SecurityType.Forex, "USDJPY", Resolution.Tick);
AddSecurity(SecurityType.Forex, "NZDUSD", Resolution.Second);
}

/// <summary>
/// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
/// </summary>
/// <param name="data">TradeBars IDictionary object with your stock data</param>
public void OnData(TradeBars data)
{
if (!Portfolio.Invested)
{
SetHoldings("SPY", .75); // leave some room lest we experience a margin call!
Debug("Purchased Stock");
}
}
}
}
@@ -0,0 +1,71 @@
/*
* 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 QuantConnect.Data;
using QuantConnect.Orders;
using static QuantConnect.Orders.OrderExtras.IBExtras;

namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// Basic template algorithm simply initializes the date range and cash. This is a skeleton
/// framework you can use for designing an algorithm.
/// </summary>
/// <meta name="tag" content="using data" />
/// <meta name="tag" content="using quantconnect" />
/// <meta name="tag" content="trading and orders" />
public class OrderExtrasDemoAlgorithm : QCAlgorithm
{
private Symbol _spy = QuantConnect.Symbol.Create("SPY", SecurityType.Equity, Market.USA);

/// <summary>
/// Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.
/// </summary>
public override void Initialize()
{
SetStartDate(2013, 10, 07); //Set Start Date
SetEndDate(2013, 10, 11); //Set End Date
SetCash(100000); //Set Strategy Cash

// Find more symbols here: http://quantconnect.com/data
// Forex, CFD, Equities Resolutions: Tick, Second, Minute, Hour, Daily.
// Futures Resolution: Tick, Second, Minute
// Options Resolution: Minute Only.
AddEquity("SPY", Resolution.Minute);

// There are other assets with similar methods. See "Selecting Options" etc for more details.
// AddFuture, AddForex, AddCfd, AddOption
}

/// <summary>
/// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
/// </summary>
/// <param name="data">Slice object keyed by symbol containing the stock data</param>
public override void OnData(Slice data)
{
if (!Portfolio.Invested)
{
OrderExtras extras = new OrderExtras();
// Set the algorithm to be used in an Interactive Brokers live order
extras.InteractiveBrokers.Algorithm = OrderAlgorithm.AdaptiveAlgo;
// Add the parameters to be used for the algorithm
extras.InteractiveBrokers.AlgoParams.Add(new Parameter("adaptivePriority", "Normal"));
// Initiate a market order passing the extra parameters
MarketOrder(_spy, 100, true, "", extras);
Debug("Purchased Stock");
}
}
}
}
@@ -84,6 +84,8 @@
</ItemGroup>
<ItemGroup>
<Compile Include="AddRemoveSecurityRegressionAlgorithm.cs" />
<Compile Include="BasicTemplateAlgorithm.cs" />
<Compile Include="OrderExtrasDemoAlgorithm.cs" />
<Compile Include="RollingWindowAlgorithm.cs" />
<Compile Include="BasicTemplateDailyAlgorithm.cs" />
<Compile Include="BasicTemplateFxcmVolumeAlgorithm.cs" />
@@ -111,7 +113,6 @@
<Compile Include="PortfolioOptimizationNumericsAlgorithm.cs" />
<Compile Include="DailyFxAlgorithm.cs" />
<Compile Include="BasicTemplateForexAlgorithm.cs" />
<Compile Include="BasicTemplateAlgorithm.cs" />
<Compile Include="BasicTemplateOptionsAlgorithm.cs" />
<Compile Include="Benchmarks\EmptyMinute400EquityAlgorithm.cs" />
<Compile Include="Benchmarks\Symbols.cs" />
@@ -155,10 +155,11 @@ public OrderTicket Order(Symbol symbol, decimal quantity)
/// <param name="quantity">Number of shares to request.</param>
/// <param name="asynchronous">Send the order asynchrously (false). Otherwise we'll block until it fills</param>
/// <param name="tag">Place a custom order property or tag (e.g. indicator data).</param>
/// <seealso cref="MarketOrder(Symbol, decimal, bool, string)"/>
public OrderTicket Order(Symbol symbol, decimal quantity, bool asynchronous = false, string tag = "")
/// <param name="extras">Extra brokerage specific paramaters for live trading</param>
/// <seealso cref="MarketOrder(QuantConnect.Symbol, decimal, bool, string, OrderAlgorithm, List{AlgoParams})/>"/>
public OrderTicket Order(Symbol symbol, decimal quantity, bool asynchronous = false, string tag = "", OrderExtras extras = null)
{
return MarketOrder(symbol, quantity, asynchronous, tag);
return MarketOrder(symbol, quantity, asynchronous, tag, extras);
}

/// <summary>
@@ -168,10 +169,11 @@ public OrderTicket Order(Symbol symbol, decimal quantity, bool asynchronous = fa
/// <param name="quantity">Number of shares to request.</param>
/// <param name="asynchronous">Send the order asynchrously (false). Otherwise we'll block until it fills</param>
/// <param name="tag">Place a custom order property or tag (e.g. indicator data).</param>
/// <param name="extras">Extra brokerage specific paramaters for live trading</param>
/// <returns>int Order id</returns>
public OrderTicket MarketOrder(Symbol symbol, int quantity, bool asynchronous = false, string tag = "")
public OrderTicket MarketOrder(Symbol symbol, int quantity, bool asynchronous = false, string tag = "", OrderExtras extras = null)
{
return MarketOrder(symbol, (decimal)quantity, asynchronous, tag);
return MarketOrder(symbol, (decimal)quantity, asynchronous, tag, extras);
}

/// <summary>
@@ -181,10 +183,11 @@ public OrderTicket MarketOrder(Symbol symbol, int quantity, bool asynchronous =
/// <param name="quantity">Number of shares to request.</param>
/// <param name="asynchronous">Send the order asynchrously (false). Otherwise we'll block until it fills</param>
/// <param name="tag">Place a custom order property or tag (e.g. indicator data).</param>
/// <param name="extras">Extra brokerage specific paramaters for live trading</param>
/// <returns>int Order id</returns>
public OrderTicket MarketOrder(Symbol symbol, double quantity, bool asynchronous = false, string tag = "")
public OrderTicket MarketOrder(Symbol symbol, double quantity, bool asynchronous = false, string tag = "", OrderExtras extras = null)
{
return MarketOrder(symbol, (decimal)quantity, asynchronous, tag);
return MarketOrder(symbol, (decimal)quantity, asynchronous, tag, extras);
}

/// <summary>
@@ -194,8 +197,9 @@ public OrderTicket MarketOrder(Symbol symbol, double quantity, bool asynchronous
/// <param name="quantity">Number of shares to request.</param>
/// <param name="asynchronous">Send the order asynchrously (false). Otherwise we'll block until it fills</param>
/// <param name="tag">Place a custom order property or tag (e.g. indicator data).</param>
/// <param name="extras">Extra brokerage specific paramaters for live trading</param>
/// <returns>int Order id</returns>
public OrderTicket MarketOrder(Symbol symbol, decimal quantity, bool asynchronous = false, string tag = "")
public OrderTicket MarketOrder(Symbol symbol, decimal quantity, bool asynchronous = false, string tag = "", OrderExtras extras = null)
{
var security = Securities[symbol];

@@ -212,7 +216,7 @@ public OrderTicket MarketOrder(Symbol symbol, decimal quantity, bool asynchronou
return mooTicket;
}

var request = CreateSubmitOrderRequest(OrderType.Market, security, quantity, tag);
var request = CreateSubmitOrderRequest(OrderType.Market, security, quantity, tag, 0, 0, extras);

// If warming up, do not submit
if (IsWarmingUp)
@@ -725,7 +729,7 @@ private OrderResponse PreOrderChecksImpl(SubmitOrderRequest request)

if (security.Holdings.IsShort)
return OrderResponse.Error(request, OrderResponseErrorCode.UnsupportedRequestType, "The security with symbol '" + request.Symbol.ToString() + "' has a short option position. Only long option positions are exercisable.");

if (request.Quantity > security.Holdings.Quantity)
return OrderResponse.Error(request, OrderResponseErrorCode.UnsupportedRequestType, "Cannot exercise more contracts of '" + request.Symbol.ToString() + "' than is currently available in the portfolio. ");

@@ -832,10 +836,12 @@ public void SetMaximumOrders(int max)
/// <param name="symbol">string symbol we wish to hold</param>
/// <param name="percentage">double percentage of holdings desired</param>
/// <param name="liquidateExistingHoldings">liquidate existing holdings if neccessary to hold this stock</param>
/// <param name="tag">Tag the order with a short string.</param>
/// <param name="extras">Extra brokerage specific paramaters for live trading</param>
/// <seealso cref="MarketOrder"/>
public void SetHoldings(Symbol symbol, double percentage, bool liquidateExistingHoldings = false)
public void SetHoldings(Symbol symbol, double percentage, bool liquidateExistingHoldings = false, string tag = "", OrderExtras extras = null)
{
SetHoldings(symbol, (decimal)percentage, liquidateExistingHoldings);
SetHoldings(symbol, (decimal)percentage, liquidateExistingHoldings, tag, extras);
}

/// <summary>
@@ -845,10 +851,11 @@ public void SetHoldings(Symbol symbol, double percentage, bool liquidateExisting
/// <param name="percentage">float percentage of holdings desired</param>
/// <param name="liquidateExistingHoldings">bool liquidate existing holdings if neccessary to hold this stock</param>
/// <param name="tag">Tag the order with a short string.</param>
/// <param name="extras">Extra brokerage specific paramaters for live trading</param>
/// <seealso cref="MarketOrder"/>
public void SetHoldings(Symbol symbol, float percentage, bool liquidateExistingHoldings = false, string tag = "")
public void SetHoldings(Symbol symbol, float percentage, bool liquidateExistingHoldings = false, string tag = "", OrderExtras extras = null)
{
SetHoldings(symbol, (decimal)percentage, liquidateExistingHoldings, tag);
SetHoldings(symbol, (decimal)percentage, liquidateExistingHoldings, tag, extras);
}

/// <summary>
@@ -858,10 +865,12 @@ public void SetHoldings(Symbol symbol, float percentage, bool liquidateExistingH
/// <param name="percentage">float percentage of holdings desired</param>
/// <param name="liquidateExistingHoldings">bool liquidate existing holdings if neccessary to hold this stock</param>
/// <param name="tag">Tag the order with a short string.</param>
/// <param name="algorithm">Interactive Brokers algorithm to trade with</param>
/// <param name="algoparams">Parameters for an Interactive Brokers Algorithm order</param>
/// <seealso cref="MarketOrder"/>
public void SetHoldings(Symbol symbol, int percentage, bool liquidateExistingHoldings = false, string tag = "")
public void SetHoldings(Symbol symbol, int percentage, bool liquidateExistingHoldings = false, string tag = "", OrderExtras extras = null)
{
SetHoldings(symbol, (decimal)percentage, liquidateExistingHoldings, tag);
SetHoldings(symbol, (decimal)percentage, liquidateExistingHoldings, tag, extras);
}

/// <summary>
@@ -873,8 +882,9 @@ public void SetHoldings(Symbol symbol, int percentage, bool liquidateExistingHol
/// <param name="percentage">decimal fraction of portfolio to set stock</param>
/// <param name="liquidateExistingHoldings">bool flag to clean all existing holdings before setting new faction.</param>
/// <param name="tag">Tag the order with a short string.</param>
/// <param name="extras">Extra brokerage specific paramaters for live trading</param>
/// <seealso cref="MarketOrder"/>
public void SetHoldings(Symbol symbol, decimal percentage, bool liquidateExistingHoldings = false, string tag = "")
public void SetHoldings(Symbol symbol, decimal percentage, bool liquidateExistingHoldings = false, string tag = "", OrderExtras extras = null)
{
//Initialize Requirements:
Security security;
@@ -894,7 +904,7 @@ public void SetHoldings(Symbol symbol, decimal percentage, bool liquidateExistin
if (holdingSymbol != symbol && holdings.AbsoluteQuantity > 0)
{
//Go through all existing holdings [synchronously], market order the inverse quantity:
Order(holdingSymbol, -holdings.Quantity, false, tag);
Order(holdingSymbol, -holdings.Quantity, false, tag, extras);
}
}
}
@@ -903,7 +913,7 @@ public void SetHoldings(Symbol symbol, decimal percentage, bool liquidateExistin
var quantity = CalculateOrderQuantity(symbol, percentage);
if (Math.Abs(quantity) > 0)
{
MarketOrder(symbol, quantity, false, tag);
MarketOrder(symbol, quantity, false, tag, extras);
}
}

@@ -1060,9 +1070,10 @@ public bool IsMarketOpen(Symbol symbol)
return exchangeHours.IsOpen(time, false);
}

private SubmitOrderRequest CreateSubmitOrderRequest(OrderType orderType, Security security, decimal quantity, string tag, decimal stopPrice = 0m, decimal limitPrice = 0m)
private SubmitOrderRequest CreateSubmitOrderRequest(OrderType orderType, Security security, decimal quantity, string tag, decimal stopPrice = 0m, decimal limitPrice = 0m, OrderExtras extras = null)
{
return new SubmitOrderRequest(orderType, security.Type, security.Symbol, quantity, stopPrice, limitPrice, UtcTime, tag);
return new SubmitOrderRequest(orderType, security.Type, security.Symbol, quantity, stopPrice, limitPrice, UtcTime, tag, extras);
}

}
}
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.