Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a1bb907e03 | ||
|
|
71540f5015 | ||
|
|
a0055a3695 | ||
|
|
0b285df496 | ||
|
|
4d37096b3f | ||
|
|
7c42ea795f | ||
|
|
f2f1d06237 |
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 }}
|
||||
|
||||
@@ -50,6 +50,8 @@ namespace QuantConnect.Brokerages
|
||||
OrderType.StopLimit,
|
||||
OrderType.ComboMarket,
|
||||
OrderType.ComboLimit,
|
||||
OrderType.MarketOnOpen,
|
||||
OrderType.MarketOnClose
|
||||
});
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -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}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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))
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
|
||||
Reference in New Issue
Block a user