/// <summary>
 /// Get a granularity in seconds
 /// </summary>
 /// <param name="granularity">The granularity</param>
 /// <returns>How many seconds that granularity represents</returns>
 public static int GetInSeconds(this CandlestickGranularity granularity)
 {
     return(granularity switch
     {
         CandlestickGranularity.S5 => 5,
         CandlestickGranularity.S10 => 10,
         CandlestickGranularity.S15 => 15,
         CandlestickGranularity.S30 => 30,
         CandlestickGranularity.M1 => 60,
         CandlestickGranularity.M2 => (60 * 2),
         CandlestickGranularity.M4 => (60 * 4),
         CandlestickGranularity.M5 => (60 * 5),
         CandlestickGranularity.M10 => (60 * 10),
         CandlestickGranularity.M15 => (60 * 15),
         CandlestickGranularity.M30 => (60 * 30),
         CandlestickGranularity.H1 => (60 * 60),
         CandlestickGranularity.H2 => (60 * 60 * 2),
         CandlestickGranularity.H3 => (60 * 60 * 3),
         CandlestickGranularity.H4 => (60 * 60 * 4),
         CandlestickGranularity.H6 => (60 * 60 * 6),
         CandlestickGranularity.H8 => (60 * 60 * 8),
         CandlestickGranularity.H12 => (60 * 60 * 12),
         CandlestickGranularity.D => (60 * 60 * 24),
         CandlestickGranularity.W => (60 * 60 * 24 * 7),
         CandlestickGranularity.M => (60 * 60 * 24 * 31),
         _ => 5,
     });
Ejemplo n.º 2
0
        /// <summary>
        /// Fetch candlestick data for an instrument.
        /// </summary>
        /// <param name="pairs">The instrument pair value</param>
        /// <param name="queryNVC"></param>
        /// <returns></returns>
        public async Task <CandlestickResponse> GetInstrumentCandles(
            InstrumentName instrument,
            DateTime from,
            DateTime to,
            CandlestickGranularity granularity = null,
            int count = 500,
            WeeklyAlignment weeklyAlignment = null,
            string price             = "M",
            bool smooth              = false,
            bool includeFirst        = true,
            int dailyAlignment       = 17,
            string alignmentTimezone = "America/New_York"
            )
        {
            #region QueryNVC
            NameValueCollection queryNVC = new NameValueCollection()
            {
                { "count", count.ToString() },
                { "price", price },
                { "smooth", smooth.ToString() },
                { "includeFirst", includeFirst.ToString() },
                { "dailyAlignment", dailyAlignment.ToString() },
                { "alignmentTimeZone", alignmentTimezone }
            };
            if (from != null)
            {
                queryNVC.Add("from", from.ToUniversalTime().ToString());
            }
            if (to != null)
            {
                queryNVC.Add("to", to.ToUniversalTime().ToString());
            }
            if (granularity != null)
            {
                queryNVC.Add("granularity", granularity.ToString());
            }
            if (weeklyAlignment != null)
            {
                queryNVC.Add("weeklyAlignment", weeklyAlignment.ToString());
            }
            #endregion

            string path  = string.Format("instruments/{0}/candles", instrument);
            string query = QueryFromNVC(queryNVC);

            using (HttpResponseMessage response = await RequestAsync(EHostAPIType.REST, HttpMethod.Get, path, query))
            {
                if (response.StatusCode != HttpStatusCode.OK)
                {
                    throw new HttpRequestException(JObject.Parse(await response.Content.ReadAsStringAsync())["errorMessage"].ToString());
                }

                using (Stream stream = await response.Content.ReadAsStreamAsync())
                {
                    string jsonString = await new StreamReader(stream).ReadToEndAsync();
                    return(JsonConvert.DeserializeObject <CandlestickResponse>(jsonString, ErrorHandlingSetting));
                }
            }
        }
        /// <summary>
        /// Is the timerange and granularity specifies more candles than Oanda can handle in one request?
        /// </summary>
        /// <param name="granularity">The granularity to check</param>
        /// <param name="from">From date time</param>
        /// <param name="to">To date time</param>
        /// <returns></returns>
        public static bool AreMultipleQueriesRequired(this CandlestickGranularity granularity, DateTime from, DateTime to)
        {
            // Always convert dates to UTC when working with Oanda
            from = from.ToUniversalTime();
            to   = to.ToUniversalTime();

            // Check the number of candles
            return(granularity.GetNumberOfCandlesForTimeRange(from, to) > OANDA_MAX_CANDLES);
        }
Ejemplo n.º 4
0
 public CandlestickResponse(
     string instrument,
     CandlestickGranularity granularity,
     ImmutableList <CandleStick> candles)
 {
     Instrument  = instrument;
     Granularity = granularity;
     Candles     = candles;
 }
Ejemplo n.º 5
0
 public async Task <CandlestickResponse> GetInstrumentCandles(
     InstrumentName instrument,
     DateTime from,
     DateTime to,
     CandlestickGranularity granularity = null,
     int count = 500,
     WeeklyAlignment weeklyAlignment = null
     )
 {
     return(await GetInstrumentCandles(instrument, from, to, granularity, count, weeklyAlignment));
 }
        /// <summary>
        /// Calculate number of candles in a time range
        /// </summary>
        /// <param name="granularity">Granularity of the candles</param>
        /// <param name="from">The from date</param>
        /// <param name="to">The to date</param>
        /// <returns></returns>
        public static double GetNumberOfCandlesForTimeRange(this CandlestickGranularity granularity, DateTime from, DateTime to)
        {
            // Always convert dates to UTC when working with Oanda
            from = from.ToUniversalTime();
            to   = to.ToUniversalTime();

            // Check not to enter endless loops
            if (from > to)
            {
                throw new ArgumentException("The 'to' time cannot be before the 'to' time.");
            }

            // Return the number of candles
            return((to - from).TotalSeconds / granularity.GetInSeconds());
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Get the last N candles for the instrument asynchronously
        /// </summary>
        /// <param name="granularity">Granularity of the candles</param>
        /// <param name="n">How many candles to get</param>
        /// <param name="pricingComponents">The pricing components to consider (bid, mid, ask)</param>
        /// <returns>Enumerable collection of candles</returns>
        public async Task <IEnumerable <Candlestick> > GetLastNCandlesAsync(CandlestickGranularity granularity, int n, IEnumerable <PricingComponent>?pricingComponents = null)
        {
            if (n > 5000)
            {
                throw new Exception("Maximum 5000 candles are allowed");
            }

            var candlesResponse = await _connection.InstrumentApi.GetInstrumentCandlesAsync(
                instrument : _instrument,
                granularity : granularity,
                count : n,
                price : ResolvePricingComponents(pricingComponents)
                );

            return(candlesResponse.Candles);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Get the candles for the instrument for the timeperiod passed asynchronously
        /// </summary>
        /// <param name="granularity">Granularity of the candles</param>
        /// <param name="from">The time the candles should start with</param>
        /// <param name="to">The time the candles should end with</param>
        /// <param name="pricingComponents">The pricing components to consider (bid, mid, ask)</param>
        /// <returns>Enumerable collection of candles</returns>
        public async Task <IEnumerable <Candlestick> > GetCandlesByTimeAsync(CandlestickGranularity granularity, DateTime from, DateTime to, IEnumerable <PricingComponent>?pricingComponents = null)
        {
            // Always convert dates to UTC when working with Oanda
            from = from.ToUniversalTime();
            to   = to.ToUniversalTime();

            if (granularity.AreMultipleQueriesRequired(from, to))
            {
                var candlesRange    = granularity.ExplodeToMultipleCandleRanges(from, to);
                var candleResponses = new List <CandlesResponse>();

                foreach (var candleFromToRange in candlesRange)
                {
                    candleResponses.Add(
                        await _connection.InstrumentApi.GetInstrumentCandlesAsync(
                            instrument: _instrument,
                            granularity: granularity,
                            price: ResolvePricingComponents(pricingComponents),
                            from: candleFromToRange.From.ToOandaDateTime(_connection.DateTimeFormat),
                            to: candleFromToRange.To.ToOandaDateTime(_connection.DateTimeFormat),
                            acceptDatetimeFormat: _connection.DateTimeFormat
                            )
                        );
                }

                return(candleResponses.SelectMany(cr => cr.Candles));
            }
            else
            {
                var candlesResponse = await _connection.InstrumentApi.GetInstrumentCandlesAsync(
                    instrument : _instrument,
                    granularity : granularity,
                    price : ResolvePricingComponents(pricingComponents),
                    from : from.ToOandaDateTime(_connection.DateTimeFormat),
                    to : to.ToOandaDateTime(_connection.DateTimeFormat),
                    acceptDatetimeFormat : _connection.DateTimeFormat
                    );

                return(candlesResponse.Candles);
            }
        }
        /// <summary>
        /// Explode a datetime range to multiple to fit in to Oanda API limitation
        /// </summary>
        /// <param name="granularity"></param>
        /// <param name="from"></param>
        /// <param name="to"></param>
        /// <returns></returns>
        public static IEnumerable <DateTimeRange> ExplodeToMultipleCandleRanges(this CandlestickGranularity granularity, DateTime from, DateTime to)
        {
            // Always convert dates to UTC when working with Oanda
            from = from.ToUniversalTime();
            to   = to.ToUniversalTime();

            // Make the timerange calulation
            var numberOfCandles = granularity.GetNumberOfCandlesForTimeRange(from, to);
            var numberOfQueries = Math.Ceiling(numberOfCandles / OANDA_MAX_CANDLES);
            var candleRanges    = new List <DateTimeRange>();

            for (var i = 0; i <= (numberOfQueries - 1); i++)
            {
                candleRanges.Add(new DateTimeRange()
                {
                    From = from.AddSeconds(i * OANDA_MAX_CANDLES * granularity.GetInSeconds()),
                    To   = (i == (numberOfQueries - 1)) ? to  : from.AddSeconds(((i + 1) * OANDA_MAX_CANDLES * granularity.GetInSeconds()) - 1)
                });
            }

            // Return the tim ranges created
            return(candleRanges);
        }
Ejemplo n.º 10
0
        public Task <CandlesResponse> GetCandles(
            CancellationToken cancellationToken,
            string instrument,
            DateTime from,
            DateTime?to,
            CandlestickGranularity granularity)
        {
            var apiUrl = $"{OandaUrls.Instruments}/{instrument}/candles";

            var queryParams = new Dictionary <string, string>();

            queryParams.Add("from", FormatDateTimeToQuery(from));

            if (to.HasValue)
            {
                queryParams.Add("to", FormatDateTimeToQuery(to.Value));
            }

            queryParams.Add("granularity", granularity.ToString());

            var queryString = string.Join("&", queryParams.Select(x => $"{x.Key}={x.Value}"));

            return(ApiClient.MakeGetRequestAsync <CandlesResponse>($"{apiUrl}?{queryString}", cancellationToken));
        }