private Insight SetGeneratedAndClosedTimes(Insight insight) { insight.GeneratedTimeUtc = UtcTime; insight.ReferenceValue = _securityValuesProvider.GetValues(insight.Symbol).Get(insight.Type); if (string.IsNullOrEmpty(insight.SourceModel)) { // set the source model name if not already set insight.SourceModel = Alpha.GetModelName(); } TimeSpan barSize; Security security; SecurityExchangeHours exchangeHours; if (Securities.TryGetValue(insight.Symbol, out security)) { exchangeHours = security.Exchange.Hours; barSize = security.Resolution.ToTimeSpan(); } else { barSize = insight.Period.ToHigherResolutionEquivalent(false).ToTimeSpan(); exchangeHours = MarketHoursDatabase.GetExchangeHours(insight.Symbol.ID.Market, insight.Symbol, insight.Symbol.SecurityType); } var localStart = UtcTime.ConvertFromUtc(exchangeHours.TimeZone); barSize = QuantConnect.Time.Max(barSize, QuantConnect.Time.OneMinute); var barCount = (int)(insight.Period.Ticks / barSize.Ticks); insight.CloseTimeUtc = QuantConnect.Time.GetEndTimeForTradeBars(exchangeHours, localStart, barSize, barCount, false).ConvertToUtc(exchangeHours.TimeZone); return(insight); }
/// <summary> /// Determines whether or not the specified security can be removed from /// this universe. This is useful to prevent securities from being taken /// out of a universe before the algorithm has had enough time to make /// decisions on the security /// </summary> /// <param name="utcTime">The current utc time</param> /// <param name="security">The security to check if its ok to remove</param> /// <returns>True if we can remove the security, false otherwise</returns> public virtual bool CanRemoveMember(DateTime utcTime, Security security) { // can always remove securities after dispose requested if (DisposeRequested) { return(true); } // can always remove delisted securities from the universe if (security.IsDelisted) { return(true); } Member member; if (Securities.TryGetValue(security.Symbol, out member)) { var timeInUniverse = utcTime - member.Added; if (timeInUniverse >= UniverseSettings.MinimumTimeInUniverse) { return(true); } } return(false); }
public SellOrder CreateSellOrder(string name, ulong quantity, ulong pricePerItem) { Security security; if (!Securities.TryGetValue(name, out security)) { return(null); } var split = security.Split(quantity); if (split == null) { return(null); } var order = new SellOrder(split, pricePerItem); order.AddCancelAction(CancelSellOrder); order.AddExecuteAction(ExecuteSellOrder); lock (SellOrders) { SellOrders.Add(order); } Updated?.Invoke(this, this); return(order); }
/// <summary> /// Gets the symbols/string from a PyObject /// </summary> /// <param name="pyObject">PyObject containing symbols</param> /// <returns>List of symbols</returns> private List <Symbol> GetSymbolsFromPyObject(PyObject pyObject) { using (Py.GIL()) { if (PyString.IsStringType(pyObject)) { Security security; if (Securities.TryGetValue(pyObject.ToString(), out security)) { return(new List <Symbol> { security.Symbol }); } return(null); } var symbols = new List <Symbol>(); foreach (var item in pyObject) { Security security; if (Securities.TryGetValue(item.ToString(), out security)) { symbols.Add(security.Symbol); } } return(symbols.Count == 0 ? null : symbols); } }
/// <summary> /// Determines whether or not the specified security can be removed from /// this universe. This is useful to prevent securities from being taken /// out of a universe before the algorithm has had enough time to make /// decisions on the security /// </summary> /// <param name="utcTime">The current utc time</param> /// <param name="security">The security to check if its ok to remove</param> /// <returns>True if we can remove the security, false otherwise</returns> public virtual bool CanRemoveMember(DateTime utcTime, Security security) { // can always remove securities after dispose requested if (DisposeRequested) { return(true); } // can always remove delisted securities from the universe if (security.IsDelisted) { return(true); } Member member; if (Securities.TryGetValue(security.Symbol, out member)) { if (_minimumTimeInUniverseRoundingInterval == null) { // lets set _minimumTimeInUniverseRoundingInterval once _minimumTimeInUniverseRoundingInterval = UniverseSettings.MinimumTimeInUniverse; AdjustMinimumTimeInUniverseRoundingInterval(); } var timeInUniverse = utcTime - member.Added; if (timeInUniverse.Round(_minimumTimeInUniverseRoundingInterval.Value) >= UniverseSettings.MinimumTimeInUniverse) { return(true); } } return(false); }
/// <summary> /// Raise the specified event /// </summary> /// <param name="eventFeedArgs">Event arguments</param> internal void RaiseEvent(EventFeedArgs eventFeedArgs) { //Skip if quote event and quote updates are being ignored if ((IgnoreQuoteEvents) && (eventFeedArgs.Event.Type == Spark.EVENT_QUOTE)) { return; } //Raise direct event if feed handler is assigned TotalEventsProcessed++; if (OnEvent != null) { OnEvent(this, eventFeedArgs); } //Raise event for security if in the dictionary Security security; if (!Securities.TryGetValue(eventFeedArgs.Symbol, out security)) { if (AutoGenerateSecurities) { security = AddSecurity(eventFeedArgs.Symbol); } } if (security != null) { security.EventReceived(this, eventFeedArgs); } }
/// <summary> /// Automatically place an order which will set the holdings to between 100% or -100% of *PORTFOLIO VALUE*. /// E.g. SetHoldings("AAPL", 0.1); SetHoldings("IBM", -0.2); -> Sets portfolio as long 10% APPL and short 20% IBM /// E.g. SetHoldings("AAPL", 2); -> Sets apple to 2x leveraged with all our cash. /// </summary> /// <param name="symbol">Symbol indexer</param> /// <param name="percentage">decimal fraction of portfolio to set stock</param> /// <param name="liquidateExistingHoldings">bool flag to clean all existing holdings before setting new faction.</param> /// <param name="tag">Tag the order with a short string.</param> /// <seealso cref="MarketOrder"/> public void SetHoldings(Symbol symbol, decimal percentage, bool liquidateExistingHoldings = false, string tag = "") { //Initialize Requirements: Security security; if (!Securities.TryGetValue(symbol, out security)) { Error(symbol.ToString() + " not found in portfolio. Request this data when initializing the algorithm."); return; } //If they triggered a liquidate if (liquidateExistingHoldings) { foreach (var kvp in Portfolio) { var holdingSymbol = kvp.Key; var holdings = kvp.Value; if (holdingSymbol != symbol && holdings.AbsoluteQuantity > 0) { //Go through all existing holdings [synchronously], market order the inverse quantity: Order(holdingSymbol, -holdings.Quantity, false, tag); } } } //Only place trade if we've got > 1 share to order. var quantity = CalculateOrderQuantity(symbol, percentage); if (Math.Abs(quantity) > 0) { MarketOrder(symbol, quantity, false, tag); } }
private IEnumerable <SubscriptionDataConfig> GetMatchingSubscriptions(Symbol symbol, Type type, Resolution?resolution = null) { Security security; if (Securities.TryGetValue(symbol, out security)) { // find all subscriptions matching the requested type with a higher resolution than requested return(from sub in security.Subscriptions.OrderByDescending(s => s.Resolution) where type.IsAssignableFrom(sub.Type) select sub); } else { var entry = MarketHoursDatabase.GetEntry(symbol.ID.Market, symbol, symbol.ID.SecurityType); resolution = GetResolution(symbol, resolution); return(SubscriptionManager .LookupSubscriptionConfigDataTypes(symbol.SecurityType, resolution.Value, symbol.IsCanonical()) .Select(x => new SubscriptionDataConfig( x.Item1, symbol, resolution.Value, entry.DataTimeZone, entry.ExchangeHours.TimeZone, UniverseSettings.FillForward, UniverseSettings.ExtendedMarketHours, true, false, x.Item2, true, UniverseSettings.DataNormalizationMode))); } }
private Alpha SetGeneratedAndClosedTimes(Alpha alpha) { alpha.GeneratedTimeUtc = UtcTime; TimeSpan barSize; Security security; SecurityExchangeHours exchangeHours; if (Securities.TryGetValue(alpha.Symbol, out security)) { exchangeHours = security.Exchange.Hours; barSize = security.Resolution.ToTimeSpan(); } else { barSize = alpha.Period.ToHigherResolutionEquivalent(false).ToTimeSpan(); exchangeHours = MarketHoursDatabase.GetExchangeHours(alpha.Symbol.ID.Market, alpha.Symbol, alpha.Symbol.SecurityType); } var localStart = UtcTime.ConvertFromUtc(exchangeHours.TimeZone); barSize = QuantConnect.Time.Max(barSize, QuantConnect.Time.OneMinute); var barCount = (int)(alpha.Period.Ticks / barSize.Ticks); alpha.CloseTimeUtc = QuantConnect.Time.GetEndTimeForTradeBars(exchangeHours, localStart, barSize, barCount, false).ConvertToUtc(exchangeHours.TimeZone); return(alpha); }
/// <summary> /// Called by setup handlers after Initialize and allows the algorithm a chance to organize /// the data gather in the Initialize method /// </summary> public void PostInitialize() { // if the benchmark hasn't been set yet, set it if (Benchmark == null) { // apply the default benchmark if it hasn't been set if (_benchmarkSymbol == Symbol.Empty) { _benchmarkSymbol = new Symbol("SPY"); _benchmarkSecurityType = SecurityType.Equity; } // if the requested benchmark system wasn't already added, then add it now Security security; if (!Securities.TryGetValue(_benchmarkSymbol, out security)) { // add the security as an internal feed so the algorithm doesn't receive the data var resolution = _liveMode ? Resolution.Second : Resolution.Daily; var market = _benchmarkSecurityType == SecurityType.Forex ? "fxcm" : "usa"; security = SecurityManager.CreateSecurity(Portfolio, SubscriptionManager, _exchangeHoursProvider, _benchmarkSecurityType, _benchmarkSymbol, resolution, market, true, 1m, false, true, false); Securities.Add(_benchmarkSymbol, security); } // just return the current price Benchmark = dateTime => security.Price; } }
/// <summary> /// Adds the security to the user defined universe for the specified /// </summary> private void AddToUserDefinedUniverse(Security security) { // if we are adding a non-internal security which already has an internal feed, we remove it first Security existingSecurity; if (Securities.TryGetValue(security.Symbol, out existingSecurity)) { if (!security.IsInternalFeed() && existingSecurity.IsInternalFeed()) { var securityUniverse = UniverseManager.Select(x => x.Value).OfType <UserDefinedUniverse>().FirstOrDefault(x => x.Members.ContainsKey(security.Symbol)); securityUniverse?.Remove(security.Symbol); Securities.Remove(security.Symbol); } } Securities.Add(security); // add this security to the user defined universe Universe universe; var subscription = security.Subscriptions.First(); var universeSymbol = UserDefinedUniverse.CreateSymbol(subscription.SecurityType, subscription.Market); if (!UniverseManager.TryGetValue(universeSymbol, out universe)) { // create a new universe, these subscription settings don't currently get used // since universe selection proper is never invoked on this type of universe var uconfig = new SubscriptionDataConfig(subscription, symbol: universeSymbol, isInternalFeed: true, fillForward: false); if (security.Type == SecurityType.Base) { // set entry in market hours database for the universe subscription to match the custom data var symbolString = MarketHoursDatabase.GetDatabaseSymbolKey(uconfig.Symbol); MarketHoursDatabase.SetEntry(uconfig.Market, symbolString, uconfig.SecurityType, security.Exchange.Hours, uconfig.DataTimeZone); } universe = new UserDefinedUniverse(uconfig, new UniverseSettings(security.Resolution, security.Leverage, security.IsFillDataForward, security.IsExtendedMarketHours, TimeSpan.Zero), SecurityInitializer, QuantConnect.Time.MaxTimeSpan, new List <Symbol> { security.Symbol } ); UniverseManager.Add(universeSymbol, universe); } var userDefinedUniverse = universe as UserDefinedUniverse; if (userDefinedUniverse != null) { userDefinedUniverse.Add(security.Symbol); } else { // should never happen, someone would need to add a non-user defined universe with this symbol throw new Exception("Expected universe with symbol '" + universeSymbol.Value + "' to be of type UserDefinedUniverse."); } }
private SecurityExchangeHours GetExchangeHours(Symbol symbol) { Security security; if (Securities.TryGetValue(symbol, out security)) { return(security.Exchange.Hours); } return(MarketHoursDatabase.GetEntry(symbol.ID.Market, symbol, symbol.ID.SecurityType).ExchangeHours); }
private SecurityExchangeHours GetExchangeHours(Symbol symbol) { Security security; if (Securities.TryGetValue(symbol, out security)) { return(security.Exchange.Hours); } return(GetMarketHours(symbol).ExchangeHours); }
/// <summary> /// Automatically place a market order which will set the holdings to between 100% or -100% of *PORTFOLIO VALUE*. /// E.g. SetHoldings("AAPL", 0.1); SetHoldings("IBM", -0.2); -> Sets portfolio as long 10% APPL and short 20% IBM /// E.g. SetHoldings("AAPL", 2); -> Sets apple to 2x leveraged with all our cash. /// If the market is closed, place a market on open order. /// </summary> /// <param name="symbol">Symbol indexer</param> /// <param name="percentage">decimal fraction of portfolio to set stock</param> /// <param name="liquidateExistingHoldings">bool flag to clean all existing holdings before setting new faction.</param> /// <param name="tag">Tag the order with a short string.</param> /// <seealso cref="MarketOrder"/> public void SetHoldings(Symbol symbol, decimal percentage, bool liquidateExistingHoldings = false, string tag = "") { //Initialize Requirements: Security security; if (!Securities.TryGetValue(symbol, out security)) { Error($"{symbol} not found in portfolio. Request this data when initializing the algorithm."); return; } //If they triggered a liquidate if (liquidateExistingHoldings) { foreach (var kvp in Portfolio) { var holdingSymbol = kvp.Key; var holdings = kvp.Value; if (holdingSymbol != symbol && holdings.AbsoluteQuantity > 0) { //Go through all existing holdings [synchronously], market order the inverse quantity: var liquidationQuantity = CalculateOrderQuantity(holdingSymbol, 0m); Order(holdingSymbol, liquidationQuantity, false, tag); } } } //Calculate total unfilled quantity for open market orders var marketOrdersQuantity = (from order in Transactions.GetOpenOrders(symbol) where order.Type == OrderType.Market select Transactions.GetOrderTicket(order.Id) into ticket where ticket != null select ticket.Quantity - ticket.QuantityFilled).Sum(); //Only place trade if we've got > 1 share to order. var quantity = CalculateOrderQuantity(symbol, percentage) - marketOrdersQuantity; if (Math.Abs(quantity) > 0) { //Check whether the exchange is open to send a market order. If not, send a market on open order instead if (security.Exchange.ExchangeOpen) { MarketOrder(symbol, quantity, false, tag); } else { MarketOnOpenOrder(symbol, quantity, tag); } } }
private Resolution?GetResolution(Symbol symbol, Resolution?resolution) { Security security; if (Securities.TryGetValue(symbol, out security)) { return(resolution ?? security.Resolution); } else { return(resolution ?? UniverseSettings.Resolution); } }
private MarketHoursDatabase.Entry GetMarketHours(Symbol symbol) { var hoursEntry = MarketHoursDatabase.GetEntry(symbol.ID.Market, symbol, symbol.ID.SecurityType); // user can override the exchange hours in algorithm, i.e. HistoryAlgorithm Security security; if (Securities.TryGetValue(symbol, out security)) { return(new MarketHoursDatabase.Entry(hoursEntry.DataTimeZone, security.Exchange.Hours)); } return(hoursEntry); }
/// <summary> /// Determines whether or not the specified security can be removed from /// this universe. This is useful to prevent securities from being taken /// out of a universe before the algorithm has had enough time to make /// decisions on the security /// </summary> /// <param name="utcTime">The current utc time</param> /// <param name="security">The security to check if its ok to remove</param> /// <returns>True if we can remove the security, false otherwise</returns> public virtual bool CanRemoveMember(DateTime utcTime, Security security) { Member member; if (Securities.TryGetValue(security.Symbol, out member)) { var timeInUniverse = utcTime - member.Added; if (timeInUniverse >= UniverseSettings.MinimumTimeInUniverse) { return(true); } } return(false); }
private Resolution GetResolution(Symbol symbol, Resolution?resolution) { Security security; if (Securities.TryGetValue(symbol, out security)) { return(resolution ?? SubscriptionManager.SubscriptionDataConfigService .GetSubscriptionDataConfigs(symbol) .GetHighestResolution()); } else { return(resolution ?? UniverseSettings.Resolution); } }
/// <summary> /// Gets the start time required for the specified bar count in terms of the algorithm's time zone /// </summary> private DateTime GetStartTimeAlgoTz(Symbol symbol, int periods, Resolution?resolution = null) { Security security; resolution = GetResolution(symbol, resolution); var exchange = GetExchangeHours(symbol); var isExtendedMarketHours = Securities.TryGetValue(symbol, out security) ? security.IsExtendedMarketHours : false; var timeSpan = resolution.Value.ToTimeSpan(); // make this a minimum of one second timeSpan = timeSpan < QuantConnect.Time.OneSecond ? QuantConnect.Time.OneSecond : timeSpan; var localStartTime = QuantConnect.Time.GetStartTimeForTradeBars(exchange, UtcTime.ConvertFromUtc(exchange.TimeZone), timeSpan, periods, isExtendedMarketHours); return(localStartTime.ConvertTo(exchange.TimeZone, TimeZone)); }
public void EventRecived(Event eventItem) { TotalEventsProcessed++; Security security; if (!Securities.TryGetValue(eventItem.Code, out security)) { security = AddSecurity(eventItem.Code); } if (security != null) { security.EventRecieved(eventItem); } }
private IEnumerable <SubscriptionDataConfig> GetMatchingSubscriptions(Symbol symbol, Type type, Resolution?resolution = null) { Security security; if (Securities.TryGetValue(symbol, out security)) { // find all subscriptions matching the requested type with a higher resolution than requested var matchingSubscriptions = from sub in security.Subscriptions.OrderByDescending(s => s.Resolution) where SubscriptionDataConfigTypeFilter(type, sub.Type) select sub; if (resolution.HasValue && (resolution == Resolution.Daily || resolution == Resolution.Hour) && symbol.SecurityType == SecurityType.Equity) { // for Daily and Hour resolution, for equities, we have to // filter out any existing subscriptions that could be of Quote type // This could happen if they were Resolution.Minute/Second/Tick matchingSubscriptions = matchingSubscriptions.Where(s => s.TickType != TickType.Quote); } return(matchingSubscriptions); } else { var entry = MarketHoursDatabase.GetEntry(symbol.ID.Market, symbol, symbol.ID.SecurityType); resolution = GetResolution(symbol, resolution); return(SubscriptionManager .LookupSubscriptionConfigDataTypes(symbol.SecurityType, resolution.Value, symbol.IsCanonical()) .Where(tuple => SubscriptionDataConfigTypeFilter(type, tuple.Item1)) .Select(x => new SubscriptionDataConfig( x.Item1, symbol, resolution.Value, entry.DataTimeZone, entry.ExchangeHours.TimeZone, UniverseSettings.FillForward, UniverseSettings.ExtendedMarketHours, true, false, x.Item2, true, UniverseSettings.DataNormalizationMode))); } }
private void ExecuteBuyOrder(BuyOrder order) { Security security; if (!Securities.TryGetValue(order.SecurityName, out security)) { Securities.Add(order.SecurityName, order.Security); } else { Securities[order.SecurityName].Merge(order.Security); } lock (BuyOrders) { BuyOrders.Remove(order); } Updated?.Invoke(this, this); }
private void CancelSellOrder(SellOrder order) { Security security; if (!Securities.TryGetValue(order.SecurityName, out security)) { Securities.Add(order.SecurityName, order.ForSale); } else { Securities[order.SecurityName].Merge(order.ForSale); } lock (SellOrders) { SellOrders.Remove(order); } Updated?.Invoke(this, this); }
private IEnumerable <SubscriptionDataConfig> GetMatchingSubscriptions(Symbol symbol, Type type) { Security security; if (Securities.TryGetValue(symbol, out security)) { // find all subscriptions matching the requested type with a higher resolution than requested return(from sub in security.Subscriptions.OrderByDescending(s => s.Resolution) where type.IsAssignableFrom(sub.Type) select sub); } else { var resolution = UniverseSettings.Resolution; var timeZone = GetExchangeHours(symbol).TimeZone; var subscriptionDataTypes = SubscriptionManager.LookupSubscriptionConfigDataTypes(symbol.SecurityType, resolution, symbol.IsCanonical()); return(subscriptionDataTypes.Select(x => new SubscriptionDataConfig(x.Item1, symbol, resolution, timeZone, timeZone, UniverseSettings.FillForward, UniverseSettings.ExtendedMarketHours, false, false, x.Item2))); } }
private Resolution GetResolution(Symbol symbol, Resolution?resolution) { Security security; if (Securities.TryGetValue(symbol, out security)) { if (resolution != null) { return(resolution.Value); } Resolution?result = null; var hasNonInternal = false; foreach (var config in SubscriptionManager.SubscriptionDataConfigService .GetSubscriptionDataConfigs(symbol, includeInternalConfigs: true) // we process non internal configs first .OrderBy(config => config.IsInternalFeed ? 1 : 0)) { if (!config.IsInternalFeed || !hasNonInternal) { // once we find a non internal config we ignore internals hasNonInternal |= !config.IsInternalFeed; if (!result.HasValue || config.Resolution < result) { result = config.Resolution; } } } return(result ?? UniverseSettings.Resolution); } else { return(resolution ?? UniverseSettings.Resolution); } }
/// <summary> /// Invoked at the end of every time step. This allows the algorithm /// to process events before advancing to the next time step. /// </summary> public void OnEndOfTimeStep() { if (_pendingUniverseAdditions.Count + _pendingUserDefinedUniverseSecurityAdditions.Count == 0) { // no point in looping through everything if there's no pending changes return; } var requiredHistoryRequests = new Dictionary <Security, Resolution>(); // rewrite securities w/ derivatives to be in raw mode lock (_pendingUniverseAdditionsLock) { foreach (var security in Securities.Select(kvp => kvp.Value).Union(_pendingUserDefinedUniverseSecurityAdditions.Keys)) { // check for any derivative securities and mark the underlying as raw if (Securities.Any(skvp => skvp.Key.HasUnderlyingSymbol(security.Symbol))) { // set data mode raw and default volatility model ConfigureUnderlyingSecurity(security); } if (security.Symbol.HasUnderlying) { Security underlyingSecurity; var underlyingSymbol = security.Symbol.Underlying; // create the underlying security object if it doesn't already exist if (!Securities.TryGetValue(underlyingSymbol, out underlyingSecurity)) { underlyingSecurity = AddSecurity(underlyingSymbol.SecurityType, underlyingSymbol.Value, security.Resolution, underlyingSymbol.ID.Market, false, 0, security.IsExtendedMarketHours); } // set data mode raw and default volatility model ConfigureUnderlyingSecurity(underlyingSecurity); if (LiveMode && underlyingSecurity.GetLastData() == null) { requiredHistoryRequests.Add(underlyingSecurity, (Resolution)Math.Max((int)security.Resolution, (int)Resolution.Minute)); } // set the underlying security on the derivative -- we do this in two places since it's possible // to do AddOptionContract w/out the underlying already added and normalized properly var derivative = security as IDerivativeSecurity; if (derivative != null) { derivative.Underlying = underlyingSecurity; } } } if (!requiredHistoryRequests.IsNullOrEmpty()) { // Create requests var historyRequests = Enumerable.Empty <HistoryRequest>(); foreach (var byResolution in requiredHistoryRequests.GroupBy(x => x.Value)) { historyRequests = historyRequests.Concat( CreateBarCountHistoryRequests(byResolution.Select(x => x.Key.Symbol), 3, byResolution.Key)); } // Request data var historicLastData = History(historyRequests); historicLastData.PushThrough(x => { var security = requiredHistoryRequests.Keys.FirstOrDefault(y => y.Symbol == x.Symbol); security?.Cache.AddData(x); }); } // add securities to their respective user defined universes foreach (var kvp in _pendingUserDefinedUniverseSecurityAdditions) { var security = kvp.Key; var userDefinedUniverse = kvp.Value; userDefinedUniverse.Add(security.Symbol); } // finally add any pending universes, this will make them available to the data feed foreach (var universe in _pendingUniverseAdditions) { UniverseManager.Add(universe.Configuration.Symbol, universe); } _pendingUniverseAdditions.Clear(); _pendingUserDefinedUniverseSecurityAdditions.Clear(); } }
/// <summary> /// Perform preorder checks to ensure we have sufficient capital, /// the market is open, and we haven't exceeded maximum realistic orders per day. /// </summary> /// <returns>OrderResponse. If no error, order request is submitted.</returns> private OrderResponse PreOrderChecksImpl(SubmitOrderRequest request) { //Most order methods use security objects; so this isn't really used. // todo: Left here for now but should review Security security; if (!Securities.TryGetValue(request.Symbol, out security)) { return(OrderResponse.Error(request, OrderResponseErrorCode.MissingSecurity, "You haven't requested " + request.Symbol.ToString() + " data. Add this with AddSecurity() in the Initialize() Method.")); } //Ordering 0 is useless. if (request.Quantity == 0 || request.Symbol == null || request.Symbol == QuantConnect.Symbol.Empty || Math.Abs(request.Quantity) < security.SymbolProperties.LotSize) { return(OrderResponse.ZeroQuantity(request)); } if (!security.IsTradable) { return(OrderResponse.Error(request, OrderResponseErrorCode.NonTradableSecurity, "The security with symbol '" + request.Symbol.ToString() + "' is marked as non-tradable.")); } var price = security.Price; //Check the exchange is open before sending a market on close orders if (request.OrderType == OrderType.MarketOnClose && !security.Exchange.ExchangeOpen) { return(OrderResponse.Error(request, OrderResponseErrorCode.ExchangeNotOpen, request.OrderType + " order and exchange not open.")); } //Check the exchange is open before sending a exercise orders if (request.OrderType == OrderType.OptionExercise && !security.Exchange.ExchangeOpen) { return(OrderResponse.Error(request, OrderResponseErrorCode.ExchangeNotOpen, request.OrderType + " order and exchange not open.")); } if (price == 0) { return(OrderResponse.Error(request, OrderResponseErrorCode.SecurityPriceZero, request.Symbol.ToString() + ": asset price is $0. If using custom data make sure you've set the 'Value' property.")); } // check quote currency existence/conversion rate on all orders Cash quoteCash; var quoteCurrency = security.QuoteCurrency.Symbol; if (!Portfolio.CashBook.TryGetValue(quoteCurrency, out quoteCash)) { return(OrderResponse.Error(request, OrderResponseErrorCode.QuoteCurrencyRequired, request.Symbol.Value + ": requires " + quoteCurrency + " in the cashbook to trade.")); } if (security.QuoteCurrency.ConversionRate == 0m) { return(OrderResponse.Error(request, OrderResponseErrorCode.ConversionRateZero, request.Symbol.Value + ": requires " + quoteCurrency + " to have a non-zero conversion rate. This can be caused by lack of data.")); } // need to also check base currency existence/conversion rate on forex orders if (security.Type == SecurityType.Forex) { Cash baseCash; var baseCurrency = ((Forex)security).BaseCurrencySymbol; if (!Portfolio.CashBook.TryGetValue(baseCurrency, out baseCash)) { return(OrderResponse.Error(request, OrderResponseErrorCode.ForexBaseAndQuoteCurrenciesRequired, request.Symbol.Value + ": requires " + baseCurrency + " and " + quoteCurrency + " in the cashbook to trade.")); } if (baseCash.ConversionRate == 0m) { return(OrderResponse.Error(request, OrderResponseErrorCode.ForexConversionRateZero, request.Symbol.Value + ": requires " + baseCurrency + " and " + quoteCurrency + " to have non-zero conversion rates. This can be caused by lack of data.")); } } //Make sure the security has some data: if (!security.HasData) { return(OrderResponse.Error(request, OrderResponseErrorCode.SecurityHasNoData, "There is no data for this symbol yet, please check the security.HasData flag to ensure there is at least one data point.")); } //We've already processed too many orders: max 100 per day or the memory usage explodes if (Transactions.OrdersCount > _maxOrders) { Status = AlgorithmStatus.Stopped; return(OrderResponse.Error(request, OrderResponseErrorCode.ExceededMaximumOrders, string.Format("You have exceeded maximum number of orders ({0}), for unlimited orders upgrade your account.", _maxOrders))); } if (request.OrderType == OrderType.OptionExercise) { if (security.Type != SecurityType.Option) { return(OrderResponse.Error(request, OrderResponseErrorCode.NonExercisableSecurity, "The security with symbol '" + request.Symbol.ToString() + "' is not exercisable.")); } if (security.Holdings.IsShort) { return(OrderResponse.Error(request, OrderResponseErrorCode.UnsupportedRequestType, "The security with symbol '" + request.Symbol.ToString() + "' has a short option position. Only long option positions are exercisable.")); } if (request.Quantity > security.Holdings.Quantity) { return(OrderResponse.Error(request, OrderResponseErrorCode.UnsupportedRequestType, "Cannot exercise more contracts of '" + request.Symbol.ToString() + "' than is currently available in the portfolio. ")); } if (request.Quantity <= 0.0m) { OrderResponse.ZeroQuantity(request); } } if (request.OrderType == OrderType.MarketOnClose) { var nextMarketClose = security.Exchange.Hours.GetNextMarketClose(security.LocalTime, false); // must be submitted with at least 10 minutes in trading day, add buffer allow order submission var latestSubmissionTime = nextMarketClose.AddMinutes(-15.50); if (!security.Exchange.ExchangeOpen || Time > latestSubmissionTime) { // tell the user we require a 16 minute buffer, on minute data in live a user will receive the 3:44->3:45 bar at 3:45, // this is already too late to submit one of these orders, so make the user do it at the 3:43->3:44 bar so it's submitted // to the brokerage before 3:45. return(OrderResponse.Error(request, OrderResponseErrorCode.MarketOnCloseOrderTooLate, "MarketOnClose orders must be placed with at least a 16 minute buffer before market close.")); } } // passes all initial order checks return(OrderResponse.Success(request)); }
public void OnEndOfTimeStep() { if (_pendingUniverseAdditions.Count + _pendingUserDefinedUniverseSecurityAdditions.Count == 0) { // no point in looping through everything if there's no pending changes return; } var requiredHistoryRequests = new Dictionary <Security, Resolution>(); // rewrite securities w/ derivatives to be in raw mode lock (_pendingUniverseAdditionsLock) { foreach (var security in Securities.Select(kvp => kvp.Value).Union( _pendingUserDefinedUniverseSecurityAdditions.Select(x => x.Security))) { // check for any derivative securities and mark the underlying as raw if (Securities.Any(skvp => skvp.Key.SecurityType != SecurityType.Base && skvp.Key.HasUnderlyingSymbol(security.Symbol))) { // set data mode raw and default volatility model ConfigureUnderlyingSecurity(security); } var configs = SubscriptionManager.SubscriptionDataConfigService .GetSubscriptionDataConfigs(security.Symbol); if (security.Symbol.HasUnderlying && security.Symbol.SecurityType != SecurityType.Base) { Security underlyingSecurity; var underlyingSymbol = security.Symbol.Underlying; var resolution = configs.GetHighestResolution(); // create the underlying security object if it doesn't already exist if (!Securities.TryGetValue(underlyingSymbol, out underlyingSecurity)) { underlyingSecurity = AddSecurity(underlyingSymbol.SecurityType, underlyingSymbol.Value, resolution, underlyingSymbol.ID.Market, false, 0, configs.IsExtendedMarketHours()); } // set data mode raw and default volatility model ConfigureUnderlyingSecurity(underlyingSecurity); if (LiveMode && underlyingSecurity.GetLastData() == null) { if (requiredHistoryRequests.ContainsKey(underlyingSecurity)) { // lets request the higher resolution var currentResolutionRequest = requiredHistoryRequests[underlyingSecurity]; if (currentResolutionRequest != Resolution.Minute && // Can not be less than Minute resolution < currentResolutionRequest) { requiredHistoryRequests[underlyingSecurity] = (Resolution)Math.Max((int)resolution, (int)Resolution.Minute); } } else { requiredHistoryRequests.Add(underlyingSecurity, (Resolution)Math.Max((int)resolution, (int)Resolution.Minute)); } } // set the underlying security on the derivative -- we do this in two places since it's possible // to do AddOptionContract w/out the underlying already added and normalized properly var derivative = security as IDerivativeSecurity; if (derivative != null) { derivative.Underlying = underlyingSecurity; } } } if (!requiredHistoryRequests.IsNullOrEmpty()) { // Create requests var historyRequests = Enumerable.Empty <HistoryRequest>(); foreach (var byResolution in requiredHistoryRequests.GroupBy(x => x.Value)) { historyRequests = historyRequests.Concat( CreateBarCountHistoryRequests(byResolution.Select(x => x.Key.Symbol), 3, byResolution.Key)); } // Request data var historicLastData = History(historyRequests); historicLastData.PushThrough(x => { var security = requiredHistoryRequests.Keys.FirstOrDefault(y => y.Symbol == x.Symbol); security?.Cache.AddData(x); }); } // add subscriptionDataConfig to their respective user defined universes foreach (var userDefinedUniverseAddition in _pendingUserDefinedUniverseSecurityAdditions) { foreach (var subscriptionDataConfig in userDefinedUniverseAddition.SubscriptionDataConfigs) { userDefinedUniverseAddition.Universe.Add(subscriptionDataConfig); } } // finally add any pending universes, this will make them available to the data feed foreach (var universe in _pendingUniverseAdditions) { UniverseManager.Add(universe.Configuration.Symbol, universe); } _pendingUniverseAdditions.Clear(); _pendingUserDefinedUniverseSecurityAdditions.Clear(); } if (!_rawNormalizationWarningSymbols.IsNullOrEmpty()) { // Log our securities being set to raw price mode Debug($"Warning: The following securities were set to raw price normalization mode to work with options: " + $"{string.Join(", ", _rawNormalizationWarningSymbols.Take(_rawNormalizationWarningSymbolsMaxCount).Select(x => x.Value))}..."); // Set our warning list to null to stop emitting these warnings after its done once _rawNormalizationWarningSymbols = null; } }
/// <summary> /// Adds the security to the user defined universe /// </summary> /// <param name="security">The security to add</param> /// <param name="configurations">The <see cref="SubscriptionDataConfig"/> instances we want to add</param> private Security AddToUserDefinedUniverse( Security security, List <SubscriptionDataConfig> configurations) { var subscription = configurations.First(); // if we are adding a non-internal security which already has an internal feed, we remove it first if (Securities.TryGetValue(security.Symbol, out var existingSecurity)) { if (!subscription.IsInternalFeed && existingSecurity.IsInternalFeed()) { var securityUniverse = UniverseManager.Select(x => x.Value).OfType <UserDefinedUniverse>().FirstOrDefault(x => x.Members.ContainsKey(security.Symbol)); securityUniverse?.Remove(security.Symbol); Securities.Remove(security.Symbol); Securities.Add(security); } else { var isTradable = security.IsTradable; // We will reuse existing so we return it to the user. // We will use the IsTradable flag of the new security, since existing could of been set to false when removed security = existingSecurity; security.IsTradable = isTradable; } } else { Securities.Add(security); } // add this security to the user defined universe Universe universe; var universeSymbol = UserDefinedUniverse.CreateSymbol(security.Type, security.Symbol.ID.Market); lock (_pendingUniverseAdditionsLock) { if (!UniverseManager.TryGetValue(universeSymbol, out universe)) { universe = _pendingUniverseAdditions.FirstOrDefault(x => x.Configuration.Symbol == universeSymbol); if (universe == null) { // create a new universe, these subscription settings don't currently get used // since universe selection proper is never invoked on this type of universe var uconfig = new SubscriptionDataConfig(subscription, symbol: universeSymbol, isInternalFeed: true, fillForward: false, exchangeTimeZone: DateTimeZone.Utc, dataTimeZone: DateTimeZone.Utc); // this is the universe symbol, has no real entry in the mhdb, will default to market and security type // set entry in market hours database for the universe subscription to match the config var symbolString = MarketHoursDatabase.GetDatabaseSymbolKey(uconfig.Symbol); MarketHoursDatabase.SetEntry(uconfig.Market, symbolString, uconfig.SecurityType, SecurityExchangeHours.AlwaysOpen(uconfig.ExchangeTimeZone), uconfig.DataTimeZone); universe = new UserDefinedUniverse(uconfig, new UniverseSettings( subscription.Resolution, security.Leverage, subscription.FillDataForward, subscription.ExtendedMarketHours, TimeSpan.Zero), QuantConnect.Time.MaxTimeSpan, new List <Symbol>()); AddUniverse(universe); } } } var userDefinedUniverse = universe as UserDefinedUniverse; if (userDefinedUniverse != null) { lock (_pendingUniverseAdditionsLock) { _pendingUserDefinedUniverseSecurityAdditions.Add( new UserDefinedUniverseAddition(userDefinedUniverse, configurations, security)); } } else { // should never happen, someone would need to add a non-user defined universe with this symbol throw new Exception($"Expected universe with symbol '{universeSymbol.Value}' to be of type {nameof(UserDefinedUniverse)} but was {universe.GetType().Name}."); } return(security); }
/// <summary> /// Invoked at the end of every time step. This allows the algorithm /// to process events before advancing to the next time step. /// </summary> public void OnEndOfTimeStep() { if (_pendingUniverseAdditions.Count + _pendingUserDefinedUniverseSecurityAdditions.Count == 0) { // no point in looping through everything if there's no pending changes return; } // rewrite securities w/ derivatives to be in raw mode lock (_pendingUniverseAdditionsLock) { foreach (var security in Securities.Select(kvp => kvp.Value).Union(_pendingUserDefinedUniverseSecurityAdditions.Keys)) { // check for any derivative securities and mark the underlying as raw if (Securities.Any(skvp => skvp.Key.HasUnderlyingSymbol(security.Symbol))) { // set data mode raw and default volatility model ConfigureUnderlyingSecurity(security); } if (security.Symbol.HasUnderlying) { Security underlyingSecurity; var underlyingSymbol = security.Symbol.Underlying; // create the underlying security object if it doesn't already exist if (!Securities.TryGetValue(underlyingSymbol, out underlyingSecurity)) { underlyingSecurity = AddSecurity(underlyingSymbol.SecurityType, underlyingSymbol.Value, security.Resolution, underlyingSymbol.ID.Market, false, 0, security.IsExtendedMarketHours); } // set data mode raw and default volatility model ConfigureUnderlyingSecurity(underlyingSecurity); // set the underying security on the derivative -- we do this in two places since it's possible // to do AddOptionContract w/out the underlying already added and normalized properly var derivative = security as IDerivativeSecurity; if (derivative != null) { derivative.Underlying = underlyingSecurity; } } } // add securities to their respective user defined universes foreach (var kvp in _pendingUserDefinedUniverseSecurityAdditions) { var security = kvp.Key; var userDefinedUniverse = kvp.Value; userDefinedUniverse.Add(security.Symbol); } // finally add any pending universes, this will make them available to the data feed foreach (var universe in _pendingUniverseAdditions) { UniverseManager.Add(universe.Configuration.Symbol, universe); } _pendingUniverseAdditions.Clear(); _pendingUserDefinedUniverseSecurityAdditions.Clear(); } }