您现在的位置: 比特财富网 >> 财经 >  >> 外匯
MT4平台自帶的EA:Moving Average詳解
外_匯_邦 WaiHuiBang.com

由於本站模板寬度的制約,看著會比較凌亂,建議復制本文內容,粘貼在記事本中,方便閱讀。www.emoneybtc.com

 

使用過MT4平台的人都知道,MT4平台自帶了一個自動交易的EA指標,那就是Moving Average ,下面我們詳細解釋一下該指標的語句功能,以便各位匯友學習EA的編程。

            //+------------------------------------------------------------------+
            //|                        Moving Average.mq4                       
               |
            //|      Copyright ?2005, MetaQuotes Software Corp.        |
            //|                  http://www.metaquotes.net/                     
              |
            //+------------------------------------------------------------------+
            #define MAGICMA   20050610
            //定義本EA操作的訂單的唯一標識號碼,由此可以實現在同一賬戶上多系統操作,各操作EA的訂單標識碼不同,就不會互相誤操作。凡是EA皆不可缺少,非常非常重要!!!
            //宏定義命令#define用法
            extern double Lots             = 0.1;//每單的交易量
            extern double MaximumRisk        = 0.02;//本系統最大可以動用總資金的2%
            extern double DecreaseFactor     = 3;//作者定義的參數,作用要看程序中的用法
            extern double MovingPeriod    = 10;//EA中使用的均線的周期
            extern double MovingShift        =3;//EA中使用的均線向左的K線偏移量
            //extern 確定從外部程序輸入的變量, 會直接顯現輸入數據窗口。數列本身不能作為外部變量。
            //+------------------------------------------------------------------+
            //| Calculate open positions                                        
                |
            //+------------------------------------------------------------------+
            int CalculateCurrentOrders(string symbol)//函數作用,計算當前持倉訂單的數量
            {
            int buys=0,sells=0;//定義兩個臨時變量,准備用於後面的多空訂單的個數計算
            //----
            for(int i=0;i<OrdersTotal();i++)//循環檢測當前的訂單隊列,不包含掛單
            {
            if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false)
            break;//挑出持倉單的每一個訂單位置
            if(OrderSymbol()==Symbol() &&
            OrderMagicNumber()==MAGICMA)//根據訂單位置,比較是否是當前K線商品
            以及訂單唯一標識號是否和本程序設置的一致,即判斷這個訂單是不是當前EA操作的。(用於避免EA誤操作其他程序控制的持倉單)
                   {
            if(OrderType()==OP_BUY)   buys++;//找到符合條件的持倉單後,如果是多單,則臨時變量buys增加1
            if(OrderType()==OP_SELL) sells++;//找到符合條件的持倉單後,如果是空單,則臨時變量sells增加1
            }
            }
            //---- return orders volume
            if(buys>0) return(buys);
            else    return(-sells);//本函數返回查詢計算結束時的持倉單的個數.這種模式返回是假設不存在鎖單的。
            }
            //+------------------------------------------------------------------+
            //| Calculate optimal lot size                                      
                  |
            //+------------------------------------------------------------------+
            double LotsOptimized()//函數目的,根據要求 計算出訂單交易量
            {
            double lot=Lots;
            int orders=HistoryTotal();     // history orders total 歷史出場訂單的個數
            int losses=0;                // number of losses orders without a
            break
            //---- select lot size
            lot=NormalizeDouble(AccountFreeMargin()*MaximumRisk/1000.0,1);//通過風險系數的計算獲得當前入場單應該采用的交易量,除以1000是因為大多貨幣對匯價都在這個附近。
            //---- calcuulate number of losses orders without a break
            if(DecreaseFactor>0)
            {
            for(int i=orders-1;i>=0;i--)
            {
            if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false) { Print("Error
            in history!"); break; }//循環查詢出場單隊列
            if(OrderSymbol()!=Symbol() || OrderType()>OP_SELL) continue;//
            //----
            if(OrderProfit()>0) break;
            if(OrderProfit()<0) losses++;//循環計算所有出場虧損單的虧損總和
            }
            if(losses>1)
            lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,1);//如果虧損額大於1,則下一入場單的交易量修正為新的計算結果。
            }
            //---- return lot size
            if(lot<0.1) lot=0.1;//如果計算出的交易量小於帳戶最小手數0.1,則下一入場單的交易手數使用0.1作為交易量
            return(lot);
            }
            //+------------------------------------------------------------------+
            //| Check for open order conditions                                
|
            //+------------------------------------------------------------------+
            void CheckForOpen()//檢查入場條件的情況並作處理
            {
            double ma;
            int res;
            //---- go trading only for first tiks of new
            bar,注意下面采用的Volume[0],Open[1]等可以確保交易是在當前周期下k線 收盤價走完才發生的。
            if(Volume[0]>1)
            return;//如果當前K線持倉量(成交量)大於1,說明不是K線的開盤時間點,即當前k線還沒收盤確定,則直接返回
            否則是K線第一個價格,則繼續下面的過程
            //---- get Moving Average
            ma=iMA(NULL,0,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE,0);//獲得當前的均線數值
            //---- sell conditions
            if(Open[1]>ma && Close[1]<ma)   //如當前K開盤價大於均線,而前一K收盤價小於均線,則發出入場多單
            {
            res=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,0,0,"",MAGICMA,0,Red);
            return;
            }
            //---- buy conditions
            if(Open[1]<ma && Close[1]>ma)   //如當前K開盤價小於均線,而前一K收盤價大於均線,則發出入場空單
            {
            res=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,0,0,"",MAGICMA,0,Blue);
            return;
            }
            //----
            }
            //+------------------------------------------------------------------+
            //| Check for close order conditions                                
            |
            //+------------------------------------------------------------------+
            void CheckForClose()//檢查出場條件的情況並作處理
            {
            double ma;
            //---- 只在一個k收盤另一個新出現時交易
            if(Volume[0]>1) return;
            //---- get Moving Average
            ma=iMA(NULL,0,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE,0);
            //----
            for(int i=0;i<OrdersTotal();i++)
            {
            if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false)        break;
            if(OrderMagicNumber()!=MAGICMA || OrderSymbol()!=Symbol()) continue;
            //----確定是不是自己系統下的單子。
            if(OrderType()==OP_BUY)            //多單平倉
            {
            if(Open[1]>ma && Close[1]<ma)
            OrderClose(OrderTicket(),OrderLots(),Bid,3,White);//如果持倉是多單,則當當前K開盤價小於均
            線,而前一K收盤價大於均線,則發出平倉指令
            break;
            }
            if(OrderType()==OP_SELL)         //空單平倉
            {
            if(Open[1]<ma && Close[1]>ma)
            OrderClose(OrderTicket(),OrderLots(),Ask,3,White););//如果持倉是空單,則當當前K開盤價大於
            均線,而前一K收盤價小於均線,則發出平倉指令
            break;
            }
            }
            //----
            }
            //+------------------------------------------------------------------+
            //| Start function                                                  
                        |
            //+------------------------------------------------------------------+
            void start()//主循環過程
            {
            //---- check for history and trading
            if(Bars<100 || IsTradeAllowed()==false) return;
            //---- calculate open orders by current symbol
            if(CalculateCurrentOrders(Symbol())==0) CheckForOpen();
            else                                  CheckForClose();
            //----
            }

外_匯_邦 WaiHuiBang.com
  • 上一个财经:
  • 下一个财经:
  •   風險提示:比特財富網的各種信息資料僅供參考,不構成任何投資建議,不對任何交易提供任何擔保,亦不構成任何邀約,不作為任何法律文件,投資人據此進行投資交易而產生的後果請自行承擔,本網站不承擔任何責任,理財有風險,投資需謹慎。
    比特財富網 版權所有 © www.emoneybtc.com