def init_signal_data_info(signalDataAddr): # 取得技术指标 techListOrigin = SourceDataDao.get_colums_from_h5(signalDataAddr) techList.clear() for x in techListOrigin: techList.append(x) # 删除已有指标控件 for widget in techframe.winfo_children(): widget.destroy() # 新增指标控件 for index, item in enumerate(techListOrigin): R1 = Radiobutton(techframe, text=item, variable=techRadioVar, value=index, command=select_tech_radio) R1.pack(anchor=W) # 信号文件地址 signalDataAddrVal.set(signalDataAddr) # originStartDate = SourceDataDao.get_first_record_from_h5( signalDataAddr).index[0][0] originEndDate = SourceDataDao.get_last_record_from_h5( signalDataAddr).index[0][0] originStartDate = DateUtil.datetime2_str(originStartDate) originEndDate = DateUtil.datetime2_str(originEndDate) originStartDateVar.set(originStartDate) originEndDateVar.set(originEndDate) #开始时间 结束时间 startDateVal.set(originStartDate) endDateVal.set(originEndDate)
def test_back_test_main_hill(self): techList = [StockConst.MOM] signalDataAddr = StockConst.ROOT + '/export/SignalDataHill.h5' databaseDict = None dailyQuoteAddr = StockConst.ROOT + '/export/DailyQuoteHill.h5' indexQuoteAddr = StockConst.ROOT + StockConst.FAKE_INDEX_QUOTE_H5_2 # 基准(算相对收益) benchmark = StockConst.HS300_CODE # 基准(算相对收益) sliceIdx = None numOfDailySignal = 5 sliceTotalNum = None doPlot = True sliceDict = { 'sliceIdx': sliceIdx, 'numOfDailySignal': numOfDailySignal, 'sliceTotalNum': sliceTotalNum } signalColumnDict = { StockConst.TRADING_DAY_NAME: 'TradingDay', StockConst.WIND_CODE_NAME: 'WindCode', StockConst.TECH_NAME: 'Mom' } resultDic = BackTestMainNew.main( BackTestMainNew.read_func1, BackTestMainNew.select_stock_func1, BackTestMainNew.trade_func1, techList, sliceDict, signalDataAddr, dailyQuoteAddr, indexQuoteAddr, benchmark, '2005-01-04', '2005-12-31', doPlot, databaseDict, signalColumnDict) # result = resultDic['result'] #校验结果(每日净值) stockStatDailyDf = resultDic['stockStatDailyDf'] rowno = 1 lastNetValue = 0 for index, row in stockStatDailyDf.iterrows(): netValue = row['netValue'] tradeday = index if rowno > 1: if tradeday <= pd.Timestamp('2004-07-01'): diff = lastNetValue * (1.001) - netValue print( DateUtil.datetime2_str(tradeday) + ' ' + str(netValue) + ' ' + str(diff)) self.assertTrue(abs(diff) < 0.000000001) elif tradeday >= pd.Timestamp('2004-07-03'): diff = lastNetValue * (0.999) - netValue print( DateUtil.datetime2_str(tradeday) + ' ' + str(netValue) + ' ' + str(diff)) self.assertTrue(abs(diff) < 0.000000001) else: print( DateUtil.datetime2_str(tradeday) + ' ' + str(netValue)) lastNetValue = netValue rowno += 1
def handle_buy_list(tradingDay, dailyQuote, stockTradeList, currHoldSet, capitalEntity, actualBuyListMV): usableCash = capitalEntity.get_usable_cash() if usableCash == 0: return if len(actualBuyListMV) == 0: return # buyCash = usableCash/len(actualBuyList) #print('vol:'+vol) #partChangePCT = 0 # buyList全部可以买入 for actualDict in actualBuyListMV: innerCode = actualDict.get(StockConst.INNERCODE) buyCash = actualDict.get('MV') # 实际买入现金 buyPrice = actualDict.get('price') # 实际买入价格 # partialFlg = actualDict.get('partialFlg') # 实际是否部分买入 # dailyQuoteRow = SourceDataDao.selectByInnerCodeAndDate(dailyQuote,tradingDay,innerCode) #print('innerCode:'+str(innerCode)) #print(dailyQuoteRow) #可买 #if buyFlg != -1: #平均买入价(没有算佣金) # buyPrice = BackTestHelper.getVWap(dailyQuoteRow) #成本价(算佣金) cost = buyPrice*(1 + StockConst.BUY_COMMISSION / 100) #仓位(股) #vol = NumUtil.getRound(turnover/cost,StockConst.volScale) #佣金(元) commission = BackTestHelper.get_buy_commission(buyCash, StockConst.BUY_COMMISSION / 100) #买入市值 buyMV = buyCash - commission #更新可用金额(减少) capitalEntity.reduce_usable_cash(buyCash) #changePCT = NumUtil.getChangePCT(cost, closePrice, 2) #realChangePCT = (changePCT - StockConst.buyCommission) * vol / 100.0 #partChangePCT = partChangePCT + realChangePCT # #stockHold = StockHoldEntity.StockHoldEntity(tradingDay,innerCode,vol) #stockTrade = StockTradeEntity.StockTradeEntity(tradingDay, innerCode, 1, vol, cost, '', '') dateStr = DateUtil.datetime2_str(tradingDay) stockTradeDict = {'tradingDay':dateStr,'innerCode':innerCode,'type':1, 'price':buyPrice,'buyMV':buyMV,'sellMV':'','commission': commission, 'sellCash':'','buyCash':buyCash,'openDate':''} stockTradeList.append(stockTradeDict) #插入表 #stockHoldDF.setdefault(innerCode,stockHold) #当前持仓: a_innerCode,a_buyPrice,a_cost,a_openDate,a_buyMV,a_originBuyPrice,a_originBuyMV stockHoldEntity = StockHoldEntity.StockHoldEntity(innerCode, buyPrice, cost, DateUtil.datetime2_str(tradingDay), buyMV, buyPrice, buyMV) currHoldSet.setdefault(innerCode,stockHoldEntity) """
def main(): signalData = SourceDataDao.getSignalData() dailyQuote = SourceDataDao.getDailyQuote() #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] #select top 5 group by TradingDay order by Mom desc groupedSignalData = signalData.groupby(level='TradingDay').apply( SelectUtil.top, 5, 'Mom', False) #param #period = 5 startDate = '1/8/2001' #endDate = '1/1/2017' endDate = '18/1/2001' #time series dateList = DateUtil.get_date_list2(startDate, endDate) stockHoldDF = {} stockTradeDF = {} lastSignalData = pd.DataFrame() usableVol = 100 netValue = 1 stockStatDaily = pd.DataFrame(index=pd.date_range(startDate, endDate), columns=['netValue', 'changePCT']) for date in dateList.index: #print(date) dateStr = DateUtil.datetime2_str(date) #print(dateStr) #isinstance(date, datetime) #DateUtil.str2Datetime('20010108') # select by single date try: #print(1) currSignalData = groupedSignalData.ix[date] print("currSignalData:" + str(len(currSignalData))) print(currSignalData) except: #假期,双休日,原数据问题 print(DateUtil.datetime2_str(date) + ': no data') continue
def handle_sell_list(tradingDay, dailyQuote, stockTradeList, currHoldSet, capitalEntity, actualSellListMV): #partChangePCT = 0 dateStr = DateUtil.datetime2_str(tradingDay) if len(actualSellListMV) == 0: return #sellList全部可以卖出 for actualDict in actualSellListMV: innerCode = actualDict.get(StockConst.INNERCODE) sellMV = actualDict.get('MV') #实际卖出市值 sellPrice = actualDict.get('price') #实际卖出价格 isAdjust = actualDict.get('isAdjust') partialFlg = actualDict.get('partialFlg') #实际是否部分卖出 #print('innerCode:' + str(innerCode)) #try: # dailyQuoteRow = SourceDataDao.selectByInnerCodeAndDate(dailyQuote, tradingDay, innerCode) #except: #退市的股票: 查询不到行情,取最后一个交易日 #dailyQuoteRow = SourceDataDao.selectByLastDay(dailyQuote,innerCode) # print(dailyQuoteSingle) #可卖 #if sellFlg != -1: #actualSellList.append(innerCode) #全部卖出 if partialFlg is None: stockHoldEntity = currHoldSet.pop(innerCode) #部分卖出(更新持仓) elif partialFlg == 1: stockHoldEntity = currHoldSet.get(innerCode) #当前市值 currMV = BackTestHelper.get_sell_mv(stockHoldEntity.closePrice, stockHoldEntity.closeMV, sellPrice) #stockHoldEntity.buyPrice, stockHoldEntity.buyMV #卖掉部分后的市值 currMV = currMV - sellMV #更新持仓(价格,仓位,变更日) stockHoldEntity.set_last_trade_price(sellPrice) stockHoldEntity.set_last_trade_mv(currMV) stockHoldEntity.set_change_date(tradingDay) #vol = stockHoldEntity.vol # sellPrice = BackTestHelper.getVWap(dailyQuoteRow) #卖出市值(没有扣佣金) #turnover = sellPrice * vol # sellMV = BackTestHelper.getSellMV(stockHoldEntity.buyPrice, stockHoldEntity.buyMV, sellPrice) #佣金(元) commission = BackTestHelper.get_sell_commission(sellMV, StockConst.SELL_COMMISSION / 100) #卖出后所得资金(扣掉佣金后所得金额) sellCash = sellMV - commission # 更新可用金额(增加) capitalEntity.increase_usable_cash(sellCash) # 开仓日 openDate = stockHoldEntity.openDate # 加入交易表 stockTradeDict = {'tradingDay': dateStr, 'innerCode': innerCode, 'type': -1, 'price': sellPrice, 'buyMV': '', 'sellMV': sellMV, 'commission': commission, 'sellCash': sellCash,'buyCash':'','openDate':openDate,'isAdjust':isAdjust,'partialFlg':partialFlg} stockTradeList.append(stockTradeDict)
def testBackTestMainHill(self): techList = [StockConst.MOM] signalDataAddr = StockConst.ROOT + '/export/SignalDataHill.h5' dailyQuoteAddr = StockConst.ROOT + '/export/DailyQuoteHill.h5' sliceIdx = None numOfDailySignal = 5 sliceTotalNum = None sliceDict = { 'sliceIdx': sliceIdx, 'numOfDailySignal': numOfDailySignal, 'sliceTotalNum': sliceTotalNum } resultDic = BackTestMainNew.main(BackTestMainNew.select_stock_func1, BackTestMainNew.trade_func1, techList, sliceDict, signalDataAddr, dailyQuoteAddr, '2004-01-01', '2005-12-31') # result = resultDic['result'] #校验结果(每日净值) stockStatDailyDf = resultDic['stockStatDailyDf'] rowno = 1 lastNetValue = 0 for index, row in stockStatDailyDf.iterrows(): netValue = row['netValue'] tradeday = index if rowno > 1: if tradeday <= pd.Timestamp('2004-07-01'): diff = lastNetValue * (1.001) - netValue print( DateUtil.datetime2_str(tradeday) + ' ' + str(netValue) + ' ' + str(diff)) self.assertTrue(abs(diff) < 0.000000001) elif tradeday >= pd.Timestamp('2004-07-03'): diff = lastNetValue * (0.999) - netValue print( DateUtil.datetime2_str(tradeday) + ' ' + str(netValue) + ' ' + str(diff)) self.assertTrue(abs(diff) < 0.000000001) else: print( DateUtil.datetime2_str(tradeday) + ' ' + str(netValue)) lastNetValue = netValue rowno += 1
def handleBuyList(tradingDate,dailyQuote,stockTradeList,currHoldSet,capitalEntity,actualBuyList): usableCach = capitalEntity.get_usable_cash() if usableCach == 0: return if len(actualBuyList) == 0: return buyCach = usableCach/len(actualBuyList) #print('vol:'+vol) #partChangePCT = 0 # buyList全部可以买入 for innerCode in actualBuyList: dailyQuoteRow = SourceDataDao.select_by_inner_code_and_date(dailyQuote, tradingDate, innerCode) #print('innerCode:'+str(innerCode)) #print(dailyQuoteRow) #可买 #if buyFlg != -1: #平均买入价(没有算佣金) buyPrice = BackTestHelper.get_vwap(dailyQuoteRow) #成本价(算佣金) cost = buyPrice*(1 + StockConst.BUY_COMMISSION / 100) #仓位(股) #vol = NumUtil.getRound(turnover/cost,StockConst.volScale) #佣金(元) commission = BackTestHelper.get_buy_commission(buyCach, StockConst.BUY_COMMISSION / 100) #买入市值 buyMV = buyCach - commission #更新可用金额(减少) capitalEntity.reduce_usable_cash(buyCach) #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, '', '') dateStr = DateUtil.datetime2_str(tradingDate) stockTradeDict = {'tradingDate':dateStr,'innerCode':innerCode,'type':1, 'price':buyPrice,'buyMV':buyMV,'sellMV':'','commission': commission, 'sellCach':'','buyCach':buyCach,'openDate':''} stockTradeList.append(stockTradeDict) #插入表 #stockHoldDF.setdefault(innerCode,stockHold) #当前持仓 stockHoldEntity = StockHoldEntity.StockHoldEntity(innerCode, buyPrice, cost, DateUtil.datetime2_str(tradingDate), buyMV) currHoldSet.setdefault(innerCode,stockHoldEntity) """
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 handleSellList(tradingDate,dailyQuote,stockTradeList,currHoldSet,capitalEntity,actualSellList): #partChangePCT = 0 dateStr = DateUtil.datetime2_str(tradingDate) if len(actualSellList) == 0: return #sellList全部可以卖出 for innerCode in actualSellList: #print('innerCode:' + str(innerCode)) #try: dailyQuoteRow = SourceDataDao.select_by_inner_code_and_date(dailyQuote, tradingDate, innerCode) #except: #退市的股票: 查询不到行情,取最后一个交易日 #dailyQuoteRow = SourceDataDao.selectByLastDay(dailyQuote,innerCode) # print(dailyQuoteSingle) #可卖 #if sellFlg != -1: #actualSellList.append(innerCode) stockHoldEntity = currHoldSet.pop(innerCode) #vol = stockHoldEntity.vol sellPrice = BackTestHelper.get_vwap(dailyQuoteRow) #卖出市值(没有扣佣金) #turnover = sellPrice * vol sellMV = BackTestHelper.get_sell_mv(stockHoldEntity.buyPrice, stockHoldEntity.buyMV, sellPrice) #佣金(元) commission = BackTestHelper.get_sell_commission(sellMV, StockConst.SELL_COMMISSION / 100) #卖出后所得资金(扣掉佣金后所得金额) sellCach = sellMV - commission # 更新可用金额(增加) capitalEntity.increase_usable_cash(sellCach) # 开仓日 openDate = stockHoldEntity.openDate # 加入交易表 stockTradeDict = {'tradingDate': dateStr, 'innerCode': innerCode, 'type': -1, 'price': sellPrice, 'buyMV': '', 'sellMV': sellMV, 'commission': commission, 'sellCach': sellCach,'buyCach':'','openDate':openDate} stockTradeList.append(stockTradeDict) """ if DateUtil.datetime2Str(tradingDate) == '2014-12-09': print('-----handleSellList-----') print(DateUtil.datetime2Str(tradingDate)) print(innerCode) print(vol) print(sellPrice) print(turnoverValue) print(dailyQuoteRow) print('----------') """ #changePCT = NumUtil.getChangePCT(prevClosePrice, sellPrice, 2) #realChangePCT = (changePCT - StockConst.sellCommission) * vol / 100.0 #partChangePCT = partChangePCT + realChangePCT """
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 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(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 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 handleSellList(tradingDate, sellList, dailyQuote, usableVol, stockHoldDF, stockTradeList, currHoldSet, actualSellList, cannotSellList, capitalEntity, numOfActualBuy, signalData, prevHoldList, numOfDailyHolding): partChangePCT = 0 dateStr = DateUtil.datetime2_str(tradingDate) if len(sellList) == 0: return #卖出列表中要保留的股票数 numOfToKeepInSellList = numOfDailyHolding - numOfActualBuy - len( prevHoldList) #卖出数 > 实际买入数:对卖出列表进行排序 #if len(sellList) > numOfActualBuy: sellList = getToSellInSellList(sellList, tradingDate, signalData, dailyQuote, numOfToKeepInSellList, cannotSellList, currHoldSet) if len(sellList) == 0: return #numOfActualSell = 0 for innerCode in sellList: #print('innerCode:' + str(innerCode)) try: dailyQuoteRow = SourceDataDao.select_by_inner_code_and_date( dailyQuote, tradingDate, innerCode) except: #退市的股票: 查询不到行情,取最后一个交易日 dailyQuoteRow = SourceDataDao.selectByLastDay( dailyQuote, innerCode) #print('innerCode:' + str(innerCode)) # print(dailyQuoteSingle) #try: turnoverValue = dailyQuoteRow["TurnoverValue"] #except: #print('tradingDate:'+dateStr) #print('innerCode:' + str(innerCode)) #print(dailyQuoteRow) turnoverVolume = dailyQuoteRow["TurnoverVolume"] #prevClosePrice = dailyQuoteRow["PrevClosePrice"] #closePrice = dailyQuoteRow["ClosePrice"] #highPrice = dailyQuoteRow["HighPrice"] #lowPrice = dailyQuoteRow["LowPrice"] #sellFlg = dailyQuoteRow[StockConst.sellFlg] #buyFlg = dailyQuoteRow["buyFlg"] #sellFlg = dailyQuoteRow["sellFlg"] #非停牌 #check1 = not BackTestHelper.isStop(closePrice, turnoverValue) #非一字跌停: 可以卖出 #check2 = not BackTestHelper.isYiZiDieTing(highPrice,lowPrice,prevClosePrice) #可卖 #if sellFlg != -1: #实际卖出数不能大于实际买入数 #if numOfActualSell >= numOfActualBuy: #continue actualSellList.append(innerCode) stockHoldEntity = currHoldSet.pop(innerCode) vol = stockHoldEntity.vol sellPrice = turnoverValue / turnoverVolume #卖出后所得资金(没有扣佣金) turnover = sellPrice * vol # 佣金(元) commission = BackTestHelper.get_sell_commission( turnover, StockConst.SELL_COMMISSION / 100) # 扣掉佣金后所得金额 turnover = turnover - commission # 更新可用金额(增加) capitalEntity.increase_usable_cash(turnover) # 加入交易表 stockTradeDict = { 'tradingDate': tradingDate, 'innerCode': innerCode, 'type': -1, 'vol': vol, 'price': sellPrice, 'turnover': turnover, 'commission': commission } stockTradeList.append(stockTradeDict) #实际卖出数 #numOfActualSell += 1 """ if DateUtil.datetime2Str(tradingDate) == '2014-12-09': print('-----handleSellList-----') print(DateUtil.datetime2Str(tradingDate)) print(innerCode) print(vol) print(sellPrice) print(turnoverValue) print(dailyQuoteRow) print('----------') """ #changePCT = NumUtil.getChangePCT(prevClosePrice, sellPrice, 2) #realChangePCT = (changePCT - StockConst.sellCommission) * vol / 100.0 #partChangePCT = partChangePCT + realChangePCT """
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 handleBuyList(tradingDate, buyList, dailyQuote, usableVol, stockHoldDF, stockTradeList, currHoldSet, actualBuyList, cannotBuyList, capitalEntity): usableCach = capitalEntity.get_usable_cash() if usableCach == 0: return #if usableVol == 0: #return 0 if len(buyList) == 0: return #可买列表 buyList = getToBuyInBuyList(buyList, dailyQuote, tradingDate, cannotBuyList) if len(buyList) == 0: return 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[StockConst.TURNOVER_VALUE] turnoverVolume = dailyQuoteRow[StockConst.TURNOVER_VOLUME] #buyFlg = dailyQuoteRow[StockConst.buyFlg] #可买 #if buyFlg != -1: #actualBuyList.append(innerCode) #平均买入价(没有算佣金) buyPrice = turnoverValue / turnoverVolume #成本价(算佣金) cost = buyPrice * (1 + StockConst.BUY_COMMISSION / 100) #仓位(股) #vol = NumUtil.getRound(turnover/cost,StockConst.volScale) #佣金(元) commission = BackTestHelper.get_buy_commission( turnover, StockConst.BUY_COMMISSION / 100) #买入市值 buyMV = turnover - commission #更新可用金额(减少) 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': 0, 'price': buyPrice, 'turnover': turnover, 'commission': commission, 'MV': buyMV } stockTradeList.append(stockTradeDict) #插入表 #stockHoldDF.setdefault(innerCode,stockHold) #当前持仓 stockHoldEntity = StockHoldEntity.StockHoldEntity( innerCode, vol, buyPrice, cost, DateUtil.datetime2_str(tradingDate)) #tradingDate, currHoldSet.setdefault(innerCode, stockHoldEntity) #vol """
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
def main(): signalData = SourceDataDao.getSignalData() dailyQuote = SourceDataDao.getDailyQuote() #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] #select top 5 group by TradingDay order by Mom desc groupedSignalData = signalData.groupby(level='TradingDay').apply(SelectUtil.top,5,'Mom',False) #param period = 5 startDate = '1/8/2001' #endDate = '1/1/2017' endDate = '1/18/2001' #time series dateList = DateUtil.get_date_list2(startDate, endDate) currHoldSet = {} stockHoldDF = {} stockTradeDF = {} #lastSignalData = pd.DataFrame() usableVol = 100; netValue = 1; stockStatDaily = pd.DataFrame(index=pd.date_range(startDate, endDate), columns=['netValue','changePCT','buyCnt','sellCnt','holdCnt']) for date in dateList.index: #print(date) dateStr = DateUtil.datetime2_str(date) #print(dateStr) #isinstance(date, datetime) #DateUtil.str2Datetime('20010108') # select by single date try: #print(1) currSignalData = groupedSignalData.ix[date] print("currSignalData:"+str(len(currSignalData))) #print(2) buyList = getBuyList(currSignalData,lastSignalData) #print(3) sellList = getSellList(currSignalData,lastSignalData) #print(4) holdList = getHoldList(currSignalData,lastSignalData) #print(currSignalData) #print("len:"+str(len(currSignalData))) except: #假期,双休日,原数据问题 print(DateUtil.datetime2_str(date) + ': no data') continue buyCnt = len(buyList) sellCnt = len(sellList) holdCnt = len(holdList) dailyChangePCT = 0 changePCTBuy = handleBuyList(date,buyList,dailyQuote,usableVol,stockHoldDF,stockTradeDF) releasedVol = getReleasedVol(sellList, stockHoldDF) usableVol = usableVol + releasedVol changePCTSell = handleSellList(date,sellList,dailyQuote,usableVol,stockHoldDF,stockTradeDF) #changePCTHold = handleHoldList(date, sellList, dailyQuote, usableVol, stockHoldDF, stockTradeDF) changePCTHold = 0 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) #print("netValue:" + str(netValue)) stockStatDaily.ix[dateStr] = netValue,dailyChangePCT,buyCnt,sellCnt,holdCnt #innerCodeList = currSignalData["InnerCode"] #print(innerCodeList) #lastSignalData = currSignalData print(stockStatDaily)
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(): signalData = SourceDataDao.getSignalData() dailyQuote = SourceDataDao.getDailyQuote() #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] #select top 5 group by TradingDay order by Mom desc groupedSignalData = signalData.groupby(level='TradingDay').apply( SelectUtil.top, 5, 'Mom', False) #param #period = 5 #startDate = '1/8/2001' startDate = '1/8/2001' #endDate = '1/1/2017' endDate = '2/18/2002' #endDate = '12/31/2016' #endDate = '12/31/2002' #time series #dateList = DateUtil.getDateList2(startDate,endDate) currHoldSet = {} stockHoldDF = {} stockTradeDF = {} #lastSignalData = pd.DataFrame() usableVol = 100 netValue = 1 #初始化每日统计表 stockStatDaily = pd.DataFrame(index=pd.date_range(startDate, endDate), columns=[ 'netValue', 'changePCT', 'buyCnt', 'sellCnt', 'prevHoldCnt', 'currHoldCnt', 'cannotSellCnt', 'cannotBuyCnt' ]) #从信号表中取得唯一性日期 dateList = SourceDataDao.select_date_from_signal(signalData, startDate, endDate) for date in dateList: #for date in dateList.index: #print(date) 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) #except: #假期,双休日,原数据问题 #if StockConst.isDebug: #print(DateUtil.datetime2Str(date) + ': no data') #continue dailyChangePCT = 0 actualSellList = [] actualBuyList = [] cannotSellList = [] cannotBuyList = [] #1.sell changePCTSell = handleSellList(date, sellList, dailyQuote, usableVol, stockHoldDF, stockTradeDF, currHoldSet, actualSellList, cannotSellList) usableVol = calculateUsableVol(currHoldSet) #2.buy changePCTBuy = handleBuyList(date, buyList, dailyQuote, usableVol, stockHoldDF, stockTradeDF, currHoldSet, actualBuyList, cannotBuyList) #3.hold changePCTHold = handleHoldList(date, prevHoldList, dailyQuote, usableVol, stockHoldDF, stockTradeDF, currHoldSet) #changePCTHold = 0 buyCnt = len(actualBuyList) sellCnt = len(actualSellList) prevHoldCnt = len(prevHoldList) currHoldCnt = len(currHoldSet) cannotSellCnt = len(cannotSellList) cannotBuyCnt = len(cannotBuyList) if StockConst.IS_DEBUG: 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) #print("netValue:" + str(netValue)) stockStatDaily.ix[ dateStr] = netValue, dailyChangePCT, buyCnt, sellCnt, prevHoldCnt, currHoldCnt, cannotSellCnt, cannotBuyCnt #innerCodeList = currSignalData["InnerCode"] #print(innerCodeList) #lastSignalData = currSignalData #每日统计(收益,净值,买入数,卖出数,持有数) stockStatDaily = stockStatDaily.dropna(how='all') print('每日统计:') print(stockStatDaily) stockStatDaily.to_csv('F:\export\stockStatDaily.csv') # 每年统计 yearList = StockYearService.main(stockStatDaily) print('每年统计:') print(yearList) # 最大回撤 maxdrop = StockMaxDropNewService.get_max_drop(stockStatDaily) print('最大回撤:') print(maxdrop) #每年的最大回撤 maxdropList = StockMaxDropNewService.get_max_drop_for_each_year( stockStatDaily) maxdropList.sort_values(by=["year"]) print('每年的最大回撤:') print(maxdropList) #夏普比率 sharpRatio = SharpRatioNewService.get_sharp_ratio(stockStatDaily) print('夏普比率:') print(sharpRatio) #每年的夏普比率 sharpRatioList = SharpRatioNewService.get_sharp_ratio_for_each_year( stockStatDaily) sharpRatioList.sort_values(by=["year"]) print('每年的夏普比率:') print(sharpRatioList)