旅好きエンジニアのメモ

旅のこと映画、統計、会計、プログラミングなど、気の向くままに語ります

kotlinでbit flyerのapiから仮想通貨の価格を取得する(android)

kotlinのデータを取得する

下記のブログを参考にさせていただきました。 ver-1-0.net

khttpを入れる

androidをほとんど触ったことがないのでライブラリをどういう風に入れるかもわかりませんでした。。。
まずはbuild.gradleにkhttpのライブラリを入れましょう。

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation"org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
    compile "khttp:khttp:0.1.0" // 追加する
}

ソースを書いていく

自分はMainActivity.ktにkhttpをinportしました。

import khttp.get

ちなみに下記はETHを取得しています。
また、MyAsyncTaskを使っている理由は、androidはメインスレッドでネットワーク通信が出来ないからです。(おそらくですが。。。)

取得処理自体はgetEthRateで行っています

全文ソース(MainActivity.kt)

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.widget.TextView
import android.os.AsyncTask
import khttp.get

open class MyAsyncTask : AsyncTask<Void, Void, String>() {

    override fun doInBackground(vararg params: Void): String? {
        return null
    }

    override fun onPostExecute(text: String) {}
}

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {

        super.onCreate(savedInstanceState)

        setContentView(R.layout.activity_main)

        object : MyAsyncTask() {
            override fun doInBackground(vararg params: Void): String? {
                return getEthRate()
            }
            override fun onPostExecute(text: String) {
                val ethRate = findViewById<TextView>(R.id.ethRate)
                ethRate.setText(text)
            }
        }.execute()
    }
}

fun getEthRate(): String {
    var url : String = "https://lightning.bitflyer.jp/v1/getboard"
    return get(url).jsonObject.getString("mid_price")
}

マニフェストを修正する

どうやらandroidは設定ファイルを修正しないとエミュレーターで通信出来ないようです。 ですので <uses-permission android:name="android.permission.INTERNET" />をAndroidManifest.xmlに追加しましょう。

全文ソース(AndroidManifest.xml)

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="e.yuma.cccheck">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
    <uses-permission android:name="android.permission.INTERNET" />
</manifest>修正する

普段Androidを触っていないと慣れないことが多いですが、やってみたら意外と楽しいかもです。(画面の修正は難しいですね)

binanceから日足を取得するスクリプトを書きました(python)

仮想通貨のコイン間での値動きの相関を調べてみたいと思い、まずはbinanceからデータを取得するpythonスクリプトを書いてみました。

実装には下記のライブラリを使用させてもらいました。(作者の方は他のwrapperも作っていて意欲的な感じがします!)

github.com

ちなみに以下が書いてみたスクリプトです。
ソースコードは自分用に書いているので汚ないです。。。

from binance.client import Client
from datetime import datetime

class Binance(object):
    def __init__(self, api_key, api_secret):
        self.client = Client(api_key, api_secret)

    def get_bars(self, bar_duration, start, end):
        kline_list = []
        for ticker_combination in self.ticker_combinations():    
            klines = self.client.get_historical_klines(ticker_combination, bar_duration, start, end)
            klines = self.format_klines(klines)
            kline_list.append({"ticker_combination":ticker_combination, "klines":klines})
        return kline_list

    def ticker_combinations(self):        
        combinations = self.client.get_all_tickers()
        ticker_combination_list = []
        for combination in combinations:
            ticker_combination_list.append(combination['symbol'])
        return ticker_combination_list

    def format_klines(self, klines):
        klines = list(map(lambda x: [self.format_timestamp(x[0]),x[1],x[2],x[3],x[4],x[5],self.format_timestamp(x[6]),x[7],x[8],x[9],x[10],x[11]], klines))
        return klines

    def format_timestamp(self, timestamp):
        time = datetime.fromtimestamp(timestamp/1000)
        return time

利用方法

api_key, api_secretはbinanceで取得してください (binanceは香港の仮想通貨取引所です。)

start = "1 Dec, 2017"  
end = "1 Jan, 2018"  
bar_duration = "1d"  

bi = Binance(api_key, api_secret)  
bi.get_bars(bar_duration, start, end)  

分析のデータがほしい方はぜひ使ってみてください。

icobenchのgem作成してみました。

ICObenchというicoの評価サイトのapiのgem(wrapper)を作成してみました。

icobench.com

wrapper

github.com

ICObenchは多くのicoが掲載されているので、好みにあったicoを探すことができます。

ただ、ICOはscamも多いので精査して購入する必要があります。

また、たとえ詐欺ではなかったとしても取引所に上場されなかった場合、売買できないので極力信頼できる案件を見つける必要があります。

興味ある方はwrapperを使って興味のある案件を探してもらうと幸いです。(探すぶんにはサイトを見るほうが早いかも知れませんが、、、。自分のDBに保存したいという方には便利かと思います。)

coinexchangeのgem作りました

最近、仮想通貨にはまっているということでcoinexchangeのapiから簡単にデータを取得できるgem作りました。

github.com

ちなみにcoinexchangeは海外の取引所でapiはまだpublicなものしかなさそう。
なのでapiで取引はまだできません。 v2になったら作りなおそうかと思います。

https://www.coinexchange.io

中国でslackは使えるのか?

中国でのslack

最近、中国の雲南省に行ってきました。

会社からのslackでの連絡も見れるかどうかも確認したく、検証してみました。

中国のネット規制

まず、gmailfacebook、lineは使えません。
しかも心の拠り所のskypeまで規制対象になるそうです。
一体何のアプリを使えばいいんだ、、、

wechat使うのもなぁー。

とまぁ、中国行ったら色々困るわけです。

ネット検索も基本的に百度ですよ。 (自分はbing国際版を使っていました。bing素晴らしい!)

肝心のslack

じゃあslackってどうなの? という感じですが、 slackアプリ版は無事使えました! ブラウザ版は試していないのでわからないですが、どうにか日本とは連絡がとれます。
会社のプログラマもこれで安心できます。

安心するならVPN借りろって言う話なんですけどね。

※2017/11時点です

rspecでappディレクトリ以外のテスト(libとかただのscriptとか)

rspecでappディレクトリ以外をテストしたい時ってありませんか? 自分はあります。例えばバッチ処理とかのただのrubyスクリプト

普通のテスト

まず、普通のrspecのテストって下記のような構造で appとspecの位置関係は1対1のようになっています。

.
├── app
│   │
│   └── controllers
│       └── nantoka_controller.rb
│       
└── spec
    └── controllers
        └── nantoka_controller_spec.rb

そして、describeの後にクラス名を以下のように書くものだと思います。

nantoka_controller_spec.rb

require 'rails_helper'
describe NantokaController do
  it '#nantoka_methods' do
    expect(nantoka_methods).to eq "correct"
  end
end

nantoka_controller.rb

class NantokaController
  def nantoka_methods
    "correct"
  end
end
appディレクトリ以外のテスト

今回はプロジェクト配下にscriptディレクトリを作成しています。

.
├── app
│   │
│   └── controllers
│       └── application_controller.rb
│
├── script
│   └── process.rb
└── spec
    └── script
        └── process_spec.rb

実は簡単にテストができます。 require_relative使うだけです。 describeの後は文字列にしましょう。 まぁ、いったんスクリプトだと処理が呼ばれるのは仕方ないです。

process_spec.rb

require "rails_helper"
require_relative '../../script/process'

describe "stock_info_listing_update" do
  before do
    @job = Script::Process.new
  end
  it '#nantoka_process_methods' do
    expect(@job.nantoka_methods).to eq "correct"
  end
end

process.rb

module Script
  class Process
    def nantoka_methods
      "correct"
    end
  end
end

Script::Process.new.nantoka_methods

例えばですけどスクリプトじゃないbinとかlibのテストだとScript::Process.new.nantoka_methodsを呼び出さなくていいので普段通りテストできます。

bin/process.rb

module Script
  class Process
    def nantoka_methods
      "correct"
    end
  end
end

pythonでjwt使おうとしたらライブラリで詰まった件について(入れなおせばいいんだ!)

jwtって

そんな人は下記記事が参考になります。
今回はエラーの対処法のみです

qiita.com

ライブラリ似過ぎな件

①Pyjwt

github.com

②jwt

github.com

はい、こいつらの共存が悪影響を及ぼします。。。

名前空間でも影響しあってるのかな?
そこまで調べる気力はないので気になる人は自分で調べてください!

エラー内容

下記コマンド打つと"jwtは使えねーよ"(すいません、エラー内容消してしまいました。。。)
みたいな感じになりました.

sign = jwt.encode(auth_payload, api_secret, 'HS256')

解決法

まぁ、解決法は下記参考でなおりました!!(ちゃんとエラー内容書いてるよ)

stackoverflow.com

jwtもpyjwtもどっちも消して入れなおせよってことです

pip uninstall JWT  
pip uninstall PyJWT  
pip install PyJWT