私はプログラミングが得意、というか、他に取り柄のない人間ですので表題のようなツールは必要ないのですが、とはいえ毎回、なにもない状態から作り始めるのはちょっと面倒です。
私には過去に作ってきたプログラム達があるので、そこから使えそうなものをコピー&ペーストして土台を作っていくわけですが、最近はもっと簡単な方法があります。
そう、AIです!
AIで土台を作る
プログラミングをしない方にはあまり馴染みがないかも知れませんが、ここ数年で急速に発展したAIのお陰でプログラミングが非常に楽になりました。
たとえば「移動平均線のクロスで売買するEAをMQL4(※)で作ってくれ」とAI(今回はChatGPT3.5)に頼めば作ってくれます。
※MQL4=MT4でEAを作るためのプログラミング言語
extern int MA_Fast_Period = 10; // 短期移動平均線の期間
extern int MA_Slow_Period = 20; // 長期移動平均線の期間
extern double LotSize = 0.1; // ロットサイズ
int maFastHandle, maSlowHandle; // 移動平均線のハンドル
// 初期化関数
int init()
{
// 短期移動平均線のハンドルを取得
maFastHandle = iMA(NULL, 0, MA_Fast_Period, 0, MODE_SMA, PRICE_CLOSE);
// 長期移動平均線のハンドルを取得
maSlowHandle = iMA(NULL, 0, MA_Slow_Period, 0, MODE_SMA, PRICE_CLOSE);
return (0);
}
// エキスパートアドバイザーのフレーム処理関数
int start()
{
// 現在のポジションを取得
int positionType = PositionsTotal() > 0 ? PositionGetInteger(POSITION_TYPE) : -1;
// 短期移動平均線の値を取得
double maFastValue = iMA(NULL, 0, MA_Fast_Period, 0, MODE_SMA, PRICE_CLOSE, 0);
// 長期移動平均線の値を取得
double maSlowValue = iMA(NULL, 0, MA_Slow_Period, 0, MODE_SMA, PRICE_CLOSE, 0);
// 買いシグナル
if (maFastValue > maSlowValue && positionType != POSITION_TYPE_BUY)
{
// 売りポジションがあればクローズ
if (positionType == POSITION_TYPE_SELL)
OrderClose(Symbol(), POSITION_MAGIC, PositionGetDouble(POSITION_VOLUME), Bid, 5, Red);
// 買いポジションをオープン
OrderSend(Symbol(), OP_BUY, LotSize, Ask, 5, Ask - StopLoss * Point, Ask + TakeProfit * Point, "BuySignal", POSITION_MAGIC, 0, Green);
}
// 売りシグナル
if (maFastValue < maSlowValue && positionType != POSITION_TYPE_SELL)
{
// 買いポジションがあればクローズ
if (positionType == POSITION_TYPE_BUY)
OrderClose(Symbol(), POSITION_MAGIC, PositionGetDouble(POSITION_VOLUME), Bid, 5, Red);
// 売りポジションをオープン
OrderSend(Symbol(), OP_SELL, LotSize, Bid, 5, Bid + StopLoss * Point, Bid - TakeProfit * Point, "SellSignal", POSITION_MAGIC, 0, Red);
}
return (0);
}
// エキスパートアドバイザーのディニシャル処理関数
void deinit()
{
// 移動平均線のハンドルを削除
ObjectDelete(maFastHandle);
ObjectDelete(maSlowHandle);
}
ただし、これをコンパイルするとエラーになります。有料のAIであればもっと精度の高いプログラムを作ってくれるかも知れませんが、ChatGPT3.5や他の(無料)AIでも余程簡単なものでない限り手直しが必要で、プログラミングの知識は必須になります。
逆に言うと、知識があるなら不完全なものでも「土台」があるのと無いのとでは大きな差です。一文字ずつキーボードを打ち込んで全部作っていく時代はもう終わりました。
AIの作るプログラムはとても綺麗で読みやすく、初学者の手本にもなります。
間違ってるけど(笑)
土台を作る他、「こういうことをする場合はどう書くんだっけ‥」といったときにピンポイントで使うことも多いです。私は暗記が苦手ですぐ忘れるのでとても重宝します。(今までは検索に頼っていましたが、検索よりも速いです(間違ってることがあるけど))
いきなり表題から外れましたが、表題の件について調査したのは「AIの作るプログラムの精度がお粗末」であるからでした。
もっと精度の高い「土台」を作れないか?そこから始まったのです。
無料ツール「EA作成機」
EAを作成するツールで有名どころですと、GogoJungleで販売されている株式会社ゴゴジャン謹製「EAつくーる」があります。
しかし、これが非常に高い。今は買い切りで29,800円でしょうか。昔はサブスクリプションだった気がするのですけど‥不評で変えたのか‥?いずれにしても高いことには変わりないです。
この「EAつくーる」ほどの機能は無いのかも知れませんが、無料でもEAを作成してくれるツールが「EA作成機」です。(EAつくーるは触ったことが無いので比較できません)
Webシステムなのでブラウザからアクセスする必要があり、使用するためにはアカウント登録が必要になります。(登録してもお金の請求はされません。不安な方は適当に使い捨てのメールアドレスを作って登録しましょう。)
外部インジケーターも使えますし、トラリピ系のEAやサインツール(インジケーター)も作れます。
無料なのにほとんど妥協していません!(本当に「すごい」と思います。これを作ろうと思ったらどれだけ時間がかかるのやら‥)
とりあえず移動平均のクロスで売買するEAを作ってみます。
//+------------------------------------------------------------------+
//
// Expert Adviser Create by FxLogBook
// EA作成機による自動生成
// IDO
// For MQL4
//
//+------------------------------------------------------------------+
#property copyright "為替じじい"
#property link "https://www.fxlogbook.jp/"
#property link "https://ameblo.jp/fx-kamisama" // 開発者ブログ
//+------------------------------------------------------------------+
// パラメーター設定
//+------------------------------------------------------------------+
input string C0="---- Base Setting ----";
input int MAGIC = 0;
input int Slippage=3;
//取引ロット関連
input int MaxPosition=1;
input double BaseLots=0.01;
input int takeprofit=0;
input int stoploss=0;
//その他項目
double Lots;
input string C1="シグナル|移動平均線クロス(順張り)";
int TimeScale1 = 0;
int Entry1 = 1;//1_直近確定の足、2_二本前、3_三本前
input int MaType1 = 0; //平均線種類
input int MA1_1 = 1; //短期線
input int MA1_2 = 2; //長期線
input int PriceType1 = 0; //価格タイプ
//インジケーター矢印の幅
input int AllowNarrow=10;
//+------------------------------------------------------------------+
// 一般関数
//+------------------------------------------------------------------+
double AdjustPoint(string Currency)//ポイント調整
{
int Symbol_Digits=(int)MarketInfo(Currency,MODE_DIGITS);
double Calculated_Point=0;
if (Symbol_Digits==2 || Symbol_Digits==3)
{
Calculated_Point=0.01;
}
else if (Symbol_Digits==4 || Symbol_Digits==5)
{
Calculated_Point=0.0001;
}
else if (Symbol_Digits==1)
{
Calculated_Point=0.1;
}
else if (Symbol_Digits==0)
{
Calculated_Point=1;
}
return(Calculated_Point);
}
int AdjustSlippage(string Currency,int Slippage_pips )//スリッページ調整
{
int Calculated_Slippage=0;
int Symbol_Digits=(int)MarketInfo(Currency,MODE_DIGITS);
if (Symbol_Digits==2 || Symbol_Digits==3)
{
Calculated_Slippage=Slippage_pips;
}
else if (Symbol_Digits==4 || Symbol_Digits==5)
{
Calculated_Slippage=Slippage_pips*10;
}
return(Calculated_Slippage);
}
int LongPosition()//ロングポジション数を取得
{
int buys=0;
for(int i=0;i<OrdersTotal();i++)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true && OrderSymbol()==Symbol() && OrderMagicNumber()==MAGIC)
{
if(OrderType()==OP_BUY) buys++;
}
}
return(buys);
}
int ShortPosition()//ショートポジション数を取得
{
int sells=0;
for(int i=0;i<OrdersTotal();i++)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true && OrderSymbol()==Symbol() && OrderMagicNumber()==MAGIC)
{
if(OrderType()==OP_SELL) sells++;
}
}
return(sells);
}
//+------------------------------------------------------------------+
// エントリ関連関数
//+------------------------------------------------------------------+
//ポジションエントリ関数
void OpenOrder(int EntryPosition)
{
int res;
bool Modified;
double SL;
double TP;
int SLP=AdjustSlippage(Symbol(),Slippage );
//ロットサイズ調整
Lots=BaseLots;//固定ロット
if( EntryPosition == 1 ) //買いの場合のエントリ条件
{
res=OrderSend(Symbol(),OP_BUY,Lots ,Ask,SLP,0,0,"IDO",MAGIC,0,Red);
if (OrderSelect(res,SELECT_BY_TICKET)==true)
{
if (stoploss!=0) SL=OrderOpenPrice()-stoploss*AdjustPoint(Symbol());
if (takeprofit!=0) TP=OrderOpenPrice()+takeprofit*AdjustPoint(Symbol());
}
if(SL!=0 || TP!=0) Modified=OrderModify(OrderTicket(),OrderOpenPrice(),SL,TP,0,Red);
}
else if(EntryPosition == -1 ) //---- 売りエントリ
{
res=OrderSend(Symbol(),OP_SELL,Lots,Bid,SLP,0,0,"IDO",MAGIC,0,White);
if(OrderSelect(res,SELECT_BY_TICKET)==true)
{
if(stoploss!=0) SL=OrderOpenPrice()+stoploss*AdjustPoint(Symbol());
if(takeprofit!=0) TP=OrderOpenPrice()-takeprofit*AdjustPoint(Symbol());
}
if(SL!=0 || TP!=0) Modified=OrderModify(OrderTicket(),OrderOpenPrice(),SL,TP,0,White);
}
return;
}
//+------------------------------------------------------------------+
// エグジット関連関数
//+------------------------------------------------------------------+
//ポジションクローズ関数
void CloseOrder(int ClosePosition)
{
for(int i=OrdersTotal()-1;i>=0;i--)
{
int res;
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true)
{
if(OrderMagicNumber()==MAGIC && OrderSymbol()==Symbol())
{
if(OrderType()==OP_SELL && (ClosePosition==-1 || ClosePosition==0 )) //売りポジションのクローズ
{
res=OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),10,Silver);
}
else if(OrderType()==OP_BUY && (ClosePosition==1 || ClosePosition==0 ) ) //買いポジションのクローズ
{
res=OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),10,Silver);
}
}
}
}
}
//+------------------------------------------------------------------+
// インジケーター
//+------------------------------------------------------------------+
//1-1 シグナル|シグナル|移動平均線クロス(順張り)
int Indicator1_1(int i,int TimeScale,int LineType,int MaPer1,int MaPer2, int PType)
{
double Ma1=iMA(NULL,TimeScale,MaPer1,0,LineType,PType,i);
double Ma2=iMA(NULL,TimeScale,MaPer2,0,LineType,PType,i);
double Ma1_1=iMA(NULL,TimeScale,MaPer1,0,LineType,PType,i+1);
double Ma2_1=iMA(NULL,TimeScale,MaPer2,0,LineType,PType,i+1);
int ret=0;
if (Ma1>Ma2 && Ma1_1<Ma2_1)
{
ret=1;
}
else if(Ma1<Ma2 && Ma1_1>Ma2_1)
{
ret=-1;
}
return(ret);
}
//+------------------------------------------------------------------+
// イニシャル処理
//+------------------------------------------------------------------+
void init()
{
//テスターで表示されるインジケータを非表示にする
HideTestIndicators(true);
}
//+------------------------------------------------------------------+
// ティック毎の処理
//+------------------------------------------------------------------+
void start()
{
// ニューバーの発生直後以外は取引しない
static datetime bartime=Time[0];
if (Time[0]==bartime) return;
bartime=Time[0];
//各種パラメーター取得
int EntryBuy=0;
int EntrySell=0;
int ExitBuy=0;
int ExitSell=0;
int LongNum=LongPosition();
int ShortNum=ShortPosition();
//クローズ基準取得
int CloseStrtagy1=Indicator1_1(1,TimeScale1,MaType1,MA1_1,MA1_2,PriceType1);
//クローズ判定
if(LongNum!=0 && (CloseStrtagy1==-1 ) )
{
ExitBuy=1;
LongNum=0;
CloseOrder(1);
}
else
if(ShortNum!=0 && ( CloseStrtagy1==1 ))
{
ExitSell=1;
ShortNum=0;
CloseOrder(-1);
}
//エントリ基準取得
int Strtagy1=Indicator1_1(Entry1,TimeScale1,MaType1,MA1_1,MA1_2,PriceType1);
int TotalNum=ShortNum+LongNum;
//エントリ判定
if((TotalNum<MaxPosition && Strtagy1==1 ))
{
EntryBuy=1;
}
else
if((TotalNum<MaxPosition && Strtagy1==-1 ))
{
EntrySell=1;
}
//クローズ処理
if(ExitBuy!=0)
{
CloseOrder(1);
}
if(ExitSell!=0)
{
CloseOrder(-1);
}
//オープン処理
if(EntryBuy!=0)
{
OpenOrder(1);
}
if(EntrySell!=0)
{
OpenOrder(-1);
}
}
長くて読みづらいコードが出来上がりました‥。機械的に生成しているので仕方ない部分ではあるのですが、これからプログラミングを作成していく「土台」としては使いづらい印象です。
しかし、プログラミングの知識が無い人にとっては「作って貼り付けてコンパイルすれば動く」というのは非常にありがたい機能ではないでしょうか。(AIと違って手直しの必要はありません)
特に個人的に気になるのは「トラップ・リピート型」です。私個人はこの手のEAが欲しいと思ったことはありませんが、人気のある手法ですので。
「くるくるワイド」や「ぐるぐるトレイン」風の「両建て+本体」といったEAも作成可能とのこと。
刺さる人には刺さる機能じゃないかと思います
まとめ
今回は別のことを調査しているときにたまたま見つけた無料ツール「EA作成機」をご紹介しました。
個人的には「あまり必要ない」と思いましたが、プログラミングをご存知無い、EAが作りたい方には便利なツールだと思います。おそらく無料でこれだけのことができるものは他にはないでしょう。
なぜこれが無料なのかわからないくらい、しっかり作ってあります。
この手のツール”あるある”で「かゆいところに手が届かない」ことがあるはずです。複雑なことをやりたい、独自のルールを付け加えたい、となると、どうしてもプログラミングの知識は必須です。(どんな多機能ツールでもできないことはあります。)
しかし、この「EA作成機」で作ったプログラムを元にして、ChatGPTなどのAI、そして検索エンジンを駆使すればおそらく「たいていのことはできる」でしょう。
そのうち慣れてきて「プログラミングができる!」という自信もでてくると思います。
実際にはそこからがスタートですけど。
是非これを機にプログラミング沼に足を踏み入れてみてください!(笑)
(実際のところ、MQLはできることが限られているので、そんなに奥が深くありません。ご安心ください。)
コメント