Bot取引プログラムのソースコードを一部公開します。
見せ玉(みせぎょく)とは、約定の意図なく特定の株式等の売買状況に関し、大量の注文を発注・取消・訂正を行いあたかも取引が活発であると見せかけ第三者の取引を誘因する注文[1]。見せ板(みせいた)とも言う。
wikipedia:見せ玉からの引用。
見せ玉って何?美味しいの?って人は詳しくは検索して下さいませ。
簡単に説明すると買う気もないのに買う素振り見せてBitcoinの価格を誘導させて取引を有利にする。といった具合でしょうか。
本サイトに訪れて頂いたユーザさんからこんなの作れない?と要望があったからです。
私自身はこのbotプログラムを利用して取引は行っておりませんが、面白そうだなーって事で作成しました。
※作成日数も2日程なので適当な名前付けをしている所もあります。
ソースコードに書いてある分は自由に利用して頂いていいと考えております。
プログラムを実行させると注文とキャンセルを行う処理が走りますので注文が成立したり、予期せぬ不具合等があるかもしれませんが当方は一切責任及び対応出来ませんのでご理解の上ご利用下さいませ。
再配布はまぁ自由にw
プログラムはbitflyerでBTCを購入を行うものになります。
require 'net/https' require 'net/http' require 'uri' require 'openssl' require 'json' require 'open-uri' require 'time' require 'rubygems' require 'sqlite3' # --------------------------------------------- # 設定はここから dbname = "miseita.db" order_kakaku = 0.05 #(例0.25% => 0.0025 現在の価格が50000jpy/btcの場合 => 49875jpy/btcでオーダーを行います。) btc_kakaku = 0.5 #注文するトータルbtc ※分けて注文する時に1回の注文が0.01btc以下になる場合は強制的に0.01btcでオーダーします。 order_kaisu = 3 #分けて注文する回数 cancel_wait_time = 60 #注文してからキャンセルを行う時間(秒) @automatic_canceling = 5 #自動的にキャンセル処理を行う時間(分) sell_buy = 1 # 1はbtcの購入 2はbtcの販売 3は両方 ※まだ実装していません。 @bitflyer_key = "aaaaaaaaaaaaaa" @bitflyer_secret = "bbbbbbbbbbbbbbbb" @stock_or_fx = "BTC_JPY" #fxを行う場合は"FX_BTC_JPY"に変更 # 設定ここまで # --------------------------------------------- #bitflyerのticker bitflyer_content = open("https://api.bitflyer.jp/v1/getticker").read bitflyer_json_data = JSON.parse(bitflyer_content) #bitflyerのbidとaskを取り出す bitflyer_bid = bitflyer_json_data["best_bid"] #bitcoinを売る時 bitflyer_ask = bitflyer_json_data["best_ask"] #bitcoinを買う時 def bitflyer_info #bitflyerのbalanceAPI # balanceの確認 puts "balanceの確認開始" key = @bitflyer_key secret = @bitflyer_secret uri = URI.parse "https://api.bitflyer.jp/v1/me/getbalance" method = "GET" path = "/v1/me/getbalance" nonce = Time.now.to_i.to_s body = "hoge=foo" message = nonce + method.to_s + path.to_s# + body signature = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new("sha256"), secret, message) headers = { "ACCESS-KEY" => key, "ACCESS-TIMESTAMP" => nonce, "ACCESS-SIGN" => signature, "Content-Type" => "application/json" } https = Net::HTTP.new(uri.host, uri.port) https.use_ssl = true response = https.get(uri, headers) body = response.body @balance_json_data = JSON.parse(body) puts @balance_json_data #ブロックが分かれている時の処理。 # puts json_data[0]["currency_code"] # 結果 => JPY # puts json_data[1]["currency_code"] # 結果 => BTC # [{"currency_code"=>"JPY", "amount"=>34551.0, "available"=>34551.0}, # {"currency_code"=>"BTC", "amount"=>0.01, "available"=>0.01}] puts "balanceの確認完了" #balanceの確認ここまで end puts "注文出来るか確認します。" bitflyer_info total_purchase_volume = btc_kakaku * bitflyer_ask if total_purchase_volume > @balance_json_data[0]["amount"] puts "JPYの予算不足為プログラムを回せません。" exit else puts "JPY予算大丈夫なのでプログラムを回します。" end def bitflyer_order(order_price, order_btc_value) #bitflyerの売買API key = @bitflyer_key secret = @bitflyer_secret order_price = order_price.to_f.round order_btc_value = 0.01 if order_btc_value <= 0.01 order_btc_value = order_btc_value.to_f.round(2) uri = URI.parse "https://api.bitflyer.jp/v1/me/sendchildorder" method = "POST" path = "/v1/me/sendchildorder" nonce = Time.now.to_i.to_s body = { "product_code" => @stock_or_fx, "child_order_type" => "LIMIT", "side" => "BUY", "price" => order_price, "size" => order_btc_value, "minute_to_expire" => @automatic_canceling, "time_in_force" => "GTC" } message = nonce + method.to_s + path.to_s + body.to_json signature = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new("sha256"), secret, message) headers = { "ACCESS-KEY" => key, "ACCESS-TIMESTAMP" => nonce, "ACCESS-SIGN" => signature, "Content-Type" => "application/json" } https = Net::HTTP.new(uri.host, uri.port) https.use_ssl = true request = Net::HTTP::Post.new(uri.request_uri, initheader = headers) request.body = body.to_json response = https.request(request) # puts response.body @bitflyer_order_json_data = JSON.parse(response.body) puts @bitflyer_order_json_data # order.buy_order_id = bitflyer_json_data["child_order_acceptance_id"] #{"child_order_acceptance_id":"JRF20151214-112159-071645"} end def bitflyer_cancel(child_order_acceptance_id) #bitflyerの売買API key = @bitflyer_key secret = @bitflyer_secret child_order_acceptance_id = child_order_acceptance_id uri = URI.parse "https://api.bitflyer.jp/v1/me/cancelchildorder" method = "POST" path = "/v1/me/cancelchildorder" nonce = Time.now.to_i.to_s body = { "product_code" => @stock_or_fx, "child_order_acceptance_id" => child_order_acceptance_id } message = nonce + method.to_s + path.to_s + body.to_json signature = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new("sha256"), secret, message) headers = { "ACCESS-KEY" => key, "ACCESS-TIMESTAMP" => nonce, "ACCESS-SIGN" => signature, "Content-Type" => "application/json" } https = Net::HTTP.new(uri.host, uri.port) https.use_ssl = true request = Net::HTTP::Post.new(uri.request_uri, initheader = headers) request.body = body.to_json response = https.request(request) end # create table # 最初の一回目にdbを作成処理を行う。 if File.exist?(dbname) puts dbname + "が存在します。" db = SQLite3::Database.new(dbname) else puts dbname + "が存在しないので作成します。" db = SQLite3::Database.new(dbname) sql = <<-SQL create table btc_order ( id integer primary key, child_order_acceptance_id varchar(200), order_jpy_price integer, order_btc_value integer, order_time varchar(200) ); SQL db.execute(sql) end #--------------------------------------------- puts "現在の1BTCのbitflyerのJPY価格 " + bitflyer_ask.to_f.to_s x = bitflyer_ask.to_f * order_kakaku.to_f y = bitflyer_ask.to_f - x.to_f order_kaisu1 = order_kaisu + 1 c = btc_kakaku.to_f / order_kaisu1.to_f / order_kaisu.to_f n = 1 order_kaisu.times do puts "BTCの購入開始" puts "回数".to_s + n.to_s puts "注文値段".to_s + y.to_s cx = c * n * 2 puts "BTC量".to_s + cx.to_f.to_s #btcの注文開始 bitflyer_order(y.to_s, cx.to_f) return_id = @bitflyer_order_json_data["child_order_acceptance_id"] puts "注文番号 " + return_id #dbへの保存開始 now_time = Time.now sql = "insert into btc_order(child_order_acceptance_id, order_jpy_price, order_btc_value, order_time) values (:child_order_acceptance_id, :order_jpy_price, :order_btc_value, :order_time)" db.execute(sql, :child_order_acceptance_id => return_id, :order_jpy_price => y, :order_btc_value => cx.to_f, :order_time => now_time.to_s) #db保存ここまで y = y - x n = n + 1 end puts cancel_wait_time.to_s + "秒後にキャンセルを開始します。" sleep(cancel_wait_time) puts "キャンセルを開始します。" db.results_as_hash = true sql_select = 'select * from btc_order order by rowid DESC limit ' + order_kaisu.to_s db.execute(sql_select) do |row| child_order_acceptance_id = row["child_order_acceptance_id"].to_s bitflyer_cancel(child_order_acceptance_id) puts child_order_acceptance_id + "の注文をキャンセルしました。" end
1)上記のbotプログラムはrubyで書いていますので、rubyで実行して下さい。
2)上記ソースコードをコピーしてテキストエディタにコピーして下さい。ファイル名は"order_buy_btc_bitflyer.rb"などで良いと思います。
3)実行は ターミナルで" ruby order_buy_btc_bitflyer.rb "で動くと思います。
4)上記3を実行させると"miseita.db"が自動的に作成され注文のid、注文量、日時などが保存されます。
"miseita.db"は消しても問題御座いませんがプログラムを動かす都度に作成されます。
bitflyerの管理画面ではキャンセルした処理は表示されないので保存しておいてもいいかもしれません。注文の期限切れの場合はbitflyerの管理画面でも確認する事が可能です。
5)bitflyerの管理画面見ながら行うと注文されて、キャンセルされるのが確認出来ると思います。(ターミナル上でも一応表示していますが、bitflyerの管理画面を見ながらの方が確実かと。)
前提としてbitflyerのapiのapi keyとapi secret keyが必要となりますので、bitflyerの管理画面で発行をお願いします。
テキストエディタで開いて以下を設定して下さい。
```
order_kakaku = 0.05 #(例0.25% => 0.0025 現在の価格が50000jpy/btcの場合 =>
49875jpy/btcでオーダーを行います。)
btc_kakaku = 0.5 #注文するトータルbtc
※分けて注文する時に1回の注文が0.01btc以下になる場合は強制的に0.01btcでオーダーします。
order_kaisu = 3 #分けて注文する回数
cancel_wait_time = 60 #注文してからキャンセルを行う時間(秒)
@automatic_canceling = 5 #自動的にキャンセル処理を行う時間(分)
sell_buy = 1 # 1はbtcの購入 2はbtcの販売 3は両方 ※まだ実装していません。
@bitflyer_key = "aaaaaaaaaaaaaa"
@bitflyer_secret = "bbbbbbbbbbbbbbbb"
@stock_or_fx = "BTC_JPY" #fxを行う場合は"FX_BTC_JPY"に変更
```
1)order_kakakuは指定したパーセントで現在の価格から下の価格を自動的に注文していきます。
2)btc_kakaku は注文する合計のbtc量になります。
3) order_kaisu はorder_kakakuで指定した値段をorder_kaisu数回の下げた価格で自動的に注文を行います。
4) cancel_wait_timeは注文してからキャンセルするまでの秒です。
5)@automatic_cancelingは4と同じです。違いはbitflyerに元からある機能で注文時に期限を設定出来るので何かあった時の予備ですかね。分で設定します。
6) @bitflyer_keyと@bitflyer_secretはapiの値を入力して下さい。
7)@stock_or_fx は現物とfxの設定を行います。FX_BTC_JPYのテストは行っていません。
↑注文にあたり、細かい所はプログラム側で補正している所もあります。
bitflyerのapiでは最低0.01btcからのオーダになりますので、btc_kakakuを0.001にしても強制的に0.01btcに修正したりしています。
小数点も切り上にしていたり、予算がない場合は注文出来ない様にしたりしています。
上記注文設定を行いプログラムを回すと以下のように見せ玉が動きます。
現在の価格から離れるほどbtcの注文量が自動的に増えます。逆に現在の価格に近い所はbtcの注文量は少なくなります。
現在の価格(jpy/btc) ※自動的に取得します。 |
50000 |
|||||||
注文する価格(order_kakaku)※設定必要 |
0.0025 |
|||||||
注文するBTC合計(btc_kakaku)※設定必要 |
80 |
|||||||
注文回数(order_kaisu)※設定必要 |
7 |
|||||||
以下はプログラムで自動計算され自動で注文されます。 | ||||||||
注文回数 |
1回目 |
2回目 |
3回目 |
4回目 |
5回目 |
6回目 |
7回目 |
|
1BTCの注文価格 |
49875 |
49750 |
49625 |
49500 |
49375 |
49250 |
49125 |
|
注文回数 | 1回目 | 2回目 | 3回目 | 4回目 | 5回目 | 6回目 | 7回目 | トータル発注量 |
BTCの注文量 |
2.857142857 |
5.714285714 |
8.571428571 |
11.42857143 |
14.28571429 |
17.14285714 |
20 |
80 |
最初はwebで出来る様にしようかと考えたのですが、取引所の仕様でapiリクエスト制限(IP アドレスごとに 1 分間に約 500 回)がありwebで公開すると色々大変かなーと考え、各個人の動かす事の出来る様にしております。
上記のプログラムを動かす程度であればapiの制限(Private API は 1 分間に約 200 回を上限)に掛からないと考えます。ですが無茶な取引は気をつけて下さいませ。もちろん私は何も保証も出来ませんのでご了承下さい。
プログラムを書いた後に気がついたのですが、bitflyerからruby用のgemが出てるんですね。。。それを使うともっと綺麗に書けるかもしれません。
本プログラムは1回回すと止まります。常に動かしたい場合はloop処理などを書き加えて下さいませ。
ruby環境があれば利用出来ます。
後はJson, sqliteなどのインストールが必要です。
Macであれば標準でrubyがインストールされているので、確認をお願いします。
Windowsはrubyのインストールが必要です。私はwindowsを所有していないので分かりませんが、検索等で"ruby インストール windows"などで検索して頂くと良いかと考えます。
基本的にはノーサポートになりますが不明点あればご連絡下さいませ。連絡が返ってこない、遅れる場合がございますのでご了承下さいませ。
お小遣い頂けるのでしたら本プログラムを動かすまでをメールでサポート出来るかもしれません。
私の環境がmacなりwinの場合はどうしようかな。。。何とかなるかな。。。ここまでメール下さい=>
※特に決まったbtcは考えていません。
予算と内容をお伺い出来ればと考えます。
上記プログラムはbitflyerのbtc購入のみですが、例えば他の取引所で似たようなのを作って欲しい。btc売りの方を作って欲しいなど。
私は本職プログラマではないので、そんなヘッポコプログラマにお願いする事を前提になりますがw
簡単なのであれば1-3btc程度でもいいなーと。少し時間や量が多そうなのであれば10btc〜といった感じでしょうか。(この辺の相場観が分かりませんが。。。)
併せて時々アービトラージのシステムを売って欲しいといった感じのご連絡を頂きますが、アビトラのシステムは販売しておりませんのでご了承下さいませ。
個人でシコシコ動かす分はいいのですが、システム提供となると独自ルールを含めて色々考えないといけないと考えると提供は難しかなーと。時々調整も必要なのでね。
興味ある方はお気軽にご連絡下さいませ=>