示例#1
0
        public async Task ProcessBatch(List <NightlyBarsModel> stocks, DateTime processDate)
        {
            var minDate = stocks.Min(e => e.MaxDate);
            var limit   = (processDate - minDate).Days;

            if (limit > 1000)
            {
                limit = 1000;
            }
            var queryParams = new BarSetRequest(stocks.Select(e => e.Symbol), TimeFrame.Day)
            {
                Limit = limit
            };

            try
            {
                var bars = await alpacaDataClient.GetBarSetAsync(queryParams);

                foreach (var candles in bars)
                {
                    var date         = stocks.Where(e => e.Symbol == candles.Key).Select(e => e.MaxDate).FirstOrDefault();
                    var symbolId     = stocks.Where(e => e.Symbol == candles.Key).Select(e => e.SymbolId).FirstOrDefault();
                    var barsToInsert = candles.Value.Where(e => e.Time.Date > date.Date).ToList();
                    if (barsToInsert.Count > 0)
                    {
                        await InsertStockBars(barsToInsert, symbolId);
                    }
                }
            }
            catch (Exception exc)
            {
            }
        }
示例#2
0
        public async void CallApi()
        {
            var limit       = 1;
            var queryParams = new BarSetRequest(Symbols, TimeFrame.FiveMinutes)
            {
                Limit = limit
            };

            try
            {
                var bars = await AlpacaDataClient.GetBarSetAsync(queryParams);

                foreach (var candles in bars)
                {
                    var  pair = new KeyValuePair <string, IAgg>(candles.Key, candles.Value.FirstOrDefault());
                    IAgg agg  = pair.Value;
                    RefreshResult.AddOrUpdate(pair.Key, agg, (key, agg) => { return(agg); });
                    //pair.Key = candles.Key;
                    //UpdateDictionary(pair);
                    //var loop = candles;
                    //var list = loop.ToKeyValuePairs().ToList();
                    //foreach (var item in list)
                    //{
                    //    var testvar = item;//RefreshResult =

                    //}
                }
            }
            catch (Exception exc)
            {
                Logger.Info(exc.ToString());
            }
        }
示例#3
0
        public async Task Run()
        {
            alpacaTradingClient = Environments.Paper.GetAlpacaTradingClient(new SecretKey(API_KEY, API_SECRET));

            alpacaDataClient = Environments.Paper.GetAlpacaDataClient(new SecretKey(API_KEY, API_SECRET));

            // First, cancel any existing orders so they don't impact our buying power.
            var orders = await alpacaTradingClient.ListAllOrdersAsync();

            foreach (var order in orders)
            {
                await alpacaTradingClient.DeleteOrderAsync(order.OrderId);
            }

            // Figure out when the market will close so we can prepare to sell beforehand.
            var calendars = (await alpacaTradingClient
                             .ListCalendarAsync(new CalendarRequest().SetTimeInterval(DateTime.Today.GetInclusiveIntervalFromThat())))
                            .ToList();
            var calendarDate = calendars.First().TradingDate;
            var closingTime  = calendars.First().TradingCloseTime;

            closingTime = new DateTime(calendarDate.Year, calendarDate.Month, calendarDate.Day, closingTime.Hour, closingTime.Minute, closingTime.Second);

            Console.WriteLine("Waiting for market open...");
            await AwaitMarketOpen();

            Console.WriteLine("Market opened.");

            // Check every minute for price updates.
            TimeSpan timeUntilClose = closingTime - DateTime.UtcNow;

            while (timeUntilClose.TotalMinutes > 15)
            {
                // Cancel old order if it's not already been filled.
                await alpacaTradingClient.DeleteOrderAsync(lastTradeId);

                // Get information about current account value.
                var account = await alpacaTradingClient.GetAccountAsync();

                Decimal buyingPower    = account.BuyingPower;
                Decimal portfolioValue = account.Equity;

                // Get information about our existing position.
                int     positionQuantity = 0;
                Decimal positionValue    = 0;
                try
                {
                    var currentPosition = await alpacaTradingClient.GetPositionAsync(symbol);

                    positionQuantity = currentPosition.Quantity;
                    positionValue    = currentPosition.MarketValue;
                }
                catch (Exception)
                {
                    // No position exists. This exception can be safely ignored.
                }

                var barSet = await alpacaDataClient.GetBarSetAsync(
                    new BarSetRequest(symbol, TimeFrame.Minute) { Limit = 20 });

                var bars = barSet[symbol].ToList();

                Decimal avg          = bars.Average(item => item.Close);
                Decimal currentPrice = bars.Last().Close;
                Decimal diff         = avg - currentPrice;

                if (diff <= 0)
                {
                    // Above the 20 minute average - exit any existing long position.
                    if (positionQuantity > 0)
                    {
                        Console.WriteLine("Setting position to zero.");
                        await SubmitOrder(positionQuantity, currentPrice, OrderSide.Sell);
                    }
                    else
                    {
                        Console.WriteLine("No position to exit.");
                    }
                }
                else
                {
                    // Allocate a percent of our portfolio to this position.
                    Decimal portfolioShare      = diff / currentPrice * scale;
                    Decimal targetPositionValue = portfolioValue * portfolioShare;
                    Decimal amountToAdd         = targetPositionValue - positionValue;

                    if (amountToAdd > 0)
                    {
                        // Buy as many shares as we can without going over amountToAdd.

                        // Make sure we're not trying to buy more than we can.
                        if (amountToAdd > buyingPower)
                        {
                            amountToAdd = buyingPower;
                        }
                        int qtyToBuy = (int)(amountToAdd / currentPrice);

                        await SubmitOrder(qtyToBuy, currentPrice, OrderSide.Buy);
                    }
                    else
                    {
                        // Sell as many shares as we can without going under amountToAdd.

                        // Make sure we're not trying to sell more than we have.
                        amountToAdd *= -1;
                        int qtyToSell = (int)(amountToAdd / currentPrice);
                        if (qtyToSell > positionQuantity)
                        {
                            qtyToSell = positionQuantity;
                        }

                        await SubmitOrder(qtyToSell, currentPrice, OrderSide.Sell);
                    }
                }

                // Wait another minute.
                Thread.Sleep(60000);
                timeUntilClose = closingTime - DateTime.UtcNow;
            }

            Console.WriteLine("Market nearing close; closing position.");
            await ClosePositionAtMarket();
        }
        public async Task Run()
        {
            Console.WriteLine("Updating VIX and SPX data");
            await ApplyUpdates(true, false);

            Console.WriteLine("Loading VIX file");
            vixPrices = CSVProcessor.ProcessVIXFile(VIXPath);

            Console.WriteLine("Connecting to alpaca trading API");
            alpacaTradingClient = Environments.Paper.GetAlpacaTradingClient(API_KEY, new SecretKey(API_SECRET));

            Console.WriteLine("Connecting to alpaca data API");
            alpacaDataClient = Environments.Paper.GetAlpacaDataClient(API_KEY, new SecretKey(API_SECRET));

            Console.WriteLine("Getting Market Calendars");
            var calendars = (await alpacaTradingClient.ListCalendarAsync(StartDate, EndDate)).ToList();

            Console.WriteLine("Writing header line in output file");
            using (StreamWriter w = File.CreateText(OutputPath))
            {
                w.WriteLine("Symbol, Date, StartTime, EndTime, PatternAlgFound, PatternVisFound, PosOpenTime, PosCloseTime, PosLong, PosReturn");
            }

            foreach (var calDate in calendars)
            {
                List <DateTime> startTimes     = new List <DateTime>();
                DateTime        loopTime       = calDate.TradingOpenTime.AddMinutes(15);
                TimeSpan        timeUntilClose = calDate.TradingCloseTime.Subtract(loopTime);
                while (timeUntilClose.TotalMinutes >= 30)
                {
                    startTimes.Add(loopTime);
                    loopTime       = loopTime.Add(new TimeSpan(0, 30, 0));
                    timeUntilClose = calDate.TradingCloseTime.Subtract(loopTime);
                }

                // High volatility only.
                if (!vixPrices.ContainsKey(calDate.TradingDate.ToString("yyyy-MM-dd")))
                {
                    continue;
                }
                if (vixPrices[calDate.TradingDate.ToString("yyyy-MM-dd")].Open < 28)
                {
                    continue;
                }

                foreach (DateTime dateTime in startTimes)
                {
                    var barSet = (await alpacaDataClient.GetBarSetAsync(symbols, TimeFrame.Minute, 60, true, dateTime.Subtract(TimeSpan.FromMinutes(14)), calDate.TradingCloseTime));


                    foreach (string sym in symbols)
                    {
                        if (!barSet.ContainsKey(sym))
                        {
                            continue;
                        }
                        var bars = barSet[sym].ToList();
                        // Pattern matching algorithm:
                        if (bars.Count < 44)
                        {
                            continue;
                        }

                        int  istr    = 14;
                        int  endtime = 14;
                        bool gr      = false;
                        bool found   = false;

                        for (int i = 14; i < 44; i++)
                        {
                            var price = bars[i];
                            if (price.Close - price.Open > 0)
                            {
                                if (gr)
                                {
                                    continue;
                                }

                                if (i - istr >= 4)
                                {
                                    found   = true;
                                    endtime = i;
                                    break;
                                }

                                istr = i;
                                gr   = true;
                            }
                            else
                            {
                                if (!gr)
                                {
                                    continue;
                                }

                                if (i - istr >= 6)
                                {
                                    found   = true;
                                    endtime = i;
                                    break;
                                }

                                istr = i;
                                gr   = false;
                            }
                        }

                        if (!found)
                        {
                            continue;
                        }

                        bool lng = !gr;

                        decimal entPrice = bars[endtime].Close;
                        decimal exPrice  = bars[43].Close;

                        decimal profit = lng ? exPrice - entPrice : entPrice - exPrice;
                        decimal pct    = profit / entPrice;

                        // End of Algorithm - Should be a pattern match now

                        List <PriceData> prices = new List <PriceData>();
                        for (int i = 0; i < 30; i++)
                        {
                            var price = bars[i + 14];
                            prices.Add(new PriceData(price.Time.ToString("HH:mm"), i, price.Open, price.Close, price.High, price.Low));
                        }

                        AlgoResult match = new AlgoResult(prices, sym, dateTime, dateTime.AddMinutes(30), true, res => {
                            //WriteToOutput(res);
                        }, dateTime.AddMinutes(14 + endtime), dateTime.AddMinutes(44), lng, pct);

                        ChartManager.SendToChartQueue(match);
                        match.PatternVisFound = true;
                        WriteToOutput(match);
                    }
                }
            }
            ChartManager.DoneProcessing();
        }