def testNPVPortfolioTEST1(self):
        portfolio = Portfolio.objects.get(name='TEST1',user='******')
        modelPositions = portfolio.modelposition_set.filter(asOf=self.pricingDate)
        for modelPosition in modelPositions:
            position = CreatePosition(modelPosition)
            portfolio.addPosition(position)
        marketDataContainer = MarketDataContainer.MarketDataContainer()
        for position in portfolio.positions:
#            print position
            marketDataContainer.add(position.marketData(pricingDate=self.pricingDate, marketId=self.marketId))
            position.marketDataContainer = marketDataContainer
            
 #       print portfolio.NPV(pricingDate=self.pricingDate, marketId=self.marketId)
        self.failIf(round(portfolio.NPV(pricingDate=self.pricingDate, marketId=self.marketId),2) <> 76669.51)
    def calc(self):
#        print 'in calc'
        startDjangoPositions = ModelPosition.objects.filter(portfolio=self.portfolio, asOf=self.start)
        for djangoPosition in startDjangoPositions:
            position = CreatePosition(djangoPosition)
            self.portfolio.addPosition(position)
        marketDataContainer = MarketDataContainer()
        for position in self.portfolio.positions:
 #           print position
            marketDataContainer.add(position.marketData(pricingDate=self.start, marketId=self.marketId))
        for position in self.portfolio.positions:
            position.marketDataContainer = marketDataContainer
        self.startValue = self.portfolio.NPV(pricingDate=self.start,marketId=self.marketId)
  #      print 'Start value = %f' % self.startValue
        
        endPortfolio =Portfolio.objects.get(name=self.portfolio.name,user=self.portfolio.user)
        endDjangoPositions = ModelPosition.objects.filter(portfolio=endPortfolio, asOf=self.end)
        for djangoPosition in endDjangoPositions:
            position = CreatePosition(djangoPosition)
            endPortfolio.addPosition(position)
        marketDataContainer = MarketDataContainer()
        for position in endPortfolio.positions:
            marketDataContainer.add(position.marketData(pricingDate=self.end, marketId=self.marketId))
        for position in endPortfolio.positions:
            position.marketDataContainer = marketDataContainer
        self.endValue = endPortfolio.NPV(pricingDate=self.end,marketId=self.marketId)
   #     print 'End portfolio value = %f' % self.endValue

        #Adjust all positions but Cash ADD and REMOVE transactions so that I do not count them
        #We ignore the interest effect of these transactions
        transactions = Transaction.objects.filter(portfolio=endPortfolio,
                                                  transactionType = TransactionType('ADD'),
                                                  positionType = PositionType('CASH'),
                                                  ticker = 'Cash',
                                                  transactionDate__range=[self.start,self.end])

        #print transactions
        for transaction in transactions:
            self.transactionValue -= transaction.amount
            
        transactions = Transaction.objects.filter(portfolio=endPortfolio,
                                                  transactionType = TransactionType('REMOVE'),
                                                  positionType = PositionType('CASH'),
                                                  ticker = 'Cash',
                                                  transactionDate__range=[self.start,self.end])
        #print transactions
        for transaction in transactions:
            self.transactionValue += transaction.amount

        self.endValue += self.transactionValue
        #print 'Effective end value = %f' % self.endValue
        try:
            self.annualPerformance = ((self.endValue - self.startValue) / self.startValue) * \
                                    365.0 / (self.end.ql() - self.start.ql())   
        except ZeroDivisionError:
            self.annualPerformance = 0
        self.periodPerformance = self.annualPerformance * (self.end.ql() - self.start.ql()) / 365.0
        #print 'Annualized Performance is %f' % self.annualPerformance
        self.upToDate = True
 def testCalculatePerformanceTEST1Portfolio1Y(self):
     #load portfolio as of start and value
     #load portfolio as of end and value
     #sum up all ADD and REMOVE Transaction
     #% return = {end - start + SUM(ADD) - SUM(REMOVE)} / Start
     startPortfolio =Portfolio.objects.get(name='TEST1')
     start = Date(month=8,day=30,year=2011)
     startDjangoPositions = ModelPosition.objects.filter(portfolio=startPortfolio, asOf=start)
     for djangoPosition in startDjangoPositions:
         position = CreatePosition(djangoPosition)
         startPortfolio.addPosition(position)
     marketDataContainer = MarketDataContainer()
     for position in startPortfolio.positions:
         marketDataContainer.add(position.marketData(pricingDate=start, marketId=self.marketId))
     for position in startPortfolio.positions:
         position.marketDataContainer = marketDataContainer
     startValue = startPortfolio.NPV(pricingDate=start,marketId=self.marketId)
     print 'Start value = %f' % startValue
     
     endPortfolio =Portfolio.objects.get(name='TEST1')
     end = Date(month=9,day=12,year=2011)
     endDjangoPositions = ModelPosition.objects.filter(portfolio=endPortfolio, asOf=end)
     for djangoPosition in endDjangoPositions:
         position = CreatePosition(djangoPosition)
         endPortfolio.addPosition(position)
     marketDataContainer = MarketDataContainer()
     for position in endPortfolio.positions:
         marketDataContainer.add(position.marketData(pricingDate=end, marketId=self.marketId))
     for position in endPortfolio.positions:
         position.marketDataContainer = marketDataContainer
     endValue = endPortfolio.NPV(pricingDate=end,marketId=self.marketId)
     print 'End value = %f' % endValue
     
     #Should add the looping over transactions that are ADD and REDUCE
     
     print 'Annualized Performance is %f' % (((endValue - startValue) / startValue) * 365.0 / (end.ql() - start.ql()))
Beispiel #4
0
    def run(self):
        #Log
        if os.path.isfile(self.logFile):
            os.remove(self.logFile)
        logFileHandle = open(self.logFile,'w')
        logFileHandle.write('Running batch as of %s\n' % self.batchDate)
        logFileHandle.write('Max batch is %s\n' % self.maxBatchDate)
#        if QuantLib.TARGET().isBusinessDay(self.batchDate.ql()) == False:
 #           logFileHandle.write('Not a good business date based on QuantLib TARGET calendar. Exiting ...')
  #          print('Not a good business date based on QuantLib TARGET calendar. Exiting ...')
        
        #Update locations with date
        logFileHandle.write('\nUpdating all locations except TEST1 with new date\n')
        locations = Location.objects.filter(~Q(name='TEST1'))
        for location in locations:
            logFileHandle.write('Updating location %s\n' % location.name)
            location.pricingDate = self.batchDate.toPythonDate()
            location.save()
        
        #Load Equity prices
        logFileHandle.write('\nLoading equity prices\n')
        equities = Equity.objects.all()
        equityLoader = EquityPriceLoader()
        for equity in equities:
            #skip TEST1 and TEST2 as they are only used for testing
            if equity.ticker in ['TEST1', 'TEST2']:
                continue
            if StockPrice.objects.filter(equity=equity, pricingDate=self.batchDate, marketId=self.marketId).exists() == True:
                logFileHandle.write('%s price exists\n' % equity.ticker)
                continue
            else:
                logFileHandle.write('Loading prices for equity %s\n' % equity.ticker)
                try:
                    equityLoader.loadCurrentPriceFromYahoo(secId=equity.ticker, 
                                                           today=self.batchDate,
                                                           marketId=self.marketId)
                except MarketDataMissing:
                    logFileHandle.write('No market data loaded for %s as of %s\n' % (equity.ticker, self.batchDate))
                    logFileHandle.write('As default loading price from last batch date\n')
                    lastPrice = StockPrice.objects.get(equity=equity, pricingDate=self.maxBatchDate, marketId=self.marketId)
                    lastPrice.pricingDate = self.batchDate
                    lastPrice.pk = None
                    lastPrice.save()
                   
        #Load Interest Rates        
        logFileHandle.write('\nLoading Interest Rates\n')
        if self.maxBatchDate != self.batchDate:
            logFileHandle.write('For now just copy rates from max batch date to current batch date\n')
            curve = InterestRateCurve.objects.get(ccy=Currency('USD'), index=Index('LIBOR'), 
                                                  term=TimePeriod('M'), numTerms=3, 
                                                  pricingDate=self.maxBatchDate, 
                                                  marketId='EOD')
            curve.loadRates()
            
            newCurve = InterestRateCurve(ccy=Currency('USD'), index=Index('LIBOR'), 
                                         term=TimePeriod('M'), numTerms=3, 
                                         pricingDate=self.batchDate, 
                                         marketId='EOD')
            
            for rate in curve.getRates():
                newRate = InterestRate(type=rate.type, term=rate.term, numTerms=rate.numTerms, mid=rate.mid, curve=newCurve)
                logFileHandle.write('Rate: %s/%d/%0.2f\n' % (rate.term, rate.numTerms, rate.mid*100))
                newCurve.addRate(newRate)
            newCurve.save()

        #Copy OAS forward and keep constant
        logFileHandle.write('\nCopying OAS from max batch date to batch date\n')
        if self.maxBatchDate != self.batchDate:
            bondOAS = BondOAS.objects.get(tCBond=TCBond.objects.get(name='PortAuth_4.00_JAN42'),
                                          marketId='EOD', pricingDate=self.maxBatchDate)
            bondOAS.pk = None
            bondOAS.pricingDate = self.batchDate
            bondOAS.save()
            
        #Process Positions
        logFileHandle.write('\nProcessing positions\n')
        #load all positions with the max date
        #if the batchDate greater than maxbatchdate then copy position to batchdate (roll position forward)
        if self.maxBatchDate < self.batchDate:
            positions = ModelPosition.objects.filter(asOf=self.maxBatchDate)
            for position in positions:
                logFileHandle.write('Copying position %s from max batch date to batch date\n' % position)
                position.pk = None
                position.asOf = self.batchDate
                position.save()

        #Update Positions based on Transactions
        logFileHandle.write('\nUpdating of positions based on transaction\n')
        transactions = Transaction.objects.filter(reflectedInPosition=False)
        if len(transactions) == 0:
            logFileHandle.write('No transactions to process\n')
        else:
            for transaction in transactions:
                logFileHandle.write('Processing transaction %s\n' % str(transaction))
                positions = transaction.relatedPositions()
                for position in positions:
                    logFileHandle.write('Processing position %s\n' % str(transaction))
                    transaction.updatePositionAmount(position=position)  
                    position.save() 
                transaction.reflectedInPosition = 'True'
                transaction.save()                 
            
        #Performance
        logFileHandle.write('\nRunning Performance Report\n')
        if os.path.isfile(self.perfFile):
            os.remove(self.perfFile)
        perfFileHandle = open(self.perfFile,'w')
        portfolios = Portfolio.objects.filter(user='******')
        startValue = 0
        endValue = 0
        for portfolio in portfolios:
            performanceCalculator = PerformanceCalculator(start=self.productionStartDate,
                                                          end=self.batchDate,
                                                          portfolio=portfolio,
                                                          marketId=self.marketId)
            perfFileHandle.write(performanceCalculator.report()+'\n')
            startValue += performanceCalculator.startValue
            endValue += performanceCalculator.endValue
            endValue += performanceCalculator.transactionValue
        
        if startValue == 0 or (self.batchDate.ql() - self.productionStartDate.ql()) == 0:
            overallPerformance = 0
        else:
            overallPerformance = ((endValue - startValue) / startValue) * 365.0 / (self.batchDate.ql() - self.productionStartDate.ql())
        perfFileHandle.write('Overall Period Performance = %.2f%%\n' % (overallPerformance*100.0/365.0*(self.batchDate.ql() - self.productionStartDate.ql())))
        perfFileHandle.write('Overall Annual Performance = %.2f%%' % (overallPerformance*100.0))
        perfFileHandle.close()
        
        #MTM and Positions
        logFileHandle.write('\nRunning MTM and Positions Report\n')
        totalValue = 0
        if os.path.isfile(self.mtmFile):
            os.remove(self.mtmFile)
        mtmFileHandle = open(self.mtmFile,'w')
        portfolios =Portfolio.objects.filter(user='******')
        mtmFileHandle.write('MTM Report as of %s\n' % self.batchDate)
        for portfolio in portfolios:
            mtmFileHandle.write('Portfolio=%s\n' % portfolio.name)
            modelPositions = ModelPosition.objects.filter(portfolio=portfolio, asOf=self.batchDate)
            for modelPosition in modelPositions:
                position = CreatePosition(modelPosition=modelPosition)
                portfolio.addPosition(position)
            marketDataContainer = MarketDataContainer()
            for position in portfolio.positions:
                marketDataContainer.add(position.marketData(pricingDate=self.batchDate, marketId=self.marketId))
            for position in portfolio.positions:
                position.marketDataContainer = marketDataContainer
            for position in portfolio.positions:
                positionValue = position.NPV(pricingDate=self.batchDate,marketId=self.marketId)
                mtmFileHandle.write('ModelPosition=%s with %.0f shares, asset type %s and value $%s\n' % (position.secId,
                                                                                                   position.amount,
                                                                                                   position.getAssetType(),
                                                                                                   fToDC(positionValue)))
            portfolioValue = portfolio.NPV(pricingDate=self.batchDate,marketId=self.marketId)
            mtmFileHandle.write('Portfolio value=$%s\n\n' % fToDC(portfolioValue))
            totalValue += portfolioValue
        mtmFileHandle.write('Total value=%s\n\n' % fToDC(totalValue))

        #Asset Allocation
        #allocations is associative array with value
        allocations = {}
        totalValue = 0
        for item in AssetType.choices:
            allocations[item[0]] = 0
        logFileHandle.write('\nRunning Allocation Report\n\n')
        if os.path.isfile(self.allocationFile):
            os.remove(self.allocationFile)
        allocationFileHandle = open(self.allocationFile,'w')
        portfolios =Portfolio.objects.filter(user='******')
        allocationFileHandle.write('Allocation Report as of %s\n\n' % self.batchDate)
        for portfolio in portfolios:
            if portfolio.name == 'TradeAug2013':
                continue
            modelPositions = ModelPosition.objects.filter(portfolio=portfolio, asOf=self.batchDate)
            for modelPosition in modelPositions:
                position = CreatePosition(modelPosition)
                portfolio.addPosition(position)
            marketDataContainer = MarketDataContainer()
            for position in portfolio.positions:
                marketDataContainer.add(position.marketData(pricingDate=self.batchDate, marketId=self.marketId))
            for position in portfolio.positions:
                position.marketDataContainer = marketDataContainer
            for position in portfolio.positions:
                npv = position.NPV(pricingDate=self.batchDate, marketId=self.marketId)
                allocations[str(position.getAssetType())] += npv
                totalValue += npv
        
        orderedAllocations = OrderedDict(sorted(allocations.items(),key=lambda t: t[1],reverse=True))
        for key in orderedAllocations.keys():
            try:
                allocationPercent = Allocation.objects.get(assetType=AssetType(key)).percent
            except:
                allocationPercent = 0.0
            try:
                actualAllocation = 100*orderedAllocations[key]/totalValue
            except:
                actualAllocation = 0.0
            allocationFileHandle.write('%s=%.0f%%\t\t\t\t\t\twith target %.0f%%\t and value $%s\n' % (key,
                                                                                           actualAllocation,
                                                                                           100*allocationPercent,
                                                                                           fToD(orderedAllocations[key])))
        
        logFileHandle.write('Batch completed\n')
        logFileHandle.close()
        
        #Every time I run the batch and it succeeds we need to save the batch info
        self.batch.save()