public static async Task StopAsync() { // TODO: Should we liquidate on stop? await Disconnect(); AlpacaTradingClient?.Dispose(); AlpacaStreamingClient?.Dispose(); PolygonDataClient?.Dispose(); PolygonStreamingClient?.Dispose(); await Scheduler?.Shutdown(); }
/// <summary> /// Initializes a new instance of the <see cref="AlpacaBrokerage"/> class. /// </summary> /// <param name="orderProvider">The order provider.</param> /// <param name="securityProvider">The holdings provider.</param> /// <param name="accountKeyId">The Alpaca api key id</param> /// <param name="secretKey">The api secret key</param> /// <param name="tradingMode">The Alpaca trading mode. paper/live</param> /// <param name="handlesMarketData">true if market data subscriptions will be handled by Alpaca</param> /// <param name="aggregator">consolidate ticks</param> public AlpacaBrokerage(IOrderProvider orderProvider, ISecurityProvider securityProvider, string accountKeyId, string secretKey, string tradingMode, bool handlesMarketData, IDataAggregator aggregator) : base("Alpaca Brokerage") { _handlesMarketData = handlesMarketData; _aggregator = aggregator; var httpScheme = "https://"; var alpacaBaseUrl = "api.alpaca.markets"; if (tradingMode.Equals("paper")) { alpacaBaseUrl = "paper-" + alpacaBaseUrl; } var httpAlpacaBaseUrl = httpScheme + alpacaBaseUrl; _orderProvider = orderProvider; _securityProvider = securityProvider; _marketHours = MarketHoursDatabase.FromDataFolder(); // Alpaca trading client _alpacaTradingClient = new AlpacaTradingClient(new AlpacaTradingClientConfiguration { ApiEndpoint = tradingMode.Equals("paper") ? Environments.Paper.AlpacaTradingApi : Environments.Live.AlpacaTradingApi, SecurityId = new SecretKey(accountKeyId, secretKey) }); // api client for alpaca data _polygonDataClient = new PolygonDataClient(new PolygonDataClientConfiguration { ApiEndpoint = Environments.Live.PolygonDataApi, KeyId = accountKeyId }); // websocket client for alpaca _sockClient = new SockClient(accountKeyId, secretKey, httpAlpacaBaseUrl); _sockClient.OnTradeUpdate += OnTradeUpdate; _sockClient.OnError += OnSockClientError; // Polygon Streaming client for Alpaca (streams trade and quote data) _polygonStreamingClient = new PolygonStreamingClient(new PolygonStreamingClientConfiguration { ApiEndpoint = Environments.Live.PolygonStreamingApi, KeyId = accountKeyId, WebSocketFactory = new WebSocketClientFactory() }); _polygonStreamingClient.QuoteReceived += OnQuoteReceived; _polygonStreamingClient.TradeReceived += OnTradeReceived; _polygonStreamingClient.OnError += OnPolygonStreamingClientError; }
/// <summary> /// Initializes a new instance of the <see cref="AlpacaBrokerage"/> class. /// </summary> /// <param name="orderProvider">The order provider.</param> /// <param name="securityProvider">The holdings provider.</param> /// <param name="mapFileProvider">representing all the map files</param> /// <param name="accountKeyId">The Alpaca api key id</param> /// <param name="secretKey">The api secret key</param> /// <param name="tradingMode">The Alpaca trading mode. paper/live</param> public AlpacaBrokerage(IOrderProvider orderProvider, ISecurityProvider securityProvider, IMapFileProvider mapFileProvider, string accountKeyId, string secretKey, string tradingMode) : base("Alpaca Brokerage") { var httpScheme = "https://"; var alpacaBaseUrl = "api.alpaca.markets"; if (tradingMode.Equals("paper")) { alpacaBaseUrl = "paper-" + alpacaBaseUrl; } var httpAlpacaBaseUrl = httpScheme + alpacaBaseUrl; _orderProvider = orderProvider; _securityProvider = securityProvider; _symbolMapper = new AlpacaSymbolMapper(mapFileProvider); _marketHours = MarketHoursDatabase.FromDataFolder(); // Alpaca trading client _alpacaTradingClient = new AlpacaTradingClient(new AlpacaTradingClientConfiguration { ApiEndpoint = tradingMode.Equals("paper") ? Environments.Paper.AlpacaTradingApi : Environments.Live.AlpacaTradingApi, SecurityId = new SecretKey(accountKeyId, secretKey) }); // api client for alpaca data _polygonDataClient = new PolygonDataClient(new PolygonDataClientConfiguration { ApiEndpoint = Environments.Live.PolygonDataApi, KeyId = accountKeyId }); // websocket client for alpaca _sockClient = new SockClient(accountKeyId, secretKey, httpAlpacaBaseUrl); _sockClient.OnTradeUpdate += OnTradeUpdate; _sockClient.OnError += OnSockClientError; }
public async Task Run() { alpacaTradingClient = Environments.Paper.GetAlpacaTradingClient(API_KEY, new SecretKey(API_SECRET)); polygonDataClient = Environments.Paper.GetPolygonDataClient(API_KEY); // Connect to Alpaca's websocket and listen for updates on our orders. alpacaStreamingClient = Environments.Paper.GetAlpacaStreamingClient(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(); 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(DateTime.Today)).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); var today = DateTime.Today; // Get the first group of bars from today if the market has already been open. var bars = await polygonDataClient.ListMinuteAggregatesAsync(symbol, 1, today, today.AddDays(1)); var lastBars = bars.Items.Skip(Math.Max(0, bars.Items.Count() - 20)); foreach (var bar in lastBars) { if (bar.Time.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.SubscribeSecondAgg(symbol); }