Administrator
4 天以前 1f69a007aa50b04a55195083970c110954935dfd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
"""
成交量管理
"""
 
# 设置历史量
# max60 60天最大量
# yesterday 昨天的量
import json
 
from code_attribute import gpcode_manager, code_nature_analyse
from db.redis_manager_delegate import RedisUtils
from log_module import async_log_util
from utils import global_util, tool
from db import redis_manager_delegate as redis_manager
from log_module.log import logger_day_volumn
 
 
class CodeVolumeManager:
    __db = 0
    __redis_manager = redis_manager.RedisManager(0)
    __instance = None
    __today_volumn_cache = {}
    __reference_volume_as_money_y_dict = {}
    __max_volume_in_5days = {}
 
    def __new__(cls, *args, **kwargs):
        if not cls.__instance:
            cls.__instance = super(CodeVolumeManager, cls).__new__(cls, *args, **kwargs)
            cls.__load_data()
        return cls.__instance
 
    # 将量从数据库加入内存
    @classmethod
    def __load_data(cls):
        redis = cls.__redis_manager.getRedis()
        try:
            keys = RedisUtils.keys(redis, "volumn_max60-*", auto_free=False)
            if keys is not None:
                for k in keys:
                    code = k.split("-")[1]
                    max60_volumn = RedisUtils.get(redis, k, auto_free=False)
                    if max60_volumn:
                        max60_volumn = json.loads(max60_volumn)
                    global_util.max60_volumn[code] = max60_volumn
            keys = RedisUtils.keys(redis, "volumn_yes-*", auto_free=False)
            if keys is not None:
                for k in keys:
                    code = k.split("-")[1]
                    global_util.yesterday_volumn[code] = RedisUtils.get(redis, k, auto_free=False)
            keys = RedisUtils.keys(redis, "volumn_max_5days-*", auto_free=False)
            if keys is not None:
                for k in keys:
                    code = k.split("-")[1]
                    val = RedisUtils.get(redis, k, auto_free=False)
                    cls.__max_volume_in_5days[code] = int(val)
        finally:
            RedisUtils.realse(redis)
 
    # 设置历史量
    def set_histry_volumn(self, code, max60, yesterday, max60_day, max60_day_count, max5_volume):
        redis = self.__redis_manager.getRedis()
        global_util.max60_volumn[code] = (max60, max60_day, max60_day_count)
        global_util.yesterday_volumn[code] = yesterday
        self.__save_max_volume_in_5days(code, max5_volume)
        try:
            RedisUtils.setex_async(self.__db, "volumn_max60-{}".format(code), tool.get_expire(),
                                   json.dumps((max60, max60_day, max60_day_count)),
                                   auto_free=False)
            RedisUtils.setex_async(self.__db, "volumn_yes-{}".format(code), tool.get_expire(), yesterday,
                                   auto_free=False)
        finally:
            RedisUtils.realse(redis)
 
    def __save_max_volume_in_5days(self, code, volume):
        self.__max_volume_in_5days[code] = volume
        RedisUtils.setex_async(self.__db, "volumn_max_5days-{}".format(code), tool.get_expire(), volume,
                               auto_free=False)
 
    def get_max_volume_in_5days(self, code):
        """
        5日最大量
        @param code:
        @return:
        """
        return self.__max_volume_in_5days.get(code)
 
    def get_radical_buy_refer_volume(self, code, limit_up_price):
        """
        获取扫入的参考量:
        参考额小于3.14亿就取90天参考量
        否则就取最近5天的参考量
        @param code:
        @param limit_up_price:
        @return:
        """
        # 60个交易日未涨停取
        k_format = code_nature_analyse.CodeNatureRecordManager().get_k_format_cache(code)
        has_limit_up_in_60 = True
        if k_format and not k_format[13]:
            has_limit_up_in_60 = False
        volume = self.get_max_volume_in_5days(code)
        if volume * limit_up_price >= 3.14e8 and has_limit_up_in_60:
            return volume
        return int(self.get_reference_volume_as_money_y(code) * 1e8 / limit_up_price)
 
    def get_volume_rate_refer_in_5days(self, code, total_sell_volume=0):
        """
        获取今日量与5日最大量的参考值
        @param total_sell_volume: 当前总卖量
        @param code:
        @return: 5日量比
        """
        max_volume = self.get_max_volume_in_5days(code)
        if not max_volume:
            return 0
        today_volume = self.get_today_volumn(code)
        return round((today_volume + total_sell_volume) / max_volume, 2)
 
    # 获取历史量
    def get_histry_volumn(self, code):
        max60 = global_util.max60_volumn.get(code)
        yesterday = global_util.yesterday_volumn.get(code)
        redis = self.__redis_manager.getRedis()
        try:
            if max60 is None:
                max60 = RedisUtils.get(redis, "volumn_max60-{}".format(code), auto_free=False)
                if max60:
                    max60 = json.loads(max60)
            if yesterday is None:
                yesterday = RedisUtils.get(redis, "volumn_yes-{}".format(code), auto_free=False)
            return max60, yesterday
        finally:
            RedisUtils.realse(redis)
 
    # 量的变化大保存
 
    # 设置今日量
    def set_today_volumn(self, code, volumn):
        async_log_util.info(logger_day_volumn, "code:{} volumn:{}".format(code, volumn))
        global_util.today_volumn[code] = volumn
        # 有1000手的变化才保存
        if code in self.__today_volumn_cache and volumn - self.__today_volumn_cache[code] < 100000:
            return
        self.__today_volumn_cache[code] = volumn
        RedisUtils.setex(self.__redis_manager.getRedis(), "volumn_today-{}".format(code), tool.get_expire(), volumn)
 
    # datas:[(code, volumn)]
    def set_today_volumns(self, datas):
        for d in datas:
            code, volumn = d
            async_log_util.info(logger_day_volumn, "code:{} volumn:{}".format(code, volumn))
            global_util.today_volumn[code] = volumn
            # 有1000手的变化才保存
            if code in self.__today_volumn_cache and volumn - self.__today_volumn_cache[code] < 100000:
                continue
            self.__today_volumn_cache[code] = volumn
            RedisUtils.setex_async(self.__db, "volumn_today-{}".format(code), tool.get_expire(), volumn)
 
    # 获取今日量
    def get_today_volumn(self, code):
        _volumn = global_util.today_volumn.get(code)
        if _volumn is None:
            _volumn = RedisUtils.get(self.__redis_manager.getRedis(), "volumn_today-{}".format(code))
        return _volumn
 
    # 获取今日量
    def get_today_volumn_cache(self, code):
        return global_util.today_volumn.get(code)
 
    # 获取量比(今日量/max(60天最大量,昨日量))
    # 将总卖量计算在内
    def get_volume_rate(self, code, total_sell_volume=0, with_info=False):
        today = self.get_today_volumn(code)
        max60, yesterday = self.get_histry_volumn(code)
        if today is None:
            today = 0
        if max60 is None or yesterday is None:
            max60 = [today, '']
            yesterday = today
            if max60[0] < 1:
                max60[0] = 1
        rate = round((int(today) + total_sell_volume) / max(int(max60[0]), int(yesterday)), 2)
        if not with_info:
            return rate
        return rate, (today, max(int(max60[0]), int(yesterday)))
 
    # 获取量参考日期
    # 返回(参考量日期,距今的交易日个数)
    def get_volume_refer_date(self, code):
        max60, yesterday = self.get_histry_volumn(code)
        if max60 is None or yesterday is None:
            raise Exception("获取失败")
        if int(max60[0]) >= int(yesterday):
            return max60[1], max60[2]
        else:
            return "上个交易日", 0
 
    # 获取量比索引
    def get_volume_rate_index(self, volume_rate):
        rates = [0.2, 0.4, 0.6, 0.8, 1, 1.2, 1.4, 1.6]
        for index in range(0, len(rates)):
            if volume_rate <= rates[index]:
                return index
        return len(rates) - 1
 
    # 保存今日量
    def save_today_volumn(self, code, volumn, volumnUnit):
        _volumn = None
        if volumnUnit == 0:
            _volumn = round(float(volumn) * 100000000)
        elif volumnUnit == 1:
            _volumn = round(float(volumn) * 10000)
        elif volumnUnit == 2:
            _volumn = int(volumn)
        if _volumn is not None:
            self.set_today_volumn(code, _volumn * 100)
 
    def get_reference_volume_as_money_y(self, code):
        """
        返回参考量今日对应的金额(单位为亿)
        @param code:
        @return:
        """
        if code in self.__reference_volume_as_money_y_dict:
            return self.__reference_volume_as_money_y_dict.get(code)
        max60, yesterday = self.get_histry_volumn(code)
        if max60:
            num = max60[0]
            limit_up_price = gpcode_manager.get_limit_up_price(code)
            if limit_up_price:
                money_y = round((num * float(limit_up_price)) / 1e8, 1)
                self.__reference_volume_as_money_y_dict[code] = money_y
                return money_y
        # 默认为5亿
        return 5
 
 
if __name__ == "__main__":
    print(CodeVolumeManager().get_volume_rate("000059"))