public async Task <object> GetTime_LastMarketClose() { IAlpacaTradingClient client = null; try { if (!String.IsNullOrWhiteSpace(Settings.API_Alpaca_Live_Key) && !String.IsNullOrWhiteSpace(Settings.API_Alpaca_Live_Secret)) { client = Environments.Live.GetAlpacaTradingClient(new SecretKey(Settings.API_Alpaca_Live_Key, Settings.API_Alpaca_Live_Secret)); } else if (!String.IsNullOrWhiteSpace(Settings.API_Alpaca_Paper_Key) && !String.IsNullOrWhiteSpace(Settings.API_Alpaca_Paper_Secret)) { client = Environments.Paper.GetAlpacaTradingClient(new SecretKey(Settings.API_Alpaca_Paper_Key, Settings.API_Alpaca_Paper_Secret)); } else { return(new ArgumentNullException()); } var calendars = client.ListCalendarAsync(new CalendarRequest().SetInclusiveTimeInterval(DateTime.UtcNow - new TimeSpan(30, 0, 0, 0), DateTime.UtcNow)).Result; return(calendars.Where(c => c.TradingCloseTimeUtc.CompareTo(DateTime.UtcNow) <= 0).Last().TradingCloseTimeUtc); } catch (Exception ex) { await Log.Error($"{MethodBase.GetCurrentMethod().DeclaringType}: {MethodBase.GetCurrentMethod().Name}", ex); return(ex.Message); } }
public async Task <IEnumerable <DateTime> > GetAllTradingHolidays(DateTime?start = null, DateTime?end = null) { var startValue = start ?? DateTime.UtcNow; var endValue = end ?? startValue.AddYears(10); var tradingDays = (await _alpacaTradingClient.ListCalendarAsync(new CalendarRequest().SetInclusiveTimeInterval(startValue, endValue))).Select(x => x.TradingDateUtc.Date); var allDays = Enumerable.Range(0, 1 + endValue.Subtract(startValue).Days) .Select(offset => startValue.AddDays(offset).Date); return(allDays.Except(tradingDays)); }
public async void ListCalendarWorks() { var calendars = await _alpacaTradingClient.ListCalendarAsync( new CalendarRequest().SetInclusiveTimeInterval( DateTime.Today.AddDays(-14), DateTime.Today.AddDays(14))); Assert.NotNull(calendars); var calendarsList = calendars.ToList(); Assert.NotEmpty(calendarsList); var first = calendarsList.First(); var last = calendarsList.Last(); Assert.True(first.TradingDateUtc <= last.TradingDateUtc); Assert.True(first.TradingOpenTimeUtc < first.TradingCloseTimeUtc); Assert.True(last.TradingOpenTimeUtc < last.TradingCloseTimeUtc); }
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.ListOrdersAsync(new ListOrdersRequest()); 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().TradingDateUtc; var closingTime = calendars.First().TradingCloseTimeUtc; 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. Int32 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; } Int32 qtyToBuy = (Int32)(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; Int32 qtyToSell = (Int32)(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() { alpacaTradingClient = Environments.Paper.GetAlpacaTradingClient(new SecretKey(API_KEY, API_SECRET)); polygonDataClient = Environments.Paper.GetPolygonDataClient(API_KEY); // Connect to Alpaca's websocket and listen for updates on our orders. alpacaStreamingClient = Environments.Paper.GetAlpacaStreamingClient(new SecretKey(API_KEY, API_SECRET)); alpacaStreamingClient.ConnectAndAuthenticateAsync().Wait(); alpacaStreamingClient.OnTradeUpdate += HandleTradeUpdate; // First, cancel any existing orders so they don't impact our buying power. var orders = await alpacaTradingClient.ListOrdersAsync(new ListOrdersRequest()); 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().TradingDateUtc; var closingTime = calendars.First().TradingCloseTimeUtc; closingTime = new DateTime(calendarDate.Year, calendarDate.Month, calendarDate.Day, closingTime.Hour, closingTime.Minute, closingTime.Second); var today = DateTime.Today; // Get the first group of bars from today if the market has already been open. var bars = await polygonDataClient.ListAggregatesAsync( new AggregatesRequest(symbol, new AggregationPeriod(1, AggregationPeriodUnit.Minute)) .SetInclusiveTimeInterval(today, today.AddDays(1))); var lastBars = bars.Items.Skip(Math.Max(0, bars.Items.Count() - 20)); foreach (var bar in lastBars) { if (bar.TimeUtc?.Date == today) { closingPrices.Add(bar.Close); } } Console.WriteLine("Waiting for market open..."); await AwaitMarketOpen(); Console.WriteLine("Market opened."); // Connect to Polygon's websocket and listen for price updates. polygonStreamingClient = Environments.Live.GetPolygonStreamingClient(API_KEY); polygonStreamingClient.ConnectAndAuthenticateAsync().Wait(); Console.WriteLine("Polygon client opened."); polygonStreamingClient.MinuteAggReceived += async(agg) => { // If the market's close to closing, exit position and stop trading. TimeSpan minutesUntilClose = closingTime - DateTime.UtcNow; if (minutesUntilClose.TotalMinutes < 15) { Console.WriteLine("Reached the end of trading window."); await ClosePositionAtMarket(); await polygonStreamingClient.DisconnectAsync(); } else { // Decide whether to buy or sell and submit orders. await HandleMinuteAgg(agg); } }; polygonStreamingClient.SubscribeMinuteAgg(symbol); }