4
4
"""
5
5
import time
6
6
import unittest
7
+ from unittest import mock
7
8
import datetime
8
9
import pandas as pd
9
10
from easyquant .easydealutils .time import get_next_trade_date , is_trade_date
11
+ import arrow
10
12
11
13
from dateutil import tz
12
14
from easyquant .main_engine import MainEngine
@@ -57,7 +59,7 @@ def setUp(self):
57
59
58
60
now = datetime .datetime .combine (self .trade_date , self .time )
59
61
# 此处重新定义 main_engine
60
- self ._main_engine = MainEngine ('ht' , now = now )
62
+ self ._main_engine = MainEngine ('ht' , 'tmp/ht.json' )
61
63
62
64
# 设置为不在交易中
63
65
self .clock_engine .trading_state = False
@@ -85,50 +87,41 @@ def tearDown(self):
85
87
86
88
def test_set_now (self ):
87
89
"""
88
- 重设 clock_engine 的时间
90
+ 1. 重设 clock_engine 的时间
91
+ 2. 通过 mock 来重设时间戳
92
+ 3. mock 只能重设 time.time 函数的时间戳,但是不能重设 datetime.datetime.now 函数的时间戳,详情见: http://stackoverflow.com/questions/4481954/python-trying-to-mock-datetime-date-today-but-not-working
93
+ 4. 在代码中需要使用时间戳时,请通过 clock_engine 中的 now 或者 now_dt 接口获得,也可以使用 time.time 获得.否则该段代码将不适用于需要更改时间戳的单元测试
89
94
:return:
90
95
"""
91
-
92
96
tzinfo = tz .tzlocal ()
93
- now = datetime .datetime .combine (
94
- self .trade_date ,
95
- datetime .time (8 , 59 , 00 , tzinfo = tzinfo ),
96
- )
97
- clock_engien = ClockEngine (EventEngine (), now , tzinfo )
97
+ # 使用datetime 类构建时间戳
98
+ now = datetime .datetime (2016 , 7 , 14 , 8 , 59 , 50 , tzinfo = tzinfo )
98
99
99
- # 去掉微秒误差后比较
100
- self .assertEqual (clock_engien .now_dt .replace (microsecond = 0 ), now )
101
-
102
- def test_reset_now (self ):
103
- """
104
- 重设时钟引擎当前时间为其他时间点
105
- :return:
106
- """
107
- tzinfo = tz .tzlocal ()
108
- clock_engien = ClockEngine (EventEngine ())
109
- now = datetime .datetime .combine (
110
- self .trade_date ,
111
- datetime .time (8 , 59 , 00 , tzinfo = tzinfo ),
112
- )
113
- clock_engien .reset_now (now )
100
+ # 通过mock ,将 time.time() 函数的返回值重设为上面的打算模拟的值,注意要转化为浮点数时间戳
101
+ time .time = mock .Mock (return_value = now .timestamp ())
114
102
115
- # 去掉微秒误差后比较
116
- self . assertEqual ( clock_engien . now_dt . replace ( microsecond = 0 ), now )
103
+ # 生成一个时钟引擎
104
+ clock_engien = ClockEngine ( EventEngine ( ), tzinfo )
117
105
118
- # 重设为当前时间
119
- clock_engien .reset_now ()
120
- now = datetime . datetime . now ( tzinfo ). replace ( microsecond = 0 )
106
+ # 去掉微秒误差后验证其数值
107
+ self . assertEqual ( clock_engien .now , now . timestamp ()) # time.time 时间戳
108
+ self . assertEqual ( clock_engien . now_dt , now ) # datetime 时间戳
121
109
122
- # 去掉微秒误差后比较
123
- self .assertEqual (clock_engien .now_dt .replace (microsecond = 0 ), now )
110
+ # 据此可以模拟一段时间内各个闹钟事件的触发,比如模拟开市9:00一直到休市15:00
111
+ for _ in range (60 ):
112
+ clock_engien .tock ()
113
+ now += datetime .timedelta (seconds = 1 ) # 每秒触发一次 tick_tock
114
+ time .time = mock .Mock (return_value = now .timestamp ())
115
+ self .assertEqual (clock_engien .now , now .timestamp ()) # time.time 时间戳
116
+ self .assertEqual (clock_engien .now_dt , now ) # datetime 时间戳
124
117
125
118
def test_clock_moment_is_active (self ):
126
119
# 设置时间
127
120
now = datetime .datetime .combine (
128
121
self .trade_date ,
129
122
datetime .time (23 , 59 , 58 , tzinfo = tz .tzlocal ()),
130
123
)
131
- self . clock_engine . reset_now ( now )
124
+ time . time = mock . Mock ( return_value = now . timestamp () )
132
125
133
126
# 触发前, 注册时间事件
134
127
moment = datetime .time (23 , 59 , 59 , tzinfo = tz .tzlocal ())
@@ -141,7 +134,8 @@ def test_clock_moment_is_active(self):
141
134
self .trade_date ,
142
135
datetime .time (23 , 59 , 59 , tzinfo = tz .tzlocal ())
143
136
)
144
- self .clock_engine .reset_now (now )
137
+ time .time = mock .Mock (return_value = now .timestamp ())
138
+
145
139
# 确认触发
146
140
self .assertTrue (cmh .is_active ())
147
141
@@ -151,7 +145,7 @@ def test_clock_update_next_time(self):
151
145
self .trade_date ,
152
146
datetime .time (23 , 59 , 58 , tzinfo = tz .tzlocal ())
153
147
)
154
- self . clock_engine . reset_now ( now )
148
+ time . time = mock . Mock ( return_value = now . timestamp () )
155
149
156
150
# 触发前, 注册时间事件
157
151
moment = datetime .time (23 , 59 , 59 , tzinfo = tz .tzlocal ())
@@ -164,7 +158,8 @@ def test_clock_update_next_time(self):
164
158
self .trade_date ,
165
159
datetime .time (23 , 59 , 59 , tzinfo = tz .tzlocal ())
166
160
)
167
- self .clock_engine .reset_now (now )
161
+ time .time = mock .Mock (return_value = now .timestamp ())
162
+
168
163
# 确认触发
169
164
self .assertTrue (cmh .is_active ())
170
165
@@ -186,7 +181,7 @@ def register_clock_moent_makeup(self, makeup):
186
181
self .trade_date ,
187
182
datetime .time (23 , 59 , 59 , tzinfo = tz .tzlocal ())
188
183
)
189
- self . clock_engine . reset_now ( begin )
184
+ time . time = mock . Mock ( return_value = begin . timestamp () )
190
185
191
186
# 注册时刻一个超时事件
192
187
moment = datetime .time (0 , 0 , 0 , tzinfo = tz .tzlocal ())
@@ -256,7 +251,7 @@ def test_register_clock_interval_not_trading_false(self):
256
251
self .assertFalse (self .clock_engine .trading_state )
257
252
258
253
def register_clock_interval (self , begin , trading , active_times ):
259
- self . clock_engine . reset_now ( begin )
254
+ time . time = mock . Mock ( return_value = begin . timestamp () )
260
255
self .active_times = 0
261
256
262
257
def clock (event ):
@@ -278,7 +273,7 @@ def clock(event):
278
273
# 开启事件引擎
279
274
for sec in range (int (minute_interval * 60 )):
280
275
now = begin + datetime .timedelta (seconds = sec )
281
- self . clock_engine . reset_now ( now )
276
+ time . time = mock . Mock ( return_value = now . timestamp () )
282
277
self .clock_engine .tock ()
283
278
time .sleep (1 )
284
279
self .main_engine .event_engine .stop ()
@@ -317,7 +312,7 @@ def count(event):
317
312
seconds = 60 * mins
318
313
for secs in range (seconds ):
319
314
now = begin + datetime .timedelta (seconds = secs )
320
- self . clock_engine . reset_now ( now )
315
+ time . time = mock . Mock ( return_value = now . timestamp () )
321
316
self .clock_engine .tock ()
322
317
time .sleep (0.001 )
323
318
@@ -358,7 +353,7 @@ def count(event):
358
353
end = (begin + datetime .timedelta (days = days )).replace (hour = 23 , minute = 59 , second = 59 )
359
354
360
355
# 重置时间到凌晨
361
- self . clock_engine . reset_now ( begin )
356
+ time . time = mock . Mock ( return_value = begin . timestamp () )
362
357
363
358
# 预估时间事件触发次数, 每个交易日触发一次
364
359
actived_times = 0
@@ -374,7 +369,7 @@ def count(event):
374
369
375
370
now = begin
376
371
while 1 :
377
- self . clock_engine . reset_now ( now )
372
+ time . time = mock . Mock ( return_value = now . timestamp () )
378
373
self .clock_engine .tock ()
379
374
time .sleep (0.001 )
380
375
now += interval
0 commit comments