PageRenderTime 28ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

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

http://scaly.googlecode.com/
Scala | 171 lines | 77 code | 49 blank | 45 comment | 7 complexity | 0db9fe8d0e7859899143b13d9e411464 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 com.mongodb.casbah.MongoConnection
  29. import com.mongodb.casbah.commons.MongoDBObject
  30. import com.mongodb.casbah.MongoCursor
  31. import scaly.parabond.util.MongoHelper
  32. import scaly.parabond.value.SimpleBondValuator
  33. import org.scalatest.junit.JUnitSuite
  34. import org.junit.Assert._
  35. import org.junit.Test
  36. import scala.util.Random
  37. import scaly.parabond.util.Helper
  38. /**
  39. * This class implements the composite serial algorithm.
  40. * @author Ron Coleman, Ph.D.
  41. */
  42. class NPortfolio00 {
  43. /** Number of bond portfolios to analyze */
  44. val PORTF_NUM = 100
  45. /** Connects to the parabond DB */
  46. val mongo = MongoConnection(MongoHelper.getHost)("parabond")
  47. /** Initialize the random number generator */
  48. val ran = new Random(0)
  49. /** Write a detailed report */
  50. val details = true
  51. /** Record captured with each result */
  52. case class Result(id: Int, price: Double, bondCount: Int, t0: Long, t1: Long)
  53. @Test
  54. def test {
  55. // Set the number of portfolios to analyze
  56. val arg = System.getProperty("n")
  57. val n = if(arg == null) PORTF_NUM else arg.toInt
  58. var me = this.getClass().getSimpleName()
  59. var outFile = me + "-dat.txt"
  60. var fos = new java.io.FileOutputStream(outFile,true)
  61. var os = new java.io.PrintStream(fos)
  62. os.print(me+" "+ "N: "+n+" ")
  63. val details = if(System.getProperty("details") != null) true else false
  64. val input = (1 to n).foldLeft(List[(Int,List[Double])]()) { (list, p) =>
  65. val r = ran.nextInt(100000)+1
  66. list ::: List((r,Helper.curveCoeffs))
  67. }
  68. val now = System.nanoTime
  69. val results = input.foldLeft(List[Result]()) { (sum, p) =>
  70. // Value each bond in the portfolio
  71. val t0 = System.nanoTime
  72. // Connect to the portfolio collection
  73. val portfsCollecton = mongo("Portfolios")
  74. // Retrieve the portfolio
  75. val (portfId, coeffs) = p
  76. val portfsQuery = MongoDBObject("id" -> portfId)
  77. val portfsCursor: MongoCursor = portfsCollecton.find(portfsQuery)
  78. // Get the bonds in the portfolio
  79. val bondIds = MongoHelper.asList(portfsCursor, "instruments")
  80. // Connect to the bonds collection
  81. val bondsCollection = mongo("Bonds")
  82. val value = bondIds.foldLeft(0.0) { (sum, id) =>
  83. // Get the bond from the bond collection
  84. val bondQuery = MongoDBObject("id" -> id)
  85. val bondCursor: MongoCursor = bondsCollection.find(bondQuery)
  86. val bond = MongoHelper.asBond(bondCursor)
  87. // Price the bond
  88. val valuator = new SimpleBondValuator(bond, Helper.curveCoeffs)
  89. val price = valuator.price
  90. // Add the price into the aggregate sum
  91. sum + price
  92. }
  93. MongoHelper.updatePrice(portfId,value)
  94. val t1 = System.nanoTime
  95. Result(portfId,value,bondIds.size,t0,t1) :: sum
  96. }
  97. val t1 = System.nanoTime
  98. // Generate the output report
  99. if (details) {
  100. println("%6s %10.10s %-5s %-2s".format("PortId", "Price", "Bonds", "dt"))
  101. results.reverse.foreach { result =>
  102. val id = result.id
  103. val dt = (result.t1 - result.t0) / 1000000000.0
  104. val bondCount = result.bondCount
  105. val price = result.price
  106. println("%6d %10.2f %5d %6.4f %12d %12d".format(id, price, bondCount, dt, result.t1 - now, result.t0 - now))
  107. }
  108. }
  109. val dt1 = results.foldLeft(0.0) { (sum,result) =>
  110. sum + (result.t1 - result.t0)
  111. } / 1000000000.0
  112. val dtN = (t1 - now) / 1000000000.0
  113. val speedup = dt1 / dtN
  114. val numCores = Runtime.getRuntime().availableProcessors()
  115. val e = 1.0
  116. os.println("dt(1): %7.4f dt(N): %7.4f cores: %d R: %5.2f e: %5.2f ".
  117. format(dt1,dtN,numCores,speedup,e))
  118. os.flush
  119. os.close
  120. println(me+" DONE! %d %7.4f".format(n,dtN))
  121. }
  122. }