def updateMainContractDict(): '''扫描所有合约数据文件,生成主力合约信息,并写入__DATA_MAIN_CONTRACT_FILENAME,虽然不是网络函数,但也耗时较长''' futurelogger.log("开始扫描所有K线数据文件并生成主力合约数据文件,updateMainContractDict() begins.") commodityList = getCommodityList() mainContractDict = {}#存放主力合约的字典 for commodityCode in commodityList:#遍历所有品种 #现将该品种的所有合约数据一次性读入到theContractDict theContractDict = __getCommodityDataToDict(commodityCode) #按照时间遍历theContractDict中的所有合约,找出主力合约 beginDate = datetime.datetime(__BEGIN_YEAR, 1, 1) endDate = datetime.datetime(__getNowYear(), __getNowMonth(), 28) theDaysList = futuretools.getDaysList(beginDate, endDate) mainContractInTheCommodity = {} lastContractName = None for theDate in theDaysList: contractVolDict = {} #读出该品种所有合约在当天的成交量 for theContractName in theContractDict.keys(): sub = theContractDict[theContractName].getSubscript(theDate) if sub is None: continue contractVolDict[theContractName] = theContractDict[theContractName].getKLine( sub).vol() #若在该品种所有合约中未找到该日期,则略过 if len(contractVolDict) == 0: continue #找出成交量最大的合约,加到mainContractDict[commodityCode]中 maxVol = __MIN_VOL_IN_MAIN_CONTRACT maxVolContractName = "" for theContractName in contractVolDict.keys(): if maxVol < contractVolDict[theContractName]: maxVol = contractVolDict[theContractName] maxVolContractName = theContractName if maxVol == __MIN_VOL_IN_MAIN_CONTRACT: #当天成交量太小的话不算数 continue #把主力合约的时间也记上 if maxVolContractName not in mainContractInTheCommodity.keys(): mainContractInTheCommodity[maxVolContractName] = [theDate, theDate] if lastContractName is not None: theLastContractBeginDate = mainContractInTheCommodity[ lastContractName][0] mainContractInTheCommodity[lastContractName] = [ theLastContractBeginDate, theDate] lastContractName = maxVolContractName theLastContractBeginDate = mainContractInTheCommodity[lastContractName][0] mainContractInTheCommodity[lastContractName] = [theLastContractBeginDate, endDate] mainContractDict[commodityCode] = mainContractInTheCommodity futuretools.writeListToFile(__DATA_MAIN_CONTRACT_FILENAME, mainContractDict) futurelogger.log("扫描所有K线数据文件并生成主力合约数据文件完毕,updateMainContractDict() ends.")
def updateAllAvailableCommodityCode(): '''从新浪接口检测获取所有存在的商品代码,并写入__DATA_COMMODITY_FILENAME,耗时较长,非出现新品种的情况下不要使用''' futurelogger.log("开始从新浪网更新最新的商品代码,updateAllAvailableCommodityCode() begins.") ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' theList = [] for commodityCode in ALPHABET: if __isCommodityExist(commodityCode): theList.append(commodityCode) for commodityCode2 in ALPHABET: if __isCommodityExist(commodityCode + commodityCode2): theList.append(commodityCode + commodityCode2) futuretools.writeListToFile(__DATA_COMMODITY_CODE_FILENAME, theList) futurelogger.log("从新浪网更新最新的商品代码完毕,updateAllAvailableCommodityCode() ends.")
def __establishCommodityDataFromInternet(commodityCode): '''从新浪接口获取所有商品信息,耗时较长,慎用''' commodityCode = commodityCode.upper() for yearAndMonth in __getAvailableDateList(): contractCode = commodityCode + yearAndMonth if contractCode in __MANUAL_MODIFIED_CONTRACT_TUPLE:#手动修改的合约不更新 continue theUrl = __DATA_SOURCE_URL + contractCode theList = __readList2FromInternet(theUrl) if theList is None: continue commodityDir = __getDataDir() + "/" + commodityCode futuretools.mkdirIfNotExist(commodityDir) futuretools.writeListToFile(commodityDir + "/" + commodityCode + yearAndMonth + ".txt", theList)
def reportParamAnalysis( beginYear, endYear, strategy, commodityList, #交易的商品代码列表,默认为所有商品 param1Begin, param1End, param1Step=1, param2Begin=0, param2End=1, param2Step=1, maxHoldDays=60, maxLossRate=10000.0): '''生成参数分析报告''' resultInfo = "" for theParam1 in range(param1Begin, param1End, param1Step): strategy.setParam1(theParam1) if strategy.getParam2() == 0: annuallyInfo = reportAnnually01(beginYear, endYear, strategy, commodityList, False, False, maxHoldDays, maxLossRate) resultInfo += annuallyInfo continue for theParam2 in range(param2Begin, param2End, param2Step): strategy.setParam2(theParam2) annuallyInfo = reportAnnually01(beginYear, endYear, strategy, commodityList, False, False, maxHoldDays, maxLossRate) resultInfo += annuallyInfo filename = __RESULT_DIR + "/" + futuretools.getClassName(strategy) if maxLossRate < 10.0: filename += "_" + format(maxLossRate, "0.1f") + "止损" else: filename += "_无止损" filename += "_参数分析报告.txt" futuretools.writeListToFile(filename, resultInfo, False)
def checkAllDayKLine(): '''检查所有K线的合法性,可接在updateAllDayKLine之后立即调用为佳,本函数耗时较长,慎用''' futurelogger.log("开始检查所有K线数据文件的合法性并将校正过的数据放入verified文件夹,checkAllDayKLine() begins.") infoDict = {} for commodityCode in getCommodityList(): #仅检查主力合约 dataDict = __getCommodityDataToDict(commodityCode, getMainContractDict()[commodityCode].keys()) for contractName in dataDict.keys(): kLineList = dataDict[contractName] info = kLineList.checkAndCorrectData(contractName) infoDict[contractName] = info setDataDirAfterVerified() commodityDir = __getDataDir() + "/" + commodityCode futuretools.mkdirIfNotExist(commodityDir) futuretools.writeListToFile(commodityDir + "/" + contractName + ".txt", kLineList) setDataDirBeforeVerified() futuretools.writeListToFile("../checkReport.txt", infoDict) setDataDirAfterVerified() futurelogger.log("检查所有K线数据文件的合法性并将校正过的数据放入verified文件夹完毕,checkAllDayKLine() ends.")
def reportAnnually01( beginYear, endYear, strategy, commodityList=futurecommodity.getCommodityList(), #交易的商品代码列表,默认为所有商品 isAnnualNeeded=True, #是否需要生成分年度的子报告文件 isTransactionDetailAdded=False, #是否需要在每份年度子报告末尾附上每笔交易记录,需要isAnnualNeeded同时开启方有效 maxHoldDays=60, maxLossRate=10000.0): futurecommodity.setDataDirAfterVerified() if commodityList is None: commodityList = futurecommodity.getCommodityList() endDate = datetime.datetime(endYear, 1, 1) finalProfit = 0.0 finalDuration = 0 finalCount = 0 finalInfo = "" profitPerCommodityDict = {} #存放各品种毛利的字典 durationSumPerCommodityDict = {} #存放各品种持仓日期的字典 transCountPerCommodityDict = {} #存放各品种持仓日期的字典 for commodity in commodityList: profitPerCommodityDict[commodity] = 0.0 durationSumPerCommodityDict[commodity] = 0.0 transCountPerCommodityDict[commodity] = 0 #用于计算收益的几何级数 geometricProfitDict = [] geometricProfitDict.append({}) geometricProfitDict.append(0) for position in __GEOMETRIC_POSITION: geometricProfitDict[0][position] = [1.0, 1.0] while beginYear < endYear: beginDate = datetime.datetime(beginYear, 1, 1) endDate = datetime.datetime(beginYear + 1, 1, 1) tc = futuretrade.TradeCenter(beginDate, endDate, maxHoldDays, maxLossRate) #有1.0止损 for commodity in commodityList: tc.addCommodity(commodity) tc.setStrategy(strategy) transactionDict = tc.trade() profitSumTotal = 0.0 durationSumTotal = 0 transCount = 0 resultInfo = "" for commodity in transactionDict.keys(): profitSumCommodity = 0.0 durationSumCommodity = 0 if len(transactionDict[commodity]) == 0: continue for theTrans in transactionDict[commodity]: profitSumCommodity += theTrans.getProfitRate() durationSumCommodity += theTrans.getDuration() count = len(transactionDict[commodity]) profitSumTotal += profitSumCommodity durationSumTotal += durationSumCommodity profitPerCommodityDict[commodity] += profitSumCommodity durationSumPerCommodityDict[commodity] += durationSumCommodity transCountPerCommodityDict[commodity] += count resultInfo += __formatInfo(commodity, profitSumCommodity, durationSumCommodity, count) transCount += count geometricProfitDict[1] += 1 if transCount == 0: beginYear += 1 continue tempInfo = __formatInfo("汇总", profitSumTotal, durationSumTotal, transCount) resultInfo += "\n" + tempInfo finalInfo += str(beginYear) + "年度" + tempInfo finalProfit += profitSumTotal finalDuration += durationSumTotal finalCount += transCount for position in __GEOMETRIC_POSITION: grossTemp = 1 + profitSumTotal * position netTemp = 1 + (profitSumTotal - __DEFAULT_COST * transCount) * position if grossTemp < 0.0: grossTemp = 0.0 if netTemp < 0.0: netTemp = 0.0 geometricProfitDict[0][position][0] *= grossTemp geometricProfitDict[0][position][1] *= netTemp if isAnnualNeeded is True: if isTransactionDetailAdded is True: resultInfo += "\n详细交易记录附表:\n" + __formatDict(transactionDict) futuretools.writeListToFile( __RESULT_DIR + "/" + str(beginYear) + "年度报告.txt", resultInfo, False) beginYear += 1 filename = (__RESULT_DIR + "/" + futuretools.getClassName(strategy) + "_" + format(strategy.getParam1(), "0>2d") + "_" + format(strategy.getParam2(), "0>2d")) if maxLossRate < 10.0: filename += "_" + format(maxLossRate, "0.1f") + "止损" else: filename += "_无止损" tempInfo = "全交易周期" + __formatInfo("汇总", finalProfit, finalDuration, finalCount, __DEFAULT_COST, geometricProfitDict) finalInfo += "\n" + tempInfo + "\n\n[各品种详情]:\n" for commodity in commodityList: finalInfo += __formatInfo(commodity, profitPerCommodityDict[commodity], durationSumPerCommodityDict[commodity], transCountPerCommodityDict[commodity]) returnInfo = format(filename[filename.rfind("/") + 1:], "<45") + tempInfo filename += "_汇总报告.txt" futuretools.writeListToFile(filename, finalInfo, False) return returnInfo