Python/Arduino学習記録,備忘録

コツコツ学んだ学習記録と備忘録。現在Python,Arduino勉強中。

【Arduino#4】ボタンスイッチとLED回路(明暗3段階に変化)

前回のボタンスイッチ/LEDの回路に引き続き,ボタンスイッチを用いてLEDのの明るさを調節する回路を作る。
順序として,単純にLEDの明るさを設定可能な回路を作成した後に,スイッチと組み合わせ,3段階でスイッチング可能なLED回路を作成する。

1. 必要素子

〇LEDの明るさ設定する簡易回路

  • ブレッドボード
  • 抵抗(10kΩ)
  • LED
  • ジャンパー線 2本

〇スイッチを用いた明るさ調節回路

  • ブレッドボード
  • 抵抗(10kΩ) 2個
  • LED
  • ジャンパー線 5本
  • ボタンスイッチ(以下,SW)

2. 配線図

〇LEDの明るさ設定する簡易回路
f:id:opuktr:20180806215621p:plain



〇スイッチを用いた明るさ調節回路
f:id:opuktr:20180812103806p:plain


3. スケッチ

〇LEDの明るさ設定する簡易回路

const int LED = 9;//pin9にLED接続
int light = 0;//明るさの変数

void setup() {
  pinMode(LED, OUTPUT);//LEDpinを出力に設定
}

void loop() {
 
  light = 0; //LED暗
  analogWrite(LED, light); //PWM波を出力(デューティ比=0%)
  delay(1000);

  light = 128;  //LED中
  analogWrite(LED, light);//PWM波を出力(デューティ比=50%)
  delay(1000);

  light = 255;  //LED明
  analogWrite(LED, light);//(PWM波を出力デューティ比=100%)
  delay(1000);
}

〇スイッチを用いた明るさ調節回路

const int LED = 9;//LEDを13番pinに設定
const int SW = 7;//プッシュボタンを7番pinに設定

int val = 0;//7番pinから読み込んだ値を格納
int val_old = 0;//古いvalを格納
int state = 0;//SWの状態を格納
int light = 0;//明るさの変数

void setup() {
  pinMode(LED,OUTPUT);//LEDpinを出力に設定
  pinMode(SW, INPUT);//SWpinを入力に設定
}

void loop() {
  val = digitalRead(SW);//7番pinからHIGH/LOW読込

  //SWのON/OFFでstateの状態を変更
  if((val == HIGH)&&(val_old == LOW)){
    if(state==0){
      state = 1 ;//state=0 → state=1
      }else if(state==1){
        state = 2 ;//state=1 → state=2
      }else{
        state = 0 ;//state=2 → state=0
      }
    delay(10);//SWのバウンシングを防ぐために間隔設定
    }

    val_old = val;//1つ前のvalを格納

  //stateの状態によって明るさ設定
  if(state == 1){
    light = 255;  //LED明
    analogWrite(LED, light);//PWM波を出力(デューティ比=100%)
    }else if(state == 2){
      light = 128;  //LED中
      analogWrite(LED, light);//PWM波を出力(デューティ比=50%)
    }else{
      light = 0; //LED暗
      analogWrite(LED, light); //PWM波を出力(デューティ比=0%)
    }
}

4. スケッチで用いた関数まとめ

各々の関数についてまとめる。基本的にはArduino Referenceで説明されている。

const int LED = 9;
const int SW = 7;

変数を読み取り専用の変数として定義するもの
不変の値を設定したい時にconstを用いると良い。

  pinMode(LED,OUTPUT);
  pinMode(SW, INPUT);
//pinMode(pin番号, OUTPUT / INPUT / INPUT_PULLUP);
//戻り値:なし

pinの動作を入力(INPUT, INPUT_PULLUP)か出力(OUTPUT)に設定する関数
入力には以下の2種類ある。
INPUT:普通の入力
INPUT_PULLUP:マイコン内部のプルアップ抵抗を利用する(回路簡素化できる)

analogWrite(LED, light);
//analogWrite(pin番号, デューティ比に対応する値(0~255));
//戻り値:なし

指定したpinからPWM波を出力する関数
ここで,指定するpinはDigital pinの~がついているpin(3,5,6,9,10,11番pin)とする必要がある。
また,デューティ比に対応する値が0であれば0Vを出力,255であれば5V(3.3V)を出力する電圧源と等しくなる。

 delay(1000);
//delay(時間[単位はms]);
//戻り値:なし

指定した時間だけプログラムを止める関数
ここで,設定する時間はunsigned long型である。

digitalRead(SW);
//digitalRead(pin番号);
//戻り値:HIGH/LOW

指定したpinの値を読み取る関数
5Vボードでは,3V以上の電圧がかかるとHIGH,1.5V以下の電圧がかかるとLOWとなる。
3.3Vボードでは,2V以上の電圧がかかるとHIGH,1V以下の電圧がかかるとLOWとなる。

【Arduino#3】ボタンスイッチとLED回路

以前までは,スケッチ例であるBlinkについて扱っていましたが,これ以降は自分でスケッチを書くことでArduinoに対する理解を深めようと思う。
今回はボタンスイッチを用いて,スイッチ押すたびにLEDがON/OFF切り替わる回路を作成する。

1. 必要素子

  • ブレッドボード
  • 抵抗(10kΩ)
  • ボタンスイッチ(以下,SW)
  • LED
  • ジャンパー線 3本

2. 配線図

今回の配線図は以下の通り。
f:id:opuktr:20180805211041p:plain

これはSWのON/OFFを電圧に変換し,マイコンに読み取ることで,LEDを制御する回路となっている。
SWのON/OFFは黄色いジャンパー線が読み取っている。

以下に回路図を用いて説明する。赤い箇所は5Vを表す。
f:id:opuktr:20180805213311p:plain

  • SW=OFFの時

電圧源の+側は5Vであるが,SWがOFFになっていることから,SWの右半分はGNDと同様の0Vとなっている。
ここで,抵抗とGNDを接続しているのはSWの右半分の基準電圧を0Vに設定する為である。
即ち,配線図の黄色いジャンパー線でマイコンが読み取る値はLOWである。

  • SW=ONの時

SWがONになったことによって,5Vの範囲が拡大した。抵抗があることによって,ショートすることを防いでいる。
即ち,配線図の黄色いジャンパー線でマイコンが読み取る値はHIGHである。


以上の回路によって,読み取ったSWのON/OFFに準じた制御指令をLEDに送ることでLEDのON/OFFを達成する。

3. スケッチ

const int SW = 7;     //SWを7番pinに設定
const int LED = 13;  //LEDを13番pinに設定

int val = 0;           //7番pinから読み込んだ値を格納
int val_old = 0;    //古いvalを格納
int state = 0;       //SWの状態を格納

void setup() {
  pinMode(LED,OUTPUT); //13番pinを出力pinに設定
  pinMode(SW, INPUT);    //7番pinを入力pinに設定
}

void loop() {
  val = digitalRead(SW);//7番pinからHIGH/LOWを読込

  //SWのON/OFFでstateの状態を変更
  if((val == HIGH)&&(val_old == LOW)){
    state = 1 - state;   //state=0 → state=1-0,state=1 → state=1-1=0
    delay(10);  //SWのバウンシングを防ぐために間隔設定
    }

    val_old = val;  //1つ前のvalを格納

  //SW=ON⇒LED=ON or SW=OFF⇒LED=OFF
  if(state == 1){
    digitalWrite(LED, HIGH);
    }else{
      digitalWrite(LED,LOW);
    }
}

4. スケッチで用いた関数まとめ

各々の関数についてまとめる。基本的にはArduino Referenceで説明されている。

const int SW = 7;     //SWを7番pinに設定
const int LED = 13;  //LEDを13番pinに設定

変数を読み取り専用の変数として定義するもの
不変の値を設定したい時にconstを用いると良い。

 pinMode(LED,OUTPUT);
 pinMode(SW, INPUT);
//pinMode(pin番号, OUTPUT / INPUT / INPUT_PULLUP);
//戻り値:なし

pinの動作を入力(INPUT, INPUT_PULLUP)か出力(OUTPUT)に設定する関数
入力には以下の2種類ある。
INPUT:普通の入力
INPUT_PULLUP:マイコン内部のプルアップ抵抗を利用する(回路簡素化できる)

digitalRead(SW);
//digitalRead(pin番号);
//戻り値:HIGH/LOW

指定したpinの値を読み取る関数
5Vボードでは,3V以上の電圧がかかるとHIGH,1.5V以下の電圧がかかるとLOWとなる。
3.3Vボードでは,2V以上の電圧がかかるとHIGH,1V以下の電圧がかかるとLOWとなる。

digitalWrite(LED, HIGH);
digitalWrite(LED, LOW);
//digitalWrite(pin番号, HIGH / LOW);
//戻り値:なし

指定したpinにHIGHかLOWを設定する関数
基本的には,HIGH=5V,LOW=0Vだが,3.3VのボードではHIGH=3.3Vと設定される。

 delay(1000);
//delay(時間[単位はms]);
//戻り値:なし

指定した時間だけプログラムを止める関数
ここで,設定する時間はunsigned long型である。

【Arduino#2】void setup()とvoid loop()

前回【Arduino#1】Introduction - Python初心者のやってみた集,兼備忘録において,Blinkというスケッチを用いた。今回はスケッチの書き方について,Blinkを例にまとめる。

1. void setup()とvoid loop()

スケッチはvoid setup()void loop()で構成されている。書き方はC言語/C++を参考にすればよい。

大まかには,

  • void setup():スケッチが実行された時に1度だけ実行される指令を書く
  • void loop() :繰り返し実行される指令を書く

という違いがある。
上記を踏まえてBlinkのスケッチを見てみよう。

2. Blinkスケッチ

Arduino - Blinkに公開されているBlinkについてみる。
以下が,そのスケッチ(一部抜粋)である。

void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}

上記では,

  • void setup()での指令を「13番pinを出力pinと設定」
  • void loop()での指令を「デジタルの13番pinにHIGHを出力(13番pinを5Vとする)」→「1000ms (1s)待つ」→「デジタルの13番pinにLOWを出力(13番pinを0Vとする)」→「1000ms (1s)待つ」→…(繰り返し)

とするスケッチになっている。

ここで,各々の関数についてまとめる。基本的にはArduino Referenceで説明されている。

pinMode(LED_BUILTIN, OUTPUT);
//pinMode(pin番号, OUTPUT / INPUT / INPUT_PULLUP);
//戻り値:なし

pinの動作を入力(INPUT, INPUT_PULLUP)か出力(OUTPUT)に設定する関数
ここで,LED_BUILTINはArduino言語の特殊な定数である(参考:Arduino Reference)。
ほとんどのボードでは13番pinを指定していると考えてよいみたいだ。
また,入力には2種類あるが,慣れるまではINPUTを用いる予定。
INPUT:普通の入力
INPUT_PULLUP:マイコン内部のプルアップ抵抗を利用する(回路簡素化できる)

digitalWrite(LED_BUILTIN, HIGH);
digitalWrite(LED_BUILTIN, LOW);
//digitalWrite(pin番号, HIGH / LOW);
//戻り値:なし

指定したpinにHIGHかLOWを設定する関数
基本的には,HIGH=5V,LOW=0Vだが,3.3VのボードではHIGH=3.3Vと設定される。

 delay(1000);
//delay(時間[単位はms]);
//戻り値:なし

指定した時間だけプログラムを止める関数
ここで,設定する時間はunsigned long型である。

【Arduino#1】Introduction

f:id:opuktr:20180729162819p:plain
先日,Arduinoと呼ばれるマイコンを購入しました!
Amazonで「ELEGOO UNO キット レベルアップ  チュートリアル付 uno mega2560 r3 nanoと互換 Arduino用」というAmazon’s Choiceに選ばれている商品だそうで。

そこで,今回はArduinoのセットアップ(Windows)についてまとめておく。

1. Arduino統合開発環境(IDE)のインストール

Arduinoにスケッチ*1を実行させるために,スケッチを書ける環境を整える必要がある。
そこで,Arduino専用の統合開発環境IDE)をインストールする。

1. Arduino公式HPの「Software」→「Downloads」に飛ぶ。
 そのサイトがこちら:https://www.arduino.cc/en/Main/Software

以下のような画面になるので,「Windows Installer, for Windows XP and up 」をクリック。
f:id:opuktr:20180729164549p:plain

2. 「ダウンロードのみ」か「寄付してダウンロード」か選択できるので,どちらかを選択。
 今回は「ダウンロードのみ」をクリック。
f:id:opuktr:20180729164949p:plain

3. 以下のようなexeファイルがダウンロードされているので,実行。
f:id:opuktr:20180729165439p:plain

4. 「I Agree」→「Next」→「install」を押す。
 この時,急にデバイスソフトウェアのインストールが始まるので「インストール」。
 インストールが終わると,「Close」。

5. デスクトップ上にアイコンが出現していれば,完了。

↓↓アイコンをクリックすると以下のファイルが開くと思います。
f:id:opuktr:20180729172322p:plain

2. ドライバの設定

IDEの設定が終わったら,次にドライバを設定する必要がある(ほぼ自動でしてくれるが...)。

1. ArduinoボードとPCをUSBケーブルで接続する。
f:id:opuktr:20180729171708p:plain

2. 電源LEDと動作確認用LEDが点灯すれば完了。

3. 動作確認(LEDチカチカさせる)

動作確認の為,キットに入っていたLEDでLチカ*2させてみる。

本来ならば自分でスケッチを書くべきだが,実はIDEと共にスケッチ例がインストールされているのでそちらを用いる。

1. Arduino IEDを開き,「ファイル」→「スケッチ例」→「01.Basics」→「Blink」を開く。
左上の「検証」を押し,コンパイルし,エラーが無いか確認する。
このスケッチの詳細はhttp://www.arduino.cc/en/Tutorial/Blinkで説明されている。
f:id:opuktr:20180729171319p:plain

2. Arduinoボード,ブレッドボード,ジャンパー線(2本),抵抗(220Ω以上のもの),LEDを用いて以下の様に回路を組む。
f:id:opuktr:20180729175953p:plain

3. Arduino IDEの左上の「マイコンボードへ書き込み」を押す。
 LEDが点滅すれば成功。

今後,センサで計測した値をシリアル通信でPCに飛ばし,Pythonとか使って遊べたらいいかなという感じ。

*1:Arduinoに実行させる制御プログラム

*2:LEDをチカチカ

【bitbank自動売買#4】リアルタイムAPIについて

今回はリアルタイムAPIについての記事。
というのも,自動売買(bot)を作ってもそのbotの勝率を確かめるために,過去の価格情報収集方法を色々調べてたらリアルタイムAPIというものを発見。

そこで,今回はリアルタイムAPIを用いる為の環境構築と使用結果について書く。

1. リアルタイムAPIとは

リアルタイムAPIとは何か?
簡単にいうと,リアルタイムで取引所の価格情報を受信することが出来るAPIだと解釈した。

私はbitbankの公式サイトからこの存在を知った。そもそも,Pubnubってなんだよレベルから始まった。
f:id:opuktr:20180520023112p:plain

このPubnubを使えば,bitbankの価格情報をリアルタイムで取得できるので,あとは保存すればいいよねっていう考えで,とりあえずやってみた。

2. Pubnubの環境構築

今回は以下の方法を参考にして,Pubnubから価格情報を取得することを試みた。
bitcoin-systra.hatenablog.com


ここでは,Pubnubとtronadoを用いるので,この2つのパッケージをインストールする。
コマンドプロンプトから,以下のコードを叩くとインストールが完了する(但し,pipのインストールが必要)。

pip install pubnub
pip install tronado

ここで,問題発生。
「parse() got an unexpected keyword argument 'transport_encoding'」とエラーを吐き,インストールが出来ない。
色々調べてみると,pipのversionが「9.0.1-py36hadba87b_3」であることが問題である可能性があるということなので,以下のコードによりversionを変更。

conda install pip

すると,見事2つともインストール完了した。

これにより,Pubnubとtronadoのパッケージが使用可能となるので,あとはサイトを参考にしてコードを書いてみる(ほぼコピーです)。

3. Pubnubとtronadoを用いてリアルタイムで価格情報受信

from pubnub.callbacks import SubscribeCallback
from pubnub.pnconfiguration import PNConfiguration
from pubnub.pubnub_tornado import PubNubTornado
from pubnub.pnconfiguration import PNReconnectionPolicy

config = PNConfiguration()
#bitbankが公開しているSubscribeKeyを設定
config.subscribe_key = 'sub-c-e12e9174-dd60-11e6-806b-02ee2ddab7fe'
config.reconnect_policy = PNReconnectionPolicy.LINEAR
pubnub = PubNubTornado(config)

from tornado import gen

@gen.coroutine
def main(channels):
    class BitbankSubscriberCallback(SubscribeCallback):

        def message(self, pubnub, message):
            # 登録したチャンネルからメッセージ(価格の変化など)がくるたび、この関数が呼ばれます
            print("%s : %s" % (message.channel, message.message))

    listener = BitbankSubscriberCallback()
    pubnub.add_listener(listener)
    pubnub.subscribe().channels(channels).execute()

if __name__ == '__main__':
 #チャンネル設定
    channels = [ 'candlestick_btc_jpy' ]
    main(channels)
    pubnub.start()

コードの内容はあまり理解できていません。解読がんばる。
実行すると,コンソールにどんどんと価格情報が受信されます。
f:id:opuktr:20180520202545p:plain
チャンネルについては,公式サイトに掲載されていますので,そちらを参照してください。
f:id:opuktr:20180520203125p:plain


一応,受信は出来たが,当初の目的である過去の価格情報を取得したり,リアルタイム情報を保存することが出来ていないので,もう少し別のアプロ―チでも考えてみる。
うおお,先は長い。。。

【bitbank自動売買#3】python_bitbankccの使い方学習(プライベートAPI)

ここでは,【bitbank自動売買#2】に引き続きプライベートAPIについて学習する。


プライベートAPIを使用する際には「APIキー」「シークレット」が必要。
これらの情報は決して他人に公開してはダメ。

#AIPキー
API_KEY = 'BITBANK_API_KEY'
#シークレット
API_SECRET = 'BITBANK_API_SECRET'

これらの情報は,bitbankのAPIから確認可能。

さて,ここから実際にプログラムを動かしてみる。

1. アセット情報の取得

#python_bitbankccのパッケージをインポート
import python_bitbankcc

#APIキー,シークレットの設定
API_KEY = 'BITBANK_API_KEY'
API_SECRET = 'BITBANK_API_SECRET'

#privte API classのオブジェクトを取得
prv = python_bitbankcc.private(API_KEY, API_SECRET)

#アセット一覧の取得
value = prv.get_asset()

#アセット情報の一例
asset_ex = value['assets'][5]
print('通貨名:' + asset_ex['asset'])
print('保有量:' + asset_ex['onhand_amount'])
print('ロックされている量:' + asset_ex['locked_amount'])
print('利用可能な量:' + asset_ex['free_amount'])
print('引き出し手数料:' + asset_ex['withdrawal_fee'])
《出力結果》
通貨名:mona
保有量:3.55940000
ロックされている量:0.00000000
利用可能な量:3.55940000
引き出し手数料:0.00100000

get.assetを用いることで,アセット*1情報が取得可能となる。
今回は「MONA」の情報を出力している。
変数valueには「JPY」「BTC」「LTC」「XRP」「ETH」「MONA」「BCC」の順で格納されているので,「JPY」の情報を取得したい場合は以下の様にすればよい。

#BTC ⇒ JPY 
asset_ex = value['assets'][5] ⇒ asset_ex = value['assets'][0]

2. 注文IDを指定して注文情報を取得

#python_bitbankccとdatetimeのパッケージをインポート
import python_bitbankcc
import datetime

#APIキー,シークレットの設定
API_KEY = 'BITBANK_API_KEY'
API_SECRET = 'BITBANK_API_SECRET'

#privte API classのオブジェクトを取得
prv = python_bitbankcc.private(API_KEY, API_SECRET)

#注文情報の取得
value = prv.get_order( 'bcc_jpy', '14288606' )#'ペア', '注文ID'

#注文情報の一例
print('取引ID:' + str(value['order_id']))
print('通貨ペア:' + value['pair'])
print('売買情報:' + value['side'])
print('注文タイプ:' + value['type'])
print('注文時の数量:' + value['start_amount'])
print('未約定の数量:' + value['remaining_amount'])
print('約定済の数量:' + value['executed_amount'])
print('注文価格:' + value['price'])
print('平均約定価格:' + value['average_price'])
print('注文状態:' + value['status'])
print('注文日時:' + str(datetime.datetime.fromtimestamp(value['ordered_at']/1000)))
print('約定日時:' + str(datetime.datetime.fromtimestamp(value['executed_at']/1000)))
《出力結果》
取引ID:14288606
通貨ペア:bcc_jpy
売買情報:sell
注文タイプ:limit
注文時の数量:0.07260000
未約定の数量:0.00000000
約定済の数量:0.07260000
注文価格:165000.0000
平均約定価格:165000.0000
注文状態:FULLY_FILLED
注文日時:2018-05-13 21:48:23.977000
約定日時:2018-05-14 06:12:58.246000

get_orderを用いることで,指定したIDの注文情報が取得可能となる。
また,prv.get_orders_infoを用いることで,複数の注文IDを指定することが可能となる。

使い方
単数:prv.get_order( 'ペア', '注文ID' )
複数:prv.get_orders_info(  'ペア', ['注文ID', '注文ID', .....] )

「注文状態」には,「UNFILLED(注文中)」「PARTIALLY_FILLED(注文中(一部約定))」「FULLY_FILLED(約定済み)」「CANCELED_UNFILLED(取消済)」「CANCELED_PARTIALLY_FILLED(取消済(一部約定))」の5種類存在する。

3. アクティブな注文情報を取得

#python_bitbankccとdatetimeのパッケージをインポート
import python_bitbankcc
import datetime

#APIキー,シークレットの設定
API_KEY = 'BITBANK_API_KEY'
API_SECRET = 'BITBANK_API_SECRET'

#privte API classのオブジェクトを取得
prv = python_bitbankcc.private(API_KEY, API_SECRET)

#アクティブな注文一覧の取得
value = prv.get_active_orders( 'bcc_jpy' )

#注文一覧の一例
order_ex = value['orders'][0]
print('取引ID:' + str(order_ex['order_id']))
print('通貨ペア:' + order_ex['pair'])
print('売買情報:' + order_ex['side'])
print('注文タイプ:' + order_ex['type'])
print('注文時の数量:' + order_ex['start_amount'])
print('未約定の数量:' + order_ex['remaining_amount'])
print('約定済の数量:' + order_ex['executed_amount'])
print('注文価格:' + order_ex['price'])
print('平均約定価格:' + order_ex['average_price'])
print('注文状態:' + order_ex['status'])
print('注文日時:' + str(datetime.datetime.fromtimestamp(order_ex['ordered_at']/1000)))
《出力結果》
取引ID:14771060
通貨ペア:bcc_jpy
売買情報:sell
注文タイプ:limit
注文時の数量:0.07270000
未約定の数量:0.07270000
約定済の数量:0.00000000
注文価格:200000.0000
平均約定価格:0.0000
注文状態:UNFILLED
注文日時:2018-05-16 23:04:37.516000

get_active_ordersを用いることで,アクティブな注文情報が取得可能となる。

4. 新規注文を行う

本当に注文が通るので,注意して自己責任でプログラムを実行してください。

#python_bitbankccとdatetimeのパッケージをインポート
import python_bitbankcc
import datetime

#APIキー,シークレットの設定
API_KEY = 'BITBANK_API_KEY'
API_SECRET = 'BITBANK_API_SECRET'

#privte API classのオブジェクトを取得
prv = python_bitbankcc.private(API_KEY, API_SECRET)

#新規注文を行う:'ペア', '価格', '注文枚数', '売or買', '指値or成行'
value = prv.order( 'bcc_jpy', '200000', '0.07', 'sell', 'limit' )

#新規注文内容
print('取引ID:' + str(value['order_id']))
print('通貨ペア:' + value['pair'])
print('売買情報:' + value['side'])
print('注文タイプ:' + value['type'])
print('注文時の数量:' + value['start_amount'])
print('未約定の数量:' + value['remaining_amount'])
print('約定済の数量:' + value['executed_amount'])
print('注文価格:' + value['price'])
print('平均約定価格:' + value['average_price'])
print('注文状態:' + value['status'])
print('注文日時:' + str(datetime.datetime.fromtimestamp(value['ordered_at']/1000)))

#注文のキャンセル(ここでは,上記の注文を即時にキャンセルしている)
prv.cancel_order( value['pair'], str(value['order_id']) ) #'ペア', '注文ID'
《出力結果》
取引ID:14779241
通貨ペア:bcc_jpy
売買情報:sell
注文タイプ:limit
注文時の数量:0.07000000
未約定の数量:0.07000000
約定済の数量:0.00000000
注文価格:200000.0000
平均約定価格:0.0000
注文状態:UNFILLED
注文日時:2018-05-17 00:29:48.840000

orderにより,新規注文が可能となる。
一方で,cancel_orderにより,注文をキャンセル可能となる(複数キャンセルも可能)。

使い方
単数:cancel_order( 'ペア', '注文ID' )
複数:cancel_order( 'ペア', ['注文ID', '注文ID', .....] )

ただし,以下の様に「取引」を選択したAPIキーを発行・使用する必要があることに注意。
f:id:opuktr:20180517002535p:plain
「取引」を選択していないAPIキーを用いると,「エラーコード: 20001 内容: API認証に失敗しました」となる。

5. 約定履歴を取得する

#python_bitbankccのパッケージをインポート
import python_bitbankcc

#APIキー,シークレットの設定
API_KEY = 'BITBANK_API_KEY'
API_SECRET = 'BITBANK_API_SECRET'

#privte API classのオブジェクトを取得
prv = python_bitbankcc.private(API_KEY, API_SECRET)

#約定履歴を取得する: 'ペア', '取得する約定数'
value = prv.get_trade_history( 'bcc_jpy', '10' )

この時「エラーコード: 20001 内容: API認証に失敗しました」を吐いてしまうので原因分析中。
(自動売買プログラムに使う時まで眠らす可能性も)
何か心当たりある方教えて頂けるとありがたいです。
もしかしたら,まだ制限されている可能性あり(以下参照)。
bitbank.cc

では,次回はいよいよ自動売買プログラムにとりかかります。

*1:資産:JPY,BTC,XRP,ETHなど

【bitbank自動売買#2】python_bitbankccの使い方学習(パブリックAPI)

【bitbank自動売買#1】では,pythonでコードを書く準備をしてきましたが,今回は実際にインストールしたパッケージを用いてコードを動かします。

 

以下に「python_bitbankcc」の使い方について説明はこちらに載っていますが,説明がざっくりしているので,実際に使ってみるのがよいかと。

GitHub(コード少し有り):https://github.com/bitbankinc/python-bitbankcc

②bitbank.ccの(公式):https://docs.bitbank.cc/#/

 

 APIには,パブリックAPIとプライベートAPIが存在する。

パブリックAPI・・・APIキーが必要なく利用可能なAPI

プライベートAPI・・・個人毎にAPIキーが必要で,個人情報を扱うことが可能なAPI

 

さて,ここから実際にプログラムを動かしてみます。まずはパブリックAPIについて。

1. ティッカー情報の取得

#python_bitbankccのパッケージをインポート
import python_bitbankcc 

# public API classのオブジェクトを取得
pub = python_bitbankcc.public()

# ティッカー情報を取得
value = pub.get_ticker( 'xrp_jpy' )

#現在の売り注文の最安値
print('sell:' + value['sell'])
#現在の買い注文の最安値
print('buy:' + value['buy'])
《出力結果》
sell:95.110
buy:95.100

ここで言う,ティッカー情報とは

  • sell: 現在の売り注文の最安値
  • buy: 現在の買い注文の最安値
  • high: 過去24時間の最高値取引価格
  • low: 過去24時間の最安値取引価格
  • last: 最新取引価格
  • vol: 過去24時間の出来高

 を指しており,get_tickerを用いることで,上記の情報が取得可能。

使い方
value = pub.get_ticker( 'ペア' )
ペア例⇒btc_jpy, xrp_jpy, ltc_btc, eth_btc, mona_jpy, mona_btc, bcc_jpy, bcc_btc

2. 板情報の取得

#python_bitbankccのパッケージをインポート
import python_bitbankcc 

# public API classのオブジェクトを取得
pub = python_bitbankcc.public()

# 板情報を取得
value = pub.get_depth( 'xrp_jpy' )

#売り板
print('売り板 [価格, 数量]:' + ','.join(map(str,value['asks'])))
#買い板
print('買い板 [価格, 数量]:' + ','.join(map(str,value['bids'])))
《出力結果》
売り板 [価格, 数量]:['97.350', '0.9877'],['97.357', '336.4811'],['97.372', '100.0000'],['97.397', '1000.0000'],['97.398', '2000.0000'],['97.399', '13966.7493'],['97.440', '4597.0588'],['97.448', '6812.6211'],['97.450', '7109.4659'],['97.464', '50.0000'],['97.465', '1.0259'],['97.499', '4304.8276'],['97.500', '30581.5952'],['97.501', '50.0000'],['97.505', '50.0000'],['97.507', '50.0000'],['97.598', '7115.7376'],['97.600', '6447.2530'],['97.603', '1070.0591'],['97.620', '200.0000'],['97.697', '656.9891'],['97.700', '17093.0801'],['97.713', '605.2533'],['97.750', '9167.3786'],['97.765', '640.4537'],['97.780', '300.0000'],['97.791', '50.0000'],['97.798', '1454.0174'],['97.799', '63873.6482'],['97.800', '66060.0511'],['97.801', '1029.9649'],['97.810', '14910.0524'],['97.820', '1403.8812'],['97.830', '2160.4389'],['97.844', '545.5653'],['97.845', '6194.8278'],['97.850', '6285.2523'],['97.860', '322.0000'],['97.881', '50.0000'],['97.890', '4170.5356'],['97.900', '35504.1476'],['97.901', '50.0000'],['97.920', '50.0000'],['97.936', '460.4725'],['97.940', '0.1000'],['97.941', '1.1111'],['97.942', '1.1111'],['97.949', '200.0000'],['97.950', '2626.4375'],['97.952', '5.2111'],['97.954', '1.1111'],['97.956', '1.1111'],['97.958', '1.1111'],['97.959', '4000.0000'],['97.960', '2042.7718'],['97.961', '1.1111'],['97.962', '51.1111'],['97.963', '1.1111'],['97.964', '1.1111'],['97.965', '100.0000'],['97.970', '0.1000'],['97.979', '2010.0000'],['97.980', '16867.6350'],['97.982', '50.0000'],['97.989', '797.2613'],['97.990', '391.1000'],['97.995', '0.0010'],['97.997', '50.0000'],['97.998', '850.0000'],['97.999', '46872.1637'],['98.000', '112256.2377'],['98.001', '50.0000'],['98.003', '50.0000'],['98.009', '71.0000'],['98.010', '536.7988'],['98.025', '17147.2806'],['98.034', '52.7888'],['98.040', '2000.0000'],['98.052', '50.0000'],['98.054', '50.0000'],['98.065', '61.2463'],['98.070', '6.8497'],['98.088', '15355.5137'],['98.096', '50.0000'],['98.100', '1689.2583'],['98.110', '1500.1081'],['98.123', '6469.0000'],['98.150', '826.7256'],['98.170', '11.0000'],['98.180', '0.1000'],['98.200', '9845.4466'],['98.221', '1500.0000'],['98.235', '172.3535'],['98.240', '0.1000'],['98.242', '71.5729'],['98.250', '800.0000'],['98.255', '100.0000'],['98.263', '9.7965'],['98.270', '311.0000'],['98.300', '13923.3426'],['98.310', '6167.8526'],['98.312', '455.8005'],['98.320', '0.2000'],['98.324', '2097.5549'],['98.330', '0.3000'],['98.350', '3530.1000'],['98.362', '100.0000'],['98.370', '17.0000'],['98.400', '36546.4974'],['98.402', '411.0000'],['98.448', '264.2404'],['98.470', '26.0000'],['98.479', '2500.0000'],['98.480', '0.1000'],['98.490', '230.0000'],['98.499', '5212.9080'],['98.500', '44729.3235'],['98.555', '5.0000'],['98.570', '26.0000'],['98.577', '250.0000'],['98.590', '5377.5260'],['98.592', '250.0000'],['98.598', '340.4155'],['98.599', '600.0000'],['98.600', '10026.5121'],['98.601', '4000.0000'],['98.633', '10375.6451'],['98.650', '3500.0000'],['98.670', '126.0000'],['98.697', '1109.0000'],['98.700', '6036.8900'],['98.710', '18636.3394'],['98.716', '250.0000'],['98.738', '1.7931'],['98.750', '5837.7034'],['98.755', '200.0000'],['98.770', '37.0000'],['98.775', '1012.4019'],['98.789', '13.0000'],['98.800', '17179.0684'],['98.810', '250.0000'],['98.850', '1500.0000'],['98.860', '1000.0000'],['98.870', '37.0000'],['98.890', '102.0000'],['98.899', '21.1896'],['98.900', '35543.3417'],['98.921', '94.3690'],['98.940', '2050.0000'],['98.970', '37.0000'],['98.980', '250.0000'],['98.981', '500.0000'],['98.987', '6.9023'],['98.989', '4000.0000'],['98.995', '110.6903'],['98.997', '1623.0000'],['98.999', '1023.7574'],['99.000', '241212.8386'],['99.012', '38.5631'],['99.070', '37.0000'],['99.075', '100.0000'],['99.080', '3203.1560'],['99.090', '4000.0000'],['99.098', '2428.0521'],['99.100', '13406.0561'],['99.103', '300.0000'],['99.107', '200.0000'],['99.170', '37.0000'],['99.180', '4.5501'],['99.191', '2300.0000'],['99.198', '6.5651'],['99.200', '9984.9523'],['99.205', '6488.1028'],['99.230', '20649.3300'],['99.243', '70.0000'],['99.258', '500.3308'],['99.270', '7.0000'],['99.300', '19243.3713'],['99.335', '4.5145'],['99.350', '1000.0000'],['99.370', '12.0000'],['99.400', '8649.2345'],['99.410', '100.0000'],['99.432', '251.0000'],['99.441', '15000.0000'],['99.450', '25.0000'],['99.470', '7.0000'],['99.474', '493.0000'],['99.487', '200.0000'],['99.490', '110.0000'],['99.500', '149305.4019'],['99.550', '2000.0000'],['99.560', '5000.0000'],['99.570', '501.5824'],['99.580', '283.8207'],['99.600', '31912.5932'],['99.610', '30.0000'],['99.640', '200.0000'],['99.670', '57.0000'],['99.700', '7085.1034']
買い板 [価格, 数量]:['97.301', '69.4011'],['97.300', '13017.0538'],['97.270', '1608.2176'],['97.265', '5237.9025'],['97.250', '4121.9940'],['97.240', '5000.0000'],['97.210', '311.1311'],['97.204', '1.0287'],['97.203', '3809.0162'],['97.201', '6767.1992'],['97.200', '28731.7438'],['97.165', '6073.2298'],['97.161', '1323.0786'],['97.160', '2037.9356'],['97.157', '859.4831'],['97.156', '3903.2252'],['97.155', '211.0000'],['97.153', '8372.6244'],['97.152', '50.0000'],['97.151', '1463.6996'],['97.150', '12385.3808'],['97.125', '2541.0518'],['97.120', '85.1043'],['97.117', '1.0296'],['97.108', '50.0000'],['97.101', '96.6025'],['97.100', '54405.4078'],['97.084', '50.0000'],['97.050', '15708.4994'],['97.011', '24997.1515'],['97.010', '550.0000'],['97.007', '332.0000'],['97.003', '1004.0000'],['97.002', '8089.0524'],['97.001', '27523.5016'],['97.000', '84438.0985'],['96.999', '1.0309'],['96.987', '983.7611'],['96.970', '3000.0000'],['96.950', '9550.2142'],['96.919', '2000.0000'],['96.910', '638.1237'],['96.900', '28452.1750'],['96.880', '1000.0000'],['96.875', '500.0000'],['96.872', '4311.4824'],['96.870', '110.0000'],['96.867', '400.0000'],['96.855', '43588.1946'],['96.850', '31495.4958'],['96.840', '9041.8946'],['96.821', '3934.2501'],['96.820', '3582.4829'],['96.812', '1693.0238'],['96.810', '5460.1555'],['96.805', '0.9785'],['96.801', '500.0000'],['96.800', '139423.5395'],['96.799', '5000.0000'],['96.770', '20670.0000'],['96.710', '665.6264'],['96.700', '22493.9051'],['96.699', '10000.0000'],['96.650', '937.7138'],['96.630', '399.6611'],['96.625', '5.0000'],['96.620', '149.0000'],['96.617', '642.2381'],['96.601', '1000.0000'],['96.600', '149854.9761'],['96.599', '15181.8818'],['96.580', '14544.7727'],['96.555', '168.1215'],['96.552', '3291.3816'],['96.550', '18785.7809'],['96.545', '50.0000'],['96.539', '193.5494'],['96.521', '594.6762'],['96.510', '11560.7840'],['96.502', '311.7029'],['96.501', '33440.9377'],['96.500', '236123.3926'],['96.470', '20000.0000'],['96.450', '85.4845'],['96.430', '100.0000'],['96.414', '4.3303'],['96.401', '1000.0000'],['96.400', '8209.0466'],['96.370', '201.0000'],['96.350', '220.9989'],['96.340', '6.9999'],['96.310', '1241.7122'],['96.309', '977.1502'],['96.305', '250.0000'],['96.300', '31645.9353'],['96.299', '31.1529'],['96.288', '150.0000'],['96.263', '4.1903'],['96.258', '1047.8291'],['96.250', '259.7402'],['96.222', '222.0000'],['96.219', '6.4090'],['96.213', '100.0000'],['96.210', '359.2232'],['96.202', '1325.0000'],['96.201', '500.0000'],['96.200', '24215.5751'],['96.185', '861.0715'],['96.182', '100.0000'],['96.152', '400.0000'],['96.150', '9540.6280'],['96.120', '1291.0000'],['96.112', '100.0000'],['96.111', '222.0000'],['96.110', '1498.1760'],['96.101', '46.4877'],['96.100', '5152.6736'],['96.096', '0.1234'],['96.056', '1525.0000'],['96.043', '4536.3652'],['96.024', '520.7036'],['96.011', '80.7348'],['96.010', '500.0000'],['96.005', '20342.5839'],['96.003', '100.0000'],['96.002', '200.0000'],['96.001', '115.9061'],['96.000', '272135.4497'],['95.999', '333.0000'],['95.987', '1000.0000'],['95.929', '1000.0000'],['95.900', '1209.2081'],['95.888', '333.0000'],['95.878', '6456.2079'],['95.834', '1.7830'],['95.822', '1.1601'],['95.820', '800.0000'],['95.801', '520.0000'],['95.800', '76112.1846'],['95.799', '9.3341'],['95.777', '333.0000'],['95.760', '16870.7866'],['95.759', '2646.8762'],['95.750', '3755.3894'],['95.700', '11921.9863'],['95.691', '600.0000'],['95.690', '342.9920'],['95.671', '63.3708'],['95.666', '333.0000'],['95.665', '562.4805'],['95.641', '200.0000'],['95.621', '400.0000'],['95.620', '6842.2904'],['95.612', '7792.2404'],['95.600', '64038.8019'],['95.557', '277.0293'],['95.555', '1784.5176'],['95.520', '1923.3673'],['95.511', '500.0000'],['95.510', '90075.1376'],['95.501', '59.6261'],['95.500', '79967.9311'],['95.460', '4.3277'],['95.444', '333.0000'],['95.401', '3533.9193'],['95.400', '1440.2238'],['95.370', '8113.9554'],['95.333', '333.0000'],['95.327', '1169.0000'],['95.313', '6.3760'],['95.311', '200.0000'],['95.310', '4.2729'],['95.300', '15361.9981'],['95.293', '307.0000'],['95.280', '29.0000'],['95.276', '2600.0000'],['95.260', '2149.0347'],['95.253', '1000.0000'],['95.244', '10000.0000'],['95.222', '333.0000'],['95.202', '11.4905'],['95.201', '500.0000'],['95.200', '39466.5452'],['95.187', '39.9302'],['95.150', '415.6012'],['95.120', '2507.3767'],['95.116', '300.0000'],['95.111', '338.0000'],['95.101', '12.0000'],['95.100', '10425.2627'],['95.076', '3000.0000'],['95.061', '81.8983'],['95.059', '0.1234'],['95.054', '200.0000'],['95.050', '100.0000'],['95.010', '969.3855'],['95.004', '100.0000'],['95.001', '5630.7872'],['95.000', '311228.6140'],['94.999', '444.0000']

get_depthを用いることで,板情報が取得可能となる。

ここで,valueにはdict型(辞書型)で「'asks':list型」,「'bids':list型」が格納されているため,join*1とmap*2を用いて文字列に変換している。
(参考:https://www.sejuku.net/blog/41752)

3. 全約定履歴の取得

#python_bitbankccとdatetimeのパッケージをインポート
import python_bitbankcc
import datetime 

# public API classのオブジェクトを取得
pub = python_bitbankcc.public()

# 全約定履歴を取得
value = pub.get_transactions( 'xrp_jpy' )

#約定履歴の一例
trans_ex = value['transactions'][0]
print('取引ID:' + str(trans_ex['transaction_id']))
print('売買情報:' + trans_ex['side'])
print('約定価格:' + trans_ex['price'])
print('数量:' + trans_ex['amount'])
print('約定日時:' + str(datetime.datetime.fromtimestamp(trans_ex['executed_at']/1000)))
《出力結果》
取引ID:8409434
売買情報:buy
約定価格:97.600
数量:5.5050
約定日時:2018-05-05 11:40:28.475000

get_transactionsを用いることで,約定履歴が取得可能となる。

ここで,2. 板情報の取得と同様に,「transaction_id」「execued_at」はint型なのでstr型に変換している。
また,「execued_at」はUnixTime*3のミリ秒表示なので,日付に変換する。
そこで,パッケージdatetimeをインポートし,datetime.datetime.fromtimestamp*4を用いる。
この時,ミリ秒表示であることから1000で除している。

加えて,日時を指定するとその日付の全約定履歴も取得可能。

使い方
value = get_transactions( 'ペア' )
又は
value = get_transactions( 'ペア', 'YYYYMMDD 型の日付' )
YYYYMMDD 型の日付例⇒20180504

4. ロウソク足データの取得

#python_bitbankccとdatetimeのパッケージをインポート
import python_bitbankcc
import datetime

# public API classのオブジェクトを取得
pub = python_bitbankcc.public()

# ロウソク足データを取得
value = pub.get_candlestick( 'xrp_jpy',  '1hour', '20180504' )

#ローソク足情報の一例(2018/5/4 午前9時の1時間足)
candle = value['candlestick'][0]
print('candle type:' + candle['type'])
print('始値:' + candle['ohlcv'][0][0])
print('高値:' + candle['ohlcv'][0][1])
print('安値:' + candle['ohlcv'][0][2])
print('終値:' + candle['ohlcv'][0][3])
print('出来高:' + candle['ohlcv'][0][4])
print('対象時刻:' + str(datetime.datetime.fromtimestamp(candle['ohlcv'][0][5]/1000)))
《出力結果》
candle type:1hour
始値:95.899
高値:95.900
安値:94.753
終値:95.080
出来高:5475452.3220
対象時刻:2018-05-04 09:00:00

get_candlestickを用いることで,ローソク足データが取得可能となる。

使い方
value = get_candlestick( 'ペア', 'ローソク足のタイプ', 'YYYYMMDD 型の日付' )
ローソク足のタイプ例⇒1min, 5min, 15min, 30min, 1hour, 4hour, 8hour, 12hour, 1day, 1week
YYYYMMDD 型(YYYY型でも良い)の日付例⇒20180504, 2017


パブリックAPIについてはこれで完了。次回はプライベートAPIを使ってみる。
opuktr.hatenablog.com

*1:‘区切り文字’.join(list)⇒同一型(str型,etc...)のlistを区切り文字を用いて区切る

*2:map(関数, list)⇒第二引数に第一引数の関数を適用

*3:1970年1月1日午前0時0分0秒から形式的な経過秒数

*4:datetime.datetime.fromtimestamp(UnixTime)⇒UnixTimeを日付に変換