1+ import pytest
2+ import logging
3+ import time
4+
5+ from mqpy .tick import Tick
6+ import MetaTrader5 as Mt5
7+
8+
9+ @pytest .fixture (scope = "module" , autouse = True )
10+ def setup_teardown ():
11+ """Set up and tear down MetaTrader5 connection for the test module."""
12+ if not Mt5 .initialize ():
13+ pytest .skip ("MetaTrader5 could not be initialized" )
14+
15+ time .sleep (5 )
16+
17+ yield
18+
19+ Mt5 .shutdown ()
20+
21+
22+ @pytest .fixture
23+ def symbol ():
24+ """Provides a valid trading symbol for testing."""
25+ time .sleep (1 )
26+
27+ symbols = Mt5 .symbols_get ()
28+ if not symbols :
29+ pytest .skip ("No symbols available for testing" )
30+
31+ for symbol in symbols :
32+ if symbol .name == "EURUSD" :
33+ return "EURUSD"
34+
35+ return symbols [0 ].name
36+
37+
38+ def test_tick_initialization (symbol ):
39+ """Test initialization of Tick with a real symbol."""
40+ tick = Tick (symbol )
41+
42+ assert tick .symbol == symbol
43+
44+ assert isinstance (tick .time , int )
45+ assert isinstance (tick .bid , float )
46+ assert isinstance (tick .ask , float )
47+ assert tick .ask >= 0
48+ assert tick .bid >= 0
49+ assert tick .ask >= tick .bid
50+
51+
52+ def test_tick_properties (symbol ):
53+ """Test all Tick properties with a real symbol."""
54+ tick = Tick (symbol )
55+
56+ assert isinstance (tick .symbol , str )
57+ assert isinstance (tick .time , int )
58+ assert isinstance (tick .bid , float )
59+ assert isinstance (tick .ask , float )
60+ assert isinstance (tick .time_msc , int )
61+ assert isinstance (tick .flags , int )
62+
63+ assert isinstance (tick .last , float ) or tick .last is None
64+ assert isinstance (tick .volume , int ) or tick .volume is None
65+
66+ if tick .volume_real is not None :
67+ assert isinstance (tick .volume_real , float )
68+
69+
70+ def test_updated_tick_data (symbol ):
71+ """Test getting updated tick data after waiting."""
72+ first_tick = Tick (symbol )
73+ first_time = first_tick .time
74+
75+ time .sleep (2 )
76+
77+ second_tick = Tick (symbol )
78+ second_time = second_tick .time
79+
80+ if first_time == second_time :
81+ print (f"Note: No tick update for { symbol } after 2 seconds" )
82+
83+
84+ def test_multiple_symbols ():
85+ """Test Tick with multiple symbols simultaneously."""
86+ symbols = Mt5 .symbols_get ()
87+ if len (symbols ) < 2 :
88+ pytest .skip ("Need at least 2 symbols for this test" )
89+
90+ symbol1 = symbols [0 ].name
91+ symbol2 = symbols [1 ].name
92+
93+ tick1 = Tick (symbol1 )
94+ tick2 = Tick (symbol2 )
95+
96+ assert tick1 .symbol == symbol1
97+ assert tick2 .symbol == symbol2
98+
99+ assert isinstance (tick1 .bid , float )
100+ assert isinstance (tick1 .ask , float )
101+ assert isinstance (tick2 .bid , float )
102+ assert isinstance (tick2 .ask , float )
103+
104+
105+ def test_invalid_symbol ():
106+ """Test behavior with an invalid symbol."""
107+ invalid_symbol = "INVALID_SYMBOL_THAT_DOESNT_EXIST"
108+
109+ with pytest .raises (Exception ):
110+ Tick (invalid_symbol )
111+
112+
113+ def test_spread_calculation (symbol ):
114+ """Test spread calculation from bid/ask values."""
115+ tick = Tick (symbol )
116+
117+ spread = tick .ask - tick .bid
118+
119+ assert spread >= 0
120+
121+ logging .info (f"Spread for { symbol } : { spread } " )
0 commit comments