public async Task Run()
        {
            alpacaTradingClient = Environments.Paper.GetAlpacaTradingClient(new SecretKey(API_KEY, API_SECRET)) as AlpacaTradingClient;

            polygonDataClient = Environments.Paper.GetPolygonDataClient(API_KEY) as PolygonDataClient;

            // Connect to Alpaca's websocket and listen for updates on our orders.
            alpacaStreamingClient = Environments.Paper.GetAlpacaStreamingClient(new SecretKey(API_KEY, API_SECRET)) as AlpacaStreamingClient;

            alpacaStreamingClient.ConnectAndAuthenticateAsync().Wait();

            alpacaStreamingClient.OnTradeUpdate += HandleTradeUpdate;
            var sort = new ListOrdersRequest();

            sort.OrderListSorting = SortDirection.Ascending;
            // Kill Switch part one
            // First, cancel any existing orders so they don't impact our buying power.
            var orders = await alpacaTradingClient.ListOrdersAsync(sort, Token);

            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().TradingDateEst;
            var closingTime  = calendars.First().TradingCloseTimeEst;

            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)
            {
                Debug.Assert(bar.TimeUtc != null, "bar.TimeUtc != null");
                if (bar.TimeUtc.Value.Add(TimeSpan.FromHours(3)) == 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 = (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);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Connects the client to the broker's remote servers
        /// </summary>
        public override void Connect()
        {
            if (IsConnected)
            {
                return;
            }

            _sockClient.ConnectAsync().SynchronouslyAwaitTask();

            if (_handlesMarketData)
            {
                _polygonStreamingClient.ConnectAndAuthenticateAsync().SynchronouslyAwaitTask();
            }

            _isConnected = true;

            // create new thread to manage disconnections and reconnections
            var connectionMonitorStartedEvent = new AutoResetEvent(false);

            _cancellationTokenSource = new CancellationTokenSource();
            _connectionMonitorThread = new Thread(() =>
            {
                connectionMonitorStartedEvent.Set();

                var nextReconnectionAttemptSeconds = 1;

                try
                {
                    while (!_cancellationTokenSource.IsCancellationRequested)
                    {
                        var isAlive = true;
                        try
                        {
                            isAlive = _sockClient.IsAlive;
                        }
                        catch (Exception)
                        {
                            // ignored
                        }

                        if (isAlive && _connectionLost)
                        {
                            _connectionLost = false;
                            nextReconnectionAttemptSeconds = 1;

                            OnMessage(BrokerageMessageEvent.Reconnected("Connection with Alpaca server restored."));
                        }
                        else if (!isAlive)
                        {
                            if (_connectionLost)
                            {
                                try
                                {
                                    Thread.Sleep(TimeSpan.FromSeconds(nextReconnectionAttemptSeconds));

                                    _sockClient.ConnectAsync().SynchronouslyAwaitTask();
                                }
                                catch (Exception exception)
                                {
                                    // double the interval between attempts (capped to 1 minute)
                                    nextReconnectionAttemptSeconds = Math.Min(nextReconnectionAttemptSeconds * 2, 60);

                                    Log.Error(exception);
                                }
                            }
                            else
                            {
                                _connectionLost = true;

                                OnMessage(
                                    BrokerageMessageEvent.Disconnected(
                                        "Connection with Alpaca server lost. " +
                                        "This could be because of internet connectivity issues. "));
                            }
                        }

                        Thread.Sleep(1000);
                    }
                }
                catch (Exception exception)
                {
                    Log.Error(exception);
                }
            })
            {
                IsBackground = true
            };
            _connectionMonitorThread.Start();

            connectionMonitorStartedEvent.WaitOne();
        }
        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);
        }