第十二节 子函数及下单面板开发

下面我们来试一下做一个简单的面板EA,这个面板应该具有可手动调节的开仓、平仓功能,有挂单的功能以及删除挂单的功能。由于创建面板需要反复创建按钮、文本框、这一类的对象,我们就想是不是能把创建这某类对象的功能集成到一个模块里面,我们只要输入参数就可以完成创建呢?那么为了实现模块化的功能,下面我们来介绍一下编写模块用的子函数。

子函数

什么是子函数呢?我们知道我们可以调用函数来帮我们做一些事,比如说创建对象的函数可以完成创建对象的工作,那么子函数其实也可以这么定义,就是能够通过调用帮我们完成特定目的的一类函数。子函数不会自己运行,必须调用才能运行。任何函数都可以调用子函数,子函数之间也可以相互调用。

那么子函数怎么用代码来表达呢?下面用脚本做一个简单的示例:

void OnStart()
  {
      int a=1;
      int b=1;
      int c=add(a,b);
      Print("C="+(string)c);
  }

int add(int a,int b)
{
   int c=a+b;
   return(c);
}

我们想用子函数来计算a+b的结果并打印它,于是我们写了一个名字叫add的子函数,add()函数里面的参数有两个,分别是整数类型的a以及整数类型的b,注意这里的参数和主函数里面的参数是不一样的,在函数里面的声明的变量为主函数里面的局部变量,只在该函数范围内有效,比如说主函数里面的a和b就只能在主函数里面发挥效果,而子函数里面的a和b也只能在子函数里面发挥效果,所以子函数里面的变量是和主函数没有关系的。需要注意的是在主函数外部声明过的全局变量名称不可作为函数的局部变量名称。

当子函数被调用时,我们就把主函数里面的a的值赋给了子函数里面的a,然后把主函数里面的b的值赋给了子函数里面的b,在子函数内声明了局部变量c,把a+b的值赋给了c,然后返回了c的值。注意我们的子函数的名称前有一个int,这个意思是我们的子函数有一个整数型的返回值,所谓返回值,就是子函数的计算结果,有一些子函数不需要返回值,那么它们的前面就是void,如果返回的是小数,那就可以用double,如果是字符串就可以用string。

有了子函数,我们就可以轻易地将新建按钮和新建文本框的代码模块化了。我们把上节课按钮和文本框的代码拿过来,塞到子函数里面,就形成了我们的按钮创建模块,以及文本框创建模块,代码如下:

void OnStart()
  {
button("button",100,50,clrBlue,clrWhite,clrBlue,15,CORNER_RIGHT_UPPER,110,10,
"Buy");
edittext("TEXT",100,50,clrGray,clrWhite,clrGray,15,CORNER_RIGHT_UPPER,210,10,
ALIGN_CENTER,false,"0.01");
  }

void button(string name,int width,int height,int clr_border,int clr_text,int clr_bg,
int fontsize,int corner,int xd,int yd,string text)
{
      ObjectCreate(0,name,OBJ_BUTTON,0,0,0);
      ObjectSetInteger(0,name,OBJPROP_BORDER_COLOR, clr_border);
      ObjectSetInteger(0,name,OBJPROP_XSIZE, width);
      ObjectSetInteger(0,name,OBJPROP_YSIZE, height);
      ObjectSetInteger(0,name,OBJPROP_COLOR, clr_text);
      ObjectSetInteger(0,name,OBJPROP_BGCOLOR, clr_bg);
      ObjectSetInteger(0,name,OBJPROP_FONTSIZE, fontsize);
      ObjectSetInteger(0,name,OBJPROP_CORNER, corner);
      ObjectSetInteger(0,name,OBJPROP_XDISTANCE, xd);
      ObjectSetInteger(0,name,OBJPROP_YDISTANCE, yd);
      ObjectSetString(0,name,OBJPROP_TEXT, text); 
}

void edittext(string name,
            int width,
            int height,
            int clr_border,
            int clr_text,
            int clr_bg,
            int fontsize,
            int corner,
            int xd,
            int yd,
            int align,
            int readonly,
            string text)
{
      ObjectCreate(0, name,OBJ_EDIT,0,0,0);
      ObjectSetInteger(0, name,OBJPROP_XSIZE,width);
      ObjectSetInteger(0,name,OBJPROP_YSIZE,height);
      ObjectSetInteger(0,name,OBJPROP_BORDER_COLOR, clr_border);
      ObjectSetInteger(0,name,OBJPROP_COLOR, clr_text);
      ObjectSetInteger(0,name,OBJPROP_BGCOLOR, clr_bg);
      ObjectSetInteger(0,name,OBJPROP_FONTSIZE, fontsize);
      ObjectSetInteger(0,name,OBJPROP_CORNER, corner);
      ObjectSetInteger(0,name,OBJPROP_XDISTANCE, xd);
      ObjectSetInteger(0,name,OBJPROP_YDISTANCE, yd);
      ObjectSetInteger(0,name,OBJPROP_ALIGN, align);
      ObjectSetInteger(0,name,OBJPROP_READONLY, readonly);
      ObjectSetString(0,name,OBJPROP_TEXT, text);
}

这样的话我们就可以不用每一个按钮和文本框都去设置一遍参数了,直接调用button和edittext子函数,把参数输进去就可以很方便地创建对象,而且减少了重复的代码,当建立多个对象时整个程序的可读性就好多了。

下单面板创建

有了子函数我们就可以尝试着去做一个下单的面板了,这对手动交易会比较方便。一般来说我们的面板会做成指标的形式,因为一个图表内EA只能加载一个,而指标可以加载多个。在此由于还没讲指标,所以我们暂时用EA来做一个演示,等到日后我们接触到了指标就可以把面板做成指标的形式了。

我们把按钮和文本框的模块拿过去,然后再做一个创建矩形面板对象的模块,方便我们画矩形面板,这个子函数的代码如下:

void lable(string name,
            int width,
            int height,
            int clr_border,
            int clr_bg,
            int corner,
            int xd,
            int yd,
            bool back)
{
      ObjectCreate(0,name,OBJ_RECTANGLE_LABEL,0,0,0);
      ObjectSetInteger(0,name,OBJPROP_XSIZE,width);
      ObjectSetInteger(0,name,OBJPROP_YSIZE,height);
      ObjectSetInteger(0,name,OBJPROP_BORDER_COLOR,clr_border);
      ObjectSetInteger(0,name,OBJPROP_BGCOLOR,clr_bg);
      ObjectSetInteger(0,name,OBJPROP_CORNER,corner);
      ObjectSetInteger(0,name,OBJPROP_XDISTANCE,xd);
      ObjectSetInteger(0,name,OBJPROP_YDISTANCE,yd);
      ObjectSetInteger(0,name,OBJPROP_BACK,back);
}

有了创建以上三种对象的子函数,我们就可以轻易地创建对象了。首先我们创建一个面板:

int OnInit()
{
ObjectDelete(0, "lable");
lable("lable",180,280,clrDarkViolet,clrLightSlateGray,CORNER_RIGHT_UPPER,
190,10,false);
return(INIT_SUCCEEDED);
}
…………

以上程序中省略的是三个子函数,之所以要在创建之前先用ObjectDelete()函数把对象删除一遍是因为怕对象的名称冲突造成不可预知的问题。我们把lable()子函数的参数一个一个输进去就可以把面板给创建出来了,运行结果如下图:

可以看到我们创建出来了一个银灰色的面板,它离图表的顶部边界距离为10,离右边界的距离也为10,宽度180,高度280。

按钮和文本的创建也十分简单了,参照面板的创建过程即可,大家可以自己练习一下,在此不多讲,完整的代码如下:

int OnInit()
{
ObjectDelete(0,"lable");
ObjectDelete(0,"button");
ObjectDelete(0,"TEXT");
ObjectDelete(0,"button1");
ObjectDelete(0,"TEXT1");
ObjectDelete(0,"button2");
ObjectDelete(0,"TEXT2");
ObjectDelete(0,"button3");
ObjectDelete(0,"TEXT3");
ObjectDelete(0,"button4");
ObjectDelete(0,"button5");
ObjectDelete(0,"button6");
ObjectDelete(0,"TEXT4");
ObjectDelete(0,"button7");
ObjectDelete(0,"button8");
ObjectDelete(0,"button9");
ObjectDelete(0,"button10");
ObjectDelete(0,"button11");
ObjectDelete(0,"button12");

lable("lable",180,280,clrDarkViolet,clrLightSlateGray,CORNER_RIGHT_UPPER,190,
10,false);

button("button1",50,25,clrNONE,clrBlack,clrDeepPink,10,CORNER_RIGHT_UPPER,175,20,"Lot",true);
edittext("TEXT1",100,25,clrBlack,clrBlack,clrWhite,10,CORNER_RIGHT_UPPER,125,20,ALIGN_CENTER,false,"0.01");

button("button2",50,25,clrNONE,clrBlack,clrDeepPink,10,CORNER_RIGHT_UPPER,175, 50,"SL",true);
edittext("TEXT2",100,25,clrBlack,clrBlack,clrWhite,10,CORNER_RIGHT_UPPER,125, 50,ALIGN_CENTER,false,"100");

button("button3",50,25,clrNONE,clrBlack,clrDeepPink,10,CORNER_RIGHT_UPPER,175, 80,"TP",true);
edittext("TEXT3",100,25,clrBlack,clrBlack,clrWhite,10,CORNER_RIGHT_UPPER,125,80,ALIGN_CENTER,false,"100");

button("button4",70,30,clrNONE,clrWhite,clrRed,10,CORNER_RIGHT_UPPER,175, 110,"BUY", false);
button("button5",70,30,clrNONE,clrWhite,clrGreen,10,CORNER_RIGHT_UPPER,95,
110,"SELL", false);
      button("button6",50,25,clrNONE,clrBlack,clrDeepPink,10,CORNER_RIGHT_UPPER,175, 145,"Price",true);
edittext("TEXT4",100,25,clrBlack,clrBlack,clrWhite,10,CORNER_RIGHT_UPPER,125,
145,ALIGN_CENTER,false,"0");

button("button7",70,30,clrNONE,clrWhite,clrRed,10,CORNER_RIGHT_UPPER,175, 175,"BUYLIMIT", false);
button("button8",70,30,clrNONE,clrWhite,clrGreen,10,CORNER_RIGHT_UPPER,95,
175,"SELLLIMIT", false);

button("button9",70,30,clrNONE,clrWhite,clrRed,10,CORNER_RIGHT_UPPER,175, 210,"BUYSTOP", false);
button("button10",70,30,clrNONE,clrWhite,clrGreen,10,CORNER_RIGHT_UPPER,95,
210,"SELLSTOP", false);

button("button11",70,30,clrNONE,clrWhite,clrRed,10,CORNER_RIGHT_UPPER,175, 245," Close", false);
button("button12",70,30,clrNONE,clrWhite,clrGreen,10,CORNER_RIGHT_UPPER,95,
245," Delete", false);
		
return(INIT_SUCCEEDED);
}

void OnDeinit(const int reason)
  {
  }

void button(string name,int width,int height,int clr_border,int clr_text,int clr_bg,
int fontsize,int corner,int xd,int yd,string text)
{
      ObjectCreate(0,name,OBJ_BUTTON,0,0,0);
      ObjectSetInteger(0,name,OBJPROP_BORDER_COLOR, clr_border);
      ObjectSetInteger(0,name,OBJPROP_XSIZE, width);
      ObjectSetInteger(0,name,OBJPROP_YSIZE, height);
      ObjectSetInteger(0,name,OBJPROP_COLOR, clr_text);
      ObjectSetInteger(0,name,OBJPROP_BGCOLOR, clr_bg);
      ObjectSetInteger(0,name,OBJPROP_FONTSIZE, fontsize);
      ObjectSetInteger(0,name,OBJPROP_CORNER, corner);
      ObjectSetInteger(0,name,OBJPROP_XDISTANCE, xd);
      ObjectSetInteger(0,name,OBJPROP_YDISTANCE, yd);
      ObjectSetString(0,name,OBJPROP_TEXT, text); 
}


void edittext(string name,
            int width,
            int height,
            int clr_border,
            int clr_text,
            int clr_bg,
            int fontsize,
            int corner,
            int xd,
            int yd,
            int align,
            int readonly,
            string text)
{
      ObjectCreate(0, name,OBJ_EDIT,0,0,0);
      ObjectSetInteger(0, name,OBJPROP_XSIZE,width);
      ObjectSetInteger(0,name,OBJPROP_YSIZE,height);
      ObjectSetInteger(0,name,OBJPROP_BORDER_COLOR, clr_border);
      ObjectSetInteger(0,name,OBJPROP_COLOR, clr_text);
      ObjectSetInteger(0,name,OBJPROP_BGCOLOR, clr_bg);
      ObjectSetInteger(0,name,OBJPROP_FONTSIZE, fontsize);
      ObjectSetInteger(0,name,OBJPROP_CORNER, corner);
      ObjectSetInteger(0,name,OBJPROP_XDISTANCE, xd);
      ObjectSetInteger(0,name,OBJPROP_YDISTANCE, yd);
      ObjectSetInteger(0,name,OBJPROP_ALIGN, align);
      ObjectSetInteger(0,name,OBJPROP_READONLY, readonly);
      ObjectSetString(0,name,OBJPROP_TEXT, text);
}

void lable(string name,
            int width,
            int height,
            int clr_border,
            int clr_bg,
            int corner,
            int xd,
            int yd,
            bool back)
{
      ObjectCreate(0,name,OBJ_RECTANGLE_LABEL,0,0,0);
      ObjectSetInteger(0,name,OBJPROP_XSIZE,width);
      ObjectSetInteger(0,name,OBJPROP_YSIZE,height);
      ObjectSetInteger(0,name,OBJPROP_BORDER_COLOR,clr_border);
      ObjectSetInteger(0,name,OBJPROP_BGCOLOR,clr_bg);
      ObjectSetInteger(0,name,OBJPROP_CORNER,corner);
      ObjectSetInteger(0,name,OBJPROP_XDISTANCE,xd);
      ObjectSetInteger(0,name,OBJPROP_YDISTANCE,yd);
      ObjectSetInteger(0,name,OBJPROP_BACK,back);
}

运行程序后我们的EA创建出来的面板如图所示:

按钮功能的实现

我们已经把面板的对象都建立好了,那么接下来我们要通过OnChartEvent()来实现按钮的功能,就如上节课那样。

我们先把买单的功能实现,首先我们要识别在BUY这个按钮上的点击事件,然后我们需要识别按钮的状态,如果按钮状态时按下的状态,那么我们就做一个买单,原理非常简单,代码如下:

void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)  
{
      double lot=(double)ObjectGetString(0,"TEXT1",OBJPROP_TEXT,0);
      double price=(double)ObjectGetString(0,"TEXT4",OBJPROP_TEXT,0);
      double sl;
      double tp;
      int check;
      int mag=12345;
      int huadian=10;
      int i;
      if(id==CHARTEVENT_OBJECT_CLICK && sparam=="button4")
      {
         if(ObjectGetInteger(0,"button4",OBJPROP_STATE,0))
         {
sl=MarketInfo(Symbol(),MODE_BID)-(int)ObjectGetString(0,"TEXT2",
OBJPROP_TEXT,0)*MarketInfo(Symbol(),MODE_POINT)*10;
tp=MarketInfo(Symbol(),MODE_BID)+(int)ObjectGetString(0,"TEXT3",
OBJPROP_TEXT,0)*MarketInfo(Symbol(),MODE_POINT)*10;
check=OrderSend(Symbol(),OP_BUY,lot,MarketInfo(Symbol(),MODE_ASK),
huadian,sl,tp,"BUY",mag,0,clrBlue);
         }
         ObjectSetInteger(0,"button4",OBJPROP_STATE,false);
      }
}

以上代码中,我们用ObjectGetString ()函数得到了文本框内的交易手数、止损点数、止盈点数以及挂单的价格,然后我们判断了是否存在Buy按钮的鼠标点击事件,接下来用ObjectGetInteger()函数判断了BUY按钮的按压状态,如果这个按钮时压下去的,那么我们就根据面板中的止损止盈点数来计算止损止盈的价格,最后开单。

我们试一下现在按钮是不是可以用了,按下之后如图所示:

可以看到我们在当前价位开出了一个订单,止损、止盈、手数都对得上,所以程序运行正常。

那么其他的按钮也是照葫芦画瓢,基本类似,只不过挂单需要把文本框里的价格用上,详细的过程就不讲了,完整的代码如下:

int OnInit()
{
ObjectDelete(0,"lable");
ObjectDelete(0,"button");
ObjectDelete(0,"TEXT");
ObjectDelete(0,"button1");
ObjectDelete(0,"TEXT1");
ObjectDelete(0,"button2");
ObjectDelete(0,"TEXT2");
ObjectDelete(0,"button3");
ObjectDelete(0,"TEXT3");
ObjectDelete(0,"button4");
ObjectDelete(0,"button5");
ObjectDelete(0,"button6");
ObjectDelete(0,"TEXT4");
ObjectDelete(0,"button7");
ObjectDelete(0,"button8");
ObjectDelete(0,"button9");
ObjectDelete(0,"button10");
ObjectDelete(0,"button11");
ObjectDelete(0,"button12");

lable("lable",180,280,clrDarkViolet,clrLightSlateGray,CORNER_RIGHT_UPPER,190,
10,false);

button("button1",50,25,clrNONE,clrBlack,clrDeepPink,10,CORNER_RIGHT_UPPER,175,20,"Lot",true);
edittext("TEXT1",100,25,clrBlack,clrBlack,clrWhite,10,CORNER_RIGHT_UPPER,125,20,ALIGN_CENTER,false,"0.01");

button("button2",50,25,clrNONE,clrBlack,clrDeepPink,10,CORNER_RIGHT_UPPER,175, 50,"SL",true);
edittext("TEXT2",100,25,clrBlack,clrBlack,clrWhite,10,CORNER_RIGHT_UPPER,125, 50,ALIGN_CENTER,false,"100");

button("button3",50,25,clrNONE,clrBlack,clrDeepPink,10,CORNER_RIGHT_UPPER,175, 80,"TP",true);
edittext("TEXT3",100,25,clrBlack,clrBlack,clrWhite,10,CORNER_RIGHT_UPPER,125,80,ALIGN_CENTER,false,"100");

button("button4",70,30,clrNONE,clrWhite,clrRed,10,CORNER_RIGHT_UPPER,175, 110,"BUY", false);
button("button5",70,30,clrNONE,clrWhite,clrGreen,10,CORNER_RIGHT_UPPER,95,
110,"SELL", false);
      button("button6",50,25,clrNONE,clrBlack,clrDeepPink,10,CORNER_RIGHT_UPPER,175, 145,"Price",true);
edittext("TEXT4",100,25,clrBlack,clrBlack,clrWhite,10,CORNER_RIGHT_UPPER,125,
145,ALIGN_CENTER,false,"0");

button("button7",70,30,clrNONE,clrWhite,clrRed,10,CORNER_RIGHT_UPPER,175, 175,"BUYLIMIT", false);
button("button8",70,30,clrNONE,clrWhite,clrGreen,10,CORNER_RIGHT_UPPER,95,
175,"SELLLIMIT", false);

button("button9",70,30,clrNONE,clrWhite,clrRed,10,CORNER_RIGHT_UPPER,175, 210,"BUYSTOP", false);
button("button10",70,30,clrNONE,clrWhite,clrGreen,10,CORNER_RIGHT_UPPER,95,
210,"SELLSTOP", false);

button("button11",70,30,clrNONE,clrWhite,clrRed,10,CORNER_RIGHT_UPPER,175, 245," Close", false);
button("button12",70,30,clrNONE,clrWhite,clrGreen,10,CORNER_RIGHT_UPPER,95,
245," Delete", false);
		
return(INIT_SUCCEEDED);
}

void OnDeinit(const int reason)
  {
ObjectDelete(0,"lable");
ObjectDelete(0,"button");
ObjectDelete(0,"TEXT");
ObjectDelete(0,"button1");
ObjectDelete(0,"TEXT1");
ObjectDelete(0,"button2");
ObjectDelete(0,"TEXT2");
ObjectDelete(0,"button3");
ObjectDelete(0,"TEXT3");
ObjectDelete(0,"button4");
ObjectDelete(0,"button5");
ObjectDelete(0,"button6");
ObjectDelete(0,"TEXT4");
ObjectDelete(0,"button7");
ObjectDelete(0,"button8");
ObjectDelete(0,"button9");
ObjectDelete(0,"button10");
ObjectDelete(0,"button11");
ObjectDelete(0,"button12");
  }

void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)  
{
      double lot=(double)ObjectGetString(0,"TEXT1",OBJPROP_TEXT,0);
      double price=(double)ObjectGetString(0,"TEXT4",OBJPROP_TEXT,0);
      double sl;
      double tp;
      int check;
      int mag=12345;
      int huadian=10;
      string sym= Symbol();
      int i;
      if(id==CHARTEVENT_OBJECT_CLICK && sparam=="button4")
      {
	//买单按钮设置
         if(ObjectGetInteger(0,"button4",OBJPROP_STATE,0))
         {
sl=MarketInfo(Symbol(),MODE_BID)-(int)ObjectGetString(0,"TEXT2",
OBJPROP_TEXT,0)*MarketInfo(Symbol(),MODE_POINT)*10;
tp=MarketInfo(Symbol(),MODE_BID)+(int)ObjectGetString(0,"TEXT3",
OBJPROP_TEXT,0)*MarketInfo(Symbol(),MODE_POINT)*10;
check=OrderSend(Symbol(),OP_BUY,lot,MarketInfo(Symbol(),MODE_ASK),
huadian,sl,tp,"BUY",mag,0,clrBlue);
         }
         ObjectSetInteger(0,"button4",OBJPROP_STATE,false);
      }
	//卖单按钮设置
if(id==CHARTEVENT_OBJECT_CLICK && sparam=="button5")
{
if(ObjectGetInteger(0,"button5",OBJPROP_STATE,0))
         {
			sl=MarketInfo(Symbol(),MODE_ASK)+(int)ObjectGetString(0,"TEXT2",
OBJPROP_TEXT,0)*MarketInfo(Symbol(),MODE_POINT)*10;
           	 tp=MarketInfo(Symbol(),MODE_ASK)-(int)ObjectGetString(0,"TEXT3",
OBJPROP_TEXT,0)*MarketInfo(Symbol(),MODE_POINT)*10;
           	 check=OrderSend(sym,OP_SELL,lot,MarketInfo(sym,MODE_BID),
huadian,sl,tp,"SELL",mag,0,clrRed);
         }
         ObjectSetInteger(0,"button5",OBJPROP_STATE,false);
}
//买单限价挂单
      if(id==CHARTEVENT_OBJECT_CLICK && sparam=="button7")
      {
         if(ObjectGetInteger(0,"button7",OBJPROP_STATE,0)==true && 
	price<MarketInfo(Symbol(),MODE_ASK))
         {
            sl=price-(int)ObjectGetString(0,"TEXT2",OBJPROP_TEXT,0)*
MarketInfo(Symbol(),MODE_POINT)*10;
  tp=price+(int)ObjectGetString(0,"TEXT3",OBJPROP_TEXT,0)*
MarketInfo(Symbol(),MODE_POINT)*10;
           check=OrderSend(sym,OP_BUYLIMIT,lot,price,huadian,sl,tp,"BUY",mag,0,clrBlue);
         }
         ObjectSetInteger(0,"button7",OBJPROP_STATE,false);
      }
//卖单限价挂单
      if(id==CHARTEVENT_OBJECT_CLICK && sparam=="button8")
      {
         if(ObjectGetInteger(0,"button8",OBJPROP_STATE,0)==true && 
	price>MarketInfo(Symbol(),MODE_BID))
         {
            sl=price+(int)ObjectGetString(0,"TEXT2",OBJPROP_TEXT,0)*
MarketInfo(Symbol(),MODE_POINT)*10;
  tp=price-(int)ObjectGetString(0,"TEXT3",OBJPROP_TEXT,0)*
MarketInfo(Symbol(),MODE_POINT)*10;
           check=OrderSend(sym,OP_SELLLIMIT,lot,price,huadian,sl,tp,"SELL",mag,0,clrRed);
         }
         ObjectSetInteger(0,"button8",OBJPROP_STATE,false);
      }
//买单止损挂单
      if(id==CHARTEVENT_OBJECT_CLICK && sparam=="button9")
      {
         if(ObjectGetInteger(0,"button9",OBJPROP_STATE,0)==true && 
	price>MarketInfo(Symbol(),MODE_ASK))
         {
            sl=price-(int)ObjectGetString(0,"TEXT2",OBJPROP_TEXT,0)*
MarketInfo(Symbol(),MODE_POINT)*10;
  tp=price+(int)ObjectGetString(0,"TEXT3",OBJPROP_TEXT,0)*
MarketInfo(Symbol(),MODE_POINT)*10;
           check=OrderSend(sym,OP_BUYSTOP,lot,price,huadian,sl,tp,"BUY",mag,0,clrBlue);
         }
         ObjectSetInteger(0,"button9",OBJPROP_STATE,false);
      }
//卖单止损挂单
      if(id==CHARTEVENT_OBJECT_CLICK && sparam=="button10")
      {
         if(ObjectGetInteger(0,"button10",OBJPROP_STATE,0)==true && 
	price<MarketInfo(Symbol(),MODE_BID))
         {
            sl=price+(int)ObjectGetString(0,"TEXT2",OBJPROP_TEXT,0)*
MarketInfo(Symbol(),MODE_POINT)*10;
  tp=price-(int)ObjectGetString(0,"TEXT3",OBJPROP_TEXT,0)*
MarketInfo(Symbol(),MODE_POINT)*10;
           check=OrderSend(sym,OP_SELLSTOP,lot,price,huadian,sl,tp,"SELL",mag,0,clrRed);
         }
         ObjectSetInteger(0,"button10",OBJPROP_STATE,false);
      }
//平仓
      if(id==CHARTEVENT_OBJECT_CLICK && sparam=="button11")
      {
         if(ObjectGetInteger(0,"button11",OBJPROP_STATE,0)==true)
         {
            for(i=OrdersTotal()-1;i>=0;i--)
            {
               if(OrderSelect(i,SELECT_BY_POS))
               {
                  if(OrderSymbol()==sym && OrderMagicNumber()==mag)
                  {
                     if(OrderType()==OP_SELL)
                     {
check=OrderClose(OrderTicket(),OrderLots(),
MarketInfo(sym,MODE_ASK),huadian);
                     }
                     else if(OrderType()==OP_BUY)
                     {
check=OrderClose(OrderTicket(),OrderLots(),
MarketInfo(sym,MODE_BID),huadian);
                     }
                  }
               }
            }
         }
         ObjectSetInteger(0,"button11",OBJPROP_STATE,false);
      }
//删除挂单
      if(id==CHARTEVENT_OBJECT_CLICK && sparam=="button12")
      {
         if(ObjectGetInteger(0,"button12",OBJPROP_STATE,0)==true)
         {
            for(i=OrdersTotal()-1;i>=0;i--)
            {
               if(OrderSelect(i,SELECT_BY_POS))
               {
                  if(OrderSymbol()==sym && OrderMagicNumber()==mag)
                  {
                     if(OrderType()==OP_SELLLIMIT || OrderType()==OP_BUYLIMIT ||
OrderType()==OP_BUYSTOP || OrderType()==OP_SELLSTOP)
                     {
                        check=OrderDelete(OrderTicket(),clrRed);
                     }
                  }
               }
            }
         }
         ObjectSetInteger(0,"button12",OBJPROP_STATE,false);
      }
}
	
void button(string name,int width,int height,int clr_border,int clr_text,int clr_bg,
int fontsize,int corner,int xd,int yd,string text, bool select)
{
      ObjectCreate(0,name,OBJ_BUTTON,0,0,0);
      ObjectSetInteger(0,name,OBJPROP_BORDER_COLOR, clr_border);
      ObjectSetInteger(0,name,OBJPROP_XSIZE, width);
      ObjectSetInteger(0,name,OBJPROP_YSIZE, height);
      ObjectSetInteger(0,name,OBJPROP_COLOR, clr_text);
      ObjectSetInteger(0,name,OBJPROP_BGCOLOR, clr_bg);
      ObjectSetInteger(0,name,OBJPROP_FONTSIZE, fontsize);
      ObjectSetInteger(0,name,OBJPROP_CORNER, corner);
      ObjectSetInteger(0,name,OBJPROP_XDISTANCE, xd);
      ObjectSetInteger(0,name,OBJPROP_YDISTANCE, yd);
      ObjectSetString(0,name,OBJPROP_TEXT, text); 
      ObjectSetInteger(0,name, OBJPROP_SELECTABLE, select);
}

void edittext(string name,
            int width,
            int height,
            int clr_border,
            int clr_text,
            int clr_bg,
            int fontsize,
            int corner,
            int xd,
            int yd,
            int align,
            int readonly,
            string text)
{
      ObjectCreate(0, name,OBJ_EDIT,0,0,0);
      ObjectSetInteger(0, name,OBJPROP_XSIZE,width);
      ObjectSetInteger(0,name,OBJPROP_YSIZE,height);
      ObjectSetInteger(0,name,OBJPROP_BORDER_COLOR, clr_border);
      ObjectSetInteger(0,name,OBJPROP_COLOR, clr_text);
      ObjectSetInteger(0,name,OBJPROP_BGCOLOR, clr_bg);
      ObjectSetInteger(0,name,OBJPROP_FONTSIZE, fontsize);
      ObjectSetInteger(0,name,OBJPROP_CORNER, corner);
      ObjectSetInteger(0,name,OBJPROP_XDISTANCE, xd);
      ObjectSetInteger(0,name,OBJPROP_YDISTANCE, yd);
      ObjectSetInteger(0,name,OBJPROP_ALIGN, align);
      ObjectSetInteger(0,name,OBJPROP_READONLY, readonly);
      ObjectSetString(0,name,OBJPROP_TEXT, text);
}

void lable(string name,
            int width,
            int height,
            int clr_border,
            int clr_bg,
            int corner,
            int xd,
            int yd,
            bool back)
{
      ObjectCreate(0,name,OBJ_RECTANGLE_LABEL,0,0,0);
      ObjectSetInteger(0,name,OBJPROP_XSIZE,width);
      ObjectSetInteger(0,name,OBJPROP_YSIZE,height);
      ObjectSetInteger(0,name,OBJPROP_BORDER_COLOR,clr_border);
      ObjectSetInteger(0,name,OBJPROP_BGCOLOR,clr_bg);
      ObjectSetInteger(0,name,OBJPROP_CORNER,corner);
      ObjectSetInteger(0,name,OBJPROP_XDISTANCE,xd);
      ObjectSetInteger(0,name,OBJPROP_YDISTANCE,yd);
      ObjectSetInteger(0,name,OBJPROP_BACK,back);
}

之前也说了,其实面板的编写应该放到指标里,但是之前我们没有学指标,所以我们用EA来做一下,原理是一样的。那么后面的课程,我们将学习一下指标的编写,至于本节课写的面板,在学完指标后大家可以自己试着把内容写到指标里面去。那么下节课见。