def test_QA_util_if_trade(self): now = QADate.QA_util_time_now() str_from_today = '%04d-%02d-%02d' % (now.year, now.month, now.day) nDayLeft = 1000 while nDayLeft > 0: toDayIsTradeDay = QADate_trade.QA_util_if_trade(str_from_today) realTradeDay = QADate_trade.QA_util_get_real_date(str_from_today) QADate.QA_util_date_valid(realTradeDay) if toDayIsTradeDay == False: prev_trade_day = QADate_trade.QA_util_get_last_day( str_from_today, -1) realTradeDay = QADate_trade.QA_util_get_real_date( prev_trade_day) self.assertEquals(realTradeDay, toDayIsTradeDay) else: self.assertEquals(realTradeDay, realTradeDay) str_from_today = QADate_trade.QA_util_get_last_day(str_from_today) nDayLeft = nDayLeft - 1 print("okok")
def test_None(self): now = QADate.QA_util_time_now() print(type(now)) today = QADate.QA_util_date_today() print(type(today)) print("okok---> do the task")
def test_QThread_Check_ZJLX_DB_Recs(self): qthread = QThread_Check_ZJLX_DB_Status() #东方财富只提高近100天的数据 #获取近100天的交易日段 dateEnd = QADate.QA_util_date_today() dateEnd = QADate_trade.QA_util_get_real_date(dateEnd) dateStart = QADate_trade.QA_util_get_last_day(dateEnd,100) stockCode = '600004' #qthread.QA_fetch_eastmoney_stock_zjlx(strStockCode = stockCode, strStartDate = dateStart, strEndDate = dateEnd, strFormat='numpy') qthread.QA_fetch_eastmoney_stock_zjlx(str_stock_code=stockCode,strStartDate=dateStart, strEndDate=dateEnd) pass
def QA_statistic_block_data(self): # 🛠 todo 直接使用monogodb 数据库去统计 try: block_list_df = QA_fetch_stock_block() blockNameList = {} block_list_df = block_list_df.set_index(['blockname']) for strIndexBlockName in block_list_df.index: try: dict = blockNameList[strIndexBlockName] dict['count'] = dict['count'] + 1 self.strTaskRunningLog = "正在统计板块{} 股票个数{}".format(strIndexBlockName, dict['count']) except Exception as ee: dictNew = {} dictNew['up'] = 0 #上涨家数 dictNew['even'] = 0 #平盘家数 dictNew['down'] = 0 #下跌家数 dictNew['count'] = 0 #板块股票数 dictNew['upRatio'] = 0.0 #上涨家数比率 dictNew['downRation'] = 0.0 #下跌家数比率 blockNameList[strIndexBlockName] = dictNew #row2 = block_list_df[i] ####################################################################################################### strToday = QADate.QA_util_today_str() strEndDate = QADate_trade.QA_util_get_real_date(date = strToday) strStartDate = QADate_trade.QA_util_get_last_day(date= strEndDate) codeTwoDayPriceeDict = {} stock_list = QA_fetch_stock_list() stock_list_len = len(stock_list) stock_name_count = 0 for aStockCode in stock_list: stock_name_count = stock_name_count + 1 strAcode = aStockCode['code'] strAName = aStockCode['name'] priceTowDay = QA_fetch_stock_day_adv(code=strAcode, start=strStartDate, end=strEndDate) up = None if priceTowDay is not None: priceTowDay.to_qfq() # price_len = len(priceTowDay) # print(priceTowDay) price_len = len(priceTowDay) if price_len == 2: closeSerial = priceTowDay.close # todayPrice = priceTowDay[1].close v1 = closeSerial[0] v2 = closeSerial[1] if v1 < v2: up = True else: up = False codeTwoDayPriceeDict[strAcode] = {'pricetwoday':priceTowDay, 'up':up} if codeTwoDayPriceeDict[strAcode]['up'] is not None and codeTwoDayPriceeDict[strAcode]['up'] == True: self.strTaskRunningLog = "正在获取股票价格 {} {} 上涨 ⬆🔺, 进度{}/{} " \ .format(strAcode, strAName, stock_name_count, stock_list_len) elif codeTwoDayPriceeDict[strAcode]['up'] is not None and codeTwoDayPriceeDict[strAcode]['up'] == False: self.strTaskRunningLog = "正在获取股票价格 {} {} 下跌 ⬇️, 进度{}/{} " \ .format(strAcode, strAName, stock_name_count, stock_list_len) else: self.strTaskRunningLog = "正在获取股票价格 {} {} 和前一天的无法统计️, 进度{}/{} " \ .format(strAcode, strAName, stock_name_count, stock_list_len) ########################################################################################################## len_block_size = len(blockNameList) count = 0 for blockName in blockNameList.keys(): count = count + 1 stocks_in_block = QA_fetch_stock_block_adv(code=None, blockname= blockName) self.strTaskRunningLog = "正在统计板块{} ,进度{}/{}".format(blockName,count,len_block_size) code_list = stocks_in_block.code iCodeLength = len(code_list) iCountForCode = 0 for iCode in code_list: iCountForCode = iCountForCode + 1 try: priceTowDay = codeTwoDayPriceeDict[iCode]['pricetwoday'] upValue = codeTwoDayPriceeDict[iCode]['up'] if priceTowDay is not None: if upValue == True: blockNameList[blockName]['up'] = blockNameList[blockName]['up'] + 1 elif upValue == False: blockNameList[blockName]['down'] = blockNameList[blockName]['down'] + 1 except Exception as ee: strErrorMsg = ee.__str__() print(strErrorMsg) self.strTaskRunningLog = "正在统计板块{} ,进度{}/{} \n 股票 {}, 进度 {}/{}"\ .format(blockName, count, len_block_size, iCode, iCountForCode, iCodeLength) pass #print(stocks_in_block) ####################################################################################################### except Exception as eee: strErrorMsg = eee.__str__() print(strErrorMsg) finally: return blockNameList
def test_mongodb_day_data(self): #读取本地tdx日线数据 到 sqllite数据 #self.oktestLocalTdxDayFileData() #更新股票列表 QA_SU_save_stock_info_tushare() # 只有主版 创业板 中小板, 不包含已经退市的股票 #QA_SU_save_stock_terminated() # 获取退市股票列表 # stock_list = QA_fetch_stock_basic_info_tushare() stock_list.sort(key=lambda k: (k.get('code'))) #stock_list_termined = QA_fetch_stock_terminated() #sorted(stock_list, key='code') curdir = os.getcwd() print("准备读取db🗃文件,目录位置%s" % (curdir + "/tdx_days")) path_for_saved_data = curdir + "/tdx_days" path_for_saved_data = path_for_saved_data.rstrip("\\") isExists = os.path.exists(path_for_saved_data) if isExists == False: print("数据库目录不存在, 请线运行 testLocalTdxDayFileData 测试 ,获取日线数据!💔") #读取通达信数据库文件 saved_sqllite_files = os.listdir(path_for_saved_data) sqllite_file_count = len(saved_sqllite_files) saved_sqllite_files.sort() #检查 Tushare 获取的股票列表 和 通达信保存的股票列表是否一致。 for aSavedFileName in saved_sqllite_files: bFound = False for iRow in stock_list: strCodeInDb = iRow.get('code') strCodeOnFileName = aSavedFileName[2:8] if strCodeInDb == strCodeOnFileName: bFound = True break if bFound == False: if (self.checkFileNameStockType(aSavedFileName) == '上交所A股') or \ (self.checkFileNameStockType(aSavedFileName) == '深交所中小板') or \ (self.checkFileNameStockType(aSavedFileName) == '深交所创业板'): #从退市的股票列表中找 # bIsTerminatedStock = False # for iTerminatedStock in stock_list_termined: # terminatedCode = iTerminatedStock.get('code') # strCode0 = aSavedFileName[2:8] # if terminatedCode == strCode0: # bIsTerminatedStock = True # continue #if bIsTerminatedStock == True: # continue # hard code 已经退市的股票 if aSavedFileName[2:8] == '600432' or \ aSavedFileName[2:8] == '600806': continue print("💔通达信数据下载不全, 没有找到 股票代码 ", aSavedFileName) self.fail( "💔通达信数据下载不全, 没有找到 股票代码 {}".format(aSavedFileName)) break else: continue for iIndexSQLLiteFile in range(sqllite_file_count): strSavedFileName = saved_sqllite_files[iIndexSQLLiteFile] strCodeType = self.checkFileNameStockType(strSavedFileName) if strCodeType == '上交所A股' or \ strCodeType == '深交所中小板' or \ strCodeType == '深交所创业板': pass else: continue sqlLiteFile = path_for_saved_data + '/' + strSavedFileName print("⛓⚙️🔬📈📉️读取SQLLite文件{}比对数据".format(sqlLiteFile)) conn = sqlite3.connect(sqlLiteFile) cur = conn.cursor() result = cur.execute('''select * from stock_days''') allrows = result.fetchall() for arow in allrows: strCode = strSavedFileName[2:8] intDate = arow[0] strDate = QAUtilDate.QA_util_date_int2str(intDate) if strCodeType == '上交所A股' or \ strCodeType == '深交所中小板' or \ strCodeType == '深交所创业板': # if isSz == True and isStartWith000 == True : qaDataStructDay = QA.QA_quotation( code=strCode, start=strDate, end=strDate, frequence=FREQUENCE.DAY, market=MARKET_TYPE.STOCK_CN, source=DATASOURCE.MONGO, output=None) else: print("证券 类型不明确!") break #对比其他 指数 基金 报价 #print(type(qaDataStructDay)) try: vhigh = (qaDataStructDay.high).item() vlow = (qaDataStructDay.low).item() vopen = (qaDataStructDay.open).item() vclose = (qaDataStructDay.close).item() except: print("error ") print(arow) print("数据库读取记录错误") #(qaDataStructDay.to_list()) fopen = (arow[1] / 100.0) fhigh = (arow[2] / 100.0) flow = (arow[3] / 100.0) fclose = (arow[4] / 100.0) bShowErro = True if fopen != vopen: print(arow) print(fopen, " 开盘价不匹配 ", vopen) if abs(fopen - vopen) > 10.0: self.fail('误差超过范围') if fhigh != vhigh: print(arow) print(fhigh, " 最高价不匹配 ", vhigh) if abs(fopen - vopen) > 10.0: self.fail('误差超过范围') if flow != vlow: print(arow) print(flow, " 最低价不匹配 ", vlow) if abs(fopen - vopen) > 10.0: self.fail('误差超过范围') if fclose != vclose: print(arow) print(fclose, " 收盘价不匹配 ", vclose) if abs(fopen - vopen) > 10.0: self.fail('误差超过范围') # self.assertEqual(fopen, vopen) # self.assertEqual(fhigh, vhigh) # self.assertEqual(flow, vlow) # self.assertEqual(fclose, vclose) # todo 🛠 总是有小数点误差,不能简单的用 assertEqual 去比较, 要允许一定的误差。。。 cur.close() conn.close() #获取改天的数据对比 pass
def setUp(self): print('Get the free stock data from wstock.net ') #获取 下载路径的特殊值 url = "http://www.wstock.net/wstock/inc/wstockV2.js" #print(url) user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)' req = urllib.request.Request( url, headers={ 'User-Agent': 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)' }) response = urllib.request.urlopen(req) content = response.read() #print(type(content)) #print(content) strings = content.decode("utf-8", "ignore") string_lines = strings.split("\r\n") for line in string_lines: #print(type(line)) #var M_SHSZ_PATH="4T1IWc2q"; if line.startswith("var M_SHSZ_PATH"): print(line) variables = line.split("=") string_of_path_v = variables[1] print(string_of_path_v) real_value_password = string_of_path_v.lstrip("\"") real_value_password = real_value_password.rstrip("\";") print(real_value_password) #http://www.wstock.net/wstock/download/4T1IWc2q/wss0502r.zip url2 = "http://www.wstock.net/wstock/download/%s/wss%sr.zip" now = QADate.QA_util_time_now() str_from_today = '%04d-%02d-%02d' % (now.year, now.month, now.day) toDayIsTradeDay = QADate_trade.QA_util_if_trade(str_from_today) nowTimeIsTrading = QADate_trade.QA_util_if_tradetime(now) #todo QADate_trade.QA_util_if_before_today_tradetime 返回是否是一天开盘前 #todo QADate_trade.QA_util_if_after_today_tradetime 返回是否是一天收盘后 _time1 = datetime.datetime.strptime( str(now)[0:19], '%Y-%m-%d %H:%M:%S') if _time1.hour in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]: toDayIsBeforeOpen = True else: toDayIsBeforeOpen = False prev_trade_day = "" if toDayIsTradeDay == False: prev_trade_day = QADate_trade.QA_util_get_real_date(str_from_today) # 今天不是交易日,往前移一天 print("非交易日,下载前一天交易日 %s" % (prev_trade_day)) elif nowTimeIsTrading == True or toDayIsBeforeOpen == True: prev_trade_day = QADate_trade.QA_util_get_real_date(str_from_today) # 当天交易时段无法下载今天的数据,往前移一天 prev_trade_day = QADate_trade.QA_util_get_last_day(prev_trade_day) print("交易时间,下载前一天交易日 %s" % (prev_trade_day)) else: prev_trade_day = str_from_today print("下载今天交易日 %s" % (prev_trade_day)) self.test_day_k_line_dates = [] self.test_day_k_line_dad_file_name = [] dayLeft = 1 # 下载5天之前的数据 while dayLeft > 0: str_month = prev_trade_day[5:7] str_day = prev_trade_day[8:10] url_data = "http://www.wstock.net/wstock/download/%s/wss%s%sr.zip" % ( real_value_password, str_month, str_day) print(url_data) #下载文件 local_file_name = "wss%s%sr.zip" % (str_month, str_day) urllib.request.urlretrieve(url_data, local_file_name, Schedule) #解压缩文件 zfile = zipfile.ZipFile(local_file_name, 'r') for filename in zfile.namelist(): data = zfile.read(filename) file = open(filename, 'w+b') file.write(data) file.close() self.test_day_k_line_dad_file_name.append(filename) strTestDate = "%04d-%s-%s" % (now.year, str_month, str_day) self.test_day_k_line_dates.append(strTestDate) #删除zip文件 , 防止误删,暂不实现 prev_trade_day = QADate_trade.QA_util_get_last_day(prev_trade_day) dayLeft = dayLeft - 1 pass
def n0_test_QAAccount_class(self): # 测试流程 获取 美康生物 300439 的走势 从 2017年10月01日开始 到 2018年 4月30日 # test_stock_code = '300439' stock_price_list = QA.QA_fetch_stock_day(code=test_stock_code, start='2017-10-01', end='2018-04-30') #buy_list = [] print(stock_price_list) print("---------开始测试买入------------") #price_list_size = stock_price_list.size # 生成随机数种子 rnd.seed(QA.QA_util_time_now().timestamp()) Account = QA.QA_Account() B = QA.QA_BacktestBroker() for aday_stock_price in stock_price_list: stock_code = aday_stock_price[0] price_open = aday_stock_price[1] price_high = aday_stock_price[2] price_low = aday_stock_price[3] price_close = aday_stock_price[4] stock_volume = aday_stock_price[5] stock_turn = aday_stock_price[6] stock_timestamp = aday_stock_price[7] # print(type(stock_timestamp)) dt = QADate.QA_util_pands_timestamp_to_datetime(stock_timestamp) date_time_to_buy = QADate.QA_util_datetime_to_strdatetime(dt) dt = QADate.QA_util_to_datetime(date_time_to_buy) if price_low != price_high: price_diff = (price_high - price_low) self.assertTrue(price_diff >= 0, "最高价一定是非负数") rand_value = rnd.random() buy_price = price_low + price_diff * rand_value print("{} 申报买入的成交价格 {}".format(dt, buy_price)) # 每天随机在开盘价格和收盘价格直接买入 Order = Account.send_order( code=test_stock_code, price=buy_price, amount=100, money=Account. cash_available, # 全仓买入, AMOUNT_MODEL.BY_AMOUNT 忽略该参数 time=date_time_to_buy, towards=QA.ORDER_DIRECTION.BUY, order_model=QA.ORDER_MODEL.LIMIT, amount_model=QA.AMOUNT_MODEL.BY_AMOUNT) print('ORDER的占用资金: {}'.format((Order.amount * Order.price) * (1 + Account.commission_coeff))) print('账户剩余资金 :{}'.format(Account.cash_available)) # ?? cash_available = Account.cash_available print(cash_available) rec_mes = B.receive_order(QA.QA_Event(order=Order)) print(rec_mes) Account.receive_deal(rec_mes) knock_down_price = rec_mes['body']['order']['price'] bid_price = round(buy_price, 2) print("{} 获取订单的价格 {}".format(dt, buy_price)) self.assertEqual(knock_down_price, bid_price) print('账户的可用资金 {}'.format(Account.cash_available)) print('-----------------------------------------------')
def test_BuyAndSell(self): # 测试买卖事件 # 测试流程, # 随机选中一组股票 # 随机选中几个交易日 (只测试当前日期) # 随机卖出 # 随机买入 # 发送订单 # 从队列中取回订单 # 比较 codeCount = 10 codeList = QARandom.QA_util_random_with_zh_stock_code(codeCount) # print(codeList) # { code: QA_DataStruct_Stock_day } # 如果代码不存在 则 code:None codeForDate = {} for codeIndex in range(0, codeCount): aStockDataStructDay = QA.QA_fetch_stock_day_adv( codeList[codeIndex]) codeForDate[codeList[codeIndex]] = aStockDataStructDay # print(codeForDate) str = QADate.QA_util_today_str() timestamp = QADate.QA_util_to_datetime(str) account = QA.QA_Account(strategy_name="TEST策略", user_cookie=None) orderList = [] for a_stock_code in codeForDate.keys(): anOrder = account.send_order( code=a_stock_code, amount=100, time=timestamp, towards=1, price=8.8, order_model=QA.ORDER_MODEL.LIMIT, amount_model=QA.AMOUNT_MODEL.BY_AMOUNT) orderList.append(anOrder) orderQueue = account.get_orders() print(orderQueue) self.assertEqual(len(orderQueue.queue_df), codeCount) orderList2 = [] print(orderQueue.queue_df) for orderId in orderQueue.queue_df.index: anOrder2 = orderQueue.query_order(orderId) orderList2.append(anOrder2) self.assertEqual(len(orderList), len(orderList2)) orderCount = len(orderList) for i in range(orderCount): order_01 = orderList[i] order_02 = orderList2[i] # 总是不正确 #b = order_01 is order_02 #b = order_01 == order_02 #b = (order_01.__dict__ == order_02.__dict__) dict1 = order_01.__dict__ for key in dict1.keys(): v1 = order_01.__dict__[key] v2 = order_02.__dict__[key] if v1 != v2: print(key) print(v1) print(v2) self.fail("订单数据不正确") # todo 继续研究为何不正确 #self.assertEqual(order_01, order_02) pass
def QA_count_eastmoney_stock_xjlc_record_count_by_aggregate( self, collections=DATABASE.eastmoney_stock_zjlx): #codeArrayList = QA_util_code_tolist(str_stock_code_list) sort = {'$sort': {'stock_code': 1, 'date': 1}} #按照count对应的值得降序排序 group = { '$group': { '_id': '$stock_code', 'first_date': { '$first': '$date' }, 'last_date': { '$last': '$date' }, 'total_num': { '$sum': 1 } } } pipeline = [group, sort] cursor = collections.aggregate([{ '$sort': { 'stock_code': 1, 'date': 1 } }, { '$group': { '_id': '$stock_code', 'first_date': { '$first': '$date' }, 'last_date': { '$last': '$date' }, 'total_num': { '$sum': 1 } } }]) items = [item for item in cursor] def takeId_sort(elem): return elem['_id'] items.sort(key=takeId_sort) strToday = QADate.QA_util_today_str() strLastTradeDate = QADate_trade.QA_util_get_real_date(strToday) strLastTradeDate = QADate_trade.QA_util_get_last_day( strLastTradeDate) #网页版资金流向只更新到前一天 #比较日期 yesterTradeDayInt = QADate.QA_util_date_str2int(strLastTradeDate) for item in items: lastDayIntInDB = QADate.QA_util_date_str2int(item['last_date']) if lastDayIntInDB < yesterTradeDayInt: item['need_update'] = 'Yes' else: item['need_update'] = 'No' #map( lambda aRecDict: aRecDict['need_update'] = (aRecDict['last_date'] == strLastTradeDate) , items) # #map( lambda aRecDict: (aRecDict['need_update'] = (aRecDict['last_date'] == strLastTradeDate)) , items) return items
def test_QA_util(self): now = QADate.QA_util_time_now() today = QADate.QA_util_date_today() self.assertEquals(today.day, now.day)
def test_mongodb_day_data(self): #读取本地 sqllite 数据 curdir = os.getcwd() print("📊准备读取📝db🗃文件,目录位置📂%s" % (curdir + "/tdx_days")) path_for_saved_data = curdir + "/tdx_days" path_for_saved_data = path_for_saved_data.rstrip("\\") isExists = os.path.exists(path_for_saved_data) if isExists == False: print("数据库目录不存在, 请线运行 testLocalTdxDayFileData 测试 ,获取日线数据!💔") #读取通达信数据库文件 saved_sqllite_file = os.listdir(path_for_saved_data) sqllite_file_count = len(saved_sqllite_file) saved_sqllite_file.sort() for iIndexSQLLiteFile in range(sqllite_file_count): sqlLiteFile = path_for_saved_data + '/' + saved_sqllite_file[ iIndexSQLLiteFile] print("📝⛓⚙️🔬📈📉📊️读取SQLLite文件{}比对数据".format(sqlLiteFile)) conn = sqlite3.connect(sqlLiteFile) cur = conn.cursor() result = cur.execute('''select * from stock_days''') allrows = result.fetchall() for arow in allrows: print(arow) strCode = saved_sqllite_file[iIndexSQLLiteFile] isSz = strCode.startswith('sh') strCode = strCode[2:8] isStartWith000 = strCode.startswith('000') intDate = arow[0] strDate = QAUtilDate.QA_util_date_int2str(intDate) if isSz == True and isStartWith000 == True: qaDataStructDay = QA.QA_quotation( code=strCode, start=strDate, end=strDate, frequence=FREQUENCE.DAY, market=MARKET_TYPE.INDEX_CN, source=DATASOURCE.MONGO, output=None) else: qaDataStructDay = QA.QA_quotation( code=strCode, start=strDate, end=strDate, frequence=FREQUENCE.DAY, market=MARKET_TYPE.STOCK_CN, source=DATASOURCE.MONGO, output=None) #print(type(qaDataStructDay)) vhigh = (qaDataStructDay.high).item() vlow = (qaDataStructDay.low).item() vopen = (qaDataStructDay.open).item() vclose = (qaDataStructDay.close).item() #(qaDataStructDay.to_list()) fopen = (arow[1] / 100.0) fhigh = (arow[2] / 100.0) flow = (arow[3] / 100.0) fclose = (arow[4] / 100.0) self.assertEqual(fopen, vopen) self.assertEqual(fhigh, vhigh) self.assertEqual(flow, vlow) self.assertEqual(fclose, vclose) # todo 🛠 总是有小数点误差,不能简单的用 assertEqual 去比较, 要允许一定的误差。。。 cur.close() conn.close() #获取改天的数据对比 pass