public override OrderEvent MarketFill(Security asset, MarketOrder order) { decimal absoluteRemaining; if (!_absoluteRemainingByOrderId.TryGetValue(order.Id, out absoluteRemaining)) { absoluteRemaining = order.AbsoluteQuantity; } // Create the object var fill = base.MarketFill(asset, order); // Set this fill amount fill.FillQuantity = Math.Sign(order.Quantity) * 10; if (absoluteRemaining == fill.FillQuantity) { fill.Status = OrderStatus.Filled; _absoluteRemainingByOrderId.Remove(order.Id); } else { fill.Status = OrderStatus.PartiallyFilled; _absoluteRemainingByOrderId[order.Id] = absoluteRemaining - fill.FillQuantity; var price = fill.FillPrice; _algorithm.Debug($"{_algorithm.Time} - Partial Fill - Remaining {absoluteRemaining} Price - {price}"); } return(fill); }
public override void Execute(QCAlgorithm algorithm, IPortfolioTarget[] targets) { var orders = targets.GroupBy(t => t.Symbol) .Select( g => new { Symbol = g.Key, Quantity = g.Sum(x => OrderSizing.GetUnorderedQuantity(algorithm, x)) } ) .Where(order => algorithm.Securities[order.Symbol].HasData && order.Quantity != 0); foreach (var order in orders) { var tickets = DoExecute(algorithm, order.Symbol, order.Quantity); foreach (var ticket in tickets) { ticket.OrderClosed .WaitOneAsync() .ContinueWith( task => { if (task.Result) { algorithm.Debug($"{algorithm.Time} - ({ticket.OrderId}) {ticket.QuantityFilled} share of {ticket.Symbol} is filled @{ticket.AverageFillPrice}."); } } ); } } }
/// <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 override void OnSecuritiesChanged(QCAlgorithm algorithm, SecurityChanges changes) { NotifiedSecurityChanges.UpdateCollection(Securities, changes); var symbols = Securities.Select(x => x.Symbol).ToArray(); var history = algorithm.History(symbols, _lookback, _resolution); var vectors = GetPriceVectors(history); if (vectors.LongLength == 0) { algorithm.Debug($"PearsonCorrelationPairsTradingAlphaModel.OnSecuritiesChanged(): The requested historical data does not have series of prices with the same date/time. Please consider increasing the looback period. Current lookback: {_lookback}"); } else { var pearsonMatrix = Correlation.PearsonMatrix(vectors).UpperTriangle(); var maxValue = pearsonMatrix.Enumerate().Where(x => Math.Abs(x) < 1).Max(); if (maxValue >= _minimumCorrelation) { var maxTuple = pearsonMatrix.Find(x => x == maxValue); _bestPair = Tuple.Create(symbols[maxTuple.Item1], symbols[maxTuple.Item2]); } } base.OnSecuritiesChanged(algorithm, changes); }
public override void OnSecuritiesChanged(QCAlgorithm algorithm, SecurityChanges changes) { foreach (var security in changes.RemovedSecurities) { if (_symbolDataBySymbol.ContainsKey(security.Symbol)) { _symbolDataBySymbol.Remove(security.Symbol); } } // Retrieve price history for all securities in the security universe // and update the indicators in the SymbolData object var symbols = changes.AddedSecurities.Select(x => x.Symbol); var history = algorithm.History(symbols, 1, _resolution); if (symbols.Count() > 0 && history.Count() == 0) { algorithm.Debug($"No data on {algorithm.Time}"); } history.PushThrough(bar => { SymbolData symbolData; if (!_symbolDataBySymbol.TryGetValue(bar.Symbol, out symbolData)) { symbolData = new SymbolData(bar.Symbol, _predictionInterval); } symbolData.Update(bar.EndTime, bar.Price); _symbolDataBySymbol[bar.Symbol] = symbolData; }); }
protected override List <OrderTicket> DoExecute(QCAlgorithm algorithm, Symbol symbol, decimal quantity) { var ticket = algorithm.MarketOrder(symbol, quantity, true); algorithm.Debug($"{algorithm.Time} - ({ticket.OrderId}) Placing Market Order for {quantity} share of {symbol}"); return(new List <OrderTicket> { ticket }); }
public override void OnSecuritiesChanged(QCAlgorithm algorithm, SecurityChanges changes) { foreach (var removed in changes.RemovedSecurities) { if (_symbolDataBySymbol.ContainsKey(removed.Symbol)) { _symbolDataBySymbol[removed.Symbol].RemoveConsolidators(algorithm); _symbolDataBySymbol.Remove(removed.Symbol); } } // Initialize data for added securities var symbols = changes.AddedSecurities.Select(x => x.Symbol); var dailyHistory = algorithm.History(symbols, _historyDays + 1, Resolution.Daily); if (symbols.Count() > 0 && dailyHistory.Count() == 0) { algorithm.Debug($"{algorithm.Time} :: No daily data"); } dailyHistory.PushThrough(bar => { SymbolData symbolData; if (!_symbolDataBySymbol.TryGetValue(bar.Symbol, out symbolData)) { symbolData = new SymbolData(algorithm, bar.Symbol, _historyDays, _lookback, _resolution); _symbolDataBySymbol.Add(bar.Symbol, symbolData); } // Update daily rate of change indicator symbolData.UpdateDailyRateOfChange(bar); }); algorithm.History(symbols, _lookback, _resolution).PushThrough(bar => { // Update rate of change indicator with given resolution if (_symbolDataBySymbol.ContainsKey(bar.Symbol)) { _symbolDataBySymbol[bar.Symbol].UpdateRateOfChange(bar); } }); }
/// <summary> /// Send debug message /// </summary> /// <param name="message">String message</param> public void Debug(string message) { _baseAlgorithm.Debug(message); }
/// <summary> /// Override method to write a line to the console in the browser. Made to appear like the System.Console handler. /// </summary> /// <param name="consoleMessage">String message to send to console.</param> /// <seealso cref="Write"/> public static void WriteLine(string consoleMessage) { _algorithmNamespace.Debug(consoleMessage); }
public OrderTicket LimitOrder(QCAlgorithm algorithm, Symbol symbol, decimal quantity, decimal price) { var openOrders = algorithm.Transactions.GetOpenOrders(symbol); void CancelOpenOrder(Order order) { var orderTicket = order.ToOrderTicket(algorithm.Transactions); try { orderTicket.Cancel(); orderTicket .OrderClosed .WaitOneAsync() .ContinueWith( task => { if (task.Result) { lock (_lock) { _pendingQuantity += orderTicket.Quantity - orderTicket.QuantityFilled; } } }); } catch { // ignored } } List <Order> sortedOrders; Order orderToAmend = null; if (quantity > 0) { sortedOrders = openOrders.OrderBy(o => o.Price).ToList(); if (sortedOrders.Any()) { var bestPriceOrder = sortedOrders.Last(); if (bestPriceOrder.Price > price) { price = bestPriceOrder.Price; orderToAmend = bestPriceOrder; } } } else { sortedOrders = openOrders.OrderByDescending(o => o.Price).ToList(); if (sortedOrders.Any()) { var bestPriceOrder = sortedOrders.Last(); if (bestPriceOrder.Price < price) { price = bestPriceOrder.Price; orderToAmend = bestPriceOrder; } } } foreach (var order in sortedOrders.Take(_maxOpenOrders)) { CancelOpenOrder(order); } lock (_lock) { quantity += _pendingQuantity; _pendingQuantity = 0; } if (orderToAmend != null) { var ticket = orderToAmend.ToOrderTicket(algorithm.Transactions); var originalQuantity = ticket.Quantity; try { ticket.UpdateQuantity(originalQuantity + quantity); algorithm.Debug( $"{algorithm.Time} - ({ticket.OrderId}) Update Limit Order of {symbol} from {originalQuantity}@{price} to {quantity}@{price}"); return(ticket); } catch { return(null); } } else { var ticket = algorithm.LimitOrder(symbol, quantity, price); algorithm.Debug($"{algorithm.Time} - ({ticket.OrderId}) Placing Limit Order of {symbol} {quantity}@{price}"); return(ticket); } }
protected void _Log(string Text, params object[] args) { _Algo.Debug(String.Format(Text, args)); }