You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Quantstrat自定义订单规模函数问题:全仓比特币与B&H策略对比

Hey there! Let's dig into this quantstrat order sizing problem you're dealing with—getting 100% of your available equity into Bitcoin to match a buy-and-hold (B&H) strategy is a super common goal, so let's figure out why your order quantities aren't calculating right and fix it step by step.

1. First, Diagnose the Core Issue

Your hunch about price matching is probably on point. Here are the two most likely culprits:

  • Future data bias: If you're using the current bar's Cl(mktdata) (closing price) to calculate order size, quantstrat might be blocking that (since you can't know the close price at the start of the bar) or using a lagged value, throwing off your quantity.
  • Misaligned equity calculation: You might be pulling total account equity (including open positions) instead of available equity that's actually free to deploy.
2. Build a Custom Full-Allocation Order Sizing Function

Let's write a function that strictly uses available equity and a tradeable price (like the bar's open price, which avoids future data issues) to calculate how much Bitcoin to buy. We'll also add handling for minimum trade units (common in crypto):

full_btc_allocation <- function(data, timestamp, orderqty, ordertype, orderside, portfolio, account, symbol, ruletype, ...) {
  # Grab available account equity at the current timestamp
  available_eq <- getEndEq(account, timestamp)
  
  # Use the bar's open price (no future data here!)
  current_price <- as.numeric(Op(mktdata[timestamp, ]))
  
  # Calculate max BTC we can buy, rounded down to 0.0001 (common minimum unit)
  max_qty <- floor(available_eq / current_price * 10000) / 10000
  
  # Return positive quantity for long positions (adjust for short if needed)
  if (orderside == "long") {
    return(max_qty)
  } else {
    return(-max_qty)
  }
}

Then bind this function to your strategy so quantstrat uses it for long orders:

# Replace "your_strategy_name" with your actual strategy object
addOrderSize(strategy = your_strategy_name, 
             type = "long", 
             fun = full_btc_allocation)
3. Fix Price Matching & Alignment

To confirm you're not hitting future data issues:

Always use Op(mktdata) (open price) or Hi(mktdata)/Lo(mktdata) for order sizing in backtests. Using Cl(mktdata) assumes you can trade at the close price before the bar ends, which is unrealistic and will lead to skewed results.

Also, double-check your data timestamps:

  • Make sure your Bitcoin bar data (daily, hourly, etc.) has timestamps that align with quantstrat's account equity calculations. For daily bars, this means using timestamps at the start of the trading period (not the close) to ensure equity and price are synced.
4. Debug to Verify the Order Book

Add debug prints to your order sizing function to spot discrepancies between expected and actual quantities:

full_btc_allocation <- function(data, timestamp, orderqty, ordertype, orderside, portfolio, account, symbol, ruletype, ...) {
  available_eq <- getEndEq(account, timestamp)
  current_price <- as.numeric(Op(mktdata[timestamp, ]))
  max_qty <- floor(available_eq / current_price * 10000) / 10000
  
  # Print debug info to cross-check
  cat(paste0("Timestamp: ", timestamp, 
             " | Available Equity: $", round(available_eq, 2), 
             " | BTC Open Price: $", round(current_price, 2), 
             " | Order Qty: ", round(max_qty, 4), "\n"))
  
  if (orderside == "long") {
    return(max_qty)
  } else {
    return(-max_qty)
  }
}

Run your backtest and compare the printed values to manual calculations (available equity ÷ BTC open price). If they don't match, check:

  • Are fees being deducted? Your addFee settings will reduce available equity—make sure they're configured correctly.
  • Do you have existing open positions? If your strategy starts with a position, available equity will be reduced by that position's value.
5. Align with Buy-and-Hold

To make sure your strategy matches B&H exactly:

  • Add a rule to only place one buy order on the first bar (no rebalancing or additional trades).
  • Compare your strategy's final equity to a manual B&H calculation: (initial_equity / first_bar_open_price) * last_bar_close_price. Any small difference should come from fees or slippage (which you can adjust in your strategy settings).

内容的提问来源于stack exchange,提问作者DerWanderer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:19:56