【失敗】5行のRubyでアルトコインの自動取引(開発環境必要なし)【coincheck】 – (failed) autotrade altcoins with 5 lines Ruby on coincheck (Ruby environment not required)

結論 – Summary

  • coincheck API は BTC-JPY しか売買できない!
    You cannot buy/sell anything but BTC-JPY with coincheck API!

5行のRuby – 5 lines Ruby

#!/usr/bin/env ruby -Ilib
require 'ruby_coincheck_client'
cc = CoincheckClient.new("YOUR API KEY", "YOUR SECRET KEY")
response = cc.create_orders(order_type:"buy", rate: 2400, amount: 0.1, pair: "fct_jpy")
p JSON.parse(response.body)
  • これでFactomが0.1FCTだけ2400円/FCTで買えそうに見える。
    You may think that you can buy 0.1 FCT by 2400 JPY/FCT.

  • しかし、{"success"=>false, "error"=>"Pair this pair isn't tradable"}と言われてしまいます。取引所APIドキュメントを良く見ると、*pair 取引ペア。現在は "btc_jpy" のみです。と書かれています。
    However, Ruby says {"success"=>false, "error"=>"Pair this pair isn't tradable"}. If you read exchange API document carefully, you will find *pair Specify deal pair. It's now only "btc_jpy".

  • rate: 2400 と指定しているのが悪いと思うかもしれないけど、rate: nil とすると、{"success"=>false, "error"=>"amount, rate are required"} とエラーが帰ってきます(数量とレートは必要です)。
    You may think that rate: 2400 is the cause of the error. However, if you write rate: nil, you get another error: {"success"=>false, "error"=>"amount, rate are required"}

やり方(失敗したけど) – How to Run (but you will fail)

  • 環境構築が面倒なのでcloud9で行います。
    It is hard to setup on your local Windows or Mac, so you should use cloud9.

*cloud9に登録して、workspaceを作ります。templateはblankを選びます。
Sign up to cloud9 and create workspace like this (select blank template).

  • コンソールにgem install ruby_coincheck_clientと入力して、coincheckのライブラリをクラウド上の開発環境にインストールします。
    Write gem install ruby_coincheck_client, then coincheck libraries will be installed on your virtual machine.

  • コンソールにtouch main.rbなどと入力して(ファイル名は適当)、Rubyファイルを作ります。
    Write touch main.rb so that you can create Ruby file (filename is not important).

  • coincheckの「設定」「APIキー」にアクセスして、「新たにAPIキーを追加する」をクリック。
    Access coincheck, settings, and API keys. Click “Add another API key”.

  • 使いたい機能にチェックを入れてOKを押します。
    Check all you need and click OK.

  • すると、アクセスキーとシークレットアクセスキーが発行されます。
    Then you get access key & secret access key.

  • cloud9で次のコードを入力します。”YOUR API KEY”, “YOUR SECRET KEY” の部分には、先程取得したアクセスキーとシークレットアクセスキーを入力してください。
    Write the following code on cloud9. Replace “YOUR API KEY”, “YOUR SECRET KEY” with your access key, secret access key.

#!/usr/bin/env ruby -Ilib
require 'ruby_coincheck_client'
cc = CoincheckClient.new("YOUR API KEY", "YOUR SECRET KEY")
response = cc.create_orders(order_type:"buy", rate: 2400, amount: 0.1, pair: "fct_jpy")
p JSON.parse(response.body)
  • コンソールにruby main.rbと入力して実行します。
    Write ruby main.rb in console and return.

  • エラーが出ます。
    You will get the following error.
    {"success"=>false, "error"=>"Pair this pair isn't tradable"}

どうする? – Next Step?

  1. 海外の取引所でアルトコインを売買する
    You can buy/sell altcoins at other exchanges with API.

  2. 自動売買は諦める
    You can give up autotrading.

  • 私はとりあえず自動売買は諦めるつもりです。
    I am giving up for now.

  • ある価格に達したら、Twilioを使って、電話がかかってくるようにしようと思いましたが、coincheckに既にその機能がありました。
    I am about to create a program which call me when a coin have huge drop/rise. However coincheck already has this feature.

  • しかしこの機能は、電話・SMSは月に30回までだそうです。メールは無制限にできると思いますが、メールは通知音が短いので寝てると気づかないのです。
    However, telephone and SMS are available only 30 times per month. You can receive emails any times, but you cannot wake up at night by short email notification sound.

  • Bitcoin Checker (Android) というアプリは、通知音ではなく、アラームを鳴らすことができる(つまり長時間音を出すことができる)ので、自分の希望に合いそう。結局、自分でプログラムを作る必要は無いのである(完)。
    I found that Bitcoin Checker (Android app) can ring alarm (long ringtone, not short notification sound). So, I do not need to create my own program (fin).

さくらのレンタルサーバーでクイックインストールしたWordPressのディレクトリを、マルチドメイン設定で既定のフォルダにしてしまったため、古いサイトの授業ノートに検索から来る人が404になってしまうのを対処しました。

さくらのレンタルサーバーでクイックインストールしたWordPressのディレクトリを、マルチドメイン設定で既定のフォルダにしてしまったため、古いサイトの授業ノートに検索から来る人が404になってしまうのを対処しました。

経緯

  • 1日に何件か、旧サイトの授業ノートに、検索からアクセスがあることが判明

  • 当然404になる

  • 404ページに旧サイトへのリンクを貼ってみるが、クリックする人はいない

  • 新しくralit.blogドメインとか取得してブログを始めるべきだったんだけど、既にTwitterやfacebookで記事をたくさん貼ってしまったため、リダイレクト設定でなんとかしようと考える。

対策

  • wpディレクトリの.htaccessを編集した

  • 以下を.htaccessの先頭に追記(末尾だとうまくいかなかった)

RewriteEngine on
RewriteBase /
RewriteRule ^note2016/(.*)$ http://ralit.sakura.ne.jp/note2016/$1 [R=301,L]
RewriteRule ^note2015/(.*)$ http://ralit.sakura.ne.jp/note2015/$1 [R=301,L]
RewriteRule ^note2014/(.*)$ http://ralit.sakura.ne.jp/note2014/$1 [R=301,L]
RewriteRule ^note/(.*)$ http://ralit.sakura.ne.jp/note/$1 [R=301,L]
RewriteRule ^blog/(.*)$ http://ralit.sakura.ne.jp/blog/$1 [R=301,L]
RewriteRule ^ofuton/(.*)$ http://ralit.sakura.ne.jp/ofuton/$1 [R=301,L]

問題点

  • WordPressの柔軟な404対策?の方が優先される。

  • 直接ブラウザにralit.org/noteと打ちこんでみると、404が表示される。

  • これはどうやら、WordPressが、記事URLに"note"を含む記事を探す機能が優先されているからみたい。

  • たとえば、ralit.org/kyotoと打ち込んでみると、ralit.org/2017/09/03/kyoto-cafe-and-bakery/という記事にリダイレクトされる。

  • URLを直接打ち込んで来る人や、授業ノートのページをブックマークに登録している人はいなさそうなので、大丈夫だとは思いますが…

  • .htaccessを編集するのはたぶん強引な方法なので、もっと良い方法を見つけたら報告します。

Ofuton Reading (Android app)

Ofuton Reading

app for reading in your bed

GooglePlay

award

GitHub

 

おふとんリーディング (Androidアプリ)

おふとんリーディング

寝ながら本を読むためのアプリです。

GooglePlay

授賞式

GitHub

 

傾き・反り・影がある文書画像の行認識(その4)

前回の記事から1週間ちょっとたちました。
プロットした点から外れ値を取り除きました。

外れ値を取り除いた

点が2つだけになった列が残っているのはあまり気にしないでください。消します。

やらなければならないこと

1. 曲線が直線になるように画像を変形する

2つの線の幅が変わるから(たとえば500ピクセルあった幅が400ピクセルになる)、どのピクセルを選ぶかというアルゴリズムを考えたが、その実装をしてない。

曲線の方程式を引数に渡したものの、制御点を渡すのを忘れてた。3次スプライン曲線は複数の3次関数をつなぎ合わせたものだって認識がどうも抜けるな。

2. 3次スプライン曲線の制御点を増やす

ご覧の通り、プロットした点に沿った曲線になっていない(左端のほうはほぼぴったりでも右端のほうは直線状になっているなど)。いまは3次関数を2つだけ繋いでいる(制御点が3つ)だが、3つ、4つと増やす必要がある(しかしあんまり増やすと計算量が増える)。

制御点がいくつでも大丈夫なようにコードを書き換えなくちゃいけない。

3. 位置関係による分類

これはまだ手をつけてません。

上の方にあって、専有面積が大きいものが店名、その下が電話番号とかをやる。

Javaのリスト速度対決

配列、ArrayList、LinkedListの速度対決をしてみました。
データ構造とアルゴリズムを習ってからずっと気になっていたんですが、
今必要に迫られて計測してみました。

条件

  • 要素数は7990272個です(中途半端)
  • for文を回す時間を計測します。初期化部分は含めません。
  • 要素はint(Integer)型です。
  • i: 0から7990271を動くindexです。
  • MAX: 7990272
  • 「10回だけ」とか指定がなければMAX回for文を回しています。

配列
普通の配列は速いですが、あとから追加・削除はできません。

  • 代入 14ms
  • 取得 14ms

ArrayList
ArrayListは以前からよく使っていました。
要素の取得は、普通の配列と遜色ない速さで嬉しいです。
要素の追加は、LinkedListより速いですね。
要素の削除は、先頭からやると、7990272回配列をコピーすることになるので、とんでもない時間がかかるようです。
末尾を削除するなら、LinkedListとほぼ同じ時間でできました。

  • add  226ms
    • ※要素を末尾に追加します
  • get(i) 19ms
    • ※指定したインデックスの要素を取得します
  • remove(0) 終わらないのであきらめた
    • ※指定したインデックスの要素を削除します
    • 一番遅いと思われる0番目を削除し続けました(1回ずつ配列を作り直すため)
  • remove(MAX – i – 1) 66ms
    • ※指定したインデックスの要素を削除します
    • 一番速いと思われる末尾の要素を削除し続けました
  • remove(3000000)を10回だけ 22ms
    • 真ん中へんの要素(3000000番目)を削除しました
    • めちゃくちゃ時間がかかりそうなので、10回だけやりました(この結果から7990272回やると恐ろしい時間がかかるのが分かります)

LinkedList
LinkedListは、普通に全ての要素を取得しようとするととんでもない時間がかかります。
先頭・末尾から削除しつつ取得すれば、かなり速く取得できます。
要素の追加は何故かArrayListより時間がかかるようです。

  • add  1070ms
    • ※要素を末尾に追加します
  • offer 1335ms
    • ※要素を末尾に追加します
  • push 1417ms
    • ※要素を先頭に追加します
  • pollFirst 55ms
    • ※先頭の要素を取得して削除します
  • pollLast 58ms
    • ※末尾の要素を取得して削除します
  • removeFirst 58ms
    • ※先頭の要素を取得して削除します
  • removeLast 69ms
    • ※末尾の要素を取得して削除します
  • get(i) 終わらないので諦めた
    • ※指定したインデックスの要素を取得します
  • remove(3000000)を10回だけ 87ms
    • 真ん中へんの要素(3000000番目)を削除しました
    • LinkedListの参照を3000000回たどる方が、ArrayListをコピーするよりも時間がかかることが分かります。

まとめ

  • もちろん普通の配列は速い。
  • でもArrayListを多用しても平気そう。特に要素の取得は普通の配列に迫る速さ。
  • 普通はわざわざLinkedListを使う必要はなさそう。要素の追加が遅いし、要素を削除せずに取得する方法は遅くて使えない。要素を削除する場合も、末尾から削除する場合はArrayListでも速い。中途半端な部分を削除する場合もArrayListを使った方がよさそう。
  • 先頭から削除する場合のみLinkedListを使う。

傾き・反り・影がある文書画像の行認識(その3)

お昼に引き続き進捗報告です。
3次スプライン曲線のフィッティングをしました。
前回の記事にも追記したのですが、曲線フィッティングによる歪み補正のアイデアは、この論文
http://human.ait.kyushu-u.ac.jp/~uchida/Papers/IS1-037.pdf
からもらっています(全く同じ実装ではありません。この論文はスキャナによる白黒2値画像を対象にしているからです)。
論文を読んで実装するのはつらいですね…審査員はその世界のトップだからソースコードがなくても再現できるだろうけど、初心者にとってはつらいです。ソースコードを添付する習慣はできないのでしょうか。

前回、40分割塗りつぶし画像のゴミをとりました。
そこからまず曲線をフィッティングさせる点をプロットします。
plot

フィッティングをします。
制御点を色々動かして、プロットした点との距離の和が最小になるものを求めます。
curve

これでフィッティングはできました。
変な方向に行ってるやつがいるのは、プロットした点に外れ値があるせいです。
次は、この外れ値を除去して、画像を変形するところまで行きましょう。

ここまでくるのに結構疲れました。
for文の階層を間違えたり、連立方程式の係数を間違えたりして、うまくいかなかったからです。
幻想的な曲線群が得られたときはどうしようかと思いました。
curve_0

傾き・反り・影がある文書画像の行認識(その2)

現在の進捗報告です。

前回「40列分割塗りつぶし」画像を得ました。
このあと何をやりたいかというと、

  1. 3次スプライン曲線をあてはめる(Curve Fitting)
  2. 3次スプライン曲線がまっすぐになるように画像全体を変形させる
  3. まっすぐになった画像から文字行を切り出す
  4. OCRにかける
  5. OCR結果に基づいて分類する

慣れてる人がやれば一瞬で終わりそうですが、まだ1にも到達していません。

1に到達するためには、以下を逆順に解決する必要があります。

  1. 3次スプライン曲線をあてはめる点の集合を求める
  2. 点の集合を求めるために、文字行を抜き出す
  3. 文字行を抜き出すために、ゴミを取り除く

まず、異様に縦長の部分を取り除きました(白黒反転してるのは気にしない)
異様に縦長のものを取り除く

次に、行っぽいものを抽出して、短い行は取り除きました。
行の抽出は、画像に対してラベリング処理(ピクセル単位)をすると遅いので、各矩形の情報を数値でもっておいて、矩形単位で処理をしました。
行を抽出

これで点の集合が求められるので、次は3次スプライン曲線をフィッティングします。
(点の集合から外れ値を取り除いた方が良さそうですが、後回しにしましょう。全体の完成が先。)

3次スプライン曲線を求めるための連立方程式を解く部分だけはつくりました。
線形代数Iで習ったガウスの消去法ですね。
制御点(3つの予定)を移動させながら各点との距離の和が最小になる組合せを求める予定。

追記

3次スプライン曲線をあてはめて変形させるというアイデアは、以下の論文から得ました。
「大局的最適化に基づく文書画像の湾曲歪み補正法」
http://human.ait.kyushu-u.ac.jp/~uchida/Papers/IS1-037.pdf

3次スプライン曲線による補完を理解するには、次のページがものすごく分かりやすかったです。
「3次スプライン補間を手作業で行う – ますぽんの雑記」
http://d.hatena.ne.jp/mscp/20091227/1261940720

連立方程式を解くための処理はこちらから。他にも数学的トピックがたくさん載っています。
「Java & C++ & Visual C++ Sample Program」
http://www.geocities.jp/java_sample_program/GaussNoSyoukyoHou.html

傾き・反り・影がある文書画像の行認識(その1)

こういう画像から行を抜き出したいです。

認識したい画像

スキャンした画像を想定しているおふとんリーディングと比べて、カメラで撮った画像なので、難しいところがたくさんあります。

  • 背景が真っ白じゃない。
  • 真っ白じゃないだけでなく影が入っている。
  • 文書の外側(机とか)まで入っている。
  • 紙が傾いている。
  • 傾いているだけじゃなく、反っている。

これを、次のようにします。思いつきです。

  1. エッジ抽出
  2. エッジ抽出した画像を2値化
  3. 2値化した画像に対して、「ある行に黒いピクセルがひとつでも入っていればその行を全て黒く塗りつぶす」処理を、画像全体を40列に分割して行う

1. エッジ抽出

エッジ抽出なら、背景が白くなくても、影が入っていても(影は明暗の変化が文字よりはゆるやかな気がするから)、文書の外側が入っていても(平坦な机とかなら問題なさそう)、文字だけが抽出できる気がした。Sobelフィルタを使った。もっといいのがあるらしいけど。

sobel

2. 2値化

大津の閾値判別法っていう判別法があるらしいので、閾値を自動判別させて2値化しました。今回の閾値は輝度が22より明るければ白くすることになりました。

22

3. 40列分割塗りつぶし

40列というのは経験則です。1〜100分割くらいして、見た目いい感じに塗りつぶせてるのが30〜40分割くらいでした。どの画像もレシート全体が写っているなら、分割数は固定でもいいのかなと思って。

stair_40

こうすると、同じ行の文字はだいたいくっつくから、曲がったり斜めになっていても行が抽出できるかなと思った。

でも、離れている文字はくっついていないし、近くにある文字も所々くっついてない。

だからこの結果を使って直接文字行を抽出しようとするより、この結果を使って、行の外形を求めて、それに曲線を当てはめて、画像全体の歪みを直した方がいいのかなと。ゆがみが直れば後は左上から順番に走査すればいいよね。