PageRenderTime 4641ms CodeModel.GetById 24ms RepoModel.GetById 2ms app.codeStats 0ms

/ParaBond/src/scaly/parabond/test/NPortfolio02.scala

http://scaly.googlecode.com/
Scala | 179 lines | 78 code | 48 blank | 53 comment | 8 complexity | 9a65332d67433f6a345f077d075c8916 MD5 | raw file
  1. /*
  2. * Copyright (c) Scaly Contributors
  3. * See CONTRIBUTORS.TXT for a full list of copyright holders.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of the Scaly Project nor the
  13. * names of its contributors may be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
  17. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
  20. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  23. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. package scaly.parabond.test
  28. import org.scalatest.junit.JUnitSuite
  29. import org.junit.Assert._
  30. import org.junit.Test
  31. import scaly.parabond.mr.MapReduce
  32. import com.mongodb.casbah.MongoConnection
  33. import com.mongodb.casbah.commons.MongoDBObject
  34. import com.mongodb.casbah.MongoCursor
  35. import scaly.parabond.util.MongoHelper
  36. import scaly.parabond.value.SimpleBondValuator
  37. import scala.util.Random
  38. import scaly.parabond.util.Helper
  39. import scaly.parabond.util.Data
  40. import scaly.parabond.util.Result
  41. /**
  42. * This class implements the composite serial algorithm.
  43. * @author Ron Coleman, Ph.D.
  44. */
  45. class NPortfolio02 {
  46. /** Number of bond portfolios to analyze */
  47. val PORTF_NUM = 100
  48. /** Connect to the parabond DB */
  49. val mongo = MongoConnection(MongoHelper.getHost)("parabond")
  50. /** Initialize the random number generator */
  51. val ran = new Random(0)
  52. /** Write a detailed report */
  53. val details = false
  54. @Test
  55. def test {
  56. // Set the number of portfolios to analyze
  57. val arg = System.getProperty("n")
  58. val n = if(arg == null) PORTF_NUM else arg.toInt
  59. var me = this.getClass().getSimpleName()
  60. var outFile = me + "-dat.txt"
  61. var fos = new java.io.FileOutputStream(outFile,true)
  62. var os = new java.io.PrintStream(fos)
  63. os.print(me+" "+ "N: "+n+" ")
  64. val details = if(System.getProperty("details") != null) true else false
  65. // Build the portfolio list
  66. val inputs = for(i <- 0 until n) yield Data(ran.nextInt(100000)+1,null,null)
  67. val list = inputs.toList
  68. // Parallel map the input
  69. val now = System.nanoTime
  70. val outputs = inputs.map(price)
  71. val t1 = System.nanoTime
  72. // Generate the detailed output report
  73. if(details) {
  74. println("%6s %10.10s %-5s %-2s".format("PortId","Price","Bonds","dt"))
  75. outputs.foreach { output =>
  76. val id = output.id
  77. val dt = (output.result.t1 - output.result.t0) / 1000000000.0
  78. val bondCount = output.result.bondCount
  79. val price = output.result.price
  80. println("%6d %10.2f %5d %6.4f %12d %12d".format(id, price, bondCount, dt, output.result.t1 - now, output.result.t0 - now))
  81. }
  82. }
  83. // Compute the "inner" time
  84. val dt1 = outputs.foldLeft(0.0) { (sum, output) =>
  85. sum + (output.result.t1 - output.result.t0)
  86. } / 1000000000.0
  87. // Compute the "outer" time
  88. val dtN = (t1 - now) / 1000000000.0
  89. val speedup = dt1 / dtN
  90. val numCores = Runtime.getRuntime().availableProcessors()
  91. val e = speedup / numCores
  92. os.println("dt(1): %7.4f dt(N): %7.4f cores: %d R: %5.2f e: %5.2f ".
  93. format(dt1,dtN,numCores,speedup,e))
  94. os.flush
  95. os.close
  96. println(me+" DONE! %d %7.4f".format(n,dtN))
  97. }
  98. /**
  99. * Prices a portfolio using the "basic" algorithm.
  100. */
  101. def price(input: Data): Data = {
  102. // Value each bond in the portfolio
  103. val t0 = System.nanoTime
  104. // Connect to the portfolio collection
  105. val portfsCollecton = mongo("Portfolios")
  106. // Retrieve the portfolio
  107. val portfId = input.id
  108. val portfsQuery = MongoDBObject("id" -> portfId)
  109. val portfsCursor : MongoCursor = portfsCollecton.find(portfsQuery)
  110. // Get the bonds ids in the portfolio
  111. val bondIds = MongoHelper.asList(portfsCursor,"instruments")
  112. // Connect to the bonds collection
  113. val bondsCollection = mongo("Bonds")
  114. // Price each bond and sum all the prices
  115. val value = bondIds.foldLeft(0.0) { (sum, id) =>
  116. // Get the bond from the bond collection
  117. val bondQuery = MongoDBObject("id" -> id)
  118. val bondCursor: MongoCursor = bondsCollection.find(bondQuery)
  119. val bond = MongoHelper.asBond(bondCursor)
  120. // Price the bond
  121. val valuator = new SimpleBondValuator(bond, Helper.curveCoeffs)
  122. val price = valuator.price
  123. // The price into the aggregate sum
  124. sum + price
  125. }
  126. // Update the portfolio price
  127. MongoHelper.updatePrice(portfId,value)
  128. val t1 = System.nanoTime
  129. Data(portfId,null,Result(portfId,value,bondIds.size,t0,t1))
  130. }
  131. }