/* * 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 NodaTime; using QuantConnect.Benchmarks; using QuantConnect.Brokerages; using QuantConnect.Data; using QuantConnect.Data.UniverseSelection; using QuantConnect.Interfaces; using QuantConnect.Notifications; using QuantConnect.Orders; using QuantConnect.Scheduling; using QuantConnect.Securities; using QuantConnect.Statistics; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using Python.Runtime; using ImpromptuInterface; namespace QuantConnect.Python.Wrappers { /// /// Wrapper for an IAlgorithm instance created in Python. /// All calls to python should be inside a "using (Py.GIL()) {/* Your code here */}" block. /// public class AlgorithmPythonWrapper : IAlgorithm { private IAlgorithm _algorithm; private IBenchmark _benchmark; private IBrokerageModel _brokerageModel; private IHistoryProvider _historyProvider; private ITradeBuilder _tradeBuilder; private dynamic _pyAlgorithm; /// /// constructor. /// Creates and wraps the algorithm written in python. /// /// Python module with the algorithm written in Python public AlgorithmPythonWrapper(PyObject module) { _algorithm = null; try { using (Py.GIL()) { if (!module.HasAttr("QCAlgorithm")) { return; } var baseClass = module.GetAttr("QCAlgorithm"); // Load module with util methods var onPythonData = Py.Import("AlgorithmPythonUtil").GetAttr("OnPythonData"); var moduleName = module.Repr().Split('\'')[1]; foreach (var name in module.Dir()) { var attr = module.GetAttr(name.ToString()); if (attr.IsSubclass(baseClass) && attr.Repr().Contains(moduleName)) { attr.SetAttr("OnPythonData", onPythonData); _pyAlgorithm = attr.Invoke(); _algorithm = Impromptu.ActLike(_pyAlgorithm); return; } } } } catch (Exception e) { Logging.Log.Error(e); } } /// /// Wrapper for in Python /// public string AlgorithmId { get { using (Py.GIL()) { return _algorithm.AlgorithmId; } } } /// /// Wrapper for in Python /// public IBenchmark Benchmark { get { using (Py.GIL()) { if (_benchmark == null) { _benchmark = new BenchmarkPythonWrapper(_algorithm.Benchmark); } return _benchmark; } } } /// /// Wrapper for in Python /// public IBrokerageMessageHandler BrokerageMessageHandler { get { using (Py.GIL()) { return _algorithm.BrokerageMessageHandler; } } set { SetBrokerageMessageHandler(value); } } /// /// Wrapper for in Python /// public IBrokerageModel BrokerageModel { get { using (Py.GIL()) { if (_brokerageModel == null) { _brokerageModel = new BrokerageModelPythonWrapper(_algorithm.BrokerageModel); } return _brokerageModel; } } } /// /// Wrapper for in Python /// public ConcurrentQueue DebugMessages { get { using (Py.GIL()) { return _algorithm.DebugMessages; } } } /// /// Wrapper for in Python /// public DateTime EndDate { get { using (Py.GIL()) { return _algorithm.EndDate; } } } /// /// Wrapper for in Python /// public ConcurrentQueue ErrorMessages { get { using (Py.GIL()) { return _algorithm.ErrorMessages; } } } /// /// Wrapper for in Python /// public IHistoryProvider HistoryProvider { get { using (Py.GIL()) { if (_historyProvider == null) { _historyProvider = new HistoryProviderPythonWrapper(_algorithm.HistoryProvider); } return _historyProvider; } } set { SetHistoryProvider(value); } } /// /// Wrapper for in Python /// public bool IsWarmingUp { get { using (Py.GIL()) { return _algorithm.IsWarmingUp; } } } /// /// Wrapper for in Python /// public bool LiveMode { get { using (Py.GIL()) { return _algorithm.LiveMode; } } } /// /// Wrapper for in Python /// public ConcurrentQueue LogMessages { get { using (Py.GIL()) { return _algorithm.LogMessages; } } } /// /// Wrapper for in Python /// public string Name { get { using (Py.GIL()) { return _algorithm.Name; } } } /// /// Wrapper for in Python /// public NotificationManager Notify { get { using (Py.GIL()) { return _algorithm.Notify; } } } /// /// Wrapper for in Python /// public SecurityPortfolioManager Portfolio { get { using (Py.GIL()) { return _algorithm.Portfolio; } } } /// /// Wrapper for in Python /// public Exception RunTimeError { get { using (Py.GIL()) { return _algorithm.RunTimeError; } } set { SetRunTimeError(value); } } /// /// Wrapper for in Python /// public Dictionary RuntimeStatistics { get { using (Py.GIL()) { return _algorithm.RuntimeStatistics; } } } /// /// Wrapper for in Python /// public ScheduleManager Schedule { get { using (Py.GIL()) { return _algorithm.Schedule; } } } /// /// Wrapper for in Python /// public SecurityManager Securities { get { using (Py.GIL()) { return _algorithm.Securities; } } } /// /// Wrapper for in Python /// public ISecurityInitializer SecurityInitializer { get { using (Py.GIL()) { return _algorithm.SecurityInitializer; } } } /// /// Wrapper for in Python /// public ITradeBuilder TradeBuilder { get { using (Py.GIL()) { if (_tradeBuilder == null) { _tradeBuilder = new TradeBuilderPythonWrapper(_algorithm.TradeBuilder); } return _tradeBuilder; } } } /// /// Wrapper for in Python /// public DateTime StartDate { get { using (Py.GIL()) { return _algorithm.StartDate; } } } /// /// Wrapper for in Python /// public AlgorithmStatus Status { get { using (Py.GIL()) { return _algorithm.Status; } } set { SetStatus(value); } } /// /// Wrapper for in Python /// /// public void SetStatus(AlgorithmStatus value) { using (Py.GIL()) { _algorithm.SetStatus(value); } } /// /// Wrapper for in Python /// /// public void SetAvailableDataTypes(Dictionary> availableDataTypes) { using (Py.GIL()) { _algorithm.SetAvailableDataTypes(availableDataTypes); } } /// /// Wrapper for in Python /// public SubscriptionManager SubscriptionManager { get { using (Py.GIL()) { return _algorithm.SubscriptionManager; } } } /// /// Wrapper for in Python /// public DateTime Time { get { using (Py.GIL()) { return _algorithm.Time; } } } /// /// Wrapper for in Python /// public DateTimeZone TimeZone { get { using (Py.GIL()) { return _algorithm.TimeZone; } } } /// /// Wrapper for in Python /// public SecurityTransactionManager Transactions { get { using (Py.GIL()) { return _algorithm.Transactions; } } } /// /// Wrapper for in Python /// public UniverseManager UniverseManager { get { using (Py.GIL()) { return _algorithm.UniverseManager; } } } /// /// Wrapper for in Python /// public UniverseSettings UniverseSettings { get { using (Py.GIL()) { return _algorithm.UniverseSettings; } } } /// /// Wrapper for in Python /// public DateTime UtcTime { get { using (Py.GIL()) { return _algorithm.UtcTime; } } } /// /// Wrapper for in Python /// /// /// /// /// /// /// /// /// public Security AddSecurity(SecurityType securityType, string symbol, Resolution resolution, string market, bool fillDataForward, decimal leverage, bool extendedMarketHours) { using (Py.GIL()) { return _algorithm.AddSecurity(securityType, symbol, resolution, market, fillDataForward, leverage, extendedMarketHours); } } /// /// Wrapper for in Python /// /// public void Debug(string message) { using (Py.GIL()) { _algorithm.Debug(message); } } /// /// Wrapper for in Python /// /// public void Error(string message) { using (Py.GIL()) { _algorithm.Error(message); } } /// /// Wrapper for in Python /// /// /// public List GetChartUpdates(bool clearChartData = false) { using (Py.GIL()) { return _algorithm.GetChartUpdates(clearChartData); } } /// /// Wrapper for in Python /// /// public bool GetLocked() { using (Py.GIL()) { return _algorithm.GetLocked(); } } /// /// Wrapper for in Python /// /// /// public string GetParameter(string name) { using (Py.GIL()) { return _algorithm.GetParameter(name); } } /// /// Wrapper for in Python /// /// public IEnumerable GetWarmupHistoryRequests() { using (Py.GIL()) { return _algorithm.GetWarmupHistoryRequests().ToList(); } } /// /// Wrapper for in Python /// public void Initialize() { using (Py.GIL()) { _algorithm.Initialize(); } } /// /// Wrapper for in Python /// /// /// public List Liquidate(Symbol symbolToLiquidate = null) { using (Py.GIL()) { return _algorithm.Liquidate(symbolToLiquidate); } } /// /// Wrapper for in Python /// /// public void Log(string message) { using (Py.GIL()) { _algorithm.Log(message); } } /// /// Wrapper for in Python /// public void OnBrokerageDisconnect() { using (Py.GIL()) { _algorithm.OnBrokerageDisconnect(); } } /// /// Wrapper for in Python /// /// public void OnBrokerageMessage(BrokerageMessageEvent messageEvent) { using (Py.GIL()) { _algorithm.OnBrokerageMessage(messageEvent); } } /// /// Wrapper for in Python /// public void OnBrokerageReconnect() { using (Py.GIL()) { _algorithm.OnBrokerageReconnect(); } } /// /// Wrapper for in Python /// public void OnData(Slice slice) { using (Py.GIL()) { _pyAlgorithm.OnPythonData(slice); } } /// /// Wrapper for in Python /// public void OnEndOfAlgorithm() { using (Py.GIL()) { _algorithm.OnEndOfAlgorithm(); } } /// /// Wrapper for in Python /// public void OnEndOfDay() { using (Py.GIL()) { _algorithm.OnEndOfDay(); } } /// /// Wrapper for in Python /// /// public void OnEndOfDay(Symbol symbol) { using (Py.GIL()) { _algorithm.OnEndOfDay(symbol); } } /// /// Wrapper for in Python /// /// public void OnMarginCall(List requests) { using (Py.GIL()) { _algorithm.OnMarginCall(requests); } } /// /// Wrapper for in Python /// public void OnMarginCallWarning() { using (Py.GIL()) { _algorithm.OnMarginCallWarning(); } } /// /// Wrapper for in Python /// /// public void OnOrderEvent(OrderEvent newEvent) { using (Py.GIL()) { _algorithm.OnOrderEvent(newEvent); } } /// /// Wrapper for in Python /// /// public void OnAssignmentOrderEvent(OrderEvent newEvent) { using (Py.GIL()) { _algorithm.OnAssignmentOrderEvent(newEvent); } } /// /// Wrapper for in Python /// /// public void OnSecuritiesChanged(SecurityChanges changes) { using (Py.GIL()) { _algorithm.OnSecuritiesChanged(changes); } } /// /// Wrapper for in Python /// public void PostInitialize() { using (Py.GIL()) { _algorithm.PostInitialize(); } } /// /// Wrapper for in Python /// /// /// public bool RemoveSecurity(Symbol symbol) { using (Py.GIL()) { return _algorithm.RemoveSecurity(symbol); } } /// /// Wrapper for in Python /// /// public void SetAlgorithmId(string algorithmId) { using (Py.GIL()) { _algorithm.SetAlgorithmId(algorithmId); } } /// /// Wrapper for in Python /// /// public void SetBrokerageMessageHandler(IBrokerageMessageHandler brokerageMessageHandler) { using (Py.GIL()) { _algorithm.SetBrokerageMessageHandler(brokerageMessageHandler); } } /// /// Wrapper for in Python /// /// public void SetBrokerageModel(IBrokerageModel brokerageModel) { using (Py.GIL()) { _algorithm.SetBrokerageModel(new BrokerageModelPythonWrapper(brokerageModel)); } } /// /// Wrapper for in Python /// /// public void SetCash(decimal startingCash) { using (Py.GIL()) { _algorithm.SetCash(startingCash); } } /// /// Wrapper for in Python /// /// /// /// public void SetCash(string symbol, decimal startingCash, decimal conversionRate) { using (Py.GIL()) { _algorithm.SetCash(symbol, startingCash, conversionRate); } } /// /// Wrapper for in Python /// /// public void SetDateTime(DateTime time) { using (Py.GIL()) { _algorithm.SetDateTime(time); } } /// /// Wrapper for in Python /// /// public void SetRunTimeError(Exception exception) { using (Py.GIL()) { _algorithm.SetRunTimeError(exception); } } /// /// Wrapper for in Python /// public void SetFinishedWarmingUp() { using (Py.GIL()) { _algorithm.SetFinishedWarmingUp(); } } /// /// Wrapper for in Python /// /// public void SetHistoryProvider(IHistoryProvider historyProvider) { using (Py.GIL()) { _algorithm.SetHistoryProvider(new HistoryProviderPythonWrapper(historyProvider)); } } /// /// Wrapper for in Python /// /// public void SetLiveMode(bool live) { using (Py.GIL()) { _algorithm.SetLiveMode(live); } } /// /// Wrapper for in Python /// public void SetLocked() { using (Py.GIL()) { _algorithm.SetLocked(); } } /// /// Wrapper for in Python /// /// public void SetMaximumOrders(int max) { using (Py.GIL()) { _algorithm.SetMaximumOrders(max); } } /// /// Wrapper for in Python /// /// public void SetParameters(Dictionary parameters) { using (Py.GIL()) { _algorithm.SetParameters(parameters); } } } }