diff --git a/Algorithm.CSharp/Collective2SignalExportDemonstrationAlgorithm.cs b/Algorithm.CSharp/Collective2SignalExportDemonstrationAlgorithm.cs index d556e7e32d35..9b59b1072ae0 100644 --- a/Algorithm.CSharp/Collective2SignalExportDemonstrationAlgorithm.cs +++ b/Algorithm.CSharp/Collective2SignalExportDemonstrationAlgorithm.cs @@ -49,13 +49,13 @@ public class Collective2SignalExportDemonstrationAlgorithm : QCAlgorithm, IRegre private bool _firstCall = true; private PortfolioTarget[] _targets = new PortfolioTarget[4]; - + /// /// Symbols accepted by Collective2. Collective2 accepts stock, /// future, forex and US stock option symbols /// private List _symbols = new() - { + { QuantConnect.Symbol.Create("SPY", SecurityType.Equity, Market.USA, null, null), QuantConnect.Symbol.Create("EURUSD", SecurityType.Forex, Market.Oanda, null, null), QuantConnect.Symbol.CreateFuture("ES", Market.CME, new DateTime(2023, 12, 15), null), @@ -95,15 +95,19 @@ public override void Initialize() // Initialize this flag, to check when the ema indicators crosses between themselves _emaFastIsNotSet = true; - // Set Collective2 signal export provider + // Set Collective2 signal export provider. + // If using the Collective2 white-label API, you can specify it in the constructor with the optional parameter `useWhiteLabelApi`: + // e.g. new Collective2SignalExport(_collective2ApiKey, _collective2SystemId, useWhiteLabelApi: true) + // The API url can also be overridden by setting the Destination property: + // e.g. new Collective2SignalExport(_collective2ApiKey, _collective2SystemId) { Destination = new Uri("your url") } SignalExport.AddSignalExportProviders(new Collective2SignalExport(_collective2ApiKey, _collective2SystemId)); SetWarmUp(100); } /// - /// Reduce the quantity of holdings for SPY or increase it, depending the case, - /// when the EMA's indicators crosses between themselves, then send a signal to + /// Reduce the quantity of holdings for SPY or increase it, depending the case, + /// when the EMA's indicators crosses between themselves, then send a signal to /// Collective2 API /// /// diff --git a/Algorithm.Python/Collective2SignalExportDemonstrationAlgorithm.py b/Algorithm.Python/Collective2SignalExportDemonstrationAlgorithm.py index 10a1b6b2c2c0..4a670cecb50d 100644 --- a/Algorithm.Python/Collective2SignalExportDemonstrationAlgorithm.py +++ b/Algorithm.Python/Collective2SignalExportDemonstrationAlgorithm.py @@ -61,6 +61,10 @@ def initialize(self): # Collective2 System ID: This value is found beside the system's name (strategy's name) on the main system page self.collective2_system_id = 0 + # If using the Collective2 white-label API, you can specify it in the constructor with the optional parameter `use_white_label_api`: + # e.g. Collective2SignalExport(self.collective2_apikey, self.collective2_system_id, use_white_label_api=True) + # The API url can also be overridden by setting the Destination property: + # e.g. Collective2SignalExport(self.collective2_apikey, self.collective2_system_id) { Destination = new Uri("your url") } self.signal_export.add_signal_export_providers(Collective2SignalExport(self.collective2_apikey, self.collective2_system_id)) self.first_call = True diff --git a/Common/Algorithm/Framework/Portfolio/SignalExports/Collective2SignalExport.cs b/Common/Algorithm/Framework/Portfolio/SignalExports/Collective2SignalExport.cs index cc496ce0bf44..71da9770d39d 100644 --- a/Common/Algorithm/Framework/Portfolio/SignalExports/Collective2SignalExport.cs +++ b/Common/Algorithm/Framework/Portfolio/SignalExports/Collective2SignalExport.cs @@ -41,11 +41,6 @@ public class Collective2SignalExport : BaseSignalExport /// private readonly int _systemId; - /// - /// Collective2 API endpoint - /// - private readonly Uri _destination; - /// /// Algorithm being ran /// @@ -56,6 +51,11 @@ public class Collective2SignalExport : BaseSignalExport /// private bool _isZeroPriceWarningPrinted; + /// + /// Collective2 API endpoint + /// + public Uri Destination { get; set; } + /// /// The name of this signal export /// @@ -83,18 +83,21 @@ public class Collective2SignalExport : BaseSignalExport /// /// API key provided by Collective2 /// Trading system's ID number - public Collective2SignalExport(string apiKey, int systemId) + /// Whether to use the white-label API instead of the general one + public Collective2SignalExport(string apiKey, int systemId, bool useWhiteLabelApi = false) { _apiKey = apiKey; _systemId = systemId; - _destination = new Uri("https://api4-general.collective2.com/Strategies/SetDesiredPositions"); + Destination = new Uri(useWhiteLabelApi + ? "https://api4-wl.collective2.com/Strategies/SetDesiredPositions" + : "https://api4-general.collective2.com/Strategies/SetDesiredPositions"); } /// /// Creates a JSON message with the desired positions using the expected /// Collective2 API format and then sends it /// - /// A list of holdings from the portfolio + /// A list of holdings from the portfolio /// expected to be sent to Collective2 API and the algorithm being ran /// True if the positions were sent correctly and Collective2 sent no errors, false otherwise public override bool Send(SignalExportTargetParameters parameters) @@ -120,7 +123,7 @@ public override bool Send(SignalExportTargetParameters parameters) /// /// Converts a list of targets to a list of Collective2 positions /// - /// A list of targets from the portfolio + /// A list of targets from the portfolio /// expected to be sent to Collective2 API and the algorithm being ran /// A list of Collective2 positions /// True if the given targets could be converted to a Collective2Position list, false otherwise @@ -266,7 +269,7 @@ private bool SendPositions(string message) HttpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", _apiKey); //Send the message - using HttpResponseMessage response = HttpClient.PostAsync(_destination, httpMessage).Result; + using HttpResponseMessage response = HttpClient.PostAsync(Destination, httpMessage).Result; //Parse it var responseObject = response.Content.ReadFromJsonAsync().Result; @@ -333,7 +336,7 @@ private class ResponseStatus { /* Example: - "ResponseStatus": + "ResponseStatus": { "ErrorCode": ""401", "Message": ""Unauthorized",