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) { } }
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()); } }
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(); }