Edited at

リアルタイム為替レートをとってみた

More than 3 years have passed since last update.

最近、インベスターZというマンガに影響され投資に興味を持った。

証券口座作ってみたりして遊んでいると、FXの口座は開設するといくらかキャッシュバックがもらえるところが多いことに気づき、DMM.com証券とか開いてみた。

お仕事はプログラマをやっているということで、やっぱシステムトレードとかそういうの興味を持ってしまう。世の中には為替取引をREST APIで提供している企業があるらしい。APIがあるなら繋ぎたい。そう思うのがWebエンジニアである。(タブン)


OANDAというところがREST APIを提供している

最近サイトのリニューアルをしたらしい。

http://markezine.jp/release/detail/468817

口座開設しないとAPIたたけないんだろうなーと思っていたが、sandboxでは必要ないらしい。(※なお、ガチ環境でやるときは25万円入金している状態でアクセストークンの発行を行わないといけない。)

FXはキャッシュバックの半分が吹っ飛んでいる程度に負けているのであんまやる気しないんですが、為替レート、jsonで取れるならとってみたい。


JavaのサンプルをScalaに書き換えてみた

javaのサンプルがここに。mavenとjavaがあれば動かせられる。

https://github.com/oanda/java-api-streaming

そんまま真似してscalaで書いてみた。

sbtがあれば動くはず。

https://github.com/oshiro-kazuma/oanda-scala-stream-api


おっおっおっ

取れとる・・・

USD_JPYとEUR_JPYを取得してみた。

sbt "run-main PriceStream"

{"tick":{"instrument":"EUR_JPY","time":"2015-01-29T15:30:09.099175Z","bid":142.564,"ask":142.584}}
{"tick":{"instrument":"USD_JPY","time":"2015-01-29T15:30:38.746838Z","bid":114.86,"ask":114.874}}
{"tick":{"instrument":"USD_JPY","time":"2015-01-29T15:30:41.068148Z","bid":114.859,"ask":114.875}}
{"tick":{"instrument":"EUR_JPY","time":"2015-01-29T15:30:42.749457Z","bid":142.564,"ask":142.585}}
{"tick":{"instrument":"USD_JPY","time":"2015-01-29T15:31:06.279973Z","bid":114.861,"ask":114.875}}
{"tick":{"instrument":"EUR_JPY","time":"2015-01-29T15:31:06.333618Z","bid":142.565,"ask":142.588}}
{"tick":{"instrument":"EUR_JPY","time":"2015-01-29T15:31:06.334019Z","bid":142.566,"ask":142.587}}
{"tick":{"instrument":"EUR_JPY","time":"2015-01-29T15:31:06.437200Z","bid":142.565,"ask":142.588}}
{"tick":{"instrument":"EUR_JPY","time":"2015-01-29T15:31:06.814322Z","bid":142.566,"ask":142.587}}


そ、、それで・・・?

そ、、そそれだけです。

scalaでBufferedReaderをうまいこと回す方法を学べたのは良かったかと。

// print realtime prices

Stream.continually(br.readLine())
.takeWhile(_ ne null)
.filterNot(_.contains("heartbeat"))
.foreach(println)

と思ったが、こっちのほうが断然良かった。

val bs: BufferedSource = Source.fromInputStream(entity.getContent)

bs.getLines()
.filter(!_.contains("heartbeat"))
.foreach(println)

初めは以下っぽく書いていたんですがscalaでコレは辛いかな、と思い。

var line: String = ""

while ({line = br.readLine()); line != null}) { // do something }


Dispatch使ったほうが3倍簡単でした

object Hoge extends App {

import dispatch._, Defaults._
import scala.concurrent.duration._

val endpoint = "http://stream-sandbox.oanda.com/v1/prices?instruments=USD_JPY"
val request = Http(url(endpoint) > as.stream.Lines(printer))

def printer(line: String) = line match {
case l if l.contains("heartbeat") => // nothing to do.
case l => println(l)
}

Await.result(request, Duration.Inf)

}