/* * 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 Python.Runtime; using QuantConnect.Data; using QuantConnect.Data.UniverseSelection; using System; using System.Collections.Generic; using QuantConnect.Python; namespace QuantConnect.Algorithm.Framework.Alphas { /// /// Provides an implementation of that wraps a object /// public class AlphaModelPythonWrapper : AlphaModel { private readonly BasePythonWrapper _model; /// /// Defines a name for a framework model /// public override string Name { get { using (Py.GIL()) { // if the model defines a Name property then use that if (_model.HasAttr(nameof(Name))) { return _model.GetProperty(nameof(Name)); } // if the model does not define a name property, use the python type name return _model.GetProperty(" __class__" ).GetAttr("__name__").GetAndDispose(); } } } /// /// Constructor for initialising the class with wrapped object /// /// >Model that generates alpha public AlphaModelPythonWrapper(PyObject model) { _model = new BasePythonWrapper(model, false); foreach (var attributeName in new[] { "Update", "OnSecuritiesChanged" }) { if (!_model.HasAttr(attributeName)) { throw new NotImplementedException($"IAlphaModel.{attributeName} must be implemented. Please implement this missing method on {model.GetPythonType()}"); } } } /// /// Updates this alpha model with the latest data from the algorithm. /// This is called each time the algorithm receives data for subscribed securities /// /// The algorithm instance /// The new data available /// The new insights generated public override IEnumerable Update(QCAlgorithm algorithm, Slice data) { return _model.InvokeMethodAndEnumerate(nameof(Update), algorithm, data); } /// /// Event fired each time the we add/remove securities from the data feed /// /// The algorithm instance that experienced the change in securities /// The security additions and removals from the algorithm public override void OnSecuritiesChanged(QCAlgorithm algorithm, SecurityChanges changes) { _model.InvokeVoidMethod(nameof(OnSecuritiesChanged), algorithm, changes); } } }