class SNService(object): K_NET_BASE = "http://stock.finance.sina.com.cn/usstock/api/json_v2.php/US_MinKService.getDailyK?" \ "symbol=%s&___qn=3n" TIME_OUT = (10, 60) def __init__(self): self.storeservice = MysqlService() def get_history_data(self,code,start, days): url = SNService.K_NET_BASE % code resp = requests.get(url,timeout=SNService.TIME_OUT) kl_pd = SNUSParser(code,start,resp.json()).df if kl_pd is not None and len(kl_pd) > 0: table = 'ft_kline' tindex = self.storeservice.find_tindex(code, 'hk') if tindex != -1: table += ('_' + str(tindex)) #table = 'ft_kline_1_1' lastdate = kl_pd['time_key'][len(kl_pd)-1] self.storeservice.insert_many(table, kl_pd, 'append') print(lastdate) return lastdate else: return None
class TXService(object): K_NET_BASE = "http://ifzq.gtimg.cn/appstock/app/%sfqkline/get?p=1¶m=%s,day,,,%d," \ "qfq&_appName=android&_dev=%s&_devId=%s&_mid=%s&_md5mid=%s&_appver=4.2.2&_ifChId=303&_screenW=%d" \ "&_screenH=%d&_osVer=%s&_uin=10000&_wxuin=20000&__random_suffix=%d" K_DEV_MODE_LIST = [ "A0001", "OPPOR9", "OPPOR9", "VIVOX5", "VIVOX6", "VIVOX6PLUS", "VIVOX9", "VIVOX9PLUS" ] # 预先设置模拟手机请求的os version K_OS_VERSION_LIST = ["4.3", "4.2.2", "4.4.2", "5.1.1"] def __init__(self): self.storeservice = MysqlService() def get_history_data(self, code, days): dev_mod = random_from_list(TXService.K_DEV_MODE_LIST) os_ver = random_from_list(TXService.K_OS_VERSION_LIST) width = 1080 height = 1920 market = 'us' sub_market = '.oq' symbol = 'TSLA' cuid = create_random_with_num_low(40) cuid_md5 = md5_from_binary(cuid) random_suffix = create_random_with_num(5) url = TXService.K_NET_BASE % ( \ market, market+symbol+sub_market, days, \ dev_mod, cuid, cuid, cuid_md5, width, height, os_ver, int(random_suffix, 10)) resp = requests.get(url) kl_pd = TXParser('us', code, '.oq', resp.json()).df if kl_pd is not None and len(kl_pd) > 0: table = 'ft4_kline' tindex = self.storeservice.find_tindex(code, 'hk') if tindex != -1: table += ('_' + str(tindex)) table = 'ft_kline_1_1' lastdate = kl_pd['time_key'][len(kl_pd) - 1] self.storeservice.insert_many(table, kl_pd, 'append') print(lastdate) return lastdate return None
class LF(object): def __init__(self, quote_ctx): self.ctx = quote_ctx self.storeservice = MysqlService() def is_holiday(self, market, date): ''' 判断是否为交易日,返回True or False ''' ret_code, ret_data = self.get_trading_days(market) if ret_code == RET_ERROR: print(ret_data) exit() return date not in ret_data def get_trading_days(self, market, start_date=None, end_date=None): ''' 功能: 获取交易日 Parameters: market – 市场类型,futuquant.common.constsnt.Market start_date – 起始日期 end_date – 结束日期 Returns: 成功时返回(RET_OK, data),data是字符串数组;失败时返回(RET_ERROR, data),其中data是错误描述字符串 ''' ret_code, ret_data = self.ctx.get_trading_days(market=market) if ret_code == RET_ERROR: print(ret_data) exit() # print("TRADING DAYS") # for x in ret_data: # print(x) return ret_code, ret_data def get_stock_basicinfo(self, market, stock_type=SecurityType.STOCK): ''' 功能: 获取指定市场中特定类型的股票基本信息 Parameters: market – 市场类型,futuquant.common.constsnt.Market stock_type – 股票类型, futuquant.common.constsnt.SecurityType Returns: (ret_code, content) ret_code 等于RET_OK时, content为Pandas.DataFrame数据, 否则为错误原因字符串, 数据列格式如下 参数 类型 说明 code str 股票代码 name str 名字 lot_size int 每手数量 stock_type str 股票类型,参见SecurityType stock_child_type str 涡轮子类型,参见WrtType stock_owner str 正股代码 listing_date str 上市时间 stock_id int 股票id ''' ret_code, ret_data = self.ctx.get_stock_basicinfo(market, stock_type) if ret_code == RET_ERROR: print(ret_data) exit() table = 'ft_stock_basicinfo' self.storeservice.insert_many(table, ret_data, 'append') return ret_code, ret_data def get_multiple_history_kline(self, codelist=[], start=None, end=None, ktype=KLType.K_DAY, autype=AuType.QFQ): """ 功能: 获取多只股票的历史k线数据 Parameters: codelist – 股票代码列表,list或str。例如:[‘HK.00700’, ‘HK.00001’],’HK.00700,SZ.399001’ start – 起始时间 end – 结束时间 ktype – k线类型,参见KLType autype – 复权类型,参见AuType Returns: 成功时返回(RET_OK, [data]),data是DataFrame数据, 数据列格式如下 参数 类型 说明 code str 股票代码 time_key str k线时间 open float 开盘价 close float 收盘价 high float 最高价 low float 最低价 pe_ratio float 市盈率 turnover_rate float 换手率 volume int 成交量 turnover float 成交额 change_rate float 涨跌幅 last_close float 昨收价 失败时返回(RET_ERROR, data),其中data是错误描述字符串 """ ret_code, ret_data = self.ctx.get_multiple_history_kline( codelist, start, end, ktype, autype) print(ret_data) if ret_code == RET_ERROR: print(ret_data) #exit() # print(ret_data) table = 'ft_kline' for item in ret_data: self.storeservice.insert_many(table, item, 'append') return ret_code, ret_data def get_history_kline(self, code, tindex=None, start=None, end=None, ktype=KLType.K_DAY, autype=AuType.QFQ, fields=KL_FIELD.ALL): ''' 获取历史K线 :param code: 股票代码 :param start: 开始时间,string; YYYY-MM-DD;为空时取去当前时间; :param end: 结束时间,string; YYYY-MM-DD;为空时取当前时间; :param ktype: k线类型,默认为日K :param autype: 复权类型,string;”qfq”-前复权,”hfq”-后复权,None-不复权,默认为”qfq” fields: 单个或多个K线字段类型,指定需要返回的数据 KL_FIELD.ALL or [KL_FIELD.DATE_TIME, KL_FIELD.OPEN],默认为KL_FIELD.ALL 开始结束时间按照闭区间查询,时间查询以k线时间time_key作为比较标准。即满足 start<=Time_key<=end条件的k线作为返回内容,k线时间time_key的设定标准在返回值中说明 :return: ret_code失败时,ret_data返回为错误描述字符串; 客户端无符合条件数据时,ret_code为成功,返回None; 正常情况下返回K线数据为一个DataFrame包含: code: 股票代码;string time_key: K线时间 string “YYYY-MM-DD HH:mm:ss” open: 开盘价;double high: 最高价;double close: 收盘价;double low: 最低价;double pe_ratio: 市盈率;double turnover_rate: 换手率;double volume: 成交量;long turnover : 成交额;double change_rate: 涨跌幅;double last_close float 昨收价 对于日K线,time_key为当日时间具体到日,比如说2016-12-23日的日K,K线时间为”2016-12-23 00:00:00” 对于周K线,12月19日到12月25日的周K线,K线时间time_key为” 2016-12-19 00:00:00” 对于月K线,12月的月K线时间time_key为” 2016-12-01 00:00:00”,即为当月1日时间 对于分K线,time_key为当日时间具体到分,例如, 分K类型 覆盖时间举例 1分K 覆盖9:35:00到9:35:59的分K,time_key为”2016-12-23 09:36:00” 5分K 覆盖10:05:00到10:09:59的分K,time_key为”2016-12-23 10:10:00” 15分K 覆盖10:00:00到10:14:59的分K,time_key为”2016-12-23 10:15:00” 30分K 覆盖10:00:00到10:29:59的分K,time_key为”2016-12-23 10:30:00” 60分K 覆盖10:00:00到10:59:59的分K,time_key为”2016-12-23 11:00:00” 失败情况: 股票代码不合法 PLS接口返回错误 US.AAPL返回为空,需要订阅吗? ''' ret_code, ret_data = self.ctx.get_history_kline( code, start, end, ktype, autype, fields) if ret_code == RET_ERROR: print(ret_data) #exit() #print(ret_data) lastdate = None if not isinstance(ret_data, str): if len(ret_data) > 0: if tindex == None: if ktype == KLType.K_DAY: table = 'ft_kline' tindex = self.storeservice.find_tindex(code, 'hk') if tindex != -1: table += ('_' + str(tindex)) elif ktype == KLType.K_5M: table = 'ft_5M' if ktype == KLType.K_5M: tindex = self.storeservice.find_tindex( code, 'hk_5m') if tindex != -1: table += ('_' + str(tindex)) else: table = 'ft_1M' if ktype == KLType.K_1M: tindex = self.storeservice.find_tindex( code, 'hk_1m') if tindex != -1: table += ('_' + str(tindex)) else: if ktype == KLType.K_DAY: table = 'ft_kline' table += ('_' + str(tindex)) elif ktype == KLType.K_5M: table = 'ft_5M' table += ('_' + str(tindex)) else: table = 'ft_1M' table += ('_' + str(tindex)) lastdate = ret_data['time_key'][len(ret_data) - 1] self.storeservice.insert_many(table, ret_data, 'append') return ret_code, ret_data, lastdate def get_autype_list(self, code_list): '''获取复权因子 :param code_list: 股票代码列表,例如,HK.00700,US.AAPL :return: ret_code失败时,ret_data返回为错误描述字符串; 客户端无符合条件数据时,ret_code为成功,ret_data返回None; 正常情况下,ret_data为一个dataframe,其中包括: code:股票代码;string,例如: ”HK.00700”,“US.AAPL” ex_div_date:除权除息日;string,格式YYYY-MM-DD split_ratio:拆合股比例; double,例如,对于5股合1股为1/5,对于1股拆5股为5/1 per_cash_div:每股派现;double per_share_div_ratio:每股送股比例; double per_share_trans_ratio:每股转增股比例; double allotment_ratio:每股配股比例;double allotment_price:配股价;double stk_spo_ratio:增发比例;double stk_spo_price :增发价格;double forward_adj_factorA:前复权因子A;double forward_adj_factorB:前复权因子B;double backward_adj_factorA:后复权因子A;double backward_adj_factorB:后复权因子B;double 返回数据中不一定包含所有codelist中的代码,调用方自己需要检查,哪些股票代码是没有返回复权数据的,未返回复权数据的股票说明没有找到相关信息。 复权价格 = 复权因子A * 价格 + 复权因子B 失败情况: 1. Codelist中股票代码不合法 2. 客户端内部或网络错误 ''' ret_code, ret_data = self.ctx.get_autype_list(code_list) if ret_code == RET_ERROR: print(ret_data) #exit() #print(ret_data) table = 'ft_autype' self.storeservice.insert_many(table, ret_data, 'append') return ret_code, ret_data @rate_limit(FREQ.GET_MARKET_SNAPSHOT) def get_market_snapshot(self, code_list): ''' 功能:获取市场快照 :param code_list: 股票列表,限制最多200只股票 :return: ret_code失败时,ret_data返回为错误描述字符串; 客户端无符合条件数据时,ret_code为成功,ret_data返回None; 正常情况下,ret_data为一个dataframe,其中包括: code :股票代码;string update_time: 更新时间(yyyy-MM-dd HH:mm:ss);string last_price : 最新价格;float open_price: 今日开盘价;float high_price: 最高价格;float low_price: 最低价格;float prev_close_price: 昨收盘价格;float volume: 成交数量; long turnover: 成交金额;float turnover_rate: 换手率;float suspension: 是否停牌(True表示停牌);bool listing_date : 上市日期 (yyyy-MM-dd);string circular_market_val: 流通市值;float total_market_val: 总市值;float wrt_valid: 是否是窝轮;bool wrt_conversion_ratio: 换股比率;float wrt_type: 窝轮类型;1=认购证 2=认沽证 3=牛证 4=熊证 string wrt_strike_price: 行使价格;float wrt_maturity_date: 格式化窝轮到期时间; string wrt_end_trade: 格式化窝轮最后交易时间;string wrt_code: 窝轮对应的正股;string wrt_recovery_price: 窝轮回收价;float wrt_street_vol: 窝轮街货量;float wrt_issue_vol: 窝轮发行量;float wrt_street_ratio: 窝轮街货占比;float wrt_delta: 窝轮对冲值;float wrt_implied_volatility: 窝轮引伸波幅;float wrt_premium: 窝轮溢价;float lot_size:每手股数;int issued_Shares:发行股本;int net_asset:资产净值;int net_profit:净利润;int earning_per_share: 每股盈利;float outstanding_shares:流通股本;int net_asset_per_share:每股净资产;float ey_ratio:收益率;float pe_ratio:市盈率;float pb_ratio:市净率;float price_spread : 当前摆盘价差亦即摆盘数据的买档或卖档的相邻档位的报价差;float 返回DataFrame,包含上述字段 窝轮类型 wrt_type,(字符串类型): 窝轮类型 标识 “CALL” 认购证 “PUT” 认沽证 “BULL” 牛证 “BEAR” 熊证 “N/A” 未知或服务器没相关数据 返回数据量不一定与codelist长度相等, 用户需要自己判断 调用频率限制: 5s一次 失败情况: Codelist中股票代码不合法 Codelist长度超过规定数量 客户端内部或网络错误 ''' ret_code, ret_data = self.ctx.get_market_snapshot(code_list) if ret_code == RET_ERROR: print(ret_data) exit() #print(ret_data) table = 'ft_market_snapshot' self.storeservice.insert_many(table, ret_data, 'append') return ret_code, ret_data @rate_limit(FREQ.GET_PLATE_STOCK) def get_plate_stock(self, plate_code): ''' 功能: 获取板块下的股票列表 :param plate_code: 板块代码, string, 例如,”SH.BK0001”,”SH.BK0002”,先利用获取子版块列表函数获取子版块代码 :return: ret == RET_OK 返回pd dataframe数据,data.DataFrame数据, 数据列格式如下 ret != RET_OK 返回错误字符串 参数 类型 说明 code str 股票代码 lot_size int 每手股数 stock_name str 股票名称 stock_owner str 所属正股的代码 stock_child_type str 股票子类型,参见WrtType stock_type str 股票类型,参见SecurityType list_time str 上市时间 stock_id int 股票id ''' ret_code, ret_data = self.ctx.get_plate_stock(plate_code) if ret_code == RET_ERROR: print(ret_data) exit() # print(ret_data) table = 'ft_plate_stock' self.storeservice.insert_many(table, ret_data, 'append') return ret_code, ret_data @rate_limit(FREQ.GET_PLATE_LIST) def get_plate_list(self, market, plate_class=Plate.ALL): ''' 功能: 获取板块集合下的子板块列表 :param market: 市场标识,注意这里不区分沪,深,输入沪或者深都会返回沪深市场的子板块(这个是和客户端保持一致的) :param plate_class: 板块分类, string; 例如,”ALL”, “INDUSTRY” 板块分类类型 ,(字符串类型): 板块分类 标识 “ALL” 所有板块 “INDUSTRY” 行业分类 “REGION” 地域分类 “CONCEPT” 概念分类 :return: ret == RET_OK 返回pd Dataframe数据,数据列格式如下 ret != RET_OK 返回错误字符串 参数 类型 说明 code str 股票代码 plate_name str 板块名字 plate_id str 板块id ''' ret_code, ret_data = self.ctx.get_plate_list(market, plate_class) if ret_code == RET_ERROR: print(ret_data) exit() #print(ret_data) table = 'ft_plate_list' self.storeservice.insert_many(table, ret_data, 'append') return ret_code, ret_data def get_global_state(self): ''' 功能:获取牛牛程序全局状态 :return: 返回: (ret, data) ret == RET_OK data为包含全局状态的字典,含义如下 ret != RET_OK data为错误描述字符串 key value类型 说明 market_sz str 深圳市场状态,参见MarketState market_us str 美国市场状态,参见MarketState market_sh str 上海市场状态,参见MarketState market_hk str 香港市场状态,参见MarketState market_hkfuture str 香港期货市场状态,参见MarketState server_ver str FutuOpenD版本号 trd_logined str ‘1’:已登录交易服务器,‘0’: 未登录交易服务器 qot_logined str ‘1’:已登录行情服务器,‘0’: 未登录行情服务器 timestamp str 当前格林威治时间戳 ''' ret_code, ret_data = self.ctx.get_global_state() if ret_code == RET_ERROR: print(ret_data) exit() return ret_code, ret_data @clock() def get_multi_points_history_kline(self, code_list, dates, fields=KL_FIELD.ALL, ktype=KLType.K_DAY): ''' 功能: 获取多支股票多个时间点的指定数据列 Parameters: code_list – 单个或多个股票 ‘HK.00700’ or [‘HK.00700’, ‘HK.00001’] dates – 单个或多个日期 ‘2017-01-01’ or [‘2017-01-01’, ‘2017-01-02’],最多5个时间点 fields – 单个或多个数据列 KL_FIELD.ALL or [KL_FIELD.DATE_TIME, KL_FIELD.OPEN] ktype – K线类型 autype – 复权类型 no_data_mode – 指定时间为非交易日时,对应的k线数据取值模式,参见KLNoDataMode Returns: (ret, data) ret == RET_OK 返回pd dataframe数据,固定表头包括’code’(代码) ‘time_point’(指定的日期) ‘data_status’ (KLDataStatus)。数据列格式如下 ret != RET_OK 返回错误字符串 参数 类型 说明 code str 股票代码 time_point str 请求的时间 data_status str 数据点是否有效,参见KLDataStatus time_key str k线时间 open float 开盘价 close float 收盘价 high float 最高价 low float 最低价 pe_ratio float 市盈率 turnover_rate float 换手率 volume int 成交量 turnover float 成交额 change_rate float 涨跌幅 last_close float 昨收价 ''' ret_code, ret_data = self.ctx.get_multi_points_history_kline( code_list, dates, fields, ktype) if ret_code == RET_ERROR: print(ret_data) exit() print(ret_data) return ret_code, ret_data