Hello everyone,
I'm learning how to use this framework to develop a perpetual futures strategy for crypto, but I'm encountering some problems along the way.
I referred to the following resources and wrote a simple strategy for backtesting
- Lean/Algorithm.Python/BasicTemplateCryptoFutureAlgorithm.py at master · QuantConnect/Lean (github.com)
- Crypto Trades - QuantConnect.com
- Requesting Data - QuantConnect.com
Orders are always invalid during backtesting:
2022-11-16 19:34:00BTCUSDT-0InvalidOrder Error: ids: [1], Insufficient buying power to complete orders (Value:[500013.4964]), Reason: Id: 1, Initial Margin: 166871.17084853999999999999998, Free Margin: 0.
This is my code:
# region imports
import datetime
from AlgorithmImports import *
# endregion
class Crypto(QCAlgorithm):
def Initialize(self):
# Locally Lean installs free sample data, to download more data please visit https://www.quantconnect.com/docs/v2/lean-cli/datasets/downloading-data
self.SetStartDate(2022, 11, 17) # Set Start Date
self.SetEndDate(2023, 11, 17) # Set End Date
self.SetTimeZone(TimeZones.Utc)
self.SetCash(1000000) # Set Strategy Cash
self.Settings.FreePortfolioValue = 100000
self.SetBrokerageModel(BrokerageName.BinanceFutures, AccountType.Margin)
self.btcUsd = self.AddCryptoFuture("BTCUSDT", leverage=3)
# define our daily macd(12,26) with a 9 day signal
self.__macd = self.MACD(self.btcUsd.Symbol, 12, 26, 9, MovingAverageType.Exponential, Resolution.Minute)
self.PlotIndicator("MACD", True, self.__macd, self.__macd.Signal)
self.PlotIndicator(self.btcUsd.Symbol, self.__macd.Fast, self.__macd.Slow)
def OnData(self, data: Slice):
"""OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
Arguments:
data: Slice object keyed by symbol containing the stock data
"""
if not self.__macd.IsReady: return
btcUsdHoldings = self.btcUsd.Holdings
# if our macd is greater than our signal, then let's go long
if self.__macd.Current.Value > self.__macd.Signal.Current.Value:
if (self.Transactions.OrdersCount > 0 and btcUsdHoldings.IsShort):
self.liquidate_crypto(self.btcUsd.Symbol)
self.set_crypto_holdings(self.btcUsd.Symbol, 0.5)
elif (self.Transactions.OrdersCount == 0):
self.set_crypto_holdings(self.btcUsd.Symbol, 0.5)
# of our macd is less than our signal, then let's go short
else:
if (self.Transactions.OrdersCount > 0 and btcUsdHoldings.IsLong):
self.liquidate_crypto(self.btcUsd.Symbol)
self.set_crypto_holdings(self.btcUsd.Symbol, -0.5)
elif (self.Transactions.OrdersCount == 0):
self.set_crypto_holdings(self.btcUsd.Symbol, -0.5)
def set_crypto_holdings(self, symbol, percentage):
crypto = self.Securities[symbol]
base_currency = crypto.BaseCurrency
# Calculate the target quantity in the base currency
target_quantity = percentage * (self.Portfolio.TotalPortfolioValue - self.Settings.FreePortfolioValue) / base_currency.ConversionRate
quantity = target_quantity - base_currency.Amount
# Round down to observe the lot size
lot_size = crypto.SymbolProperties.LotSize
quantity = round(quantity / lot_size) * lot_size
if self.is_valid_order_size(crypto, quantity):
self.MarketOrder(symbol, quantity)
# Brokerages have different order size rules
# Binance considers the minimum volume (price x quantity):
def is_valid_order_size(self, crypto, quantity):
min_order_size = crypto.SymbolProperties.MinimumOrderSize
if min_order_size is None:
min_order_size = 0
return abs(crypto.Price * quantity) > min_order_size
def liquidate_crypto(self, symbol):
crypto = self.Securities[symbol]
base_currency = crypto.BaseCurrency
# Avoid negative amount after liquidate
quantity = min(crypto.Holdings.Quantity, base_currency.Amount)
# Round down to observe the lot size
lot_size = crypto.SymbolProperties.LotSize;
quantity = (round(quantity / lot_size) - 1) * lot_size
if self.is_valid_order_size(crypto, quantity):
self.MarketOrder(symbol, -quantity)
Thanks and kind regards, Kenneth
Ashutosh
Hi Kenneth Tang
Captivated by the intricacies of the crypto code, I decided to make refinements to the provided script, streamlining the necessity of monitoring the model's Buying Power.
I removed the check of buying power:
You can reference our document on Buying Power models.
The strategy was depleting the portfolio value rapidly at a minute resolution, prompting me to adjust the resolution to an hourly and daily timeframe. It would be beneficial to review the overall code logic for managing portfolio values and position-taking strategies.
I'd appreciate your feedback and confirmation on whether you were able to grasp the logic in your code.
Backtest Attached:
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
Kenneth Tang
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
To unlock posting to the community forums please complete at least 30% of Boot Camp.
You can continue your Boot Camp training progress from the terminal. We hope to see you in the community soon!