mirror of
https://github.com/KhizarImran/backtestingfx.git
synced 2026-11-02 11:36:31 +00:00
49 lines
2.2 KiB
Python
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()
|