def handleBuyList(tradingDate, buyList, dailyQuote, usableVol, stockHoldDF, stockTradeDF): vol = usableVol / len(buyList) #print('vol:'+vol) partChangePCT = 0 for innerCode in buyList: dailyQuoteRow = SourceDataDao.select_by_inner_code_and_date( dailyQuote, tradingDate, innerCode) #print('innerCode:'+str(innerCode)) #print(dailyQuoteRow) turnoverValue = dailyQuoteRow["TurnoverValue"] turnoverVolume = dailyQuoteRow["TurnoverVolume"] closePrice = dailyQuoteRow["ClosePrice"] cost = turnoverValue / turnoverVolume changePCT = NumUtil.get_change_pct(cost, closePrice, 2) realChangePCT = changePCT * vol / 100.0 partChangePCT = partChangePCT + realChangePCT hold = StockHoldEntity.StockHoldEntity(tradingDate, innerCode, vol) trade = StockTradeEntityBak.StockTradeEntity(tradingDate, innerCode, 1, vol, cost, changePCT, realChangePCT) stockHoldDF.setdefault(innerCode, hold) #TODO trade return partChangePCT
def calculateDailyMV(currHoldSet, capitalEntity, dailyQuote, tradingDate, stockHoldDailyList, initialMV): usableCach = capitalEntity.get_usable_cash() dailyMV = 0 for innerCode in currHoldSet: dailyQuoteRow = SourceDataDao.select_by_inner_code_and_date( dailyQuote, tradingDate, innerCode) stockHoldEntity = currHoldSet[innerCode] vol = stockHoldEntity.vol # print('innerCode:' + str(innerCode)) closePrice = dailyQuoteRow["ClosePrice"] mv = vol * closePrice dailyMV += mv #stockHoldEntity.setClosePrice(closePrice) #stockHoldEntity.setMV(mv) cost = stockHoldEntity.cost profit = (closePrice - cost) * vol holdDict = { 'tradingDate': tradingDate, 'innerCode': innerCode, 'vol': vol, 'buyPrice': stockHoldEntity.buyPrice, 'cost': cost, 'closePrice': closePrice, 'mv': mv, 'profit': profit, 'profitPCT': NumUtil.get_round(profit / initialMV * 100, 5) } stockHoldDailyList.append(holdDict) #print('dailyMV:' + str(dailyMV)) #print('usableCach:' + str(usableCach)) dailyMV = dailyMV + usableCach return dailyMV
def get_year_profit(df, column=''): df = df.sort_index(ascending=True) start = df.ix[0][column] end = df.ix[-1][column] # print("start:" + str(start)) # print("end:" + str(end)) profit = NumUtil.get_change_pct(start, end, 2) return profit
def get_max_drop(net_value_list_param): net_value_list = net_value_list_param.copy() net_value_list.insert(1, 'hightestNetValue', Series()) net_value_list.insert(2, 'drop', Series()) hightest = 0 #算出历史最高,和当日相对于历史最高的回撤 for index, row in net_value_list.iterrows(): #print(row['netValue']) if row['netValue'] > hightest: hightest = row['netValue'] net_value_list.ix[index, ['hightestNetValue']] = hightest net_value_list.ix[index, ['drop']] = NumUtil.get_change_pct( hightest, row['netValue'], 2) * -1 #最大回撤 max_drop = net_value_list['drop'].max() # 最大回撤 max_drop_rows = net_value_list.loc[(net_value_list['drop'] == max_drop)] # 最大回撤发生日 max_drop_end_date = DateUtil.datetime2_str( max_drop_rows.index[0]) #& (netValueList.index > maxDropStartDate) hightest_net_value = max_drop_rows.ix[0, ['hightestNetValue']][ 0] #['hightestNetValue'] #print('maxDropEndDate:'+str(maxDropEndDate)) #print('hightestNetValue:' + str(hightestNetValue)) # 最大回撤开始日 # 找到净值最高的记录 且 离开回撤发生日最近 hightest_rows = net_value_list.loc[( net_value_list['netValue'] == hightest_net_value )] # & (DateUtil.datetime2Str(netValueList.index) <= maxDropEndDate) hightest_rows = hightest_rows.sort_index(ascending=False) max_drop_start_date = DateUtil.datetime2_str(hightest_rows.index[0]) #print('maxDropStartDate:' + str(maxDropStartDate)) max_drop_dict = { 'maxDrop': NumUtil.get_round(max_drop, 2), 'maxDropStartDate': max_drop_start_date, 'maxDropEndDate': max_drop_end_date } return max_drop_dict
def calculate_daily_mv(currHoldSet, capitalEntity, dailyQuote, tradingDay, stockHoldDailyList, initialCash): usableCash = capitalEntity.get_usable_cash() stockMV = 0 for innerCode in currHoldSet: #try: dailyQuoteRow = SourceDataDao.select_by_inner_code_and_date(dailyQuote, tradingDay, innerCode) #except: #缺少数据,取最近一个交易日的数据 #dailyQuoteRow = SourceDataDao.selectByPrevTradingDay(dailyQuote, tradingDay, innerCode) #print('calculateDailyMV '+DateUtil.datetime2Str(tradingDay)+' '+str(innerCode)) stockHoldEntity = currHoldSet[innerCode] #vol = stockHoldEntity.vol # print('innerCode:' + str(innerCode)) closePrice = BackTestHelper.get_close_price(dailyQuoteRow) #mv = vol * closePrice #收盘市值 closeMV = BackTestHelper.get_sell_mv(stockHoldEntity.lastTradePrice, stockHoldEntity.lastTradeMV, closePrice) #stockHoldEntity.buyPrice, stockHoldEntity.buyMV # stockHoldEntity.set_close_price(closePrice) stockHoldEntity.set_close_mv(closeMV) #每日市值 stockMV += closeMV #该股收益(已扣佣金)(仅用于查看) TODO(部分卖出时的算法) profit = (closeMV - stockHoldEntity.lastTradeMV) * (1 - StockConst.BUY_COMMISSION / 100) holdDict = {'tradingDay': tradingDay, 'innerCode': innerCode, 'lastTradePrice': stockHoldEntity.lastTradePrice, 'lastTradeMV': stockHoldEntity.lastTradeMV, 'cost': stockHoldEntity.cost, 'closePrice': closePrice, 'closeMV': closeMV, 'profit': profit, 'openDate': stockHoldEntity.openDate, 'profitPCT': NumUtil.get_round(profit / initialCash * 100, 5), 'changeDate': stockHoldEntity.changeDate } stockHoldDailyList.append(holdDict) #print('dailyMV:' + str(dailyMV)) #print('usableCash:' + str(usableCash)) #总资产=股票市值+现金 totalAsset = stockMV + usableCash capitalEntity.set_total_asset(totalAsset) #股票市值 capitalEntity.set_stock_mv(stockMV)
def handleBuyList(tradingDate, buyList, dailyQuote, usableVol, stockHoldDF, stockTradeDF, currHoldSet, actualBuyList, cannotBuyList): if usableVol == 0: return 0 if len(buyList) == 0: return 0 vol = usableVol / len(buyList) #print('vol:'+vol) partChangePCT = 0 for innerCode in buyList: dailyQuoteRow = SourceDataDao.select_by_inner_code_and_date( dailyQuote, tradingDate, innerCode) #print('innerCode:'+str(innerCode)) #print(dailyQuoteRow) turnoverValue = dailyQuoteRow["TurnoverValue"] turnoverVolume = dailyQuoteRow["TurnoverVolume"] prevClosePrice = dailyQuoteRow["PrevClosePrice"] closePrice = dailyQuoteRow["ClosePrice"] highPrice = dailyQuoteRow["HighPrice"] lowPrice = dailyQuoteRow["LowPrice"] # 非停牌 且 非一字涨停: 可以卖出 check = not BackTestHelper.isYiZiZhangTing(highPrice, lowPrice, prevClosePrice) if (closePrice != 0) & (turnoverValue != float(0)) & check: actualBuyList.append(innerCode) cost = turnoverValue / turnoverVolume changePCT = NumUtil.get_change_pct(cost, closePrice, 2) realChangePCT = (changePCT - StockConst.BUY_COMMISSION) * vol / 100.0 partChangePCT = partChangePCT + realChangePCT # stockHold = StockHoldEntity.StockHoldEntity( tradingDate, innerCode, vol) stockTrade = StockTradeEntityBak.StockTradeEntity( tradingDate, innerCode, 1, vol, cost, changePCT, realChangePCT) #插入表 #stockHoldDF.setdefault(innerCode,stockHold) #当前持仓 currHoldSet.setdefault(innerCode, vol) #TODO trade else: cannotBuyList.append(innerCode) return partChangePCT
def calculateDailyMV(currHoldSet, capitalEntity, dailyQuote, tradingDate, stockHoldDailyList, initialMV): usableCach = capitalEntity.get_usable_cash() dailyMV = 0 for innerCode in currHoldSet: #try: dailyQuoteRow = SourceDataDao.select_by_inner_code_and_date( dailyQuote, tradingDate, innerCode) #except: #缺少数据,取最近一个交易日的数据 #dailyQuoteRow = SourceDataDao.selectByPrevTradingDay(dailyQuote, tradingDate, innerCode) #print('calculateDailyMV '+DateUtil.datetime2Str(tradingDate)+' '+str(innerCode)) stockHoldEntity = currHoldSet[innerCode] #vol = stockHoldEntity.vol # print('innerCode:' + str(innerCode)) closePrice = BackTestHelper.get_close_price(dailyQuoteRow) #mv = vol * closePrice #收盘市值 closeMV = BackTestHelper.get_sell_mv(stockHoldEntity.buyPrice, stockHoldEntity.buyMV, closePrice) #每日市值 dailyMV += closeMV #该股收益(已扣佣金)(仅用于查看) profit = (closeMV - stockHoldEntity.buyMV) * ( 1 - StockConst.BUY_COMMISSION / 100) holdDict = { 'tradingDate': tradingDate, 'innerCode': innerCode, 'buyPrice': stockHoldEntity.buyPrice, 'buyMV': stockHoldEntity.buyMV, 'cost': stockHoldEntity.cost, 'closePrice': closePrice, 'closeMV': closeMV, 'profit': profit, 'openDate': stockHoldEntity.openDate, 'profitPCT': NumUtil.get_round(profit / initialMV * 100, 5) } stockHoldDailyList.append(holdDict) #print('dailyMV:' + str(dailyMV)) #print('usableCach:' + str(usableCach)) dailyMV = dailyMV + usableCach return dailyMV
def handleSellList(tradingDate, sellList, dailyQuote, usableVol, stockHoldDF, stockTradeDF): partChangePCT = 0 for innerCode in sellList: dailyQuoteSingle = SourceDataDao.select_by_inner_code_and_date( dailyQuote, tradingDate, innerCode) #print('innerCode:' + str(innerCode)) hold = stockHoldDF.pop(innerCode) vol = hold.vol # print(dailyQuoteSingle) turnoverValue = dailyQuoteSingle["TurnoverValue"] turnoverVolume = dailyQuoteSingle["TurnoverVolume"] prevClosePrice = dailyQuoteSingle["PrevClosePrice"] sellPrice = turnoverValue / turnoverVolume changePCT = NumUtil.get_change_pct(prevClosePrice, sellPrice, 2) realChangePCT = changePCT * vol / 100.0 partChangePCT = partChangePCT + realChangePCT return partChangePCT
def handleSellList(tradingDate, sellList, dailyQuote, usableVol, stockHoldDF, stockTradeDF, currHoldSet, actualSellList, cannotSellList): partChangePCT = 0 dateStr = DateUtil.datetime2_str(tradingDate) if len(sellList) == 0: return 0 for innerCode in sellList: dailyQuoteRow = SourceDataDao.select_by_inner_code_and_date( dailyQuote, tradingDate, innerCode) #print('innerCode:' + str(innerCode)) # print(dailyQuoteSingle) turnoverValue = dailyQuoteRow["TurnoverValue"] turnoverVolume = dailyQuoteRow["TurnoverVolume"] prevClosePrice = dailyQuoteRow["PrevClosePrice"] closePrice = dailyQuoteRow["ClosePrice"] highPrice = dailyQuoteRow["HighPrice"] lowPrice = dailyQuoteRow["LowPrice"] #非停牌 且 非一字跌停: 可以卖出 check = not BackTestHelper.isYiZiDieTing(highPrice, lowPrice, prevClosePrice) if (closePrice != 0) & (turnoverValue != float(0)) & check: actualSellList.append(innerCode) vol = currHoldSet.pop(innerCode) sellPrice = turnoverValue / turnoverVolume changePCT = NumUtil.get_change_pct(prevClosePrice, sellPrice, 2) realChangePCT = (changePCT - StockConst.SELL_COMMISSION) * vol / 100.0 partChangePCT = partChangePCT + realChangePCT """ if dateStr == '2001-01-17': print("vol:"+str(vol)+" turnoverValue:"+str(turnoverValue)+" turnoverVolume:"+str(turnoverVolume)+ " prevClosePrice:"+str(prevClosePrice)+" closePrice:"+str(closePrice)+" sellPrice:"+str(sellPrice)+ " changePCT:"+str(changePCT)+ " realChangePCT:"+str(realChangePCT)+" partChangePCT:"+str(partChangePCT)) """ else: cannotSellList.append(innerCode) return partChangePCT
def handleSellList(tradingDate,sellList,dailyQuote,usableVol,stockHoldDF,stockTradeDF): partChangePCT = 0 dateStr = DateUtil.datetime2_str(tradingDate) for innerCode in sellList: dailyQuoteSingle = SourceDataDao.select_by_inner_code_and_date(dailyQuote, tradingDate, innerCode) #print('innerCode:' + str(innerCode)) hold = stockHoldDF.pop(innerCode) vol = hold.vol # print(dailyQuoteSingle) turnoverValue = dailyQuoteSingle["TurnoverValue"] turnoverVolume = dailyQuoteSingle["TurnoverVolume"] prevClosePrice = dailyQuoteSingle["PrevClosePrice"] sellPrice = turnoverValue / turnoverVolume changePCT = NumUtil.get_change_pct(prevClosePrice, sellPrice, 2) realChangePCT = changePCT * vol / 100.0 partChangePCT = partChangePCT + realChangePCT; if dateStr == '2001-01-17': print("vol:"+str(vol)+" turnoverValue:"+str(turnoverValue)+" turnoverVolume:"+str(turnoverVolume)+ " prevClosePrice:"+str(prevClosePrice)+" sellPrice:"+str(sellPrice)+" changePCT:"+str(changePCT)+ " realChangePCT:"+str(realChangePCT)+" partChangePCT:"+str(partChangePCT)) return partChangePCT
def handleHoldList(tradingDate, holdList, dailyQuote, usableVol, stockHoldDF, stockTradeDF, currHoldSet): partChangePCT = 0 #dateStr = DateUtil.datetime2Str(tradingDate) if len(holdList) == 0: return 0 for innerCode in holdList: dailyQuoteRow = SourceDataDao.select_by_inner_code_and_date( dailyQuote, tradingDate, innerCode) #print('innerCode:' + str(innerCode)) # print(dailyQuoteSingle) turnoverValue = dailyQuoteRow["TurnoverValue"] #turnoverVolume = dailyQuoteRow["TurnoverVolume"] prevClosePrice = dailyQuoteRow["PrevClosePrice"] closePrice = dailyQuoteRow["ClosePrice"] #非停牌 if (closePrice != 0) & (turnoverValue != float(0)): vol = currHoldSet.get(innerCode) changePCT = NumUtil.get_change_pct(prevClosePrice, closePrice, 2) realChangePCT = changePCT * vol / 100.0 partChangePCT = partChangePCT + realChangePCT return partChangePCT
def main(netValueList): standardMaxDrop = -5 stockTradeResultMaxDropList = [] startPoint = None startDate = None endDate = None changePCTToStart = None maxDrop = None happenDate = None maxDate = None maxDropNumOfDay = None dateIndexFromStart = 1 dateIndexFromHappen = 1 dateIndex = 1 totalNumOfDay = len(netValueList) #for stockTradeResultDailyEntity in netValueList: for index, row in netValueList.iterrows(): msgIsNewMaxDrop = "" msgIsNewStartPoint = "" msgIsEndPoint = "" msgInsert = "" currNetValue = row['netValue'] currDate = DateUtil.datetime2_str(index) if (startPoint == None): startPoint = currNetValue startDate = currDate dateIndexFromStart = 1 dateIndexFromHappen = 1 msgIsNewStartPoint = "newStartPoint" dateIndexFromStart = dateIndexFromStart + 1 dateIndexFromHappen = dateIndexFromHappen + 1 dateIndex = dateIndex + 1 else: changePCTToStart = NumUtil.get_change_pct(startPoint, currNetValue, 2) if maxDrop == None: check = True elif changePCTToStart < maxDrop: check = True else: check = False if ((changePCTToStart <= standardMaxDrop) & check): if (maxDrop == None): happenDate = currDate dateIndexFromHappen = 1 maxDrop = changePCTToStart maxDate = currDate maxDropNumOfDay = dateIndexFromHappen msgIsNewMaxDrop = "newMaxDrop" if ((currNetValue >= startPoint) | (dateIndex == totalNumOfDay)): if (maxDrop != None): endDate = currDate #msgInsert = " [insert]" + startDate + " " + endDate + " " + happenDate + " " + maxDrop + " " + maxDate + " " + maxDropNumOfDay; #StockTradeResultMaxDropEntity stockTradeResultMaxDropEntity = new StockTradeResultMaxDropEntity( # execModelId, startDate, endDate, happenDate, maxDrop, maxDate, #maxDropNumOfDay, DateUtils.getCurrentDateWithSecond3()); #if (stockTradeResultMaxDropList == null):stockTradeResultMaxDropList = new ArrayList(); #stockTradeResultMaxDropList.add(stockTradeResultMaxDropEntity); dict1 = { 'startDate': startDate, 'endDate': endDate, 'happenDate': happenDate, 'maxDrop': maxDrop, 'maxDate': maxDate } stockTradeResultMaxDropList.append(dict1) maxDrop = None happenDate = None maxDate = None maxDropNumOfDay = None msgIsEndPoint = "endPoint" if (currNetValue >= startPoint): startPoint = currNetValue startDate = currDate dateIndexFromStart = 1 msgIsNewStartPoint = "newStartPoint" dateIndexFromStart = dateIndexFromStart + 1 dateIndexFromHappen = dateIndexFromHappen + 1 dateIndex = dateIndex + 1 #非时间序列DF df = pd.DataFrame(stockTradeResultMaxDropList) return df
def deal(self,signalData1day,techList,select_stock_1day_func,trade_1day_func): #是否有更好的获取当天日期的方法? signalDay = signalData1day.index.get_level_values(0).unique() signalDayIndex = self.dateList.index(signalDay) #非最后一天 if signalDayIndex < (len(self.dateList) - 1): #交易日 tradingDay = self.dateList[signalDayIndex + 1] tradingDayStr = DateUtil.datetime2_str(tradingDay) #print('dateStr:'+dateStr) # 最后一天 else: return #选股结果(当天) currSelectStock = select_stock_1day_func(signalData1day,techList) #交易结果 dict = trade_1day_func(currSelectStock, self.currHoldSet, self.dailyQuote, tradingDay, self.signalData, self.capitalEntity) # end_inloop1 = time.clock() # print("trade_func花费时间:%f s" % (end_inloop1 - start_inloop1)) actualBuyList = dict['actualBuyList'] actualSellList = dict['actualSellList'] prevHoldList = dict['prevHoldList'] cannotBuyList = dict['cannotBuyList'] cannotSellList = dict['cannotSellList'] stockTradeListDaily = dict['stockTradeList'] if len(stockTradeListDaily) > 0 : self.stockTradeList.extend(stockTradeListDaily) #当日市值 currMV = calculateDailyMV(self.currHoldSet, self.capitalEntity, self.dailyQuote, tradingDay, self.stockHoldDailyList, self.initialMV) #个数 buyCnt = len(actualBuyList) sellCnt = len(actualSellList) prevHoldCnt = len(prevHoldList) currHoldCnt = len(self.currHoldSet) cannotSellCnt = len(cannotSellList) cannotBuyCnt = len(cannotBuyList) # print(currMV) # if StockConst.isDebug: # print("dateStr:" + dateStr + " changePCTBuy:" + str(changePCTBuy) + " changePCTSell:" + str(changePCTSell) + # " changePCTHold:" + str(changePCTHold)) # 当日净值 netValue = currMV / self.initialMV # print("netValue:" + str(netValue)) # 当日收益 dailyChangePCT = NumUtil.get_change_pct(self.lastMV, currMV, 2) # 当日可用现金 usableCach = self.capitalEntity.get_usable_cash() # self.stockStatDailyDf.ix[tradingDayStr] = netValue, dailyChangePCT, buyCnt, sellCnt, prevHoldCnt, currHoldCnt, cannotSellCnt, cannotBuyCnt, usableCach, currMV # self.lastMV = currMV
def main(read_func,select_stock_func,trade_func,techList,sliceDict,signalDataAddr = '', dailyQuoteAddr = '', indexQuoteAddr='', benchmark='', startDate = '2004-01-01', endDate = '2005-12-31', doPlot=True, table_name=None): start = time.clock() # signalData = SourceDataDao.loadSignalData(signalDataAddr) # dailyQuote = SourceDataDao.loadNewDailyQuote(dailyQuoteAddr) # indexQuote = SourceDataDao.loadH5(indexQuoteAddr) #StockConst.root + StockConst.fakeIndexQuoteH5 # signalData = SourceDataDao.read_file_set_index(signalDataAddr) signalData = read_func(signalDataAddr, table_name) dailyQuote = SourceDataDao.read_file_set_index(dailyQuoteAddr) indexQuote = SourceDataDao.read_file_set_index(indexQuoteAddr) if signalDataAddr is not None: maxSignalDate = SourceDataDao.get_max_date(signalDataAddr) minSignalDate = SourceDataDao.get_min_date(signalDataAddr) else: maxSignalDate = SignalDataMSSQLDao.select_max_data(table_name) minSignalDate = SignalDataMSSQLDao.select_min_data(table_name) # print('print') # print(maxSignalDate) # print(minSignalDate) maxDailyQuoteDate = SourceDataDao.get_max_date(dailyQuoteAddr) minDailyQuoteDate = SourceDataDao.get_min_date(dailyQuoteAddr) maxIndexQuoteDate = SourceDataDao.get_max_date(indexQuoteAddr) minIndexQuoteDate = SourceDataDao.get_min_date(indexQuoteAddr) # print('minSignalDate:' + minSignalDate) # print('maxSignalDate:' + maxSignalDate) # # print('minDailyQuoteDate:' + minDailyQuoteDate) # print('maxDailyQuoteDate:' + maxDailyQuoteDate) # # print('minIndexQuoteDate:' + minIndexQuoteDate) # print('maxIndexQuoteDate:' + maxIndexQuoteDate) # if minSignalDate < minDailyQuoteDate: startDate = minDailyQuoteDate else: startDate = minSignalDate if maxSignalDate > maxDailyQuoteDate: endDate = maxDailyQuoteDate else: endDate = maxSignalDate # if startDate < minIndexQuoteDate: startDate = minIndexQuoteDate else: pass if endDate > maxIndexQuoteDate: endDate = maxIndexQuoteDate else: pass print('startDate:'+startDate) print('endDate:' + endDate) #TODO 暂时不需要 # dailyQuotePn = SourceDataDao.loadNewDailyQuoteToPn(dailyQuoteAddr) dailyQuotePn = None #参数 #初始资金 initialCash = 1000000 #1000000 #选股结果(外部传入) #select top 5 group by TradingDay order by Mom desc allSelectStock = select_stock_func(signalData,techList,sliceDict) print('allSelectStock:'+str(len(allSelectStock))) # print(allSelectStock) if len(allSelectStock) == 0: return #当前持仓 currHoldSet = {} #资金情况 capitalEntity = CapitalEntity.CapitalEntity(initialCash, 0, initialCash) lastCapitalEntity = copy.copy(capitalEntity) #初始化每日统计表 stockStatDailyDf = pd.DataFrame(index=pd.date_range(startDate, endDate), columns=['netValue','changePCT','buyCnt','sellCnt','prevHoldCnt','currHoldCnt','cannotSellCnt','cannotBuyCnt', 'usableCash','totalAsset','indexChangePCT','relativeChangePCT','relativeNetValue']) #初始化每日持仓表 stockHoldDailyList = [] stockTradeList = [] #从信号表中取得唯一性日期 dateList = SourceDataDao.select_date_from_signal(dailyQuote, startDate, endDate) #signalData dailyQuote # print(dateList) # lastTradingDay = None # lastTradingDayStr = None lastRelativeNetValue = 1 #昨日相对净值 start_loop = time.clock() for index, item in enumerate(dateList): #for date in dateList: #print('index:'+str(index)+' len:'+str(len(dateList))) # start_inloop0 = time.clock() #信号日 signalDay = dateList[index] # 非最后一天 if index < (len(dateList) - 1): #交易日 tradingDay = dateList[index + 1] tradingDayStr = DateUtil.datetime2_str(tradingDay) # tradingDayTsp = pd.Timestamp(tradingDayStr) # print(tradingDay) # print(tradingDayStr) # print(tradingDayTsp) # print(type(tradingDay)) # print(type(tradingDayStr)) # print(type(tradingDayTsp)) #print('dateStr:'+dateStr) # 最后一天 else: break # dailyQuote1day = dailyQuote[dailyQuote.index.get_level_values(0) == tradingDay] #TODO # start_slice = time.clock() # print(str(len(dailyQuote))) # print(type(tradingDay)) #交易日行情 dailyQuote1day = dailyQuote.xs(tradingDay) # print('dailyQuote1day:'+str(len(dailyQuote1day))) # end_slice = time.clock() # print("切片花费时间:%f s" % (end_slice - start_slice)) # dailyQuote1day = None #print(dateStr) #信号日选股 currSelectStock = allSelectStock.xs(signalDay) #.xs(signalDay) # print('currSelectStock:'+str(len(currSelectStock))) # if StockConst.isDebug: # print('tradingDayStr:'+tradingDayStr+' currSignalData:'+str(len(currSignalData))) #print(currSignalData) # end_inloop0 = time.clock() # print("inloop0花费时间:%f s" % (end_inloop0 - start_inloop0)) #交易方法(外部传入) # start_inloop1 = time.clock() dict = trade_func(currSelectStock, currHoldSet, dailyQuote, tradingDay, signalData, capitalEntity, dailyQuotePn, dailyQuote1day, lastCapitalEntity) # end_inloop1 = time.clock() # print("trade_func花费时间:%f s" % (end_inloop1 - start_inloop1)) actualBuyList = dict['actualBuyList'] actualSellList = dict['actualSellList'] prevHoldList = dict['prevHoldList'] cannotBuyList = dict['cannotBuyList'] cannotSellList = dict['cannotSellList'] stockTradeListDaily = dict['stockTradeList'] if len(stockTradeListDaily) > 0 : stockTradeList.extend(stockTradeListDaily) # print(currHoldSet) #3.计算当日市值 # start_inloop2 = time.clock() calculate_daily_mv(currHoldSet, capitalEntity, dailyQuote, tradingDay, stockHoldDailyList, initialCash) totalAsset = capitalEntity.get_total_asset() # end_inloop2 = time.clock() # print("calculateDailyMV花费时间:%f s" % (end_inloop2 - start_inloop2)) # start_inloop3 = time.clock() #4.个数 buyCnt = len(actualBuyList) sellCnt = len(actualSellList) prevHoldCnt = len(prevHoldList) currHoldCnt = len(currHoldSet) cannotSellCnt = len(cannotSellList) cannotBuyCnt = len(cannotBuyList) # print(currMV) #if StockConst.isDebug: #print("dateStr:" + dateStr + " changePCTBuy:" + str(changePCTBuy) + " changePCTSell:" + str(changePCTSell) + #" changePCTHold:" + str(changePCTHold)) #当日净值 netValue = totalAsset / initialCash #print("netValue:" + str(netValue)) #当日收益(%) dailyChangePCT = NumUtil.get_change_pct(lastCapitalEntity.get_total_asset(), totalAsset, 5) #当日可用现金 usableCash = capitalEntity.get_usable_cash() # 当日的指数 indexQuote1day = None indexChangePCT = 0 if indexQuote is not None: indexQuote1day = indexQuote.ix[(tradingDay, benchmark)] indexChangePCT = indexQuote1day['ChangePCT'] #相对收益=每日收益-指数收益 (%) relativeChangePCT = dailyChangePCT - indexChangePCT #相对净值=昨日相对净值*(1+相对收益/100) relativeNetValue = lastRelativeNetValue*(1+relativeChangePCT/100) #统计表 stockStatDailyDf.ix[tradingDayStr] = netValue,dailyChangePCT,buyCnt,sellCnt,prevHoldCnt,currHoldCnt,cannotSellCnt,cannotBuyCnt,usableCash,totalAsset,indexChangePCT,relativeChangePCT,relativeNetValue #昨日资产 lastCapitalEntity = copy.copy(capitalEntity) #昨日相对净值 lastRelativeNetValue = relativeNetValue # lastTradingDay = tradingDay # lastTradingDayStr = tradingDayStr # end_inloop3 = time.clock() # print("inloop3花费时间:%f s" % (end_inloop3 - start_inloop3)) end_loop = time.clock() print("for循环花费时间:%f s" % (end_loop - start_loop)) result = '' start_stat = time.clock() # 信号数据 #allSelectStock.to_csv(StockConst.root + '\export\allSelectStock.csv') # # 每日交易 # # print('每日交易:') # # print(stockTradeList) # stockTradeDailyDf = pd.DataFrame(stockTradeList) # stockTradeDailyDf.sort_values(by=['tradingDay'], ascending=True) # # stockTradeDailyDf.to_csv(StockConst.root + '\export\stockTradeDaily.csv') # # 每日持仓 # #print('每日持仓:') # stockHoldDailyDf = pd.DataFrame(stockHoldDailyList) # stockHoldDailyDf.sort_values(by=['tradingDay'],ascending=True) # # stockHoldDailyDf.to_csv(StockConst.root + '\export\stockHoldDaily.csv') start_stat_1 = time.clock() #每日统计(收益,净值,买入数,卖出数,持有数) stockStatDailyDf = stockStatDailyDf.dropna(how='all') result += '--' * 70 + '\n' result += '每日统计:' + '\n' result += stockStatDailyDf.to_string() + '\n' stockStatDailyDf.to_csv(StockConst.ROOT + '\export\stockStatDaily.csv') end_stat_1 = time.clock() print("统计1花费时间:%f s" % (end_stat_1 - start_stat_1)) start_stat_2 = time.clock() # 每年统计 result += '--' * 70 + '\n' yearDf = StockYearService.main(stockStatDailyDf) result += '每年统计:' + '\n' result += yearDf.to_string() + '\n' end_stat_2 = time.clock() print("统计2花费时间:%f s" % (end_stat_2 - start_stat_2)) start_stat_3 = time.clock() # 最大回撤 result += '--' * 70 + '\n' maxdrop = StockMaxDropNewService.get_max_drop(stockStatDailyDf) result += '最大回撤:' + '\n' result += SetUtil.dict_to_string(maxdrop) + '\n' # #每年的最大回撤 # maxdropDf = StockMaxDropNewService.getMaxDropForEachYear(stockStatDailyDf) # maxdropDf.sort_values(by=["year"]) # result += '每年的最大回撤:' + '\n' # result += maxdropDf.to_string() + '\n' end_stat_3 = time.clock() print("统计3花费时间:%f s" % (end_stat_3 - start_stat_3)) start_stat_4 = time.clock() #夏普比率 result += '--' * 70 + '\n' sharpRatio = SharpRatioNewService.get_sharp_ratio(stockStatDailyDf) result += '夏普比率:' + '\n' result += str(sharpRatio) + '\n' #每年的夏普比率 sharpRatioDf = SharpRatioNewService.get_sharp_ratio_for_each_year(stockStatDailyDf) sharpRatioDf.sort_values(by=["year"]) result += '每年的夏普比率:' + '\n' result += sharpRatioDf.to_string() + '\n' end_stat_4 = time.clock() print("统计4花费时间:%f s" % (end_stat_4 - start_stat_4)) end_stat = time.clock() print("统计花费时间:%f s" % (end_stat - start_stat)) # result += '回测完成' end = time.clock() print("main花费时间:%f s" % (end - start)) if doPlot: # # # 净值曲线图 # stockStatDailyDf['netValue'].plot() # plt.show() # # # # 相对净值曲线图 # stockStatDailyDf['relativeNetValue'].plot() # plt.show() pass # resultDic={ 'stockStatDailyDf': stockStatDailyDf, 'result': result, 'sharpRatio': sharpRatio } print(result) return resultDic
def main(select_stock, numOfDailySignal): signalData = SourceDataDao.getSignalData() #dailyQuote = SourceDataDao.getDailyQuote() dailyQuote = SourceDataDao.getNewDailyQuote() #参数 #每天信号数 #numOfDailySignal = 5 #初始资金 initialMV = 1000000 #1000000 #开始结束日期 #startDate = '1/8/2001' startDate = '1/1/2004' #endDate = '1/1/2017' #eendDate = '5/18/2001' endDate = '12/31/2005' #endDate = '12/31/2002' #endDate = '1/9/2001' #select top 5 group by TradingDay order by Mom desc groupedSignalData = select_stock(signalData, numOfDailySignal) #groupedSignalData = signalData.groupby(level=StockConst.TradingDay).apply(SelectUtil.top,numOfDailySignal,StockConst.Mom,False) #False True #当前持仓 key:innerCode value: currHoldSet = {} stockTradeList = [] # capitalEntity = CapitalEntity.CapitalEntity(initialMV) lastMV = initialMV #netValue = 1; #初始化每日统计表 stockStatDailyDf = pd.DataFrame(index=pd.date_range(startDate, endDate), columns=[ 'netValue', 'changePCT', 'buyCnt', 'sellCnt', 'prevHoldCnt', 'currHoldCnt', 'cannotSellCnt', 'cannotBuyCnt', 'usableCach', 'mv' ]) #初始化每日持仓表 stockHoldDailyList = [] #从信号表中取得唯一性日期 dateList = SourceDataDao.select_date_from_signal(signalData, startDate, endDate) for index, item in enumerate(dateList): #for date in dateList: #print('index:'+str(index)+' len:'+str(len(dateList))) #信号日 signalDay = dateList[index] # 非最后一天 if index < (len(dateList) - 1): #交易日 tradingDay = dateList[index + 1] tradingDayStr = DateUtil.datetime2_str(tradingDay) #print('dateStr:'+dateStr) # 最后一天 else: break #print(dateStr) currSignalData = groupedSignalData.ix[signalDay] if StockConst.IS_DEBUG: print("currSignalData:" + str(len(currSignalData))) #print(currSignalData) # 计划买入列表 planBuyList = getPlanBuyList(currSignalData, currHoldSet) # 计划卖出列表 planSellList = getPlanSellList(currSignalData, currHoldSet) # 昨日持仓部分(在今日持仓中) prevHoldList = getPrevHoldList(currSignalData, currHoldSet) """ if (dateStr >= '2015-01-05') & (dateStr <= '2015-01-05'): print('-----'+dateStr+'-----') #print(currSignalData) #print(buyList) print(list(currHoldSet.keys())) for key in currHoldSet.keys(): print(str(key) + ':' + currHoldSet.get(key).openDate) print('----------------') """ #dailyChangePCT = 0 cannotSellList = [] cannotBuyList = [] # 实际买入列表 actualBuyList = getActualBuyList(planBuyList, dailyQuote, tradingDay, cannotBuyList) # "卖出列表"中要保留的股票数 numOfToKeepInSellList = numOfDailySignal - len(actualBuyList) - len( prevHoldList) # 实际卖出列表 actualSellList = getActualSellList(planSellList, tradingDay, signalData, dailyQuote, numOfToKeepInSellList, cannotSellList) #1.处理实际卖出 handleSellList(tradingDay, dailyQuote, stockTradeList, currHoldSet, capitalEntity, actualSellList) #2.处理实际买入 handleBuyList(tradingDay, dailyQuote, stockTradeList, currHoldSet, capitalEntity, actualBuyList) #3.计算当日市值 currMV = calculateDailyMV(currHoldSet, capitalEntity, dailyQuote, tradingDay, stockHoldDailyList, initialMV) #4.个数 buyCnt = len(actualBuyList) sellCnt = len(actualSellList) prevHoldCnt = len(prevHoldList) currHoldCnt = len(currHoldSet) cannotSellCnt = len(cannotSellList) cannotBuyCnt = len(cannotBuyList) #if StockConst.isDebug: #print("dateStr:" + dateStr + " changePCTBuy:" + str(changePCTBuy) + " changePCTSell:" + str(changePCTSell) + #" changePCTHold:" + str(changePCTHold)) #当日净值 netValue = currMV / initialMV #print("netValue:" + str(netValue)) #当日收益 dailyChangePCT = NumUtil.get_change_pct(lastMV, currMV, 2) #当日可用现金 usableCach = capitalEntity.get_usable_cash() # stockStatDailyDf.ix[ tradingDayStr] = netValue, dailyChangePCT, buyCnt, sellCnt, prevHoldCnt, currHoldCnt, cannotSellCnt, cannotBuyCnt, usableCach, currMV # lastMV = currMV # 信号数据 #groupedSignalData.to_csv(StockConst.root + '\export\groupedSignalData.csv') # 每日交易 # print('每日交易:') stockTradeDailyDf = pd.DataFrame(stockTradeList) stockTradeDailyDf.sort_values(by=['tradingDate'], ascending=True) stockTradeDailyDf.to_csv(StockConst.ROOT + '\export\stockTradeDaily.csv') # 每日持仓 #print('每日持仓:') stockHoldDailyDf = pd.DataFrame(stockHoldDailyList) stockHoldDailyDf.sort_values(by=['tradingDate'], ascending=True) stockHoldDailyDf.to_csv(StockConst.ROOT + '\export\stockHoldDaily.csv') #每日统计(收益,净值,买入数,卖出数,持有数) stockStatDailyDf = stockStatDailyDf.dropna(how='all') print('每日统计:') print(stockStatDailyDf) stockStatDailyDf.to_csv(StockConst.ROOT + '\export\stockStatDaily.csv') # 每年统计 yearDf = StockYearService.main(stockStatDailyDf) print('每年统计:') print(yearDf) # 最大回撤 maxdrop = StockMaxDropNewService.get_max_drop(stockStatDailyDf) print('最大回撤:') print(maxdrop) #每年的最大回撤 maxdropDf = StockMaxDropNewService.get_max_drop_for_each_year( stockStatDailyDf) maxdropDf.sort_values(by=["year"]) print('每年的最大回撤:') print(maxdropDf) #夏普比率 sharpRatio = SharpRatioNewService.get_sharp_ratio(stockStatDailyDf) print('夏普比率:') print(sharpRatio) #每年的夏普比率 sharpRatioDf = SharpRatioNewService.get_sharp_ratio_for_each_year( stockStatDailyDf) sharpRatioDf.sort_values(by=["year"]) print('每年的夏普比率:') print(sharpRatioDf)
def reduce_usable_cash(self, a_cach): self.usable_cach -= a_cach self.usable_cach = NumUtil.get_round(self.usable_cach, StockConst.USABLE_CASH_SCALE)
def increase_usable_cash(self, a_cach): self.usable_cach += a_cach self.usable_cach = NumUtil.get_round(self.usable_cach, StockConst.USABLE_CASH_SCALE)
def main(): signalData = SourceDataDao.getSignalData() #dailyQuote = SourceDataDao.getDailyQuote() dailyQuote = SourceDataDao.getNewDailyQuote() #columns filter #df3 = sourceData.loc[(df['Mom'] <= 4) & (df['Mom'] <= 4), ['Mom']] #index filter #startDate=DateUtils.str2Datetime('20010105'); #endDate=DateUtils.str2Datetime('20010111'); #df4 = df3.ix[startDate:endDate] numOfDailyHolding = 5 #select top 5 group by TradingDay order by Mom desc groupedSignalData = signalData.groupby(level='TradingDay').apply( SelectUtil.top, numOfDailyHolding, 'Mom', False) #param #period = 5 #startDate = '1/8/2001' startDate = '1/8/2001' #endDate = '1/1/2017' #eendDate = '5/18/2001' endDate = '12/31/2016' #endDate = '12/31/2002' #endDate = '1/9/2001' #time series #dateList = DateUtil.getDateList2(startDate,endDate) #当前持仓 key:innerCode value: currHoldSet = {} stockHoldDF = {} stockTradeList = [] #资金情况 #capitalDict = {'usableCach':1000000} #初始资金 initialMV = 1000000 capitalEntity = CapitalEntity.CapitalEntity(initialMV) lastMV = initialMV #lastSignalData = pd.DataFrame() usableVol = 100 netValue = 1 #初始化每日统计表 stockStatDailyDf = pd.DataFrame(index=pd.date_range(startDate, endDate), columns=[ 'netValue', 'changePCT', 'buyCnt', 'sellCnt', 'prevHoldCnt', 'currHoldCnt', 'cannotSellCnt', 'cannotBuyCnt', 'usableCach', 'mv' ]) #初始化每日持仓表 stockHoldDailyList = [] #从信号表中取得唯一性日期 dateList = SourceDataDao.select_date_from_signal(signalData, startDate, endDate) for date in dateList: dateStr = DateUtil.datetime2_str(date) #print(dateStr) #isinstance(date, datetime) # select by single date #try: #print(1) currSignalData = groupedSignalData.ix[date] if StockConst.IS_DEBUG: print("currSignalData:" + str(len(currSignalData))) #print(2) buyList = getBuyList(currSignalData, currHoldSet) #print(3) sellList = getSellList(currSignalData, currHoldSet) #print(4) prevHoldList = getPrevHoldList(currSignalData, currHoldSet) #print(currSignalData) """ if (dateStr >= '2015-01-05') & (dateStr <= '2015-01-05'): print('-----'+dateStr+'-----') #print(currSignalData) #print(buyList) print(list(currHoldSet.keys())) for key in currHoldSet.keys(): print(str(key) + ':' + currHoldSet.get(key).openDate) print('----------------') """ #except: #假期,双休日,原数据问题 #if StockConst.isDebug: #print(DateUtil.datetime2Str(date) + ': no data') #continue dailyChangePCT = 0 actualSellList = [] actualBuyList = [] cannotSellList = [] cannotBuyList = [] #实际买入个数 numOfActualBuy = getNumOfActualBuy(date, buyList, dailyQuote) #1.sell changePCTSell handleSellList(date, sellList, dailyQuote, usableVol, stockHoldDF, stockTradeList, currHoldSet, actualSellList, cannotSellList, capitalEntity, numOfActualBuy, signalData, prevHoldList, numOfDailyHolding) #usableVol = calculateUsableVol(currHoldSet) #2.buy changePCTBuy handleBuyList(date, buyList, dailyQuote, usableVol, stockHoldDF, stockTradeList, currHoldSet, actualBuyList, cannotBuyList, capitalEntity) #3.hold #changePCTHold = handleHoldList(date,prevHoldList,dailyQuote,usableVol,stockHoldDF,stockTradeDF,currHoldSet) #changePCTHold = 0 currMV = calculateDailyMV(currHoldSet, capitalEntity, dailyQuote, date, stockHoldDailyList, initialMV) #handleStockHoldDaily(currHoldSet, stockHoldDailyList, date) buyCnt = len(actualBuyList) sellCnt = len(actualSellList) prevHoldCnt = len(prevHoldList) currHoldCnt = len(currHoldSet) cannotSellCnt = len(cannotSellList) cannotBuyCnt = len(cannotBuyList) #if StockConst.isDebug: #print("dateStr:" + dateStr + " changePCTBuy:" + str(changePCTBuy) + " changePCTSell:" + str(changePCTSell) + #" changePCTHold:" + str(changePCTHold)) #dailyChangePCT = changePCTBuy+changePCTSell+changePCTHold #print("dailyChangePCT:"+str(dailyChangePCT)) #netValue = netValue * (1 + dailyChangePCT / 100) #每日净值 netValue = currMV / initialMV #print("netValue:" + str(netValue)) #每日收益 dailyChangePCT = NumUtil.get_change_pct(lastMV, currMV, 2) #每日可用现金 usableCach = capitalEntity.get_usable_cash() stockStatDailyDf.ix[ dateStr] = netValue, dailyChangePCT, buyCnt, sellCnt, prevHoldCnt, currHoldCnt, cannotSellCnt, cannotBuyCnt, usableCach, currMV lastMV = currMV #debug 行情数据 debugDailyQuote(groupedSignalData) # 信号数据 #groupedSignalData.to_csv(StockConst.root + '\export\groupedSignalData.csv') # 每日交易 # print('每日交易:') stockTradeDailyDf = pd.DataFrame(stockTradeList) stockTradeDailyDf.sort_values(by=['tradingDate'], ascending=True) stockTradeDailyDf.to_csv(StockConst.ROOT + '\export\stockTradeDaily.csv') # 每日持仓 #print('每日持仓:') stockHoldDailyDf = pd.DataFrame(stockHoldDailyList) stockHoldDailyDf.sort_values(by=['tradingDate'], ascending=True) stockHoldDailyDf.to_csv(StockConst.ROOT + '\export\stockHoldDaily.csv') #每日统计(收益,净值,买入数,卖出数,持有数) stockStatDailyDf = stockStatDailyDf.dropna(how='all') print('每日统计:') print(stockStatDailyDf) stockStatDailyDf.to_csv(StockConst.ROOT + '\export\stockStatDaily.csv') # 每年统计 yearDf = StockYearService.main(stockStatDailyDf) print('每年统计:') print(yearDf) # 最大回撤 maxdrop = StockMaxDropNewService.get_max_drop(stockStatDailyDf) print('最大回撤:') print(maxdrop) #每年的最大回撤 maxdropDf = StockMaxDropNewService.get_max_drop_for_each_year( stockStatDailyDf) maxdropDf.sort_values(by=["year"]) print('每年的最大回撤:') print(maxdropDf) #夏普比率 sharpRatio = SharpRatioNewService.get_sharp_ratio(stockStatDailyDf) print('夏普比率:') print(sharpRatio) #每年的夏普比率 sharpRatioDf = SharpRatioNewService.get_sharp_ratio_for_each_year( stockStatDailyDf) sharpRatioDf.sort_values(by=["year"]) print('每年的夏普比率:') print(sharpRatioDf)
def handleBuyList(tradingDate, buyList, dailyQuote, usableVol, stockHoldDF, stockTradeList, currHoldSet, actualBuyList, cannotBuyList, capitalEntity): usableCach = capitalEntity.get_usable_cash() if usableCach == 0: return 0 #if usableVol == 0: #return 0 if len(buyList) == 0: return 0 turnover = usableCach / len(buyList) #print('vol:'+vol) partChangePCT = 0 for innerCode in buyList: dailyQuoteRow = SourceDataDao.select_by_inner_code_and_date( dailyQuote, tradingDate, innerCode) #print('innerCode:'+str(innerCode)) #print(dailyQuoteRow) turnoverValue = dailyQuoteRow["TurnoverValue"] turnoverVolume = dailyQuoteRow["TurnoverVolume"] buyFlg = dailyQuoteRow[StockConst.BUY_FLG] #可买 if buyFlg != -1: actualBuyList.append(innerCode) #平均买入价(没有算佣金) buyPrice = turnoverValue / turnoverVolume #成本价(算佣金) cost = buyPrice * (1 + StockConst.BUY_COMMISSION / 100) #仓位(股) vol = NumUtil.get_round(turnover / cost, StockConst.VOL_SCALE) #佣金(元) commission = BackTestHelper.get_buy_commission( turnover, StockConst.BUY_COMMISSION / 100) #更新可用金额(减少) capitalEntity.reduce_usable_cash(turnover) #changePCT = NumUtil.getChangePCT(cost, closePrice, 2) #realChangePCT = (changePCT - StockConst.buyCommission) * vol / 100.0 #partChangePCT = partChangePCT + realChangePCT # #stockHold = StockHoldEntity.StockHoldEntity(tradingDate,innerCode,vol) #stockTrade = StockTradeEntity.StockTradeEntity(tradingDate, innerCode, 1, vol, cost, '', '') stockTradeDict = { 'tradingDate': tradingDate, 'innerCode': innerCode, 'type': 1, 'vol': vol, 'price': buyPrice, 'turnover': turnover, 'commission': commission } stockTradeList.append(stockTradeDict) #插入表 #stockHoldDF.setdefault(innerCode,stockHold) #当前持仓 stockHoldEntity = StockHoldEntity.StockHoldEntity( innerCode, vol, buyPrice, cost, DateUtil.datetime2_str(tradingDate)) #tradingDate, currHoldSet.setdefault(innerCode, stockHoldEntity) #vol """ if (DateUtil.datetime2Str(tradingDate) == '2014-12-08') | (DateUtil.datetime2Str(tradingDate) == '2014-12-09'): print('-----handleBuyList-----') print(DateUtil.datetime2Str(tradingDate)) print(innerCode) print(vol) print(buyPrice) print(cost) print(turnoverValue) print(dailyQuoteRow) print('----------') """ else: cannotBuyList.append(innerCode)
def main(select_stock_func, trade_func, techList, signalDataAddr='', dailyQuoteAddr='', startDate='1/1/2004', endDate='12/31/2005'): start = time.clock() signalData = SourceDataDao.load_signal_data(signalDataAddr) #dailyQuote = SourceDataDao.loadDailyQuote() dailyQuote = SourceDataDao.load_new_daily_quote(dailyQuoteAddr) #参数 #每天信号数 #numOfDailySignal = 5 #初始资金 initialMV = 1000000 #1000000 #开始结束日期 #startDate = '1/8/2001' #startDate = '1/1/2004' #endDate = '1/1/2017' #eendDate = '5/18/2001' #endDate = '12/31/2005' #endDate = '12/31/2002' #endDate = '1/9/2001' #选股结果(外部传入) #select top 5 group by TradingDay order by Mom desc groupedSignalData = select_stock_func(signalData, techList) #当前持仓 key:innerCode value: currHoldSet = {} #资金情况 capitalEntity = CapitalEntity.CapitalEntity(initialMV) lastMV = initialMV #初始化每日统计表 stockStatDailyDf = pd.DataFrame(index=pd.date_range(startDate, endDate), columns=[ 'netValue', 'changePCT', 'buyCnt', 'sellCnt', 'prevHoldCnt', 'currHoldCnt', 'cannotSellCnt', 'cannotBuyCnt', 'usableCach', 'mv' ]) #初始化每日持仓表 stockHoldDailyList = [] stockTradeList = [] #从信号表中取得唯一性日期 dateList = SourceDataDao.select_date_from_signal(signalData, startDate, endDate) # print(dateList) start_loop = time.clock() for index, item in enumerate(dateList): #for date in dateList: #print('index:'+str(index)+' len:'+str(len(dateList))) start_inloop0 = time.clock() #信号日 signalDay = dateList[index] # 非最后一天 if index < (len(dateList) - 1): #交易日 tradingDay = dateList[index + 1] tradingDayStr = DateUtil.datetime2_str(tradingDay) #print('dateStr:'+dateStr) # 最后一天 else: break #print(dateStr) currSignalData = groupedSignalData.ix[signalDay] # print(currSignalData) if StockConst.IS_DEBUG: print("currSignalData:" + str(len(currSignalData))) #print(currSignalData) end_inloop0 = time.clock() print("inloop0花费时间:%f s" % (end_inloop0 - start_inloop0)) #交易方法(外部传入) start_inloop1 = time.clock() dict = trade_func(currSignalData, currHoldSet, dailyQuote, tradingDay, signalData, capitalEntity) end_inloop1 = time.clock() print("trade_func花费时间:%f s" % (end_inloop1 - start_inloop1)) actualBuyList = dict['actualBuyList'] actualSellList = dict['actualSellList'] prevHoldList = dict['prevHoldList'] cannotBuyList = dict['cannotBuyList'] cannotSellList = dict['cannotSellList'] stockTradeListDaily = dict['stockTradeList'] if len(stockTradeListDaily) > 0: stockTradeList.extend(stockTradeListDaily) # print(currHoldSet) #3.计算当日市值 start_inloop2 = time.clock() currMV = calculateDailyMV(currHoldSet, capitalEntity, dailyQuote, tradingDay, stockHoldDailyList, initialMV) end_inloop2 = time.clock() print("calculateDailyMV花费时间:%f s" % (end_inloop2 - start_inloop2)) start_inloop3 = time.clock() #4.个数 buyCnt = len(actualBuyList) sellCnt = len(actualSellList) prevHoldCnt = len(prevHoldList) currHoldCnt = len(currHoldSet) cannotSellCnt = len(cannotSellList) cannotBuyCnt = len(cannotBuyList) # print(currMV) #if StockConst.isDebug: #print("dateStr:" + dateStr + " changePCTBuy:" + str(changePCTBuy) + " changePCTSell:" + str(changePCTSell) + #" changePCTHold:" + str(changePCTHold)) #当日净值 netValue = currMV / initialMV #print("netValue:" + str(netValue)) #当日收益 dailyChangePCT = NumUtil.get_change_pct(lastMV, currMV, 2) #当日可用现金 usableCach = capitalEntity.get_usable_cash() # stockStatDailyDf.ix[ tradingDayStr] = netValue, dailyChangePCT, buyCnt, sellCnt, prevHoldCnt, currHoldCnt, cannotSellCnt, cannotBuyCnt, usableCach, currMV # lastMV = currMV end_inloop3 = time.clock() print("inloop3花费时间:%f s" % (end_inloop3 - start_inloop3)) pass end_loop = time.clock() print("for循环花费时间:%f s" % (end_loop - start_loop)) result = '' start_stat = time.clock() # 信号数据 #groupedSignalData.to_csv(StockConst.root + '\export\groupedSignalData.csv') # 每日交易 # print('每日交易:') # print(stockTradeList) stockTradeDailyDf = pd.DataFrame(stockTradeList) stockTradeDailyDf.sort_values(by=['tradingDate'], ascending=True) # stockTradeDailyDf.to_csv(StockConst.root + '\export\stockTradeDaily.csv') # 每日持仓 #print('每日持仓:') stockHoldDailyDf = pd.DataFrame(stockHoldDailyList) stockHoldDailyDf.sort_values(by=['tradingDate'], ascending=True) # stockHoldDailyDf.to_csv(StockConst.root + '\export\stockHoldDaily.csv') #每日统计(收益,净值,买入数,卖出数,持有数) stockStatDailyDf = stockStatDailyDf.dropna(how='all') result += '--' * 70 + '\n' result += '每日统计:' + '\n' result += stockStatDailyDf.to_string() + '\n' # stockStatDailyDf.to_csv(StockConst.root + '\export\stockStatDaily.csv') # 每年统计 result += '--' * 70 + '\n' yearDf = StockYearService.main(stockStatDailyDf) result += '每年统计:' + '\n' result += yearDf.to_string() + '\n' # 最大回撤 result += '--' * 70 + '\n' maxdrop = StockMaxDropNewService.get_max_drop(stockStatDailyDf) result += '最大回撤:' + '\n' result += SetUtil.dict_to_string(maxdrop) + '\n' #每年的最大回撤 maxdropDf = StockMaxDropNewService.get_max_drop_for_each_year( stockStatDailyDf) maxdropDf.sort_values(by=["year"]) result += '每年的最大回撤:' + '\n' result += maxdropDf.to_string() + '\n' #夏普比率 result += '--' * 70 + '\n' sharpRatio = SharpRatioNewService.get_sharp_ratio(stockStatDailyDf) result += '夏普比率:' + '\n' result += str(sharpRatio) + '\n' #每年的夏普比率 sharpRatioDf = SharpRatioNewService.get_sharp_ratio_for_each_year( stockStatDailyDf) sharpRatioDf.sort_values(by=["year"]) result += '每年的夏普比率:' + '\n' result += sharpRatioDf.to_string() + '\n' end_stat = time.clock() print("统计花费时间:%f s" % (end_stat - start_stat)) # result += '回测完成' end = time.clock() print("main花费时间:%f s" % (end - start)) # 净值曲线图 stockStatDailyDf['netValue'].plot() plt.show() resultDic = {'stockStatDailyDf': stockStatDailyDf, 'result': result} print(result) return resultDic