コード例 #1
0
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
コード例 #2
0
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
コード例 #3
0
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
コード例 #4
0
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
コード例 #5
0
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)
コード例 #6
0
ファイル: BackTestMain.py プロジェクト: dxcv/backtest-2
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
コード例 #7
0
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
コード例 #8
0
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
コード例 #9
0
ファイル: BackTestMain.py プロジェクト: dxcv/backtest-2
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
コード例 #10
0
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
コード例 #11
0
ファイル: BackTestMain.py プロジェクト: dxcv/backtest-2
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
コード例 #12
0
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
コード例 #13
0
    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
コード例 #14
0
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
コード例 #15
0
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)
コード例 #16
0
 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)
コード例 #17
0
 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)
コード例 #18
0
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)
コード例 #19
0
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)
コード例 #20
0
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