🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
CCXT

CCXT(CryptoCurrency eXchange Trading)は、ビットコインやアルトコインといった仮想通貨の売買を自動化するためのJavaScript/Python/PHP向けライブラリ。CCXTが取引所間のAPI差分を吸収することで、異なる取引所に共通した実装が可能です。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

Q&A

解決済

1回答

2172閲覧

CCXT,foreverを用いBTC自動取引プログラムを作りたいが24時間作動してくれない問題

Kota_Sato

総合スコア4

CCXT

CCXT(CryptoCurrency eXchange Trading)は、ビットコインやアルトコインといった仮想通貨の売買を自動化するためのJavaScript/Python/PHP向けライブラリ。CCXTが取引所間のAPI差分を吸収することで、異なる取引所に共通した実装が可能です。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

0グッド

0クリップ

投稿2020/11/30 02:01

前提・実現したいこと

・node.js のccxtライブラリを使いビットコイン自動取引プログラムをforeverを用い24時間稼働させたい
・foreverをvimで実行、以下のエラーメッセージが発生しました。
途中まではうまくいくのですがプログラム稼働から3,4時間経つと必ず停止してしまいます。

発生している問題・エラーメッセージ(コマンドプロンプトからvimを確認)

(node:11164) UnhandledPromiseRejectionWarning: ExchangeNotAvailable: bitflyer GET https://api.bitflyer.com/v1/getticker?product_code=BTC_JPY system request to https://api.bitflyer.com/v1/getticker?product_code=BTC_JPY failed, reason: write ECONNABORTED at C:\Projects\bitcoin\node_modules\ccxt\js\base\Exchange.js:395:35 at processTicksAndRejections (internal/process/task_queues.js:97:5) at async timeout (C:\Projects\bitcoin\node_modules\ccxt\js\base\functions\time.js:195:24) at async bitflyer.fetchTicker (C:\Projects\bitcoin\node_modules\ccxt\js\bitflyer.js:209:24) at async C:\Projects\bitcoin\btc-jpy.js:16:20

コードの意図

私はBTC現物取引をするために30秒ごとに計測し4回連続で上がれば売却、下がれば購入という簡単なプログラムを作りました。取引量は1回あたり0.001BTCとしています。
また売る元手、買う元手がない時はコンソールに取引ができないことを表示するようにしています。

該当のソースコード

JavaScript

1 'use strict'; 2const ccxt = require('ccxt'); 3const key = require('./key'); 4 5const btcPrice = []; 6const numberOfSheets = 0.001; //1回の取引で使うBTC枚数 7 8const sleep = () => { 9 return new Promise((resolve) => { setTimeout(() => { resolve(); }, 30000); }); 10} 11 12(async function () { 13 //bitflyer取引所を利用 14 let bitflyer = new ccxt.bitflyer(key); 15 while (true) { 16 const ticker = await bitflyer.fetchTicker('BTC/JPY'); 17 btcPrice.push(ticker.ask); 18 if (btcPrice.length > 4) { 19 btcPrice.shift(); 20 } 21 console.log(btcPrice); 22 // 上昇を検知 23 if (btcPrice[3] > btcPrice[2] && btcPrice[2] > btcPrice[1] && btcPrice[1] > btcPrice[0]) { 24 try { 25 await bitflyer.createMarketSellOrder('BTC/JPY', numberOfSheets); 26 console.log(`上昇傾向を検知,${numberOfSheets}BTC売りました`); 27 } catch (e) { 28 console.log("上昇傾向を検知しましたがBTCがないため売ることができませんでした"); 29 } 30 } 31 // 下降を検知 32 if (btcPrice[3] < btcPrice[2] && btcPrice[2] < btcPrice[1] && btcPrice[1] < btcPrice[0]) { 33 try { 34 await bitflyer.createMarketBuyOrder('BTC/JPY', numberOfSheets); 35 console.log(`下降傾向を検知,${numberOfSheets}BTC買いました`) 36 } catch (e) { 37 console.log("下降傾向を検知しましたがJPYがないため買うことができませんでした"); 38 } 39 } 40 await sleep(); 41 } 42})();

試したこと

取引間隔を変えてみたりしましたがどうにもなりませんでした。
宜しくお願い致します。

補足情報(FW/ツールのバージョンなど)

node 12.19.0
OS windows
npm 6.14.8

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

以下のticker取得時に何らかの理由でAPIとの接続エラーが発生しているようです。

const ticker = await bitflyer.fetchTicker('BTC/JPY');

原因はサーバー側かプログラムを動作している環境とサーバー間のネットワークの問題か切り分けは難しいですが、取り急ぎの対応としては、リトライ処理を入れるのがよいかと思います。

リトライ処理の方法はいくつか考えられますが、上記のticker取得の処理をtry catchで括り、catch句の中で適当な秒数sleepした後whileをcontinueすればいいかと思います。

投稿2020/11/30 16:42

DaikiOjima

総合スコア271

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Kota_Sato

2020/12/01 08:47 編集

ご回答ありがとうございます。 問題の箇所( while (true) {から if (btcPrice.length > 4) { の行の間) はこのように修正してみました。 try { const ticker = await bitflyer.fetchTicker('BTC/JPY'); btcPrice.push(ticker.ask); } catch (e) { //10時間ほど経つとfetchTicker関数は接続エラーを起こすためエラーハンドリング let date = new Date().toLocaleString({ timeZone: 'Asia/Tokyo' }); console.log("await bitflyer.fetchTicker('BTC/JPY');でエラー発生", e); console.log(`エラー発生時刻: ${date}`); await sleep(); continue; } しかしこのコードでは解決しませんでした。 「whileをcontinueしforeverの停止を回避」のやり方が違うのでしょうか? 今回のようにAPIを利用しその過程でリトライ処理をするときには基本的に必要なものなのでしょうか? 教えていただけると大変ありがたいです。 Github https://github.com/07130918/Bitcoin-Automatic-trading-Bitflyer-/blob/master/btc-jpy.js
DaikiOjima

2020/12/02 18:10

GitHubのコードを確認しましたが、エラーハンドリング自体は問題ないように見受けられました。 > 今回のようにAPIを利用しその過程でリトライ処理をするときには基本的に必要なものなのでしょうか? 外部のサーバーやネットワーク起因で止まってしまうことが考えられるため、エラー処理/リトライ処理はなるべく行ったほうが安全かと思います。また、今回のケースではforeverを使ってプロセスの永続化を行っており、最悪プロせずごと再起動されるという状況ではあると思いますが、停止直前のログを取りやすくなり停止&再起動の原因がトレースしやすくなるメリットも有るため、アプリケーションコード側で明示的にエラーハンドリングを行うのがよいと思います。 > しかしこのコードでは解決しませんでした。 この際、foreverのログにはどのようなエラーが記録されていますでしょうか?
Kota_Sato

2020/12/05 07:16

返信が遅くなってしまい申し訳ありません。 githubのコードで現在も動かしていますが現状、エラーをはいても何とか動いてくれています。 foreverをvimコマンドで覗いてみると以下のようなエラーが記録されています。 2件貼っておきます。 await bitflyer.fetchTicker('BTC/JPY');でエラー発生 ExchangeNotAvailable: bitflyer GET https://api.bitflyer.com/v1/getticker?product_code=BTC_JPY system request to https://api.bitflyer.com/v1/getticker?product_code=BTC_JPY failed, reason: getaddrinfo ENOTFOUND api.bitflyer.com at C:\Projects\bitcoin\node_modules\ccxt\js\base\Exchange.js:395:35 at runMicrotasks (<anonymous>) at processTicksAndRejections (internal/process/task_queues.js:97:5) at async timeout (C:\Projects\bitcoin\node_modules\ccxt\js\base\functions\time.js:195:24) at async bitflyer.fetchTicker (C:\Projects\bitcoin\node_modules\ccxt\js\bitflyer.js:209:24) at async C:\Projects\bitcoin\btc-jpy.js:18:22 { constructor: [class ExchangeNotAvailable extends NetworkError] } エラー発生時刻: 2020-12-5 9:52:18 await bitflyer.fetchTicker('BTC/JPY');でエラー発生 ExchangeNotAvailable: bitflyer GET https://api.bitflyer.com/v1/getticker?product_code=BTC_JPY system request to https://api.bitflyer.com/v1/getticker?product_code=BTC_JPY failed, reason: write ECONNRESET at C:\Projects\bitcoin\node_modules\ccxt\js\base\Exchange.js:395:35 at runMicrotasks (<anonymous>) at processTicksAndRejections (internal/process/task_queues.js:97:5) at async timeout (C:\Projects\bitcoin\node_modules\ccxt\js\base\functions\time.js:195:24) at async bitflyer.fetchTicker (C:\Projects\bitcoin\node_modules\ccxt\js\bitflyer.js:209:24) at async C:\Projects\bitcoin\btc-jpy.js:18:22 { constructor: [class ExchangeNotAvailable extends NetworkError] } エラー発生時刻: 2020-12-5 5:16:41 >エラーハンドリング自体は問題ないように見受けられました。 回答者様のおかげでエラーをはいても現在は自分で動いてくれています。 しかしものすごく不思議なのがエラーからの立ち直りが尋常じゃなく遅いことです。 記録されているように2020-12-5 5:16:41にエラーをはいたとき次のエラー(時刻:2020-12-5 9:52:18 )をはくまで一回も取引を行っていませんでした。 さすがにこの問題の原因を調べることは難しいと思いますが。一応お伝えさせていただきます。 ↓上記2つのエラーの際の取引が全く行われていなかった時間です。 https://gyazo.com/8852cb8b827bc48c5a86d0f75015a653
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問