Files
backtestingfx/tests/test_intrabar_execution.py
T

49 lines
2.2 KiB
Python

import unittest
import pandas as pd
from backtestingfx import Backtest, Strategy
class IntrabarExecutionTest(unittest.TestCase):
def test_new_entries_are_checked_from_the_following_bar(self):
for is_long in (True, False):
for count in (1, 2):
with self.subTest(is_long=is_long, count=count):
seen = []
class EnterOnce(Strategy):
def next(self):
seen.append(len(self.positions))
if self.index == 0:
if is_long:
self.buy(1.0, stop_loss=1.09, take_profit=1.11)
else:
self.sell(1.0, stop_loss=1.11, take_profit=1.09)
index = pd.date_range("2026-01-01", periods=count, freq="h", tz="UTC")
data = pd.DataFrame(
{"open": [1.1] * count, "high": [1.12] * count,
"low": [1.08] * count, "close": [1.1] * count},
index=index,
)
stats = Backtest(data, EnterOnce, commission=0, spread=0).run()
self.assertEqual(stats.num_trades, 1)
trade = stats.trades[0]
self.assertEqual(trade.entry_timestamp, int(index[0].timestamp()))
self.assertEqual(trade.exit_timestamp, int(index[-1].timestamp()))
if count == 1:
# Final liquidation at close: the entry bar's range is not replayed.
self.assertAlmostEqual(trade.exit_price, 1.1)
self.assertAlmostEqual(trade.pnl, 0.0)
self.assertEqual(seen, [0])
else:
# Both levels touched on the next bar: stop is processed before next().
self.assertAlmostEqual(trade.exit_price, 1.09 if is_long else 1.11)
self.assertAlmostEqual(trade.pnl, -1000.0)
self.assertEqual(seen, [0, 0])
if __name__ == "__main__":
unittest.main()