MT4のチャート上に複数の仮想通貨取引所のビットコインレートを表示するやり方
公開日:
:
MT4/MT5の仮想通貨自動売買 MT4, ビットコイン, API
先日、ブログを読んでいただいてる方からコードをいただいたので、ご紹介します。(OKをもらいました。)
仮想通貨FXトレードができるおすすめ海外FX会社一覧(MT4)
中身はタイトルの通りなのですが、仮想通貨取引所のAPIにおけるレート取得のメソッドはpublicメソッドであるため、認証不要でレートを取得することができます。
簡単に言うと、取引所の特定のURLにアクセスすれば現在のビットコインレートが取得できるということです。MQLにはWebRequest関数があり、MT4/MT5でURLを許可していればWEBアクセスをすることができます。
bitFlyer,CoinChech,ZAIF,kraken,quoine,btcboxのレートを引っ張ります。
それぞれのURLは、
1 2 3 4 5 6 7 |
string url[6]={"https://api.bitflyer.jp/v1/ticker", "https://coincheck.com/api/ticker/", "https://api.kraken.com/0/public/Ticker?pair=XXBTZJPY", "https://www.btcbox.co.jp/api/v1/ticker/", "https://api.quoine.com/products", "https://api.zaif.jp/api/1/depth/btc_jpy" }; |
こんな感じです。
レートの取得はそれぞれの取引所によって仕様が異なるので、jsonを見つつ丁寧に分解しなければなりません。(ここら辺が自分でやろうとすると大変なんですよね。)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
switch(i) { case 0: //bitFlyer ask[i] = StrToDouble(StringSubstr(responce,StringFind(responce,"best_ask",0)+10,7)); bid[i] = StrToDouble(StringSubstr(responce,StringFind(responce,"best_bid",0)+10,7)); break; case 1: //coincheck ask[i] = StrToDouble(StringSubstr(responce,StringFind(responce,"ask",0)+5,7)); bid[i] = StrToDouble(StringSubstr(responce,StringFind(responce,"bid",0)+5,7)); break; case 2: //kraken ask[i] = StrToDouble(StringSubstr(responce,40,7)); bid[i] = StrToDouble(StringSubstr(responce,71,7)); break; case 3: //BTCBOX ask[i] = StrToDouble(StringSubstr(responce,StringFind(responce,"sell",0)+6,7)); bid[i] = StrToDouble(StringSubstr(responce,StringFind(responce,"buy",0)+5,7)); break; case 4: //quoine responceQ=StringSubstr(responce,StringFind(responce,"id\":\"5\"",0),500); //Print(responceQ); ask[i] = StrToDouble(StringSubstr(responceQ,StringFind(responceQ,"market_ask",0)+12,7)); bid[i] = StrToDouble(StringSubstr(responceQ,StringFind(responceQ,"market_bid",0)+12,7)); break; case 5: //Zaif //Print(responce); ask[i] = StrToDouble(StringSubstr(responce,StringFind(responce,"asks",0)+9,7)); bid[i] = StrToDouble(StringSubstr(responce,StringFind(responce,"bids",0)+9,7)); break; default: ask[i]=0; bid[i]=0; } |
(これはコードの一部なので、全体像は後で見えてくると思います。)
このコードはスクリプトなので、コンパイルした後はscriptフォルダに保存してください。ExpertAdviserやIndicatorとして実行しても表示されないと思います。
コード全体
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 |
int timeout=10000; //Timeout below 1000 (1 sec.) is not enough for slow Internet connection string bros[6]={"bitFlyer ", "CoinCheck ", "Kraken ", "BTCBOX ", "Quoine ", "Zaif " }; string url[6]={"https://api.bitflyer.jp/v1/ticker", "https://coincheck.com/api/ticker/", "https://api.kraken.com/0/public/Ticker?pair=XXBTZJPY", "https://www.btcbox.co.jp/api/v1/ticker/", "https://api.quoine.com/products", "https://api.zaif.jp/api/1/depth/btc_jpy" }; double bid[6],ask[6]; //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { ArrayInitialize(bid,0); ArrayInitialize(ask,0); ChartSetInteger(0,CHART_FOREGROUND,false); ChartSetInteger(0,CHART_SHOW_BID_LINE,false); ChartSetInteger(0,CHART_SHOW_ASK_LINE,false); ChartSetInteger(0,CHART_SHOW_PERIOD_SEP,true); ChartSetInteger(0,CHART_SHOW_GRID,false); ChartSetInteger(0,CHART_SHOW_VOLUMES,false); ChartSetInteger(0,CHART_COLOR_BACKGROUND,Black); ChartSetInteger(0,CHART_COLOR_FOREGROUND,Aqua); ChartSetInteger(0,CHART_SCALE,0); ChartSetInteger(0,CHART_MODE,CHART_LINE); ChartSetInteger(0,CHART_COLOR_CHART_LINE,clrNONE); ChartSetInteger(0,CHART_SCALEFIX,true); ChartSetDouble(0,CHART_FIXED_MAX,170); ChartSetDouble(0,CHART_FIXED_MIN,0); ChartSetDouble(0,CHART_SHIFT_SIZE,20); ChartSetInteger(0,CHART_SHIFT,true); ObjectCreate(0,"$100",OBJ_HLINE,0,0,100); ObjectSet("$100",OBJPROP_COLOR,Silver); ObjectCreate(0,"$75",OBJ_HLINE,0,0,75); ObjectSet("$75",OBJPROP_COLOR,Silver); ObjectSet("$75",OBJPROP_STYLE,STYLE_DASH); ObjectCreate(0,"$50",OBJ_HLINE,0,0,50); ObjectSet("$50",OBJPROP_COLOR,Silver); ObjectSet("$50",OBJPROP_STYLE,STYLE_DASH); ObjectCreate(0,"$25",OBJ_HLINE,0,0,25); ObjectSet("$25",OBJPROP_COLOR,Silver); ObjectSet("$25",OBJPROP_STYLE,STYLE_DASH); string suffix="",brobuyM,brosellM; int len=StringLen(_Symbol); if(len>6) suffix=StringSubstr(_Symbol,6,len-6); double MaxArb=0; int today=TimeDay(TimeLocal()); int min=TimeMinute(TimeLocal()); int barNum=1; if(GlobalVariableCheck("barNum")) barNum=(int)GlobalVariableGet("barNum")+1; int barAdjust=0; //---------------------------------------Repeat while(!IsStopped()) { string cookie=NULL,headers; char post[],result[]; int res; double tempAsk,tempBid; for(int i=0; i<6; i++) { string copybro=bros[i]; if(StringReplace(copybro," ","")>-1) if(GlobalVariableCheck(copybro)) { ask[i] = 9990000; bid[i] = 9; continue; } ResetLastError(); res=WebRequest("GET",url[i],cookie,NULL,timeout,post,0,result,headers); //--- Checking errors if(res==-1) { ask[i] = 9999999;//Ask*MarketInfo("USDJPY",MODE_BID); bid[i] = 0;//Bid*MarketInfo("USDJPY",MODE_ASK)-3000; //Print("Error in WebRequest. "+url[i]+" Error code =",GetLastError()); continue; } else { //--- Load successfully string responce=CharArrayToString(result,0,-1,CP_UTF8); //Print(bros[i],responce); tempAsk=ask[i]; tempBid=bid[i]; string responceQ;//for Quoine switch(i) { case 0: //bitFlyer ask[i] = StrToDouble(StringSubstr(responce,StringFind(responce,"best_ask",0)+10,7)); bid[i] = StrToDouble(StringSubstr(responce,StringFind(responce,"best_bid",0)+10,7)); break; case 1: //coincheck ask[i] = StrToDouble(StringSubstr(responce,StringFind(responce,"ask",0)+5,7)); bid[i] = StrToDouble(StringSubstr(responce,StringFind(responce,"bid",0)+5,7)); break; case 2: //kraken ask[i] = StrToDouble(StringSubstr(responce,40,7)); bid[i] = StrToDouble(StringSubstr(responce,71,7)); break; case 3: //BTCBOX ask[i] = StrToDouble(StringSubstr(responce,StringFind(responce,"sell",0)+6,7)); bid[i] = StrToDouble(StringSubstr(responce,StringFind(responce,"buy",0)+5,7)); break; case 4: //quoine responceQ=StringSubstr(responce,StringFind(responce,"id\":\"5\"",0),500); //Print(responceQ); ask[i] = StrToDouble(StringSubstr(responceQ,StringFind(responceQ,"market_ask",0)+12,7)); bid[i] = StrToDouble(StringSubstr(responceQ,StringFind(responceQ,"market_bid",0)+12,7)); break; case 5: //Zaif //Print(responce); ask[i] = StrToDouble(StringSubstr(responce,StringFind(responce,"asks",0)+9,7)); bid[i] = StrToDouble(StringSubstr(responce,StringFind(responce,"bids",0)+9,7)); break; default: ask[i]=0; bid[i]=0; } if(ask[i]==0) ask[i]=tempAsk; if(bid[i]==0) bid[i]=tempBid; } } double minAsk=MathMin(ask[0],MathMin(ask[1],MathMin(ask[2],MathMin(ask[3],MathMin(ask[4],ask[5]))))); double maxBid=MathMax(bid[0],MathMax(bid[1],MathMax(bid[2],MathMax(bid[3],MathMax(bid[4],bid[5]))))); //-----Comment string commstr="\n"; string broBid=" ----> 売り側",broAsk=" <---- 買い側"; string brobuy,brosell; for(int i=0; i<6; i++) { commstr=commstr+bros[i]+" ASK= ¥"+DoubleToStr(ask[i],0)+" BID= ¥"+DoubleToStr(bid[i],0); if(ask[i]==minAsk) { commstr=commstr+broAsk; brobuy=bros[i]; } if(bid[i]==maxBid) { commstr=commstr+broBid; brosell=bros[i]; } commstr=commstr+"\n"; } //commstr=commstr+bros[5]+" ASK= "+DoubleToStr(ask[5],2)+" BID= "+DoubleToStr(bid[6],2); //---Reset MaxArb if(MaxArb<maxBid-minAsk) { MaxArb=maxBid-minAsk; brobuyM=brobuy; brosellM=brosell; } if(today!=TimeDay(TimeLocal()) || GlobalVariableCheck("inimax")) { MaxArb=0; brobuyM="?"; brosellM="?"; today=TimeDay(TimeLocal()); } commstr=commstr+"\n \n ARB = ¥"+DoubleToStr(maxBid-minAsk,0) +"\n Today's MaxArb= ¥"+DoubleToStr(MaxArb,0)+" 買い: "+brobuyM+" 売り: "+brosellM; Comment(commstr); //-----Draw chart //---New bar if(min!=TimeMinute(TimeLocal())) { barNum++; GlobalVariableSet("barNum",barNum); min=TimeMinute(TimeLocal()); //---Move in weekend ResetLastError(); if(OrderSend(_Symbol,OP_BUYSTOP,0.1,10000000,0,0,0,NULL,0,TimeCurrent()+601,clrNONE)<0) //Not really order, only for get error 132=ERR_MARKET_CLOSED { int err=GetLastError(); //Print(err); if(err==132) //ERR_MARKET_CLOSED { //Print("ERR_MARKET_CLOSED"); int barsPerChart=WindowBarsPerChart(); int barCount=barsPerChart; if(barCount>barNum) barCount=barNum; else barAdjust=barNum-barsPerChart; for(int i=1; i<=barCount; i++) { if(ObjectFind(0,(string)(i+barAdjust))>=0) { ObjectSetInteger(0,(string)(i+barAdjust),OBJPROP_TIME1,Time[barNum-barAdjust-i]); ObjectSetInteger(0,(string)(i+barAdjust),OBJPROP_TIME2,Time[barNum-barAdjust-i]); } } } } } string barName=(string)barNum; Sleep(10000); RefreshRates(); //to get Time[0] if(ObjectFind(0,barName)<0) { ObjectCreate(0,barName,OBJ_TREND,0,Time[0],0,Time[0],(maxBid-minAsk)/100); ObjectSet(barName,OBJPROP_RAY,false); ObjectSet(barName,OBJPROP_COLOR,Red); ObjectSet(barName,OBJPROP_WIDTH,2); } else ObjectSetDouble(0,barName,OBJPROP_PRICE2,(maxBid-minAsk)/100); } } //+------------------------------------------------------------------+ |
(ところで、KrakenのWEBサイトにアクセスしようとすると頻繁にエラーになるのは私だけ?)
関連記事
-
業者間アービトラージやってみた(開発と配布)[MT4/MT5/API][裁定取引]
アービトラージというのは、業者間のレート差を利用した超高速後出しエントリーロジック、あるいは両建てロ
-
[MT4]仮想通貨(ビットコイン)のシステムトレード検証(ソースコードあり)
MT4/MT5でも仮想通貨の取扱業者が増えてきたので、そろそろ自動売買やらバックテストやらができるよ
-
MT4/MT5/APIでビットコインアービトラージするためのツール無料ダウンロード
ビットコインアービトラージと言えば仮想通貨取引所間のAPIを使ったアービトラージが定番ですが、昨今は
-
仮想通貨MT4注文システム
このサイトでもMT4で仮想通貨トレードを行う方法はいくつか紹介していますが、 bitbank等MT
-
仮想通貨/ビットコイン長期EA(MT4) 勝てるEA[無料]
バックテスト結果 USDJPY 2019/1/1~2019/12/31 スプレッド:2 D
コメント
掲載ありがとうございました。
私の稚拙なコードもこうやって見るとかっちょいいです。
今Krakenのサイトにアクセスしたら私も1回はねられました。KrakenはAPIも弱いので、全体的にサーバが脆弱なのかもしれません。私は鞘取りの方はミスが多いので外しています。