Closed 0xdaduck closed 2 weeks ago
StateValues
's balance doesn't include the value of open positions. Your equity is computed as balance + position * price - fee
.
Thanks for your reply. I think your code has given the answer, but I can't find how to call it in the backtest.
impl AssetType for LinearAsset {
fn amount(&self, exec_price: f64, qty: f64) -> f64 {
self.contract_size * exec_price * qty
}
fn equity(&self, price: f64, balance: f64, position: f64, fee: f64) -> f64 {
balance + self.contract_size * position * price - fee
}
}
For now, you'll need to compute it manually due to compatibility with the live bot. You can access state values using hbt.state_values(asset_no)
.
I need to check the status of the order when calculating the available balance. However, checking the logs shows that the status of the new order is still Status::New after 18 minutes of submission. I useExchangeKind::PartialFillExchange and IOC to submit orders.
The order type and time-in-force were not properly handled. This has been fixed at 126ccee3382a5132a650a9cd3c9e1a76ff86108d.
Thank you for your selflessness. Now the IOC order execution strategy is correct. I still have some doubts. As shown in the two pictures below, first, the local timestamp in the order has become microseconds. Is this to match the exchange timestamp? Second, when observing the variables during debugging, it is found that the timestamp in the order is less than the current timestamp, and the market has changed and the transaction cannot be completed. Is this caused by order delay? It is difficult to effectively judge the current effective balance in the backtest process dominated by hbt.elapse(). I really hope that the author can consider adding the functions of setting the initial balance, available balance, frozen balance, and total balance. pic 1
pic 2
In your screenshot, the timestamp is in nanoseconds. I'm not sure what you meant by your question.
In the backtesting logic, there is no manipulation of the timestamp unit. It's crucial to ensure that your data (such as feed and order latency) and your code maintain a consistent time unit.
The local_timestamp in Order represents the time when the order is requested.
Regarding setting the initial balance, I will consider it, but I believe it's something that can be easily managed by the user's code. Adding this feature would complicate the builder code, and it would require setting the balance for each asset individually.
I'm not sure where you're having difficulty in computing your total balance, which is your equity value, correct? The following snippet may help you.
let depth = hbt.depth(asset_no);
let price = (depth.best_bid() + depth_best_ask()) / 2.0;
let state_values = hbt.state_values(asset_no);
let equity = state_values.balance + state_values.position * price - state_values.fee;
However, if you need to calculate something like available margin to open more positions, that depends on the exchange's margin calculation and must be handled on your end.
When a strategy opens a short position, the short position value is added directly to the balance. How to distinguish between available balance and frozen balance in backtesting?