rlquantdata 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of rlquantdata might be problematic. Click here for more details.

@@ -0,0 +1,65 @@
1
+ import os
2
+
3
+ import pandas as pd
4
+
5
+ from src import rlquantdata, rlquantdata as pai
6
+ from src.rlquantdata.DateUtilities import Date
7
+ from src.rlquantdata.DateUtilities.Date_enum import BizDayConventions, DateGeneration
8
+ from src.rlquantdata.client import BaseClient
9
+
10
+
11
+ class TradeDateUtils:
12
+ def __init__(self, trade_path=None, client: BaseClient = None):
13
+ if trade_path is not None and os.path.exists(trade_path):
14
+ biz_data = pd.read_feather(trade_path).set_index('trade_date')['001002'].astype(bool)
15
+
16
+ true_indexes = pd.to_datetime(biz_data.index[~biz_data.values])
17
+
18
+ # 将 datetime 类型转换为 Date 类型,并用 set() 函数转换为集合类型
19
+ def date_to_Date(pydate):
20
+ return str(Date(pydate.year, pydate.month, pydate.day))
21
+
22
+ src.rlquantdata.DateUtilities.Calendar.sse_holDays = set([date_to_Date(d.date()) for d in true_indexes])
23
+ elif client is not None:
24
+ sorted_sse_holDays = sorted(list(src.rlquantdata.DateUtilities.Calendar.sse_holDays))
25
+ result = client.get_remote_hol_dates(sorted_sse_holDays[-1])
26
+ if result is None:
27
+ print(f'无法从服务端获取交易日列表,使用预设交易日历。')
28
+ result = []
29
+ else:
30
+ print(f'服务端获取交易日列表成功。')
31
+ src.rlquantdata.DateUtilities.Calendar.sse_holDays.update(result)
32
+ else:
33
+ print(f'{trade_path} 路径无效,使用预设交易日历。')
34
+
35
+ def isBizDay(self, holidayCenter, ref):
36
+ return pai.isBizDay(holidayCenter, ref)
37
+
38
+ def datesList(self, fromDate, toDate):
39
+ return pai.datesList(fromDate, toDate)
40
+
41
+ def bizDatesList(self, holidayCenter, fromDate, toDate):
42
+ return pai.bizDatesList(holidayCenter, fromDate, toDate)
43
+
44
+ def holDatesList(self, holidayCenter, fromDate, toDate, includeWeekend=True):
45
+ return pai.holDatesList(holidayCenter, fromDate, toDate, includeWeekend)
46
+
47
+ def advanceDate(self, referenceDate, period):
48
+ return pai.advanceDate(referenceDate, period)
49
+
50
+ def adjustDateByCalendar(self, holidayCenter, referenceDate, convention=BizDayConventions.Following):
51
+ return pai.adjustDateByCalendar(holidayCenter, referenceDate, convention)
52
+
53
+ def advanceDateByCalendar(self, holidayCenter, referenceDate, period, convention=BizDayConventions.Following):
54
+ return pai.advanceDateByCalendar(holidayCenter, referenceDate, period, convention)
55
+
56
+ def nthWeekDay(self, nth, dayOfWeek, month, year):
57
+ return pai.nthWeekDay(nth, dayOfWeek, month, year)
58
+
59
+ def makeSchedule(self, firstDate,
60
+ endDate,
61
+ tenor,
62
+ calendar='NullCalendar',
63
+ dateRule=BizDayConventions.Following,
64
+ dateGenerationRule=DateGeneration.Forward):
65
+ return pai.makeSchedule(firstDate, endDate, tenor, calendar, dateRule, dateGenerationRule)
@@ -0,0 +1,197 @@
1
+ import os
2
+ import datetime as dt
3
+ import glob
4
+ import pandas as pd
5
+ import numpy as np
6
+
7
+
8
+ def search_files(parent_dir, freq, file_name):
9
+ pattern = '{}/{}/[{}]'.format(parent_dir, freq,
10
+ ']['.join([s.lower() + s.upper() for s in file_name]))
11
+ files = glob.glob(pattern)
12
+ if len(files) > 1:
13
+ raise ValueError('too many candidate file for key:{}'.format(file_name))
14
+ if len(files) == 0:
15
+ raise FileNotFoundError('no file for key:{}'.format(file_name))
16
+ return files[0]
17
+
18
+
19
+ def get_split_field_names(start_time, end_time, field):
20
+ if end_time is None:
21
+ end_time = dt.datetime.today().strftime('%Y-%m-%d 15:00:00')
22
+ else:
23
+ end_time = pd.to_datetime(end_time).strftime('%Y-%m-%d 15:00:00')
24
+ freq, key = field.split('/')
25
+ # 日频数据一个字段一个feather文件,一分钟的按月切割,其他的按年切割
26
+ if freq == '01d':
27
+ field_names = [key]
28
+ elif freq in ['01min']:
29
+ months = pd.date_range(start_time, end_time, freq="M")
30
+ months = [ia.strftime('%Y%m') for ia in months]
31
+ months.append(pd.to_datetime(end_time).strftime('%Y%m'))
32
+ months = np.unique(months)
33
+ field_names = [key + '_' + _m for _m in months]
34
+ else:
35
+ years = pd.date_range(start_time, end_time, freq="Y")
36
+ years = [ia.strftime('%Y') for ia in years]
37
+ end_t = pd.to_datetime(end_time)
38
+ years.append(str(end_t.year))
39
+ years = np.unique(years)
40
+ field_names = [key + '_' + _m for _m in years]
41
+ return field_names
42
+
43
+
44
+ def get_feather(msg_path, include930, key, start_time, end_time, stocks=None, freq='price01d'):
45
+ """获取basic_data price 各频率数据"""
46
+ if stocks is None:
47
+ cols = None
48
+ else:
49
+ stocks = [str(ia) for ia in stocks]
50
+ cols = ['trade_date'] + stocks
51
+
52
+ start_time = pd.to_datetime(start_time).strftime('%Y-%m-%d %H:%M:%S')
53
+ end_time = None if end_time is None else pd.to_datetime(end_time).strftime('%Y-%m-%d 15:00:00')
54
+ field_names = get_split_field_names(start_time, end_time, key)
55
+ files_len = len(field_names)
56
+ df_list = []
57
+ for idx, field_name in enumerate(field_names):
58
+ filename = "{}/{}/{}.fea".format(msg_path, freq, field_name)
59
+ if not os.path.exists(filename):
60
+ filename = search_files(msg_path, freq, '{}.fea'.format(field_name))
61
+ # with open(filename, 'rb') as f:
62
+ # with mmap.mmap(f.fileno(), 0, access=1) as mf:
63
+ # tmp = pd.read_feather(mf, cols, use_threads=False)
64
+ tmp = pd.read_feather(filename, cols, use_threads=False).set_index('trade_date')
65
+ tmp.index = pd.to_datetime(tmp.index)
66
+ if freq.endswith('min') and not include930:
67
+ tmp = tmp[tmp.index.time != pd.to_datetime('09:30:00').time()]
68
+ if idx == 0:
69
+ tmp = tmp.loc[start_time:]
70
+ if idx == files_len - 1 and end_time is not None:
71
+ tmp = tmp.loc[:end_time]
72
+ # tmp = tmp.loc[start_time:end_time]
73
+ df_list.append(tmp)
74
+ df = pd.concat(df_list, join='outer', sort=False)
75
+
76
+ if stocks is not None:
77
+ stock_not_in = np.setdiff1d(stocks, df.columns)
78
+ if len(stock_not_in) > 0:
79
+ df[stock_not_in] = np.nan
80
+ df.columns = df.columns.astype(int)
81
+ df = df.sort_index().sort_index(axis=1)
82
+ df.columns.name = 'code'
83
+ df.index.name = 'trade_date'
84
+ return df
85
+
86
+
87
+ def trade_time(full_tick, start_time=None, end_time=None, bar_counts=None):
88
+ """
89
+ 从full tick中获取相应的交易时间戳,根据不同频率传入不同的full_tick
90
+ full_tick: 相应频率的所有时间戳
91
+ start_time: pd.timestamp
92
+ end_time: pd.timestamp
93
+ bar_counts: 从end time/start time 推多少个时刻,优先 bar_counts + end_time
94
+
95
+ """
96
+ # 交易时间段
97
+ if start_time is None and (end_time is not None) and (bar_counts is not None):
98
+ # 从endtime往前取n bars
99
+ idx = np.where(full_tick <= end_time)[0][-1]
100
+ days = full_tick[max(0, idx - bar_counts + 1): idx + 1]
101
+ return pd.to_datetime(days).tolist()
102
+
103
+ elif start_time is None and (end_time is not None) and (bar_counts is None):
104
+ # 从endtime往前取n bars
105
+ idx = np.where(full_tick <= end_time)[0][-1]
106
+ days = full_tick[: idx+1]
107
+ return pd.to_datetime(days).tolist()
108
+
109
+ elif (start_time is not None) and (bar_counts is not None):
110
+ # 从startime往后取n bars
111
+ idx = np.where(full_tick >= start_time)[0][0]
112
+ days = full_tick[idx: idx + bar_counts]
113
+ return pd.to_datetime(days).tolist()
114
+
115
+ elif (start_time is not None) and (end_time is not None):
116
+ idx_st = np.where(full_tick >= start_time)[0][0]
117
+ idx_et = np.where(full_tick <= end_time)[0][-1]
118
+ if idx_st > idx_et:
119
+ raise ValueError('no trading between {}~{}'.format(start_time, end_time))
120
+ days = full_tick[idx_st: idx_et + 1]
121
+ return pd.to_datetime(days).tolist()
122
+ elif (start_time is not None) and (end_time is None) and (bar_counts is None):
123
+ end_time = pd.to_datetime(dt.datetime.now().strftime('%Y-%m-%d 15:00:00'))
124
+ idx_st = np.where(full_tick >= start_time)[0][0]
125
+ idx_et = np.where(full_tick <= end_time)[0][-1]
126
+ if idx_st > idx_et:
127
+ raise ValueError('no trading between {}~{}'.format(start_time, end_time))
128
+ days = full_tick[idx_st: idx_et + 1]
129
+ return pd.to_datetime(days).tolist()
130
+ else:
131
+ raise ValueError('not support for start time:{}, end_time:{}, bar_counts:{}'.format(start_time, end_time,
132
+ bar_counts))
133
+
134
+
135
+ def construct_day_tradings(day, freq, include930):
136
+ """
137
+ construct_day_tradings
138
+ """
139
+ day = pd.to_datetime(day).strftime("%Y%m%d")
140
+
141
+ time_0930 = "{} 093000".format(day)
142
+ time_1130 = pd.to_datetime('{} 113000'.format(day), format='%Y-%m-%d %H:%M:%S')
143
+ time_1330 = "{} 133000".format(day)
144
+
145
+ tradings = pd.date_range(time_0930, time_1330, freq=freq)
146
+ tradings = pd.Series(tradings) # 索引对象不可变,转换为Series对象
147
+ idxs = tradings > time_1130
148
+ tradings[idxs] = tradings[idxs] + dt.timedelta(minutes=90)
149
+ if not include930:
150
+ tradings = tradings[1:]
151
+ return tradings
152
+
153
+
154
+ def get_full_trade_tick(tradings, freq, include930=False):
155
+ """
156
+ 根据频率生产出完成的交易日及日内时间戳
157
+ :param include930:
158
+ :param start_time:
159
+ :param end_time:
160
+ :param freq:
161
+ :return: array / list of datetime
162
+ """
163
+ # tradings = pd.to_datetime(get_tradings(db_service, start_time, end_time))
164
+ tradings = np.unique(tradings)
165
+
166
+ if freq != "01d":
167
+ all_tradings = []
168
+ for day in tradings:
169
+ # 获取每日的交易时间
170
+ day_tradings = construct_day_tradings(day, freq, include930)
171
+ all_tradings.extend(day_tradings.tolist())
172
+
173
+ tradings = pd.to_datetime(all_tradings)
174
+
175
+ return tradings
176
+
177
+
178
+ def format_time(start_time=None, end_time=None, freq='d'):
179
+ if freq in ['d', 'D']:
180
+ if end_time is not None:
181
+ end_time = pd.to_datetime(pd.to_datetime(end_time).date())
182
+ if start_time is not None:
183
+ start_time = pd.to_datetime(pd.to_datetime(start_time).date())
184
+ elif freq in ['min', 'T']:
185
+ if end_time is not None:
186
+ if len(str(end_time)) > 10:
187
+ end_time = pd.to_datetime(end_time)
188
+ else:
189
+ end_time = pd.to_datetime(pd.to_datetime(end_time).strftime("%Y-%m-%d 15:00:00"))
190
+ if start_time is not None:
191
+ if len(str(start_time)) > 10:
192
+ start_time = pd.to_datetime(start_time)
193
+ else:
194
+ start_time = pd.to_datetime(pd.to_datetime(start_time).strftime("%Y-%m-%d 00:00:00"))
195
+ else:
196
+ raise ValueError('not support for freq:{}'.format(freq))
197
+ return start_time, end_time
@@ -0,0 +1 @@
1
+ version = '1.0.0'