<commit_before>﻿/*
 * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
 * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
*/

using System;
using System.Collections.Generic;
using System.Linq;
using NodaTime;
using QuantConnect.Brokerages.Alpaca.Markets;
using QuantConnect.Data.Market;
using QuantConnect.Logging;
using QuantConnect.Orders;

namespace QuantConnect.Brokerages.Alpaca
{
    /// <summary>
    /// Alpaca Brokerage utility methods
    /// </summary>
    public partial class AlpacaBrokerage
    {
        /// <summary>
        /// Retrieves the current rate for each of a list of instruments
        /// </summary>
        /// <param name="instruments">the list of instruments to check</param>
        /// <returns>Dictionary containing the current quotes for each instrument</returns>
        private Dictionary<string, Tick> GetRates(IEnumerable<string> instruments)
        {
            CheckRateLimiting();

            var task = _restClient.ListQuotesAsync(instruments);
            var response = task.SynchronouslyAwaitTaskResult();

            return response
                .ToDictionary(
                    x => x.Symbol,
                    x => new Tick
                    {
                        Symbol = Symbol.Create(x.Symbol, SecurityType.Equity, Market.USA),
                        BidPrice = x.BidPrice,
                        AskPrice = x.AskPrice,
                        Time = x.LastTime,
                        TickType = TickType.Quote
                    }
                );
        }

        private IOrder GenerateAndPlaceOrder(Order order)
        {
            var quantity = (long)order.Quantity;
            var side = order.Quantity > 0 ? OrderSide.Buy : OrderSide.Sell;
            if (order.Quantity < 0) quantity = -quantity;
            Markets.OrderType type;
            decimal? limitPrice = null;
            decimal? stopPrice = null;
            var timeInForce = Markets.TimeInForce.Gtc;

            switch (order.Type)
            {
                case Orders.OrderType.Market:
                    type = Markets.OrderType.Market;
                    break;

                case Orders.OrderType.Limit:
                    type = Markets.OrderType.Limit;
                    limitPrice = ((LimitOrder)order).LimitPrice;
                    break;

                case Orders.OrderType.StopMarket:
                    type = Markets.OrderType.Stop;
                    stopPrice = ((StopMarketOrder)order).StopPrice;
                    break;

                case Orders.OrderType.StopLimit:
                    type = Markets.OrderType.StopLimit;
                    stopPrice = ((StopLimitOrder)order).StopPrice;
                    limitPrice = ((StopLimitOrder)order).LimitPrice;
                    break;

                case Orders.OrderType.MarketOnOpen:
                    type = Markets.OrderType.Market;
                    timeInForce = Markets.TimeInForce.Opg;
                    break;

                default:
                    throw new NotSupportedException("The order type " + order.Type + " is not supported.");
            }

            CheckRateLimiting();
            var task = _restClient.PostOrderAsync(order.Symbol.Value, quantity, side, type, timeInForce,
                limitPrice, stopPrice);

            var apOrder = task.SynchronouslyAwaitTaskResult();

            return apOrder;
        }

        /// <summary>
        /// Event handler for streaming events
        /// </summary>
        /// <param name="trade">The event object</param>
        private void OnTradeUpdate(ITradeUpdate trade)
        {
            Log.Trace($"AlpacaBrokerage.OnTradeUpdate(): Event:{trade.Event} OrderId:{trade.Order.OrderId} OrderStatus:{trade.Order.OrderStatus}");

            Order order;
            var tradeEvent = trade.Event.ToUpper();
            lock (_locker)
            {
                order = _orderProvider.GetOrderByBrokerageId(trade.Order.OrderId.ToString());
            }
            if (order != null)
            {
                if (tradeEvent == "FILL" || tradeEvent == "PARTIAL_FILL")
                {
                    order.PriceCurrency = _securityProvider.GetSecurity(order.Symbol).SymbolProperties.QuoteCurrency;

                    var status = Orders.OrderStatus.Filled;
                    if (trade.Order.FilledQuantity < trade.Order.Quantity) status = Orders.OrderStatus.PartiallyFilled;
                    OnOrderEvent(new OrderEvent(order, DateTime.UtcNow, 0, "Alpaca Fill Event")
                    {
                        Status = status,
                        FillPrice = trade.Price.Value,
                        FillQuantity = Convert.ToInt32(trade.Order.Quantity)
                    });
                }
                else if (tradeEvent == "CANCELED")
                {
                    OnOrderEvent(new OrderEvent(order, DateTime.UtcNow, 0, "Alpaca Cancel Order Event") { Status = Orders.OrderStatus.Canceled });
                }
            }
            else
            {
                Log.Error($"AlpacaBrokerage.OnTradeUpdate(): order id not found: {trade.Order.OrderId}");
            }
        }
<commit_msg>Add rejected order cancel brokerage message<commit_after>﻿/*
 * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
 * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
*/

using System;
using System.Collections.Generic;
using System.Linq;
using NodaTime;
using QuantConnect.Brokerages.Alpaca.Markets;
using QuantConnect.Data.Market;
using QuantConnect.Logging;
using QuantConnect.Orders;

namespace QuantConnect.Brokerages.Alpaca
{
    /// <summary>
    /// Alpaca Brokerage utility methods
    /// </summary>
    public partial class AlpacaBrokerage
    {
        /// <summary>
        /// Retrieves the current rate for each of a list of instruments
        /// </summary>
        /// <param name="instruments">the list of instruments to check</param>
        /// <returns>Dictionary containing the current quotes for each instrument</returns>
        private Dictionary<string, Tick> GetRates(IEnumerable<string> instruments)
        {
            CheckRateLimiting();

            var task = _restClient.ListQuotesAsync(instruments);
            var response = task.SynchronouslyAwaitTaskResult();

            return response
                .ToDictionary(
                    x => x.Symbol,
                    x => new Tick
                    {
                        Symbol = Symbol.Create(x.Symbol, SecurityType.Equity, Market.USA),
                        BidPrice = x.BidPrice,
                        AskPrice = x.AskPrice,
                        Time = x.LastTime,
                        TickType = TickType.Quote
                    }
                );
        }

        private IOrder GenerateAndPlaceOrder(Order order)
        {
            var quantity = (long)order.Quantity;
            var side = order.Quantity > 0 ? OrderSide.Buy : OrderSide.Sell;
            if (order.Quantity < 0) quantity = -quantity;
            Markets.OrderType type;
            decimal? limitPrice = null;
            decimal? stopPrice = null;
            var timeInForce = Markets.TimeInForce.Gtc;

            switch (order.Type)
            {
                case Orders.OrderType.Market:
                    type = Markets.OrderType.Market;
                    break;

                case Orders.OrderType.Limit:
                    type = Markets.OrderType.Limit;
                    limitPrice = ((LimitOrder)order).LimitPrice;
                    break;

                case Orders.OrderType.StopMarket:
                    type = Markets.OrderType.Stop;
                    stopPrice = ((StopMarketOrder)order).StopPrice;
                    break;

                case Orders.OrderType.StopLimit:
                    type = Markets.OrderType.StopLimit;
                    stopPrice = ((StopLimitOrder)order).StopPrice;
                    limitPrice = ((StopLimitOrder)order).LimitPrice;
                    break;

                case Orders.OrderType.MarketOnOpen:
                    type = Markets.OrderType.Market;
                    timeInForce = Markets.TimeInForce.Opg;
                    break;

                default:
                    throw new NotSupportedException("The order type " + order.Type + " is not supported.");
            }

            CheckRateLimiting();
            var task = _restClient.PostOrderAsync(order.Symbol.Value, quantity, side, type, timeInForce,
                limitPrice, stopPrice);

            var apOrder = task.SynchronouslyAwaitTaskResult();

            return apOrder;
        }

        /// <summary>
        /// Event handler for streaming events
        /// </summary>
        /// <param name="trade">The event object</param>
        private void OnTradeUpdate(ITradeUpdate trade)
        {
            Log.Trace($"AlpacaBrokerage.OnTradeUpdate(): Event:{trade.Event} OrderId:{trade.Order.OrderId} OrderStatus:{trade.Order.OrderStatus}");

            Order order;
            var tradeEvent = trade.Event.ToUpper();
            lock (_locker)
            {
                order = _orderProvider.GetOrderByBrokerageId(trade.Order.OrderId.ToString());
            }
            if (order != null)
            {
                if (tradeEvent == "FILL" || tradeEvent == "PARTIAL_FILL")
                {
                    order.PriceCurrency = _securityProvider.GetSecurity(order.Symbol).SymbolProperties.QuoteCurrency;

                    var status = Orders.OrderStatus.Filled;
                    if (trade.Order.FilledQuantity < trade.Order.Quantity) status = Orders.OrderStatus.PartiallyFilled;
                    OnOrderEvent(new OrderEvent(order, DateTime.UtcNow, 0, "Alpaca Fill Event")
                    {
                        Status = status,
                        FillPrice = trade.Price.Value,
                        FillQuantity = Convert.ToInt32(trade.Order.Quantity)
                    });
                }
                else if (tradeEvent == "CANCELED")
                {
                    OnOrderEvent(new OrderEvent(order, DateTime.UtcNow, 0, "Alpaca Cancel Order Event") { Status = Orders.OrderStatus.Canceled });
                }
                else if (tradeEvent == "ORDER_CANCEL_REJECTED")
                {
                    var message = $"Order cancellation rejected: OrderId: {order.Id}";
                    OnMessage(new BrokerageMessageEvent(BrokerageMessageType.Warning, -1, message));
                }
            }
            else
            {
                Log.Error($"AlpacaBrokerage.OnTradeUpdate(): order id not found: {trade.Order.OrderId}");
            }
        }

{'fraction_non_alphanumeric': 0.08773553162853298, 'fraction_numerical': 0.0027759084791386273, 'mean_word_length': 1.6573535985695127, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7547955', 'n_tokens_mistral': 3087, 'n_tokens_neox': 2844, 'n_words': 724}