MQL4進階課程

指標的調(diào)用

均線指標

#property copyright "shiyingpan"
#property link      "https://aijy.github.io"
#property version   "1.00"
#property strict

void OnStart()
  {
//---------- 默認幣種4小時周期例隆,前三根K線14日均線值 -----------//
 
   string 幣種=Symbol(); //----幣種Symbol為圖表幣種,也可直接定義如“EURUSD”
   int 時間周期=240;     //----時間周期指圖表周期奕坟,240(分鐘)是4小時圖,使用0,則默認圖表周期
   int 均線周期=14;      //----均線周期,本例指14均線

   double ma_0=iMA(幣種,時間周期,均線周期,0,MODE_EMA,PRICE_CLOSE,0);  //---最后一個參數(shù)表示第幾根k線煞聪,0是從右往左第一根,即最近的一根K線
   double ma_1=iMA(幣種,時間周期,均線周期,0,MODE_EMA,PRICE_CLOSE,1);  //---第二根逝慧,從右往左昔脯。注意第n+1根K線的標號為n啄糙。
   double ma_2=iMA(幣種,時間周期,均線周期,0,MODE_EMA,PRICE_CLOSE,2);  

   PrintFormat("前三根K線均線值為:%.5f,%.5f,%.5f",ma_0,ma_1,ma_2);
   
//---------- 獲取 EURUSD 日線50日周期的前日收盤均線值 -----------//  
   double ma_eurusd=iMA("EURUSD",PERIOD_D1,50,0,MODE_EMA,PRICE_CLOSE,1);  
   PrintFormat("EURUSD的均線值為:%.5f",ma_eurusd); 
  }


MACD指標

#property copyright "shiyingpan"
#property link      "https://aijy.github.io"
#property version   "1.00"
#property strict

void OnStart()
  {
/*
    設置幣種4小時周期,前根K線MACD值,MACD有2個返回值macd的值云稚,與macd的均線值
*/
   string 幣種=Symbol(); //----幣種Symbol為圖表幣種隧饼,也可直接定義如“EURUSD”
   int 時間周期=240;     //----時間周期指圖表周期,240(分鐘)是4小時圖静陈,使用0燕雁,則默認圖表周期
   int 慢周期=26,快周期=12,均滑周期=9;
   
   double macd_main=iMACD(幣種,時間周期,快周期,慢周期,均滑周期,PRICE_CLOSE,MODE_MAIN,1);  //---最后一個參數(shù)表示第幾根k線,0是從右往左第一根鲸拥,即最近的一根K線
   double macd_signal=iMACD(幣種,時間周期,快周期,慢周期,均滑周期,PRICE_CLOSE,MODE_SIGNAL,1);  //---第二根拐格,從右往左。注意第n+1根K線的標號為n刑赶。

   PrintFormat("MACD值為:%.5f,SIGNAL:%.5f",macd_main,macd_signal);
   
//---------- 獲取 EURUSD 日線當前MACD值 -----------//  
   macd_main=iMACD("EURUSD",PERIOD_D1,快周期,慢周期,均滑周期,PRICE_CLOSE,MODE_MAIN,0);  //---最后一個參數(shù)表示第幾根k線捏浊,0是從右往左第一根,即最近的一根K線
   macd_signal=iMACD("EURUSD",PERIOD_D1,快周期,慢周期,均滑周期,PRICE_CLOSE,MODE_SIGNAL,0);  //---第二根撞叨,從右往左金踪。注意第n+1根K線的標號為n。

   PrintFormat("MACD值為:%.5f,SIGNAL:%.5f",macd_main,macd_signal);
  }

布林線

#property copyright "shiyingpan"
#property link      "https://aijy.github.io"
#property version   "1.00"
#property strict

void OnStart()
  {
/*
    設置幣種4小時周期牵敷,前根K線布林線上胡岔、中、下軌值
*/
   string 幣種=Symbol(); //----幣種Symbol為圖表幣種枷餐,也可直接定義如“EURUSD”
   int 時間周期=240;     //----時間周期指圖表周期靶瘸,240(分鐘)是4小時圖,使用0尖淘,則默認圖表周期
   int 布林線周期=20,布林線方差=2;
   
   double bands_upper  =iBands(幣種,時間周期,布林線周期,布林線方差,0,PRICE_CLOSE,MODE_UPPER,1);  //---第二根k線奕锌,布林線上軌值
   double bands_middle =iBands(幣種,時間周期,布林線周期,布林線方差,0,PRICE_CLOSE,MODE_MAIN,1);  //---第二根k線,布林線中軌值
   double bands_lower  =iBands(幣種,時間周期,布林線周期,布林線方差,0,PRICE_CLOSE,MODE_LOWER,1);  //---第二根k線村生,布林線下軌值

   PrintFormat("4小時布林線前K線上軌值:%.5f,中軌值:%.5f,下軌值:%.5f",bands_upper,bands_middle,bands_lower);
   
//---------- 獲取 EURUSD 日線當前布林線值 -----------//  
   bands_upper  =iBands("EURUSD",PERIOD_D1,20,2,0,PRICE_CLOSE,MODE_UPPER,0);  //--- 布林線上軌值
   bands_middle =iBands("EURUSD",PERIOD_D1,20,2,0,PRICE_CLOSE,MODE_MAIN,0);  //--- 布林線中軌值
   bands_lower  =iBands("EURUSD",PERIOD_D1,20,2,0,PRICE_CLOSE,MODE_LOWER,0);  //--- 布林線下軌值

   PrintFormat("當前日線布林線上軌值:%.5f,中軌值:%.5f,下軌值:%.5f",bands_upper,bands_middle,bands_lower);
  }


RSI

#property copyright "shiyingpan"
#property link      "https://aijy.github.io"
#property version   "1.00"
#property strict

void OnStart()
  {
//---------- 設置幣種4小時周期惊暴,前三根K線14日RSI值 -----------//
 
   string 幣種=Symbol(); //----幣種Symbol為圖表幣種,也可直接定義如“EURUSD”
   int 時間周期=240;     //----時間周期指圖表周期趁桃,240(分鐘)是4小時圖辽话,使用0,則默認圖表周期
   int RSI周期=14;      //----均線周期卫病,本例指14均線

   double rsi_0=iRSI(幣種,時間周期,RSI周期,PRICE_CLOSE,0);  //---最后一個參數(shù)表示第幾根k線油啤,0是從右往左第一根,即最近的一根K線
   double rsi_1=iRSI(幣種,時間周期,RSI周期,PRICE_CLOSE,1);  //---第二根蟀苛,從右往左益咬。注意第n+1根K線的標號為n。
   double rsi_2=iRSI(幣種,時間周期,RSI周期,PRICE_CLOSE,2);  

   PrintFormat("前三根K線RSI值為:%.5f,%.5f,%.5f",rsi_0,rsi_1,rsi_2);
   
//---------- 獲取 EURUSD 日線日收盤RSI值 -----------//  
   double rsi_eurusd=iRSI("EURUSD",PERIOD_D1,14,PRICE_CLOSE,1);  
   PrintFormat("EURUSD日線的RSI值為:%.5f",rsi_eurusd); 
  }


KD指標

#property copyright "shiyingpan"
#property link      "https://aijy.github.io"
#property version   "1.00"
#property strict

void OnStart()
  {
/*
    設置幣種4小時周期帜平,前根K線KD值,KD有2個返回值K值幽告,與D值
*/
   string 幣種=Symbol(); //----幣種Symbol為圖表幣種梅鹦,也可直接定義如“EURUSD”
   int 時間周期=240;     //----時間周期指圖表周期,240(分鐘)是4小時圖冗锁,使用0齐唆,則默認圖表周期
   int K周期=5,D周期=3,均滑周期=3;
   
   double kd_main=iStochastic(幣種,時間周期,K周期,D周期,均滑周期,MODE_EMA,0,MODE_MAIN,1);  //---最后一個參數(shù)表示第幾根k線,0是從右往左第一根冻河,即最近的一根K線
   double kd_signal=iStochastic(幣種,時間周期,K周期,D周期,均滑周期,MODE_EMA,0,MODE_SIGNAL,1);  //---第二根箍邮,從右往左。注意第n+1根K線的標號為n叨叙。

   PrintFormat("KD值為:%.5f,SIGNAL:%.5f",kd_main,kd_signal);
   
//---------- 獲取 EURUSD 日線當前KD值 -----------//  
   kd_main=iStochastic("EURUSD",PERIOD_D1,5,3,3,MODE_EMA,0,MODE_MAIN,0);  //---最后一個參數(shù)表示第幾根k線锭弊,0是從右往左第一根,即最近的一根K線
   kd_signal=iStochastic("EURUSD",PERIOD_D1,5,3,3,MODE_EMA,0,MODE_SIGNAL,0);  //---第二根擂错,從右往左廷蓉。注意第n+1根K線的標號為n。

   PrintFormat("KD值為:%.5f,SIGNAL:%.5f",kd_main,kd_signal);
  }

其他系統(tǒng)自帶指標

其他系統(tǒng)自帶指標參照幫助文件中的指標調(diào)用方式調(diào)用马昙,調(diào)用形式都是一樣的。

自定義指標

#property copyright "shiyingpan"
#property link      "https://aijy.github.io"
#property version   "1.00"
#property strict

void OnStart()
  {
//---------- 調(diào)用自定義指標刹悴,指標需在指標文件夾中 -----------//
 
/*----  iCustom用法
 iCustom(貨幣對名稱, 時間周期, 指標名, 指標輸入?yún)?shù)1,指標輸入?yún)?shù)2,第幾個數(shù)據(jù),第幾根K線); 
*/ 
   string 幣種=Symbol(); //----幣種Symbol為圖表幣種行楞,也可直接定義如“EURUSD”
   int 時間周期=240;     //----時間周期指圖表周期,240(分鐘)是4小時圖土匀,使用0子房,則默認圖表周期
   string 指標名="RSI";

   double value_0=iCustom(幣種,時間周期,指標名,14,0,0);  //---最后一個參數(shù)表示第幾根k線,0是從右往左第一根就轧,即最近的一根K線
   double value_1=iCustom(幣種,時間周期,指標名,14,0,1);  //---第二根证杭,從右往左。注意第n+1根K線的標號為n妒御。
   double value_2=iCustom(幣種,時間周期,指標名,14,0,2);  

   PrintFormat("前三根K線RSI值為:%.5f,%.5f,%.5f",value_0,value_1,value_2);
   
//---------- 獲取 EURUSD 日線的zigzag值 -----------// 
    
   double zz_value=0;
   double position=0;
   for(int i=0;i<100;i++)
   {
      zz_value=iCustom("EURUSD", PERIOD_D1, "ZigZag", 12, 5, 3, 0, i); 
      if(zz_value!=0)
      {
         position=i;
         break;
      }   
   }   
   PrintFormat("EURUSD日線上個峰值/底值為:%.5f,第%d根K線",zz_value,position); 
  }

基于KD指標的下單程序

本例有以下幾個要點:

  • 移動止損
  • 一根K線下一次單
  • 如何避免無限重復下單
#property copyright "shiyingpan"
#property link      "https://aijy.github.io"
#property version   "1.00"
#property strict

input double 單量=0.2;
input int 止損=400;
input int 移動止損=100;
input int 啟動移動止損=300;

input int 交易開始時間=2;
input int 交易停止時間=22;

int Magic_num=445678;
datetime trade_time;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
//---

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   if(AccountNumber()==0) //----通過判斷賬戶號解愤,確定是否連接網(wǎng)絡
      return;

   double kd15_main,kd15_main_prv,kd15_sig,kd15_sig_prv;
   int ticket;
   bool long_order_exist=false,short_order_exist=false;

   for(int i=OrdersTotal()-1;i>=0;i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) && OrderSymbol()==Symbol())
        {
         if(OrderType()==OP_BUY && OrderMagicNumber()==Magic_num)
           {
            long_order_exist=true;
            //--首先價格要超過啟動止損位置,然后還要比當前止損大 移動止損以上
            if(Bid>(OrderOpenPrice()+啟動移動止損*Point) && (Bid-OrderStopLoss())>移動止損*Point)
               OrderModify(OrderTicket(),OrderOpenPrice(),Bid-移動止損*Point,0,0,clrNONE);// 設置移動止損         
           }

         if(OrderType()==OP_SELL && OrderMagicNumber()==Magic_num)
           {
            short_order_exist=true;
            if(Ask<(OrderOpenPrice()-啟動移動止損*Point) && (OrderStopLoss()-Ask)>移動止損*Point)
               OrderModify(OrderTicket(),OrderOpenPrice(),Ask+移動止損*Point,0,0,clrNONE);// 設置移動止損         

           }
        }
     }

   //-- TimeHour() 函數(shù)返回 時間參數(shù) 的小時數(shù)
   if(TimeHour(TimeCurrent())>=交易停止時間 || TimeHour(TimeCurrent())<交易開始時間) //---------在流動性差的時間段不交易(點差高)
      return;

   if(trade_time==iTime(Symbol(),PERIOD_M15,0)) //---每隔15分鐘計算一次是否要下單
     {
      return;
     }
   trade_time=iTime(Symbol(),PERIOD_M15,0);

   kd15_main=iStochastic(Symbol(),PERIOD_M15,5,3,3,MODE_EMA,0,MODE_MAIN,1);
   kd15_sig=iStochastic(Symbol(),PERIOD_M15,5,3,3,MODE_EMA,0,MODE_SIGNAL,1);

   kd15_main_prv=iStochastic(Symbol(),PERIOD_M15,5,3,3,MODE_EMA,0,MODE_MAIN,2);
   kd15_sig_prv=iStochastic(Symbol(),PERIOD_M15,5,3,3,MODE_EMA,0,MODE_SIGNAL,2);

   if(long_order_exist==false) //---當前有多單乎莉,就不再下多單
     {
      // 在35以下的金叉買入
      if(kd15_main_prv<kd15_sig_prv && kd15_main>kd15_sig && kd15_main_prv<35 && kd15_sig_prv<35 && kd15_main<35 && kd15_sig<35)
        {
         ticket=OrderSend(Symbol(),OP_BUY,單量,Ask,3,止損*Point,0,"KD_long",Magic_num,0,clrRed);
         if(ticket==0)
           {
            Print("open buy order error:",GetLastError());
           }
        }
     }

   if(short_order_exist==false)  //---當前有空單送讲,就不再下空單
     {
      //--在65以上的死叉賣出
      if(kd15_main_prv>kd15_sig_prv && kd15_main<kd15_sig && kd15_main_prv>65 && kd15_sig_prv>65 && kd15_main>65 && kd15_sig>65)
        {
         ticket=OrderSend(Symbol(),OP_SELL,單量,Bid,3,止損*Point,0,"KD_short",Magic_num,0,clrYellow);
         if(ticket==0)
           {
            Print("open sell order error:",GetLastError());
           }
        }
     }
  }

指標的編寫

KD指標代碼解讀


#property copyright   "2005-2014, MetaQuotes Software Corp."
#property link        "http://www.mql4.com"
#property description "Stochastic Oscillator"
#property strict

#property indicator_separate_window  //-- 顯示在附圖上,若要主圖顯示用 indicator_chart_window 
#property indicator_minimum    0     //-- 指標下限(可選) 
#property indicator_maximum    100   //-- 指標上限(可選) 
#property indicator_buffers    2     //-- 指標數(shù)據(jù)緩存,2表示這個指標有2個數(shù)據(jù)惋啃。非常重要
#property indicator_color1     LightSeaGreen   //-- 第一根指標線的顏色
#property indicator_color2     Red   //-- 第二根指標線的顏色
#property indicator_level1     20.0    //-- 指標數(shù)值參考線
#property indicator_level2     80.0    //-- 指標數(shù)值參考線
#property indicator_levelcolor clrSilver  //-- 指標數(shù)值參考線顏色(統(tǒng)一的顏色)
#property indicator_levelstyle STYLE_DOT  //-- 指標數(shù)值參考線類型(統(tǒng)一的類型)哼鬓,本例點線
//--- input parameters
input int InpKPeriod=5; // K Period     參數(shù)定義與輸入
input int InpDPeriod=3; // D Period
input int InpSlowing=3; // Slowing

//-- 定義需要使用的緩存器,按需定義。只要要定義上面設置的數(shù)據(jù)緩存數(shù)目
double ExtMainBuffer[];       //-- 定義主緩存空間
double ExtSignalBuffer[];     //-- 定義Signal數(shù)值的緩存空間
double ExtHighesBuffer[];     //-- 中間變量空間边灭,供中間計算
double ExtLowesBuffer[];      //-- 中間變量空間异希,供中間計算
//---
int draw_begin1=0;
int draw_begin2=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit(void)
  {
   string short_name;
//--- 2 additional buffers are used for counting.
   IndicatorBuffers(4);                   //-- 聲明4個緩存空間
   SetIndexBuffer(2, ExtHighesBuffer);    //-- 緩存空間與編號要一一對應,ExtHighesBuffer對應2
   SetIndexBuffer(3, ExtLowesBuffer);     //-- ExtLowesBuffer對應3绒瘦,問題:為什么中間變量空間不對應0和1称簿?
                                          //-- 答:編號首先供指標緩存使用扣癣,然后才能給中間變量空間使用
   
//--- indicator lines
   SetIndexStyle(0,DRAW_LINE);            //-- 設置數(shù)據(jù)1是線型  
   SetIndexBuffer(0, ExtMainBuffer);      //-- 指定數(shù)據(jù)1的緩存空間
   SetIndexStyle(1,DRAW_LINE);            //-- 設置數(shù)據(jù)2是線型
   SetIndexBuffer(1, ExtSignalBuffer);    //-- 指定數(shù)據(jù)2的緩存空間
//--- name for DataWindow and indicator subwindow label
   short_name="Sto("+IntegerToString(InpKPeriod)+","+IntegerToString(InpDPeriod)+","+IntegerToString(InpSlowing)+")";
   IndicatorShortName(short_name); //--指標名
   SetIndexLabel(0,short_name); //-- 數(shù)據(jù)1的名稱
   SetIndexLabel(1,"Signal"); //-- 數(shù)據(jù)2的名稱
//---
   draw_begin1=InpKPeriod+InpSlowing;
   draw_begin2=draw_begin1+InpDPeriod;
   SetIndexDrawBegin(0,draw_begin1);   //-- 數(shù)據(jù)1畫線起始位置
   SetIndexDrawBegin(1,draw_begin2);   //-- 數(shù)據(jù)2畫線起始位置
//--- initialization done
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Stochastic oscillator                                            |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   int    i,k,pos;
//--- rates_total是當前可用的K線數(shù)量,如果太小予跌,則不能計算指標
   if(rates_total<=InpKPeriod+InpDPeriod+InpSlowing)
      return(0);
//--- 指標的數(shù)據(jù)存儲是按K線從左到右計算的搏色,不需要反向
   ArraySetAsSeries(ExtMainBuffer,false);
   ArraySetAsSeries(ExtSignalBuffer,false);
   ArraySetAsSeries(ExtHighesBuffer,false);
   ArraySetAsSeries(ExtLowesBuffer,false);
   ArraySetAsSeries(low,false);
   ArraySetAsSeries(high,false);
   ArraySetAsSeries(close,false);
//---
   pos=InpKPeriod-1;
   if(pos+1<prev_calculated) //---prev_calculated表示未參與運算的K線數(shù)
      pos=prev_calculated-2;
   else
     {
      for(i=0; i<pos; i++)      //--  通過for循環(huán)為最初沒有用到的空間賦初值0
        {                       //--  比如highbuffer是記錄前5日的高點的,那么0-4的值是沒有的券册,賦為0
         ExtLowesBuffer[i]=0.0;  
         ExtHighesBuffer[i]=0.0;
        }
     }
//--- calculate HighesBuffer[] and ExtHighesBuffer[]
   for(i=pos; i<rates_total && !IsStopped(); i++) //-- 從未計算的K線開始频轿,一直計算到所有K線
     {
      double dmin=1000000.0;
      double dmax=-1000000.0;
      for(k=i-InpKPeriod+1; k<=i; k++)
        {
         if(dmin>low[k])
            dmin=low[k];        //-- 前InpKPeriod(5)根K線的低點
         if(dmax<high[k])
            dmax=high[k];       //-- 前InpKPeriod(5)根K線的高點
        }
      ExtLowesBuffer[i]=dmin;   //-- ExtLowesBuffer[i],指的是第i根K線前InpKPeriod(5)根K線的低點
      ExtHighesBuffer[i]=dmax;  //-- ExtLowesBuffer[i]烁焙,指的是第i根K線前InpKPeriod(5)根K線的低點
     }
//--- 為未使用到的K值存儲空間賦初值0
   pos=InpKPeriod-1+InpSlowing-1;
   if(pos+1<prev_calculated)
      pos=prev_calculated-2;
   else
     {
      for(i=0; i<pos; i++)
         ExtMainBuffer[i]=0.0;
     }
//--- 計算K值航邢,主循環(huán),
   for(i=pos; i<rates_total && !IsStopped(); i++)
     {
      //-- 自定義指標的的數(shù)據(jù)緩存空間的計算主要在這個位置進行計算
      //-- 以下是K值計算方法骄蝇,每種指標計算方法不同膳殷,理解這種結構和操作形式即可
      double sumlow=0.0;
      double sumhigh=0.0;
      for(k=(i-InpSlowing+1); k<=i; k++)
        {
         sumlow +=(close[k]-ExtLowesBuffer[k]); //-- 計算均滑(3)日的總和值。
         sumhigh+=(ExtHighesBuffer[k]-ExtLowesBuffer[k]);
        }
      if(sumhigh==0.0)
         ExtMainBuffer[i]=100.0;
      else
         ExtMainBuffer[i]=sumlow/sumhigh*100.0;
     }
//--- 計算D值九火,主循環(huán)
   pos=InpDPeriod-1;
   if(pos+1<prev_calculated)
      pos=prev_calculated-2;
   else
     {
      for(i=0; i<pos; i++)
         ExtSignalBuffer[i]=0.0;
     }
   for(i=pos; i<rates_total && !IsStopped(); i++)
     {
      double sum=0.0;
      for(k=0; k<InpDPeriod; k++)
         sum+=ExtMainBuffer[i-k];
      ExtSignalBuffer[i]=sum/InpDPeriod;
     }
//--- 到此計算結束赚窃,只要在計算中給緩存空間賦值即可,圖表會根據(jù)數(shù)值和設定的圖表類型自動畫上去岔激。
   return(rates_total);
  }

三色線指標代碼實現(xiàn)

/*--------------------------------
本例制作一款趨勢類型的變色均線指標勒极,
紅色是跌勢
黃色是震蕩
綠線是上漲
均線周期可選
----------------------------------*/
#property copyright "shiyingpan"
#property link      "https://aijy.github.io"
#property version   "1.00"
#property strict
//---定義指標屬性
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1 Red
#property indicator_color2 Green
#property indicator_color3 Yellow
//---設置輸入?yún)?shù)
input int 短周期=10;
input int 中周期=20;
input int 長周期=30;

//---定義指標緩存空間
double LongBuffer[];
double ShortBuffer[];
double NoTrendBuffer[];

//--- 指標起始點
int draw_begin=0;
int OnInit()
  {
//-- 為指標取個名字  
   string short_name="趨勢指標("+IntegerToString(短周期)+IntegerToString(中周期)+IntegerToString(長周期)+")";
   IndicatorShortName(short_name);
//-- 設置指標緩存空間數(shù)量,設置線型并做連接,在此都設置為線型
   IndicatorBuffers(3);
   SetIndexStyle(0,DRAW_LINE,STYLE_SOLID,2);  
   SetIndexBuffer(0,LongBuffer);
   SetIndexStyle(1,DRAW_LINE,STYLE_SOLID,2);
   SetIndexBuffer(1,ShortBuffer);
   SetIndexStyle(2,DRAW_LINE,STYLE_SOLID,2);
   SetIndexBuffer(2,NoTrendBuffer);
//-- 設置指標起始的地方,小于長周期的K線并沒有值   
   draw_begin=長周期;
   SetIndexDrawBegin(0,draw_begin);
//-- 返回初始化成功虑鼎,若返回 INIT_FAILED則指標不會成功加載
   return(INIT_SUCCEEDED);
  }

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//-- 若K線數(shù)量小于長周期數(shù)目辱匿,則不夠計算
   if(rates_total<=長周期)
      return(0);
//-- 緩存空間順序是從左到右的,最左邊是1      
   ArraySetAsSeries(LongBuffer,false);
   ArraySetAsSeries(ShortBuffer,false);
   ArraySetAsSeries(NoTrendBuffer,false);

         
   double ma_fast,ma_mid,ma_slow;
   double ma_fast_prv,ma_mid_prv,ma_slow_prv;

//-- 為顯示趨勢變化快慢炫彩,為較短的周期賦予較大的權重
   double sum=短周期+中周期+長周期;
   double w1=長周期/sum,w2=中周期/sum,w3=短周期/sum;
    
   for(int i=draw_begin+1; i<=rates_total && !IsStopped(); i++)
   {
      ma_fast = iMA(Symbol(),0,短周期,0,MODE_EMA,PRICE_CLOSE,rates_total-i);
      ma_mid = iMA(Symbol(),0,中周期,0,MODE_EMA,PRICE_CLOSE,rates_total-i);
      ma_slow = iMA(Symbol(),0,長周期,0,MODE_EMA,PRICE_CLOSE,rates_total-i); 
      
      ma_fast_prv = iMA(Symbol(),0,短周期,0,MODE_EMA,PRICE_CLOSE,rates_total-i+1);
      ma_mid_prv = iMA(Symbol(),0,中周期,0,MODE_EMA,PRICE_CLOSE,rates_total-i+1);
      ma_slow_prv = iMA(Symbol(),0,長周期,0,MODE_EMA,PRICE_CLOSE,rates_total-i+1); 
      
      if(ma_fast>ma_mid && ma_mid>ma_slow)  //--- 多頭排列匾七,上漲趨勢
      {
         LongBuffer[i]=(ma_fast+ma_mid+ma_slow)/3;              //--  計算本根和上一根的值,做不同趨勢的連接
         LongBuffer[i-1]=(ma_fast_prv+ma_mid_prv+ma_slow_prv)/3;
         
         //LongBuffer[i]  =ma_fast*w1+ma_mid*w2+ma_slow*w3;              
         //LongBuffer[i-1]=ma_fast_prv*w1+ma_mid_prv*w2+ma_slow_prv*w3;
      }
      else if(ma_fast<ma_mid && ma_mid<ma_slow)  //--- 空頭排列江兢,下跌趨勢
      {
         ShortBuffer[i]=(ma_fast+ma_mid+ma_slow)/3;
         ShortBuffer[i-1]=(ma_fast_prv+ma_mid_prv+ma_slow_prv)/3;
         
         //ShortBuffer[i]  =ma_fast*w1+ma_mid*w2+ma_slow*w3;              
         //ShortBuffer[i-1]=ma_fast_prv*w1+ma_mid_prv*w2+ma_slow_prv*w3;
      }
      else  //-- 除了上漲昨忆、下跌趨勢,就是歸納于震蕩
      {
         NoTrendBuffer[i]=(ma_fast+ma_mid+ma_slow)/3;
         NoTrendBuffer[i-1]=(ma_fast_prv+ma_mid_prv+ma_slow_prv)/3;
         
         //NoTrendBuffer[i]  =ma_fast*w1+ma_mid*w2+ma_slow*w3;              
         //NoTrendBuffer[i-1]=ma_fast_prv*w1+ma_mid_prv*w2+ma_slow_prv*w3;
      }
   }
   return(rates_total);
  }

賬戶的操作

  • 賬號
  • 賬戶名
  • 賬戶資金
  • 賬戶類型

賬戶凈值風險控制

#property copyright "shiyingpan"
#property link      "https://aijy.github.io"
#property version   "1.00"
#property strict

int 授權賬號=123;
double 初始資金=0;

int OnInit()
  {
   while(AccountNumber()==0) //-- 加載前可先使用賬戶號判斷時候可交易杉允,網(wǎng)絡未連接時扔嵌,賬號為0
      Sleep(500);            //-- 程序在此停留0.5秒,啥也不干夺颤,再判斷賬號值
   if(AccountNumber()!=授權賬號)
   {
      Alert("非授權賬號");
      return INIT_FAILED;   //-- 非授權賬號痢缎,不能加載成功
   }
   Print("賬號名:",AccountName());    //-- 獲取賬戶名   
   初始資金=AccountEquity();           //-- 加載EA時獲取當前賬戶凈值
   
   if(!IsDemo())                  //-- 如果是實盤
   {
      Alert("當前賬戶為實盤賬戶!");
   }
   return(INIT_SUCCEEDED);
  }

void OnDeinit(const int reason)
  {

   
  }

void OnTick()
  {
//--------------- 賬戶凈值風險控制 ----------------//
   if(AccountEquity()<初始資金*0.8)
   {
      Alert("當前賬戶凈值虧損20%世澜,已停止交易");
      //-- 添加平倉操作(平倉退出)
      ExpertRemove(); //-- 退出EA
      return;
   }
  }

文件夾操作

文件夾操作可用于提取一定格式數(shù)據(jù)独旷,用于分析。

提取隔夜利息

#property copyright "shiyingpan"
#property link      "https://aijy.github.io"
#property version   "1.00"
#property strict
/* ------------------------------------------------------------------+
本例統(tǒng)計平臺的貨幣對隔夜利息
//+-----------------------------------------------------------------*/
string forex_name[29]={"EURUSD","AUDUSD","GBPUSD","NZDUSD","USDJPY","USDCAD",
                      "USDCHF","EURGBP","EURJPY","EURCHF","EURCAD","EURAUD","EURNZD","AUDCHF","AUDJPY","AUDNZD","AUDCAD","CADCHF",
                      "CADJPY","GBPCAD","CHFJPY","GBPAUD","GBPNZD","GBPJPY","NZDCAD","NZDJPY","NZDCHF","GBPCHF","XAUUSD"};
string forex_data_name[58],file_name="隔夜利息.csv";
string first_line="forex_name",second_line="LONG",third_line="SHORT";
double swaplong[29],swapshort[29];

void OnStart()
  {
//---
   for(int i=0;i<29;i++)
   {
      first_line=first_line+","+forex_name[i];
   }
   
   for(int i=0;i<29;i++)
   {
      swaplong[i]=MarketInfo(forex_name[i],MODE_SWAPLONG);
      swapshort[i]=MarketInfo(forex_name[i],MODE_SWAPSHORT);
      second_line=second_line+","+DoubleToStr(swaplong[i],2); 
      third_line=third_line+","+DoubleToStr(swapshort[i],2);  
   }
   
   
   
   int handle=FileOpen(file_name,FILE_CSV|FILE_WRITE|FILE_ANSI,',');
   if(handle>0)
   {
      FileSeek(handle,0,SEEK_CUR);
      FileWrite(handle,first_line);
      FileWrite(handle,second_line);
      FileWrite(handle,third_line);         
   }
   
   FileClose(handle);
      
  }

提取實時點差

#property copyright "shiyingpan"
#property link      "https://aijy.github.io"
#property version   "1.00"
#property strict
#property indicator_chart_window

string forex_file_name;
int handle;
int spread1;
int k=0;
int flag=0;
string spread_write;
int count=0;
int start_count=0;
int OnInit()
  {
//--- indicator buffers mapping

//---
   return(INIT_SUCCEEDED);
  }
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   if(flag==0 && DayOfWeek()==2)
     {
      forex_file_name=Symbol()+"_SPREAD.csv";
      spread_write=TimeToStr(TimeCurrent());
      start_count=1;
      flag=1;
      handle=FileOpen(forex_file_name,FILE_CSV|FILE_WRITE,';');

     }

   if(start_count==1)
     {
      RefreshRates();
      spread1=MarketInfo(Symbol(),MODE_SPREAD);
      spread_write=spread_write+";"+spread1;
      count++;
      //         Print("count:",count);

      if(count==400)
        {

         if(handle>0)
           {
            FileSeek(handle,0,SEEK_CUR);
            FileWriteString(handle,spread_write+"\r\n");
           }

         k=k+1;
         spread_write=TimeToStr(TimeCurrent());
         count=0;
         if(k%1000==0)
            Print("k:",k);
        }
      if(k==300)
        {
         FileClose(handle);
         start_count=0;
         Alert("data is full,time:",TimeCurrent());
        }
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }

編寫馬丁EA

馬丁策略是一種倉位管理方式,它的基本原理基于金字塔式的加倉方式嵌洼。在訂單被套的時候案疲,不斷同方向間隔加倉,攤薄成本麻养。只要行情回撤褐啡,就可以讓被套的系列訂單解套。
轉(zhuǎn)載于:http://www.reibang.com/p/4ab42f1f761e

馬丁策略優(yōu)點

  1. 馬丁策略的原理簡單鳖昌。只要死扛备畦,資金量足夠大,馬丁在理論上不會爆倉许昨。而市場行情總是在不同時間周期內(nèi)來回切換擺動懂盐,一個回撤就可以解放所有的被套訂單。

  2. 馬丁策略的回撤是可計算的糕档。馬丁的加倉與回撤莉恼,在等間距、加倉倍數(shù)恒定的情況下速那,是可以事先計算出來的俐银。這意味著馬丁策略從數(shù)學意義上講,是可以測算的端仰。

  3. 馬丁在程序化上代碼編寫的難度要小悉患。相對于其它策略,馬丁策略的代碼編寫難度要小榆俺。在外匯EA編寫人才缺乏的現(xiàn)狀下,受到各方開發(fā)者的青睞坞淮。

  4. 好的馬丁策略茴晋,對付震蕩型行情可以通殺完勝。馬丁怕單邊回窘,愛震蕩诺擅。在可測算的震蕩型行情里,馬丁策略可以達到大小通吃的完美結果啡直,這對于自動化交易者來說烁涌,極具魅力。

代碼實現(xiàn)

為方便理解酒觅,本次代碼分為多頭馬丁和空頭馬丁撮执,多頭馬丁只會下買單,而空頭馬丁只會下空單舷丹。
多頭馬妒闱:

#property copyright "aijy.github.io"
#property link      "https://aijy.github.io"
#property version   "1.00"

input bool    UseAdd=true;    // 是否使用加倉策略,true:是
input double  LotExponent=1; // 加倉系數(shù)
input int  slip=3;   // 滑點
input double  Lots=0.05; // 初始單量
input int  LotsDigits=2;  //單量精確到小數(shù)點后2位
input double  TakeProfit=200; // 止盈
input double  PipStep=300; //  加倉間隔,當一根K線的開盤價與上次開倉價之間價格大于這個數(shù)值谋币,才加倍開倉
input int     MaxTrades=10;  //最大訂單數(shù)
input bool    UseEquityStop=true;  //未使用
input double  TotalEquityRisk=20; //loss as a percentage of equity

int MagicNumber=123456;
double PriceTarget,StartEquity,BuyTarget,SellTarget;
double AveragePrice,SellLimit,BuyLimit;
double LastBuyPrice,LastSellPrice,ClosePrice,Spread;
string EAName="BUY";
datetime timeprev=0;
int NumOfTrades=0;
double iLots;
int cnt=0,total;
bool TradeNow=false,LongTrade=false,ShortTrade=false;

bool NewOrdersPlaced=false;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int init()
  {
   Spread=MarketInfo(Symbol(),MODE_SPREAD)*Point;
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int deinit()
  {
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTick()
  {
//---------開倉條件
   bool long_trade=false;
   if(iClose(Symbol(),PERIOD_M1,2)<iClose(Symbol(),PERIOD_M1,1))
      long_trade=true;
//------------------------
//---獲取平均的開倉價格---
//------------------------
   int ticket;
   total=CountTrades();
   AveragePrice=0;
   double Count=0;
   for(cnt=OrdersTotal()-1;cnt>=0;cnt--)
     {
      if(OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
            if(OrderType()==OP_BUY || OrderType()==OP_SELL)
              {
               AveragePrice=AveragePrice+OrderOpenPrice()*OrderLots();
               Count=Count+OrderLots();
              }
     }
   if(total>0)
      AveragePrice=NormalizeDouble(AveragePrice/Count,Digits);

   for(int i=OrdersTotal()-1;i>=0;i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) && OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
        {
         if(OrderType()==OP_BUY)
           {
            PriceTarget=AveragePrice+TakeProfit*Point;
            if(Bid>PriceTarget && PriceTarget>0)
              {
               CloseThisSymbolAll();
              }
           }
        }
     }

   if(timeprev==Time[0])
     {
      return;
     }
   timeprev=Time[0];
   

   double CurrentPairProfit=CalculateProfit();
   if(UseEquityStop)
     { //當資金損失低于風險值仗扬,不再開倉
      if(CurrentPairProfit<0 && MathAbs(CurrentPairProfit)>(TotalEquityRisk/100)*AccountEquityHigh())
        {
           if(TimeCurrent()%120==0)
               Print("stop opening new orders");
           return;
        }
     }
   
   Print("貨幣對"+Symbol()+"的止盈:",PriceTarget);

   total=CountTrades(); //計算本貨幣對訂單總數(shù)(不包括其他貨幣對)
   NumOfTrades=total;

   double LastBuyLots;
   double LastSellLots;
   for(cnt=OrdersTotal()-1;cnt>=0;cnt--)
     {
      //統(tǒng)計所有訂單,從中間查找本EA執(zhí)行的本貨幣對訂單蕾额,判斷之前下的是多單還是空單早芭,供后續(xù)使用
      if(OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
            if(OrderType()==OP_BUY)
              {
               LongTrade=true;
               ShortTrade=false;
               LastBuyLots=OrderLots();
               break;
              }
      if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
         if(OrderType()==OP_SELL)
           {
            LongTrade=false;
            ShortTrade=true;
            LastSellLots=OrderLots();
            break;
           }
     }
   if(total>0 && total<=MaxTrades) //有訂單且訂單總量小于最大值
     {
      LastBuyPrice=FindLastBuyPrice(); //得到上次開倉的買價(多單)
      LastSellPrice=FindLastSellPrice();//得到上次開倉的賣價(空單)
      if(LongTrade && (LastBuyPrice-Ask)>=(PipStep*Point))//判斷是否要增開多倉
        {
         TradeNow=true;
        }
      if(ShortTrade && (Bid-LastSellPrice)>=(PipStep*Point))//判斷是否要增開空倉
        {
         TradeNow=true;
        }
     }
   if(total<1) //無訂單的情況
     {
      ShortTrade=false;
      LongTrade=false;
      TradeNow=true;
      StartEquity=AccountEquity();
     }
   if(TradeNow && total>0) //如果之前判斷要加倉則執(zhí)行if
     {
      LastBuyPrice=FindLastBuyPrice(); //得到上次開倉的買價(多單)
      LastSellPrice=FindLastSellPrice();//得到上次開倉的賣價(空單)
      if(ShortTrade) //如果是空倉
        {
         NumOfTrades=total;
         iLots=fGetLots(OP_SELL);//獲得增加倉位的訂單手數(shù)
         if(UseAdd)//按以上計算出來的加倉手數(shù)下單
           {
            if(iLots>0)
              {//#
               RefreshRates();
               ticket=OpenPendingOrder(OP_SELL,iLots,Bid,slip,Ask,0,0,EAName+"-"+IntegerToString(NumOfTrades),MagicNumber,0,HotPink);
               if(ticket<0){Print("Error: ",GetLastError()); return;}
               LastSellPrice=FindLastSellPrice();
               TradeNow=false;
               NewOrdersPlaced=true;
              }//#
           }
        }
      else if(LongTrade)//如果是多倉
        {
         NumOfTrades=total;

         iLots=fGetLots(OP_BUY);//獲得增加倉位的訂單手數(shù)
         if(UseAdd)//按以上計算出來的加倉手數(shù)下單
           {
            if(iLots>0)
              {//#
               ticket=OpenPendingOrder(OP_BUY,iLots,Ask,slip,Bid,0,0,EAName+"-"+NumOfTrades,MagicNumber,0,Lime);
               if(ticket<0)
                 {Print("Error: ",GetLastError()); return;}
               LastBuyPrice=FindLastBuyPrice();
               TradeNow=false;
               NewOrdersPlaced=true;
              }//#
           }
        }
     }
   if(TradeNow && total<1)//當前無本貨幣對訂單,并且需要交易
     {
      SellLimit=Bid;
      BuyLimit=Ask;
      if(!ShortTrade && !LongTrade)//當前既無多單又無空單
        {
         NumOfTrades=total;
         if(long_trade==true)//多單
           {
            iLots=fGetLots(OP_BUY);
            if(iLots>0)
              {//#      
               ticket=OpenPendingOrder(OP_BUY,iLots,BuyLimit,slip,BuyLimit,0,0,EAName+"-"+NumOfTrades,MagicNumber,0,Lime);
               if(ticket<0)
                 {
                  Print(iLots,"Error: ",GetLastError());
                  return;
                 }
               LastSellPrice=FindLastSellPrice();
               NewOrdersPlaced=true;
              }//#
           }
        }
      TradeNow=false;
     }

//------------------------------------------------------
//---以平均開倉價格诅蝶,計算出止損供所有本貨幣對倉位使用---
//------------------------------------------------------

   if(NewOrdersPlaced)
      for(cnt=OrdersTotal()-1;cnt>=0;cnt--)
        {
         if(OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))
            if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
               if(OrderType()==OP_BUY) // Calculate profit/stop target for long 
                 {
                  PriceTarget=AveragePrice+(TakeProfit*Point);
                  BuyTarget=PriceTarget;
                 }
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
            if(OrderType()==OP_SELL) // Calculate profit/stop target for short
              {
               PriceTarget=AveragePrice-(TakeProfit*Point);
               SellTarget=PriceTarget;
              }
        }
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double fGetLots(int aTradeType)
  {
   double tLots;
   tLots=NormalizeDouble(Lots*MathPow(LotExponent,NumOfTrades),LotsDigits);
   if(AccountFreeMarginCheck(Symbol(),aTradeType,tLots)<=0)
     {
      return(-1);
     }
   if(GetLastError()==134)
     {
      return(-2);
     }
   return(tLots);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int CountTrades()
  {
   int count=0;
   int trade;
   for(trade=OrdersTotal()-1;trade>=0;trade--)
     {
      if(OrderSelect(trade,SELECT_BY_POS,MODE_TRADES))
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
            if(OrderType()==OP_SELL || OrderType()==OP_BUY)
               count++;
     }//for
   return(count);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CloseThisSymbolAll()
  {
   int trade;
   for(trade=OrdersTotal()-1;trade>=0;trade--)
     {
      if(OrderSelect(trade,SELECT_BY_POS,MODE_TRADES))
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
           {
            if(OrderType()==OP_BUY)
               OrderClose(OrderTicket(),OrderLots(),Bid,slip,Blue);
            if(OrderType()==OP_SELL)
               OrderClose(OrderTicket(),OrderLots(),Ask,slip,Red);
           }
      Sleep(1000);
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OpenPendingOrder(int pType,double pLots,double pLevel,int sp,double pr,int sl,int tp,string pComment,int pMagic,datetime pExpiration,color pColor)
  {
   int ticket=0;
   int err=0;
   int c=0;
   int NumberOfTries=100;
   switch(pType)
     {
      case OP_BUYLIMIT:
         for(c=0;c<NumberOfTries;c++)
           {
            ticket=OrderSend(Symbol(),OP_BUYLIMIT,pLots,pLevel,sp,StopLong(pr,sl),TakeLong(pLevel,tp),pComment,pMagic,pExpiration,pColor);
            err=GetLastError();
            if(err==0)
              {
               break;
              }
            else
              {
               if(err==4 || err==137 || err==146 || err==136) //Busy errors
                 {
                  Sleep(1000);
                  continue;
                 }
               else //normal error
                 {
                  break;
                 }
              }
           }
         break;
      case OP_BUYSTOP:
         for(c=0;c<NumberOfTries;c++)
           {
            ticket=OrderSend(Symbol(),OP_BUYSTOP,pLots,pLevel,sp,StopLong(pr,sl),TakeLong(pLevel,tp),pComment,pMagic,pExpiration,pColor);
            err=GetLastError();
            if(err==0)
              {
               break;
              }
            else
              {
               if(err==4 || err==137 || err==146 || err==136) //Busy errors
                 {
                  Sleep(5000);
                  continue;
                 }
               else //normal error
                 {
                  break;
                 }
              }
           }
         break;
      case OP_BUY:
         for(c=0;c<NumberOfTries;c++)
           {
            RefreshRates();
            ticket=OrderSend(Symbol(),OP_BUY,pLots,Ask,sp,StopLong(Bid,sl),TakeLong(Ask,tp),pComment,pMagic,pExpiration,pColor);
            err=GetLastError();
            if(err==0)
              {
               break;
              }
            else
              {
               if(err==4 || err==137 || err==146 || err==136) //Busy errors
                 {
                  Sleep(5000);
                  continue;
                 }
               else //normal error
                 {
                  break;
                 }
              }
           }
         break;
      case OP_SELLLIMIT:
         for(c=0;c<NumberOfTries;c++)
           {
            ticket=OrderSend(Symbol(),OP_SELLLIMIT,pLots,pLevel,sp,StopShort(pr,sl),TakeShort(pLevel,tp),pComment,pMagic,pExpiration,pColor);
            err=GetLastError();
            if(err==0)
              {
               break;
              }
            else
              {
               if(err==4 || err==137 || err==146 || err==136) //Busy errors
                 {
                  Sleep(5000);
                  continue;
                 }
               else //normal error
                 {
                  break;
                 }
              }
           }
         break;
      case OP_SELLSTOP:
         for(c=0;c<NumberOfTries;c++)
           {
            ticket=OrderSend(Symbol(),OP_SELLSTOP,pLots,pLevel,sp,StopShort(pr,sl),TakeShort(pLevel,tp),pComment,pMagic,pExpiration,pColor);
            err=GetLastError();
            if(err==0)
              {
               break;
              }
            else
              {
               if(err==4 || err==137 || err==146 || err==136) //Busy errors
                 {
                  Sleep(5000);
                  continue;
                 }
               else //normal error
                 {
                  break;
                 }
              }
           }
         break;
      case OP_SELL:
         for(c=0;c<NumberOfTries;c++)
           {
            ticket=OrderSend(Symbol(),OP_SELL,pLots,Bid,sp,StopShort(Ask,sl),TakeShort(Bid,tp),pComment,pMagic,pExpiration,pColor);
            err=GetLastError();
            if(err==0)
              {
               break;
              }
            else
              {
               if(err==4 || err==137 || err==146 || err==136) //Busy errors
                 {
                  Sleep(5000);
                  continue;
                 }
               else //normal error
                 {
                  break;
                 }
              }
           }
         break;
     }

   return(ticket);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double StopLong(double price,int stop)
  {
   if(stop==0)
      return(0);
   else
      return(price-(stop*Point));
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double StopShort(double price,int stop)
  {
   if(stop==0)
      return(0);
   else
      return(price+(stop*Point));
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double TakeLong(double price,int take)
  {
   if(take==0)
      return(0);
   else
      return(price+(take*Point));
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double TakeShort(double price,int take)
  {
   if(take==0)
      return(0);
   else
      return(price-(take*Point));
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double CalculateProfit()
  {
   double Profit=0;
   for(cnt=OrdersTotal()-1;cnt>=0;cnt--)
     {
      if(OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
            if(OrderType()==OP_BUY || OrderType()==OP_SELL)
              {
               Profit=Profit+OrderProfit();
              }
     }
   return(Profit);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double AccountEquityHigh()
  {
   static double AccountEquityHighAmt,PrevEquity;
   if(CountTrades()==0) AccountEquityHighAmt=AccountEquity();
   if(AccountEquityHighAmt<PrevEquity) AccountEquityHighAmt=PrevEquity;
   else AccountEquityHighAmt=AccountEquity();
   PrevEquity=AccountEquity();
   return(AccountEquityHighAmt);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double FindLastBuyPrice()
  {
   double oldorderopenprice=0,orderprice=0;
   int cnt_temp,oldticketnumber=0,ticketnumber;
   for(cnt_temp=OrdersTotal()-1;cnt_temp>=0;cnt_temp--)
     {
      if(OrderSelect(cnt_temp,SELECT_BY_POS,MODE_TRADES))
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber && OrderType()==OP_BUY)
           {
            ticketnumber=OrderTicket();
            if(ticketnumber>oldticketnumber)
              {
               orderprice=OrderOpenPrice();
               oldorderopenprice=orderprice;
               oldticketnumber=ticketnumber;
              }
           }
     }
   return(orderprice);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double FindLastSellPrice()
  {
   double oldorderopenprice=0,orderprice=0;
   int cnt_temp,oldticketnumber=0,ticketnumber;
   for(cnt_temp=OrdersTotal()-1;cnt_temp>=0;cnt_temp--)
     {
      if(OrderSelect(cnt_temp,SELECT_BY_POS,MODE_TRADES))
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber && OrderType()==OP_SELL)
           {
            ticketnumber=OrderTicket();
            if(ticketnumber>oldticketnumber)
              {
               orderprice=OrderOpenPrice();
               oldorderopenprice=orderprice;
               oldticketnumber=ticketnumber;
              }
           }
     }
   return(orderprice);
  }
//+------------------------------------------------------------------+

空頭馬锻烁觥:

#property copyright "aijy.github.io"
#property link      "https://aijy.github.io"
#property version   "1.00"

input bool    UseAdd=true;    // 是否使用加倉策略,true:是
input double  LotExponent=1; // 加倉系數(shù)
input int  slip=3;   // 滑點
input double  Lots=0.05; // 初始單量
input int  LotsDigits=2;  //單量精確到小數(shù)點后2位
input double  TakeProfit=200; // 止盈
input double  PipStep=300; //  加倉間隔秤涩,當一根K線的開盤價與上次開倉價之間價格大于這個數(shù)值帜乞,才加倍開倉
input int     MaxTrades=10;  //最大訂單數(shù)
input bool    UseEquityStop=true;  //未使用
input double  TotalEquityRisk=20; //loss as a percentage of equity

int MagicNumber=654321;
double PriceTarget,StartEquity,BuyTarget,SellTarget;
double AveragePrice,SellLimit,BuyLimit;
double LastBuyPrice,LastSellPrice,ClosePrice,Spread;

string EAName="SELL";
datetime timeprev=0,expiration;
int NumOfTrades=0;
double iLots;
int cnt=0,total;
double Stopper=0;
bool TradeNow=false,LongTrade=false,ShortTrade=false;

bool NewOrdersPlaced=false;
int init()
  {
   Spread=MarketInfo(Symbol(),MODE_SPREAD)*Point;
   return(0);
  }
int deinit()
  {
   return(0);
  }
void OnTick()
  {
//---------開倉條件
   bool sell_trade=false;
   if(iClose(Symbol(),PERIOD_M1,2)>iClose(Symbol(),PERIOD_M1,1))
      sell_trade=true;
//------------------------
//---獲取平均的開倉價格---
//------------------------
   int ticket;
   total=CountTrades();
   
   if(total>=3)
   {
      int total_profit=CalculateTotalProfit();
      if(total_profit>0)
      {
      
      }
   }
   
   
   AveragePrice=0;
   double Count=0;
   for(cnt=OrdersTotal()-1;cnt>=0;cnt--)
     {
      if(OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
            if(OrderType()==OP_BUY || OrderType()==OP_SELL)
              {
               AveragePrice=AveragePrice+OrderOpenPrice()*OrderLots();
               Count=Count+OrderLots();
              }
     }
   if(total>0)
      AveragePrice=NormalizeDouble(AveragePrice/Count,Digits);

   for(int i=OrdersTotal()-1;i>=0;i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) && OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
        {
         if(OrderType()==OP_SELL)
           {
            PriceTarget=AveragePrice-TakeProfit*Point;
            if(Ask<PriceTarget)
              {
               CloseThisSymbolAll();
              }
           }
        }
     }

   if(timeprev==Time[0])
     {
      return;
     }
   timeprev=Time[0];

   double CurrentPairProfit=CalculateProfit();
   if(UseEquityStop)
     { 
     //當資金損失低于風險值,不再開倉
      if(CurrentPairProfit<0 && MathAbs(CurrentPairProfit)>(TotalEquityRisk/100)*AccountEquityHigh())
        {
         if(TimeCurrent()%120==0)
            Print("stop opening new orders");
            return;
        }
     }   
   
   Print("貨幣對"+Symbol()+"的止盈:",PriceTarget);

   total=CountTrades(); //計算本貨幣對訂單總數(shù)(不包括其他貨幣對)
   NumOfTrades=total;

   double LastBuyLots;
   double LastSellLots;
   for(cnt=OrdersTotal()-1;cnt>=0;cnt--)
     {
      //統(tǒng)計所有訂單筐眷,從中間查找本EA執(zhí)行的本貨幣對訂單黎烈,判斷之前下的是多單還是空單,供后續(xù)使用
      if(OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
            if(OrderType()==OP_BUY)
              {
               LongTrade=true;
               ShortTrade=false;
               LastBuyLots=OrderLots();
               break;
              }
      if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
         if(OrderType()==OP_SELL)
           {
            LongTrade=false;
            ShortTrade=true;
            LastSellLots=OrderLots();
            break;
           }
     }
   if(total>0 && total<=MaxTrades) //有訂單且訂單總量小于最大值
     {
      LastBuyPrice=FindLastBuyPrice(); //得到上次開倉的買價(多單)
      LastSellPrice=FindLastSellPrice();//得到上次開倉的賣價(空單)
      if(LongTrade && (LastBuyPrice-Ask)>=(PipStep*Point))//判斷是否要增開多倉
        {
         TradeNow=true;
        }
      if(ShortTrade && (Bid-LastSellPrice)>=(PipStep*Point))//判斷是否要增開空倉
        {
         TradeNow=true;
        }
     }
   if(total<1) //無訂單的情況
     {
      ShortTrade=false;
      LongTrade=false;
      TradeNow=true;
      StartEquity=AccountEquity();
     }
   if(TradeNow && total>0) //如果之前判斷要加倉則執(zhí)行if
     {
      LastBuyPrice=FindLastBuyPrice(); //得到上次開倉的買價(多單)
      LastSellPrice=FindLastSellPrice();//得到上次開倉的賣價(空單)
      if(ShortTrade) //如果是空倉
        {
         NumOfTrades=total;
         iLots=fGetLots(OP_SELL);//獲得增加倉位的訂單手數(shù)
         if(UseAdd)//按以上計算出來的加倉手數(shù)下單
           {

            if(iLots>0)
              {//#
               RefreshRates();
               ticket=OpenPendingOrder(OP_SELL,iLots,Bid,slip,Ask,0,0,EAName+"-"+IntegerToString(NumOfTrades),MagicNumber,0,HotPink);
               if(ticket<0){Print("Error: ",GetLastError()); return;}
               LastSellPrice=FindLastSellPrice();
               TradeNow=false;
               NewOrdersPlaced=true;
              }//#
           }
        }
      else if(LongTrade)//如果是多倉
        {
         NumOfTrades=total;

         iLots=fGetLots(OP_BUY);//獲得增加倉位的訂單手數(shù)
         if(UseAdd)//按以上計算出來的加倉手數(shù)下單
           {
            if(iLots>0)
              {//#
               ticket=OpenPendingOrder(OP_BUY,iLots,Ask,slip,Bid,0,0,EAName+"-"+NumOfTrades,MagicNumber,0,Lime);
               if(ticket<0)
                 {
                 Print("Error: ",GetLastError());
                  return;
                 }
               LastBuyPrice=FindLastBuyPrice();
               TradeNow=false;
               NewOrdersPlaced=true;
              }//#
           }
        }
     }
   if(TradeNow && total<1)//當前無本貨幣對訂單匀谣,并且需要交易
     {
      SellLimit=Bid;
      BuyLimit=Ask;
      if(!ShortTrade && !LongTrade)//當前既無多單又無空單
        {
         NumOfTrades=total;
         if(sell_trade==true)//如果第二個K線收盤價大于第一根K線收盤價照棋,下空單(首次下單的判定條件)
           {
            iLots=fGetLots(OP_SELL);
            if(iLots>0)
              {//#
               ticket=OpenPendingOrder(OP_SELL,iLots,SellLimit,slip,SellLimit,0,0,EAName+"-"+NumOfTrades,MagicNumber,0,HotPink);
               if(ticket<0)
                 {
                  Print(iLots,"Error: ",GetLastError());
                  return;
                 }
               LastBuyPrice=FindLastBuyPrice();
               NewOrdersPlaced=true;
              }//#
           }
        }
      TradeNow=false;
     }

//------------------------------------------------------
//---以平均開倉價格,計算出止損供所有本貨幣對倉位使用---
//------------------------------------------------------

   if(NewOrdersPlaced)
      for(cnt=OrdersTotal()-1;cnt>=0;cnt--)
        {
         if(OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))
            if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
               if(OrderType()==OP_BUY) // Calculate profit/stop target for long 
                 {
                  PriceTarget=AveragePrice+(TakeProfit*Point);
                  BuyTarget=PriceTarget;
                 }
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
            if(OrderType()==OP_SELL) // Calculate profit/stop target for short
              {
               PriceTarget=AveragePrice-(TakeProfit*Point);
               SellTarget=PriceTarget;
              }
        }
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double fGetLots(int aTradeType)
  {
   double tLots;
   tLots=NormalizeDouble(Lots*MathPow(LotExponent,NumOfTrades),LotsDigits);
   if(AccountFreeMarginCheck(Symbol(),aTradeType,tLots)<=0)
     {
      return(-1);
     }
   if(GetLastError()==134)
     {
      return(-2);
     }
   return(tLots);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int CountTrades()
  {
   int count=0;
   int trade;
   for(trade=OrdersTotal()-1;trade>=0;trade--)
     {
      if(OrderSelect(trade,SELECT_BY_POS,MODE_TRADES))
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
            if(OrderType()==OP_SELL || OrderType()==OP_BUY)
               count++;
     }//for
   return(count);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CloseThisSymbolAll()
  {
   int trade;
   for(trade=OrdersTotal()-1;trade>=0;trade--)
     {
      if(OrderSelect(trade,SELECT_BY_POS,MODE_TRADES))
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
           {
            if(OrderType()==OP_BUY)
               OrderClose(OrderTicket(),OrderLots(),Bid,slip,Blue);
            if(OrderType()==OP_SELL)
               OrderClose(OrderTicket(),OrderLots(),Ask,slip,Red);
           }
      Sleep(1000);
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OpenPendingOrder(int pType,double pLots,double pLevel,int sp,double pr,int sl,int tp,string pComment,int pMagic,datetime pExpiration,color pColor)
  {
   int ticket=0;
   int err=0;
   int c=0;
   int NumberOfTries=100;
   switch(pType)
     {
      case OP_BUYLIMIT:
         for(c=0;c<NumberOfTries;c++)
           {
            ticket=OrderSend(Symbol(),OP_BUYLIMIT,pLots,pLevel,sp,StopLong(pr,sl),TakeLong(pLevel,tp),pComment,pMagic,pExpiration,pColor);
            err=GetLastError();
            if(err==0)
              {
               break;
              }
            else
              {
               if(err==4 || err==137 || err==146 || err==136) //Busy errors
                 {
                  Sleep(1000);
                  continue;
                 }
               else //normal error
                 {
                  break;
                 }
              }
           }
         break;
      case OP_BUYSTOP:
         for(c=0;c<NumberOfTries;c++)
           {
            ticket=OrderSend(Symbol(),OP_BUYSTOP,pLots,pLevel,sp,StopLong(pr,sl),TakeLong(pLevel,tp),pComment,pMagic,pExpiration,pColor);
            err=GetLastError();
            if(err==0)
              {
               break;
              }
            else
              {
               if(err==4 || err==137 || err==146 || err==136) //Busy errors
                 {
                  Sleep(5000);
                  continue;
                 }
               else //normal error
                 {
                  break;
                 }
              }
           }
         break;
      case OP_BUY:
         for(c=0;c<NumberOfTries;c++)
           {
            RefreshRates();
            ticket=OrderSend(Symbol(),OP_BUY,pLots,Ask,sp,StopLong(Bid,sl),TakeLong(Ask,tp),pComment,pMagic,pExpiration,pColor);
            err=GetLastError();
            if(err==0)
              {
               break;
              }
            else
              {
               if(err==4 || err==137 || err==146 || err==136) //Busy errors
                 {
                  Sleep(5000);
                  continue;
                 }
               else //normal error
                 {
                  break;
                 }
              }
           }
         break;
      case OP_SELLLIMIT:
         for(c=0;c<NumberOfTries;c++)
           {
            ticket=OrderSend(Symbol(),OP_SELLLIMIT,pLots,pLevel,sp,StopShort(pr,sl),TakeShort(pLevel,tp),pComment,pMagic,pExpiration,pColor);
            err=GetLastError();
            if(err==0)
              {
               break;
              }
            else
              {
               if(err==4 || err==137 || err==146 || err==136) //Busy errors
                 {
                  Sleep(5000);
                  continue;
                 }
               else //normal error
                 {
                  break;
                 }
              }
           }
         break;
      case OP_SELLSTOP:
         for(c=0;c<NumberOfTries;c++)
           {
            ticket=OrderSend(Symbol(),OP_SELLSTOP,pLots,pLevel,sp,StopShort(pr,sl),TakeShort(pLevel,tp),pComment,pMagic,pExpiration,pColor);
            err=GetLastError();
            if(err==0)
              {
               break;
              }
            else
              {
               if(err==4 || err==137 || err==146 || err==136) //Busy errors
                 {
                  Sleep(5000);
                  continue;
                 }
               else //normal error
                 {
                  break;
                 }
              }
           }
         break;
      case OP_SELL:
         for(c=0;c<NumberOfTries;c++)
           {
            ticket=OrderSend(Symbol(),OP_SELL,pLots,Bid,sp,StopShort(Ask,sl),TakeShort(Bid,tp),pComment,pMagic,pExpiration,pColor);
            err=GetLastError();
            if(err==0)
              {
               break;
              }
            else
              {
               if(err==4 || err==137 || err==146 || err==136) //Busy errors
                 {
                  Sleep(5000);
                  continue;
                 }
               else //normal error
                 {
                  break;
                 }
              }
           }
         break;
     }

   return(ticket);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double StopLong(double price,int stop)
  {
   if(stop==0)
      return(0);
   else
      return(price-(stop*Point));
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double StopShort(double price,int stop)
  {
   if(stop==0)
      return(0);
   else
      return(price+(stop*Point));
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double TakeLong(double price,int take)
  {
   if(take==0)
      return(0);
   else
      return(price+(take*Point));
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double TakeShort(double price,int take)
  {
   if(take==0)
      return(0);
   else
      return(price-(take*Point));
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double CalculateProfit()
  {
   double Profit=0;
   for(cnt=OrdersTotal()-1;cnt>=0;cnt--)
     {
      if(OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
            if(OrderType()==OP_BUY || OrderType()==OP_SELL)
              {
               Profit=Profit+OrderProfit();
              }
     }
   return(Profit);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double AccountEquityHigh()
  {
   static double AccountEquityHighAmt,PrevEquity;
   if(CountTrades()==0) AccountEquityHighAmt=AccountEquity();
   if(AccountEquityHighAmt<PrevEquity) AccountEquityHighAmt=PrevEquity;
   else AccountEquityHighAmt=AccountEquity();
   PrevEquity=AccountEquity();
   return(AccountEquityHighAmt);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double FindLastBuyPrice()
  {
   double oldorderopenprice=0,orderprice=0;
   int cnt_temp,oldticketnumber=0,ticketnumber;
   for(cnt_temp=OrdersTotal()-1;cnt_temp>=0;cnt_temp--)
     {
      if(OrderSelect(cnt_temp,SELECT_BY_POS,MODE_TRADES))
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber && OrderType()==OP_BUY)
           {
            ticketnumber=OrderTicket();
            if(ticketnumber>oldticketnumber)
              {
               orderprice=OrderOpenPrice();
               oldorderopenprice=orderprice;
               oldticketnumber=ticketnumber;
              }
           }
     }
   return(orderprice);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double FindLastSellPrice()
  {
   double oldorderopenprice=0,orderprice=0;
   int cnt_temp,oldticketnumber=0,ticketnumber;
   for(cnt_temp=OrdersTotal()-1;cnt_temp>=0;cnt_temp--)
     {
      if(OrderSelect(cnt_temp,SELECT_BY_POS,MODE_TRADES))
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber && OrderType()==OP_SELL)
           {
            ticketnumber=OrderTicket();
            if(ticketnumber>oldticketnumber)
              {
               orderprice=OrderOpenPrice();
               oldorderopenprice=orderprice;
               oldticketnumber=ticketnumber;
              }
           }
     }
   return(orderprice);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double CalculateTotalProfit()
  {
   double Profit=0;
   for(cnt=OrdersTotal()-1;cnt>=0;cnt--)
     {
      if(OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES) && OrderMagicNumber()==MagicNumber)
        {
         Profit=Profit+OrderProfit();
        }
     }
   return(Profit);
  }

馬丁策略的改良方法

馬丁策略在單邊行情越大時風險越大武翎。下面烈炭,我們簡單探討一下馬丁的風險控制。

  1. 在加倉間距上進行控制宝恶,使用較大的加倉可減小風險符隙,過大的加倉間距可能遲遲不能盈利出場,這點比較難把控垫毙。

  2. 在加倉倍數(shù)上進行控制霹疫,使用較小的加倉倍數(shù)睡榆,策略會更穩(wěn)健压汪。

  3. 馬丁也可以結合止盈止損,該止損的時候不能猶豫雾鬼,如果真的觸碰了止損線膀藐,就要反思參數(shù)設置的合理性了屠阻。

  4. 可以改變馬丁加倉的位置,加倉的位置可以是K線有回調(diào)的時候才加额各。

EA的風險控制

EA風險控制是重中之重国觉。

凈值風險控制

#property copyright "shiyingpan"
#property link      "https://aijy.github.io"
#property version   "1.0"
#property strict

enum mybool
{
   是=1,
   否=0,
};

input mybool 是否手動輸入凈值=否; 
input double 手動輸入初始資金=0;
input double 凈值風險率=15;        //--- 凈值虧損15%時,強平出場
input double 盈利提示一=5;         //--- 凈值盈利到5%時虾啦,提示關注
input double 盈利提示二=10;        //--- 凈值盈利到10%時蛉加,強平出場
input double 虧損提示一=5;         //--- 凈值虧損到5%時蚜枢,提示關注
input double 虧損提示二=10;        //--- 凈值虧損到10%時,搶平出場
double 初始資金=0;

int flag[4]={0,0,0,0}; //--- 凈值浮動狀態(tài)

int OnInit()
  {
   while(AccountNumber()==0)
      Sleep(10000);
//   初始資金=AccountEquity();   
   if(是否手動輸入凈值==否)
       初始資金=AccountBalance();
   else
       初始資金=手動輸入初始資金;    
   if(初始資金==0)
   {
      Alert("當前賬戶無資金针饥!");
      return(INIT_FAILED);
   }
   if(AccountEquity()<初始資金*(100-凈值風險率)/100)
   {
      Alert("當前凈值虧損超過凈值風險率厂抽,無法加載!");
      return(INIT_FAILED);  
   }
   
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
 
  }
void OnTick()
  {
   if(AccountEquity()<初始資金*(100-凈值風險率)/100)
   {
      Alert("資金虧損超過"+DoubleToString(凈值風險率,1)+"%,全部平倉丁眼。虧損:",DoubleToStr(AccountEquity()-初始資金,2)," 凈值:",AccountEquity());
      SendMail("資金虧損超過"+DoubleToString(凈值風險率,1)+"%,全部平倉筷凤。虧損:"+DoubleToStr(AccountEquity()-初始資金,2)+" 凈值:"+DoubleToStr(AccountEquity()),"");
      flag[1]=1;flag[2]=1;
      close_chart(); //改Return 為close_chart();
      close_all();
      Sleep(5000);
   }   
   if(AccountEquity()<初始資金*(100-虧損提示一)/100 && flag[1]==0) 
   {
      Alert("資金虧損超過"+DoubleToString(虧損提示一,1)+"%,虧損:",DoubleToStr(AccountEquity()-初始資金,2)," 凈值:",AccountEquity());
      SendMail("資金虧損超過"+DoubleToString(虧損提示一,1)+"%,虧損:"+DoubleToStr(AccountEquity()-初始資金,2)+" 凈值:"+DoubleToStr(AccountEquity()),"");
      flag[1]=1;
      return;   
   }  
   if(AccountEquity()<初始資金*(100-虧損提示二)/100 && flag[2]==0) 
   {
      Alert("資金虧損超過"+DoubleToString(虧損提示二,1)+"%,虧損:",DoubleToStr(AccountEquity()-初始資金,2)," 凈值:",AccountEquity());
      SendMail("資金虧損超過"+DoubleToString(虧損提示二,1)+"%,虧損:"+DoubleToStr(AccountEquity()-初始資金,2)+" 凈值:"+DoubleToStr(AccountEquity()),"");
      flag[2]=1;
      close_chart();
      close_all();
      ExpertRemove();
      Sleep(100000);
      return;
   }       
   if(AccountEquity()>初始資金*(100+盈利提示一)/100 && flag[3]==0) 
   {
      Alert("資金盈利超過"+DoubleToString(盈利提示一,1)+"%,盈利:",DoubleToStr(AccountEquity()-初始資金,2)," 凈值:",AccountEquity());
      SendMail("資金盈利超過"+DoubleToString(盈利提示一,1)+"%,盈利:"+DoubleToStr(AccountEquity()-初始資金,2)+" 凈值:"+DoubleToStr(AccountEquity()),"");
      flag[3]=1;
      return;
   } 
   
   if(AccountEquity()>初始資金*(100+盈利提示二)/100 && flag[4]==0) 
   {
      Alert("資金盈利超過"+DoubleToString(盈利提示二,1)+"%,盈利:",DoubleToStr(AccountEquity()-初始資金,2)," 凈值:",AccountEquity());
      SendMail("資金盈利超過"+DoubleToString(盈利提示二,1)+"%,盈利:"+DoubleToStr(AccountEquity()-初始資金,2)+" 凈值:"+DoubleToStr(AccountEquity()),"");
      flag[4]=1;
      close_chart();
      close_all();
      ExpertRemove();
      Sleep(100000);
      return;
   } 
   Sleep(500);   
   
  }

void close_all() //--- 平掉所有倉位
{
   int ticket[200],cnt=0;
   for(int i=0;i<=OrdersTotal()-1;i++)
   {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
      {
         ticket[cnt]=OrderTicket();
         cnt++;
      }   
   }
   for(int i=0;i<=cnt-1;i++)
   {
      if(OrderSelect(ticket[i],SELECT_BY_TICKET,MODE_TRADES))
      {
         if(OrderType()==OP_BUY)
            if(!OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_BID),3,clrRed))
               OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_BID),3,clrRed);
         if(OrderType()==OP_SELL)
            if(!OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_ASK),3,clrRed))
               OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_ASK),3,clrRed);  
         if(OrderType()==OP_BUYLIMIT || OrderType()==OP_SELLLIMIT || OrderType()==OP_BUYSTOP || OrderType()==OP_SELLSTOP)  
            if(!OrderDelete(OrderTicket(),clrRed))
               OrderDelete(OrderTicket(),clrRed);           
      }   
   }

}

void close_chart()  //--- 關閉所有圖表和EA
{
   long chart_total[100];
   long currChart,prevChart=ChartFirst(); 
   chart_total[0]=prevChart;
   int i=0,limit=100; 

   while(i<limit)// We have certainly not more than 100 open charts 
     { 
      currChart=ChartNext(prevChart); // Get the new chart ID by using the previous chart ID 
      if(currChart<0) break;          // Have reached the end of the chart list 
      prevChart=currChart;// let's save the current chart ID for the ChartNext() 
      i=i+1;// Do not forget to increase the counter 
      chart_total[i]=prevChart;
      Print(i,chart_total[i]);      
     }

   for(int j=0;j<=i;j++)
      if(chart_total[j]!=ChartID())
         ChartClose(chart_total[j]);
}


單量風險控制

#property copyright "shiyingpan"
#property link      "https://aijy.github.io"
#property version   "1.00"
#property strict

input double 萬美金最大單量=2;     //--- 一萬美金可下幾首單量,按比例縮減
bool new_orders=true;
double max_lots=0;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
   while(AccountNumber()==0)
      Sleep(10000);
   max_lots=AccountEquity()/10000*萬美金最大單量;
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {

  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTick()
  {

   double total_lots=0;
   for(int i=OrdersTotal()-1;i>=0;i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         total_lots=total_lots+OrderLots();
        }
     }

   if(total_lots>max_lots)
     {
      new_orders=false;
     }

   if(new_orders==true)
     {
      Print("當前單量未超最大單量苞七,允許下單");
     }
  }

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末藐守,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子蹂风,更是在濱河造成了極大的恐慌卢厂,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件惠啄,死亡現(xiàn)場離奇詭異慎恒,居然都是意外死亡,警方通過查閱死者的電腦和手機撵渡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進店門融柬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人趋距,你說我怎么就攤上這事粒氧。” “怎么了节腐?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵外盯,是天一觀的道長。 經(jīng)常有香客問我翼雀,道長饱苟,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任锅纺,我火速辦了婚禮,結果婚禮上肋殴,老公的妹妹穿的比我還像新娘囤锉。我一直安慰自己,他們只是感情好护锤,可當我...
    茶點故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布官地。 她就那樣靜靜地躺著,像睡著了一般烙懦。 火紅的嫁衣襯著肌膚如雪驱入。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天,我揣著相機與錄音亏较,去河邊找鬼莺褒。 笑死,一個胖子當著我的面吹牛雪情,可吹牛的內(nèi)容都是我干的遵岩。 我是一名探鬼主播,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼巡通,長吁一口氣:“原來是場噩夢啊……” “哼尘执!你這毒婦竟也來了?” 一聲冷哼從身側響起宴凉,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤誊锭,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后弥锄,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體丧靡,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年叉讥,在試婚紗的時候發(fā)現(xiàn)自己被綠了窘行。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡图仓,死狀恐怖罐盔,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情救崔,我是刑警寧澤惶看,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站六孵,受9級特大地震影響纬黎,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜劫窒,卻給世界環(huán)境...
    茶點故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一本今、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧主巍,春花似錦冠息、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至搞旭,卻和暖如春散怖,著一層夾襖步出監(jiān)牢的瞬間菇绵,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工镇眷, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留咬最,地道東北人。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓偏灿,卻偏偏與公主長得像丹诀,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子翁垂,可洞房花燭夜當晚...
    茶點故事閱讀 45,512評論 2 359

推薦閱讀更多精彩內(nèi)容