QuantConnect
Binance Crypto Future Margin Rate Data
Introduction
The Binance Crypto Future Margin Rate Data by QuantConnect is for crypto-currency futures margin interest data points. The data covers 421 Cryptocurrency pairs, starts in August 2020, and is delivered on a daily update frequency. This dataset is created by downloading data using Binance API.
This dataset is an important companion to the Binance Crypto Future Price Data dataset because it contains information on margin interest data to model margin costs.
For more information about the Binance 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 Binance Crypto Future Margin Rate dataset:
def initialize(self) -> None: self.set_brokerage_model(BrokerageName.BINANCE_FUTURES, AccountType.MARGIN) self.set_brokerage_model(BrokerageName.BINANCE_COIN_FUTURES, AccountType.MARGIN) self.crypto_future_symbol = self.add_crypto_future("BTCBUSD", Resolution.MINUTE).symbol
private Symbol _cryptoFutureSymbol; public override void Initialize { SetBrokerageModel(BrokerageName.BinanceFutures, AccountType.Margin); SetBrokerageModel(BrokerageName.BinanceCoinFutures, AccountType.Margin); // perpetual futures does not have a filter function _cryptoFutureSymbol = AddCryptoFuture("BTCBUSD", Resolution.Minute).Symbol; }
The Binance 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:
Property | Value |
---|---|
Start Date | August 2020 |
Asset Coverage | 421 Crypto Futures Pairs |
Data Density | Regular |
Resolution | Daily |
Timezone | UTC |
Market Hours | Always Open |
Requesting Data
To add Binance Crypto Future Margin Rate data to your algorithm, call the AddCryptoFuture
add_crypto_future
method. Save a reference to the Crypto Future Symbol
so you can access the data later in your algorithm.
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 Binance Stable Coin for USD self.set_account_currency("BUSD") self.set_cash(100000) self.set_brokerage_model(BrokerageName.BINANCE_FUTURES, AccountType.MARGIN) self.set_brokerage_model(BrokerageName.BINANCE_COIN_FUTURES, AccountType.MARGIN) crypto_future = self.add_crypto_future("BTCBUSD", Resolution.MINUTE) # perpetual futures does not have a filter function self.btcbusd = 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 Binance Stable Coin for USD SetAccountCurrency("BUSD"); SetCash(100000); SetBrokerageModel(BrokerageName.BinanceFutures, AccountType.Margin); SetBrokerageModel(BrokerageName.BinanceCoinFutures, AccountType.Margin); var cryptoFuture = AddCryptoFuture("BTCBUSD", 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 Binance Crypto Margin Rate data, index the MarginInterestRates
margin_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.btcbusd in slice.margin_interest_rates: interest_rate = slice.margin_interest_rates[self.btcbusd].interest_rate self.log(f"{self.btcbusd} 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 Binance 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.btcbusd, 100, Resolution.DAILY) # MarginInterestRate objects history = self.history[MarginInterestRate](self.btcbusd, 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 AddCrypto
add_crypto
method, call the RemoveSecurity
remove_security
method.
self.remove_security(self.btcbusd)
RemoveSecurity(_symbol);
The RemoveSecurity
remove_security
method cancels your open orders for the security and liquidates your holdings in the virtual pair.
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 BTCBUSD perpetual future contract if the last day's close price was close to ask close price than bid close price, sells short of that in opposite, through the Binance exchange:
from AlgorithmImports import * class BinanceCryptoFutureDataAlgorithm(QCAlgorithm): def initialize(self) -> None: self.set_start_date(2022, 10, 1) self.set_end_date(2022, 10, 10) # Set Account Currency to Binance Stable Coin, since USD-BUSD will not auto-convert and USD cannot be used to trade self.set_cash("BUSD", 100000) # Binance Futures Exchange accepts both Cash and Margin account types, select the one you need for the best reality modeling. self.set_brokerage_model(BrokerageName.BINANCE_FUTURES, AccountType.MARGIN) # Requesting data, we only trade on BTCBUSD Future in Binance Future exchange crypto_future = self.add_crypto_future("BTCBUSD", Resolution.DAILY) # perpetual futures does not have a filter function self.btcbusd = crypto_future.symbol # Historical data history = self.history(self.btcbusd, 10, Resolution.DAILY) self.debug(f"We got {len(history)} from our history request for {self.btcbusd}") 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.btcbusd in slice.margin_interest_rates: interest_rate = slice.margin_interest_rates[self.btcbusd].interest_rate self.log(f"{self.btcbusd} close at {slice.time}: {interest_rate}") # Trade only based on updated price data if not slice.bars.contains_key(self.btcbusd) or not slice.quote_bars.contains_key(self.btcbusd): return quote = slice.quote_bars[self.btcbusd] price = slice.bars[self.btcbusd].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.btcbusd, -1) else: self.set_holdings(self.btcbusd, 1)
using System.Linq; using QuantConnect.Data; using QuantConnect.Brokerages; namespace QuantConnect.Algorithm.CSharp { public class BinanceCryptoFutureDataAlgorithm : QCAlgorithm { public Symbol _symbol; public override void Initialize() { SetStartDate(2022, 1, 1); SetEndDate(2023, 1, 1); // Set Account Currency to Binance Stable Coin, since USD-BUSD will not auto-convert and USD cannot be used to trade SetCash("BUSD", 100000); // Binance Futures Exchange accepts both Cash and Margin account types, select the one you need for the best reality modeling. SetBrokerageModel(BrokerageName.BinanceFutures, AccountType.Margin); // Requesting data, we only trade on BTCBUSD Future in Binance Future exchange var cryptoFuture = AddCryptoFuture("BTCBUSD", 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.Bars.ContainsKey(_symbol) || !slice.QuoteBars.TryGet(_symbol, out var quote)) { 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 algorithm hold a 100% long BTCBUSD future portfolio if the last day's close price was close to ask close price than bid close price, while hold short of that in opposite, through the Binance exchange using the algorithm framework implementation:
from AlgorithmImports import * class BinanceCryptoFutureDataAlgorithm(QCAlgorithm): def initialize(self) -> None: self.set_start_date(2022, 10, 1) self.set_end_date(2022, 10, 10) # Set Account Currency to Binance Stable Coin, since USD-BUSD will not auto-convert and USD cannot be used to trade self.set_cash("BUSD", 100000) # Binance Futures Exchange accepts both Cash and Margin account types, select the one you need for the best reality modeling. self.set_brokerage_model(BrokerageName.BINANCE_FUTURES, AccountType.MARGIN) self.universe_settings.resolution = Resolution.DAILY self.universe_settings.leverage = 2 # We only trade on BTCBUSD Future in Binance Future exchange symbols = Symbol.create("BTCBUSD", SecurityType.CRYPTO_FUTURE, Market.BINANCE) 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 BinanceCryptoFutureDataAlgorithm : QCAlgorithm { public Symbol _symbol; public override void Initialize() { SetStartDate(2022, 10, 1); SetEndDate(2022, 10, 10); // Set Account Currency to Binance Stable Coin, since USD-BUSD will not auto-convert and USD cannot be used to trade SetCash("BUSD", 100000); // Binance Futures Exchange accepts both Cash and Margin account types, select the one you need for the best reality modeling. SetBrokerageModel(BrokerageName.BinanceFutures, AccountType.Margin); UniverseSettings.Resolution = Resolution.Daily; UniverseSettings.Leverage = 2; // We only trade on BTCBUSD Future in Binance Future exchange var symbols = new List{ QuantConnect.Symbol.Create("BTCBUSD", SecurityType.CryptoFuture, Market.Binance) }; 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 _symbols = new(); public override List Update(QCAlgorithm algorithm, Slice slice) { var insights = new List(); 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 quote)) { 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); } } } }