mirror of
https://github.com/Ichinga-Samuel/aiomql.git
synced 2026-07-28 12:47:43 +00:00
108 lines
3.1 KiB
Python
108 lines
3.1 KiB
Python
import asyncio
|
|
import json
|
|
import shutil
|
|
from datetime import datetime, UTC
|
|
from logging import getLogger
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from aiomql.core import Config
|
|
from aiomql.core.meta_backtester import MetaBackTester
|
|
from aiomql.core.backtesting.backtest_engine import BackTestEngine
|
|
from aiomql.lib import Positions, History, Order
|
|
|
|
logger = getLogger(__name__)
|
|
|
|
|
|
async def cleanup():
|
|
try:
|
|
shutil.rmtree(Path("tests/backtest/configs"), ignore_errors=True)
|
|
Path.unlink(Path("tests/backtest/test.json"), missing_ok=True)
|
|
shutil.rmtree(Path("tests/backtest/trade_records"), ignore_errors=True)
|
|
shutil.rmtree(Path("tests/backtest/backtesting"), ignore_errors=True)
|
|
await close_all_positions()
|
|
await MetaBackTester().shutdown()
|
|
except Exception as err:
|
|
logger.error(f"Failed to complete cleanup: {err}")
|
|
|
|
|
|
async def close_all_positions():
|
|
try:
|
|
mt = MetaBackTester()
|
|
positions = await mt.positions_get()
|
|
tasks = []
|
|
for position in positions:
|
|
order_type = mt.ORDER_TYPE_BUY if position.type == mt.ORDER_TYPE_SELL else mt.ORDER_TYPE_SELL
|
|
req = {
|
|
"action": mt.TRADE_ACTION_DEAL,
|
|
"symbol": position.symbol,
|
|
"volume": position.volume,
|
|
"type": order_type,
|
|
"position": position.ticket,
|
|
"price": position.price_current,
|
|
}
|
|
tasks.append(mt.order_send(req))
|
|
await asyncio.gather(*tasks)
|
|
except Exception as err:
|
|
logger.error(f"Failed to close all positions: {err}")
|
|
|
|
|
|
@pytest.fixture(scope="package", autouse=True)
|
|
async def config(request):
|
|
Path("tests/backtest/configs").mkdir(exist_ok=True)
|
|
with open("aiomql.json", "r") as fh, open("tests/backtest/configs/test2.json", "w") as fh1, open(
|
|
"tests/backtest/test.json", "w"
|
|
) as fh2:
|
|
data = json.load(fh)
|
|
data["mode"] = "backtest"
|
|
json.dump(data, fh1, indent=2)
|
|
json.dump(data, fh2, indent=2)
|
|
config = Config(config_file="tests/backtest/test.json", root="tests/backtest", filename="test.json")
|
|
yield config
|
|
await cleanup()
|
|
|
|
|
|
@pytest.fixture(scope="package", autouse=True)
|
|
async def mt():
|
|
mt = MetaBackTester()
|
|
await mt.initialize()
|
|
await mt.login()
|
|
yield mt
|
|
await mt.shutdown()
|
|
|
|
|
|
@pytest.fixture(scope="package")
|
|
async def period():
|
|
return {"start": datetime(2024, 2, 1, hour=8, tzinfo=UTC),
|
|
"end": datetime(2024, 2, 7, hour=16, tzinfo=UTC)}
|
|
|
|
|
|
@pytest.fixture(scope="package")
|
|
async def backtest_engine(period):
|
|
start = period["start"]
|
|
end = period["end"]
|
|
return BackTestEngine(start=start, end=end, name="backtest_data", assign_to_config=True, preload=False)
|
|
|
|
|
|
@pytest.fixture(scope="function")
|
|
def order_sell(sell_order):
|
|
return Order(**sell_order)
|
|
|
|
|
|
@pytest.fixture(scope="function")
|
|
def order_buy(buy_order):
|
|
return Order(**buy_order)
|
|
|
|
|
|
@pytest.fixture(scope="package")
|
|
def positions():
|
|
return Positions()
|
|
|
|
|
|
@pytest.fixture(scope="package")
|
|
def history(period):
|
|
start = period["start"]
|
|
end = period["end"]
|
|
return History(date_from=start, date_to=end)
|