找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
首页论坛EAHub 外汇论坛
查看: 10|回复: 0

资金管理指标,按照外汇冠军思路设计下单手数

[复制链接]

4万

主题

54

回帖

4万

积分

管理员

积分
45954
发表于 2026-8-21 14:55:00 | 显示全部楼层 |阅读模式
资金管理指标,按照外汇冠军思路设计下单手数



//+------------------------------------------------------------------+
//|                                                 资金管理指标.mq4 |
//|                                            www.shuidongyijing.cn |
//+------------------------------------------------------------------+
#property copyright "教与交易 www.shuidongyijing.cn "
#property link      "http://www.shuidongyijing.cn"
#property strict


#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1  clrNONE
#property indicator_color2  clrNONE
#property indicator_color3  clrNONE

extern double    风险 = 0.01;
extern bool      Use_ATR_Based_StopLoss = true;
extern int       波幅计算天数 = 14;
extern double    ATR_SL_Multiplier = 1.5;
extern int       止损修正点数 = 1000;
extern int       计算历史蜡烛数 = 500;
int       Display_Corner = 2;

double   buffer_atrPoints[];
double   buffer_stoplossPoints[];
double   buffer_lotsize[];

int init() {

   SetIndexBuffer(0,buffer_atrPoints); SetIndexLabel(0,"buffer_atrPoints"); SetIndexStyle(0,DRAW_NONE); SetIndexEmptyValue(0,EMPTY_VALUE);
   SetIndexBuffer(1,buffer_stoplossPoints); SetIndexLabel(1,"buffer_stoplossPoints"); SetIndexStyle(1,DRAW_NONE); SetIndexEmptyValue(1,EMPTY_VALUE);
   SetIndexBuffer(2,buffer_lotsize); SetIndexLabel(2,"buffer_lotsize"); SetIndexStyle(2,DRAW_NONE); SetIndexEmptyValue(2,EMPTY_VALUE);

   IndicatorShortName(WindowExpertName());
   
   return(0);
}

int deinit() {
   ObjectDelete("@MM-ATR");
   ObjectDelete("@MM-LotText");
   ObjectDelete("@MM-LotSize");
   return(0);
}

int start() {
   int counted_bars=IndicatorCounted();
   if(counted_bars<0) return(-1);
   if(counted_bars>0) counted_bars--;
   int limit = 计算历史蜡烛数 - counted_bars;

   double atr,lotsize;
   int atrPoints, slPoints;
   
   for(int i=limit; i>=0; i--) {
     atr = iATR(NULL,0,波幅计算天数,i+1);
     atrPoints = (int)(atr * MathPow(10,MarketInfo(Symbol(),MODE_DIGITS)));
     
     if(Use_ATR_Based_StopLoss) {
         slPoints = (int)MathCeil(ATR_SL_Multiplier*atrPoints);
         slPoints = slPoints > 0 ? slPoints : 止损修正点数;
     } else {
         slPoints = 止损修正点数;
     }
     
     lotsize = CalculateLotSize(Symbol(),风险, slPoints, 0, 10);

     buffer_atrPoints=StrToDouble(DoubleToStr(atrPoints,0));
     buffer_stoplossPoints=StrToDouble(DoubleToStr(slPoints,0));
     buffer_lotsize=StrToDouble(DoubleToStr(lotsize,2));;
   }

   if(Use_ATR_Based_StopLoss) {
      DisplayText("@MM-ATR",StringConcatenate("真实波幅 (",波幅计算天数,"): ",buffer_atrPoints[0]," 点"),clrGold,30,35,Display_Corner);
   }

   DisplayText("@MM-LotText",StringConcatenate("允许最大手数 (风险 ",DoubleToStr((风险*100),0),"% , 建议止盈止损距离 ",buffer_stoplossPoints[0]," 点) :"),clrGold,30,10,Display_Corner);
   DisplayText("@MM-LotSize",StringConcatenate(buffer_lotsize[0]),clrAqua,580,10,Display_Corner);

   return(0);
}

double Multiplicator(string currencyPairAppendix="")
{
        double multiplicator = 1.0;
       
        if ( AccountCurrency() == "USD" )
                return ( multiplicator );
   if ( AccountCurrency() == "EUR" )
                multiplicator = 1.0 / MarketInfo ( "EURUSD" + currencyPairAppendix, MODE_BID );
   if ( AccountCurrency() == "GBP" )
                multiplicator = 1.0 / MarketInfo ( "GBPUSD" + currencyPairAppendix, MODE_BID );
   if ( AccountCurrency() == "AUD" )
                multiplicator = 1.0 / MarketInfo ( "AUDUSD" + currencyPairAppendix, MODE_BID );               
   if ( AccountCurrency() == "NZD" )
                multiplicator = 1.0 / MarketInfo ( "NZDUSD" + currencyPairAppendix, MODE_BID );               
   if ( AccountCurrency() == "CHF" )
                multiplicator = MarketInfo ( "USDCHF" + currencyPairAppendix, MODE_BID );
   if ( AccountCurrency() == "JPY" )
                multiplicator = MarketInfo ( "USDJPY" + currencyPairAppendix, MODE_BID );
   if ( AccountCurrency() == "CAD" )
                multiplicator = MarketInfo ( "USDCAD" + currencyPairAppendix, MODE_BID );               
   if ( multiplicator == 0 )
           multiplicator = 1.0; // If account currency is neither of EUR, GBP, AUD, NZD, CHF, JPY or CAD we assumes that it is USD
        return ( multiplicator );
}


double CalculateLotSize(string argSymbol, double argRiskDecimal, int argStoplossPoints, int argExtraPriceGapPoints, double argAllowedMaxLotSize)
{
   // Calculate LotSize based on Equity, Risk in decimal and StopLoss in points
   double _availableMoney, _maxLotByEquity, _maxLot, _minLot, _lotSize1, _lotSize2, _lotSize;
        int _lotdigit = 2;
          
   // Calculate margin required for 1 lot
   double _marginForOneLot = MarketInfo(argSymbol, MODE_MARGINREQUIRED);
   // Step in lot size changing
   double _lotStep = MarketInfo(argSymbol, MODE_LOTSTEP);
        // Amount of money in base currency for 1 lot
        double _lotBase = MarketInfo ( Symbol(), MODE_LOTSIZE );
       
        if ( _lotStep ==  1)
                _lotdigit = 0;
        if ( _lotStep == 0.1 )       
                _lotdigit = 1;
   if ( _lotStep == 0.01 )
                _lotdigit = 2;

        // Get available money as Equity
        _availableMoney = AccountEquity();
        // Maximum allowed Lot by the broker according to Equity. And we don't use 100% but 98%
        _maxLotByEquity = MathFloor(_availableMoney * 0.98 / _marginForOneLot / _lotStep) * _lotStep;
        _maxLot = MathMin(_maxLotByEquity, MathMin(argAllowedMaxLotSize, MarketInfo(argSymbol, MODE_MAXLOT)));
        // Minimum allowed Lot by the broker
        _minLot = MarketInfo(argSymbol, MODE_MINLOT);
        // Lot according to Risk.
        _lotSize1 = MathFloor ( argRiskDecimal * _availableMoney / ( argStoplossPoints + argExtraPriceGapPoints ) / _lotStep ) * _lotStep;
   _lotSize2 = _lotSize1 * Multiplicator("");
   _lotSize = MathMax(MathMin(_lotSize2, _maxLot), _minLot);
        _lotSize = NormalizeDouble (_lotSize, _lotdigit);

        return ( _lotSize );
}

void DisplayText(string objname,string objtext,int clr,int x,int y,int corner) {
   if(ObjectFind(objname)==-1) {
      ObjectCreate(objname,OBJ_LABEL,0,0,0);
      ObjectSet(objname,OBJPROP_CORNER,corner);
      ObjectSet(objname,OBJPROP_XDISTANCE,x);
      ObjectSet(objname,OBJPROP_YDISTANCE,y);
   }
   ObjectSetText(objname,objtext,18,"Arial",clr);
}

复制代码
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|EAHub外汇论坛

GMT+8, 2026-10-11 07:24 , Processed in 0.102883 second(s), 19 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表