Compare commits

...

1 Commits
13402 ... 12342

Author SHA1 Message Date
Martin-Molinero
d84f563c07 Alpha holdings state
- Alpha result packet will optionally provide the algorithms portfolio
  state
2021-07-14 20:22:25 -03:00
5 changed files with 150 additions and 19 deletions

View File

@@ -342,6 +342,12 @@ namespace QuantConnect
resultPacket.Orders = resultPacket.Orders.GroupBy(order => order.Id)
.Select(ordersGroup => ordersGroup.Last()).ToList();
}
if (newerPacket.Portfolio != null)
{
// we just keep the newest state if not null
resultPacket.Portfolio = newerPacket.Portfolio;
}
}
}
return resultPacket;

View File

@@ -1,4 +1,4 @@
/*
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
@@ -14,15 +14,11 @@
*
*/
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.2 Copyright 2015 QuantConnect Corporation.
*/
using System.Collections.Generic;
using Newtonsoft.Json;
using QuantConnect.Algorithm.Framework.Alphas;
using QuantConnect.Orders;
using QuantConnect.Securities;
using System.Collections.Generic;
using QuantConnect.Algorithm.Framework.Alphas;
namespace QuantConnect.Packets
{
@@ -68,6 +64,12 @@ namespace QuantConnect.Packets
[JsonProperty("orders", DefaultValueHandling = DefaultValueHandling.Ignore)]
public List<Order> Orders { get; set; }
/// <summary>
/// The algorithms current portfolio state
/// </summary>
[JsonProperty("portfolio", DefaultValueHandling = DefaultValueHandling.Ignore)]
public SecurityPortfolioState Portfolio { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="AlphaResultPacket"/> class
/// </summary>
@@ -84,7 +86,8 @@ namespace QuantConnect.Packets
/// <param name="insights">Alphas generated by the algorithm</param>
/// <param name="orderEvents">OrderEvents generated by the algorithm</param>
/// <param name="orders">Orders generated or updated by the algorithm</param>
public AlphaResultPacket(string algorithmId, int userId, List<Insight> insights = null, List<OrderEvent> orderEvents = null, List<Order> orders = null)
/// <param name="portfolio">The algorithms current portfolio state</param>
public AlphaResultPacket(string algorithmId, int userId, List<Insight> insights = null, List<OrderEvent> orderEvents = null, List<Order> orders = null, SecurityPortfolioState portfolio = null)
: base(PacketType.AlphaResult)
{
UserId = userId;
@@ -92,6 +95,7 @@ namespace QuantConnect.Packets
Insights = insights;
OrderEvents = orderEvents;
Orders = orders;
Portfolio = portfolio;
}
}
}

View File

@@ -26,14 +26,6 @@ namespace QuantConnect.Securities
/// </summary>
public class CashBuyingPowerModel : BuyingPowerModel
{
/// <summary>
/// Initializes a new instance of the <see cref="CashBuyingPowerModel"/> class
/// </summary>
public CashBuyingPowerModel()
: base(1m, 0m, 0m)
{
}
/// <summary>
/// Gets the current leverage of the security
/// </summary>

View File

@@ -0,0 +1,128 @@
/*
* 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 Newtonsoft.Json;
using System.Collections.Generic;
using QuantConnect.Securities.Positions;
namespace QuantConnect.Securities
{
/// <summary>
/// Snapshot of an algorithms portfolio state
/// </summary>
public class SecurityPortfolioState
{
/// <summary>
/// Portfolio state id
/// </summary>
public int Id { get; set; }
/// <summary>
/// Algorithms account currency
/// </summary>
public string AccountCurrency { get; set; }
/// <summary>
/// The utc time this state was captured
/// </summary>
public DateTime UtcTime { get; set; }
/// <summary>
/// The current total portfolio value
/// </summary>
public decimal TotalPortfolioValue { get; set; }
/// <summary>
/// The margin used
/// </summary>
public decimal TotalMarginUsed { get; set; }
/// <summary>
/// The different positions groups
/// </summary>
[JsonProperty("positionGroups", DefaultValueHandling = DefaultValueHandling.Ignore)]
public List<PositionGroupState> PositionGroups { get; set; }
/// <summary>
/// Gets the cash book that keeps track of all currency holdings (only settled cash)
/// </summary>
[JsonProperty("cashBook", DefaultValueHandling = DefaultValueHandling.Ignore)]
public Dictionary<string, Cash> CashBook { get; set; }
/// <summary>
/// Gets the cash book that keeps track of all currency holdings (only unsettled cash)
/// </summary>
[JsonProperty("unsettledCashBook", DefaultValueHandling = DefaultValueHandling.Ignore)]
public Dictionary<string, Cash> UnsettledCashBook { get; set; }
}
/// <summary>
/// Snapshot of a position group state
/// </summary>
public class PositionGroupState
{
/// <summary>
/// Currently margin used
/// </summary>
public decimal MarginUsed { get; set; }
/// <summary>
/// The margin used by this position in relation to the total portfolio value
/// </summary>
public decimal PortfolioValuePercentage { get; set; }
/// <summary>
/// THe positions which compose this group
/// </summary>
public List<PositionState> Positions { get; set; }
}
/// <summary>
/// Snapshot of a position state
/// </summary>
public class PositionState : IPosition
{
/// <summary>
/// The symbol
/// </summary>
public Symbol Symbol { get; set; }
/// <summary>
/// The quantity
/// </summary>
public decimal Quantity { get; set; }
/// <summary>
/// The unit quantity. The unit quantities of a group define the group. For example, a covered
/// call has 100 units of stock and -1 units of call contracts.
/// </summary>
public decimal UnitQuantity { get; set; }
/// <summary>
/// Creates a new instance
/// </summary>
public static PositionState Create(IPosition position)
{
return new PositionState
{
Symbol = position.Symbol,
Quantity = position.Quantity,
UnitQuantity = position.UnitQuantity
};
}
}
}

View File

@@ -67,15 +67,16 @@ namespace QuantConnect.Tests.Common.Util
};
var orders = new List<Order> { new MarketOrder(btcusd, 1000, DateTime.UtcNow, "ExpensiveOrder") { Id = 1 } };
var packet1 = new AlphaResultPacket("1", 1, insights: insights);
var packet1 = new AlphaResultPacket("1", 1, insights: insights, portfolio: new SecurityPortfolioState { TotalPortfolioValue = 11 });
var packet2 = new AlphaResultPacket("1", 1, orders: orders);
var packet3 = new AlphaResultPacket("1", 1, orderEvents: orderEvents);
var packet3 = new AlphaResultPacket("1", 1, orderEvents: orderEvents, portfolio: new SecurityPortfolioState { TotalPortfolioValue = 12 });
var result = new List<AlphaResultPacket> { packet1, packet2, packet3 }.Batch();
Assert.AreEqual(2, result.Insights.Count);
Assert.AreEqual(2, result.OrderEvents.Count);
Assert.AreEqual(1, result.Orders.Count);
Assert.AreEqual(12, result.Portfolio.TotalPortfolioValue);
Assert.IsTrue(result.Insights.SequenceEqual(insights));
Assert.IsTrue(result.OrderEvents.SequenceEqual(orderEvents));