/// <summary> /// Constructor initializes the symbol and period of the RollingWindow /// </summary> /// <param name="symbol">string - ticker symbol</param> /// <param name="period">int - the period of the Trend History Rolling Window</param> /// <param name="tradesize">int - the number of shares to trade</param> /// <param name="algorithm"></param> public RateOfChangePercentStrategy(string symbol, int period, QCAlgorithm algorithm) { //sma20 = new SimpleMovingAverage(20); _symbol = symbol; Price = new RollingWindow<IndicatorDataPoint>(period); _algorithm = algorithm; orderFilled = true; }
/// <summary> /// Empty Consturctor /// </summary> //public InstantTrendStrategy() { } /// <summary> /// Constructor initializes the symbol and period of the RollingWindow /// </summary> /// <param name="symbol">string - ticker symbol</param> /// <param name="period">int - the period of the Trend History Rolling Window</param> /// <param name="algorithm"></param> public InstantTrendStrategyQC(string symbol, int period, QCAlgorithm algorithm) { _symbol = symbol; trendHistory = new RollingWindow<IndicatorDataPoint>(period); _algorithm = algorithm; orderFilled = true; maketrade = true; }
/// <summary> /// Empty Consturctor /// </summary> //public InstantTrendStrategy() { } /// <summary> /// Constructor initializes the symbol and period of the RollingWindow /// </summary> /// <param name="symbol">string - ticker symbol</param> /// <param name="period">int - the period of the Trend History Rolling Window</param> /// <param name="algorithm"></param> public QCLiveSignal(string symbol, int period, QCAlgorithm algorithm) { _symbol = symbol; trendHistory = new RollingWindow<IndicatorDataPoint>(period); _algorithm = algorithm; orderFilled = true; maketrade = true; }
/// <summary> /// Empty Consturctor /// </summary> //public InstantTrendStrategy() { } /// <summary> /// Constructor initializes the symbol and period of the RollingWindow /// </summary> /// <param name="symbol">string - ticker symbol</param> /// <param name="period">int - the period of the Trend History Rolling Window</param> /// <param name="algorithm"></param> public Sig1(Symbol symbol, int period, QCAlgorithm algorithm) { _symbol = symbol; trendHistory = new RollingWindow<IndicatorDataPoint>(3); _algorithm = algorithm; orderFilled = true; maketrade = true; Id = 1; }
public Sig2(Symbol symbol, int period, QCAlgorithm algorithm) { _symbol = symbol; trendHistory = new RollingWindow<decimal>(3); _algorithm = algorithm; orderFilled = true; maketrade = true; trendArray = new decimal[] { 0, 0, 0 }; Id = 2; }
public CustomSlippageModel(QCAlgorithm algorithm) { _algorithm = algorithm; }
public CustomFeeModel(QCAlgorithm algorithm) { _algorithm = algorithm; }
public void Setup() { _algorithm = new QCAlgorithm(); _algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(_algorithm)); _algorithm.HistoryProvider = _testHistoryProvider = new TestHistoryProvider(); }
public void RemoteDataDoesNotIncreaseNumberOfSlices() { Config.Set("quandl-auth-token", "QUANDL-TOKEN"); var startDate = new DateTime(2018, 4, 2); var endDate = new DateTime(2018, 4, 19); var algorithm = new QCAlgorithm(); var timeProvider = new ManualTimeProvider(TimeZones.NewYork); timeProvider.SetCurrentTime(startDate); var dataQueueHandler = new FuncDataQueueHandler(fdqh => { var time = timeProvider.GetUtcNow().ConvertFromUtc(TimeZones.NewYork); var tick = new Tick(time, Symbols.SPY, 1.3m, 1.2m, 1.3m) { TickType = TickType.Trade }; var tick2 = new Tick(time, Symbols.AAPL, 1.3m, 1.2m, 1.3m) { TickType = TickType.Trade }; return(new[] { tick, tick2 }); }); CreateDataFeed(dataQueueHandler); var dataManager = new DataManagerStub(algorithm, _feed); algorithm.SubscriptionManager.SetDataManager(dataManager); var symbols = new List <Symbol> { algorithm.AddData <Quandl>("CBOE/VXV", Resolution.Daily).Symbol, algorithm.AddData <QuandlVix>("CBOE/VIX", Resolution.Daily).Symbol, algorithm.AddEquity("SPY", Resolution.Daily).Symbol, algorithm.AddEquity("AAPL", Resolution.Daily).Symbol }; algorithm.PostInitialize(); var cancellationTokenSource = new CancellationTokenSource(); var dataPointsEmitted = 0; var slicesEmitted = 0; RunLiveDataFeed(algorithm, startDate, symbols, timeProvider, dataManager); Thread.Sleep(5000); // Give remote sources a handicap, so the data is available in time // create a timer to advance time much faster than realtime and to simulate live Quandl data file updates var timerInterval = TimeSpan.FromMilliseconds(100); var timer = Ref.Create <Timer>(null); timer.Value = new Timer(state => { // stop the timer to prevent reentrancy timer.Value.Change(Timeout.Infinite, Timeout.Infinite); var currentTime = timeProvider.GetUtcNow().ConvertFromUtc(TimeZones.NewYork); if (currentTime.Date > endDate.Date) { _feed.Exit(); cancellationTokenSource.Cancel(); return; } timeProvider.Advance(TimeSpan.FromHours(3)); // restart the timer timer.Value.Change(timerInterval, timerInterval); }, null, TimeSpan.FromSeconds(2), timerInterval); try { foreach (var timeSlice in _synchronizer.StreamData(cancellationTokenSource.Token)) { if (timeSlice.Slice.HasData) { slicesEmitted++; dataPointsEmitted += timeSlice.Slice.Values.Count; Assert.IsTrue(timeSlice.Slice.Values.Any(x => x.Symbol == symbols[0]), $"Slice doesn't contain {symbols[0]}"); Assert.IsTrue(timeSlice.Slice.Values.Any(x => x.Symbol == symbols[1]), $"Slice doesn't contain {symbols[1]}"); Assert.IsTrue(timeSlice.Slice.Values.Any(x => x.Symbol == symbols[2]), $"Slice doesn't contain {symbols[2]}"); Assert.IsTrue(timeSlice.Slice.Values.Any(x => x.Symbol == symbols[3]), $"Slice doesn't contain {symbols[3]}"); } } } catch (Exception exception) { Log.Trace($"Error: {exception}"); } timer.Value.Dispose(); Assert.AreEqual(14, slicesEmitted); Assert.AreEqual(14 * symbols.Count, dataPointsEmitted); }
/// <summary> /// Submit orders for the specified portolio targets. /// This model is free to delay or spread out these orders as it sees fit /// </summary> /// <param name="algorithm">The algorithm instance</param> /// <param name="targets">The portfolio targets just emitted by the portfolio construction model. /// These are always just the new/updated targets and not a complete set of targets</param> public virtual void Execute(QCAlgorithm algorithm, IPortfolioTarget[] targets) { throw new System.NotImplementedException("Types deriving from 'ExecutionModel' must implement the 'void Execute(QCAlgorithm, IPortfolioTarget[]) method."); }
/// <summary> /// Defines the coarse fundamental selection function. /// </summary> /// <param name="algorithm">The algorithm instance</param> /// <param name="coarse">The coarse fundamental data used to perform filtering</param> /// <returns>An enumerable of symbols passing the filter</returns> public abstract IEnumerable <Symbol> SelectCoarse(QCAlgorithm algorithm, IEnumerable <CoarseFundamental> coarse);
public override IEnumerable <IPortfolioTarget> CreateTargets(QCAlgorithm algorithm, Insight[] insights) { Insights = insights; return(insights.Select(insight => PortfolioTarget.Percent(algorithm, insight.Symbol, 0.01m))); }
protected override bool IsSafeToRemove(QCAlgorithm algorithm, Symbol symbol) { return(base.IsSafeToRemove(algorithm, symbol)); }
public void Run(Position initialPosition, Position finalPosition, FeeType feeType, PriceMovement priceMovement, int leverage) { //Console.WriteLine("----------"); //Console.WriteLine("PARAMETERS"); //Console.WriteLine("Initial position: " + initialPosition); //Console.WriteLine("Final position: " + finalPosition); //Console.WriteLine("Fee type: " + feeType); //Console.WriteLine("Price movement: " + priceMovement); //Console.WriteLine("Leverage: " + leverage); //Console.WriteLine("----------"); //Console.WriteLine(); var algorithm = new QCAlgorithm(); algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm)); var security = algorithm.AddSecurity(_symbol.ID.SecurityType, _symbol.ID.Symbol); security.FeeModel = _feeModels[feeType]; security.SetLeverage(leverage); var buyingPowerModel = new TestSecurityMarginModel(leverage); security.BuyingPowerModel = buyingPowerModel; algorithm.SetCash(Cash); Update(security, BasePrice); decimal targetPercentage; OrderDirection orderDirection; MarketOrder order; OrderFee orderFee; OrderEvent fill; decimal orderQuantity; decimal freeMargin; decimal requiredMargin; if (initialPosition != Position.Zero) { targetPercentage = (decimal)initialPosition; orderDirection = initialPosition == Position.Long ? OrderDirection.Buy : OrderDirection.Sell; orderQuantity = algorithm.CalculateOrderQuantity(_symbol, targetPercentage); order = new MarketOrder(_symbol, orderQuantity, DateTime.UtcNow); freeMargin = buyingPowerModel.GetMarginRemaining(algorithm.Portfolio, security, orderDirection); requiredMargin = buyingPowerModel.GetInitialMarginRequiredForOrder( new InitialMarginRequiredForOrderParameters( new IdentityCurrencyConverter(algorithm.Portfolio.CashBook.AccountCurrency), security, order)); //Console.WriteLine("Current price: " + security.Price); //Console.WriteLine("Target percentage: " + targetPercentage); //Console.WriteLine("Order direction: " + orderDirection); //Console.WriteLine("Order quantity: " + orderQuantity); //Console.WriteLine("Free margin: " + freeMargin); //Console.WriteLine("Required margin: " + requiredMargin); //Console.WriteLine(); Assert.That(Math.Abs(requiredMargin) <= freeMargin); orderFee = security.FeeModel.GetOrderFee( new OrderFeeParameters(security, order, Currencies.USD)); fill = new OrderEvent(order, DateTime.UtcNow, orderFee) { FillPrice = security.Price, FillQuantity = orderQuantity }; algorithm.Portfolio.ProcessFill(fill); //Console.WriteLine("Portfolio.Cash: " + algorithm.Portfolio.Cash); //Console.WriteLine("Portfolio.TotalPortfolioValue: " + algorithm.Portfolio.TotalPortfolioValue); //Console.WriteLine(); if (priceMovement == PriceMovement.RisingSmall) { Update(security, HighPrice); } else if (priceMovement == PriceMovement.FallingSmall) { Update(security, LowPrice); } else if (priceMovement == PriceMovement.RisingLarge) { Update(security, VeryHighPrice); } else if (priceMovement == PriceMovement.FallingLarge) { Update(security, VeryLowPrice); } } targetPercentage = (decimal)finalPosition; orderDirection = finalPosition == Position.Long || (finalPosition == Position.Zero && initialPosition == Position.Short) ? OrderDirection.Buy : OrderDirection.Sell; orderQuantity = algorithm.CalculateOrderQuantity(_symbol, targetPercentage); order = new MarketOrder(_symbol, orderQuantity, DateTime.UtcNow); freeMargin = buyingPowerModel.GetMarginRemaining(algorithm.Portfolio, security, orderDirection); requiredMargin = buyingPowerModel.GetInitialMarginRequiredForOrder( new InitialMarginRequiredForOrderParameters( new IdentityCurrencyConverter(algorithm.Portfolio.CashBook.AccountCurrency), security, order)); //Console.WriteLine("Current price: " + security.Price); //Console.WriteLine("Target percentage: " + targetPercentage); //Console.WriteLine("Order direction: " + orderDirection); //Console.WriteLine("Order quantity: " + orderQuantity); //Console.WriteLine("Free margin: " + freeMargin); //Console.WriteLine("Required margin: " + requiredMargin); //Console.WriteLine(); Assert.That(Math.Abs(requiredMargin) <= freeMargin); orderFee = security.FeeModel.GetOrderFee( new OrderFeeParameters(security, order, Currencies.USD)); fill = new OrderEvent(order, DateTime.UtcNow, orderFee) { FillPrice = security.Price, FillQuantity = orderQuantity }; algorithm.Portfolio.ProcessFill(fill); //Console.WriteLine("Portfolio.Cash: " + algorithm.Portfolio.Cash); //Console.WriteLine("Portfolio.TotalPortfolioValue: " + algorithm.Portfolio.TotalPortfolioValue); //Console.WriteLine(); }
/// <summary> /// Determines if it's safe to remove the associated symbol data /// </summary> protected virtual bool IsSafeToRemove(QCAlgorithm algorithm, Symbol symbol) { // confirm the security isn't currently a member of any universe return(!algorithm.UniverseManager.Any(kvp => kvp.Value.ContainsMember(symbol))); }
public MinimumAccountBalanceBrokerageModel(QCAlgorithm algorithm, decimal minimumAccountBalance) { _algorithm = algorithm; _minimumAccountBalance = minimumAccountBalance; }
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); _transactionHandler.Initialize(_algorithm, _brokerage, new TestResultHandler()); _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), 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), 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), 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), ErrorCurrencyConverter.Instance, RegisteredSecurityDataTypesProvider.Null ); _buyingPowerModel = new CashBuyingPowerModel(); _timeKeeper = new LocalTimeKeeper(new DateTime(2019, 4, 22), DateTimeZone.Utc); _btcusd.SetLocalTimeKeeper(_timeKeeper); _ethusd.SetLocalTimeKeeper(_timeKeeper); _btceur.SetLocalTimeKeeper(_timeKeeper); _ethbtc.SetLocalTimeKeeper(_timeKeeper); }
public EitPfeNdxAlgo(QCAlgorithm algo, decimal cash = 0) : base(algo, cash) { }
public override void Execute(QCAlgorithm algorithm, IPortfolioTarget[] targets) { // NOP }
public InstantTrendBetSizer(QCAlgorithm algorithm) { this._algorithm = algorithm; }
public void SetAlgorithm(QCAlgorithm algorithm) { _algorithm = algorithm; }
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 ); 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 void TestSubscriptionSynchronizerSpeed(QCAlgorithm algorithm) { var feed = new AlgorithmManagerTests.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(feed, algorithm, securityService), algorithm.Settings, 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 synchronizer = new SubscriptionSynchronizer(dataManager.UniverseSelection, algorithm.Portfolio.CashBook); synchronizer.SetTimeProvider(subscriptionBasedTimeProvider); synchronizer.SetSliceTimeZone(algorithm.TimeZone); 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 }
/// <summary> /// Updates this alpha model with the latest data from the algorithm. /// This is called each time the algorithm receives data for subscribed securities /// </summary> /// <param name="algorithm">The algorithm instance</param> /// <param name="data">The new data available</param> /// <returns>The new insights generated</returns> public override IEnumerable <Insight> Update(QCAlgorithm algorithm, Slice data) { return(Enumerable.Empty <Insight>()); }
public override IEnumerable <Insight> Update(QCAlgorithm algorithm, Slice data) { yield return(Insight.Price(Symbols.SPY, TimeSpan.FromDays(1), InsightDirection.Up, .5, .75)); }
public Contract_ES(QCAlgorithm Algorithm_ES) { _Algorithm_ES = Algorithm_ES; }
/// <summary> /// Defines the fine fundamental selection function. /// </summary> /// <param name="algorithm">The algorithm instance</param> /// <param name="fine">The fine fundamental data used to perform filtering</param> /// <returns>An enumerable of symbols passing the filter</returns> public virtual IEnumerable <Symbol> SelectFine(QCAlgorithm algorithm, IEnumerable <FineFundamental> fine) { // default impl performs no filtering of fine data return(fine.Select(f => f.Symbol)); }
public CustomBuyingPowerModel(QCAlgorithm algorithm) { _algorithm = algorithm; }
public override void OnSecuritiesChanged(QCAlgorithm algorithm, SecurityChanges changes) { }
public CustomPartialFillModel(QCAlgorithm algorithm) : base() { _algorithm = algorithm; _absoluteRemainingByOrderId = new Dictionary <int, decimal>(); }
/// <summary> /// Event fired each time the we add/remove securities from the data feed /// </summary> /// <param name="algorithm">The algorithm instance that experienced the change in securities</param> /// <param name="changes">The security additions and removals from the algorithm</param> public virtual void OnSecuritiesChanged(QCAlgorithm algorithm, SecurityChanges changes) { }
/// <summary> /// Updates this alpha model with the latest data from the algorithm. /// This is called each time the algorithm receives data for subscribed securities /// </summary> /// <param name="algorithm">The algorithm instance</param> /// <param name="data">The new data available</param> /// <returns>The new insights generated</returns> public virtual IEnumerable <Insight> Update(QCAlgorithm algorithm, Slice data) { throw new System.NotImplementedException("Types deriving from 'AlphaModel' must implement the 'IEnumerable<Insight> Update(QCAlgorithm, Slice) method."); }
public void EmitsDailyQuandlFutureDataOverWeekends() { RemoteFileSubscriptionStreamReader.SetDownloadProvider(new Api.Api()); var tickers = new[] { "CHRIS/CME_ES1", "CHRIS/CME_ES2" }; var startDate = new DateTime(2018, 4, 1); var endDate = new DateTime(2018, 4, 20); // delete temp files foreach (var ticker in tickers) { var fileName = TestableQuandlFuture.GetLocalFileName(ticker, "test"); File.Delete(fileName); } var algorithm = new QCAlgorithm(); CreateDataFeed(); var dataManager = new DataManagerStub(algorithm, _feed); algorithm.SubscriptionManager.SetDataManager(dataManager); var symbols = tickers.Select(ticker => algorithm.AddData <TestableQuandlFuture>(ticker, Resolution.Daily).Symbol).ToList(); var timeProvider = new ManualTimeProvider(TimeZones.NewYork); timeProvider.SetCurrentTime(startDate); var dataPointsEmitted = 0; RunLiveDataFeed(algorithm, startDate, symbols, timeProvider, dataManager); var cancellationTokenSource = new CancellationTokenSource(); var lastFileWriteDate = DateTime.MinValue; // create a timer to advance time much faster than realtime and to simulate live Quandl data file updates var timerInterval = TimeSpan.FromMilliseconds(20); var timer = Ref.Create <Timer>(null); timer.Value = new Timer(state => { try { var currentTime = timeProvider.GetUtcNow().ConvertFromUtc(TimeZones.NewYork); if (currentTime.Date > endDate.Date) { Log.Trace($"Total data points emitted: {dataPointsEmitted}"); _feed.Exit(); cancellationTokenSource.Cancel(); return; } if (currentTime.Date > lastFileWriteDate.Date) { foreach (var ticker in tickers) { var source = TestableQuandlFuture.GetLocalFileName(ticker, "csv"); // write new local file including only rows up to current date var outputFileName = TestableQuandlFuture.GetLocalFileName(ticker, "test"); var sb = new StringBuilder(); { using (var reader = new StreamReader(source)) { var firstLine = true; string line; while ((line = reader.ReadLine()) != null) { if (firstLine) { sb.AppendLine(line); firstLine = false; continue; } var csv = line.Split(','); var time = DateTime.ParseExact(csv[0], "yyyy-MM-dd", CultureInfo.InvariantCulture); if (time.Date >= currentTime.Date) { break; } sb.AppendLine(line); } } } if (currentTime.Date.DayOfWeek != DayOfWeek.Saturday && currentTime.Date.DayOfWeek != DayOfWeek.Sunday) { var fileContent = sb.ToString(); try { File.WriteAllText(outputFileName, fileContent); } catch (IOException) { Log.Error("IOException: will sleep 200ms and retry once more"); // lets sleep 200ms and retry once more, consumer could be reading the file // this exception happens in travis intermittently, GH issue 3273 Thread.Sleep(200); File.WriteAllText(outputFileName, fileContent); } Log.Trace($"Time:{currentTime} - Ticker:{ticker} - Files written:{++_countFilesWritten}"); } } lastFileWriteDate = currentTime; } // 30 minutes is the check interval for daily remote files, so we choose a smaller one to advance time timeProvider.Advance(TimeSpan.FromMinutes(20)); //Log.Trace($"Time advanced to: {timeProvider.GetUtcNow().ConvertFromUtc(TimeZones.NewYork)}"); // restart the timer timer.Value.Change(timerInterval.Milliseconds, Timeout.Infinite); } catch (Exception exception) { Log.Error(exception); _feed.Exit(); cancellationTokenSource.Cancel(); } }, null, timerInterval.Milliseconds, Timeout.Infinite); try { foreach (var timeSlice in _synchronizer.StreamData(cancellationTokenSource.Token)) { foreach (var dataPoint in timeSlice.Slice.Values) { Log.Trace($"Data point emitted at {timeSlice.Slice.Time}: {dataPoint.Symbol.Value} {dataPoint.Value} {dataPoint.EndTime}"); dataPointsEmitted++; } } } catch (Exception exception) { Log.Trace($"Error: {exception}"); } timer.Value.Dispose(); Assert.AreEqual(14 * tickers.Length, dataPointsEmitted); }
/// <inheritdoc /> public override IEnumerable <Symbol> SelectCoarse(QCAlgorithm algorithm, IEnumerable <CoarseFundamental> coarse) { return(_coarseSelector(coarse)); }
public SymbolData(Symbol symbol, QCAlgorithm algorithm) { Symbol = symbol; Security = algorithm.Securities[symbol]; Close = algorithm.Identity(symbol); ADX = algorithm.ADX(symbol, 14); EMA = algorithm.EMA(symbol, 14); MACD = algorithm.MACD(symbol, 12, 26, 9); // if we're receiving daily _algorithm = algorithm; }
/// <inheritdoc /> public override IEnumerable <Symbol> SelectFine(QCAlgorithm algorithm, IEnumerable <FineFundamental> fine) { return(_fineSelector(fine)); }
public void AddDataSecurityTickerWithUnderlying(string ticker, Type customDataType, SecurityType securityType, bool securityShouldBeMapped, bool customDataShouldBeMapped) { SymbolCache.Clear(); var qcAlgorithm = new QCAlgorithm(); qcAlgorithm.SubscriptionManager.SetDataManager(new DataManagerStub(qcAlgorithm)); Security asset; switch (securityType) { case SecurityType.Cfd: asset = qcAlgorithm.AddCfd(ticker, Resolution.Daily); break; case SecurityType.Crypto: asset = qcAlgorithm.AddCrypto(ticker, Resolution.Daily); break; case SecurityType.Equity: asset = qcAlgorithm.AddEquity(ticker, Resolution.Daily); break; case SecurityType.Forex: asset = qcAlgorithm.AddForex(ticker, Resolution.Daily); break; case SecurityType.Future: asset = qcAlgorithm.AddFuture(ticker, Resolution.Daily); break; default: throw new Exception($"SecurityType {securityType} is not valid for this test"); } // Aliased value for Futures contains a forward-slash, which causes the // lookup in the SymbolCache to fail if (securityType == SecurityType.Future) { ticker = asset.Symbol.Value; } // Dummy here is meant to try to corrupt the SymbolCache. Ideally, SymbolCache should return non-custom data types with higher priority // in case we want to add two custom data types, but still have them associated with the equity from the cache if we're using it. // This covers the case where two idential data subscriptions are created. var dummy = qcAlgorithm.AddData(customDataType, ticker, Resolution.Daily, qcAlgorithm.SubscriptionManager.Subscriptions.Where(x => x.SecurityType == securityType).First().DataTimeZone); var customData = qcAlgorithm.AddData(customDataType, ticker, Resolution.Daily, qcAlgorithm.SubscriptionManager.Subscriptions.Where(x => x.SecurityType == securityType).First().DataTimeZone); Assert.IsTrue(customData.Symbol.HasUnderlying, $"Custom data added as {ticker} Symbol with SecurityType {securityType} does not have underlying"); Assert.AreEqual(customData.Symbol.Underlying, asset.Symbol, $"Custom data underlying does not match {securityType} Symbol for {ticker}"); var assetSubscription = qcAlgorithm.SubscriptionManager.Subscriptions.Where(x => x.SecurityType == securityType).First(); var customDataSubscription = qcAlgorithm.SubscriptionManager.Subscriptions.Where(x => x.SecurityType == SecurityType.Base).Single(); var assetShouldBeMapped = assetSubscription.TickerShouldBeMapped(); var customShouldBeMapped = customDataSubscription.TickerShouldBeMapped(); if (securityType == SecurityType.Equity) { Assert.AreEqual(securityShouldBeMapped, assetShouldBeMapped); Assert.AreEqual(customDataShouldBeMapped, customShouldBeMapped); Assert.AreNotEqual(assetSubscription, customDataSubscription); if (assetShouldBeMapped == customShouldBeMapped) { Assert.AreEqual(assetSubscription.MappedSymbol, customDataSubscription.MappedSymbol); Assert.AreEqual(asset.Symbol.Value, customData.Symbol.Value.Split('.').First()); } } }
public CustomFillModel(QCAlgorithm algorithm) { _algorithm = algorithm; }
public void AddDataSecurityTickerNoUnderlying(string ticker, Type customDataType, SecurityType securityType, bool securityShouldBeMapped, bool customDataShouldBeMapped) { SymbolCache.Clear(); var qcAlgorithm = new QCAlgorithm(); qcAlgorithm.SubscriptionManager.SetDataManager(new DataManagerStub(qcAlgorithm)); Security asset; switch (securityType) { case SecurityType.Cfd: asset = qcAlgorithm.AddCfd(ticker, Resolution.Daily); break; case SecurityType.Crypto: asset = qcAlgorithm.AddCrypto(ticker, Resolution.Daily); break; case SecurityType.Equity: asset = qcAlgorithm.AddEquity(ticker, Resolution.Daily); break; case SecurityType.Forex: asset = qcAlgorithm.AddForex(ticker, Resolution.Daily); break; case SecurityType.Future: asset = qcAlgorithm.AddFuture(ticker, Resolution.Daily); break; default: throw new Exception($"SecurityType {securityType} is not valid for this test"); } // Dummy here is meant to try to corrupt the SymbolCache. Ideally, SymbolCache should return non-custom data types with higher priority // in case we want to add two custom data types, but still have them associated with the equity from the cache if we're using it. // This covers the case where two idential data subscriptions are created. var dummy = qcAlgorithm.AddData(customDataType, ticker, Resolution.Daily, qcAlgorithm.SubscriptionManager.Subscriptions.Where(x => x.SecurityType == securityType).First().DataTimeZone); var customData = qcAlgorithm.AddData(customDataType, ticker, Resolution.Daily, qcAlgorithm.SubscriptionManager.Subscriptions.Where(x => x.SecurityType == securityType).First().DataTimeZone); // Check to see if we have an underlying symbol when we shouldn't Assert.IsFalse(customData.Symbol.HasUnderlying, $"{customDataType.Name} has underlying symbol for SecurityType {securityType} with ticker {ticker}"); Assert.AreEqual(customData.Symbol.Underlying, null, $"{customDataType.Name} - Custom data underlying Symbol for SecurityType {securityType} is not null"); var assetSubscription = qcAlgorithm.SubscriptionManager.Subscriptions.Where(x => x.SecurityType == securityType).First(); var customDataSubscription = qcAlgorithm.SubscriptionManager.Subscriptions.Where(x => x.SecurityType == SecurityType.Base).Single(); var assetShouldBeMapped = assetSubscription.TickerShouldBeMapped(); var customShouldBeMapped = customDataSubscription.TickerShouldBeMapped(); Assert.AreEqual(securityShouldBeMapped, assetShouldBeMapped); Assert.AreEqual(customDataShouldBeMapped, customShouldBeMapped); Assert.AreNotEqual(assetSubscription, customDataSubscription); if (assetShouldBeMapped == customShouldBeMapped) { // Would fail with CL future without this check because MappedSymbol returns "/CL" for the Future symbol if (assetSubscription.SecurityType == SecurityType.Future) { Assert.AreNotEqual(assetSubscription.MappedSymbol, customDataSubscription.MappedSymbol); Assert.AreNotEqual(asset.Symbol.Value, customData.Symbol.Value.Split('.').First()); } else { Assert.AreEqual(assetSubscription.MappedSymbol, customDataSubscription.MappedSymbol); Assert.AreEqual(asset.Symbol.Value, customData.Symbol.Value.Split('.').First()); } } }
/// <summary> /// Initialize the Console override to send the messages to the algorithm debug function. /// </summary> /// <param name="algorithmNamespace">Algorithm Debug Function Access</param> public static void Initialize(QCAlgorithm algorithmNamespace) { _algorithmNamespace = algorithmNamespace; }
public void OrdersAreSubmittedWhenRequiredForTargetsToExecute( Language language, decimal currentPrice, int expectedOrdersSubmitted, decimal expectedTotalQuantity) { var actualOrdersSubmitted = new List <SubmitOrderRequest>(); var time = new DateTime(2018, 8, 2, 14, 0, 0); var algorithm = new QCAlgorithm(); algorithm.SetPandasConverter(); algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm)); algorithm.SetDateTime(time.AddMinutes(5)); var security = algorithm.AddEquity(Symbols.AAPL.Value); security.SetMarketPrice(new TradeBar { Value = 250 }); // pushing the ask higher will cause the spread the widen and no trade to happen var ask = expectedOrdersSubmitted == 0 ? currentPrice * 1.1m : currentPrice; security.SetMarketPrice(new QuoteBar { Time = time, Symbol = Symbols.AAPL, Ask = new Bar(ask, ask, ask, ask), Bid = new Bar(currentPrice, currentPrice, currentPrice, currentPrice) }); algorithm.SetFinishedWarmingUp(); var orderProcessor = new Mock <IOrderProcessor>(); orderProcessor.Setup(m => m.Process(It.IsAny <SubmitOrderRequest>())) .Returns((SubmitOrderRequest request) => new OrderTicket(algorithm.Transactions, request)) .Callback((OrderRequest request) => actualOrdersSubmitted.Add((SubmitOrderRequest)request)); orderProcessor.Setup(m => m.GetOpenOrders(It.IsAny <Func <Order, bool> >())) .Returns(new List <Order>()); algorithm.Transactions.SetOrderProcessor(orderProcessor.Object); var model = GetExecutionModel(language); algorithm.SetExecution(model); var changes = new SecurityChanges(new[] { security }, Enumerable.Empty <Security>()); model.OnSecuritiesChanged(algorithm, changes); var targets = new IPortfolioTarget[] { new PortfolioTarget(Symbols.AAPL, 10) }; model.Execute(algorithm, targets); Assert.AreEqual(expectedOrdersSubmitted, actualOrdersSubmitted.Count); Assert.AreEqual(expectedTotalQuantity, actualOrdersSubmitted.Sum(x => x.Quantity)); if (actualOrdersSubmitted.Count == 1) { var request = actualOrdersSubmitted[0]; Assert.AreEqual(expectedTotalQuantity, request.Quantity); Assert.AreEqual(algorithm.UtcTime, request.Time); } }