book
Checkout our new book! Hands on AI Trading with Python, QuantConnect, and AWS Learn More arrow

QuantConnect

Bybit Crypto Future Margin Rate Data

Introduction

The Bybit Crypto Future Margin Rate Data by QuantConnect is for Cryptocurrency Futures margin interest data points. The data covers 433 Cryptocurrency pairs, starts in August 2020, and is delivered on a daily update frequency. This dataset is created by downloading data using Bybit API.

This dataset is an important companion to the Bybit Crypto Future Price Data dataset because it contains information on margin interest data to model margin costs.

For more information about the Bybit Crypto Future Margin Rate Data dataset, including CLI commands and pricing, see the dataset listing.

About the Provider

QuantConnect was founded in 2012 to serve quants everywhere with the best possible algorithmic trading technology. Seeking to disrupt a notoriously closed-source industry, QuantConnect takes a radically open-source approach to algorithmic trading. Through the QuantConnect web platform, more than 50,000 quants are served every month.

Getting Started

The following snippet demonstrates how to request data from the Bybit Crypto Future Margin Rate dataset:

def Initialize(self) -> None:
    self.SetBrokerageModel(BrokerageName.Bybit, AccountType.Margin)

    self.crypto_future_symbol = self.AddCryptoFuture("BTCBUSD", Resolution.Minute).Symbol
private Symbol _cryptoFutureSymbol;

public override void Initialize
{
    SetBrokerageModel(BrokerageName.Bybit, AccountType.Margin);

    // perpetual futures does not have a filter function
    _cryptoFutureSymbol = AddCryptoFuture("BTCBUSD", Resolution.Minute).Symbol;
}

The Bybit Crypto Future Margin Rate data is added to your algorithm along with the market data when you add a crypto future subscription.

Data Summary

The following table describes the dataset properties:

PropertyValue
Start DateAugust 2020
Asset Coverage433 Crypto Futures Pairs
Data DensityRegular
ResolutionDaily
TimezoneUTC
Market HoursAlways Open

Requesting Data

To add Bybit Crypto Future Margin Rate data to your algorithm, call the AddCryptoFutureadd_crypto_future method. Save a reference to the Crypto Future Symbol so you can access the data later in your algorithm.

from AlgorithmImports import *
from QuantConnect.DataSource import *

class CoinAPIDataAlgorithm(QCAlgorithm):

    def initialize(self) -> None:
        self.set_start_date(2020, 6, 1)
        self.set_end_date(2021, 6, 1)

        # Set Account Currency to Tether
        self.set_account_currency("USDT", 100000)

        self.set_brokerage_model(BrokerageName.BYBIT, AccountType.MARGIN)
        
        crypto_future = self.add_crypto_future("BTCUSDT", Resolution.MINUTE)
        # perpetual futures does not have a filter function
        self.btcusdt = crypto_future.symbol
namespace QuantConnect
{
    public class CoinAPIDataAlgorithm : QCAlgorithm
    {
        private Symbol _symbol ;
        
        public override void Initialize()
        {
            SetStartDate(2020, 6, 1);
            SetEndDate(2021, 6, 1);

            // Set Account Currency to Tether
            SetAccountCurrency("USDT", 100000);

            SetBrokerageModel(BrokerageName.Bybit, AccountType.Margin);
            
            var cryptoFuture = AddCryptoFuture("BTCUSDT", Resolution.Minute);
            // perpetual futures does not have a filter function
            _symbol = cryptoFuture.Symbol;
        }
    }
}

For more information about creating Crypto Future subscriptions, see Requesting Data.

Accessing Data

To get the current Bybit Crypto Margin Rate data, index the MarginInterestRatesmargin_interest_rates property of the current Slice with the Crypto Future Symbol. Slice objects deliver unique events to your algorithm as they happen, but the Slice may not contain data for your security at every time step. To avoid issues, check if the Slice contains the data you want before you index it.

def on_data(self, slice: Slice) -> None:
        if self.btcusdt in slice.margin_interest_rates:
            interest_rate = slice.margin_interest_rates[self.btcusdt].interest_rate
            self.log(f"{self.btcusdt} close at {slice.time}: {interest_rate}")
public override void OnData(Slice slice)
{
    if (slice.MarginInterestRates.ContainsKey(_symbol))
    {
        var interestRate = slice.MarginInterestRates[_symbol].InterestRate;
        Log($"{_symbol} price at {slice.Time}: {interestRate}");
    }
}

You can also iterate through all of the data objects in the current Slice.

def on_data(self, slice: Slice) -> None:
    for symbol, margin_interest_rate in slice.margin_interest_rates.items():
        interest_rate = margin_interest_rate.interest_rate
        self.log(f"{symbol} close at {slice.time}: {interest_rate}")
public override void OnData(Slice slice)
{
    foreach (var kvp in slice.MarginInterestRates)
    {
        var symbol = kvp.Key;
        var marginInterestRate = kvp.Value;
        var interestRate = marginInterestRate.InterestRate;
        Log($"{symbol} price at {slice.Time}: {interestRate}");
    }
}

For more information about accessing Crypto Future data, see Handling Data.

Historical Data

To get historical Bybit Crypto Future Margin Rate data, call the History<MarginInterestRate>history method with MarginInterestRate data type and the Crypto Future Symbol. If there is no data in the period you request, the history result is empty.

# DataFrame
history_df = self.history(MarginInterestRate, self.btcusdt, 100, Resolution.DAILY)

# MarginInterestRate objects
history = self.history[MarginInterestRate](self.btcusdt, 100, Resolution.DAILY)
var history = History<MarginInterestRate>(_symbol, 100, Resolution.Daily);

For more information about historical data, see History Requests.

Remove Subscriptions

To unsubscribe from a Crypto pair that you added with the AddCryptoadd_crypto method, call the RemoveSecurityremove_security method.

self.remove_security(self.btcusdt)
RemoveSecurity(_symbol);

TheRemoveSecurityremove_security method cancels your open orders for the security and liquidates your holdings in the virtual pair.

Supported Assets

The following table shows the available Crypto Future pairs:

Example Applications

The Binance Crypto Future Margin Rate dataset enables correct margin cost so you can accurately design strategies for Cryptocurrencies with term structure. Examples include the following strategies:

  • Horizontal/Diagonal arbitrage with the underlying Cryptocurrencies
  • Trade Contango/Backwardation predictions
  • Hedge for illiquid Cryptocurrencies

Classic Algorithm Example

The following example algorithm buys a BTCUSDT perpetual Futures contract through the Bybit exchange if the previous day's closing price was closer to ask close price than bid close price. Otherwise, it short sells the contract.

from AlgorithmImports import *

class BybitCryptoFutureDataAlgorithm(QCAlgorithm):

    def initialize(self) -> None:
        self.set_start_date(2022, 10, 1)
        self.set_end_date(2022, 10, 10)
        # Set Account Currency to Tether, since USD and USDT will not auto-convert and USD cannot be used to trade
        self.set_account_currency("USDT", 100000)
        # Bybit accepts both Cash and Margin account types, select the one you need for the best reality modeling.
        self.set_brokerage_model(BrokerageName.BYBIT, AccountType.MARGIN)

        # Requesting data, we only trade on BTCUSDT Future in Bybit exchange
        crypto_future = self.add_crypto_future("BTCUSDT", Resolution.DAILY)
        # perpetual futures does not have a filter function
        self.btcusdt = crypto_future.symbol

        # Historical data
        history = self.history(self.btcusdt, 10, Resolution.DAILY)
        self.debug(f"We got {len(history)} from our history request for {self.btcusdt}")

    def on_data(self, slice: Slice) -> None:
        # Note that you may want to access the margin interest of the crypto future to calculate if it would impact a trade's PnL
        # Or you can calculate the trade size on keeping the quote currency constant
        if self.btcusdt in slice.margin_interest_rates:
            interest_rate = slice.margin_interest_rates[self.btcusdt].interest_rate
            self.log(f"{self.btcusdt} close at {slice.time}: {interest_rate}")      
  
        # Trade only based on updated price data
        if not slice.bars.contains_key(self.btcusdt) or not slice.quote_bars.contains_key(self.btcusdt):
            return

        quote = slice.quote_bars[self.btcusdt]
        price = slice.bars[self.btcusdt].price

        # Scalp-trade the bid-ask spread based on the supply-demand strength
        if price - quote.bid.close > quote.ask.close - price:
            self.set_holdings(self.btcusdt, -1)
        else:
            self.set_holdings(self.btcusdt, 1)
using System.Linq;
using QuantConnect.Data;
using QuantConnect.Brokerages;

namespace QuantConnect.Algorithm.CSharp
{
    public class BybitCryptoFutureDataAlgorithm : QCAlgorithm
    {
        public Symbol _symbol;

        public override void Initialize()
        {
            SetStartDate(2022, 1, 1);
            SetEndDate(2023, 1, 1);
            // Set Account Currency to Tether, since USD and USDT will not auto-convert and USD cannot be used to trade
            SetAccountCurrency("USDT", 100000);
            // Bybit accepts both Cash and Margin account types, select the one you need for the best reality modeling.
            SetBrokerageModel(BrokerageName.Bybit, AccountType.Margin);

            // Requesting data, we only trade on BTCUSDT Future in Bybit exchange
            var cryptoFuture = AddCryptoFuture("BTCUSDT", Resolution.Daily);
            // perpetual futures does not have a filter function
            _symbol = cryptoFuture.Symbol;

            // Historical data
            var history = History(_symbol, 10, Resolution.Daily);
            Debug($"We got {history.Count()} from our history request for {_symbol}");
        }

        public override void OnData(Slice slice)
        {
            // Note that you may want to access the margin interest of the crypto future to calculate if it would impact a trade's PnL
            // Or you can calculate the trade size on keeping the quote currency constant
            if (slice.MarginInterestRates.ContainsKey(_symbol))
            {
                var interestRate = slice.MarginInterestRates[_symbol].InterestRate;
                Log($"{_symbol} price at {slice.Time}: {interestRate}");
            }

            // Trade only based on updated price data
            if (!slice.QuoteBars.TryGet(_symbol, out var quote) || !slice.Bars.ContainsKey(_symbol))
            {
                return;
            }
            var price = slice.Bars[_symbol].Price;
            
            // Scalp-trade the bid-ask spread based on the supply-demand strength
            if (price - quote.Bid.Close > quote.Ask.Close - price)
            {
                SetHoldings(_symbol, -1m);
            }
            else
            {
                SetHoldings(_symbol, 1m);
            }
        }
    }
}

Framework Algorithm Example

The following example framework algorithm holds a 100% long BTCUST Future portfolio if the previous day's closing price was closer to ask close price than bid close price. Otherwise, it holds a short position in the contract.

from AlgorithmImports import *

class BybitCryptoFutureDataAlgorithm(QCAlgorithm):

    def initialize(self) -> None:
        self.set_start_date(2022, 10, 1)
        self.set_end_date(2022, 10, 10)
        # Set Account Currency to Tether, since USD and USDT will not auto-convert and USD cannot be used to trade
        self.set_account_currency("USDT", 100000)
        # Bybit accepts both Cash and Margin account types, select the one you need for the best reality modeling.
        self.set_brokerage_model(BrokerageName.BYBIT, AccountType.MARGIN)

        self.universe_settings.resolution = Resolution.DAILY
        self.universe_settings.leverage = 2
        # We only trade on BTCUSDT Future in Bybit exchange
        symbols = [Symbol.create("BTCUSDT", SecurityType.CRYPTO_FUTURE, Market.BYBIT)]
        self.add_universe_selection(ManualUniverseSelectionModel(symbols))
        # Custom alpha model to emit insights based on the Crypto Future price data
        self.add_alpha(CryptoFutureAlphaModel())
        # Equally invest to evenly dissipate the capital concentration risk of inidividual crypto pair
        self.set_portfolio_construction(EqualWeightingPortfolioConstructionModel())
        self.set_execution(ImmediateExecutionModel())

class CryptoFutureAlphaModel(AlphaModel):

    def __init__(self) -> None:
        self.symbols = []

    def update(self, algorithm: QCAlgorithm, slice: Slice) -> List[Insight]:
        insights = []

        for symbol in self.symbols:
            # Note that you may want to access the margin interest of the crypto future to calculate if it would impact a trade's PnL
            # Or you can calculate the trade size on keeping the quote currency constant
            if symbol in slice.margin_interest_rates:
                interest_rate = slice.margin_interest_rates[symbol].interest_rate
                algorithm.log(f"{symbol} close at {slice.time}: {interest_rate}")      

            # Trade only based on updated price data
            if not slice.bars.contains_key(symbol) or not slice.quote_bars.contains_key(symbol):
                continue
            quote = slice.quote_bars[symbol]
            price = slice.bars[symbol].price

            # Scalp-trade the bid-ask spread based on the supply-demand strength
            if price - quote.bid.close > quote.ask.close - price:
                insights.append(Insight.price(symbol, timedelta(1), InsightDirection.DOWN))
            else:
                insights.append(Insight.price(symbol, timedelta(1), InsightDirection.UP))
            
        return insights

    def on_securities_changed(self, algorithm: QCAlgorithm, changes: SecurityChanges) -> None:
        for security in changes.added_securities:
            symbol = security.symbol
            self.symbols.append(symbol)

            # Historical data
            history = algorithm.history(symbol, 10, Resolution.DAILY)
            algorithm.debug(f"We got {len(history)} from our history request for {symbol}")

        for security in changes.removed_securities:
            symbol = security.symbol
            if symbol in self.symbols:
                self.symbols.remove(symbol)
using System;
using System.Collections.Generic;
using System.Linq;
using QuantConnect.Brokerages;
using QuantConnect.Data;
using QuantConnect.Data.UniverseSelection;
using QuantConnect.Algorithm.Framework.Selection;
using QuantConnect.Algorithm.Framework.Alphas;
using QuantConnect.Algorithm.Framework.Portfolio;
using QuantConnect.Algorithm.Framework.Execution;

namespace QuantConnect.Algorithm.CSharp
{
    public class BybitCryptoFutureDataAlgorithm : QCAlgorithm
    {
        public Symbol _symbol;

        public override void Initialize()
        {
            SetStartDate(2022, 10, 1);
            SetEndDate(2022, 10, 10);
            // Set Account Currency to Tether, since USD and USDT will not auto-convert and USD cannot be used to trade
            SetAccountCurrency("USDT", 100000);
            // Bybit accepts both Cash and Margin account types, select the one you need for the best reality modeling.
            SetBrokerageModel(BrokerageName.Bybit, AccountType.Margin);

            UniverseSettings.Resolution = Resolution.Daily;
            UniverseSettings.Leverage = 2;
            // We only trade on BTCUSDT Future in Bybit exchange
            var symbols = new []{
                QuantConnect.Symbol.Create("BTCUSDT", SecurityType.CryptoFuture, Market.Bybit)
            };
            AddUniverseSelection(new ManualUniverseSelectionModel(symbols));
            // Custom alpha model to emit insights based on the Crypto Future price data
            AddAlpha(new CryptoFutureAlphaModel());
            // Equally invest to evenly dissipate the capital concentration risk of inidividual crypto pair
            SetPortfolioConstruction(new EqualWeightingPortfolioConstructionModel());
            SetExecution(new ImmediateExecutionModel());
        }
    }

    public class CryptoFutureAlphaModel : AlphaModel
    {
        private List<Symbol> _symbols = new();

        public override List<Insight> Update(QCAlgorithm algorithm, Slice slice)
        {
            var insights = new List<Insight>();

            foreach (var symbol in _symbols)
            {
                // Note that you may want to access the margin interest of the crypto future to calculate if it would impact a trade's PnL
                // Or you can calculate the trade size on keeping the quote currency constant
                if (slice.MarginInterestRates.ContainsKey(symbol))
                {
                    var interestRate = slice.MarginInterestRates[symbol].InterestRate;
                    algorithm.Log($"{symbol} price at {slice.Time}: {interestRate}");
                }

                // Trade only based on updated price data
                if (!slice.Bars.ContainsKey(symbol) || !slice.QuoteBars.TryGet(symbol, out var qoute))
                {
                    continue;
                }
                var price = slice.Bars[symbol].Price;

                // Scalp-trade the bid-ask spread based on the supply-demand strength
                if (price - quote.Bid.Close > quote.Ask.Close - price)
                {
                    insights.Add(
                        Insight.Price(symbol, TimeSpan.FromDays(1), InsightDirection.Down)
                    );
                }
                else
                {
                    insights.Add(
                        Insight.Price(symbol, TimeSpan.FromDays(1), InsightDirection.Up)
                    );
                }
            }
            
            return insights;
        }

        public override void OnSecuritiesChanged(QCAlgorithm algorithm, SecurityChanges changes)
        {
            foreach (var security in changes.AddedSecurities)
            {
                var symbol = security.Symbol;
                _symbols.Add(symbol);

                // Historical data
                var history = algorithm.History(symbol, 10, Resolution.Daily);
                algorithm.Debug($"We got {history.Count()} from our history request for {symbol}");
            }

            foreach (var security in changes.RemovedSecurities)
            {
                _symbols.Remove(security.Symbol);
            }
        }
    }
}

Data Point Attributes

The Binance Crypto Future Margin Rate dataset provides MarginInterestRate objects, which have the following attributes:

You can also see our Videos. You can also get in touch with us via Discord.

Did you find this page helpful?

Contribute to the documentation: