Compare commits

..

7 Commits
16640 ... 16651

Author SHA1 Message Date
Roman Yavnikov
a1bb907e03 Feature:Alpaca: support MarketOnOpen and MarketOnClose (#8341)
* feat: missed Alpaca config in Launcher

* feature: support of new OrderTypes for Equtity in AlpacaBrokerage model
2024-09-25 14:30:27 -03:00
Roman Yavnikov
71540f5015 Feature: support MarketOnOpen and MarketOnClose (#8340)
* remove: not used proxy config TradeStation

* feat: missed config of TradeStation in Launcher

* feat: support new OrderTypes in TradeStationBrokerageModel
2024-09-24 15:11:36 -03:00
Kevin Wheeler
a0055a3695 Improve data not found error messages. (#8295)
* Improve data not found error messages.

* Minor tweaks

---------

Co-authored-by: Kevin Wheeler <spreadlove5683@gmail.com>
Co-authored-by: Martin Molinero <martin.molinero1@gmail.com>
2024-09-20 16:56:58 -03:00
Martin-Molinero
0b285df496 Minor fix for option contract universe (#8337) 2024-09-20 13:16:20 -03:00
Martin Molinero
4d37096b3f Reduce realtime shutdown timeout 2024-09-20 10:04:58 -03:00
Martin Molinero
7c42ea795f Minor improvement for live trading shutdown 2024-09-19 20:09:21 -03:00
Martin-Molinero
f2f1d06237 Improve shutdown (#8335) 2024-09-19 19:32:29 -03:00
10 changed files with 90 additions and 28 deletions

View File

@@ -35,7 +35,7 @@ namespace QuantConnect.Algorithm.Selection
/// <param name="configuration">The universe configuration to use</param>
/// <param name="universeSettings">The universe settings to use</param>
public OptionContractUniverse(SubscriptionDataConfig configuration, UniverseSettings universeSettings)
: base(configuration, universeSettings, Time.EndOfTimeTimeSpan,
: base(AdjustUniverseConfiguration(configuration), universeSettings, Time.EndOfTimeTimeSpan,
// Argument isn't used since we override 'SelectSymbols'
Enumerable.Empty<Symbol>())
{
@@ -95,5 +95,13 @@ namespace QuantConnect.Algorithm.Selection
return new Symbol(sid, ticker);
}
/// <summary>
/// Make sure the configuration of the universe is what we want
/// </summary>
private static SubscriptionDataConfig AdjustUniverseConfiguration(SubscriptionDataConfig input)
{
return new SubscriptionDataConfig(input, fillForward: false);
}
}
}

View File

@@ -30,7 +30,8 @@ namespace QuantConnect.Brokerages
/// </summary>
private readonly Dictionary<SecurityType, HashSet<OrderType>> _supportOrderTypeBySecurityType = new()
{
{ SecurityType.Equity, new HashSet<OrderType> { OrderType.Market, OrderType.Limit, OrderType.StopMarket, OrderType.StopLimit, OrderType.TrailingStop } },
{ SecurityType.Equity, new HashSet<OrderType> { OrderType.Market, OrderType.Limit, OrderType.StopMarket, OrderType.StopLimit,
OrderType.TrailingStop, OrderType.MarketOnOpen, OrderType.MarketOnClose } },
// Market and limit order types see https://docs.alpaca.markets/docs/options-trading-overview
{ SecurityType.Option, new HashSet<OrderType> { OrderType.Market, OrderType.Limit } },
{ SecurityType.Crypto, new HashSet<OrderType> { OrderType.Market, OrderType.Limit, OrderType.StopLimit }}

View File

@@ -50,6 +50,8 @@ namespace QuantConnect.Brokerages
OrderType.StopLimit,
OrderType.ComboMarket,
OrderType.ComboLimit,
OrderType.MarketOnOpen,
OrderType.MarketOnClose
});
/// <summary>

View File

@@ -85,7 +85,7 @@ namespace QuantConnect.Data
var isUniverseData = path.Contains("coarse", StringComparison.OrdinalIgnoreCase) ||
path.Contains("universe", StringComparison.OrdinalIgnoreCase);
if (e.Succeded)
if (e.Succeeded)
{
WriteLineToFile(_succeededDataRequestsWriter, path, _succeededDataRequestsFileName);
Interlocked.Increment(ref _succeededDataRequestsCount);
@@ -105,7 +105,7 @@ namespace QuantConnect.Data
if (Logging.Log.DebuggingEnabled)
{
Logging.Log.Debug($"DataMonitor.OnNewDataRequest(): Data from {path} could not be fetched");
Logging.Log.Debug($"DataMonitor.OnNewDataRequest(): Data from {path} could not be fetched, error: {e.ErrorMessage}");
}
}
}

View File

@@ -30,17 +30,24 @@ namespace QuantConnect.Interfaces
/// <summary>
/// Whether the data was fetched successfully
/// </summary>
public bool Succeded { get; }
public bool Succeeded { get; }
/// <summary>
/// Any error message that occurred during the fetch
/// </summary>
public string ErrorMessage { get; }
/// <summary>
/// Initializes a new instance of the <see cref="DataProviderNewDataRequestEventArgs"/> class
/// </summary>
/// <param name="path">The path to the fetched data</param>
/// <param name="succeded">Whether the data was fetched successfully</param>
public DataProviderNewDataRequestEventArgs(string path, bool succeded)
/// <param name="succeeded">Whether the data was fetched successfully</param>
/// <param name="errorMessage">Any error message that occured during the fetch</param>
public DataProviderNewDataRequestEventArgs(string path, bool succeeded, string errorMessage)
{
Path = path;
Succeded = succeded;
Succeeded = succeeded;
ErrorMessage = errorMessage;
}
}
}

View File

@@ -48,6 +48,7 @@ namespace QuantConnect.Lean.Engine
private IAlgorithm _algorithm;
private readonly object _lock;
private readonly bool _liveMode;
private bool _cancelRequested;
private CancellationTokenSource _cancellationTokenSource;
/// <summary>
@@ -612,13 +613,20 @@ namespace QuantConnect.Lean.Engine
_algorithm.SetStatus(state);
}
if (state == AlgorithmStatus.Deleted)
if (_cancellationTokenSource != null && !_cancellationTokenSource.IsCancellationRequested && !_cancelRequested)
{
if (!_cancellationTokenSource.IsCancellationRequested)
if (state == AlgorithmStatus.Deleted)
{
// if the algorithm was deleted or stopped, let's give the algorithm a few seconds to shutdown and cancel it out
_cancelRequested = true;
// if the algorithm was deleted, let's give the algorithm a few seconds to shutdown and cancel it out
_cancellationTokenSource.CancelAfter(TimeSpan.FromSeconds(5));
}
else if (state == AlgorithmStatus.Stopped)
{
_cancelRequested = true;
// if the algorithm was stopped, let's give the algorithm a few seconds to shutdown and cancel it out
_cancellationTokenSource.CancelAfter(TimeSpan.FromMinutes(1));
}
}
}
}

View File

@@ -24,6 +24,8 @@ namespace QuantConnect.Lean.Engine.DataFeeds
/// </summary>
public class DefaultDataProvider : IDataProvider, IDisposable
{
private bool _oneTimeWarningLog;
/// <summary>
/// Event raised each time data fetch is finished (successfully or not)
/// </summary>
@@ -37,6 +39,7 @@ namespace QuantConnect.Lean.Engine.DataFeeds
public virtual Stream Fetch(string key)
{
var success = true;
var errorMessage = string.Empty;
try
{
return new FileStream(FileExtension.ToNormalizedPath(key), FileMode.Open, FileAccess.Read, FileShare.Read);
@@ -44,8 +47,17 @@ namespace QuantConnect.Lean.Engine.DataFeeds
catch (Exception exception)
{
success = false;
if (exception is DirectoryNotFoundException
|| exception is FileNotFoundException)
errorMessage = exception.Message;
if (exception is DirectoryNotFoundException)
{
if (!_oneTimeWarningLog)
{
_oneTimeWarningLog = true;
Logging.Log.Debug($"DefaultDataProvider.Fetch(): DirectoryNotFoundException: please review data paths, current 'Globals.DataFolder': {Globals.DataFolder}");
}
return null;
}
else if (exception is FileNotFoundException)
{
return null;
}
@@ -54,7 +66,7 @@ namespace QuantConnect.Lean.Engine.DataFeeds
}
finally
{
OnNewDataRequest(new DataProviderNewDataRequestEventArgs(key, success));
OnNewDataRequest(new DataProviderNewDataRequestEventArgs(key, success, errorMessage));
}
}

View File

@@ -196,11 +196,6 @@ namespace QuantConnect.Lean.Engine.DataFeeds
factory = new TimeTriggeredUniverseSubscriptionEnumeratorFactory(request.Universe as ITimeTriggeredUniverse,
_marketHoursDatabase,
_timeProvider);
if (request.Universe is UserDefinedUniverse)
{
return factory.CreateEnumerator(request, _dataProvider);
}
}
else if (request.Configuration.Type == typeof(FundamentalUniverse))
{

View File

@@ -209,7 +209,7 @@ namespace QuantConnect.Lean.Engine.RealTime
/// </summary>
public override void Exit()
{
_realTimeThread.StopSafely(TimeSpan.FromMinutes(5), _cancellationTokenSource);
_realTimeThread.StopSafely(TimeSpan.FromMinutes(1), _cancellationTokenSource);
_cancellationTokenSource.DisposeSafely();
base.Exit();
}

View File

@@ -208,18 +208,19 @@
"tt-log-fix-messages": false,
// Trade Station configuration
"trade-station-api-key": "",
"trade-station-api-secret": "",
"trade-station-code-from-url": "",
"trade-station-client-id": "",
"trade-station-client-secret": "",
"trade-station-redirect-url": "http://localhost",
"trade-station-refresh-token": "",
"trade-station-api-url": "https://sim-api.tradestation.com",
"trade-station-account-type": "Cash|Margin|Futures",
// [Optional] Trade Station Proxy Settings
"trade-station-use-proxy": false,
"trade-station-proxy-address-port": "",
"trade-station-proxy-username": "",
"trade-station-proxy-password": "",
"trade-station-account-id": "",
// Alpaca configuration
"alpaca-api-key": "",
"alpaca-api-secret": "",
"alpaca-access-token": "",
"alpaca-paper-trading": true,
// Exante trading configuration
// client-id, application-id, shared-key are required to access Exante REST API
@@ -532,6 +533,34 @@
"history-provider": [ "BrokerageHistoryProvider", "SubscriptionDataReaderHistoryProvider" ]
},
"live-trade-station": {
"live-mode": true,
// real brokerage implementations require the BrokerageTransactionHandler
"live-mode-brokerage": "TradeStationBrokerage",
"data-queue-handler": [ "TradeStationBrokerage" ],
"setup-handler": "QuantConnect.Lean.Engine.Setup.BrokerageSetupHandler",
"result-handler": "QuantConnect.Lean.Engine.Results.LiveTradingResultHandler",
"data-feed-handler": "QuantConnect.Lean.Engine.DataFeeds.LiveTradingDataFeed",
"real-time-handler": "QuantConnect.Lean.Engine.RealTime.LiveTradingRealTimeHandler",
"transaction-handler": "QuantConnect.Lean.Engine.TransactionHandlers.BrokerageTransactionHandler",
"history-provider": [ "BrokerageHistoryProvider", "SubscriptionDataReaderHistoryProvider" ]
},
"live-alpaca": {
"live-mode": true,
// real brokerage implementations require the BrokerageTransactionHandler
"live-mode-brokerage": "AlpacaBrokerage",
"data-queue-handler": [ "AlpacaBrokerage" ],
"setup-handler": "QuantConnect.Lean.Engine.Setup.BrokerageSetupHandler",
"result-handler": "QuantConnect.Lean.Engine.Results.LiveTradingResultHandler",
"data-feed-handler": "QuantConnect.Lean.Engine.DataFeeds.LiveTradingDataFeed",
"real-time-handler": "QuantConnect.Lean.Engine.RealTime.LiveTradingRealTimeHandler",
"transaction-handler": "QuantConnect.Lean.Engine.TransactionHandlers.BrokerageTransactionHandler",
"history-provider": [ "BrokerageHistoryProvider", "SubscriptionDataReaderHistoryProvider" ]
},
"live-futures-bybit": {
"live-mode": true,