LoginSignup
1
0

投資プログラマ日記

Last updated at Posted at 2023-11-22

ソースコードの利用について
自由に利用することは可能ですが、私はいかなる責任も負いません

投資を始めた理由

やろうと思ったきっかけは中学生のとき(正確には忘れた)。とある投資アプリなるもので、移動平均曲線の存在を知った。
image.png
↑たしかこんな感じだった

これを見たときに私はこう考えた↓
20231122140517_d60731cb3d60839540e585e0a3b773af.png
はい、これがすべての始まり。

本格的に学び始めて現実に気がつく

高校生のときは「今はしっかり勉強すべき」と言っておきながら一切やらずゲームをする日々を送っていた(絶対私みたいになるなよ!)。なので、プログラムを本格的に学び始めたのは大学1年の春から。
投資用(FX用)の言語は

  • MQL4
  • MQL5

の二種類があり、取り敢えずMQL4で良いかと思って勉強を始めた。なので私が初めて触ったプログラム言語はMQL4。(かなり特殊)
色々と唸りながらプログラムを作った結果がこちら(面倒な人は見ないでもOK)

初めて作ったプログラム

ver1.10
mql4

//平均線のクロスで決済、ポジション持ちをする。

#property version   "1.10"
#property strict
#property script_show_confirm

int Magicnumber=19;
int pos,ticket;
double lots,sma11_1,sma22_1,sma33_1,sma11_2,sma22_2,sma33_2;
double A, B, C, D;
double ATR=0;
input int sma1=3;
input int sma2=15;
input int sma3=30; 
input double tradingstop=0;
input double losscut=0;
bool H;
datetime EntryTime = 0;


int OnInit(){
     if(OrderSelect(0,SELECT_BY_POS,MODE_TRADES)){
       ticket=OrderTicket();
       lots=OrderLots();
         if(OrderType()==OP_BUY){//買いポジションが存在して決済してなかったとき
           if(OrderClose(ticket,lots,Bid,10,clrOrange)){
             EntryTime =1;
             pos=0;
             Print("未決済チケット番号 ",ticket," は正しく決済されました");
           }
           else{
             Print("未決済チケット番号 ",ticket," は正しく決済されませんでした");
             EntryTime = 1;
             pos=1;
           }
         }
         if(OrderType()==OP_SELL){//売りポジションが存在して決済してなかったとき
           if(OrderClose(ticket,lots,Ask,10,clrOrange)){
             pos=0;
             EntryTime = 1;
             Print("未決済チケット番号 ",ticket," は正しく決済されました");
           }
           else{
             Print("未決済チケット番号 ",ticket," は正しく決済されませんでした");
             pos=2;
             EntryTime = 1;
           }
         }
     }
     else{
       Print("未決済チケットが存在しないので、このまま取引を開始します。");
     }
     
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason){
  
  
  if(pos!=0 && OrderClose(ticket,1,OrderType(),30,clrOrange)){
      Print("正しく決済され、プログラムを停止しました");
  }
  else if  (pos!=0&& 1!=OrderClose(ticket,1,OrderType(),30,clrOrange)){
    Print("機械側が勝手に決済したのでこのまま取引を終了します");
  }
  else if  (pos==0){
    Print("チケットが存在しないのでこのまま取引を停止します");
  }
  else{
    Print("正しく決済できずにプログラムが停止しました。手動で決済して下さい。");
  }   
  
  Print("リカバリーファクタ- = ",TesterStatistics(STAT_PROFIT)/TesterStatistics(STAT_BALANCE_DD));
}


double OnTester()
{
//(リカバリーファクター)-(プロフィットファクター)
return(TesterStatistics(STAT_PROFIT)/TesterStatistics(STAT_BALANCE_DD));
}






     
void OnTick(){


if(Time[0]>EntryTime){
  sma11_1=iMA(_Symbol,0,sma1,0,MODE_SMA,PRICE_OPEN,1);
  sma11_2=iMA(_Symbol,0,sma1,0,MODE_SMA,PRICE_OPEN,2);
  sma22_1=iMA(_Symbol,0,sma2,0,MODE_SMA,PRICE_OPEN,1);
  sma22_2=iMA(_Symbol,0,sma2,0,MODE_SMA,PRICE_OPEN,2);
  sma33_1=iMA(_Symbol,0,sma3,0,MODE_SMA,PRICE_OPEN,1);
  sma33_2=iMA(_Symbol,0,sma3,0,MODE_SMA,PRICE_OPEN,2);
  EntryTime=Time[0];



//買いポジションを持ってるとき且つ決済するとき
  if((pos==1)&&( sma11_2 > sma22_2 )&&( sma11_1 < sma22_1 )){
      if(OrderClose(ticket,1,Bid,20,clrOrange)){
        Print("チケット番号 ",ticket," は正しく決済されました");
        pos=0;
      }
      else{
        Print("なんらかの理由でチケット番号 ",ticket," は正しく決済ができませんでした");
        Print("次の時間帯にもう一度決済を行います");
      }
  }
      



 //売りポジション持ってる且つ決済するとき
  if((pos==2)&&( sma11_2 < sma22_2 )&&( sma11_1 > sma22_1 )){
      if(OrderClose(ticket,1,Ask,20,clrOrange)){
        Print("チケット番号 ",ticket," は正しく決済されました");
        pos=0;
      }
      else{
        Print("なんらかの理由でチケット番号 ",ticket," は正しく決済ができませんでした");
        Print("次の時間帯にもう一度決済を行います");
      }
  }




  //ポジションを持ってない且つ売るとき
  if(( sma11_1 < sma22_1 )&&( sma22_1 < sma33_1 )&&( sma11_2 - sma11_1 >0)&&( sma22_2 - sma22_1 >0)&&( sma33_2 - sma33_1 >0)&&(pos==0)){
   /* for(int i=1; i<21 ; i++){//ユニットの計算
      A=iHigh(_Symbol,PERIOD_D1,i)-iClose(_Symbol,PERIOD_D1,i);
      B=iClose(_Symbol,PERIOD_D1,i)-iLow(_Symbol,PERIOD_D1,i);
      C=iHigh(_Symbol,PERIOD_D1,i)-iLow(_Symbol,PERIOD_D1,i);  
      D=MathMax(C,MathMax(A,B));
      ATR=ATR+D;
    }
    ATR=ATR/20;
    lots=AccountInfoDouble(ACCOUNT_BALANCE)/(ATR*10000000);
    lots=NormalizeDouble(lots,2);*/
    ticket=OrderSend(_Symbol,OP_SELL,1,Bid,20,losscut,tradingstop,NULL,2000,0,clrBlue);
      if(ticket!=-1){
        pos=2;
        Print("チケット番号=",ticket);
      }
      else{
        Print("なんらかの理由でポジションを持つことができませんでした");
      }
  }
  
  
  
  //ポジションを持ってない且つ買うとき
  if(( sma11_1 > sma22_1 )&& ( sma22_1 > sma33_1 )&&( sma11_1 - sma11_2 >0)&&( sma22_1 - sma22_2 >0)&&( sma33_1 - sma33_2 >0)&&(pos==0)){
    for(int i=1; i<21 ; i++){//ユニットの計算
        A=iHigh(_Symbol,PERIOD_D1,i)-iClose(_Symbol,PERIOD_D1,i);
        B=iClose(_Symbol,PERIOD_D1,i)-iLow(_Symbol,PERIOD_D1,i);
        C=iHigh(_Symbol,PERIOD_D1,i)-iLow(_Symbol,PERIOD_D1,i);
        D=MathMax(C,MathMax(A,B));
        ATR=ATR+D;
      }
      ATR=ATR/20;
      lots=AccountInfoDouble(ACCOUNT_BALANCE)/(ATR*10000000);
      lots=NormalizeDouble(lots,2);
      ticket=OrderSend(_Symbol,OP_BUY,1,Ask,20,losscut,tradingstop,NULL,2000,0,clrRed);
      if(ticket!=-1){
        pos=1;
        Print("チケット番号=",ticket);
      }
      else{
        Print("なんらかの理由でポジションを持つことができませんでした");
      }
      
  }
 
 }
}


取り敢えず作ったら、利益が得られるか分からないためバックテストをす。

バックテスト

バックテストの流れは以下の通り
1.定数として定めた値を変化させて、過去のデータでどれぐらい成果が出たか確かめる。
2.前述の操作で成績がよかった定数の組み合わせで1とは別の過去のデータでテストを行い、再現性があるかどうか確かめる。
3.フォワードテスト(現在刻々と変化する実際の相場でテストすること)で成績を残せるか試して、最終的な吟味を行う。

正確に知りたい人へ
ver1.10プログラムの始めのところに

input int sma1=3;
input int sma2=15;
input int sma3=30; 
input double tradingstop=0;
input double losscut=0;

と書いてあったはずだ。バックテストではこのinputの変数を自分達で決めてバックテストする設定がある。
image.png
↑実際のバックテスト設定画面。左のチェックボックスにチェックを入れるとバックテストにその値が適用される。(逆に何も入れてなかったら、「値」欄に入っている値がそのまま利用される)

では、実際にやってみよう
1 USD/JPY 期間が2022/01/01~2023/01/01
横軸がテスターの通し番号(input定数の組み合わせ)
縦軸がPF(利益率みたいなやつ。今は利益だと思ってOK)
青い点一つ一つが結果
TesterGraph.gif

2
先程のグラフを見るといい成績になっているものがあることがわかる。この成績の中では

input int sma1=8;
input int sma2=21;
input int sma3=47; 
input double tradingstop=0;
input double losscut=0;

この組み合わせがいい成績を残している。
実際に個別で見てみると、以下のようになる
USD/JPY 期間が2022/01/01~2023/01/01 定数の組み合わせは前述
TesterGraph.gif
順調に右肩上がりで良い。

この組み合わせのまま、他の時間帯でバックテストしてみよう
USD/JPY 期間が2015/01/01~2016/01/01
TesterGraph.gif

?????????????????????????????????????????????????????????????????????????????
?????????????????????????????????????????????????????????????????????????????

(´ε`;)ウーン…

初めてこれを見たとき、私は絶対にやってはいけない世界に片足を突っ込んでいる。そう感じた。

これから私がやるべきことと

今回紹介したコードはかなり昔(投資勉強中の初期)に書いたコードである。
いまも勉強は続けているが、全く成果が出ていない
一応機械学習にこれから着手してみてどうなるかやってみようと思う。
機械学習でおすすめの本あったら是非教えてほしい。20231122150010_d9c2e8a7f586f93b0588ffea0be6cffa.png

おまけ、ボツソースコード集(ダイジェスト版)

私が作ってきたプログラムは30近くあるが、全てここに載せるわけにも行かないので、いくつか厳選してボツソースコードを紹介する

真EA ver1.50 EMAとSMAの複雑なクロスを描いたときに取引をするようになっているプログラム。 実際はもうちょっと複雑で、決済をするタイミングは移動平均線で山を作った後に安値を更新するときか単純にクロスしたとき。利益が伸び悩んでいたので取れるときにりえきw取っていこうという具合。
mql4
#property strict
int pos,ticket,e,bar1,bar2,A,bar,d,B,AA,BB;
double SMa0,SMa1,EMA_short_open_0,EMA_short_open_1,high1_1,high1_2,high2_1,high2_2,low1_1,low1_2,low2_1,low2_2,EMA_short_open_2,a,lots,X,Y,EMA_long_open_0,EMA_long_open_1,high1_3,low1_3,EMA_short_close_1,EMA_short_close_0,EMA_short_close_2;
double tradingstop_nedan;
input int Ema1;
input int Sma1;
input int Ema2;
input double tradingstop1;
datetime Time1;
datetime EntryTime = 0;





// 1.50 チケットの統一



int OnInit(){
  for(int i=0; i<2 ;i++){
    pos=0;
    pos=0;
    if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)){
         lots=OrderLots();
         if(OrderType()==OP_BUY){//買いポジションが存在して決済してなかったとき
           ticket=OrderTicket();
           if(OrderClose(ticket,lots,Bid,20,clrOrange)){
             EntryTime =1;
             pos=0;
             Print("未決済チケット番号 ",ticket," は正しく決済されました");
           }
           else{
             Print("未決済チケット番号 ",ticket," は正しく決済されませんでした");
             EntryTime = 1;
             pos=1;
           }
         }
         if(OrderType()==OP_SELL){//売りポジションが存在して決済してなかったとき
           ticket=OrderTicket();
           if(OrderClose(ticket,lots,Ask,20,clrOrange)){
             pos=0;
             EntryTime = 1;
             Print("未決済チケット番号 ",ticket," は正しく決済されました");
           }
           else{
             Print("未決済チケット番号 ",ticket," は正しく決済されませんでした");
             pos=1;
             EntryTime = 1;
           }
         }
     }
     else{
       Print("未決済チケットが存在しないので、このまま取引を開始します。");
       pos=0;
       pos=0;
     }
   }   
  return(INIT_SUCCEEDED);
  }





void OnDeinit(const int reason){ 

  if( pos!=0 || pos!=0 ){
  if(pos==1){
    if(OrderSelect(ticket, SELECT_BY_TICKET,MODE_TRADES)){
        if(OrderClose(ticket,1,Bid,30,clrOrange)){
            Print("正しく決済され、プログラムを停止しました");
        }
        else{
            Print("買いチケット番号",ticket,"は正しく決済できずにプログラムが停止しました。手動で決済して下さい。");
        }
    }
    else{
        Print("買いポジションは損切りです");
    }
  if(pos==1){
    if(OrderSelect(ticket, SELECT_BY_TICKET,MODE_TRADES)){
      if(OrderClose(ticket,1,Ask,30,clrOrange)){
           Print("正しく決済され、プログラムを停止しました");
      }
      else{
          Print("売りチケット番号",ticket,"は正しく決済できずにプログラムが停止しました。手動で決済して下さい。");
      }
    }
    else{
       Print("売りポジションは損切りです");
    }
  }
  }
  }


  else if  (pos==0 && pos==0){
    Print("チケットが存在しないのでこのまま取引を停止します");
  }


  else{
    Print("正しく決済できずにプログラムが停止しました。手動で決済して下さい。");
  }     
}


double OnTester(){
return(TesterStatistics(STAT_PROFIT)/TesterStatistics(STAT_BALANCE_DD));
}





void OnTick(){
  
  
  
     //損切りしたかどうか判断してもらう
  if( pos==1 ){//買いポジションの損切り
      if(OrderSelect(ticket,SELECT_BY_TICKET)){
        if(OrderCloseTime()!=0){
          pos=0;
          Print("チケット番号",ticket,"は損切りになりました");
        }
      }
  }
  
  if(pos==2 ){//売りポジションの損切り
      if(OrderSelect(ticket,SELECT_BY_TICKET)){
         if(OrderCloseTime()!=0){
             pos=0;
             Print("チケット番号",ticket,"は損切りになりました");
         }
      }
  }
  
  
//--------------------------------------------------------------------------------------------------------------------------
  if( Bars > d ){

  
  d=Bars;


  if(OrderSelect(ticket, SELECT_BY_TICKET)){
      X=OrderOpenPrice();
  }
  if(OrderSelect(ticket, SELECT_BY_TICKET)){
      Y=OrderOpenPrice();
  }
    
    A=0;
    B=0;
    AA=0;
    BB=0;
    high1_1=0;
    high1_2=0;
    high1_3=0;
    low1_1=20000000;
    low1_2=20000000;
    low1_3=20000000;
    high2_1=0;
    high2_2=0;
    low2_1=20000000;
    low2_2=20000000; 
    bar1=0;
    bar2=0;   
  if(pos==1){
      if(OrderSelect(ticket,SELECT_BY_TICKET)){
          bar1=Bars(0,0,OrderOpenTime(),TimeCurrent());
          if(bar1 >= 4){
              for(int i=0; i<bar1 ;i++){
                  EMA_short_open_0=iMA(_Symbol,0,Ema1,0,MODE_EMA,PRICE_OPEN,i);
                  if( high1_1 != MathMax(high1_1,EMA_short_open_0) ){
                      A=i;
                      high1_1=EMA_short_open_0;
                  }
              }
              if(A>=3){
              int j=0;
              for(int i=0; i<A-2 ;i++){
                  EMA_short_open_0=iMA(_Symbol,0,Ema1,0,MODE_EMA,PRICE_OPEN,i);
                  EMA_short_open_1=iMA(_Symbol,0,Ema1,0,MODE_EMA,PRICE_OPEN,i+1);
                  EMA_short_open_2=iMA(_Symbol,0,Ema1,0,MODE_EMA,PRICE_OPEN,i+2);
                  if(( EMA_short_open_2<EMA_short_open_1 ) && ( EMA_short_open_1>EMA_short_open_0 )){
                      if( high1_2<EMA_short_open_1 || j==0 ){
                          high1_2=EMA_short_open_1;
                          j++;
                          AA=1;
                      }
                  }
              }
              }
              for(int i=0; i<A-1 ;i++){
                  EMA_short_open_0=iMA(_Symbol,0,Ema1,0,MODE_EMA,PRICE_OPEN,i);
                  if( low1_1 != MathMin(low1_1,EMA_short_open_0) ){
                      low1_1=EMA_short_open_0;
                  }
              }
              
      }
               
      }
      
  }
  if(pos==2){
      if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)){
          
          bar2=Bars(0,0,OrderOpenTime(),TimeCurrent());
          if(bar2>=4){
              for(int i=0; i<bar2 ;i++){
                  EMA_short_open_0=iMA(_Symbol,0,Ema1,0,MODE_EMA,PRICE_OPEN,i);
                  if( low2_1 != MathMin(low2_1,EMA_short_open_0)){
                      B=i;
                      low2_1=EMA_short_open_0;
                  }
              }
              if(B>=3){
              int j=0;
              for(int i=0; i<B-2 ;i++){
                  EMA_short_open_0=iMA(_Symbol,0,Ema1,0,MODE_EMA,PRICE_OPEN,i);
                  EMA_short_open_1=iMA(_Symbol,0,Ema1,0,MODE_EMA,PRICE_OPEN,i+1);
                  EMA_short_open_2=iMA(_Symbol,0,Ema1,0,MODE_EMA,PRICE_OPEN,i+2);
                  if(( EMA_short_open_2<EMA_short_open_1 ) && ( EMA_short_open_1>EMA_short_open_0 )){
                      if( high2_2<EMA_short_open_1 || j==0 ){
                          high2_2=EMA_short_open_1;
                          j++;
                      }
                  }
              }
              }
              for(int i=0; i<B-1 ;i++){
                  EMA_short_open_0=iMA(_Symbol,0,Ema1,0,MODE_EMA,PRICE_OPEN,i);
                  if( high2_1 != MathMax(high2_1,EMA_short_open_0) ){
                      high2_1=EMA_short_open_0;
                  }
              }
              if(B>=3){
              int j=0;
              for(int i=0; i<B-2 ;i++){
                  EMA_short_open_0=iMA(_Symbol,0,Ema1,0,MODE_EMA,PRICE_OPEN,i);
                  EMA_short_open_1=iMA(_Symbol,0,Ema1,0,MODE_EMA,PRICE_OPEN,i+1);
                  EMA_short_open_2=iMA(_Symbol,0,Ema1,0,MODE_EMA,PRICE_OPEN,i+2);
                  if(( EMA_short_open_2>EMA_short_open_1 ) && ( EMA_short_open_1<EMA_short_open_0 )){
                      if( low2_2>EMA_short_open_1 || j==0){
                          low2_2=EMA_short_open_1;
                          j++;
                          BB=1;
                      }
                  }
              }
              }
      }
      }
   } 
    
  EMA_short_open_0=iMA(_Symbol,0,Ema1,0,MODE_EMA,PRICE_OPEN,0);
  EMA_short_open_1=iMA(_Symbol,0,Ema1,0,MODE_EMA,PRICE_OPEN,1);
  EMA_short_open_2=iMA(_Symbol,0,Ema1,0,MODE_EMA,PRICE_OPEN,2); 
  SMa0=iMA(_Symbol,0,Sma1,0,MODE_SMA,PRICE_OPEN,0); 
  SMa1=iMA(_Symbol,0,Sma1,0,MODE_SMA,PRICE_OPEN,1);
  EMA_long_open_0=iMA(_Symbol,0,Ema2,0,MODE_EMA,PRICE_OPEN,0);
  EMA_long_open_1=iMA(_Symbol,0,Ema2,0,MODE_EMA,PRICE_OPEN,1);
  EMA_short_close_0=iMA(_Symbol,0,Ema1,0,MODE_EMA,PRICE_CLOSE,0);
  EMA_short_close_1=iMA(_Symbol,0,Ema1,0,MODE_EMA,PRICE_CLOSE,1);
  EMA_short_close_2=iMA(_Symbol,0,Ema1,0,MODE_EMA,PRICE_CLOSE,2);

    
      if( pos==1 && bar1>3  ){
          if((  AA==1  &&  high1_1>high1_2  && low1_1<low1_2)  ||    EMA_long_open_0>EMA_short_open_0 ||  EMA_long_open_1>EMA_short_close_1   ){
              if(OrderClose(ticket,1,Bid,20,clrOrange)){
                  Print("チケット番号 ",ticket," は正しく決済されました1");
                  pos=0;
              }  
              else{
                  Print("なんらかの理由でチケット番号 ",ticket," は正しく決済ができませんでした");
                  Print("次の時間帯にもう一度決済を行います");
              }
         } 
      }
  
  
  if( pos==2  &&  bar2>3  ){
      if((  BB==1  &&  low2_1<low2_2  &&  high2_1>high2_2 )  ||   EMA_long_open_0<EMA_short_open_0   ||  EMA_long_open_1<EMA_short_close_1  ){
          if(OrderClose(ticket,1,Ask,20,clrOrange)){
              Print("チケット番号 ",ticket," は正しく決済されました321");
              pos=0;
          }  
          else{
              Print("なんらかの理由でチケット番号 ",ticket," は正しく決済ができませんでした");
              Print("次の時間帯にもう一度決済を行います");
          }
      }
  }
  

  //ポジションなし且つ買い
  
  if(pos==0 &&  EMA_short_open_1<EMA_short_open_0  &&  EMA_short_open_2<EMA_short_open_1  &&  (EMA_short_open_0-SMa0)>(EMA_short_open_1-SMa1)  ){
     if(    EMA_short_close_2<EMA_short_close_1    ){ //
         ticket=OrderSend(_Symbol,OP_BUY,1,Ask,20,0,0,NULL,2000,0,clrRed);
         if(ticket != -1){
             pos=1;
             Print("買いチケット番号=",ticket);
         }
         else{
             Print("なんらかの理由で買いポジションを持つことができませんでした");
         }
     }
  }
  
  
  
  //ポジションなし且つ売り
  if(pos==0 &&  EMA_short_open_0<EMA_short_open_1  &&  EMA_short_open_1<EMA_short_open_2  &&  (EMA_short_open_0-SMa0)<(EMA_short_open_1-SMa1) ) {
      if(   EMA_short_close_1<EMA_short_close_2 ){ 
          ticket =OrderSend(_Symbol,OP_SELL,1,Bid,20,0,0,NULL,2000,0,clrBlue);
          if(ticket != -1){
              pos=2;
              Print("売りチケット番号=",ticket);
          }
          else{
              Print("なんらかの理由で売りポジションを持つことができませんでした");
          }
      }
   }  
  
 
 
   //買いポジションをもっているかつ決済
  
  
  
  if(pos==1  &&  bar1>3 ){
          if( (high1_1-tradingstop1*_Point > Bid) ){  
          if(OrderClose(ticket,1,Bid,20,clrOrange)){
              Print("チケット番号 ",ticket," は正しく決済されました");
              pos=0;
          }  
          else{
              Print("なんらかの理由でチケット番号 ",ticket," は正しく決済ができませんでした");
              Print("次の時間帯にもう一度決済を行います");
          }
      }
  }
  
  
  
  
  
  
  //売りポジションをもっている且つ決済
  if(pos==2  &&  bar2>3 ){
    if( low2_1+tradingstop1*_Point < Ask ){
        if(OrderClose(ticket,1,Ask,20,clrOrange)){
            Print("チケット番号 ",ticket," は正しく決済されました");
            pos=0;
        }  
        else{
            Print("なんらかの理由でチケット番号 ",ticket," は正しく決済ができませんでした");
            Print("次の時間帯にもう一度決済を行います");
        }
    }
  }
 
 }
//-----------------------------------------------------------------------------------------------------------------------------------
  
  
  
  //買いポジションをもっているかつ決済
  
  
  
  if(pos==1  &&  bar1>3 ){
        if( high1_3-tradingstop1*_Point > Bid  ||( X-tradingstop1*_Point > Bid)){  
          if(OrderClose(ticket,1,Bid,20,clrOrange)){
              Print("チケット番号 ",ticket," は正しく決済されました");
              pos=0;
          }  
          else{
              Print("なんらかの理由でチケット番号 ",ticket," は正しく決済ができませんでした");
              Print("次の時間帯にもう一度決済を行います");
          }
      }
  }
  
  
  
  
  
  
  //売りポジションをもっている且つ決済
  if(pos==2  &&  bar2>3 ){
    if( (low1_3+tradingstop1*_Point < Ask) || ( Y+tradingstop1*_Point < Ask )){
        if(OrderClose(ticket,1,Ask,20,clrOrange)){
            Print("チケット番号 ",ticket," は正しく決済されました");
            pos=0;
        }  
        else{
            Print("なんらかの理由でチケット番号 ",ticket," は正しく決済ができませんでした");
            Print("次の時間帯にもう一度決済を行います");
        }
    }
  }
}
確率計算ver1.10 tickのデータは離散的だと仮定したときの期待値を求め、一番期待値が高くなる指値の取引をする。 金融市場のグラフは自己相関があるため、結局没になった。
mql4
#property strict


int pos,EntryTime,ticket,sum,ticket1,ticket2,limitA,limitB;
double lots,ASK_rikaku,ASK_sonngiri,BID_rikaku,BID_sonngiri,ASK_torihiki,BID_torihiki,AAA,AAAA;
double ask,bid,askbid,tickAsk_0,tickAsk_1,tickBid_0,tickBid_1,tickAsk_2,tickBid_2;
int bar=0;
int bar_rousoku=0;
int Bars1=0;
bool AA=false;
bool BB=false;
double A[][2];
double B[][2];
double sum1=0;
double sum2=0;
double sum3=0;
double sum4=0;
double sum5=0;
double sum6=0;
double rieki1=0;
double rieki2=0;
double ask1=0;
double bid1=0;
int D=0;
int sumA,sumB,stopA,stopB;
input bool DDD=false;




int OnInit(){
  for(int i=0; i<2 ;i++){
    pos=0;
    pos=0;
    if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)){
         lots=OrderLots();
         if(OrderType()==OP_BUY){//買いポジションが存在して決済してなかったとき
           ticket=OrderTicket();
           if(OrderClose(ticket,lots,Bid,20,clrOrange)){
             EntryTime =1;
             pos=0;
             Print("未決済チケット番号 ",ticket," は正しく決済されました");
           }
           else{
             Print("未決済チケット番号 ",ticket," は正しく決済されませんでした");
             EntryTime = 1;
             pos=1;
           }
         }
         if(OrderType()==OP_SELL){//売りポジションが存在して決済してなかったとき
           ticket=OrderTicket();
           if(OrderClose(ticket,lots,Ask,20,clrOrange)){
             pos=0;
             EntryTime = 1;
             Print("未決済チケット番号 ",ticket," は正しく決済されました");
           }
           else{
             Print("未決済チケット番号 ",ticket," は正しく決済されませんでした");
             pos=1;
             EntryTime = 1;
           }
         }
     }
     else{
       Print("未決済チケットが存在しないので、このまま取引を開始します。");
       pos=0;
       pos=0;
     }
   }   
  return(INIT_SUCCEEDED);
  }





void OnDeinit(const int reason){ 

  if( pos!=0 || pos!=0 ){
  if(pos==1){
    if(OrderSelect(ticket, SELECT_BY_TICKET,MODE_TRADES)){
        if(OrderClose(ticket,1,Bid,30,clrOrange)){
            Print("正しく決済され、プログラムを停止しました");
        }
        else{
            Print("買いチケット番号",ticket,"は正しく決済できずにプログラムが停止しました。手動で決済して下さい。");
        }
    }
    else{
        Print("買いポジションは損切りです");
    }
  if(pos==1){
    if(OrderSelect(ticket, SELECT_BY_TICKET,MODE_TRADES)){
      if(OrderClose(ticket,1,Ask,30,clrOrange)){
           Print("正しく決済され、プログラムを停止しました");
      }
      else{
          Print("売りチケット番号",ticket,"は正しく決済できずにプログラムが停止しました。手動で決済して下さい。");
      }
    }
    else{
       Print("売りポジションは損切りです");
    }
  }
  }
  }


  else if  (pos==0 && pos==0){
    Print("チケットが存在しないのでこのまま取引を停止します");
  }


  else{
    Print("正しく決済できずにプログラムが停止しました。手動で決済して下さい。");
  }     
}

















void OnTick(){
  //損切りの確認
 bar++;

  if(ticket1!=0){
    if(OrderSelect(ticket1,SELECT_BY_TICKET)){
      if(OrderCloseTime()!=0){
          Print("チケット番号 ",ticket1," は損切りになりました");
          ticket1=0;
      }
    }
    }
  
  
  if(ticket2!=0){
     if(OrderSelect(ticket2,SELECT_BY_TICKET)){
      if(OrderCloseTime()!=0){
          Print("チケット番号 ",ticket2," は損切りになりました");
          ticket2=0;
      }
    }
    }
    
    
  if( Bars!=Bars1)
  {
   bar=0;
     Bars1=Bars;
     ArrayResize(A,1);
     ArrayResize(B,1);
     ArrayInitialize(A,0);
     ArrayInitialize(B,0);
  }
  /*
  
  //バーの更新を確かめる。その時に同時にロウソク足のtick更新数もリセットする。
  if(Bars1!=Bars(_Symbol,PERIOD_H4)){
    
    
    bar=0;
    Bars1=Bars(_Symbol,PERIOD_H4);
    ArrayResize(A,1);
    ArrayResize(B,1);
    ArrayInitialize(A,0);
    ArrayInitialize(B,0);
  }*/
  ask=Ask;
  bid=Bid;
  

  //配列に数字を度数分布みたいに組み込む
  if(bar>1){
    for( int i=0; (ArraySize(A)/2)>i ;i++ ){
    
    if(A[i][0]==ask){
      A[i][1]=A[i][1]+1;
      AA=true;
      break;
    }  
    }
    if(AA==false)
    {
      ArrayResize(A,(ArraySize(A)/2)+1);
      A[(ArraySize(A)/2)-1][0]=ask;
      A[(ArraySize(A)/2)-1][1]=1;
    }
    
    
    
    for(int p=0; (ArraySize(B)/2)>p ;p++ ){
      if(B[p][0]==bid)
      {
        B[p][1]=B[p][1]+1;
        BB=true;
        break;
      } 
    }
    
    if(BB==false){
      ArrayResize(B,(ArraySize(B)/2)+1);
      B[(ArraySize(B)/2)-1][0]=bid;
      B[(ArraySize(B)/2)-1][1]=1;
    }
    
    
    AA=false;
    BB=false;
  }
    
    
    
    

  
  
   if(bar<2){
    ArrayResize(A,1);
    A[0][0]=ask;
    A[0][1]=1;
    ArrayResize(B,1);
    B[0][0]=bid;
    B[0][1]=1;
  }
    

  

  //bar(値段更新数)が20000またはそれ以上の10000ごとに諸々の値を計算し直す
  if(  ((bar==1000)  ||  (bar>500 && bar%500==0))  ){
  //配列をソートする
  ArraySort( A,WHOLE_ARRAY,0,MODE_ASCEND);
  ArraySort( B,WHOLE_ARRAY,0,MODE_ASCEND);
  sum1=0;
  sum2=0;
  sum3=0;
  sum4=0;
  rieki1=0;
  rieki2=0;
  sumA=0;
  sumB=0;
  stopA=0;
  stopB=0;
  
  
  
  
  //-----------------------------------------------------------------------------------------------------
  //全事象の数の計算
  
  for(int i=0;i<(ArraySize(A)/2);i++){
    sumA=sumA+A[i][1];
  }
  
  for(int i=0;i<(ArraySize(B)/2);i++){
    sumB=sumB+B[i][1];
  }  
  
  //-----------------------------------------------------------------------------------------------------
  if(DDD){
  
  //中央値の設定
  for(int i=0 ; ArraySize(A)>=i; i++ )
  {
    sum1=sum1+A[i][1];
    if( 2*sum1 >= sumA ){
      ask1=A[i][0];
      stopA=i;
      break;
    }
  }
  
  for(int i=0 ; ArraySize(B)>=i; i++ )
  {
    sum2=sum2+B[i][1];
    if( 2*sum2 >= sumB ){
      bid1=B[i][0];
      stopB=i;
      break;
    }
  }

  //-----------------------------------------------------------------------------------------------------------------
  //中央値を基本として売るときの金額設定
  //買値について
  sum1=0;
  for(int i=0; i<stopA ;i++){
  sum1=sum1+A[i][1];
  sum2=0;
    for(int j=stopA+1;(ArraySize(A)/2)>j;j++){
        sum2=sum2+A[j][1];
        
        if(  (A[j][0]-A[i][0])*(sum1/sumA)*((0.5)-(sum2/sumA))  > rieki1){
        
        ASK_torihiki=A[stopA][0];
        ASK_rikaku=A[j][0];
        ASK_sonngiri=A[i][0];
      
        }       
    }
  }
  sum1=0;
  sum1=0;
  sum1=0;
  //売値について
  for(int i=0; i<stopB ;i++){
  sum1=sum1+B[i][1];
  sum2=0;
    for(int j=stopB+1;(ArraySize(B)/2)>j;j++){
        sum2=sum2+B[j][1];

        if(  (B[j][0]-B[i][0])*(sum1*1000/sumB)*((0.5)-(sum2*1000/sumB))  > rieki2){
        
        BID_torihiki=B[stopB][0];
        BID_rikaku=B[i][0];
        BID_sonngiri=B[j][0];

      
        }       
    }
  }

  }
  //-----------------------------------------------------------------------------------------------------------------
  
  //買値の期待値の計算をしている
  else{
  for(int i=1 ; (ArraySize(A)/2)>i-1 ;i++)
  {
  sum1=0;
    for(int j=0;1>j;j++){
    sum1=sum1+A[j][1];
    sum2=0;
      for(int l=i+1;(ArraySize(A)/2)>l;l++){
        sum2=sum2+A[l][1];
        if(  (A[l][0]-A[j][0])* (sum1)*(0.5*sumA)-(sum2)> rieki1*sumA){
        ASK_torihiki=A[i][0];
        ASK_rikaku=A[l][0];
        ASK_sonngiri=A[j][0];
      
        }
      }
    }
  }
  //-----------------------------------------------------------------------------------------------
  //売値について期待値の計算をしている
  
    for(int i=1 ; (ArraySize(B)/2)>i-1 ;i++)
  {
  sum1=0;
    for(int j=0;1>j;j++){
    sum1=sum1+B[j][1];
    sum2=0;
      for(int l=i+1;(ArraySize(B)/2)>l;l++){
        sum2=sum2+B[l][1];
        if(  (B[l][0]-B[j][0])*(sum1)*((0.5*sumB)-(sum2))  > rieki2*sumB){
        
        BID_torihiki=B[i][0];
        BID_rikaku=B[j][0];
        BID_sonngiri=B[l][0];
      
      
        }
      }
    }
  }
  
  //----------------------------------------------------------------------------------------------------
  }
  // 決まった値段がASK_rikaku BID_rikaku 損切りがASK_sonngiri BID_sonngiri 
  }
  
  //その期待値を上回る指値注文をする
  tickAsk_2=tickAsk_1;
  tickBid_2=tickBid_1;
  tickAsk_1=tickAsk_0;
  tickBid_1=tickBid_0;
  tickAsk_0=Ask;
  tickBid_0=Bid;
  
  
  
  
  if(  (  ASK_torihiki-10*_Point <= Ask  &&  Ask <= ASK_torihiki+10*_Point  ) && ticket1==0 && tickAsk_0>tickAsk_1  &&  tickAsk_1>tickAsk_2){
    ticket1=OrderSend(_Symbol,OP_BUY,1,Ask,25,Ask-(ASK_torihiki-ASK_sonngiri),Ask+(ASK_rikaku-ASK_torihiki),NULL,0,0,clrRed);
    if(ticket1!=-1){ 
        Print("チケット番号 = ",ticket1);
      }
      else{
        Print("買うことに失敗しました1");
        ticket1=0;
      }
  }
 
  
  
  if(( BID_torihiki-10*_Point <= Bid  &&  Bid <= BID_torihiki+10*_Point) && ticket2==0  &&  tickBid_0<tickBid_1  &&  tickBid_1<tickBid_2){
    ticket2=OrderSend(_Symbol,OP_SELL,1,Bid,25,Bid+(BID_sonngiri-BID_torihiki),Bid-(BID_torihiki-BID_rikaku),NULL,0,0,clrBlue);
    if(ticket2!=-1){ 
        Print("チケット番号 = ",ticket2);
      }
      else{
        Print("買うことに失敗しました2");
        ticket2=0;
      }
  }
  
  
}



1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0