/// <summary>Convert a time frame to the string to use in a request</summary> public static string ToRequestString(EMarketTimeFrames tf) { switch (tf) { default: throw new Exception($"Unknown time frame value: {tf}"); case EMarketTimeFrames.None: return(""); case EMarketTimeFrames.Minute1: return("1m"); case EMarketTimeFrames.Minute5: return("5m"); case EMarketTimeFrames.Minute15: return("15m"); case EMarketTimeFrames.Minute30: return("30m"); case EMarketTimeFrames.Hour1: return("1h"); case EMarketTimeFrames.Hour3: return("3h"); case EMarketTimeFrames.Hour6: return("6h"); case EMarketTimeFrames.Hour12: return("12h"); case EMarketTimeFrames.Day1: return("1D"); case EMarketTimeFrames.Week1: return("7D"); case EMarketTimeFrames.Week2: return("14D"); case EMarketTimeFrames.Month1: return("1M"); } }
public List <Candle> GetChartData(CurrencyPair pair, EMarketTimeFrames tf, long time_beg, long time_end, CancellationToken?cancel = null) { // https://api.bitfinex.com/v2/candles/trade:TimeFrame:Symbol/Section var reply = GetData($"v2/candles/trade:{Misc.ToRequestString(tf)}:{pair.Id}/hist", cancel, new KV("start", Misc.ToUnixTime(time_beg) * 1000), new KV("end", Misc.ToUnixTime(time_end) * 1000), new KV("sort", -1)); // Update the chart data for the given pair Candles.ParseUpdate(pair, tf, JArray.Parse(reply)); return(Candles[pair, tf]); }
/// <summary>Return the candle data for the given pair</summary> public List <Candle> this[CurrencyPair pair, EMarketTimeFrames tf] { get { return (!m_data.TryGetValue(pair, out var time_frames) ? new List <Candle>() : !time_frames.TryGetValue(tf, out var candles) ? new List <Candle>() : candles); } set { if (!m_data.TryGetValue(pair, out var time_frames)) { m_data.Add(pair, time_frames = new TimeFramesToCandles()); } time_frames[tf] = value; } }
public SubscriptionCandleData(CurrencyPair pair, EMarketTimeFrames tf) : base(API.ChannelName.Candles) { Pair = pair; TimeFrame = tf; }
/// <summary>Return candle data for the given time range</summary> public List <Candle> GetChartData(CurrencyPair pair, EMarketTimeFrames tf, DateTimeOffset time_beg, DateTimeOffset time_end, CancellationToken?cancel = null) { return(GetChartData(pair, tf, time_beg.Ticks, time_end.Ticks, cancel)); }
/// <summary>Parse a candle message</summary> public void ParseUpdate(CurrencyPair pair, EMarketTimeFrames tf, JArray data) { // Get the candle collection var candles = this[pair, tf]; // If the update contains an array of arrays, then this is a history update if (data[0].Type == JTokenType.Array) { // Expect the data to be order from oldest to newest var new_candles = data.Select(x => new Candle((JArray)x)).ToList(); // Insert 'new_candles' into 'candles' if (new_candles.Count != 0) { // Erase the range spanned by 'new_candles' var beg = new_candles[0]; var end = new_candles[new_candles.Count - 1]; var ibeg = candles.BinarySearch(beg); var iend = candles.BinarySearch(end); if (ibeg < 0) { ibeg = ~ibeg; } if (iend < 0) { iend = ~iend; } candles.RemoveRange(ibeg, iend - ibeg); // Insert the new candles into 'candles' candles.InsertRange(ibeg, new_candles); } } // Otherwise, this is an update to the latest candle else { var new_candle = new Candle(data); // Insert/Update 'new_candle' in 'candles' var last = candles.Count != 0 ? candles[candles.Count - 1] : null; if (last == null || last.Timestamp < new_candle.Timestamp) { candles.Add(new_candle); } else if (last.Timestamp == new_candle.Timestamp) { candles[candles.Count - 1] = new_candle; } else { var idx = candles.BinarySearch(new_candle); if (idx >= 0) { candles[idx] = new_candle; } else { candles.Insert(~idx, new_candle); } } } // Save the candle collection this[pair, tf] = candles; }
/// <summary>True if there is candle data for 'pair' at period 'tf'</summary> public bool Contains(CurrencyPair pair, EMarketTimeFrames tf) { return (m_data.TryGetValue(pair, out var time_frames) && time_frames.TryGetValue(tf, out var candles)); }