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は、
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を見つつ丁寧に分解しなければなりません。(ここら辺が自分でやろうとすると大変なんですよね。)
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として実行しても表示されないと思います。
コード全体
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を使ったアービトラージが定番ですが、昨今は
-
-
仮想通貨/ビットコイン長期EA(MT4) 勝てるEA[無料]
バックテスト結果 USDJPY 2019/1/1~2019/12/31 スプレッド:2 D
-
-
BitPoint(ビットポイント)で仮想通貨の自動売買を始める方法
注:現在、bitpointはMT4の採用を取りやめたので、国内業者かつMT4で仮想通貨を扱える業者は



コメント
掲載ありがとうございました。
私の稚拙なコードもこうやって見るとかっちょいいです。
今Krakenのサイトにアクセスしたら私も1回はねられました。KrakenはAPIも弱いので、全体的にサーバが脆弱なのかもしれません。私は鞘取りの方はミスが多いので外しています。