/* * 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.Algorithm.Framework.Portfolio; using QuantConnect.Algorithm.Framework.Portfolio.SignalExports; using QuantConnect.Securities; using System.Collections.Generic; using QuantConnect.Data.UniverseSelection; using System.Linq; namespace QuantConnect.Algorithm.CSharp { /// /// This algorithm sends an array of current portfolio targets to Numerai API /// every time the ema indicators crosses between themselves. /// See (https://docs.numer.ai/numerai-signals/signals-overview) for more information /// about accepted symbols, signals, etc. /// /// /// /// public class NumeraiSignalExportDemonstrationAlgorithm : QCAlgorithm { private readonly List _securities = new(); private Symbol _etfSymbol; public override void Initialize() { SetStartDate(2020, 10, 7); // Set Start Date SetEndDate(2020, 10, 12); // Set End Date SetCash(100000); // Set Strategy Cash SetSecurityInitializer(new BrokerageModelSecurityInitializer(BrokerageModel, new FuncSecuritySeeder(GetLastKnownPrices))); // Add the CRSP US Total Market Index constituents, which represents approximately 100% of the investable US Equity market _etfSymbol = AddEquity("VTI").Symbol; AddUniverse(Universe.ETF(_etfSymbol)); // Create a Scheduled Event to submit signals every trading day at 13:00 UTC Schedule.On(DateRules.EveryDay(_etfSymbol), TimeRules.At(13, 0, TimeZones.Utc), SubmitSignals); // Add the Numerai signal export provider // Numerai Public ID: This value is provided by Numerai Signals in their main webpage once you've logged in // and created a API key. See (https://signals.numer.ai/account) var numeraiPublicId = ""; // Numerai Secret ID: This value is provided by Numerai Signals in their main webpage once you've logged in // and created a API key. See (https://signals.numer.ai/account) var numeraiSecretId = ""; // Numerai Model ID: This value is provided by Numerai Signals in their main webpage once you've logged in // and created a model. See (https://signals.numer.ai/models) var numeraiModelId = ""; var numeraiFilename = ""; // (Optional) Replace this value with your submission filename // Disable automatic exports as we manually set them SignalExport.AutomaticExportTimeSpan = null; // Set Numerai signal export provider SignalExport.AddSignalExportProvider(new NumeraiSignalExport(numeraiPublicId, numeraiSecretId, numeraiModelId, numeraiFilename)); } public void SubmitSignals() { // Select the subset of ETF constituents we can trade var symbols = _securities.Where(security => security.HasData) .Select(security => security.Symbol) .OrderBy(symbol => symbol) .ToList(); if (symbols.Count == 0) { return; } // Get historical data // var history = History(symbols, 22, Resolution.Daily); // Create portfolio targets // Numerai requires that at least one of the signals have a unique weight // To ensure they are all unique, this demo gives a linear allocation to each symbol (ie. 1/55, 2/55, ..., 10/55) var denominator = symbols.Count * (symbols.Count + 1) / 2.0m; // sum of 1, 2, ..., symbols.Count var targets = symbols.Select((symbol, i) => new PortfolioTarget(symbol, (i + 1) / denominator)).ToList(); // (Optional) Place trades SetHoldings(targets); // Send signals to Numerai var success = SignalExport.SetTargetPortfolio(targets.ToArray()); if (!success) { Debug($"Couldn't send targets at {Time}"); } } public override void OnSecuritiesChanged(SecurityChanges changes) { foreach (var security in changes.RemovedSecurities) { if (_securities.Contains(security)) { _securities.Remove(security); } } foreach (var security in changes.AddedSecurities) { if (security.Symbol != _etfSymbol) { _securities.Add(security); } } } } }