コード例 #1
0
ファイル: DBOrders.cs プロジェクト: mpvyard/ServiceNimbus
        public IEnumerable <Order> GetOrderHistory(AccountInfo info, int count, int skip)
        {
            if (skip < 0 || count < 1)
            {
                return(new List <Order>(0));
            }

            var result = new List <Order>();

            using (var aConnection = new SqlConnection(_connectionString))
            {
                //select N latest records of each symbol
                var cmd = new SqlCommand("WITH TOPRECORDS AS ( "
                                         + "SELECT s.[Symbol], h.[Quantity], h.[ExecutedQuantity], h.[Status], h.[OrderId], h.[Price], "
                                         + "h.[Type], h.[TIF], h.[Date], h.[BrokerID], h.[OpeningQuantity], h.[ClosingQuantity], h.[Origin], ROW_NUMBER() "
                                         + "OVER(PARTITION BY h.[Symbol], h.[DataFeed] ORDER BY [Date] DESC) AS RowNumber FROM [Orders] AS h "
                                         + "INNER JOIN[dbo].[Securities] AS s ON s.Symbol = h.Symbol AND s.DataFeed = h.DataFeed "
                                         + "WHERE h.[UserName] = @userName AND h.[AccountId] = @account AND h.[BrokerName] = @broker) "
                                         + "SELECT * FROM TOPRECORDS WHERE RowNumber > @start AND RowNumber <= @end", aConnection);
                cmd.Parameters.AddWithValue("start", skip);
                cmd.Parameters.AddWithValue("end", skip + count);
                cmd.Parameters.AddWithValue("userName", info.UserName);
                cmd.Parameters.AddWithValue("account", info.ID);
                cmd.Parameters.AddWithValue("broker", info.BrokerName);

                SqlTransaction transaction = null;
                try
                {
                    aConnection.Open();
                    transaction     = aConnection.BeginTransaction(System.Data.IsolationLevel.ReadUncommitted, "Orders Select");
                    cmd.Transaction = transaction;

                    using (var reader = cmd.ExecuteReader())
                    {
                        if (!reader.HasRows)
                        {
                            return(result);
                        }

                        while (reader.Read())
                        {
                            try
                            {
                                var qty     = (decimal)reader["Quantity"];
                                var execQty = (decimal)reader["ExecutedQuantity"];
                                var status  = DBConverters.ParseOrderStatus((string)reader["Status"]);
                                var order   = new Order((string)reader["OrderId"], (string)reader["Symbol"])
                                {
                                    BrokerID          = (string)reader["BrokerID"],
                                    AvgFillPrice      = status == Status.Filled ? (decimal)reader["Price"] : 0,
                                    Price             = status == Status.Cancelled ? (decimal)reader["Price"] : 0,
                                    OrderSide         = qty > 0 ? Side.Buy : Side.Sell,
                                    OrderType         = DBConverters.ParseOrderType((string)reader["Type"]),
                                    BrokerName        = info.BrokerName,
                                    AccountId         = info.ID,
                                    TimeInForce       = DBConverters.ParseTif((string)reader["TIF"]),
                                    OpenDate          = (DateTime)reader["Date"],
                                    CancelledQuantity = status == Status.Cancelled ? Math.Abs(execQty) : 0,
                                    FilledQuantity    = status == Status.Filled ? Math.Abs(execQty) : 0,
                                    OpeningQty        = status == Status.Filled ? (decimal)reader["OpeningQuantity"] : 0,
                                    ClosingQty        = status == Status.Filled ? (decimal)reader["ClosingQuantity"] : 0,
                                    Origin            = reader["Origin"] as string
                                };

                                if (status == Status.Cancelled)
                                {
                                    order.CancelledQuantity = Math.Abs(qty);
                                }
                                else
                                {
                                    order.FilledQuantity = Math.Abs(qty);
                                }

                                result.Add(order);
                            }
                            catch (Exception ex)
                            {
                                Logger.Error("Failed to parse historical order", ex);
                            }
                        }
                    }

                    transaction.Commit();
                }
                catch (Exception e)
                {
                    Logger.Error("Failed to load order history", e);
                    transaction?.Rollback();
                    return(result);
                }
            }
            return(result);
        }
コード例 #2
0
ファイル: DBSignals.cs プロジェクト: mpvyard/ServiceNimbus
        public List <ReportField> GetReport(string userName, string strategyName, DateTime startDate, DateTime endDate)
        {
            var result = new List <ReportField>();

            using (var aConnection = new SqlConnection(_connectionString))
            {
                var cmd = new SqlCommand(
                    "SELECT o.Symbol, o.Type, o.Status, o.TIF, o.ExecutedQuantity, s.SignalName, s.Date as SignalDate,"
                    + " s.DataBaseEntry as SignalDBDate, o.Date, o.FilledDate, o.DataBaseEntry as OrderDBDate"
                    + " FROM[dbo].[Orders] o"
                    + " LEFT JOIN[dbo].[Signals] s ON o.SignalID = s.SignalID"
                    + " WHERE s.UserLogin = @userLogin AND s.SignalName = @signalName  AND s.Date BETWEEN @startDate AND @endDate", aConnection);

                cmd.Parameters.AddWithValue("userLogin", userName);
                cmd.Parameters.AddWithValue("signalName", strategyName);
                cmd.Parameters.AddWithValue("startDate", startDate);
                cmd.Parameters.AddWithValue("endDate", endDate);

                SqlTransaction transaction = null;
                try
                {
                    aConnection.Open();
                    transaction =
                        aConnection.BeginTransaction(System.Data.IsolationLevel.ReadUncommitted, "Orders Select");
                    cmd.Transaction = transaction;

                    using (var reader = cmd.ExecuteReader())
                    {
                        if (!reader.HasRows)
                        {
                            return(result);
                        }

                        while (reader.Read())
                        {
                            try
                            {
                                var qty = (decimal)reader["ExecutedQuantity"];

                                var field = new ReportField
                                {
                                    Symbol                  = (string)reader["Symbol"],
                                    TradeType               = DBConverters.ParseOrderType((string)reader["Type"]),
                                    Status                  = DBConverters.ParseOrderStatus((string)reader["Status"]),
                                    TimeInForce             = DBConverters.ParseTif((string)reader["TIF"]),
                                    Quantity                = qty,
                                    Side                    = qty > 0 ? Side.Buy : Side.Sell,
                                    SignalName              = (string)reader["SignalName"],
                                    SignalGeneratedDateTime = (DateTime)reader["SignalDate"],
                                    OrderFilledDate         = (DateTime)reader["FilledDate"],
                                    OrderGeneratedDate      = (DateTime)reader["Date"],
                                    DBOrderEntryDate        = (DateTime)reader["OrderDBDate"],
                                    DBSignalEntryDate       = (DateTime)reader["SignalDBDate"]
                                };

                                field.CalculateDiff();
                                result.Add(field);
                            }
                            catch (Exception ex)
                            {
                                Logger.Error("Failed to parse report field", ex);
                            }
                        }
                    }

                    transaction.Commit();
                }
                catch (Exception e)
                {
                    Logger.Error("Failed to load report", e);
                    transaction?.Rollback();
                    return(result);
                }
            }

            return(result);
        }
コード例 #3
0
ファイル: DBOrders.cs プロジェクト: mpvyard/ServiceNimbus
        public void AddHistoricalOrder(Order order, AccountInfo info, Status status, bool canRetry = false)
        {
            using (var aConnection = new SqlConnection(_connectionString))
            {
                ////simple insert
                var cmd = new SqlCommand("INSERT INTO [dbo].[Orders] ([OrderId],[BrokerID],[SignalID],[BrokerName],[DataFeed],[UserName],[AccountId],[Symbol],[Price],[Quantity],[ExecutedQuantity],[Status],"
                                         + "[Type],[TIF],[Date],[PlacedDate],[FilledDate],[OpeningQuantity],[ClosingQuantity],[Origin]) "
                                         + "VALUES (@orderId, @brokerId, @signalId, @brokerName, @dataFeed, @userName, @accountId, @symbol, @price, @qty, @execQty, @status, "
                                         + "@type, @tif, @openDate, @placedDate, @filledDate, @openingQty, @closingQty, @origin);", aConnection);

                //upsert via MERGE
                //var cmd1 = new SqlCommand("MERGE [dbo].[Orders] AS Target "
                //                         + "USING (VALUES(@orderId, @brokerId, @signalId, @brokerName, @accountId, @symbol, @datafeed, @price, @qty, @execQty, @status, "
                //                         + "@type, @tif, @openDate, @placedDate, @filledDate, @openingQty, @closingQty, @origin)) "
                //                         + "AS item([OrderId],[BrokerID],[SignalID],[BrokerName],[AccountId],[Symbol],[DataFeed],[Price],[Quantity],[ExecutedQuantity],"
                //                         + "[Status],[Type],[TIF],[Date],[PlacedDate],[FilledDate],[OpeningQuantity],[ClosingQuantity],[Origin]) "
                //                         + "ON (Target.OrderId = item.OrderId AND Target.BrokerID = item.BrokerID AND Target.SignalID = item.SignalID AND Target.AccountId = item.AccountId) "
                //                         + "WHEN MATCHED THEN "
                //                         + "UPDATE SET Target.Price = item.Price, Target.Quantity = item.Quantity, Target.ExecutedQuantity = item.ExecutedQuantity, "
                //                         + "Target.Status = item.Status, Target.[Type] = item.[Type], Target.TIF = item.TIF, Target.[Date] = item.[Date], "
                //                         + "Target.[PlacedDate] = item.[PlacedDate], Target.[FilledDate] = item.[FilledDate], "
                //                         + "Target.OpeningQuantity = item.OpeningQuantity, Target.ClosingQuantity = item.ClosingQuantity,Target.Origin = item.Origin "
                //                         + "WHEN NOT MATCHED BY TARGET THEN "
                //                         + "INSERT ([OrderId],[BrokerID],[SignalID],[BrokerName],[AccountId],[Symbol],[DataFeed],[Price],[Quantity],[ExecutedQuantity],[Status],"
                //                         + "[Type],[TIF],[Date],[PlacedDate],[FilledDate],[OpeningQuantity],[ClosingQuantity],[Origin]) "
                //                         + "VALUES (item.OrderId,item.BrokerID,item.SignalID,item.BrokerName,item.AccountId,item.Symbol,item.DataFeed,item.Price,"
                //                         + "item.Quantity,item.ExecutedQuantity,item.Status,item.[Type],item.TIF,item.[Date],item.[PlacedDate],item.[FilledDate],"
                //                         + "item.OpeningQuantity,item.ClosingQuantity,item.Origin);", aConnection);

                cmd.Parameters.AddWithValue("orderId", order.UserID);
                cmd.Parameters.AddWithValue("brokerId", order.BrokerID);
                cmd.Parameters.AddWithValue("brokerName", info.BrokerName);
                cmd.Parameters.AddWithValue("datafeed", order.DataFeedName);
                cmd.Parameters.AddWithValue("userName", info.UserName);
                cmd.Parameters.AddWithValue("accountId", info.ID);
                cmd.Parameters.AddWithValue("symbol", order.Symbol);
                cmd.Parameters.AddWithValue("qty", order.OrderSide == Side.Buy ? order.Quantity : -order.Quantity);
                cmd.Parameters.AddWithValue("openingQty", order.OpeningQty);
                cmd.Parameters.AddWithValue("closingQty", order.ClosingQty);
                cmd.Parameters.AddWithValue("status", DBConverters.OrderStatusToString(status));
                cmd.Parameters.AddWithValue("type", DBConverters.OrderTypeToString(order.OrderType));
                cmd.Parameters.AddWithValue("tif", DBConverters.TifToString(order.TimeInForce));
                cmd.Parameters.AddWithValue("openDate", order.OpenDate);
                cmd.Parameters.AddWithValue("placedDate", order.PlacedDate);
                cmd.Parameters.AddWithValue("filledDate", order.FilledDate);

                if (order.SignalID == null)
                {
                    cmd.Parameters.AddWithValue("signalId", DBNull.Value);
                }
                else
                {
                    cmd.Parameters.AddWithValue("signalId", order.SignalID);
                }

                if (string.IsNullOrWhiteSpace(order.Origin))
                {
                    cmd.Parameters.AddWithValue("origin", DBNull.Value);
                }
                else
                {
                    cmd.Parameters.AddWithValue("origin", order.Origin);
                }

                if (status == Status.Filled)
                {
                    cmd.Parameters.AddWithValue("execQty",
                                                order.OrderSide == Side.Buy ? order.FilledQuantity : -order.FilledQuantity);
                    cmd.Parameters.AddWithValue("price", order.AvgFillPrice);
                }
                else if (status == Status.Cancelled)
                {
                    cmd.Parameters.AddWithValue("execQty",
                                                order.OrderSide == Side.Buy ? order.CancelledQuantity : -order.CancelledQuantity);
                    cmd.Parameters.AddWithValue("price", order.Price);
                }

                SqlTransaction transaction = null;

                try
                {
                    aConnection.Open();
                    transaction     = aConnection.BeginTransaction();
                    cmd.Transaction = transaction;
                    cmd.ExecuteNonQuery();
                    transaction.Commit();
                }
                catch (Exception e)
                {
                    if (canRetry && e is SqlException)
                    {
                        var code = ((SqlException)e).Number;
                        if (code == 1205 || code == -2)  //deadlock or timeout
                        {
                            Logger.Error($"Failed to add {order.Symbol} order to DB (will retry): {e.Message}");
                            AddHistoricalOrder(order, info, status);
                            return;
                        }
                    }

                    Logger.Error($"Failed to add {order.Symbol} order to DB", e);

                    transaction?.Rollback();
                }
            }
        }