Skip to content

Instantly share code, notes, and snippets.

@tng527
Created December 25, 2017 13:42
Show Gist options
  • Save tng527/279af0087e401c757ec41586ff825530 to your computer and use it in GitHub Desktop.
Save tng527/279af0087e401c757ec41586ff825530 to your computer and use it in GitHub Desktop.
package main
import (
"encoding/json"
"fmt"
"strings"
"time"
coincheckgo "github.com/Akagi201/coincheckgo"
)
const TICKER_HISTORY_NUM = 10
const BUY_RATE_THRESHOLD = 0.0002
const SELL_RATE_THRESHOLD = 0.0002
type TickerResult struct {
Last float64 `json:"last"`
Bid float64 `json:"bid"`
Ask float64 `json:"ask"`
High float64 `json:"high"`
Low float64 `json:"low"`
Volume float64 `json:"volume"`
Timestamp int `json:"timestamp"`
}
func main() {
client := new(coincheckgo.CoinCheck).NewClient("YourAccessKey", "YourSecretKey")
// 取引判断のときにも毎回取得するが、初期値として一定回数分のtickerを取得しておく
var tick_history []TickerResult
for i := 0; i < TICKER_HISTORY_NUM; i++ {
tick_history = append(tick_history, getTicker(client))
time.Sleep(1000 * time.Millisecond)
}
for true {
// 新しいTickを入れて、古いTickを消す(メモリ配慮)
tick_history = append(tick_history, getTicker(client))
tick_history = tick_history[1:]
// 取引を行うべきか、行うならどの取引をどの値で行うかを判断
gen_tx_flag, order_type, rate := judgement(tick_history)
if gen_tx_flag {
// 取引
success, id := order(client, order_type, fmt.Sprint(rate), "0.005")
if !success {
panic("order 失敗")
}
fmt.Printf("order_id: %v\n", id)
}
time.Sleep(1000 * time.Millisecond)
}
}
// 売りor買い注文を入れて、API結果と注文idを返却する
func order(client coincheckgo.CoinCheck, order_type, rate, amount string) (bool, int64) {
resp := client.Order.Create(`{"rate":"` + rate + `","amount":"` + amount + `", "order_type":"` + order_type + `", "pair":"btc_jpy"}`)
var result interface{}
decoder := json.NewDecoder(strings.NewReader(resp))
if err := decoder.Decode(&result); err != nil {
panic(err)
}
success := result.(map[string]interface{})["success"].(bool)
id := result.(map[string]interface{})["id"].(float64)
return success, int64(id)
}
// 売るか買うか何もしないかを判断する
// 暫定で損切り(塩漬け)は考えない
func judgement(tick_history []TickerResult) (bool, string, int64) {
bid_up_cnt := 0
bid_down_cnt := 0
ask_up_cnt := 0
ask_down_cnt := 0
if len(tick_history) < TICKER_HISTORY_NUM {
panic("tick_history不足")
}
for i := 0; i < len(tick_history)-1; i++ {
// 売り安値を比較して買うか判断
bid_diff := tick_history[i+1].Bid - tick_history[i].Bid
if bid_diff > 0 {
bid_up_cnt++
} else {
bid_down_cnt++
}
// 買い高値を比較して売るか判断
ask_diff := tick_history[i+1].Ask - tick_history[i].Ask
if ask_diff > 0 {
ask_up_cnt++
} else {
ask_down_cnt++
}
}
// 直近10秒間で、売値が下がり基調かつ値幅の動きが2%以上あれば買う
last_bid := tick_history[len(tick_history)-1].Bid
first_bid := tick_history[0].Bid
bid_diff_rate := float64(first_bid-last_bid) / float64(first_bid) // 値幅の動き
if bid_down_cnt > TICKER_HISTORY_NUM-2-1 && bid_diff_rate > SELL_RATE_THRESHOLD {
return true, "buy", int64(last_bid - 100)
}
// 直近10秒間で、買値が上がり基調かつ値幅の動きが2%以上あれば売る
last_ask := tick_history[len(tick_history)-1].Ask
first_ask := tick_history[0].Ask
ask_diff_rate := float64(last_ask-first_ask) / float64(first_ask) // 値幅の動き
if ask_up_cnt > TICKER_HISTORY_NUM-2-1 && ask_diff_rate > BUY_RATE_THRESHOLD {
// rateは上がり基調なので現在の値より高い価格で売る
return true, "sell", int64(last_ask + 100)
}
// 何も無いときは何もしない。0を返すのは怖いので中立的な値としてlast_bidを返す
return false, "", int64(last_bid)
}
func getTicker(client coincheckgo.CoinCheck) TickerResult {
resp := client.Ticker.All()
var tick_result TickerResult
json_err := json.Unmarshal([]byte(resp), &tick_result)
if json_err != nil {
panic(json_err)
}
return tick_result
}
@k1asa
Copy link

k1asa commented Jan 10, 2018

API keyを入れて動かしてみましたが、下記のようなエラーとなります。
なにか原因はわかりますでしょうか。

panic: interface conversion: interface {} is nil, not float64

goroutine 1 [running]:
main.order(0x21d78a, 0x10, 0x222931, 0x20, 0x10b6c0c0, 0x10b6c0c0, 0x10b6c0c0, 0x10b6c0c0, 0x10b6c0c0, 0x10b6c0c0, ...)
        /home/pi/coincheck_auto.go:63 +0x270
main.main()
        /home/pi/coincheck_auto.go:44 +0x2b0
exit status 2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment