CoinAPI
Bybit Crypto Future Price Data
Introduction
The Bybit Crypto Future Price Data by CoinAPI is for Cryptocurrency Futures price and volume data points. The data covers 631 Cryptocurrency pairs, starts in August 2020, and is delivered on any frequency from tick to daily. This dataset is created by monitoring the trading activity on Bybit.
The Bybit Crypto Future Margin Rate Data dataset provides margin interest rate data to model margin costs.
For more information about the Bybit Crypto Future Price Data dataset, including CLI commands and pricing, see the dataset listing.
About the Provider
CoinAPI was founded by Artur Pietrzyk in 2016 with the goal of providing real-time and historical cryptocurrency market data, collected from hundreds of exchanges. CoinAPI provides access to Cryptocurrencies for traders, market makers, and developers building third-party applications.
Getting Started
The following snippet demonstrates how to request data from the Bybit Crypto Future Price dataset:
def initialize(self) -> None:
self.set_brokerage_model(BrokerageName.BYBIT, AccountType.MARGIN)
self.crypto_future_symbol = self.add_crypto_future("BTCUSDT", Resolution.MINUTE).symbol
private Symbol _cryptoFutureSymbol;
public override void Initialize
{
SetBrokerageModel(BrokerageName.Bybit, AccountType.Margin);
_cryptoFutureSymbol = AddCryptoFuture("BTCUSDT", Resolution.Minute).Symbol;
}
Data Summary
The following table describes the dataset properties:
| Property | Value |
|---|---|
| Start Date | October 2019 |
| Asset Coverage | 631 Crypto Futures Pairs |
| Data Density | Dense |
| Resolution | Tick, Second, Minute, Hourly, & Daily |
| Timezone | UTC |
| Market Hours | Always Open |
Requesting Data
To add Bybit Crypto Future Price 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.
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)
self.btcusdt = crypto_future.symbol 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);
_symbol = cryptoFuture.Symbol;
}
}
For more information about creating Crypto Future subscriptions, see Requesting Data.
Accessing Data
To get the current Bybit Crypto Future Price data, index the Barsbars, QuoteBarsquote_bars, or Ticksticks properties 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.bars:
trade_bar = slice.bars[self.btcusdt]
self.log(f"{self.btcusdt} close at {slice.time}: {trade_bar.close}")
if self.btcusdt in slice.quote_bars:
quote_bar = slice.quote_bars[self.btcusdt]
self.log(f"{self.btcusdt} bid at {slice.time}: {quote_bar.bid.close}")
if self.btcusdt in slice.ticks:
ticks = slice.ticks[self.btcusdt]
for tick in ticks:
self.log(f"{self.btcusdt} price at {slice.time}: {tick.price}") public override void OnData(Slice slice)
{
if (slice.Bars.ContainsKey(_symbol))
{
var tradeBar = slice.Bars[_symbol];
Log($"{_symbol} price at {slice.Time}: {tradeBar.Close}");
}
if (slice.QuoteBars.ContainsKey(_symbol))
{
var quoteBar = slice.QuoteBars[_symbol];
Log($"{_symbol} bid at {slice.Time}: {quoteBar.Bid.Close}");
}
if (slice.Ticks.ContainsKey(_symbol))
{
var ticks = slice.Ticks[_symbol];
foreach (var tick in ticks)
{
Log($"{_symbol} price at {slice.Time}: {tick.Price}");
}
}
}
You can also iterate through all of the data objects in the current Slice.
def on_data(self, slice: Slice) -> None:
for symbol, trade_bar in slice.bars.items():
self.log(f"{symbol} close at {slice.time}: {trade_bar.close}")
for symbol, quote_bar in slice.quote_bars.items():
self.log(f"{symbol} bid at {slice.time}: {quote_bar.bid.close}")
for symbol, ticks in slice.ticks.items():
for tick in ticks:
self.log(f"{symbol} price at {slice.time}: {tick.price}") public override void OnData(Slice slice)
{
foreach (var kvp in slice.Bars)
{
var symbol = kvp.Key;
var tradeBar = kvp.Value;
Log($"{symbol} price at {slice.Time}: {tradeBar.Close}");
}
foreach (var kvp in slice.QuoteBars)
{
var symbol = kvp.Key;
var quoteBar = kvp.Value;
Log($"{symbol} bid at {slice.Time}: {quoteBar.Bid.Close}");
}
foreach (var kvp in slice.Ticks)
{
var symbol = kvp.Key;
var ticks = kvp.Value;
foreach (var tick in ticks)
{
Log($"{symbol} price at {slice.Time}: {tick.Price}");
}
}
}
For more information about accessing Crypto Future data, see Handling Data.
Historical Data
To get historical Bybit Crypto Future Price data, call the Historyhistory method with the Crypto Future Symbol. If there is no data in the period you request, the history result is empty.
# DataFrame history_df = self.history(self.btcusdt, 100, Resolution.DAILY) # TradeBar objects history_trade_bars = self.history[TradeBar](self.btcusdt, 100, Resolution.MINUTE) # QuoteBar objects history_quote_bars = self.history[QuoteBar](self.btcusdt, 100, Resolution.MINUTE) # Tick objects history_ticks = self.history[Tick](self.btcusdt, timedelta(seconds=10), Resolution.TICK)
// TradeBar objects var historyTradeBars = History(_symbol, 100, Resolution.Daily); // QuoteBar objects var historyQuoteBars = History<QuoteBar>(_symbol, 100, Resolution.Minute); // Tick objects var historyTicks = History<Tick>(_symbol, TimeSpan.FromSeconds(10), Resolution.Tick);
For more information about historical data, see History Requests.
Remove Subscriptions
To unsubscribe from a Crypto Future contract that you added with the AddCryptoFutureadd_crypto_future method, call the RemoveSecurityremove_security method.
self.remove_security(self.btcusdt)
RemoveSecurity(_symbol);
The RemoveSecurityremove_security method cancels your open orders for the security and liquidates your Crypto Future holdings.
Example Applications
The Bybit Crypto Future Price dataset enables you to accurately design strategies for Crypto Futures 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 BTCUSDT 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 Bybit exchange:
from AlgorithmImports import *
class BybitCryptoFutureDataAlgorithm(QCAlgorithm):
def initialize(self) -> None:
self.set_start_date(2024, 9, 1)
self.set_end_date(2024, 12, 31)
# 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)
def on_data(self, slice: Slice) -> None:
# 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) public class BybitCryptoFutureDataAlgorithm : QCAlgorithm
{
public Symbol _symbol;
public override void Initialize()
{
SetStartDate(2024, 9, 1);
SetEndDate(2024, 12, 31);
// 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);
}
public override void OnData(Slice slice)
{
// Trade only based on updated price data
if (!slice.QuoteBars.TryGetValue(_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 algorithm hold a 100% long BTCUST 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 Bybit exchange using the algorithm framework implementation:
from AlgorithmImports import *
class BybitCryptoFutureDataAlgorithm(QCAlgorithm):
def initialize(self) -> None:
self.set_start_date(2024, 9, 1)
self.set_end_date(2024, 12, 31)
# 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:
# 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)
for security in changes.removed_securities:
symbol = security.symbol
if symbol in self.symbols:
self.symbols.remove(symbol) public class BybitCryptoFutureDataAlgorithm : QCAlgorithm
{
public Symbol _symbol;
public override void Initialize()
{
SetStartDate(2024, 9, 1);
SetEndDate(2024, 12, 31);
// 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)
{
// Trade only based on updated price data
if (!slice.Bars.ContainsKey(symbol) || !slice.QuoteBars.TryGetValue(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);
}
foreach (var security in changes.RemovedSecurities)
{
_symbols.Remove(security.Symbol);
}
}
}
Data Point Attributes
The Bybit Crypto Future Price dataset provides TradeBar, QuoteBar, and Tick objects.
TradeBar Attributes
TradeBar objects have the following attributes:
QuoteBar Attributes
QuoteBar objects have the following attributes:
Tick Attributes
Tick objects have the following attributes: