Skip to content

Commit

Permalink
Add research node packet (#8360)
Browse files Browse the repository at this point in the history
  • Loading branch information
Martin-Molinero authored Oct 15, 2024
1 parent 8f57a8c commit ffdb615
Show file tree
Hide file tree
Showing 8 changed files with 111 additions and 9 deletions.
5 changes: 5 additions & 0 deletions Common/Api/Organization.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,11 @@ public class ProductItem
/// </summary>
[JsonProperty(PropertyName = "productId")]
public int Id { get; set; }

/// <summary>
/// Quantity for this product
/// </summary>
public int Quantity { get; set; }
}

/// <summary>
Expand Down
29 changes: 22 additions & 7 deletions Common/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -209,21 +209,36 @@ public static MarketHoursDatabase.Entry GetEntry(this MarketHoursDatabase market
/// <param name="jsonArray">The value to deserialize</param>
public static List<string> DeserializeList(this string jsonArray)
{
List<string> result = new();
return DeserializeList<string>(jsonArray);
}

/// <summary>
/// Helper method to deserialize a json array into a list also handling single json values
/// </summary>
/// <param name="jsonArray">The value to deserialize</param>
public static List<T> DeserializeList<T>(this string jsonArray)
{
try
{
if (string.IsNullOrEmpty(jsonArray))
{
return result;
return new();
}
result = JsonConvert.DeserializeObject<List<string>>(jsonArray);
return JsonConvert.DeserializeObject<List<T>>(jsonArray);
}
catch(JsonReaderException)
catch (Exception ex)
{
result.Add(jsonArray);
}
if (ex is not JsonReaderException && ex is not JsonSerializationException)
{
throw;
}

return result;
if (typeof(T) == typeof(string))
{
return new List<T> { (T)Convert.ChangeType(jsonArray, typeof(T), CultureInfo.InvariantCulture) };
}
return new List<T> { JsonConvert.DeserializeObject<T>(jsonArray) };
}
}

/// <summary>
Expand Down
7 changes: 6 additions & 1 deletion Common/Global.cs
Original file line number Diff line number Diff line change
Expand Up @@ -990,7 +990,12 @@ public enum DeploymentTarget
/// <summary>
/// Local Platform (1)
/// </summary>
LocalPlatform
LocalPlatform,

/// <summary>
/// Private Cloud Platform (2)
/// </summary>
PrivateCloudPlatform
}

/// <summary>
Expand Down
4 changes: 4 additions & 0 deletions Common/Packets/AlgorithmNodePacket.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ public string AlgorithmId
{
return ((LiveNodePacket)this).DeployId;
}
else if (Type == PacketType.ResearchNode)
{
return ((ResearchNodePacket)this).ResearchId;
}
return ((BacktestNodePacket)this).BacktestId;
}
}
Expand Down
3 changes: 3 additions & 0 deletions Common/Packets/Packet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -191,5 +191,8 @@ public enum PacketType

/// Algorithm tags update
AlgorithmTagsUpdate,

/// Research job packet
ResearchNode,
}
}
41 changes: 41 additions & 0 deletions Common/Packets/ResearchNodePacket.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* 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.
*
*/

namespace QuantConnect.Packets
{
/// <summary>
/// Represents a research node packet
/// </summary>
public class ResearchNodePacket : AlgorithmNodePacket
{
/// <summary>
/// The research id
/// </summary>
public string ResearchId { get; set; }

/// <summary>
/// Associated research token
/// </summary>
public string ResearchToken { get; set; }

/// <summary>
/// Creates a new instance
/// </summary>
public ResearchNodePacket() : base(PacketType.ResearchNode)
{
}
}
}
2 changes: 1 addition & 1 deletion Common/Util/Composer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ public T GetExportedValueByTypeName<T>(string typeName, bool forceTypeNameOnExis
if (selectedPart == null)
{
throw new ArgumentException(
$"Unable to locate any exports matching the requested typeName: {typeName}", nameof(typeName));
$"Unable to locate any exports matching the requested typeName: {typeName}. Type: {type}", nameof(typeName));
}

var exportDefinition =
Expand Down
29 changes: 29 additions & 0 deletions Tests/Common/Util/ExtensionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,35 @@ namespace QuantConnect.Tests.Common.Util
[TestFixture]
public class ExtensionsTests
{
[TestCase("A test", 1)]
[TestCase("[\"A test\"]", 1)]
[TestCase("[\"A test\", \"something else\"]", 2)]
public void DeserializeList(string input, int count)
{
var result = input.DeserializeList();
Assert.AreEqual(count, result.Count);
Assert.AreEqual("A test", result[0]);
if (count == 2)
{
Assert.AreEqual("something else", result[1]);
}
}

private class DeserializeListObject { public int Property { get; set; } }
[TestCase("{ \"property\": 10}", 1)]
[TestCase("[{ \"property\": 10}]", 1)]
[TestCase("[{ \"property\": 10}, { \"property\": 20 }]", 2)]
public void DeserializeObjectList(string input, int count)
{
var result = input.DeserializeList<DeserializeListObject>();
Assert.AreEqual(count, result.Count);
Assert.AreEqual(10, result[0].Property);
if (count == 2)
{
Assert.AreEqual(20, result[1].Property);
}
}

[TestCase(true)]
[TestCase(false)]
public void ConvertPythonSymbolEnumerableSingle(bool useSymbol)
Expand Down

0 comments on commit ffdb615

Please sign in to comment.