mirror of
https://github.com/Ichinga-Samuel/aiomql.git
synced 2026-08-13 11:58:04 +00:00
v4
This commit is contained in:
@@ -14,40 +14,20 @@ class TestBackTestEngine:
|
||||
def setup_class(cls):
|
||||
cls.start = datetime(2024, 2, 1)
|
||||
cls.end = datetime(2024, 2, 7)
|
||||
cls.g_data = GetData(
|
||||
start=cls.start,
|
||||
end=cls.end,
|
||||
symbols=["BTCUSD", "SOLUSD"],
|
||||
timeframes=[TimeFrame.H1, TimeFrame.H2],
|
||||
name="test_engine",
|
||||
)
|
||||
cls.bte = BackTestEngine(
|
||||
start=cls.start, end=cls.end, assign_to_config=True, preload=False
|
||||
)
|
||||
cls.g_data = GetData(start=cls.start, end=cls.end, symbols=["BTCUSD", "SOLUSD"], timeframes=[TimeFrame.H1, TimeFrame.H2], name="test_engine")
|
||||
cls.bte = BackTestEngine(start=cls.start, end=cls.end, assign_to_config=True, preload=False)
|
||||
|
||||
@pytest.fixture(scope="class")
|
||||
async def bte2(self):
|
||||
await self.g_data.get_data()
|
||||
bte2 = BackTestEngine(
|
||||
start=self.start,
|
||||
end=self.end,
|
||||
data=self.g_data.data,
|
||||
use_terminal=False,
|
||||
preload=False,
|
||||
)
|
||||
bte2 = BackTestEngine(start=self.start, end=self.end, data=self.g_data.data, use_terminal=False, preload=False)
|
||||
await bte2.setup_account(balance=100)
|
||||
return bte2
|
||||
|
||||
@pytest.fixture(scope="class")
|
||||
async def sell_order(self):
|
||||
sym = await self.bte.get_symbol_info(symbol="BTCUSD")
|
||||
request = {
|
||||
"type": OrderType.SELL,
|
||||
"symbol": "BTCUSD",
|
||||
"volume": sym.volume_min,
|
||||
"price": sym.bid,
|
||||
"action": TradeAction.DEAL,
|
||||
}
|
||||
request = {"type": OrderType.SELL, "symbol": "BTCUSD", "volume": sym.volume_min, "price": sym.bid, "action": TradeAction.DEAL}
|
||||
return request
|
||||
|
||||
@pytest.fixture(scope="class")
|
||||
@@ -67,16 +47,11 @@ class TestBackTestEngine:
|
||||
}
|
||||
return request
|
||||
|
||||
def modify_stops(self, order):
|
||||
...
|
||||
def modify_stops(self, order): ...
|
||||
|
||||
def test_span_and_range(self):
|
||||
assert self.bte.range == range(
|
||||
0, int((self.end - self.start).total_seconds()), self.bte.speed
|
||||
)
|
||||
assert self.bte.span == range(
|
||||
int(self.start.timestamp()), int(self.end.timestamp()), self.bte.speed
|
||||
)
|
||||
assert self.bte.range == range(0, int((self.end - self.start).total_seconds()), self.bte.speed)
|
||||
assert self.bte.span == range(int(self.start.timestamp()), int(self.end.timestamp()), self.bte.speed)
|
||||
assert len(self.bte.span) == len(self.bte.range)
|
||||
|
||||
def test_cursor(self):
|
||||
@@ -158,16 +133,12 @@ class TestBackTestEngine:
|
||||
|
||||
async def test_get_rates_from(self):
|
||||
start = datetime(2024, 2, 3, 12, 43, tzinfo=UTC)
|
||||
rates = await self.bte.get_rates_from(
|
||||
symbol="BTCUSD", timeframe=TimeFrame.H1, date_from=start, count=24
|
||||
)
|
||||
rates = await self.bte.get_rates_from(symbol="BTCUSD", timeframe=TimeFrame.H1, date_from=start, count=24)
|
||||
assert len(rates) == 24
|
||||
|
||||
async def test_get_rates_from_2(self, bte2):
|
||||
start = datetime(2024, 2, 3, 12, 12, tzinfo=UTC)
|
||||
rates = await bte2.get_rates_from(
|
||||
symbol="BTCUSD", timeframe=TimeFrame.H1, date_from=start, count=24
|
||||
)
|
||||
rates = await bte2.get_rates_from(symbol="BTCUSD", timeframe=TimeFrame.H1, date_from=start, count=24)
|
||||
assert len(rates) == 24
|
||||
|
||||
async def test_get_rates_from_pos(self):
|
||||
@@ -175,51 +146,37 @@ class TestBackTestEngine:
|
||||
self.bte.go_to(time=now)
|
||||
tf = TimeFrame.H2
|
||||
start_pos = 2
|
||||
rates = await self.bte.get_rates_from_pos(
|
||||
symbol="BTCUSD", timeframe=tf, start_pos=start_pos, count=24
|
||||
)
|
||||
rates = await self.bte.get_rates_from_pos(symbol="BTCUSD", timeframe=tf, start_pos=start_pos, count=24)
|
||||
assert len(rates) == 24
|
||||
assert int(rates[-1][0]) == round_down(
|
||||
int(now.replace(hour=now.hour - start_pos).timestamp()), tf.seconds
|
||||
)
|
||||
assert int(rates[-1][0]) == round_down(int(now.replace(hour=now.hour - start_pos).timestamp()), tf.seconds)
|
||||
|
||||
async def test_get_rates_from_pos2(self, bte2):
|
||||
now = datetime(2024, 2, 4, 12, 15, tzinfo=UTC)
|
||||
bte2.go_to(time=now)
|
||||
tf = TimeFrame.H1
|
||||
start_pos = 2
|
||||
rates = await bte2.get_rates_from_pos(
|
||||
symbol="BTCUSD", timeframe=tf, start_pos=start_pos, count=24
|
||||
)
|
||||
assert int(rates[-1][0]) == round_down(
|
||||
int(now.replace(hour=10).timestamp()), tf.seconds
|
||||
)
|
||||
rates = await bte2.get_rates_from_pos(symbol="BTCUSD", timeframe=tf, start_pos=start_pos, count=24)
|
||||
assert int(rates[-1][0]) == round_down(int(now.replace(hour=10).timestamp()), tf.seconds)
|
||||
# assert int(rates[-1][0]) == round_up(int(now.timestamp()), tf.seconds) - start_pos * tf.seconds
|
||||
assert len(rates) == 24
|
||||
|
||||
async def test_get_rates_range(self):
|
||||
start = datetime(2024, 2, 3, 12, tzinfo=UTC)
|
||||
end = datetime(2024, 2, 4, 18, tzinfo=UTC)
|
||||
rates = await self.bte.get_rates_range(
|
||||
symbol="BTCUSD", timeframe=TimeFrame.H1, date_from=start, date_to=end
|
||||
)
|
||||
rates = await self.bte.get_rates_range(symbol="BTCUSD", timeframe=TimeFrame.H1, date_from=start, date_to=end)
|
||||
assert len(rates) == 31
|
||||
assert int(rates[-1][0]) == int(end.timestamp())
|
||||
|
||||
async def test_get_rates_range2(self, bte2):
|
||||
start = datetime(2024, 2, 3, 12, tzinfo=UTC)
|
||||
end = datetime(2024, 2, 4, 18, tzinfo=UTC)
|
||||
rates = await bte2.get_rates_range(
|
||||
symbol="BTCUSD", timeframe=TimeFrame.H1, date_from=start, date_to=end
|
||||
)
|
||||
rates = await bte2.get_rates_range(symbol="BTCUSD", timeframe=TimeFrame.H1, date_from=start, date_to=end)
|
||||
assert len(rates) == 31
|
||||
assert int(rates[-1][0]) == int(end.timestamp())
|
||||
|
||||
async def test_get_ticks_from(self):
|
||||
start = datetime(2024, 2, 3, 12, tzinfo=UTC)
|
||||
ticks = await self.bte.get_ticks_from(
|
||||
symbol="BTCUSD", date_from=start, count=24
|
||||
)
|
||||
ticks = await self.bte.get_ticks_from(symbol="BTCUSD", date_from=start, count=24)
|
||||
assert len(ticks) == 24
|
||||
|
||||
async def test_get_ticks_from2(self, bte2):
|
||||
@@ -230,23 +187,15 @@ class TestBackTestEngine:
|
||||
async def test_get_ticks_range(self):
|
||||
start = datetime(2024, 2, 3, 12, tzinfo=UTC)
|
||||
end = datetime(2024, 2, 3, 15, tzinfo=UTC)
|
||||
ticks = await self.bte.get_ticks_range(
|
||||
symbol="BTCUSD", date_from=start, date_to=end
|
||||
)
|
||||
approx_total = (
|
||||
end - start
|
||||
).total_seconds() // 2 # assuming 2 ticks per second at least
|
||||
ticks = await self.bte.get_ticks_range(symbol="BTCUSD", date_from=start, date_to=end)
|
||||
approx_total = (end - start).total_seconds() // 2 # assuming 2 ticks per second at least
|
||||
assert len(ticks) >= approx_total
|
||||
|
||||
async def test_get_ticks_range2(self, bte2):
|
||||
start = datetime(2024, 2, 3, 12, tzinfo=UTC)
|
||||
end = datetime(2024, 2, 3, 15, tzinfo=UTC)
|
||||
ticks = await bte2.get_ticks_range(
|
||||
symbol="BTCUSD", date_from=start, date_to=end
|
||||
)
|
||||
approx_total = (
|
||||
end - start
|
||||
).total_seconds() // 2 # assuming 2 ticks per second at least
|
||||
ticks = await bte2.get_ticks_range(symbol="BTCUSD", date_from=start, date_to=end)
|
||||
approx_total = (end - start).total_seconds() // 2 # assuming 2 ticks per second at least
|
||||
assert len(ticks) >= approx_total
|
||||
|
||||
async def test_price_tick(self, bte2):
|
||||
@@ -287,22 +236,14 @@ class TestBackTestEngine:
|
||||
tp = sym_info.ask + dsl
|
||||
|
||||
profit = await self.bte.order_calc_profit(
|
||||
action=OrderType.BUY,
|
||||
symbol=sym,
|
||||
volume=sym_info.volume_min,
|
||||
price_open=sym_info.ask,
|
||||
price_close=tp,
|
||||
action=OrderType.BUY, symbol=sym, volume=sym_info.volume_min, price_open=sym_info.ask, price_close=tp
|
||||
)
|
||||
assert profit > 0
|
||||
sym_info2 = await bte2.get_symbol_info(symbol=sym)
|
||||
dsl2 = (sym_info2.trade_stops_level + sym_info2.spread) * 2 * sym_info2.point
|
||||
tp2 = sym_info2.ask + dsl2
|
||||
profit2 = await bte2.order_calc_profit(
|
||||
action=OrderType.BUY,
|
||||
symbol=sym,
|
||||
volume=sym_info2.volume_min,
|
||||
price_open=sym_info2.ask,
|
||||
price_close=tp2,
|
||||
action=OrderType.BUY, symbol=sym, volume=sym_info2.volume_min, price_open=sym_info2.ask, price_close=tp2
|
||||
)
|
||||
assert ceil(profit) == ceil(profit2)
|
||||
|
||||
@@ -314,20 +255,10 @@ class TestBackTestEngine:
|
||||
bte2.go_to(time=moment)
|
||||
sym = "BTCUSD"
|
||||
sym_info = await self.bte.get_symbol_info(symbol=sym)
|
||||
margin = await self.bte.order_calc_margin(
|
||||
action=OrderType.SELL,
|
||||
symbol=sym,
|
||||
volume=sym_info.volume_min,
|
||||
price=sym_info.bid,
|
||||
)
|
||||
margin = await self.bte.order_calc_margin(action=OrderType.SELL, symbol=sym, volume=sym_info.volume_min, price=sym_info.bid)
|
||||
assert margin > 0
|
||||
sym_info2 = await self.bte.get_symbol_info(symbol=sym)
|
||||
margin2 = await bte2.order_calc_margin(
|
||||
action=OrderType.SELL,
|
||||
symbol=sym,
|
||||
volume=sym_info2.volume_min,
|
||||
price=sym_info2.bid,
|
||||
)
|
||||
margin2 = await bte2.order_calc_margin(action=OrderType.SELL, symbol=sym, volume=sym_info2.volume_min, price=sym_info2.bid)
|
||||
assert margin2 > 0
|
||||
|
||||
async def test_order_check(self, buy_order, sell_order):
|
||||
|
||||
@@ -11,12 +11,8 @@ from aiomql.core.constants import TimeFrame
|
||||
class TestCandle:
|
||||
@classmethod
|
||||
def setup_class(cls):
|
||||
cls.bullish_candle = Candle(
|
||||
open=1.3421, high=1.3462, low=1.3405, close=1.3452, time=0, Index=0
|
||||
)
|
||||
cls.bearish_candle = Candle(
|
||||
open=1.3452, high=1.3405, low=1.3462, close=1.3421, time=1, Index=1
|
||||
)
|
||||
cls.bullish_candle = Candle(open=1.3421, high=1.3462, low=1.3405, close=1.3452, time=0, Index=0)
|
||||
cls.bearish_candle = Candle(open=1.3452, high=1.3405, low=1.3462, close=1.3421, time=1, Index=1)
|
||||
|
||||
def test_repr(self):
|
||||
repr_str = repr(self.bearish_candle)
|
||||
|
||||
@@ -14,13 +14,7 @@ class TestGetData:
|
||||
cls.end = datetime(2024, 2, 2, tzinfo=UTC)
|
||||
cls.symbols = ["BTCUSD", "ETHUSD"]
|
||||
cls.timeframes = [TimeFrame.H1, TimeFrame.H2]
|
||||
cls.g_data = GetData(
|
||||
start=cls.start,
|
||||
end=cls.end,
|
||||
symbols=cls.symbols,
|
||||
timeframes=cls.timeframes,
|
||||
name="test_data",
|
||||
)
|
||||
cls.g_data = GetData(start=cls.start, end=cls.end, symbols=cls.symbols, timeframes=cls.timeframes, name="test_data")
|
||||
|
||||
@pytest.fixture(scope="class", autouse=True)
|
||||
async def get_data(self):
|
||||
@@ -34,9 +28,7 @@ class TestGetData:
|
||||
assert self.g_data.timeframes == set(self.timeframes)
|
||||
assert self.g_data.name == "test_data"
|
||||
assert self.g_data.range == range(int((self.end - self.start).total_seconds()))
|
||||
assert self.g_data.span == range(
|
||||
int(self.start.timestamp()), int(self.end.timestamp())
|
||||
)
|
||||
assert self.g_data.span == range(int(self.start.timestamp()), int(self.end.timestamp()))
|
||||
|
||||
async def test_get_data(self):
|
||||
assert self.g_data.data.fully_loaded is True
|
||||
|
||||
@@ -111,19 +111,13 @@ class TestMetaTrader:
|
||||
assert res.shape[0] == 10
|
||||
|
||||
async def test_copy_ticks_from(self):
|
||||
res = await self.mt.copy_ticks_from(
|
||||
self.symbol, self.start, 10, self.mt.COPY_TICKS_ALL
|
||||
)
|
||||
res = await self.mt.copy_ticks_from(self.symbol, self.start, 10, self.mt.COPY_TICKS_ALL)
|
||||
assert res is not None
|
||||
assert res.shape[0] == 10
|
||||
|
||||
async def test_copy_ticks_range(self):
|
||||
res = await self.mt.copy_ticks_range(
|
||||
self.symbol, self.start, self.end, self.mt.COPY_TICKS_ALL
|
||||
)
|
||||
res2 = self.mt5.copy_ticks_range(
|
||||
self.symbol, self.start, self.end, self.mt5.COPY_TICKS_ALL
|
||||
)
|
||||
res = await self.mt.copy_ticks_range(self.symbol, self.start, self.end, self.mt.COPY_TICKS_ALL)
|
||||
res2 = self.mt5.copy_ticks_range(self.symbol, self.start, self.end, self.mt5.COPY_TICKS_ALL)
|
||||
assert res is not None
|
||||
assert res.shape[0] == res2.shape[0]
|
||||
|
||||
@@ -149,9 +143,7 @@ class TestMetaTrader:
|
||||
price_open = buy_order["price"]
|
||||
price_close = buy_order["tp"]
|
||||
type_ = buy_order["type"]
|
||||
res = await self.mt.order_calc_profit(
|
||||
type_, self.symbol, volume, price_open, price_close
|
||||
)
|
||||
res = await self.mt.order_calc_profit(type_, self.symbol, volume, price_open, price_close)
|
||||
assert isinstance(res, float)
|
||||
|
||||
async def test_order_check(self, buy_order):
|
||||
|
||||
@@ -36,9 +36,7 @@ class TestResult:
|
||||
|
||||
async def test_json(self, order_results):
|
||||
res1, res2 = order_results
|
||||
await asyncio.gather(
|
||||
res1.save(trade_record_mode="json"), res2.save(trade_record_mode="json")
|
||||
)
|
||||
await asyncio.gather(res1.save(trade_record_mode="json"), res2.save(trade_record_mode="json"))
|
||||
assert res1.config.records_dir.exists()
|
||||
record = res1.config.records_dir / f"{res1.name}.json"
|
||||
assert record.exists()
|
||||
|
||||
@@ -15,9 +15,7 @@ class TestSessions:
|
||||
def make_session(self):
|
||||
end = time(hour=16, minute=59, second=59, microsecond=999_999, tzinfo=UTC)
|
||||
london = Session(start=8, end=end, name="London", on_end="close_all")
|
||||
start, end = time(hour=0, tzinfo=UTC), time(
|
||||
hour=23, minute=59, second=59, tzinfo=UTC
|
||||
)
|
||||
start, end = time(hour=0, tzinfo=UTC), time(hour=23, minute=59, second=59, tzinfo=UTC)
|
||||
all_day = Session(start=start, end=end, name="AllDay", on_end="close_all")
|
||||
end = time(hour=6, minute=59, second=59, microsecond=999_999, tzinfo=UTC)
|
||||
over_night = Session(start=18, end=end, name="OverNight", on_end="close_all")
|
||||
|
||||
@@ -35,19 +35,13 @@ class TestSymbol:
|
||||
async def test_rates(self, btc):
|
||||
start = datetime(year=2023, month=10, day=5)
|
||||
end = start + timedelta(hours=9)
|
||||
rates_from = await btc.copy_rates_from(
|
||||
timeframe=btc.mt5.TIMEFRAME_H1, date_from=start, count=10
|
||||
)
|
||||
rates_from = await btc.copy_rates_from(timeframe=btc.mt5.TIMEFRAME_H1, date_from=start, count=10)
|
||||
assert isinstance(rates_from, Candles)
|
||||
assert len(rates_from) == 10
|
||||
rates_from_pos = await btc.copy_rates_from_pos(
|
||||
timeframe=btc.mt5.TIMEFRAME_H1, count=10, start_position=0
|
||||
)
|
||||
rates_from_pos = await btc.copy_rates_from_pos(timeframe=btc.mt5.TIMEFRAME_H1, count=10, start_position=0)
|
||||
assert isinstance(rates_from_pos, Candles)
|
||||
assert len(rates_from_pos) == 10
|
||||
rates_range = await btc.copy_rates_range(
|
||||
timeframe=btc.mt5.TIMEFRAME_H1, date_from=start, date_to=end
|
||||
)
|
||||
rates_range = await btc.copy_rates_range(timeframe=btc.mt5.TIMEFRAME_H1, date_from=start, date_to=end)
|
||||
assert isinstance(rates_range, Candles)
|
||||
assert len(rates_range) == 10
|
||||
ticks_from = await btc.copy_ticks_from(date_from=start, count=10)
|
||||
|
||||
@@ -27,9 +27,7 @@ class TestTrader:
|
||||
assert res.retcode == 10009
|
||||
|
||||
async def test_create_order_with_sl(self):
|
||||
sl = (
|
||||
self.trader.symbol.trade_stops_level * 2 + self.trader.symbol.spread
|
||||
) * self.trader.symbol.point
|
||||
sl = (self.trader.symbol.trade_stops_level * 2 + self.trader.symbol.spread) * self.trader.symbol.point
|
||||
tick = await self.trader.symbol.info_tick()
|
||||
sl = tick.bid + sl
|
||||
await self.trader.create_order_with_sl(order_type=OrderType.SELL, sl=sl)
|
||||
@@ -44,9 +42,7 @@ class TestTrader:
|
||||
|
||||
async def test_create_order_with_points(self):
|
||||
points = self.trader.symbol.trade_stops_level * 2 + self.trader.symbol.spread
|
||||
await self.trader.create_order_with_points(
|
||||
order_type=OrderType.BUY, points=points
|
||||
)
|
||||
await self.trader.create_order_with_points(order_type=OrderType.BUY, points=points)
|
||||
res = await self.trader.order.send()
|
||||
profit = floor(await self.trader.order.calc_profit())
|
||||
loss = -floor(abs(await self.trader.order.calc_loss()))
|
||||
@@ -57,16 +53,12 @@ class TestTrader:
|
||||
assert res.retcode == 10009
|
||||
|
||||
async def test_create_order_with_stops(self):
|
||||
sl = (
|
||||
self.trader.symbol.trade_stops_level * 2 + self.trader.symbol.spread
|
||||
) * self.trader.symbol.point
|
||||
sl = (self.trader.symbol.trade_stops_level * 2 + self.trader.symbol.spread) * self.trader.symbol.point
|
||||
tp = sl * self.trader.ram.risk_to_reward
|
||||
tick = await self.trader.symbol.info_tick()
|
||||
sl = tick.ask - sl
|
||||
tp = tick.ask + tp
|
||||
await self.trader.create_order_with_stops(
|
||||
order_type=OrderType.BUY, sl=sl, tp=tp
|
||||
)
|
||||
await self.trader.create_order_with_stops(order_type=OrderType.BUY, sl=sl, tp=tp)
|
||||
res = await self.trader.order.send()
|
||||
profit = floor(await self.trader.order.calc_profit())
|
||||
loss = -floor(abs(await self.trader.order.calc_loss()))
|
||||
|
||||
Reference in New Issue
Block a user