株のポジション管理を出来るようにしたいと思っています
- 大分放置してしまいましたが、ちょっとずつ再開します。
- まずは銘柄一覧をブラウザから見えるようにします。
- http://kabusapo.com/ranking/ からダウンロードしたcsvファイルを case クラスにパースしてmongoDBにインサート→ mongoDBからフェッチして画面表示しました
- クライアントなどは前回のTODO管理で作ったものをほとんど再利用しています。
コード
Stock.scala
package services.domain import org.mongodb.scala.bson.ObjectId import org.mongodb.scala.bson.codecs.Macros._ import org.mongodb.scala.bson.codecs.DEFAULT_CODEC_REGISTRY import org.bson.codecs.configuration.CodecRegistries.{fromRegistries, fromProviders} case class Stock(_id: ObjectId, code: String, name: String, market: String, industryType: String, unit: Int, isNK225: Boolean) object Stock { def apply(code: String, name: String, market: String, industryType: String, unit: Int, isNK225: Boolean): Stock = new Stock(new ObjectId, code, name, market, industryType, unit, isNK225) implicit val codecRegistry = fromRegistries(fromProviders(classOf[Stock]), DEFAULT_CODEC_REGISTRY) }
Entityクラスはこんな感じで書きました。
* mongoDBのユニークキーであるObjectId
を生成してからインスタンス化するようにしています。
* codecRegistry は クラスとJsonのマッパーのようなものだと解釈しています。
StockRepositry.scala
package services.repository import java.util.concurrent.atomic.AtomicBoolean import javax.inject.Singleton import org.mongodb.scala.{MongoClient, MongoCollection} import play.Environment import services.domain.Stock import services.repository.Helpers._ import scala.io.Source @Singleton class StockRepository { val mongoClient = MongoClient() val database = mongoClient.getDatabase("database").withCodecRegistry(Stock.codecRegistry) val initialized = new AtomicBoolean() def toStock(data: String): Stock = { val el = data.split(",") Stock(el(0), el(1), el(2), el(3), safeStringToInt(el(4)).getOrElse(0), if (el.length > 5) "1".equals(el(5)) else false) } def initializeIfNeeded(): Unit = { if (initialized.get()) { return } val collection: MongoCollection[Stock] = database.getCollection("stock") collection.drop().results() val s = Source.fromFile(Environment.simple().getFile("data/stocklist.csv"), "UTF-8") val lines = s.getLines().toList val stocks: List[Stock] = lines.tail.map(l => toStock(l)).toList collection.insertMany(stocks).results() this.initialized.set(true) } def getStockList(): List[Stock] = { initializeIfNeeded() val collection: MongoCollection[Stock] = database.getCollection("stock") return collection.find().results().toList } def safeStringToInt(str: String): Option[Int] = { import scala.util.control.Exception._ catching(classOf[NumberFormatException]) opt str.toInt } }
AtomicBoolean を初期化済みフラグとして、初期化されていなかったらファイルの読み込み→インサートとしています。
- ホントはファイルをダウンロードしたいんだけど上手く行かなかった...
tail
を使うことで1列目を読み飛ばす(= ヘッダーを読み飛ばす)ことが出来ます。
val stocks: List[Stock] = lines.tail.map(l => toStock(l)).toList
- 文字列からオブジェクトにパースする際に、単元株数の列に"単元制度なし"というレコードが有ったので(#^ω^)ピキピキ
def safeStringToInt(str: String): Option[Int] = { import scala.util.control.Exception._ catching(classOf[NumberFormatException]) opt str.toInt }
といったメソッドで Option を返すようにしています。
結果
こんな感じになりました。
次にやること
- まずは kendo-ui で上手くフィルタリング出来るようにしたい
- ポジションを登録できるようにする
- 時価をうまい具合に取れるようにする
- お気に入り銘柄(ウォッチリスト)を作れるようにする
くらいですかね。ちょっとずつ頑張ります。