/// <summary> /// Construct the Equity Object /// </summary> public Equity(SecurityExchangeHours exchangeHours, SubscriptionDataConfig config, decimal leverage, bool isDynamicallyLoadedData = false) : base(exchangeHours, config, leverage, isDynamicallyLoadedData) { //Holdings for new Vehicle: Cache = new EquityCache(); Exchange = new EquityExchange(exchangeHours); DataFilter = new EquityDataFilter(); //Set the Equity Transaction Model TransactionModel = new EquityTransactionModel(); PortfolioModel = new EquityPortfolioModel(); MarginModel = new EquityMarginModel(leverage); Holdings = new EquityHolding(this, TransactionModel, MarginModel); }
/// <summary> /// Construct the Equity Object /// </summary> public Equity(SecurityExchangeHours exchangeHours, SubscriptionDataConfig config, decimal leverage) : base(exchangeHours, config, leverage) { //Holdings for new Vehicle: Cache = new EquityCache(); Exchange = new EquityExchange(exchangeHours); DataFilter = new EquityDataFilter(); //Set the Equity Transaction Model TransactionModel = new EquityTransactionModel(); PortfolioModel = new EquityPortfolioModel(); MarginModel = new EquityMarginModel(leverage); SettlementModel = new ImmediateSettlementModel(); Holdings = new EquityHolding(this, TransactionModel, MarginModel); }
/// <summary> /// Construct the Equity Object /// </summary> public Equity(SecurityExchangeHours exchangeHours, SubscriptionDataConfig config) : base( config, new EquityExchange(exchangeHours), new EquityCache(), new EquityPortfolioModel(), new ImmediateFillModel(), new InteractiveBrokersFeeModel(), new ConstantSlippageModel(0m), new ImmediateSettlementModel(), new EquityMarginModel(2m), new EquityDataFilter() ) { Holdings = new EquityHolding(this); }
/// <summary> /// Constructor for the CFD security /// </summary> /// <param name="exchangeHours">Defines the hours this exchange is open</param> /// <param name="quoteCurrency">The cash object that represent the quote currency</param> /// <param name="config">The subscription configuration for this security</param> /// <param name="symbolProperties">The symbol properties for this security</param> public Cfd(SecurityExchangeHours exchangeHours, Cash quoteCurrency, SubscriptionDataConfig config, SymbolProperties symbolProperties) : base(config, quoteCurrency, symbolProperties, new CfdExchange(exchangeHours), new CfdCache(), new SecurityPortfolioModel(), new ImmediateFillModel(), new ConstantFeeModel(0), new SpreadSlippageModel(), new ImmediateSettlementModel(), new SecurityMarginModel(50m), new CfdDataFilter() ) { Holdings = new CfdHolding(this); }
/// <summary> /// Constructor for the CFD security /// </summary> /// <param name="symbol">The security's symbol</param> /// <param name="exchangeHours">Defines the hours this exchange is open</param> /// <param name="quoteCurrency">The cash object that represent the quote currency</param> /// <param name="symbolProperties">The symbol properties for this security</param> public Cfd(Symbol symbol, SecurityExchangeHours exchangeHours, Cash quoteCurrency, SymbolProperties symbolProperties) : base(symbol, quoteCurrency, symbolProperties, new CfdExchange(exchangeHours), new CfdCache(), new SecurityPortfolioModel(), new ImmediateFillModel(), new ConstantFeeModel(0), new SpreadSlippageModel(), new ImmediateSettlementModel(), Securities.VolatilityModel.Null, new SecurityMarginModel(50m), new CfdDataFilter() ) { Holdings = new CfdHolding(this); }
/// <summary> /// Construct the Equity Object /// </summary> public Equity(Symbol symbol, SecurityExchangeHours exchangeHours, Cash quoteCurrency, SymbolProperties symbolProperties) : base(symbol, quoteCurrency, symbolProperties, new EquityExchange(exchangeHours), new EquityCache(), new SecurityPortfolioModel(), new ImmediateFillModel(), new InteractiveBrokersFeeModel(), new ConstantSlippageModel(0m), new ImmediateSettlementModel(), Securities.VolatilityModel.Null, new SecurityMarginModel(2m), new EquityDataFilter() ) { Holdings = new EquityHolding(this); }
/// <summary> /// Constructor for the forex security /// </summary> /// <param name="exchangeHours">Defines the hours this exchange is open</param> /// <param name="quoteCurrency">The cash object that represent the quote currency</param> /// <param name="config">The subscription configuration for this security</param> /// <param name="leverage">The leverage used for this security</param> public Forex(SecurityExchangeHours exchangeHours, Cash quoteCurrency, SubscriptionDataConfig config, decimal leverage) : base(exchangeHours, config, leverage) { QuoteCurrency = quoteCurrency; //Holdings for new Vehicle: Cache = new ForexCache(); Exchange = new ForexExchange(exchangeHours); DataFilter = new ForexDataFilter(); TransactionModel = new ForexTransactionModel(); PortfolioModel = new ForexPortfolioModel(); MarginModel = new ForexMarginModel(leverage); Holdings = new ForexHolding(this); // decompose the symbol into each currency pair string baseCurrencySymbol, quoteCurrencySymbol; DecomposeCurrencyPair(config.Symbol.Value, out baseCurrencySymbol, out quoteCurrencySymbol); BaseCurrencySymbol = baseCurrencySymbol; QuoteCurrencySymbol = quoteCurrencySymbol; }
/// <summary> /// Constructor for the option security /// </summary> /// <param name="exchangeHours">Defines the hours this exchange is open</param> /// <param name="quoteCurrency">The cash object that represent the quote currency</param> /// <param name="config">The subscription configuration for this security</param> /// <param name="symbolProperties">The symbol properties for this security</param> public Option(SecurityExchangeHours exchangeHours, SubscriptionDataConfig config, Cash quoteCurrency, SymbolProperties symbolProperties) : base(config, quoteCurrency, symbolProperties, new OptionExchange(exchangeHours), new OptionCache(), new SecurityPortfolioModel(), new ImmediateFillModel(), new InteractiveBrokersFeeModel(), new SpreadSlippageModel(), new ImmediateSettlementModel(), Securities.VolatilityModel.Null, new SecurityMarginModel(2m), new OptionDataFilter() ) { PriceModel = new CurrentPriceOptionPriceModel(); ContractFilter = new StrikeExpiryOptionFilter(-5, 5, TimeSpan.Zero, TimeSpan.FromDays(35)); }
/// <summary> /// Constructor for the forex security /// </summary> /// <param name="exchangeHours">Defines the hours this exchange is open</param> /// <param name="quoteCurrency">The cash object that represent the quote currency</param> /// <param name="config">The subscription configuration for this security</param> /// <param name="symbolProperties">The symbol properties for this security</param> public Forex(SecurityExchangeHours exchangeHours, Cash quoteCurrency, SubscriptionDataConfig config, SymbolProperties symbolProperties) : base(config, quoteCurrency, symbolProperties, new ForexExchange(exchangeHours), new ForexCache(), new SecurityPortfolioModel(), new ImmediateFillModel(), new InteractiveBrokersFeeModel(), new SpreadSlippageModel(), new ImmediateSettlementModel(), new SecurityMarginModel(50m), new ForexDataFilter() ) { Holdings = new ForexHolding(this); // decompose the symbol into each currency pair string baseCurrencySymbol, quoteCurrencySymbol; DecomposeCurrencyPair(config.Symbol.Value, out baseCurrencySymbol, out quoteCurrencySymbol); BaseCurrencySymbol = baseCurrencySymbol; }
/// <summary> /// Constructor for the CFD security /// </summary> /// <param name="exchangeHours">Defines the hours this exchange is open</param> /// <param name="quoteCurrency">The cash object that represent the quote currency</param> /// <param name="config">The subscription configuration for this security</param> /// <param name="symbolProperties">The symbol properties for this security</param> public Cfd(SecurityExchangeHours exchangeHours, Cash quoteCurrency, SubscriptionDataConfig config, SymbolProperties symbolProperties) : base(config, new CfdExchange(exchangeHours), new CfdCache(), new CfdPortfolioModel(), new ImmediateFillModel(), new ConstantFeeModel(0), new SpreadSlippageModel(), new ImmediateSettlementModel(), new CfdMarginModel(50m), new CfdDataFilter() ) { QuoteCurrency = quoteCurrency; Holdings = new CfdHolding(this); SymbolProperties = symbolProperties; if (symbolProperties == null) throw new ArgumentException("CFD requires a valid SymbolProperties argument"); if (symbolProperties.QuoteCurrency != quoteCurrency.Symbol) throw new ArgumentException("CFD SymbolProperties.QuoteCurrency and QuoteCurrency.Symbol do not match."); }
/// <summary> /// Initializes a new instance of the <see cref="HistoryRequest"/> class from the specified config and exchange hours /// </summary> /// <param name="config">The subscription data config used to initialize this request</param> /// <param name="hours">The exchange hours used for fill forward processing</param> /// <param name="startTimeUtc">The start time for this request,</param> /// <param name="endTimeUtc">The start time for this request</param> public HistoryRequest(SubscriptionDataConfig config, SecurityExchangeHours hours, DateTime startTimeUtc, DateTime endTimeUtc) : this(startTimeUtc, endTimeUtc, config.Type, config.Symbol, config.Resolution, hours, config.DataTimeZone, config.FillDataForward ? config.Resolution : (Resolution?)null, config.ExtendedMarketHours, config.IsCustomData, config.DataNormalizationMode, config.TickType, config.DataMappingMode, config.ContractDepthOffset) { }
public void GetsHistory(Symbol symbol, Resolution resolution, TickType tickType, TimeSpan period, bool shouldBeEmpty) { var now = new DateTime(2020, 5, 20, 15, 0, 0).RoundDown(resolution.ToTimeSpan()); var dataType = LeanData.GetDataType(resolution, tickType); var requests = new[] { new HistoryRequest(now.Add(-period), now, dataType, symbol, resolution, SecurityExchangeHours.AlwaysOpen(TimeZones.NewYork), TimeZones.NewYork, null, true, false, DataNormalizationMode.Adjusted, tickType) }; var history = _historyProvider.GetHistory(requests, TimeZones.NewYork).ToList(); if (dataType == typeof(TradeBar)) { foreach (var slice in history) { var bar = slice.Bars[symbol]; Log.Trace($"{bar.Time}: {bar.Symbol} - O={bar.Open}, H={bar.High}, L={bar.Low}, C={bar.Close}"); } } else if (dataType == typeof(QuoteBar)) { foreach (var slice in history) { var bar = slice.QuoteBars[symbol]; Log.Trace($"{bar.Time}: {bar.Symbol} - O={bar.Open}, H={bar.High}, L={bar.Low}, C={bar.Close}"); } } else if (dataType == typeof(Tick)) { foreach (var slice in history) { var ticks = slice.Ticks[symbol]; foreach (var tick in ticks) { Log.Trace($"{tick.Time}: {tick.Symbol} - B={tick.BidPrice}, A={tick.AskPrice}, P={tick.LastPrice}, Q={tick.Quantity}"); } } } Log.Trace("Data points retrieved: " + _historyProvider.DataPointCount); if (shouldBeEmpty) { Assert.IsTrue(history.Count == 0); } else { Assert.IsTrue(history.Count > 0); } }
/// <summary> /// Extension method to round a datetime down by a timespan interval until it's /// within the specified exchange's open hours. The rounding is performed in the /// specified time zone /// </summary> /// <param name="dateTime">Time to be rounded down</param> /// <param name="interval">Timespan interval to round to.</param> /// <param name="exchangeHours">The exchange hours to determine open times</param> /// <param name="roundingTimeZone">The time zone to perform the rounding in</param> /// <param name="extendedMarket">True for extended market hours, otherwise false</param> /// <returns>Rounded datetime</returns> public static DateTime ExchangeRoundDownInTimeZone(this DateTime dateTime, TimeSpan interval, SecurityExchangeHours exchangeHours, DateTimeZone roundingTimeZone, bool extendedMarket) { // can't round against a zero interval if (interval == TimeSpan.Zero) { return(dateTime); } var rounded = dateTime.RoundDownInTimeZone(interval, exchangeHours.TimeZone, roundingTimeZone); while (!exchangeHours.IsOpen(rounded, rounded + interval, extendedMarket)) { rounded = (rounded - interval).RoundDownInTimeZone(interval, exchangeHours.TimeZone, roundingTimeZone); } return(rounded); }
public static Security GetSecurity(decimal price = 1m) { return(new Security(SecurityExchangeHours.AlwaysOpen(TimeZones.Utc), CreateConfig(), new Cash(CashBook.AccountCurrency, 1000, price), new SymbolProperties("BTCUSD", CashBook.AccountCurrency, 1, 1, 0.01m))); }
/// <summary> /// Creates a new dividend from this factor file row and the one chronologically in front of it /// This dividend may have a distribution of zero if this row doesn't represent a dividend /// </summary> /// <param name="futureFactorFileRow">The next factor file row in time</param> /// <param name="symbol">The symbol to use for the dividend</param> /// <param name="exchangeHours">Exchange hours used for resolving the previous trading day</param> /// <param name="decimalPlaces">The number of decimal places to round the dividend's distribution to, defaulting to 2</param> /// <returns>A new dividend instance</returns> public Dividend GetDividend(FactorFileRow futureFactorFileRow, Symbol symbol, SecurityExchangeHours exchangeHours, int decimalPlaces = 2) { if (futureFactorFileRow.PriceFactor == 0m) { throw new InvalidOperationException(Invariant( $"Unable to resolve dividend for '{symbol.ID}' at {Date:yyyy-MM-dd}. Price factor is zero." )); } // find previous trading day var previousTradingDay = exchangeHours.GetNextTradingDay(Date); return(Dividend.Create( symbol, previousTradingDay, ReferencePrice, PriceFactor / futureFactorFileRow.PriceFactor, decimalPlaces )); }
public void Initialize() { _algorithm = new QCAlgorithm(); _algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(_algorithm)); _portfolio = _algorithm.Portfolio; _portfolio.CashBook.Add("EUR", 0, 1.20m); _portfolio.CashBook.Add("BTC", 0, 15000m); _portfolio.CashBook.Add("ETH", 0, 1000m); _algorithm.SetBrokerageModel(BrokerageName.GDAX, AccountType.Cash); _transactionHandler = new BacktestingTransactionHandler(); _brokerage = new BacktestingBrokerage(_algorithm); _resultHandler = new TestResultHandler(); _transactionHandler.Initialize(_algorithm, _brokerage, _resultHandler); _algorithm.Transactions.SetOrderProcessor(_transactionHandler); var tz = TimeZones.NewYork; _btcusd = new Crypto( SecurityExchangeHours.AlwaysOpen(tz), _portfolio.CashBook[Currencies.USD], new SubscriptionDataConfig(typeof(TradeBar), Symbols.BTCUSD, Resolution.Minute, tz, tz, true, false, false), new SymbolProperties("BTCUSD", Currencies.USD, 1, 0.01m, 0.00000001m, string.Empty), ErrorCurrencyConverter.Instance, RegisteredSecurityDataTypesProvider.Null ); _ethusd = new Crypto( SecurityExchangeHours.AlwaysOpen(tz), _portfolio.CashBook[Currencies.USD], new SubscriptionDataConfig(typeof(TradeBar), Symbols.ETHUSD, Resolution.Minute, tz, tz, true, false, false), new SymbolProperties("ETHUSD", Currencies.USD, 1, 0.01m, 0.00000001m, string.Empty), ErrorCurrencyConverter.Instance, RegisteredSecurityDataTypesProvider.Null ); _btceur = new Crypto( SecurityExchangeHours.AlwaysOpen(tz), _portfolio.CashBook["EUR"], new SubscriptionDataConfig(typeof(TradeBar), Symbols.BTCEUR, Resolution.Minute, tz, tz, true, false, false), new SymbolProperties("BTCEUR", "EUR", 1, 0.01m, 0.00000001m, string.Empty), ErrorCurrencyConverter.Instance, RegisteredSecurityDataTypesProvider.Null ); _ethbtc = new Crypto( SecurityExchangeHours.AlwaysOpen(tz), _portfolio.CashBook["BTC"], new SubscriptionDataConfig(typeof(TradeBar), Symbols.ETHBTC, Resolution.Minute, tz, tz, true, false, false), new SymbolProperties("ETHBTC", "BTC", 1, 0.00001m, 0.00000001m, string.Empty), ErrorCurrencyConverter.Instance, RegisteredSecurityDataTypesProvider.Null ); _globalTimeKeeper = new TimeKeeper(new DateTime(2019, 4, 22)); _timeKeeper = _globalTimeKeeper.GetLocalTimeKeeper(tz); _buyingPowerModel = new BuyingPowerModelComparator( new CashBuyingPowerModel(), new SecurityPositionGroupBuyingPowerModel(), _portfolio, _globalTimeKeeper ); _btcusd.SetLocalTimeKeeper(_timeKeeper); _ethusd.SetLocalTimeKeeper(_timeKeeper); _btceur.SetLocalTimeKeeper(_timeKeeper); _ethbtc.SetLocalTimeKeeper(_timeKeeper); }
public void BaroneAdesiWhaleyPortfolioTest() { const decimal price = 30.00m; const decimal underlyingPrice = 200m; const decimal underlyingVol = 0.25m; const decimal riskFreeRate = 0.01m; var tz = TimeZones.NewYork; var evaluationDate = new DateTime(2015, 2, 19); var equity = new Equity( SecurityExchangeHours.AlwaysOpen(tz), new SubscriptionDataConfig(typeof(TradeBar), Symbols.SPY, Resolution.Minute, tz, tz, true, false, false), new Cash(Currencies.USD, 0, 1m), SymbolProperties.GetDefault(Currencies.USD), ErrorCurrencyConverter.Instance ); equity.SetMarketPrice(new Tick { Value = underlyingPrice }); equity.VolatilityModel = new DummyVolatilityModel(underlyingVol); var contract = new OptionContract(Symbols.SPY_C_192_Feb19_2016, Symbols.SPY) { Time = evaluationDate }; var optionCall = new Option( SecurityExchangeHours.AlwaysOpen(tz), new SubscriptionDataConfig( typeof(TradeBar), Symbols.SPY_C_192_Feb19_2016, Resolution.Minute, tz, tz, true, false, false ), new Cash(Currencies.USD, 0, 1m), new OptionSymbolProperties(SymbolProperties.GetDefault(Currencies.USD)), ErrorCurrencyConverter.Instance ); optionCall.SetMarketPrice(new Tick { Value = price }); optionCall.Underlying = equity; var priceModel = OptionPriceModels.BaroneAdesiWhaley(); var results = priceModel.Evaluate(optionCall, null, contract); var callPrice = results.TheoreticalPrice; var impliedVolatility = results.ImpliedVolatility; var greeks = results.Greeks; Assert.Greater(price, callPrice); Assert.Greater(impliedVolatility, underlyingVol); // BS equation (inequality) var rightPart = greeks.Theta + riskFreeRate * underlyingPrice * greeks.Delta + 0.5m * underlyingVol * underlyingVol * underlyingPrice * underlyingPrice * greeks.Gamma; var leftPart = riskFreeRate * callPrice; Assert.GreaterOrEqual(Math.Round(leftPart, 4), Math.Round(rightPart, 4)); }
public void SetPeriodAndCloseTime(Insight insight, SecurityExchangeHours exchangeHours) { insight.Period = Time.EndOfTimeTimeSpan; insight.CloseTimeUtc = Time.EndOfTime; }
public void SetPeriodAndCloseTime(Insight insight, SecurityExchangeHours exchangeHours) { insight.Period = Resolution.ToTimeSpan().Multiply(BarCount); insight.CloseTimeUtc = ComputeCloseTime(exchangeHours, insight.GeneratedTimeUtc, Resolution, BarCount); }
public void SetPeriodAndCloseTime(Insight insight, SecurityExchangeHours exchangeHours) { insight.Period = Period; insight.CloseTimeUtc = ComputeCloseTime(exchangeHours, insight.GeneratedTimeUtc, Period); }
public void ReturnsExpectedPortfolioTarget( Language language, decimal maxDrawdownPercent, bool invested, decimal unrealizedProfit, decimal absoluteHoldingsCost, bool shouldLiquidate) { var security = new Mock <Equity>( Symbols.AAPL, SecurityExchangeHours.AlwaysOpen(TimeZones.NewYork), new Cash(Currencies.USD, 0, 1), SymbolProperties.GetDefault(Currencies.USD), ErrorCurrencyConverter.Instance, RegisteredSecurityDataTypesProvider.Null, new SecurityCache() ); security.Setup(m => m.Invested).Returns(invested); var holding = new Mock <EquityHolding>(security.Object, new IdentityCurrencyConverter(Currencies.USD)); holding.Setup(m => m.UnrealizedProfit).Returns(unrealizedProfit); holding.Setup(m => m.AbsoluteHoldingsCost).Returns(absoluteHoldingsCost); security.Object.Holdings = holding.Object; var algorithm = new QCAlgorithm(); algorithm.SetPandasConverter(); algorithm.Securities.Add(Symbols.AAPL, security.Object); if (language == Language.Python) { using (Py.GIL()) { const string name = nameof(MaximumDrawdownPercentPerSecurity); var instance = Py.Import(name).GetAttr(name).Invoke(maxDrawdownPercent.ToPython()); var model = new RiskManagementModelPythonWrapper(instance); algorithm.SetRiskManagement(model); } } else { var model = new MaximumDrawdownPercentPerSecurity(maxDrawdownPercent); algorithm.SetRiskManagement(model); } var targets = algorithm.RiskManagement.ManageRisk(algorithm, null).ToList(); if (shouldLiquidate) { Assert.AreEqual(1, targets.Count); Assert.AreEqual(Symbols.AAPL, targets[0].Symbol); Assert.AreEqual(0, targets[0].Quantity); } else { Assert.AreEqual(0, targets.Count); } }
private Subscription CreateSubscription(Resolution resolution, string symbol = "AAPL", bool isInternalFeed = false, SecurityType type = SecurityType.Equity, TickType tickType = TickType.Trade) { var start = DateTime.UtcNow; var end = start.AddSeconds(10); Security security; Symbol _symbol; if (type == SecurityType.Equity) { _symbol = new Symbol(SecurityIdentifier.GenerateEquity(DateTime.Now, symbol, Market.USA), symbol); security = new Equity( _symbol, SecurityExchangeHours.AlwaysOpen(DateTimeZone.Utc), new Cash(Currencies.USD, 0, 1), SymbolProperties.GetDefault(Currencies.USD), ErrorCurrencyConverter.Instance, RegisteredSecurityDataTypesProvider.Null, new SecurityCache() ); } else if (type == SecurityType.Option) { _symbol = new Symbol(SecurityIdentifier.GenerateOption(DateTime.Now, SecurityIdentifier.GenerateEquity(DateTime.Now, symbol, Market.USA), Market.USA, 0.0m, OptionRight.Call, OptionStyle.American), symbol); security = new Option( _symbol, SecurityExchangeHours.AlwaysOpen(DateTimeZone.Utc), new Cash(Currencies.USD, 0, 1), new OptionSymbolProperties(SymbolProperties.GetDefault(Currencies.USD)), ErrorCurrencyConverter.Instance, RegisteredSecurityDataTypesProvider.Null, new SecurityCache() ); } else if (type == SecurityType.Future) { _symbol = new Symbol(SecurityIdentifier.GenerateFuture(DateTime.Now, symbol, Market.USA), symbol); security = new Future( _symbol, SecurityExchangeHours.AlwaysOpen(DateTimeZone.Utc), new Cash(Currencies.USD, 0, 1), SymbolProperties.GetDefault(Currencies.USD), ErrorCurrencyConverter.Instance, RegisteredSecurityDataTypesProvider.Null, new SecurityCache() ); } else { throw new Exception("SecurityType not implemented"); } var config = new SubscriptionDataConfig(typeof(TradeBar), _symbol, resolution, DateTimeZone.Utc, DateTimeZone.Utc, true, false, isInternalFeed, false, tickType); var timeZoneOffsetProvider = new TimeZoneOffsetProvider(DateTimeZone.Utc, start, end); var enumerator = new EnqueueableEnumerator <BaseData>(); var subscriptionDataEnumerator = new SubscriptionDataEnumerator(config, security.Exchange.Hours, timeZoneOffsetProvider, enumerator); var subscriptionRequest = new SubscriptionRequest(false, null, security, config, start, end); return(new Subscription(subscriptionRequest, subscriptionDataEnumerator, timeZoneOffsetProvider)); }
public void FillForwardFlagIsCorrectlySet(bool isFillForward, Type type) { var config = new SubscriptionDataConfig( typeof(TradeBar), Symbols.SPY, Resolution.Hour, TimeZones.Utc, TimeZones.Utc, false, false, false ); var scale = 0.5m; config.DataNormalizationMode = DataNormalizationMode.Adjusted; var data = (BaseData)Activator.CreateInstance(type); if (isFillForward) { data = data.Clone(isFillForward); } var subscriptionData = (PrecalculatedSubscriptionData)SubscriptionData.Create(config, SecurityExchangeHours.AlwaysOpen(TimeZones.Utc), new TimeZoneOffsetProvider(TimeZones.NewYork, new DateTime(2015, 1, 1), new DateTime(2016, 1, 1)), data, config.DataNormalizationMode, scale); config.DataNormalizationMode = DataNormalizationMode.Raw; Assert.AreEqual(isFillForward, subscriptionData.Data.IsFillForward); config.DataNormalizationMode = DataNormalizationMode.Adjusted; Assert.AreEqual(isFillForward, subscriptionData.Data.IsFillForward); }
internal static Security CreateSecurity(Symbol symbol) { return(new Security(SecurityExchangeHours.AlwaysOpen(TimeZones.NewYork), new SubscriptionDataConfig(typeof(TradeBar), symbol, Resolution.Minute, TimeZones.NewYork, TimeZones.NewYork, false, false, false), new Cash(CashBook.AccountCurrency, 0, 1m), SymbolProperties.GetDefault(CashBook.AccountCurrency))); }
public void EvaluationDateWorksInPortfolioTest() { const decimal price = 30.00m; const decimal underlyingPrice = 200m; const decimal underlyingVol = 0.25m; const decimal riskFreeRate = 0.01m; var tz = TimeZones.NewYork; var evaluationDate1 = new DateTime(2015, 2, 19); var evaluationDate2 = new DateTime(2015, 2, 20); var equity = new Equity( SecurityExchangeHours.AlwaysOpen(tz), new SubscriptionDataConfig(typeof(TradeBar), Symbols.SPY, Resolution.Minute, tz, tz, true, false, false), new Cash(Currencies.USD, 0, 1m), SymbolProperties.GetDefault(Currencies.USD), ErrorCurrencyConverter.Instance ); equity.SetMarketPrice(new Tick { Value = underlyingPrice }); equity.VolatilityModel = new DummyVolatilityModel(underlyingVol); var contract = new OptionContract(Symbols.SPY_C_192_Feb19_2016, Symbols.SPY) { Time = evaluationDate1 }; var optionCall = new Option( SecurityExchangeHours.AlwaysOpen(tz), new SubscriptionDataConfig( typeof(TradeBar), Symbols.SPY_C_192_Feb19_2016, Resolution.Minute, tz, tz, true, false, false ), new Cash(Currencies.USD, 0, 1m), new OptionSymbolProperties(SymbolProperties.GetDefault(Currencies.USD)), ErrorCurrencyConverter.Instance ); optionCall.SetMarketPrice(new Tick { Value = price }); optionCall.Underlying = equity; var priceModel = OptionPriceModels.BaroneAdesiWhaley(); var results = priceModel.Evaluate(optionCall, null, contract); var callPrice1 = results.TheoreticalPrice; contract.Time = evaluationDate2; results = priceModel.Evaluate(optionCall, null, contract); var callPrice2 = results.TheoreticalPrice; Assert.Greater(callPrice1, callPrice2); }
public void GetsHistory(Symbol symbol, Resolution resolution, TimeSpan period, bool throwsException) { TestDelegate test = () => { var environment = Config.Get("oanda-environment").ConvertTo <Environment>(); var accessToken = Config.Get("oanda-access-token"); var accountId = Config.Get("oanda-account-id"); var brokerage = new OandaBrokerage(null, null, environment, accessToken, accountId); var historyProvider = new BrokerageHistoryProvider(); historyProvider.SetBrokerage(brokerage); historyProvider.Initialize(new HistoryProviderInitializeParameters(null, null, null, null, null, null)); var now = DateTime.UtcNow; var requests = new[] { new HistoryRequest(now.Add(-period), now, typeof(QuoteBar), symbol, resolution, SecurityExchangeHours.AlwaysOpen(TimeZones.EasternStandard), DateTimeZone.Utc, Resolution.Minute, false, false, DataNormalizationMode.Adjusted, TickType.Quote) }; var history = historyProvider.GetHistory(requests, TimeZones.Utc); foreach (var slice in history) { if (resolution == Resolution.Tick) { foreach (var tick in slice.Ticks[symbol]) { Log.Trace("{0}: {1} - {2} / {3}", tick.Time, tick.Symbol, tick.BidPrice, tick.AskPrice); } } else { var bar = slice.QuoteBars[symbol]; Log.Trace("{0}: {1} - O={2}, H={3}, L={4}, C={5}", bar.Time, bar.Symbol, bar.Open, bar.High, bar.Low, bar.Close); } } Log.Trace("Data points retrieved: " + historyProvider.DataPointCount); }; if (throwsException) { Assert.Throws <ArgumentException>(test); } else { Assert.DoesNotThrow(test); } }
public void GreekApproximationTest() { const decimal price = 20.00m; const decimal underlyingPrice = 190m; const decimal underlyingVol = 0.15m; var tz = TimeZones.NewYork; var evaluationDate = new DateTime(2016, 1, 19); var equity = new Equity( SecurityExchangeHours.AlwaysOpen(tz), new SubscriptionDataConfig(typeof(TradeBar), Symbols.SPY, Resolution.Minute, tz, tz, true, false, false), new Cash(Currencies.USD, 0, 1m), SymbolProperties.GetDefault(Currencies.USD), ErrorCurrencyConverter.Instance ); equity.SetMarketPrice(new Tick { Value = underlyingPrice }); equity.VolatilityModel = new DummyVolatilityModel(underlyingVol); var contract = new OptionContract(Symbols.SPY_P_192_Feb19_2016, Symbols.SPY) { Time = evaluationDate }; var optionPut = new Option( SecurityExchangeHours.AlwaysOpen(tz), new SubscriptionDataConfig( typeof(TradeBar), Symbols.SPY_P_192_Feb19_2016, Resolution.Minute, tz, tz, true, false, false ), new Cash(Currencies.USD, 0, 1m), new OptionSymbolProperties(SymbolProperties.GetDefault(Currencies.USD)), ErrorCurrencyConverter.Instance ); optionPut.SetMarketPrice(new Tick { Value = price }); optionPut.Underlying = equity; var priceModel = (QLOptionPriceModel)OptionPriceModels.CrankNicolsonFD(); priceModel.EnableGreekApproximation = false; var results = priceModel.Evaluate(optionPut, null, contract); var greeks = results.Greeks; Assert.AreEqual(greeks.Theta, 0); Assert.AreEqual(greeks.Rho, 0); Assert.AreEqual(greeks.Vega, 0); priceModel = (QLOptionPriceModel)OptionPriceModels.CrankNicolsonFD(); priceModel.EnableGreekApproximation = true; results = priceModel.Evaluate(optionPut, null, contract); greeks = results.Greeks; Assert.LessOrEqual(greeks.Theta, 0); Assert.AreNotEqual(greeks.Rho, 0); Assert.Greater(greeks.Vega, 0); }
// reproduces GH issue 3877 public void ConfigurationForAddedSubscriptionIsAlwaysPresent() { var dataPermissionManager = new DataPermissionManager(); var dataFeed = new TestDataFeed(); var dataManager = new DataManager(dataFeed, new UniverseSelection(_algorithm, _securityService, dataPermissionManager), _algorithm, _algorithm.TimeKeeper, MarketHoursDatabase.AlwaysOpen, false, new RegisteredSecurityDataTypesProvider(), dataPermissionManager); var config = new SubscriptionDataConfig(typeof(TradeBar), Symbols.SPY, Resolution.Daily, TimeZones.NewYork, TimeZones.NewYork, false, false, false); // Universe A: adds the config dataManager.SubscriptionManagerGetOrAdd(config); var request = new SubscriptionRequest(false, null, new Security(Symbols.SPY, SecurityExchangeHours.AlwaysOpen(DateTimeZone.Utc), new Cash(Currencies.USD, 1, 1), SymbolProperties.GetDefault(Currencies.USD), new IdentityCurrencyConverter(Currencies.USD), new RegisteredSecurityDataTypesProvider(), new SecurityCache()), config, new DateTime(2019, 1, 1), new DateTime(2019, 1, 1)); dataFeed.Subscription = new Subscription(request, new EnqueueableEnumerator <SubscriptionData>(), null); // Universe A: adds the subscription dataManager.AddSubscription(request); // Universe B: adds the config dataManager.SubscriptionManagerGetOrAdd(config); // Universe A: removes the subscription Assert.IsTrue(dataManager.RemoveSubscription(config)); Assert.AreEqual(0, dataManager.GetSubscriptionDataConfigs(config.Symbol).Count); // Universe B: adds the subscription Assert.IsTrue(dataManager.AddSubscription(request)); // the config should be present Assert.AreEqual(1, dataManager.GetSubscriptionDataConfigs(config.Symbol).Count); dataManager.RemoveAllSubscriptions(); }
public void PutCallParityTest() { const decimal underlyingPrice = 200m; const decimal underlyingVol = 0.15m; const decimal riskFreeRate = 0.01m; var tz = TimeZones.NewYork; var evaluationDate = new DateTime(2015, 2, 19); var SPY_C_192_Feb19_2016E = Symbol.CreateOption("SPY", Market.USA, OptionStyle.European, OptionRight.Call, 192m, new DateTime(2016, 02, 19)); var SPY_P_192_Feb19_2016E = Symbol.CreateOption("SPY", Market.USA, OptionStyle.European, OptionRight.Put, 192m, new DateTime(2016, 02, 19)); // setting up underlying var equity = new Equity( SecurityExchangeHours.AlwaysOpen(tz), new SubscriptionDataConfig(typeof(TradeBar), Symbols.SPY, Resolution.Minute, tz, tz, true, false, false), new Cash(Currencies.USD, 0, 1m), SymbolProperties.GetDefault(Currencies.USD), ErrorCurrencyConverter.Instance ); equity.SetMarketPrice(new Tick { Value = underlyingPrice }); equity.VolatilityModel = new DummyVolatilityModel(underlyingVol); // setting up European style call option var contractCall = new OptionContract(SPY_C_192_Feb19_2016E, Symbols.SPY) { Time = evaluationDate }; var optionCall = new Option( SecurityExchangeHours.AlwaysOpen(tz), new SubscriptionDataConfig(typeof(TradeBar), SPY_C_192_Feb19_2016E, Resolution.Minute, tz, tz, true, false, false), new Cash(Currencies.USD, 0, 1m), new OptionSymbolProperties(SymbolProperties.GetDefault(Currencies.USD)), ErrorCurrencyConverter.Instance ); optionCall.Underlying = equity; // setting up European style put option var contractPut = new OptionContract(SPY_P_192_Feb19_2016E, Symbols.SPY) { Time = evaluationDate }; var optionPut = new Option( SecurityExchangeHours.AlwaysOpen(tz), new SubscriptionDataConfig(typeof(TradeBar), SPY_P_192_Feb19_2016E, Resolution.Minute, tz, tz, true, false, false), new Cash(Currencies.USD, 0, 1m), new OptionSymbolProperties(SymbolProperties.GetDefault(Currencies.USD)), ErrorCurrencyConverter.Instance ); optionPut.Underlying = equity; // running evaluation var priceModel = OptionPriceModels.BlackScholes(); var resultsCall = priceModel.Evaluate(optionCall, null, contractCall); var resultsPut = priceModel.Evaluate(optionPut, null, contractPut); var callPrice = resultsCall.TheoreticalPrice; var putPrice = resultsPut.TheoreticalPrice; // Put-call parity equation var rightPart = putPrice + underlyingPrice; // no yield var leftPart = callPrice + contractCall.Strike * (decimal)Math.Exp((double)-riskFreeRate); Assert.AreEqual((double)leftPart, (double)rightPart, 0.0001); }
public void FillsForwardOnNulls() { var reference = new DateTime(2015, 10, 08); var period = Time.OneSecond; var underlying = new List <BaseData> { // 0 seconds new TradeBar(reference, Symbols.SPY, 10, 20, 5, 15, 123456, period), // 1 seconds null, // 3 seconds new TradeBar(reference.AddSeconds(2), Symbols.SPY, 100, 200, 50, 150, 1234560, period), null, null, null, null }; var timeProvider = new ManualTimeProvider(TimeZones.NewYork); timeProvider.SetCurrentTime(reference); var exchange = new SecurityExchange(SecurityExchangeHours.AlwaysOpen(TimeZones.NewYork)); var fillForward = new LiveFillForwardEnumerator(timeProvider, underlying.GetEnumerator(), exchange, Ref.Create(Time.OneSecond), false, Time.EndOfTime, Time.OneSecond, exchange.TimeZone); // first point is always emitted Assert.IsTrue(fillForward.MoveNext()); Assert.AreEqual(underlying[0], fillForward.Current); Assert.AreEqual(123456, ((TradeBar)fillForward.Current).Volume); // stepping again without advancing time does nothing, but we'll still // return true as per IEnumerator contract Assert.IsTrue(fillForward.MoveNext()); Assert.IsNull(fillForward.Current); timeProvider.SetCurrentTime(reference.AddSeconds(1)); // non-null next will fill forward in between Assert.IsTrue(fillForward.MoveNext()); Assert.AreEqual(underlying[0].EndTime, fillForward.Current.Time); Assert.AreEqual(underlying[0].Value, fillForward.Current.Value); Assert.IsTrue(fillForward.Current.IsFillForward); Assert.AreEqual(0, ((TradeBar)fillForward.Current).Volume); // even without stepping the time this will advance since non-null data is ready Assert.IsTrue(fillForward.MoveNext()); Assert.AreEqual(underlying[2], fillForward.Current); Assert.AreEqual(1234560, ((TradeBar)fillForward.Current).Volume); // step ahead into null data territory timeProvider.SetCurrentTime(reference.AddSeconds(4)); Assert.IsTrue(fillForward.MoveNext()); Assert.AreEqual(underlying[2].Value, fillForward.Current.Value); Assert.AreEqual(timeProvider.GetUtcNow().ConvertFromUtc(TimeZones.NewYork), fillForward.Current.EndTime); Assert.IsTrue(fillForward.Current.IsFillForward); Assert.AreEqual(0, ((TradeBar)fillForward.Current).Volume); Assert.IsTrue(fillForward.MoveNext()); Assert.IsNull(fillForward.Current); timeProvider.SetCurrentTime(reference.AddSeconds(5)); Assert.IsTrue(fillForward.MoveNext()); Assert.AreEqual(underlying[2].Value, fillForward.Current.Value); Assert.AreEqual(timeProvider.GetUtcNow().ConvertFromUtc(TimeZones.NewYork), fillForward.Current.EndTime); Assert.IsTrue(fillForward.Current.IsFillForward); Assert.AreEqual(0, ((TradeBar)fillForward.Current).Volume); timeProvider.SetCurrentTime(reference.AddSeconds(6)); Assert.IsTrue(fillForward.MoveNext()); Assert.AreEqual(underlying[2].Value, fillForward.Current.Value); Assert.AreEqual(timeProvider.GetUtcNow().ConvertFromUtc(TimeZones.NewYork), fillForward.Current.EndTime); Assert.IsTrue(fillForward.Current.IsFillForward); Assert.AreEqual(0, ((TradeBar)fillForward.Current).Volume); fillForward.Dispose(); }
public OptionExchange(SecurityExchangeHours exchangeHours) : base(exchangeHours) { }
/// <summary> /// Initializes a new instance of the <see cref="ForexExchange"/> class using the specified /// exchange hours to determine open/close times /// </summary> /// <param name="exchangeHours">Contains the weekly exchange schedule plus holidays</param> public ForexExchange(SecurityExchangeHours exchangeHours) : base(exchangeHours) { }
/// <summary> /// Initializes a new instance of the <see cref="EquityExchange"/> class using the specified /// exchange hours to determine open/close times /// </summary> /// <param name="exchangeHours">Contains the weekly exchange schedule plus holidays</param> public EquityExchange(SecurityExchangeHours exchangeHours) : base(exchangeHours) { }
public void GtdTimeInForceCryptoOrderExpiresAtMidnightUtcAfterExpiryDate() { var utcTime = new DateTime(2018, 4, 27, 10, 0, 0); var security = new Crypto( SecurityExchangeHours.AlwaysOpen(TimeZones.Utc), new Cash(Currencies.USD, 0, 1m), new SubscriptionDataConfig( typeof(QuoteBar), Symbols.BTCUSD, Resolution.Minute, TimeZones.Utc, TimeZones.Utc, true, true, true ), SymbolProperties.GetDefault(Currencies.USD), ErrorCurrencyConverter.Instance, RegisteredSecurityDataTypesProvider.Null ); var localTimeKeeper = new LocalTimeKeeper(utcTime, TimeZones.Utc); security.SetLocalTimeKeeper(localTimeKeeper); var timeInForce = TimeInForce.GoodTilDate(new DateTime(2018, 5, 1)); var orderProperties = new OrderProperties { TimeInForce = timeInForce }; var order = new LimitOrder(Symbols.BTCUSD, 10, 100, utcTime, "", orderProperties); Assert.IsFalse(timeInForce.IsOrderExpired(security, order)); var fill1 = new OrderEvent(order.Id, order.Symbol, utcTime, OrderStatus.PartiallyFilled, OrderDirection.Buy, order.LimitPrice, 3, OrderFee.Zero); Assert.IsTrue(timeInForce.IsFillValid(security, order, fill1)); var fill2 = new OrderEvent(order.Id, order.Symbol, utcTime, OrderStatus.Filled, OrderDirection.Buy, order.LimitPrice, 7, OrderFee.Zero); Assert.IsTrue(timeInForce.IsFillValid(security, order, fill2)); // April 27th before midnight localTimeKeeper.UpdateTime(utcTime.AddHours(14).AddSeconds(-1)); Assert.IsFalse(timeInForce.IsOrderExpired(security, order)); // April 28th at midnight localTimeKeeper.UpdateTime(utcTime.AddHours(14)); Assert.IsFalse(timeInForce.IsOrderExpired(security, order)); // May 1st at 10 AM localTimeKeeper.UpdateTime(utcTime.AddDays(4)); Assert.IsFalse(timeInForce.IsOrderExpired(security, order)); // May 1st before midnight localTimeKeeper.UpdateTime(utcTime.AddDays(4).AddHours(14).AddSeconds(-1)); Assert.IsFalse(timeInForce.IsOrderExpired(security, order)); // May 2nd at midnight localTimeKeeper.UpdateTime(utcTime.AddDays(4).AddHours(14)); Assert.IsTrue(timeInForce.IsOrderExpired(security, order)); Assert.IsTrue(timeInForce.IsFillValid(security, order, fill1)); Assert.IsTrue(timeInForce.IsFillValid(security, order, fill2)); }
private IBrokerage InitializeBrokerage() { Log.Trace(""); Log.Trace("- INITIALIZING BROKERAGE -"); Log.Trace(""); var brokerage = CreateBrokerage(OrderProvider, SecurityProvider); brokerage.Connect(); if (!brokerage.IsConnected) { Assert.Fail("Failed to connect to brokerage"); } Log.Trace(""); Log.Trace("GET OPEN ORDERS"); Log.Trace(""); foreach (var openOrder in brokerage.GetOpenOrders()) { OrderProvider.Add(openOrder); } Log.Trace(""); Log.Trace("GET ACCOUNT HOLDINGS"); Log.Trace(""); foreach (var accountHolding in brokerage.GetAccountHoldings()) { // these securities don't need to be real, just used for the ISecurityProvider impl, required // by brokerages to track holdings SecurityProvider[accountHolding.Symbol] = new Security(SecurityExchangeHours.AlwaysOpen(TimeZones.NewYork), new SubscriptionDataConfig(typeof(TradeBar), accountHolding.Symbol, Resolution.Minute, TimeZones.NewYork, TimeZones.NewYork, false, false, false), 1); } brokerage.OrderStatusChanged += (sender, args) => { Log.Trace(""); Log.Trace("ORDER STATUS CHANGED: " + args); Log.Trace(""); // we need to keep this maintained properly if (args.Status == OrderStatus.Filled || args.Status == OrderStatus.PartiallyFilled) { Log.Trace("FILL EVENT: " + args.FillQuantity + " units of " + args.Symbol.ToString()); Security security; if (_securityProvider.TryGetValue(args.Symbol, out security)) { var holding = _securityProvider[args.Symbol].Holdings; holding.SetHoldings(args.FillPrice, holding.Quantity + args.FillQuantity); } else { var accountHoldings = brokerage.GetAccountHoldings().ToDictionary(x => x.Symbol); if (accountHoldings.ContainsKey(args.Symbol)) { _securityProvider[args.Symbol].Holdings.SetHoldings(args.FillPrice, args.FillQuantity); } else { _securityProvider[args.Symbol] = new Security(SecurityExchangeHours.AlwaysOpen(TimeZones.NewYork), new SubscriptionDataConfig(typeof(TradeBar), args.Symbol, Resolution.Minute, TimeZones.NewYork, TimeZones.NewYork, false, false, false), 1); _securityProvider[args.Symbol].Holdings.SetHoldings(args.FillPrice, args.FillQuantity); } } Log.Trace("--HOLDINGS: " + _securityProvider[args.Symbol]); // update order mapping var order = _orderProvider.GetOrderById(args.OrderId); order.Status = args.Status; } }; return(brokerage); }
public void GetsHistory(Symbol symbol, Resolution resolution, TimeSpan period, bool shouldBeEmpty) { var keyId = Config.Get("alpaca-key-id"); var secretKey = Config.Get("alpaca-secret-key"); var tradingMode = Config.Get("alpaca-trading-mode"); using (var brokerage = new AlpacaBrokerage(null, null, keyId, secretKey, tradingMode, false)) { var historyProvider = new BrokerageHistoryProvider(); historyProvider.SetBrokerage(brokerage); historyProvider.Initialize(new HistoryProviderInitializeParameters(null, null, null, null, null, null, null, false)); var now = DateTime.UtcNow; var requests = new[] { new HistoryRequest( now.Add(-period), now, typeof(TradeBar), symbol, resolution, SecurityExchangeHours.AlwaysOpen(TimeZones.NewYork), TimeZones.NewYork, null, false, false, DataNormalizationMode.Adjusted, TickType.Trade) }; var history = historyProvider.GetHistory(requests, TimeZones.NewYork).ToList(); foreach (var slice in history) { if (resolution == Resolution.Tick) { foreach (var tick in slice.Ticks[symbol]) { Console.WriteLine($"{tick.Time}: {tick.Symbol} - P={tick.Price}, Q={tick.Quantity}"); } } else { var bar = slice.Bars[symbol]; Console.WriteLine($"{bar.Time}: {bar.Symbol} - O={bar.Open}, H={bar.High}, L={bar.Low}, C={bar.Close}, V={bar.Volume}"); } } if (shouldBeEmpty) { Assert.IsTrue(history.Count == 0); } else { Assert.IsTrue(history.Count > 0); } brokerage.Disconnect(); Log.Trace("Data points retrieved: " + historyProvider.DataPointCount); } }
/// <summary> /// Initializes a new instance of the <see cref="OptionExchange"/> class using the specified /// exchange hours to determine open/close times /// </summary> /// <param name="exchangeHours">Contains the weekly exchange schedule plus holidays</param> public OptionExchange(SecurityExchangeHours exchangeHours) : base(exchangeHours) { }
public void TestLongCallsPuts() { const decimal price = 1.2345m; const decimal underlyingPrice = 200m; var tz = TimeZones.NewYork; var equity = new QuantConnect.Securities.Equity.Equity( SecurityExchangeHours.AlwaysOpen(tz), new SubscriptionDataConfig(typeof(TradeBar), Symbols.SPY, Resolution.Minute, tz, tz, true, false, false), new Cash(Currencies.USD, 0, 1m), SymbolProperties.GetDefault(Currencies.USD), ErrorCurrencyConverter.Instance, RegisteredSecurityDataTypesProvider.Null ); equity.SetMarketPrice(new Tick { Value = underlyingPrice }); var optionPut = new Option( SecurityExchangeHours.AlwaysOpen(tz), new SubscriptionDataConfig( typeof(TradeBar), Symbols.SPY_P_192_Feb19_2016, Resolution.Minute, tz, tz, true, false, false ), new Cash(Currencies.USD, 0, 1m), new OptionSymbolProperties("", Currencies.USD, 100, 0.01m, 1), ErrorCurrencyConverter.Instance, RegisteredSecurityDataTypesProvider.Null ); optionPut.SetMarketPrice(new Tick { Value = price }); optionPut.Underlying = equity; optionPut.Holdings.SetHoldings(1m, 2); var optionCall = new Option( SecurityExchangeHours.AlwaysOpen(tz), new SubscriptionDataConfig( typeof(TradeBar), Symbols.SPY_C_192_Feb19_2016, Resolution.Minute, tz, tz, true, false, false ), new Cash(Currencies.USD, 0, 1m), new OptionSymbolProperties("", Currencies.USD, 100, 0.01m, 1), ErrorCurrencyConverter.Instance, RegisteredSecurityDataTypesProvider.Null ); optionCall.SetMarketPrice(new Tick { Value = price }); optionCall.Underlying = equity; optionCall.Holdings.SetHoldings(1.5m, 2); var buyingPowerModel = new TestOptionMarginModel(); // we expect long positions to be 100% charged. Assert.AreEqual(optionPut.Holdings.AbsoluteHoldingsCost, buyingPowerModel.GetMaintenanceMargin(optionPut)); Assert.AreEqual(optionCall.Holdings.AbsoluteHoldingsCost, buyingPowerModel.GetMaintenanceMargin(optionCall)); }
public void OptionExercise_NonAccountCurrency() { var algorithm = new QCAlgorithm(); var securities = new SecurityManager(new TimeKeeper(DateTime.Now, TimeZones.NewYork)); var transactions = new SecurityTransactionManager(null, securities); var transactionHandler = new BacktestingTransactionHandler(); var portfolio = new SecurityPortfolioManager(securities, transactions); var EUR = new Cash("EUR", 100 * 192, 10); portfolio.CashBook.Add("EUR", EUR); portfolio.SetCash("USD", 0, 1); algorithm.Securities = securities; transactionHandler.Initialize(algorithm, new BacktestingBrokerage(algorithm), _resultHandler); transactions.SetOrderProcessor(transactionHandler); securities.Add( Symbols.SPY, new Security( SecurityExchangeHours.AlwaysOpen(TimeZones.NewYork), CreateTradeBarConfig(Symbols.SPY), EUR, SymbolProperties.GetDefault(EUR.Symbol), ErrorCurrencyConverter.Instance, RegisteredSecurityDataTypesProvider.Null, new SecurityCache() ) ); securities.Add( Symbols.SPY_C_192_Feb19_2016, new Option( SecurityExchangeHours.AlwaysOpen(TimeZones.NewYork), CreateTradeBarConfig(Symbols.SPY_C_192_Feb19_2016), EUR, new OptionSymbolProperties(new SymbolProperties("EUR", "EUR", 100, 0.01m, 1, string.Empty)), ErrorCurrencyConverter.Instance, RegisteredSecurityDataTypesProvider.Null ) ); securities[Symbols.SPY_C_192_Feb19_2016].Holdings.SetHoldings(1, 1); securities[Symbols.SPY].SetMarketPrice(new Tick { Value = 200 }); transactions.AddOrder(new SubmitOrderRequest(OrderType.OptionExercise, SecurityType.Option, Symbols.SPY_C_192_Feb19_2016, -1, 0, 0, securities.UtcTime, "")); var option = (Option)securities[Symbols.SPY_C_192_Feb19_2016]; var order = (OptionExerciseOrder)transactions.GetOrders(x => true).First(); option.Underlying = securities[Symbols.SPY]; var fills = option.OptionExerciseModel.OptionExercise(option, order).ToList(); Assert.AreEqual(2, fills.Count); Assert.IsFalse(fills[0].IsAssignment); Assert.AreEqual("Automatic Exercise", fills[0].Message); Assert.AreEqual("Option Exercise", fills[1].Message); foreach (var fill in fills) { portfolio.ProcessFill(fill); } // now we have long position in SPY with average price equal to strike var newUnderlyingHoldings = securities[Symbols.SPY].Holdings; // we added 100*192 EUR (strike price) at beginning, all consumed by exercise Assert.AreEqual(0, EUR.Amount); Assert.AreEqual(0, portfolio.CashBook["USD"].Amount); Assert.AreEqual(100, newUnderlyingHoldings.Quantity); Assert.AreEqual(192.0, newUnderlyingHoldings.AveragePrice); // and long call option position has disappeared Assert.AreEqual(0, securities[Symbols.SPY_C_192_Feb19_2016].Holdings.Quantity); }
private void TestSubscriptionSynchronizerSpeed(QCAlgorithm algorithm) { var feed = new MockDataFeed(); var marketHoursDatabase = MarketHoursDatabase.FromDataFolder(); var symbolPropertiesDataBase = SymbolPropertiesDatabase.FromDataFolder(); var securityService = new SecurityService( algorithm.Portfolio.CashBook, marketHoursDatabase, symbolPropertiesDataBase, algorithm); algorithm.Securities.SetSecurityService(securityService); var dataManager = new DataManager(feed, new UniverseSelection(algorithm, securityService), algorithm, algorithm.TimeKeeper, marketHoursDatabase); algorithm.SubscriptionManager.SetDataManager(dataManager); algorithm.Initialize(); algorithm.PostInitialize(); // set exchanges to be always open foreach (var kvp in algorithm.Securities) { var security = kvp.Value; security.Exchange = new SecurityExchange(SecurityExchangeHours.AlwaysOpen(security.Exchange.TimeZone)); } var endTimeUtc = algorithm.EndDate.ConvertToUtc(TimeZones.NewYork); var startTimeUtc = algorithm.StartDate.ConvertToUtc(TimeZones.NewYork); var subscriptionBasedTimeProvider = new SubscriptionFrontierTimeProvider(startTimeUtc, dataManager); var timeSliceFactory = new TimeSliceFactory(algorithm.TimeZone); var synchronizer = new SubscriptionSynchronizer(dataManager.UniverseSelection); synchronizer.SetTimeProvider(subscriptionBasedTimeProvider); synchronizer.SetTimeSliceFactory(timeSliceFactory); var totalDataPoints = 0; var subscriptions = dataManager.DataFeedSubscriptions; foreach (var kvp in algorithm.Securities) { int dataPointCount; subscriptions.TryAdd(CreateSubscription(algorithm, kvp.Value, startTimeUtc, endTimeUtc, out dataPointCount)); totalDataPoints += dataPointCount; } // force JIT synchronizer.Sync(subscriptions); // log what we're doing Console.WriteLine($"Running {subscriptions.Count()} subscriptions with a total of {totalDataPoints} data points. Start: {algorithm.StartDate:yyyy-MM-dd} End: {algorithm.EndDate:yyyy-MM-dd}"); var count = 0; DateTime currentTime = DateTime.MaxValue; DateTime previousValue; var stopwatch = Stopwatch.StartNew(); do { previousValue = currentTime; var timeSlice = synchronizer.Sync(subscriptions); currentTime = timeSlice.Time; count += timeSlice.DataPointCount; }while (currentTime != previousValue); stopwatch.Stop(); var kps = count / 1000d / stopwatch.Elapsed.TotalSeconds; Console.WriteLine($"Current Time: {currentTime:u} Elapsed time: {(int)stopwatch.Elapsed.TotalSeconds,4}s KPS: {kps,7:.00} COUNT: {count,10}"); Assert.GreaterOrEqual(count, 100); // this assert is for sanity purpose }
public void EnumerationWhileUpdatingDoesNotThrow() { var cts = new CancellationTokenSource(); var subscriptions = new SubscriptionCollection(); var start = DateTime.UtcNow; var end = start.AddSeconds(10); var config = new SubscriptionDataConfig(typeof(TradeBar), Symbols.SPY, Resolution.Minute, DateTimeZone.Utc, DateTimeZone.Utc, true, false, false); var security = new Equity( Symbols.SPY, SecurityExchangeHours.AlwaysOpen(DateTimeZone.Utc), new Cash("USD", 0, 1), SymbolProperties.GetDefault("USD"), ErrorCurrencyConverter.Instance ); var timeZoneOffsetProvider = new TimeZoneOffsetProvider(DateTimeZone.Utc, start, end); var enumerator = new EnqueueableEnumerator <BaseData>(); var subscriptionDataEnumerator = SubscriptionData.Enumerator(config, security, timeZoneOffsetProvider, enumerator); var subscription = new Subscription(null, security, config, subscriptionDataEnumerator, timeZoneOffsetProvider, start, end, false); var addTask = new TaskFactory().StartNew(() => { Console.WriteLine("Add task started"); while (DateTime.UtcNow < end) { if (!subscriptions.Contains(config)) { subscriptions.TryAdd(subscription); } Thread.Sleep(1); } Console.WriteLine("Add task ended"); }, cts.Token); var removeTask = new TaskFactory().StartNew(() => { Console.WriteLine("Remove task started"); while (DateTime.UtcNow < end) { Subscription removed; subscriptions.TryRemove(config, out removed); Thread.Sleep(1); } Console.WriteLine("Remove task ended"); }, cts.Token); var readTask = new TaskFactory().StartNew(() => { Console.WriteLine("Read task started"); while (DateTime.UtcNow < end) { foreach (var sub in subscriptions) { } Thread.Sleep(1); } Console.WriteLine("Read task ended"); }, cts.Token); Task.WaitAll(addTask, removeTask, readTask); }