64349fea13
After much review, it was determined that this was much more confusing than it was helpful. The removed implementation hinged on the thinking that the construction model would be emitting targets as quantities of cash and not quantities of virtual positions. A previous commit added a warning message for cash modelling and this commit removes a (bad) attempt at making cash modelling work as expected. For now, if you want to use cash modelling with the algorithm framework, careful thought will need to be applied to the implementation of the portofio construction model AND the execution model. They'll each need to be speaking on the same terms. As of this point, we're unsure of a means to address all concerns, and so are leaving it as a warning message coupled with decent documentation in the commit history regarding our discussions/thoughts on the topics. Again, the key for cash modelling working properly is just that the portfolio construction model and the execution model agree on what each target means and also agree on how virual positions vs currency balances are handled and managed.
80 lines
3.4 KiB
C#
80 lines
3.4 KiB
C#
/*
|
|
* 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.Linq;
|
|
using QuantConnect.Algorithm.Framework.Portfolio;
|
|
using QuantConnect.Securities;
|
|
|
|
namespace QuantConnect.Algorithm.Framework.Execution
|
|
{
|
|
/// <summary>
|
|
/// Provides methods for computing a maximum order size.
|
|
/// </summary>
|
|
public static class OrderSizing
|
|
{
|
|
/// <summary>
|
|
/// Gets the maximum order size as a percentage of the current bar's volume.
|
|
/// </summary>
|
|
/// <param name="security">The security object</param>
|
|
/// <param name="maximumPercentCurrentVolume">The maximum percentage of the current bar's volume</param>
|
|
/// <returns>The fractional quantity of shares that equal the specified percentage of the current bar's volume</returns>
|
|
public static decimal PercentVolume(Security security, decimal maximumPercentCurrentVolume)
|
|
{
|
|
return maximumPercentCurrentVolume * security.Volume;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the maximum order size using a maximum order value in units of the account currency
|
|
/// </summary>
|
|
/// <param name="security">The security object</param>
|
|
/// <param name="maximumOrderValueInAccountCurrency">The maximum order value in units of the account currency</param>
|
|
/// <returns>The quantity of fractional of shares that yield the specified maximum order value</returns>
|
|
public static decimal Value(Security security, decimal maximumOrderValueInAccountCurrency)
|
|
{
|
|
var priceInAccountCurrency = security.Price * security.QuoteCurrency.ConversionRate;
|
|
|
|
if (priceInAccountCurrency == 0m)
|
|
{
|
|
return 0m;
|
|
}
|
|
|
|
return maximumOrderValueInAccountCurrency / priceInAccountCurrency;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the remaining quantity to be ordered to reach the specified target quantity.
|
|
/// </summary>
|
|
/// <param name="algorithm">The algorithm instance</param>
|
|
/// <param name="target">The portfolio target</param>
|
|
/// <returns>The remaining quantity to be ordered</returns>
|
|
public static decimal GetUnorderedQuantity(QCAlgorithmFramework algorithm, IPortfolioTarget target)
|
|
{
|
|
var security = algorithm.Securities[target.Symbol];
|
|
var holdings = security.Holdings.Quantity;
|
|
var openOrderQuantity = algorithm.Transactions.GetOpenOrders(target.Symbol).Sum(o => o.Quantity);
|
|
var quantity = target.Quantity - holdings - openOrderQuantity;
|
|
|
|
// check if we're below the lot size threshold
|
|
if (Math.Abs(quantity) < security.SymbolProperties.LotSize)
|
|
{
|
|
return 0m;
|
|
}
|
|
|
|
return quantity;
|
|
}
|
|
}
|
|
}
|