115 lines
3.6 KiB
Python
115 lines
3.6 KiB
Python
import baostock as bs
|
|
|
|
from Common.CEnum import AUTYPE, DATA_FIELD, KL_TYPE
|
|
from Common.CTime import CTime
|
|
from Common.func_util import kltype_lt_day, str2float
|
|
from KLine.KLine_Unit import CKLine_Unit
|
|
|
|
from .CommonStockAPI import CCommonStockApi
|
|
|
|
|
|
def create_item_dict(data, column_name):
|
|
for i in range(len(data)):
|
|
data[i] = parse_time_column(data[i]) if i == 0 else str2float(data[i])
|
|
return dict(zip(column_name, data))
|
|
|
|
|
|
def parse_time_column(inp):
|
|
# 20210902113000000
|
|
# 2021-09-13
|
|
if len(inp) == 10:
|
|
year = int(inp[:4])
|
|
month = int(inp[5:7])
|
|
day = int(inp[8:10])
|
|
hour = minute = 0
|
|
elif len(inp) == 17:
|
|
year = int(inp[:4])
|
|
month = int(inp[4:6])
|
|
day = int(inp[6:8])
|
|
hour = int(inp[8:10])
|
|
minute = int(inp[10:12])
|
|
elif len(inp) == 19:
|
|
year = int(inp[:4])
|
|
month = int(inp[5:7])
|
|
day = int(inp[8:10])
|
|
hour = int(inp[11:13])
|
|
minute = int(inp[14:16])
|
|
else:
|
|
raise Exception(f"unknown time column from baostock:{inp}")
|
|
return CTime(year, month, day, hour, minute)
|
|
|
|
|
|
def GetColumnNameFromFieldList(fileds: str):
|
|
_dict = {
|
|
"time": DATA_FIELD.FIELD_TIME,
|
|
"date": DATA_FIELD.FIELD_TIME,
|
|
"open": DATA_FIELD.FIELD_OPEN,
|
|
"high": DATA_FIELD.FIELD_HIGH,
|
|
"low": DATA_FIELD.FIELD_LOW,
|
|
"close": DATA_FIELD.FIELD_CLOSE,
|
|
"volume": DATA_FIELD.FIELD_VOLUME,
|
|
"amount": DATA_FIELD.FIELD_TURNOVER,
|
|
"turn": DATA_FIELD.FIELD_TURNRATE,
|
|
}
|
|
return [_dict[x] for x in fileds.split(",")]
|
|
|
|
|
|
class CBaoStock(CCommonStockApi):
|
|
is_connect = None
|
|
|
|
def __init__(self, code, k_type=KL_TYPE.K_DAY, begin_date=None, end_date=None, autype=AUTYPE.QFQ):
|
|
super(CBaoStock, self).__init__(code, k_type, begin_date, end_date, autype)
|
|
|
|
def get_kl_data(self):
|
|
# 天级别以上才有详细交易信息
|
|
if kltype_lt_day(self.k_type):
|
|
if not self.is_stock:
|
|
raise Exception("没有获取到数据,注意指数是没有分钟级别数据的!")
|
|
fields = "time,open,high,low,close"
|
|
else:
|
|
fields = "date,open,high,low,close,volume,amount,turn"
|
|
autype_dict = {AUTYPE.QFQ: "2", AUTYPE.HFQ: "1", AUTYPE.NONE: "3"}
|
|
rs = bs.query_history_k_data_plus(
|
|
code=self.code,
|
|
fields=fields,
|
|
start_date=self.begin_date,
|
|
end_date=self.end_date,
|
|
frequency=self.__convert_type(),
|
|
adjustflag=autype_dict[self.autype],
|
|
)
|
|
if rs.error_code != '0':
|
|
raise Exception(rs.error_msg)
|
|
while rs.error_code == '0' and rs.next():
|
|
yield CKLine_Unit(create_item_dict(rs.get_row_data(), GetColumnNameFromFieldList(fields)))
|
|
|
|
def SetBasciInfo(self):
|
|
rs = bs.query_stock_basic(code=self.code)
|
|
if rs.error_code != '0':
|
|
raise Exception(rs.error_msg)
|
|
code, code_name, ipoDate, outDate, stock_type, status = rs.get_row_data()
|
|
self.name = code_name
|
|
self.is_stock = (stock_type == '1')
|
|
|
|
@classmethod
|
|
def do_init(cls):
|
|
if not cls.is_connect:
|
|
cls.is_connect = bs.login()
|
|
|
|
@classmethod
|
|
def do_close(cls):
|
|
if cls.is_connect:
|
|
bs.logout()
|
|
cls.is_connect = None
|
|
|
|
def __convert_type(self):
|
|
_dict = {
|
|
KL_TYPE.K_DAY: 'd',
|
|
KL_TYPE.K_WEEK: 'w',
|
|
KL_TYPE.K_MON: 'm',
|
|
KL_TYPE.K_5M: '5',
|
|
KL_TYPE.K_15M: '15',
|
|
KL_TYPE.K_30M: '30',
|
|
KL_TYPE.K_60M: '60',
|
|
}
|
|
return _dict[self.k_type]
|