HHR’s diary

日記は無理でも週記…いや、月記でがんばろう。

OANDA(つーかFIX API)で自動売買プログラム作成が大変

前回↓から約1年(!)、とりあえずFIX APIでレート取得が出来ました。

hhr.hatenablog.com

いやー、牛歩もいいところですね。

まぁ、実際のとろこはほとんど放置状態だったんですが。

たまにOANDAのドキュメント読んでFIX APIわかんねーって悶ていただけ…

しかし!

さるGWに一念発起しまして、OANDAのFIX APIを使っての自動売買プログラム作成を再開しました!

GWなら取引時間内での検証も出来ますしね。

これ結構重要で、放置の理由にFIX APIわからんということもあったのですが、むしろFXは平日しかレートが動いていないということの方が放置の原因だったり。

株も同じですが平日しか取引していないのはやっぱりやりづらいですね。

まぁ、株は平日の日中のみに対して、FXは平日であれば24時間取引しているので気合があればなんとかなるんですが…

僕にはその気合は無かった…

(´・ω・`)

それはさておき、GWにわりとガッツリ取り組んでから約二ヶ月、とりあえずレート取得のみですが一週間連続で安定稼動させることが出来ました。

前回同様、なかなか分かりづらい点が有ったので、そのことも含めてやったことを書き残そうかと思います。

先に作った物の概要。

# 実行例
$ java -jar \
    -Dpassword=$PASS \
    -Daccount=$ACCOUNT \
    -Dsymbols=USD/JPY,EUR/JPY \
    fix-prototype-1.5-SNAPSHOT.jar
  • 標準出力にレート
USD/JPY Mon May 29 09:22:23 JST 2017 111.239 0.008
USD/JPY Mon May 29 09:22:23 JST 2017 111.24 0.008
EUR/JPY Mon May 29 09:22:23 JST 2017 124.264 0.013
USD/JPY Mon May 29 09:22:23 JST 2017 111.242 0.008
USD/JPY Mon May 29 09:22:23 JST 2017 111.242 0.008
6 12, 2017 4:55:02 午前 com.example.FixApplication onMessage
重大: Notes on market data entry: Halted
6 13, 2017 9:32:02 午前 quickfix.Session disconnect
情報: [FIX.4.4:hogehoge->OANDA/RATES:testusr1-Session1] Disconnecting: Encountered END_OF_STREAM
6 13, 2017 9:32:03 午前 quickfix.mina.initiator.IoSessionInitiator$ConnectTask resetIoConnector
情報: [FIX.4.4:hogehoge->OANDA/RATES:testusr1-Session1] - reset IoConnector

以上。

ではでは、以下について記していこうと思います。

  • OANDAサンプル付属のcfg
    • DataDictionary
    • StartTimeとEndTime
    • その他
  • Tips
    • JMX
    • FileLogPath
    • cfgのシステムProperty展開機能

OANDAサンプル付属のcfg

OANDAにFIX APIの設定をしてもらう際、サンプルのJavaアプリケーションを貰えます。

そのサンプルには、FIXにおける設定ファイルに相当するcfgファイルが含まれており、そのcfgファイルに自身のアカウントとパスワードを記述することによってサンプルJavaアプリケーションを動作させることができます。
(詳細は前回記事を参照)

このcfgを自作のFIXアプリケーションでそのまま利用するとハマります…

UseDataDictionary

OANDAのサンプルFIXアプリケーション付属のcfgではUseDataDictionary=Nが指定されています。

にも関わらず、DataDictionary=FIX42.xmlが指定されています。

UseDataDictionary=Nだと意味がないはずなんですが…

それはさておき、QuickFIX/Jのドキュメントを読む感じではこの指定方法だとrepeating groupsが作用せずにうまく値が取得できないはずです。

実際、自分が作成したFIXアプリケーションではこの指定方法でrepeating groupsがうまく作用せずに値が取れない状況になり、随分とハマりました。

具体的にどうなるかというと、例えば↓のFIXメッセージはとある時点でのUSD/JPYのbitとofferですが、

8=FIX.4.4 9=211 35=W 34=4 49=OANDA 50=RATES 52=20170620-09:09:19.900
56=account-id 55=USD/JPY 262=1497949759660 268=2 269=0 270=111.612
271=3000000 272=20170620 273=09:09:17 269=1 270=111.62 271=3000000
272=20170620 273=09:09:17 10=165

(読みやすいように整形)

repeating groupsが効いていない状態では、bitの値しか取れません…

だがしかし、OANDAのサンプルFIXアプリケーションはうまく動作しているようです。

OANDAサンプルもQuickFIX/Jを使っているっぽいのですが…

謎です…

/(^o^)\

それはさておき、UseDataDictionary=Yにしなければならないということはわかったのですが、

DataDictionaryどこでゲットすんの?

ってなります。

これはわりとすぐに解決してQuickFIX/Jのリポジトリを漁ったら発見しました。

後は簡単。

src/main/resources/に発見したDataDictionaryファイル(FIX44.xml)を置いておけばmaven-resources-pluginがbuild時に良しなにやってくれます。

これでrepeating groupsが作用して、先ほどの例でのbitしか取れない問題が解決してbitとofferの値がきちんと取れるようになります。

めでたしめでたし。

と思いきや、続きがあります。

ふと、OANDAのサンプルFIXアプリケーションはどうなっているんだろう、と思い立って漁ってみたらquickfixj-all-1.4.0-oanda.jarなる意味深なjarを読み込んで実行していることを発見。

jarの中身を見てみると、ありましたFIX44.xml

QuickFIX/Jリポジトリにあるものと比べてみると結構diffがあり、ざっと見た感じquickfixj-all-1.4.0-oanda.jarにあったDataDictionaryのほうが良さそうだったのでこっちを使うことにしました。

我ながらよく気がついたなぁと思います(ドヤァァ

めでたしめでたし。

余談ですが、OANDAのサンプルFIXアプリケーションはやっぱりツッコミどころ満載だと思います。

実行可能jarが配置されているにもかかわらず、その中身らしきclassファイルが別途、置かれています。

何のために?

Javaソースコードをそのまま置いてほしかったっす…

StartTimeとEndTime

自作のFIXアプリケーションを何日か連続稼働していると、必ず1日1回、決まった時間にセッションを貼り直している(再起動している)ログに気が付きました。

なんでだろなーっと思ってドキュメントを調べているとOANDAサンプルのcfgの指定方法だとdailyなアプリケーションの設定になっていることがわかりました。

その設定値が表題のStartTimeとEndTimeです。

この2つの設定のみだとアプリケーションはdailyでセッションを貼り直します。

歴史的経緯でしょうか。

少なくとも現在のOANDAは月曜朝のオープンから土曜朝のクローズまでダウンタイム無しで稼働しているようなのでweeklyの設定に変更しました。

これは簡単でStartDayとEndDayを追加して何曜日の何時オープンで何曜日の何時にクローズかを指定するだけです。

具体的には↓な感じ。

StartDay=sun
StartTime=19:55:00
EndDay=fri
EndTime=21:05:00

念のため、ゆとりを持たせて5分ずつ前後に挟んでいます。

が、運用実績的に1分もいらないかなぁという感想です。

めでたしめでたし。

その他

FIXプロトコルにもVersionがいくつかあるようで、OANDAのサンプルFIXアプリケーションでは4.2が指定されていたのですが、ドキュメントを読む限り4.4の方が勝手が良さそうなので4.4に変更しました。

ちなみに、前述の通り、OANDAのサンプルFIXアプリケーションには4.4のDataDictionaryが含まれています。

なして4.2指定なの…

Tips

いやー、いろいろとハマったのは辛かったんですが、そのかいあってか調べている過程でいろいろな機能を発見できました。

その中から使えるなーと思った機能は自作のFIXアプリケーションに取り込んでいます。

せっかくなので、それらを紹介しようと思います。

JMX

Javaあるあるのアレです。JConsoleとかでつなぐ奴。

これを有効化するといろいろと便利になる奴です。(問われる語彙力w

QuickFIX/JがJmxExporterクラスを用意してくれているので有効化はとっても簡単。

new JmxExporter().register(initiator);

これだけ。

そーすると何が嬉しいかというと、いろいろとあるんですが、おおきく以下の2つがあります。

  • (ヒープの利用状況などの)メトリクスの可視化
  • ログレベルの動的変更

それぞれについて記載します。

メトリクスの可視化

24時間365日とまでいかなくても、5日間連続稼動させると気になることがあります。

メモリリークとかGCとかGCとか。

JMX + JConsoleを使うと簡単にメトリクスを見れるので便利です。

5日間連続稼動を何回か繰り返し運用してみた感じだと大体↓な傾向が見れました。

  • Max80MBのヒープで動作
  • GCで0.5秒くらいSTW
    • 週1回発生
    • CPUがAtomなので…

ヒープ使用率やGCの時間などを監視&通知までできるとベストですが、ただでさえ牛歩なのでいったんはこれで満足としましょう(諦め大事

ただ、0.5秒のGCはなんとかしたいなぁ…

G1GCとか検証したいとは思います。

ログレベルの動的変更

アプリケーション起動時のログレベルはinfoです。

つーかロギングの設定を何もしていないのでデフォルトの動作なんですがw

まぁ、それはゆくゆくやるとして、 JConsoleを使うとアプリケーション起動後、つまり動作中に動的にログレベルを変更できます。

やり方は簡単で、JConsleのMBeansタブ→左のBeans一覧からjava.util.logging→Logging→Operations→setLoggerLevel(p1,p2)のp1にクラス名(例:com.example.FixApplication)、p2にログレベルを入れて実行するだけ。

ちなみにですが、QuickFIX/J関連も同様の手順でいろいろできます。

リセットとかHeartBeat送信とか。

FileLogPath

cfgの設定にFileLogPathという項目があります。

こいつにパスを指定するだけでイベントと送受信FIXメッセージを指定したパスにロギングしてくれます。

例えば、↓をcfgに記述すると、

[LOGGING]
FileLogPath=log/

↓なログファイルが生成されます。

$ tail -n5 log/FIX.4.4-hoge0011-OANDA_RATES-testusr2-Session1.event.log
20170625-09:20:25: Session FIX.4.4:hoge0011->OANDA/RATES:testusr2-Session1 schedule is daily, 00:00:00-UTC - 00:00:00-UTC
20170625-09:20:25: Created session: FIX.4.4:hoge0011->OANDA/RATES:testusr2-Session1
20170625-09:20:27: Initiated logon request
20170625-09:20:28: Logon contains ResetSeqNumFlag=Y, resetting sequence numbers to 1
20170625-09:20:28: Received logon
$ tail -n5 log/FIX.4.4-hoge0011-OANDA_RATES-testusr2-Session1.messages.log | tr "^A" " "
8=FIX.4.4 9=421 35=B 34=2 49=OANDA 50=RATES 52=20170625-09:20:28.497 56=hoge0011 33=4 58=version: 2.4.21 (fxTrade rates server 03 [3,130] 1498382428 163.49.210.211) 58=notice: Market Data Request now supports new MarketDepth and MDUpdateType settings 58=notice: halted pairs are now marked QuoteCondition=B Text=Halted 58=notice: please include the complete server version string in all support requests 148=OANDA FIX Server Information 10=213
8=FIX.4.4 9=158 35=V 34=2 49=hoge0011 52=20170625-09:20:28.553 56=OANDA 57=RATES 262=1498382428547 263=1 264=1 265=1 146=3 55=USD/JPY 55=EUR/JPY 55=EUR/USD 267=2 269=0 269=1 10=206
8=FIX.4.4 9=243 35=W 34=3 49=OANDA 50=RATES 52=20170625-09:20:28.801 56=hoge0011 55=USD/JPY 262=1498382428547 268=2 269=0 270=111.258 271=3000000 272=20170623 273=20:59:59 276=B 58=Halted 269=1 270=111.34 271=3000000 272=20170623 273=20:59:59 276=B 58=Halted 10=231
8=FIX.4.4 9=244 35=W 34=4 49=OANDA 50=RATES 52=20170625-09:20:28.801 56=hoge0011 55=EUR/USD 262=1498382428547 268=2 269=0 270=1.11922 271=3000000 272=20170623 273=20:59:59 276=B 58=Halted 269=1 270=1.11953 271=3000000 272=20170623 273=20:59:59 276=B 58=Halted 10=026
8=FIX.4.4 9=244 35=W 34=5 49=OANDA 50=RATES 52=20170625-09:20:28.801 56=hoge0011 55=EUR/JPY 262=1498382428547 268=2 269=0 270=124.515 271=3000000 272=20170623 273=20:59:59 276=B 58=Halted 269=1 270=124.606 271=3000000 272=20170623 273=20:59:59 276=B 58=Halted 10=035

とくにmessages.logはAcceptanceテスト用の入力データ(↓な感じらしい)に使えそうです。

I8=FIX.4.2␁35=A␁34=1␁49=TW␁52=<time>␁56=ISLD␁98=0␁108=30␁
E8=FIX.4.2␁9=57␁35=A␁34=1␁49=ISLD␁52=00000000-00:00:00␁56=TW␁98=0␁108=30␁10=0␁

ただし、全てのFIXメッセージをロギングするのでディスクを大量消費する点と、ログインパスワードもロギングされちゃうので扱いに注意です><

cfgのシステムProperty展開機能

cfgに↓のように記述するとJavaのシステムPropertyを展開することができます。

SenderCompID=${account}
# アカウントIDをhoge0011にして実行
$ java -jar -Daccount=hoge0011 fix-prototype-1.5-SNAPSHOT.jar

これ、とっても便利です。

なのにドキュメントに書いていないですorz

QuickFIX/Jのコード読んでいて違和感を感じて、デバッガでステップ実行してやっと気が付きました。

ドキュメントェ

これまた、我ながらよく気がついたなぁと思います(ドヤァァ

まとめ

ふぅ。疲れた。

FIXつらたん。

編集後記

上記以外にもMarketDataRequestでの値の取得方法がいまいちわからずGithubを検索したりと牛歩要因がほんとに多いなと思いました。

果たして完成する日は来るのか…

自動売買の道のりは長いンゴねぇ…

今後、特にやりたいことリストです。

  • Acceptance(受け入れ)テストの導入
    • 単体テストもまだですが…
    • これができると取引時間外の土日での開発が捗る(はず)
  • order(売買)実装
    • 何をトリガーとして売買するかが悩みどころ
    • とりあえず、単純に移動平均線に触れたことをトリガーにする

ちなみにですが、OANDAのルールがわりと大きく変更されています。

FIX使うにはプロコース必須になって、スプレッドが0.8銭になったり。

ぐぬぬ

OANDA Japan

OANDAのデモ口座でFIX APIを使えるまでの手順が難解

前回↓から2週間、とりあえずデモ口座APIの疎通確認まで出来ました。

hhr.hatenablog.com

なかなか分かりづらい点が有ったので、そのことも含めて書き残そうかと思います。

先にまとめ。

  • APIは3種類でSDKは今回スルー
    1. REST
    2. OANDA独自SDK(Java)
    3. FIX(FX業界デファクトプロトコルらしい)
  • デモ口座REST APIは本番口座開設不要(たぶん)
  • SDK(Java)とFIXは口座開設必須
    • なおかつデモ口座も必要
  • 本番&デモ口座でRESTで動作確認
  • 本番&デモ口座でFIXのサンプルで動作確認

以下、自分が行ったことを時系列で記します。

ではでは。

口座開設

特筆すべきことは無いです。

今年からマイナンバーが増えて面倒臭くなりました。が、これに限った話ではないです。

本人確認書類、マイナンバーの提出は、最近よくある画像ファイルアップロード形式でした。
自分はスマホでパシャリと両方ともに表裏を撮影してアップしました。

不備は生じなかったようで、翌日には「簡易書留でID&パス送付しましたー」的なメールを受信、その週のうちに受け取れてログインまで出来ました。

最近は早くて良いンゴねぇ。

余談ですが、よく見かける「◯分で完了」をOANDAさんも謳うのですが、ご多分に漏れず、無理っす。入力、早すぎんだろ。

OANDA Japan

入金

API紹介ページ↓に「API使うなら25万入金してねっ」とあるのでログイン後の入金画面から入金手続きをします。

www.oanda.jp

他のFX業者と同じく即時入金が可能です。
そのため、すぐさまAPI利用手続きに進むことが出来ます。

API利用手続き

ログイン後のトップ画面にAPI関連の項目があるので、そこを辿って行くと以下の2つが表示されます。

1つずつやっていきます。

REST API

こちらは簡単。

アクセスするとおもむろにアクセストークンの発行、と出るのでクリック。

アクセストークンが即時、発行されます。

ドキュメント通りに叩いてみます。

$ curl -H "Authorization: Bearer アクセストークン" \
    https://api-fxtrade.oanda.com/v1/accounts
{
        "accounts" : [
                {
                        "accountId" : ****,
                        "accountName" : "hogehoge",
                        "accountCurrency" : "JPY",
                        "marginRate" : 0.04
                }
        ]
}

やっほい。

ちなみに、本番口座のアクセストークンがバレると/(^o^)\です。どこかの誰かに口座の残高が溶かされます。たぶん。
そんなリスクを抱え込むOANDAはやっぱり攻めてるなぁ。

FIX、Java API

こちらはやっかい。

アクセスするとまず、FIX or Javaの選択があります。

JavaとあるのはおそらくOANDA独自SDKのことです。
こちらは日本語ドキュメントが無い、かつ、英語ドキュメント内にあるJavaDocのコピーライトが2005と不安を煽るので今回はスルー。

ということで、FIXを選択。

次に、OANDA fxTrade PracticeのIDの入力欄があります。

※デモにてAPIをご利用になられる場合は、下記にご利用になるデモのログインIDを記載してください。 後程弊社からご連絡いたします。

とあるので、適当なIDを入力すれば後で連絡が来るのかな、と思って適当な文字列を入力しました。

これ、間違いでした。

後述します。

入力完了後、すぐにメールを受信します。おおよそ以下の旨が記載されています。

  • 本番口座のAPI設定が完了したよ
  • デモ口座は設定後にまた連絡すんね
  • サンプルはココね(URL)

ふむふむ。

待てとのことなのでデモ口座は置いといて、とりま、本番口座でサンプルを試してみます。

サンプルを提示されたURLからダウンロードして、zipだったので展開して、READMEは無くlogファイルを見るも何も書いてない…

batファイルがあるので起動するとサッと落ちる…

仕方がないのでbatファイルをテキストエディタで開いて、絶対パスでCドライブ直下にzip展開想定ってマジかよなんか別のbat呼んでるあっ設定ファイルっぽいの指定してるlogファイルって実行時ログファイルかよ設定ファイルの説明がねぇJavaかよshell実行ファイルあるのに使われてねぇーetc…

と、奮闘します。(割愛)

そして…

C:\fix_sample\fix-client>java -Xmx32m -Djava.util.logging.config.file=etc/logging.properties -jar fix-client.jar etc/client.cfg

Created session FIX.4.2:****->OANDA/TEST:testusr1-Session1

IN:
========
+-HEADER
|    8  BeginString               = FIX.4.2
|    9  BodyLength                = 82
|   34  MsgSeqNum                 = 1
|   35  MsgType                   = A
|   49  SenderCompID              = OANDA
|   50  SenderSubID               = TEST
|   52  SendingTime               = 20160716-14:41:54.350
|   56  TargetCompID              = ****
+-BODY
|   98  EncryptMethod             = NONE_OTHER (0)
|  108  HeartBtInt                = 60
|  141  ResetSeqNumFlag           = YES_RESET_SEQUENCE_NUMBERS (Y)
+-TRAILER
|   10  CheckSum                  = 129
+-END OF MESSAGE

IN:
========
+-HEADER
|    8  BeginString               = FIX.4.2
|    9  BodyLength                = 425
|   34  MsgSeqNum                 = 2
|   35  MsgType                   = B
|   49  SenderCompID              = OANDA
|   50  SenderSubID               = TEST
|   52  SendingTime               = 20160716-14:41:54.350
|   56  TargetCompID              = ****
+-BODY
|   33  LinesOfText               = 4
|  148  Headline                  = OANDA FIX Server Information
|   33  LinesOfText (count = 4)
|   58  Text                      = version: 2.4.21 (fxTrade Practice order server [3,45] 1468680114 ***.***.***.***)
|   58  Text                      = notice: Market Data Request now supports new MarketDepth and MDUpdateType settings
|   58  Text                      = notice: halted pairs are now marked QuoteCondition=B Text=Halted
|   58  Text                      = notice: please include the complete server version string in all support requests
+-TRAILER
|   10  CheckSum                  = 040
+-END OF MESSAGE

Operations will be executed as **** with FIX.4.2 command

[M]: Market Data Request
[O]: Market Order
[E]: Entry Order
[L]: Limit Order
[T]: Stop Order
[C]: Cancel Order
[F]: Modify Order
[S]: Order Status
[R]: Enter Raw Text Message
[D]: Delay
[U]: Choose FIX User

---------------------------

[Q]: Quit

Choose Command >

キタ━━━━(゚∀゚)━━━━!!

[M]: Market Data Requestのコマンドから為替レート取得等、動作確認が出来ました。

しかし早いです。簡易書留を受け取ったら当日中にAPI使えます。
デモ口座じゃなくて本番口座ですが。

デモ口座API利用手続き

さて、目的はデモ口座でのAPI利用です。

前回も書きましたが、本番口座でAPI利用とか怖すぎるので、目的であるデモ口座でのAPI利用手続きを進めます。

さきほど、本番口座のFIX利用手続きと一緒にデモ口座利用の手続きをして「設定後にまた連絡すんね」と有りましたが、しばらく経っても連絡が有りませんでした。

ということでサポートに問合せます。

以下、意訳。

僕「まだっすか?」

サ「お前の言うデモ口座IDなんて存在しねぇよ。デモ口座開設してね♡」

衝撃の事実。

ということで、デモ口座を開設します。
こちらは開設フォーム入力後すぐにログイン出来ました。やったー。

デモ口座にログインして本番口座同様トップ画面からAPI関連の項目を辿って行きますが、本番口座にはあったFIXの利用手続き画面が有りません…

むむむ。

僕「デモ口座ID取ってログインしたけど見っかんねーんだけど。どうすればいいかおせーて?」

と、ここで本番口座FIX API利用手続き時のOANDA fxTrade PracticeのID入力欄を思い出します。

まさかと思い、本番口座にログインしてFIX API利用手続き画面のOANDA fxTrade PracticeのIDに取得したデモ口座IDを入力して決定します。

僕「本番口座のFIX利用手続きでデモ口座ID入れて送ったけど、あってる?」

サ「おk」

fxTrade Practiceってデモ口座かーい!

サ「あと、デモ口座のFIX利用、設定したンゴ」

はやっ

何はともあれ、無事にデモ口座でFIXが使えるとの事なので、早速、さきほどのサンプルで設定ファイルを書き換えて実行してみます。

C:\fix_sample\fix-client>java -Xmx32m -Djava.util.logging.config.file=etc/logging.properties -jar fix-client.jar etc/client.cfg

Created session FIX.4.2:****->OANDA/TEST:testusr1-Session1
Session FIX.4.2:****->OANDA/TEST:testusr1-Session1 disconnected
Could not logon to FIX server; Exiting.

ファッ

接続できんとな。

僕「接続できん」

サ「デモ口座はドメイン違うンゴ。これな。っfxgame-fix.oanda.com」

どこにも書いてないやんけ…

fxgame site:www.oanda.jp - Google 検索

サ「あと、APIはサポ外な。海外事業部に聞いて。あ、英語な」

サーセン

気を取り直して、設定ファイルを修正して実行します。

C:\fix_sample\fix-client>java -Xmx32m -Djava.util.logging.config.file=etc/logging.properties -jar fix-client.jar etc/client.cfg

Created session FIX.4.2:****->OANDA/TEST:testusr1-Session1

IN:
========
+-HEADER
|    8  BeginString               = FIX.4.2
|    9  BodyLength                = 82
|   34  MsgSeqNum                 = 1
|   35  MsgType                   = A
|   49  SenderCompID              = OANDA
|   50  SenderSubID               = TEST
|   52  SendingTime               = 20160716-15:21:22.904
|   56  TargetCompID              = ****
+-BODY
|   98  EncryptMethod             = NONE_OTHER (0)
|  108  HeartBtInt                = 60
|  141  ResetSeqNumFlag           = YES_RESET_SEQUENCE_NUMBERS (Y)
+-TRAILER
|   10  CheckSum                  = 126
+-END OF MESSAGE

IN:
========
+-HEADER
|    8  BeginString               = FIX.4.2
|    9  BodyLength                = 416
|   34  MsgSeqNum                 = 2
|   35  MsgType                   = B
|   49  SenderCompID              = OANDA
|   50  SenderSubID               = TEST
|   52  SendingTime               = 20160716-15:21:22.904
|   56  TargetCompID              = ****
+-BODY
|   33  LinesOfText               = 4
|  148  Headline                  = OANDA FIX Server Information
|   33  LinesOfText (count = 4)
|   58  Text                      = version: 2.4.21 (fxTrade order server [2,53] 1468682482 ***.***.***.***)
|   58  Text                      = notice: Market Data Request now supports new MarketDepth and MDUpdateType settings
|   58  Text                      = notice: halted pairs are now marked QuoteCondition=B Text=Halted
|   58  Text                      = notice: please include the complete server version string in all support requests
+-TRAILER
|   10  CheckSum                  = 226
+-END OF MESSAGE

Operations will be executed as **** with FIX.4.2 command

[M]: Market Data Request
[O]: Market Order
[E]: Entry Order
[L]: Limit Order
[T]: Stop Order
[C]: Cancel Order
[F]: Modify Order
[S]: Order Status
[R]: Enter Raw Text Message
[D]: Delay
[U]: Choose FIX User

---------------------------

[Q]: Quit

Choose Command >

キタ━━━━(゚∀゚)━━━━!!

さいごに

やっていて気が付いたのですが、デモ口座でRESTは口座開設しなくても利用できますね。たぶん。

あと、後で気が付きましたが、API紹介ページのドメインはwww.oanda.jpであるのに対し、APIドキュメントページのドメインはdeveloper.oanda.comですね。
もしやと思ってググるfxgame site:developer.oanda.com - Google 検索)とTroubleshootingのページが引っかかり、見てみるとProblems with Connectingの項目(一番上)にデモ口座のドメインが書いてありました。

/(^o^)\

サーセン

しかし、サポートのレスが早いです。休日でもレスが来ます。とっても助かりました。

いやぁ~、もっぱらデモ口座APIのために口座開設したけれど、手動トレードでも使ってみるンゴ!

しかし、FIXのSEO最悪ですね。RESTにもストリーミングがあるので悩みます。

ちなみにですが、Brexitの傷はほとんど癒えました。ありがとう参院選
だが、改憲かぁ…

OANDA Japan MT4

つづき

hhr.hatenablog.com

OANDAはデモ口座でWebAPIを使ってFXの自動売買が試せるみたい

Brexit

随所で阿鼻叫喚の様相を呈していましたが、僕もご多分に漏れず、株&FX&投信でちょっとやられました(まだ含み損状態)

まぁ、僕も日本人。日本人らしく資産はほとんどは銀行の普通預金なので微々たるダメージなのですが、

やっぱり悲しいンゴ…

それはさておき、最近、OANDA Japanの広告にやたらターゲティングされておりまして、ブラウジングしていると高確率で表示されます。

WebAPIが提供されているFX会社としてOANDAのことは知っていました。1年ほど前に僕の周辺でやたらシストレ&自動売買が流行りまして、やれMT4だのOandaAPIだのと盛り上がっていましたので。

みんなスイスフランショックとか今回のBrexitは大丈夫だったのかなぁー。

一方、話題は変わりまして、最近のトレンドとして人工知能、AI、ディープラーニングが有りますね。

FXは売買がわりかしシンプルであるおかげかOANDAAPIを使ってオレオレアルゴリズムディープラーニングでなんちゃらなんちゃらな記事をちょくちょく見かけます。

実際に自分のお金でオレオレアルゴリズムのテストするとか、

まぢパネェっす

って思っていたのですが、OANDAさん、口座開設すると、なんともれなくデモ口座でAPIが試せるみたいです。

すごい。

というわけで口座開設してデモ口座でAPI試してみようかなと思います。

しかし、金融口座がどんどん増えていく…
マネーアグリゲーションサービス使っていても辛いレベルです…

OANDA Japan MT4

つづき

hhr.hatenablog.com

いまさらk10statでLlanoの低電圧化をして自鯖の省エネを夢見る

5/14のやつです。

タイトルにも有りますが、夢見てます。まだ、道半ばです。

いまさらなLlanoなので、より新しいCPUのk10stat相当は以下の通りです。(使ったこと無い)

  • Trinity/Richland → PSCheck
  • Kaveri → K15TK

しかし、最近はスマホCPUの話題ばかりで寂しいなぁ。



chromesafariで動作確認

クリックで進む。右クリックで戻る。

 

AMD A-series プロセッサ A10 7870K BlackEdition FM2+ AD787KXDJCBOX

AMD A-series プロセッサ A10 7870K BlackEdition FM2+ AD787KXDJCBOX

Redisのreplication構成+自動failover(sentinel)をVagrantで構築してnode.js(express + ioredis)から利用する

はじめに

Redisのcluster構成に関する記述はありません。

Redisの構成に関しては公式ドキュメント(英語)にあるreplicationsentinelの記述の通りです。
目新しいことは無いと思います。

node.jsのRedisクライアントにはioredisを利用します。node_redisに関する記述はありません。

expressのsession-storeにRedisを利用する前提で記述してあります。
なぜCookieだけでないのか、なぜsession-storeにRDBなどの他のミドルウェアを利用しないのか、のような話題の記述はありません。

取り扱う内容

  • Vagrant
    • 下記構成のRedisサーバを構築
  • Redis
    • replication
      • master-slave構成のこと
    • 自動failover
      • masterのdown検知時に自動で(人の手を介さずに)slaveがmasterに昇格すること
      • masterの監視はredis-sentinelを使用
  • expressからの利用
    • 構築したRedisをexpressのsession-storeとして利用

ローカルの仮想マシンでreplicationと自動failoverをしてもあまり意味がないので、可能ならばAWS複数リージョンを使うなど、IaaSを活用したかったのですが、お金がかかるので諦めました。

以下は全てmacで実行していますが、Vagrantに依存するものがほとんどのため、Vagrantが動作する環境ならばどこでも大丈夫だと思います。

Redisの準備

f:id:HHR:20160116165435p:plain:right

Vagrantを使用してRedisサーバを3台、作成します。
1台のサーバあたりメモリを500MBちょっとつかうのでメモリをとっても圧迫します…。使用しているmacのメモリの8GBでは複数仮想マシンを動作させるには辛い様子で、途中、動作が重たくなったのでchromeを閉じました。
あと、電池がよく減ります。

構成

1台はmasterのRedis、他2台はslaveのRedisを配置します。
それぞれのサーバにはRedisのプロセスとは別にsentinelのプロセスを起動します。

                  +---------------+
                  | 192.168.50.10 |
                  |---------------|
                  | master        |
                  | sentinel-1    |
                  +---------------+
                          |
+---------------+         |         +---------------+
| 192.168.50.11 |---------+---------| 192.168.50.12 |
|---------------|                   |---------------|
| slave-1       |                   | slave-2       |
| sentinel-2    |                   | sentinel-3    |
+---------------+                   +---------------+

Vagrantのインストール

brew install Caskroom/cask/vagrant

f:id:HHR:20160116165328p:plain:w270,right

Vagrantはとっても便利です。よく利用します。

今回はubuntu公式のBoxを使用しました。
余談ですが、仮想マシンに特化したメジャーなBoxは無いのでしょうか…。Boxのダウンロードも前述したメモリ使用量も電池の減りも、とにかく重いです…

それとも自分が情弱なだけですでに存在するのでしょうか。

Vagrantfile

仮想マシンの構成を定義するVagrantfileを用意します。

ココにRedisをインストールするVagrantfileとプロビジョニングのスクリプトがあったので利用させてもらいました。

ただし、これは1台の仮想マシン用のコードであるため、前述の構成に対応する変更を加えます。

Rubyは詳しくないのですが、endの数がすごいことなっています。JavaScriptのコールバックヘルみたいです。

プロビジョニングのスクリプトにも変更を加えます。
1台はmaster、他2台はslaveにする処理とsentinelを起動する処理です。
本番運用ではmasterとslaveで設定ファイルを分け、sentinelは自動起動スクリプトを登録したりするべきかと思いますが手を抜きます。

sentinelの設定ファイルを追加します。
デーモン化とPIDファイル置き場所の指定、初期時点でのmasterの場所とquorumを設定します。
quorumについては割愛します。

まとめたコードはGithubに置いてあります。

起動

vagrant up

初回はとっても長いです。 osのboxイメージ取得から処理されるので強いネットワーク回線必須です。
自分は最初、テザリング環境でトライしてむりぽを悟り、ご自宅でリトライをいたしました。わかっていましたけどね…

構成の確認

ホストマシン(ここではmac)にRedisのクライアントをインストールしてRedisの状態を確認します。
クライアントをインストールと言いつつ、サーバもインストールされてしまいますが無視します。

brew install redis
replication
$ redis-cli -h 192.168.50.10 info replication
# Replication
role:master                       <- ココ
connected_slaves:2
slave0:ip=192.168.50.11,port=6379,state=online,offset=245191,lag=0
slave1:ip=192.168.50.12,port=6379,state=online,offset=245191,lag=0
master_repl_offset:245191
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:245190

$ redis-cli -h 192.168.50.11 info replication
# Replication
role:slave                        <- ココ
master_host:192.168.50.10
master_port:6379
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_repl_offset:247884
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

$ redis-cli -h 192.168.50.12 info replication
# Replication
role:slave                        <- ココ
master_host:192.168.50.10
master_port:6379
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_repl_offset:248744
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

少し使った後の実行結果なのでまっさらではないですが、良い感じです。

sentinel
$ redis-cli -h 192.168.50.10 -p 26379 info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
master0:name=mymaster,status=ok,address=192.168.50.10:6379,slaves=3,sentinels=3

$ redis-cli -h 192.168.50.11 -p 26379 info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
master0:name=mymaster,status=ok,address=192.168.50.10:6379,slaves=3,sentinels=3

$ redis-cli -h 192.168.50.12 -p 26379 info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
master0:name=mymaster,status=ok,address=192.168.50.10:6379,slaves=3,sentinels=3

大丈夫そうです。

動作確認

実際にreplicationと自動failoverの動作確認をします。

replication

masterに値をセットしてslaveで取得できるかを確認します。

$ redis-cli -h 192.168.50.10 set hoge 'fuga'
OK

$ redis-cli -h 192.168.50.10 get hoge
"fuga"

$ redis-cli -h 192.168.50.11 get hoge
"fuga"

$ redis-cli -h 192.168.50.12 get hoge
"fuga"

良いですが、どうしてもローカル環境なので当たり前感が…。
AWS複数のリージョンにサーバを設置するなど、遠隔地環境でタイムラグ等の実測値がどうなるかは気になります。

自動failoverの確認

masterを擬似的に落とします。

$ redis-cli -h 192.168.50.10 DEBUG sleep 30
OK

roleがどうなったかを確認。

$ redis-cli -h 192.168.50.10 info replication
# Replication
role:slave                        <- slaveに変わった
master_host:192.168.50.11
master_port:6379
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_repl_offset:374134
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:66095
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:66094

$ redis-cli -h 192.168.50.11 info replication
# Replication
role:master                       <- masterに変わった
connected_slaves:2
slave0:ip=192.168.50.10,port=6379,state=online,offset=376249,lag=0
slave1:ip=192.168.50.12,port=6379,state=online,offset=376263,lag=0
master_repl_offset:376263
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:341012
repl_backlog_histlen:35252

$ redis-cli -h 192.168.50.12 info replication
# Replication
role:slave                        <- そのまま
master_host:192.168.50.11
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:383073
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

グッドです。
sentinelも確認します。

$ redis-cli -h 192.168.50.10 -p 26379 info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
master0:name=mymaster,status=ok,address=192.168.50.11:6379,slaves=3,sentinels=3

$ redis-cli -h 192.168.50.11 -p 26379 info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
master0:name=mymaster,status=ok,address=192.168.50.11:6379,slaves=3,sentinels=3

$ redis-cli -h 192.168.50.12 -p 26379 info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
master0:name=mymaster,status=ok,address=192.168.50.11:6379,slaves=3,sentinels=3

がはは、グッドだー

因みにですが、slaveになった192.168.50.10には書き込めなくなります。

$ redis-cli -h 192.168.50.10 set hoge huga
(error) READONLY You can't write against a read only slave.

つまり、クライアントはRedisサーバがfailoverで切り替わった際に向き先を変更しなければ書き込みができなくなってしまいます。
せっかくRedisサーバが自動failoverしてもクライアントが対応しないと意味無いです。
クライアントがnode.jsの場合どうするかを後述します。

再度、192.168.50.10をmasterにします。

$ redis-cli -h 192.168.50.11 DEBUG sleep 30
OK

expressからの利用

f:id:HHR:20160116233047p:plain:right

自分のmacのスペック的にこれ以上は仮想マシンを追加したくなかったので、ホストマシンでnode.jsのアプリケーションを起動してそこから仮想マシン上のRedisをコールすることにします。
node.jsもプラットフォームの対応が素晴らしいのでmacに限らず大体どこでも大丈夫だと思います。

brew install node.js
npm install express-generator -g
express redis-failover-hello-world
cd redis-failover-hello-world && npm install

前述のとおり、ioredisを使用します。

npm install --save ioredis

セッションの保存先をRedisにするnpmパッケージをインストール。

npm install --save connect-redis express-session 

app.jsを書き換えて、セッションの保存先をVagrant上に構築したRedisに指定します。

起動。

$ DEBUG=ioredis:* npm start

> redis-failover-hello-world@0.0.0 start /Users/hhr/git/redis-failover-hello-world
> node ./bin/www

  ioredis:redis status[localhost:6379]: [empty] -> connecting +0ms
  ioredis:redis status[192.168.50.10:26379]: [empty] -> connecting +7ms
  ioredis:redis queue command[0] -> sentinel(get-master-addr-by-name,mymaster) +4ms
  ioredis:redis status[192.168.50.10:26379]: connecting -> connect +76ms
  ioredis:redis status[192.168.50.10:26379]: connect -> ready +1ms
  ioredis:connection send 1 commands in offline queue +0ms
  ioredis:redis write command[0] -> sentinel(get-master-addr-by-name,mymaster) +1ms
  ioredis:redis status[192.168.50.10:6379]: connecting -> connect +11ms
  ioredis:redis write command[0] -> info() +1ms
  ioredis:redis status[192.168.50.10:6379]: connect -> ready +3ms
  ioredis:redis status[192.168.50.10:26379]: ready -> close +1ms
  ioredis:connection skip reconnecting since the connection is manually closed. +0ms
  ioredis:redis status[192.168.50.10:26379]: close -> end +0ms

ふむふむ、

  1. 192.168.50.10:26379に接続(sentinelに接続)
  2. redis-cli -h 192.168.50.10 -p 26379 sentinel get-master-addr-by-name mymaster的なコマンド実行(sentinelにmasterの場所を問い合わせ)
  3. 192.168.50.10が返ってくる)
  4. 192.168.50.10:6379に接続(masterに接続)
  5. redis-cli -h 192.168.50.10 -p 6379 info的なコマンド実行(masterであることを確認している?)
  6. 192.168.50.10:26379を切断

のようです。

HTTPサーバが起動したので、ブラウザからアクセスして挙動を確認します。

http://localhost:3000

  ioredis:redis write command[0] -> set(sess:vp5z1WR_7aK8eHjzJkbv5xXLRZEKPahs,{"cookie":{"originalMaxAge":null,"expires":null,"httpOnly":true,"path":"/"}},EX,86400) +2m
GET / 200 43.978 ms - 170
  ioredis:redis write command[0] -> get(sess:vp5z1WR_7aK8eHjzJkbv5xXLRZEKPahs) +47ms
  ioredis:redis write command[0] -> expire(sess:vp5z1WR_7aK8eHjzJkbv5xXLRZEKPahs,86400) +3ms
GET /stylesheets/style.css 200 1.763 ms - 111
  ioredis:redis write command[0] -> get(sess:vp5z1WR_7aK8eHjzJkbv5xXLRZEKPahs) +162ms
  ioredis:redis write command[0] -> expire(sess:vp5z1WR_7aK8eHjzJkbv5xXLRZEKPahs,86400) +41ms
GET /favicon.ico 404 40.017 ms - 1919
  ioredis:redis write command[0] -> get(sess:vp5z1WR_7aK8eHjzJkbv5xXLRZEKPahs) +27ms
  ioredis:redis write command[0] -> expire(sess:vp5z1WR_7aK8eHjzJkbv5xXLRZEKPahs,86400) +28ms
GET /favicon.ico 404 27.736 ms - 1919

favicon.icoが無い、は無視します。
セッション情報をRedisに書き込んでそれを取得している様子が確認できます。

ブラウザの開発ツール等でHTTPヘッダやクッキーを見るとs:vp5z1WR_7aK8eHjzJkbv5xXLRZEKPahs...があり、これがセッションIDであることがわかります。

ブラウザリロード。

  ioredis:redis write command[0] -> get(sess:vp5z1WR_7aK8eHjzJkbv5xXLRZEKPahs) +4m
  ioredis:redis write command[0] -> expire(sess:vp5z1WR_7aK8eHjzJkbv5xXLRZEKPahs,86400) +14ms
GET / 304 13.421 ms - -
  ioredis:redis write command[0] -> get(sess:vp5z1WR_7aK8eHjzJkbv5xXLRZEKPahs) +40ms
  ioredis:redis write command[0] -> expire(sess:vp5z1WR_7aK8eHjzJkbv5xXLRZEKPahs,86400) +4ms
GET /stylesheets/style.css 304 2.832 ms - -

2回目以降はセッションIDの有効期限内であれば書き込みはされないようです。
有効期限切れのパターンは割愛します。

ターミナルからも見てみます。

$ redis-cli -h 192.168.50.10 keys '*'
1) "hoge"
2) "sess:vp5z1WR_7aK8eHjzJkbv5xXLRZEKPahs"

$ redis-cli -h 192.168.50.10 get 'sess:vp5z1WR_7aK8eHjzJkbv5xXLRZEKPahs'
"{\"cookie\":{\"originalMaxAge\":null,\"expires\":null,\"httpOnly\":true,\"path\":\"/\"}}"

セッションの保存、良い感じです。
slaveに保存されているかの確認は割愛します。

failoverさせます。

redis-cli -h 192.168.50.10 DEBUG sleep 30
  ioredis:redis status[192.168.50.10:6379]: ready -> close +7m
  ioredis:connection reconnect in 2ms +0ms
  ioredis:redis status[192.168.50.10:6379]: close -> reconnecting +1ms
  ioredis:redis status[192.168.50.10:6379]: reconnecting -> connecting +2ms
  ioredis:redis status[192.168.50.11:26379]: [empty] -> connecting +1ms
  ioredis:redis queue command[0] -> sentinel(get-master-addr-by-name,mymaster) +1ms
  ioredis:redis status[192.168.50.11:26379]: connecting -> connect +1ms
  ioredis:redis status[192.168.50.11:26379]: connect -> ready +0ms
  ioredis:connection send 1 commands in offline queue +1ms
  ioredis:redis write command[0] -> sentinel(get-master-addr-by-name,mymaster) +0ms
  ioredis:redis status[192.168.50.11:6379]: connecting -> connect +2ms
  ioredis:redis write command[0] -> info() +0ms
  ioredis:redis status[192.168.50.11:26379]: ready -> close +1ms
  ioredis:connection skip reconnecting since the connection is manually closed. +1ms
  ioredis:redis status[192.168.50.11:26379]: close -> end +0ms
  ioredis:redis status[192.168.50.11:6379]: connect -> ready +1ms

おぉ、切り替わりました。 注目すべきは、HTTPアクセスが無い状態で勝手に接続先が切り替わったことです。大変よい感じです。うふふ。

さいごに

以上、ざっとですが自動failoverするRedisサーバをexpressで使用することができました。
masterがdownして、その後に復帰したらどうなるかとか無いので本当にざっとです…

個人で自動failoverする構成の需要が高くないためか、割りと調べることに苦労しました…

まぁ、AWSやherokuとかではたいてい機能が用意されているので地味なネタなのかもです。

Redis入門 インメモリKVSによる高速データ管理

Redis入門 インメモリKVSによる高速データ管理

コマンドラインだけでoAuth(Y!ID連携)のアクセストークンを取得してみる

11/07のやつです。

 

chromesafariで動作確認

クリックで進む。右クリックで戻る。

IDCFのキャンペーンに乗っかってCPU16コアでx264動画エンコード

去年の年末らへんにIDCFの新規入会キャンペーンみたいの(またやっている)でサーバ作ったんですけど、ちょっとだけ使ってHerokuに移行、その後は放置していました。
無料枠がまだ7000円分ほど残っていて、有効期限が5月だったのでもったいないなー、と思って日々ネタ探しをしていたのですが、ふと、昔に撮ったmpeg動画の圧縮をやろうやろうとして忘れていたのを思い出しました。

実はffmpegは2年ちょっと前にさわったことがあり、四苦八苦してコンパイルまでしていざエンコードしたら1時間弱の動画のエンコードに30時間かかったりといろいろ力不足(僕自身もマシンも)感に苛まれました。(当時の環境は2コアの2.4GHzぐらい)
また、こんな記事を読んだりして、すっかり熱が冷めちゃいました。
そんなこんなで、コンパイルの仕方と一応のエンコード方法がわかって満足かなーっと、ほったらかしにしていました。

話を戻しまして、IDCFのリソース構成を見てみますと、2.6GHzのCPU16コア(152円/時)があって、2年ちょっと前のローカルマシン環境から大幅スペックアップを発見しました。
単純計算ですが、8倍以上のパフォーマンス! と意気込んで再チャレンジしてみました。

ffmpegの最新情報だけは追っかけていて、公式コンパイル方法とか公式エンコード方法とかブックマークしてあったので、それを試したいという気持ちもそこそこ。

コンパイルエンコードはほぼ記事通りに行ったので割愛して、期待の性能なんですが…
すごいですねー。
1時間弱の動画のエンコードが2時間程度で終わりました。

CPU16コアの top も圧巻。

ffmpeg -i in.mpg -c:v libx264 -preset veryslow -crf 18 -c:a libfdk_aac -b:a 128k -movflags +faststart out.mkv
Tasks: 331 total,   1 running, 330 sleeping,   0 stopped,   0 zombie
%Cpu0  :  1.1 us,  0.4 sy, 95.4 ni,  3.2 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu1  :  0.4 us,  0.0 sy, 98.9 ni,  0.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu2  :  6.2 us,  0.0 sy, 80.3 ni, 13.5 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu3  :  6.0 us,  0.4 sy, 90.8 ni,  2.8 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu4  :  7.4 us,  0.4 sy, 88.7 ni,  3.5 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu5  : 10.7 us,  0.3 sy, 83.4 ni,  5.5 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu6  :  4.2 us,  0.0 sy, 92.2 ni,  3.5 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu7  :  6.0 us,  0.7 sy, 89.8 ni,  3.5 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu8  : 11.1 us,  0.3 sy, 84.1 ni,  4.5 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu9  :  2.8 us,  0.0 sy, 95.1 ni,  2.1 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu10 :  7.6 us,  0.3 sy, 85.4 ni,  6.6 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu11 :  9.1 us,  0.4 sy, 85.6 ni,  4.9 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu12 :  0.0 us,  0.0 sy, 99.3 ni,  0.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu13 :  4.7 us,  0.7 sy, 85.1 ni,  9.5 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu14 :  4.2 us,  0.0 sy, 93.7 ni,  2.1 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu15 :  2.5 us,  0.0 sy, 95.4 ni,  2.1 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st

どやっ

元記事が手元に無くてうろ覚えなんですけど、クラウドの可能性みたいな題目でNew York Timesがハイスペックリソースをクラウドで調達して記事の電子化(少し記憶が曖昧)をサクッと処理。というのを思い出しました。
当時は「へぇー」程度だったんですが、実際に個人でクラウドのハイスペックリソースを借りてCPU依存の処理をしてみて、ありかもなぁ。とか思いました。
CPU依存の処理を個人が必要とするシーンがあまり思いつかないのですが…

因みにですが、このブログ書いていたらffmpegバージョンアップしました。 NVIDIAのH.264ハードウェアエンコーダーかぁ…