bug fix
This commit is contained in:
+44
-47
@@ -442,11 +442,13 @@ class BacktestResult:
|
||||
self,
|
||||
pair_nm: str,
|
||||
symbol: str,
|
||||
side: str,
|
||||
action: str,
|
||||
price: Any,
|
||||
disequilibrium: Optional[float] = None,
|
||||
scaled_disequilibrium: Optional[float] = None,
|
||||
timestamp: Optional[datetime] = None,
|
||||
status: Optional[str] = None,
|
||||
) -> None:
|
||||
"""Add a trade to the results tracking."""
|
||||
pair_nm = str(pair_nm)
|
||||
@@ -456,7 +458,15 @@ class BacktestResult:
|
||||
if symbol not in self.trades[pair_nm]:
|
||||
self.trades[pair_nm][symbol] = []
|
||||
self.trades[pair_nm][symbol].append(
|
||||
(action, price, disequilibrium, scaled_disequilibrium, timestamp)
|
||||
{"symbol":symbol,
|
||||
"side":side,
|
||||
"action":action,
|
||||
"price":price,
|
||||
"disequilibrium":disequilibrium,
|
||||
"scaled_disequilibrium":scaled_disequilibrium,
|
||||
"timestamp":timestamp,
|
||||
"status":status
|
||||
}
|
||||
)
|
||||
|
||||
def add_outstanding_position(self, position: Dict[str, Any]) -> None:
|
||||
@@ -493,6 +503,7 @@ class BacktestResult:
|
||||
print(result)
|
||||
|
||||
for row in result.itertuples():
|
||||
side = row.side
|
||||
action = row.action
|
||||
symbol = row.symbol
|
||||
price = row.price
|
||||
@@ -502,15 +513,17 @@ class BacktestResult:
|
||||
timestamp = getattr(row, "time")
|
||||
else:
|
||||
timestamp = convert_timestamp(row.Index)
|
||||
|
||||
status = row.status
|
||||
self.add_trade(
|
||||
pair_nm=str(row.pair),
|
||||
action=str(action),
|
||||
symbol=str(symbol),
|
||||
side=str(side),
|
||||
action=str(action),
|
||||
price=float(str(price)),
|
||||
disequilibrium=disequilibrium,
|
||||
scaled_disequilibrium=scaled_disequilibrium,
|
||||
timestamp=timestamp,
|
||||
status=str(status) if status is not None else "?",
|
||||
)
|
||||
|
||||
def print_single_day_results(self) -> None:
|
||||
@@ -553,42 +566,22 @@ class BacktestResult:
|
||||
for symbol, trades in symbols.items():
|
||||
if len(trades) == 0:
|
||||
continue
|
||||
|
||||
symbol_return = 0
|
||||
symbol_trades = []
|
||||
|
||||
# Process all trades sequentially for this symbol
|
||||
for i, trade in enumerate(trades):
|
||||
# Handle both old and new tuple formats
|
||||
if len(trade) == 2: # Old format: (action, price)
|
||||
action, price = trade
|
||||
disequilibrium = None
|
||||
scaled_disequilibrium = None
|
||||
timestamp = None
|
||||
else: # New format: (action, price, disequilibrium, scaled_disequilibrium, timestamp)
|
||||
action, price = trade[:2]
|
||||
disequilibrium = trade[2] if len(trade) > 2 else None
|
||||
scaled_disequilibrium = trade[3] if len(trade) > 3 else None
|
||||
timestamp = trade[4] if len(trade) > 4 else None
|
||||
|
||||
symbol_trades.append((action, price, disequilibrium, scaled_disequilibrium, timestamp))
|
||||
|
||||
symbol_trades = [trade for trade in trades if trade["symbol"] == symbol]
|
||||
|
||||
# Calculate returns for all trade combinations
|
||||
for i in range(len(symbol_trades) - 1):
|
||||
trade1 = symbol_trades[i]
|
||||
trade2 = symbol_trades[i + 1]
|
||||
|
||||
action1, price1, diseq1, scaled_diseq1, ts1 = trade1
|
||||
action2, price2, diseq2, scaled_diseq2, ts2 = trade2
|
||||
trade1 = trades[i]
|
||||
trade2 = trades[i + 1]
|
||||
|
||||
# Calculate return based on action combination
|
||||
trade_return = 0
|
||||
if action1 == "BUY" and action2 == "SELL":
|
||||
if trade1["side"] == "BUY" and trade2["side"] == "SELL":
|
||||
# Long position
|
||||
trade_return = (price2 - price1) / price1 * 100
|
||||
elif action1 == "SELL" and action2 == "BUY":
|
||||
trade_return = (trade2["price"] - trade1["price"]) / trade1["price"] * 100
|
||||
elif trade1["side"] == "SELL" and trade2["side"] == "BUY":
|
||||
# Short position
|
||||
trade_return = (price1 - price2) / price1 * 100
|
||||
trade_return = (trade1["price"] - trade2["price"]) / trade1["price"] * 100
|
||||
|
||||
symbol_return += trade_return
|
||||
|
||||
@@ -596,13 +589,13 @@ class BacktestResult:
|
||||
pair_trades.append(
|
||||
(
|
||||
symbol,
|
||||
action1,
|
||||
price1,
|
||||
action2,
|
||||
price2,
|
||||
trade1["side"],
|
||||
trade1["price"],
|
||||
trade2["side"],
|
||||
trade2["price"],
|
||||
trade_return,
|
||||
scaled_diseq1,
|
||||
scaled_diseq2,
|
||||
trade1["scaled_disequilibrium"],
|
||||
trade2["scaled_disequilibrium"],
|
||||
i + 1, # Trade sequence number
|
||||
)
|
||||
)
|
||||
@@ -614,24 +607,28 @@ class BacktestResult:
|
||||
print(f" {pair}:")
|
||||
for (
|
||||
symbol,
|
||||
action1,
|
||||
price1,
|
||||
action2,
|
||||
price2,
|
||||
trade1["side"],
|
||||
trade1["price"],
|
||||
trade2["side"],
|
||||
trade2["price"],
|
||||
trade_return,
|
||||
scaled_diseq1,
|
||||
scaled_diseq2,
|
||||
trade1["scaled_disequilibrium"],
|
||||
trade2["scaled_disequilibrium"],
|
||||
trade_num,
|
||||
) in pair_trades:
|
||||
disequil_info = ""
|
||||
if (
|
||||
scaled_diseq1 is not None
|
||||
and scaled_diseq2 is not None
|
||||
trade1["scaled_disequilibrium"] is not None
|
||||
and trade2["scaled_disequilibrium"] is not None
|
||||
):
|
||||
disequil_info = f" | Open Dis-eq: {scaled_diseq1:.2f}, Close Dis-eq: {scaled_diseq2:.2f}"
|
||||
disequil_info = f" | Open Dis-eq: {trade1["scaled_disequilibrium"]:.2f},"
|
||||
f" Close Dis-eq: {trade2["scaled_disequilibrium"]:.2f}"
|
||||
|
||||
print(
|
||||
f" {symbol} (Trade #{trade_num}): {action1} @ ${price1:.2f}, {action2} @ ${price2:.2f}, Return: {trade_return:.2f}%{disequil_info}"
|
||||
f" {symbol} (Trade #{trade_num}):"
|
||||
f" {trade1["side"]} @ ${trade1["price"]:.2f},"
|
||||
f" {trade2["side"]} @ ${trade2["price"]:.2f},"
|
||||
f" Return: {trade_return:.2f}%{disequil_info}"
|
||||
)
|
||||
print(f" Pair Total Return: {pair_return:.2f}%")
|
||||
day_return += pair_return
|
||||
|
||||
Reference in New Issue
Block a user