6
6
import logging
7
7
import os
8
8
import time
9
+ from pathlib import Path
9
10
from typing import Generator
10
11
11
12
import MetaTrader5 as Mt5
@@ -31,39 +32,39 @@ def is_headless() -> bool:
31
32
32
33
33
34
@pytest .fixture (scope = "module" , autouse = True )
34
- def setup_teardown () -> Generator [None , None , None ]:
35
+ def setup_teardown () -> Generator [None , None , None ]: # noqa: C901 - Test setup needs to handle many cases
35
36
"""Set up and tear down MetaTrader5 connection for the test module."""
36
37
if is_headless ():
37
38
logger .info ("Running in headless mode - skipping MT5 initialization" )
38
39
yield
39
40
return
40
41
41
42
init_result = Mt5 .initialize ()
42
-
43
+
43
44
if not init_result :
44
45
common_paths = [
45
46
"C:\\ Program Files\\ MetaTrader 5\\ terminal64.exe" ,
46
- "C:\\ Program Files (x86)\\ MetaTrader 5\\ terminal.exe"
47
+ "C:\\ Program Files (x86)\\ MetaTrader 5\\ terminal.exe" ,
47
48
]
48
-
49
+
49
50
for path in common_paths :
50
- if os . path .exists (path ):
51
+ if Path ( path ) .exists ():
51
52
init_result = Mt5 .initialize (path = path )
52
53
if init_result :
53
54
logger .info (f"Successfully initialized MT5 with path: { path } " )
54
55
break
55
-
56
+
56
57
if not init_result :
57
58
pytest .skip (f"MetaTrader5 could not be initialized. Error: { Mt5 .last_error ()} " )
58
59
59
60
time .sleep (5 )
60
-
61
+
61
62
symbols = Mt5 .symbols_get ()
62
63
if not symbols :
63
64
logger .warning ("No symbols loaded. Attempting to fix..." )
64
65
Mt5 .symbols_total () # Sometimes this helps refresh the symbols list
65
66
time .sleep (3 )
66
-
67
+
67
68
symbols = Mt5 .symbols_get ()
68
69
if not symbols :
69
70
logger .error ("Still no symbols available after retry." )
@@ -432,15 +433,15 @@ def test_open_sell_position(trade: Trade) -> None:
432
433
433
434
434
435
@pytest .mark .real_trading
435
- def test_close_position (trade : Trade ) -> None :
436
+ def test_close_position (trade : Trade ) -> None : # noqa: C901 - Test needs to handle many edge cases
436
437
"""Test closing a position with real trades."""
437
438
# First, ensure we can get symbol info
438
439
symbol_info = Mt5 .symbol_info (trade .symbol )
439
440
if not symbol_info :
440
441
pytest .skip (f"Could not get symbol info for { trade .symbol } " )
441
-
442
+
442
443
logger .info (f"Symbol { trade .symbol } trade mode: { symbol_info .trade_mode } " )
443
-
444
+
444
445
# Check if we have any existing positions to close
445
446
positions = Mt5 .positions_get (symbol = trade .symbol )
446
447
has_existing_position = False
@@ -450,37 +451,37 @@ def test_close_position(trade: Trade) -> None:
450
451
has_existing_position = True
451
452
logger .info (f"Found existing position with ticket { position .ticket } " )
452
453
break
453
-
454
+
454
455
if not has_existing_position :
455
456
# Try to open a new position
456
457
try :
457
458
logger .info (f"Attempting to open a new position for { trade .symbol } " )
458
459
trade .open_buy_position ("Test Position to Close" )
459
460
time .sleep (2 ) # Wait for position to open
460
-
461
+
461
462
# Verify position was opened
462
463
positions = Mt5 .positions_get (symbol = trade .symbol )
463
464
assert positions is not None , "Failed to get positions after opening"
464
-
465
+
465
466
has_position = False
466
467
for position in positions :
467
468
if position .magic == TEST_MAGIC_NUMBER :
468
469
has_position = True
469
470
logger .info (f"Successfully opened position with ticket { position .ticket } " )
470
471
break
471
-
472
+
472
473
assert has_position , "Failed to find opened position"
473
-
474
- except Exception as e :
474
+
475
+ except Exception :
475
476
logger .exception ("Error opening position" )
476
477
raise
477
-
478
+
478
479
# Now try to close the position
479
480
try :
480
481
logger .info ("Attempting to close position" )
481
482
trade .close_position ("Test Closing Position" )
482
483
time .sleep (2 ) # Wait for position to close
483
-
484
+
484
485
# Verify position was closed
485
486
positions = Mt5 .positions_get (symbol = trade .symbol )
486
487
has_position = False
@@ -490,17 +491,17 @@ def test_close_position(trade: Trade) -> None:
490
491
has_position = True
491
492
logger .warning (f"Position still exists with ticket { position .ticket } " )
492
493
break
493
-
494
+
494
495
assert not has_position , "Position was not closed successfully"
495
496
logger .info ("Position closed successfully" )
496
-
497
- except Exception as e :
497
+
498
+ except Exception :
498
499
logger .exception ("Error during position test" )
499
500
raise
500
501
501
502
502
503
@pytest .fixture (autouse = True )
503
- def skip_real_trading_in_headless (request ) -> None :
504
+ def skip_real_trading_in_headless (request : pytest . FixtureRequest ) -> None :
504
505
"""Skip real trading tests in headless mode."""
505
506
if is_headless () and request .node .get_closest_marker ("real_trading" ):
506
507
pytest .skip ("Skipping real trading test in headless mode" )
0 commit comments