예제 #1
0
        /// <summary>
        /// decimal GetMarketPrice(string symbol)
        /// Input symbol in string format
        /// Returns Market Price
        /// </summary>
        /// <param name="symbol"></param>
        /// <returns></returns>
        public static decimal GetMarketPrice(string symbol)
        {
            MarketDataServiceClient Client = new MarketDataServiceClient();
            var tempData = Client.GetSymbolData(symbol);

            return(Convert.ToDecimal(tempData.Price));
        }
예제 #2
0
        public DataTable GetStockPrices(DateTime startDate, DateTime endDate)
        {
            MarketDataServiceClient client = new MarketDataServiceClient();
            DataSet   dsPrices;
            DataTable dtOutput = null;

            int i = 0, pageSize = 20;

            while (startDate.AddDays(pageSize * i) <= endDate)
            {
                DateTime start, end;
                start    = (startDate.AddDays(i * pageSize));
                end      = (startDate.AddDays(pageSize * (i + 1) - 1) > endDate) ? endDate : startDate.AddDays(pageSize * (i + 1) - 1);
                dsPrices = client.GetStockPrices(start, end, null);

                if (dtOutput == null)
                {
                    dtOutput = dsPrices.Tables[0].Copy();
                }
                else
                {
                    foreach (DataRow oRow in dsPrices.Tables[0].Rows)
                    {
                        dtOutput.ImportRow(oRow);
                    }
                }

                i++;
            }

            return(dtOutput);
        }
예제 #3
0
 public PerformanceReportController(PseudoMarketsDbContext context, MongoClient mongoClient, MarketDataServiceClient marketDataServiceClient)
 {
     _context                     = context;
     _mongoClient                 = mongoClient;
     _mongoDatabase               = _mongoClient.GetDatabase("PseudoMarketsDB");
     _mongoCollection             = _mongoDatabase.GetCollection <BsonDocument>("PortfolioPerformance");
     _marketDataServiceClient     = marketDataServiceClient;
     _performanceReportCalculator = new PerformanceReportCalculator(_marketDataServiceClient);
 }
예제 #4
0
        public TradeController(PseudoMarketsDbContext context, IOptions <PseudoMarketsConfig> appConfig,
                               DateTimeHelper dateTimeHelper, UnifiedAuthService unifiedAuth, MarketDataServiceClient marketDataService,
                               TradingPlatformClient tradingPlatformClient)
        {
            _context = context;
            var config = appConfig;

            _syncDbConnectionString             = config.Value.DataSyncTargetDb;
            _dataSyncEnabled                    = config.Value.DataSyncEnabled;
            _dateTimeHelper                     = dateTimeHelper;
            _unifiedAuth                        = unifiedAuth;
            _marketDataService                  = marketDataService;
            _consolidatedTradingPlatformEnabled = config.Value.ConsolidatedTradingPlatformEnabled;
            _tradingPlatformClient              = tradingPlatformClient;
        }
예제 #5
0
        /// <summary>
        /// void UpdateSymbols()
        /// Adds or Updates the Symbol_Properties
        /// </summary>
        public static void UpdateSymbols()
        {
            MarketDataServiceClient Client = new MarketDataServiceClient();
            EquityEntities          db     = new EquityEntities();

            try
            {
                var tempData = Client.GetWholeData().ToList();
                foreach (var item in tempData)
                {
                    db.UPSERT(item.Symbol, Convert.ToDecimal(item.Price), item.Name);
                }
                db.SaveChanges();
            }
            catch (Exception e)
            {
                if (e.Message.Contains("Endpoint"))
                {
                    MessageBox.Show("Server Down\n Showing old data");
                }
            }
        }
 public QuotesController(MarketDataServiceClient marketDataClient)
 {
     _marketDataClient = marketDataClient;
 }
예제 #7
0
        public DataTable GetIndexPrices(DateTime startDate, DateTime endDate, string code)
        {
            MarketDataServiceClient client = new MarketDataServiceClient();

            return(client.GetIndexPrices(startDate, endDate, code).Tables[0]);
        }
예제 #8
0
        public DataTable GetHS300Weight(DateTime endDate)
        {
            MarketDataServiceClient client = new MarketDataServiceClient();

            return(client.GetHS300Weight(endDate).Tables[0]);
        }
예제 #9
0
        public DataTable GetTradingDaysList(DateTime start, DateTime end)
        {
            MarketDataServiceClient client = new MarketDataServiceClient();

            return(client.GetTradingDays(start, end).Tables[0]);
        }
예제 #10
0
        public DataTable GetSWIndustryList()
        {
            MarketDataServiceClient client = new MarketDataServiceClient();

            return(client.GetSWIndustryList().Tables[0]);
        }
예제 #11
0
        public DataTable GetFreeFloatCapital(DateTime endDate, string code)
        {
            MarketDataServiceClient client = new MarketDataServiceClient();

            return(client.GetFreeFloatCapital(endDate, code).Tables[0]);
        }
예제 #12
0
        //public DataTable GetStockPrices(DateTime startDate, DateTime endDate, List<string> codeList)
        //{
        //    try
        //    {
        //        MarketDataServiceClient client = new MarketDataServiceClient();


        //        //TODO: 每次取20天的数据
        //        DataSet dsPrices;
        //        DataTable dtOutput = null;

        //        if (codeList != null && codeList.Count > 0)
        //        {
        //            //check duplication
        //            codeList.Sort();

        //            int i = 1;
        //            while (i < codeList.Count)
        //            {
        //                if (codeList[i] == codeList[i - 1])
        //                    codeList.RemoveAt(i);
        //                else
        //                    i++;
        //            }

        //            //get data
        //            foreach (string code in codeList)
        //            {
        //                dsPrices = client.GetStockPrices(startDate, endDate, code);

        //                if (dtOutput == null)
        //                {
        //                    dtOutput = dsPrices.Tables[0].Copy();
        //                }
        //                else
        //                {
        //                    foreach (DataRow oRow in dsPrices.Tables[0].Rows)
        //                    {
        //                        dtOutput.ImportRow(oRow);
        //                    }
        //                }
        //            }
        //        }
        //        else
        //        {
        //            dsPrices = client.GetStockPrices(startDate, endDate, null);
        //            if (dsPrices.Tables.Count > 0)
        //                dtOutput = dsPrices.Tables[0].Copy();
        //        }

        //        return dtOutput;
        //    }
        //    catch (Exception ex)
        //    {
        //        throw ex;
        //    }
        //}

        //public DataTable GetStockPrices(DateTime startDate, DateTime endDate, List<string> codeList)
        //{
        //    MarketDataServiceClient client = new MarketDataServiceClient();
        //    DataSet ds;

        //    if (codeList == null || codeList.Count == 0)
        //        ds = client.GetStockPricesByCodeList(startDate, endDate, null);
        //    else
        //    {
        //        //check duplication
        //        codeList.Sort();

        //        int i = 1;
        //        while(i<codeList.Count)
        //        {
        //            if (codeList[i] == codeList[i - 1])
        //                codeList.RemoveAt(i);
        //            else
        //                i++;
        //        }


        //        //get data
        //        ds = client.GetStockPricesByCodeList(startDate, endDate, codeList.ToArray());
        //    }

        //    if (ds.Tables.Count > 0)
        //        return ds.Tables[0];
        //    else
        //        return null;
        //}

        public DataTable GetAShareStockList(string code)
        {
            MarketDataServiceClient client = new MarketDataServiceClient();

            return(client.GetAShareStockList(code, null, null, "1").Tables[0]);
        }
예제 #13
0
        public static async Task <TradeExecOutput> ProcessTradingRequestUsingRdsFallback(Users user, Accounts account,
                                                                                         TradeExecInput input, PseudoMarketsDbContext context, MarketDataServiceClient marketDataService,
                                                                                         DateTimeHelper dateTimeHelper)
        {
            try
            {
                var transactionId = Guid.NewGuid().ToString();

                var latestPrice = await marketDataService.GetLatestPrice(input.Symbol);

                double price = latestPrice.price;

                double value = price * input.Quantity;
                bool   hasSufficientBalance = account.Balance >= value;

                TradeExecOutput output = new TradeExecOutput();

                // TODO: Extract trade logic into a separate static class
                if (hasSufficientBalance)
                {
                    if (input.Type.ToUpper() == "BUY" || input.Type.ToUpper() == "SELL" ||
                        input.Type.ToUpper() == "SELLSHORT")
                    {
                        if (price > 0 && input.Quantity > 0)
                        {
                            if (dateTimeHelper.IsMarketOpen())
                            {
                                Orders order = new Orders
                                {
                                    Symbol         = input.Symbol,
                                    Type           = input.Type,
                                    Price          = price,
                                    Quantity       = input.Quantity,
                                    Date           = DateTime.Now,
                                    TransactionID  = transactionId,
                                    EnvironmentId  = RDSEnums.EnvironmentId.RdsFallback,
                                    OriginId       = RDSEnums.OriginId.PseudoMarkets,
                                    SecurityTypeId = RDSEnums.SecurityType.RealWorld
                                };

                                Transactions transaction = new Transactions
                                {
                                    AccountId     = account.Id,
                                    TransactionId = transactionId,
                                    EnvironmentId = RDSEnums.EnvironmentId.RdsFallback,
                                    OriginId      = RDSEnums.OriginId.PseudoMarkets
                                };

                                context.Orders.Add(order);
                                context.Transactions.Add(transaction);
                                await context.SaveChangesAsync();

                                var createdOrder =
                                    await context.Orders.FirstOrDefaultAsync(x => x.TransactionID == transactionId);

                                if (input.Type.ToUpper() == "BUY")
                                {
                                    var doesAccountHaveExistingPosition =
                                        context.Positions.Any(x =>
                                                              x.AccountId == account.Id && x.Symbol == input.Symbol);
                                    if (doesAccountHaveExistingPosition)
                                    {
                                        var existingPosition = await context.Positions
                                                               .Where(x => x.AccountId == account.Id && x.Symbol == input.Symbol)
                                                               .FirstOrDefaultAsync();

                                        // Long position
                                        if (existingPosition.Quantity > 0)
                                        {
                                            existingPosition.Value               += value;
                                            existingPosition.Quantity            += input.Quantity;
                                            context.Entry(existingPosition).State = EntityState.Modified;
                                            account.Balance = account.Balance - value;
                                            context.Entry(account).State = EntityState.Modified;
                                            await context.SaveChangesAsync();
                                        }
                                        else // Short position
                                        {
                                            if (Math.Abs(existingPosition.Quantity) == input.Quantity)
                                            {
                                                double gainOrLoss = existingPosition.Value - value;
                                                account.Balance += gainOrLoss;
                                                context.Entry(account).State          = EntityState.Modified;
                                                context.Entry(existingPosition).State = EntityState.Deleted;
                                                await context.SaveChangesAsync();
                                            }
                                            else
                                            {
                                                existingPosition.Value                = existingPosition.Value - value;
                                                existingPosition.Quantity            += input.Quantity;
                                                account.Balance                      += existingPosition.Value - value;
                                                context.Entry(existingPosition).State = EntityState.Modified;
                                                context.Entry(account).State          = EntityState.Modified;
                                                await context.SaveChangesAsync();
                                            }
                                        }
                                    }
                                    else
                                    {
                                        Positions position = new Positions
                                        {
                                            AccountId      = account.Id,
                                            OrderId        = createdOrder.Id,
                                            Value          = value,
                                            Symbol         = input.Symbol,
                                            Quantity       = input.Quantity,
                                            EnvironmentId  = RDSEnums.EnvironmentId.RdsFallback,
                                            OriginId       = RDSEnums.OriginId.PseudoMarkets,
                                            SecurityTypeId = RDSEnums.SecurityType.RealWorld
                                        };
                                        context.Positions.Add(position);
                                        await context.SaveChangesAsync();

                                        account.Balance = account.Balance - value;
                                        context.Entry(account).State = EntityState.Modified;
                                        await context.SaveChangesAsync();
                                    }
                                }
                                else if (input.Type.ToUpper() == "SELL")
                                {
                                    var doesAccountHaveExistingPosition =
                                        context.Positions.Any(x =>
                                                              x.AccountId == account.Id && x.Symbol == input.Symbol);
                                    if (doesAccountHaveExistingPosition)
                                    {
                                        var existingPosition = await context.Positions
                                                               .Where(x => x.AccountId == account.Id && x.Symbol == input.Symbol)
                                                               .FirstOrDefaultAsync();

                                        if (input.Quantity == existingPosition.Quantity)
                                        {
                                            account.Balance = account.Balance + value;
                                            context.Entry(existingPosition).State = EntityState.Deleted;
                                            context.Entry(account).State          = EntityState.Modified;
                                            await context.SaveChangesAsync();
                                        }
                                        else
                                        {
                                            existingPosition.Value               -= value;
                                            existingPosition.Quantity            -= input.Quantity;
                                            context.Entry(existingPosition).State = EntityState.Modified;
                                            account.Balance = account.Balance + value;
                                            context.Entry(account).State = EntityState.Modified;
                                            await context.SaveChangesAsync();
                                        }
                                    }
                                    else
                                    {
                                        output.StatusCode    = TradeStatusCodes.ExecutionError;
                                        output.StatusMessage =
                                            StatusMessages.InvalidPositionsMessage + input.Symbol;
                                        return(output);
                                    }
                                }
                                else if (input.Type.ToUpper() == "SELLSHORT")
                                {
                                    var doesAccountHaveExistingPosition =
                                        context.Positions.Any(x =>
                                                              x.AccountId == account.Id && x.Symbol == input.Symbol);
                                    if (doesAccountHaveExistingPosition)
                                    {
                                        var existingPosition = await context.Positions
                                                               .Where(x => x.AccountId == account.Id && x.Symbol == input.Symbol)
                                                               .FirstOrDefaultAsync();

                                        if (existingPosition.Quantity > 0)
                                        {
                                            context.Entry(createdOrder).State = EntityState.Deleted;
                                            await context.SaveChangesAsync();

                                            output.StatusCode    = TradeStatusCodes.ExecutionError;
                                            output.StatusMessage =
                                                StatusMessages.InvalidShortPositionMessage;
                                            return(output);
                                        }

                                        existingPosition.Value               += value;
                                        existingPosition.Quantity            += input.Quantity * -1;
                                        context.Entry(existingPosition).State = EntityState.Modified;
                                        await context.SaveChangesAsync();
                                    }
                                    else
                                    {
                                        Positions position = new Positions
                                        {
                                            AccountId      = account.Id,
                                            OrderId        = createdOrder.Id,
                                            Value          = value,
                                            Symbol         = input.Symbol,
                                            Quantity       = input.Quantity * -1,
                                            EnvironmentId  = RDSEnums.EnvironmentId.RdsFallback,
                                            OriginId       = RDSEnums.OriginId.PseudoMarkets,
                                            SecurityTypeId = RDSEnums.SecurityType.RealWorld
                                        };

                                        context.Positions.Add(position);
                                        account.Balance = account.Balance - value;
                                        context.Entry(account).State = EntityState.Modified;
                                        await context.SaveChangesAsync();
                                    }
                                }

                                output.StatusCode    = TradeStatusCodes.ExecutionOk;
                                output.StatusMessage = StatusMessages.SuccessMessage;
                                output.Order         = createdOrder;
                                return(output);
                            }

                            CreateQueuedOrder(input, user.Id, context);
                            output.StatusMessage =
                                "Market is closed, order has been queued to be filled on next market open";
                            output.StatusCode = TradeStatusCodes.ExecutionQueued;
                            return(output);
                        }

                        output.StatusCode    = TradeStatusCodes.ExecutionError;
                        output.StatusMessage = StatusMessages.InvalidSymbolOrQuantityMessage;
                        return(output);
                    }

                    output.StatusCode    = TradeStatusCodes.ExecutionError;
                    output.StatusMessage = StatusMessages.InvalidOrderTypeMessage;
                    return(output);
                }

                output.StatusCode    = TradeStatusCodes.ExecutionError;
                output.StatusMessage = StatusMessages.InsufficientBalanceMessage;
                return(output);
            }
            catch (Exception e)
            {
                TradeExecOutput status = new TradeExecOutput
                {
                    Order         = null,
                    StatusCode    = TradeStatusCodes.ExecutionError,
                    StatusMessage = StatusMessages.FailureMessage
                };
                Log.Fatal(e, $"{nameof(ProcessTradingRequestUsingRdsFallback)}");
                return(status);
            }
        }