PageRenderTime 35ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 0ms

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

http://scaly.googlecode.com/
Scala | 178 lines | 78 code | 48 blank | 52 comment | 8 complexity | 5a8eb1db9248c7592bf1fe1e7dfcee16 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 uses parallel collections to price n portfolios in the
  43. * parabond database using the composite "naive" algorithm.
  44. * @author Ron Coleman
  45. */
  46. class Par00 {
  47. /** Number of bond portfolios to analyze */
  48. val PORTF_NUM = 100
  49. /** Connect to the parabond DB */
  50. val mongo = MongoConnection(MongoHelper.getHost)("parabond")
  51. /** Initialize the random number generator */
  52. val ran = new Random(0)
  53. /** Write a detailed report */
  54. val details = false
  55. @Test
  56. def test {
  57. // Set the number of portfolios to analyze
  58. val arg = System.getProperty("n")
  59. val n = if(arg == null) PORTF_NUM else arg.toInt
  60. var me = this.getClass().getSimpleName()
  61. var outFile = me + "-dat.txt"
  62. var fos = new java.io.FileOutputStream(outFile,true)
  63. var os = new java.io.PrintStream(fos)
  64. os.print(me+" "+ "N: "+n+" ")
  65. val details = if(System.getProperty("details") != null) true else false
  66. // Build the portfolio list
  67. val inputs = for(i <- 0 until n) yield Data(ran.nextInt(100000)+1,null,null)
  68. val list = inputs.toList
  69. // Parallel map the input
  70. val now = System.nanoTime
  71. val outputs = inputs.par.map(price)
  72. val t1 = System.nanoTime
  73. // Generate the detailed output report
  74. if(details) {
  75. println("%6s %10.10s %-5s %-2s".format("PortId","Price","Bonds","dt"))
  76. outputs.foreach { output =>
  77. val id = output.id
  78. val dt = (output.result.t1 - output.result.t0) / 1000000000.0
  79. val bondCount = output.result.bondCount
  80. val price = output.result.price
  81. println("%6d %10.2f %5d %6.4f %12d %12d".format(id, price, bondCount, dt, output.result.t1 - now, output.result.t0 - now))
  82. }
  83. }
  84. val dt1 = outputs.foldLeft(0.0) { (sum, output) =>
  85. sum + (output.result.t1 - output.result.t0)
  86. } / 1000000000.0
  87. val dtN = (t1 - now) / 1000000000.0
  88. val speedup = dt1 / dtN
  89. val numCores = Runtime.getRuntime().availableProcessors()
  90. val e = speedup / numCores
  91. os.println("dt(1): %7.4f dt(N): %7.4f cores: %d R: %5.2f e: %5.2f ".
  92. format(dt1,dtN,numCores,speedup,e))
  93. os.flush
  94. os.close
  95. println(me+" DONE! %d %7.4f".format(n,dtN))
  96. }
  97. /**
  98. * Prices a portfolio using the "basic" algorithm.
  99. */
  100. def price(input: Data): Data = {
  101. // Value each bond in the portfolio
  102. val t0 = System.nanoTime
  103. // Connect to the portfolio collection
  104. val portfsCollecton = mongo("Portfolios")
  105. // Retrieve the portfolio
  106. val portfId = input.id
  107. val portfsQuery = MongoDBObject("id" -> portfId)
  108. val portfsCursor : MongoCursor = portfsCollecton.find(portfsQuery)
  109. // Get the bonds ids in the portfolio
  110. val bondIds = MongoHelper.asList(portfsCursor,"instruments")
  111. // Connect to the bonds collection
  112. val bondsCollection = mongo("Bonds")
  113. // Price each bond and sum all the prices
  114. val value = bondIds.foldLeft(0.0) { (sum, id) =>
  115. // Get the bond from the bond collection by its key id
  116. val bondQuery = MongoDBObject("id" -> id)
  117. val bondCursor: MongoCursor = bondsCollection.find(bondQuery)
  118. val bond = MongoHelper.asBond(bondCursor)
  119. // Price the bond
  120. val valuator = new SimpleBondValuator(bond, Helper.curveCoeffs)
  121. val price = valuator.price
  122. // The price into the aggregate sum
  123. sum + price
  124. }
  125. // Update the portfolio price
  126. MongoHelper.updatePrice(portfId,value)
  127. val t1 = System.nanoTime
  128. Data(portfId,null,Result(portfId,value,bondIds.size,t0,t1))
  129. }
  130. }