Overall Statistics
Total Trades
0
Average Win
0%
Average Loss
0%
Compounding Annual Return
0%
Drawdown
0%
Expectancy
0
Net Profit
0%
Sharpe Ratio
0
Probabilistic Sharpe Ratio
0%
Loss Rate
0%
Win Rate
0%
Profit-Loss Ratio
0
Alpha
0
Beta
0
Annual Standard Deviation
0
Annual Variance
0
Information Ratio
-6.47
Tracking Error
0.131
Treynor Ratio
0
Total Fees
$0.00
Estimated Strategy Capacity
$0
Lowest Capacity Asset
#region imports
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using Newtonsoft.Json;
    using QuantConnect.Util;
    using QuantConnect.Data;
    using QuantConnect.Data.UniverseSelection;
    using QuantConnect.Securities;
#endregion

namespace QuantConnect.DataSource
{
    public class FundingRate : BaseData
    {
        [JsonProperty("time")]
        [JsonConverter(typeof(DateTimeJsonConverter), "yyyy-MM-ddTHH:mm:ssK")]
        public override DateTime EndTime { get; set; }
        
        [JsonProperty("future")]
        public string FTXsymbol { get; set; }

        [JsonProperty("rate")]
    	[JsonConverter(typeof(JsonScientificConverter))]
        public decimal Rate { get; set; }
        
        public override SubscriptionDataSource GetSource(SubscriptionDataConfig config, DateTime date, bool isLive)
	    {
	        var source = $"https://ftx.com/api/funding_rates?future={config.Symbol.Value}-PERP";
	
	        return new SubscriptionDataSource(source, SubscriptionTransportMedium.RemoteFile, FileFormat.UnfoldingCollection);
	    }

        public override BaseData Reader(SubscriptionDataConfig config, string line, DateTime date, bool isLive)
    	{
            var response = JsonConvert.DeserializeObject<RawFundingRate>(line, _jsonSerializerSettings);

            if (!response.Success) return null;

            var data = response.Result.Select(json =>
            {
                json.Symbol = config.Symbol;
                json.Time = json.EndTime.AddHours(-1);
                json.Value = json.Rate;
                return json;
            })
            .OrderBy(f => f.Time).ToList();

            return new BaseDataCollection(date, config.Symbol, data);
        }

        public override bool RequiresMapping()
        {
            return false;
        }

        public override bool IsSparseData()
        {
            return true;
        }

        public override Resolution DefaultResolution()
        {
            return Resolution.Hour;
        }

        public override List<Resolution> SupportedResolutions()
        {
            return new List<Resolution>{Resolution.Hour};
        }

        private readonly JsonSerializerSettings _jsonSerializerSettings = new()
        {
            DateTimeZoneHandling = DateTimeZoneHandling.Utc
        };

        private class JsonScientificConverter : JsonConverter
        {
            public override bool CanRead => true;
            public override bool CanConvert(Type objectType) => true;

            public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
            {
                serializer.Serialize(writer, value);
            }

            public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
            {
                return (decimal)(serializer.Deserialize<decimal>(reader));
            }       
        }
    }

    public class RawFundingRate
    {
        [JsonProperty("success")]
        public bool Success { get; set; }

        [JsonProperty("result")]
        public List<FundingRate> Result { get; set; }
    }
}
#region imports
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Globalization;
    using System.Drawing;
    using QuantConnect;
    using QuantConnect.Algorithm.Framework;
    using QuantConnect.Algorithm.Framework.Selection;
    using QuantConnect.Algorithm.Framework.Alphas;
    using QuantConnect.Algorithm.Framework.Portfolio;
    using QuantConnect.Algorithm.Framework.Execution;
    using QuantConnect.Algorithm.Framework.Risk;
    using QuantConnect.Parameters;
    using QuantConnect.Benchmarks;
    using QuantConnect.Brokerages;
    using QuantConnect.Util;
    using QuantConnect.Interfaces;
    using QuantConnect.Algorithm;
    using QuantConnect.Indicators;
    using QuantConnect.Data;
    using QuantConnect.Data.Consolidators;
    using QuantConnect.Data.Custom;
    using QuantConnect.DataSource;
    using QuantConnect.Data.Fundamental;
    using QuantConnect.Data.Market;
    using QuantConnect.Data.UniverseSelection;
    using QuantConnect.Notifications;
    using QuantConnect.Orders;
    using QuantConnect.Orders.Fees;
    using QuantConnect.Orders.Fills;
    using QuantConnect.Orders.Slippage;
    using QuantConnect.Scheduling;
    using QuantConnect.Securities;
    using QuantConnect.Securities.Equity;
    using QuantConnect.Securities.Future;
    using QuantConnect.Securities.Option;
    using QuantConnect.Securities.Forex;
    using QuantConnect.Securities.Crypto;
    using QuantConnect.Securities.Interfaces;
    using QuantConnect.Storage;
    using QuantConnect.Data.Custom.AlphaStreams;
    using QCAlgorithmFramework = QuantConnect.Algorithm.QCAlgorithm;
    using QCAlgorithmFrameworkBridge = QuantConnect.Algorithm.QCAlgorithm;
#endregion

namespace QuantConnect.Algorithm.CSharp
{
    public class TestAlgo : QCAlgorithm
    {
        private Dictionary<Symbol, FundingRate> _fundingRates = new();

		public override void Initialize()
        {
        	SetStartDate(2022, 7, 28);
            SetCash(10000);

            var cryptos = new List<string>{"BTC", "ETH"};

            foreach (var crypto in cryptos)
            {
                AddData<FundingRate>(crypto, Resolution.Hour);
            }
        }
        
        public override void OnData(Slice data)
        {
			foreach (var fr in data.Get<FundingRate>().Values)
			{
                Debug($"Acctual Time {Time} | FR EndTime {fr.EndTime} | FR Symbol {fr.FTXsymbol} | FR Value {fr.Rate}");
            }
    	}
    }
}