欢迎光临散文网 会员登陆 & 注册

量化交易软件:如何分析图表中所选择信号的交易

2023-07-18 15:36 作者:bili_45793681098  | 我要投稿

概述

新信号,免费或付费,会永久性地出现在信号 服务中。 赫兹量化团队注意到可以在不退出终端的情况下使用该服务。 所有剩余的工作就是选择可接受风险范围能够产生最高利润的信号。 很久以前就讨论过这个问题。 曾提出过通过指定标准 [1] 自动选择信号的方法。 然而,传统观点认为一张图片胜过千言万语。 在本文中,我提议研究和分析品种图表中所选信号的交易历史。 或许,这种方法可以令我们更好地理解交易策略和风险评估。

编辑切换为居中

1. 为我们未来的工作设定目标

我好像听到您难过了: '如果终端已经提供了在图表中显示交易历史的能力,为什么还要重新创建轮子呢? 我的意思是,只需按下终端中的按钮即可选择所需的信号。'


编辑

在此之后,根据所使用品种信号的数量,在终端中打开新窗口,并在交易上做出标记。 当然,分页图表以及在其中搜索交易是相当费力的活动。 甚或,在不同图表中进行的交易可能会在时间上重合,且在分别分析每个图表时您无法看到。 在此阶段,我赫兹量化们将尝试将我们的部分工作自动化。

为了辨别我们从图表获得的所需分析的品种,我们必须清晰地了解我们需要的最终结果。 以下是我最终想要的基本项目:

  • 查看信号在不同品种上的均匀性如何;

  • 了解如何分配资金的负荷,以及同时可开仓数量;

  • 如果信号同时开多笔仓位,那么它们是否为对冲,亦或增加了资金的负荷;

  • 在什么时刻以及在哪些品种上出现了最大的缩水; 以及

  • 在什么时刻实现最大的盈利。

2. 收集交易统计数据

2.1. 用于保存订单信息的类

因此,我赫兹量化们选择所需的信号并在图表中显示其交易历史。 然后收集我们将要分析的初始数据。 为了记录每笔订单的信息,我们基于 CObject 类创建 COrder 类。 在这个类的变量中,我们保存订单号,交易类型和手数,交易价格,操作类型 (入场/出场),订单开仓时间,当然还有品名。

class COrder : public CObject  { private:   long                 l_Ticket;   double               d_Lot;   double               d_Price;   ENUM_POSITION_TYPE   e_Type;   ENUM_DEAL_ENTRY      e_Entry;   datetime             dt_OrderTime;   string               s_Symbol;   public:                        COrder();                       ~COrder();   bool                 Create(string symbol, long ticket, double volume, double price, datetime time, ENUM_POSITION_TYPE type); //---   string               Symbol(void)   const {  return s_Symbol;     }   long                 Ticket(void)   const {  return l_Ticket;     }   double               Volume(void)   const {  return d_Lot;        }   double               Price(void)    const {  return d_Price;      }   datetime             Time(void)     const {  return dt_OrderTime; }   ENUM_POSITION_TYPE   Type(void)           {  return e_Type;       }   ENUM_DEAL_ENTRY      DealEntry(void)const {  return e_Entry;      }   void                 DealEntry(ENUM_DEAL_ENTRY value) {  e_Entry=value; } //--- 操纵文件的方法   virtual bool         Save(const int file_handle);   virtual bool         Load(const int file_handle); //---   //--- 比较对象的方法   virtual int          Compare(const CObject *node,const int mode=0) const;  };

伴随数据访问函数,我们向订单类添加了操纵文件函数以便保存和随后读取数据,还有比较类似的函数,因为我们将需要对订单进行排序。

为了与订单进行比较,我赫兹量化们需要重新编写虚函数 Compare。 这是基类的函数,用于比较 CObject 对象。 所以,对象 CObject 的链接和排序方法将作为参数传递给它。 我们仅在一个方向上对订单进行排序,即按照执行日期升序,因此我们不会在函数代码中使用参数 "mode"。 但是,对于通过链接获得的对象 COrder,我们必须首先将其降低到相关类型。 之后,我们比较所获订单的日期和当前订单的日期。 如果所获订单更老,则返回 "-1"。 如果它比较新, 则返回 "1"。 如果执行订单的日期相等,则函数将返回 "0"。

int COrder::Compare(const CObject *node,const int mode=0) const  {   const COrder *temp=GetPointer(node);   if(temp.Time()>dt_OrderTime)      return -1; //---   if(temp.Time()<dt_OrderTime)      return 1; //---   return 0;  }

2.2. 从图表中收集信息

为了处理订单,我们基于 CArrayObj 类创建 COrdersCollection 类。 将在其中收集和处理信息。 为了存储数据,我们将声明一个对象实例直接处理特定订单,以及一个用于存储所用品种列表的数组。 我们将使用基类函数存储订单数组。

class COrdersCollection : public CArrayObj  { private:   COrder            *Temp;   string            ar_Symbols[];   public:                     COrdersCollection();                    ~COrdersCollection(); //--- 初始化   bool              Create(void); //--- 加入一笔订单   bool              Add(COrder *element); //--- 访问数据   int               Symbols(string &array[]);   bool              GetPosition(const string symbol, const datetime time, double &volume, double &price, ENUM_POSITION_TYPE &type);   datetime          FirstOrder(const string symbol=NULL);   datetime          LastOrder(const string symbol=NULL); //--- 获取时间序列   bool              GetTimeSeries(const string symbol, const datetime start_time, const datetime end_time, const int direct,                                   double &balance[], double &equity[], double &time[], double &profit, double &loss,int &long_trades, int &short_trades); //---   void              SetDealsEntry(void);  };

函数 'Create' 直接负责收集数据。 在方法实体内,我们将安排一个循环来搜索终端中已打开的所有图表。 我们将在每个图表中搜索 OBJ_ARROW_BUY 和 OBJ_ARROW_SELL 等图形对象。

bool COrdersCollection::Create(void)  {   long chart=ChartFirst();   while(chart>0)     {      int total_buy=ObjectsTotal(chart,0,OBJ_ARROW_BUY);      int total_sell=ObjectsTotal(chart,0,OBJ_ARROW_SELL);      if((total_buy+total_sell)<=0)        {         chart=ChartNext(chart);         continue;        }

如果在图表中找到了对象,那么我赫兹量化们将图表品种添加到品种数组中 (不过,我们会预先检查这些品种是否不在已保存的品种中)。

     int symb=ArraySize(ar_Symbols);      string symbol=ChartSymbol(chart);      bool found=false;      for(int i=0;(i<symb && !found);i++)         if(ar_Symbols[i]==symbol)           {            found=true;            symb=i;            break;           }      if(!found)        {         if(ArrayResize(ar_Symbols,symb+1,10)<=0)            return false;         ar_Symbols[symb]=symbol;        }

然后我们安排从图表中收集交易信息,并存储到数据数组。 注意: 图形对象是我们唯一的交易信息来源。 从对象参数里,我们只能得到交易的时间和价格。 我们必须从对象名称的文本字符串中获取所有其它详细信息。


编辑


在图片中,您可以看到对象名称包含交易中的所有数据,以空格分隔。 我们利用这点并将字符串用空格切分成一个字符串元素数组。 然后,我赫兹量化们从相关元素中减少信息量,并保存所需的数据类型。 收集信息后,我们转到下一个图表。

     int total=fmax(total_buy,total_sell);      for(int i=0;i<total;i++)        {         if(i<total_buy)           {            string name=ObjectName(chart,i,0,OBJ_ARROW_BUY);            datetime time=(datetime)ObjectGetInteger(chart,name,OBJPROP_TIME);            StringTrimLeft(name);            StringTrimRight(name);            StringReplace(name,"#","");            string split[];            StringSplit(name,' ',split);            Temp=new COrder;            if(CheckPointer(Temp)!=POINTER_INVALID)              {               if(Temp.Create(ar_Symbols[symb],StringToInteger(split[1]),StringToDouble(split[3]),StringToDouble(split[6]),time,POSITION_TYPE_BUY))                  Add(Temp);              }           } //---         if(i<total_sell)           {            string name=ObjectName(chart,i,0,OBJ_ARROW_SELL);            datetime time=(datetime)ObjectGetInteger(chart,name,OBJPROP_TIME);            StringTrimLeft(name);            StringTrimRight(name);            StringReplace(name,"#","");            string split[];            StringSplit(name,' ',split);            Temp=new COrder;            if(CheckPointer(Temp)!=POINTER_INVALID)              {               if(Temp.Create(ar_Symbols[symb],StringToInteger(split[1]),StringToDouble(split[3]),StringToDouble(split[6]),time,POSITION_TYPE_SELL))                  Add(Temp);              }           }        }      chart=ChartNext(chart);     }

图形标记没有每笔交易是开仓还是平仓的信息。 这就是为什么在保存交易信息时此字段仍未填写的原因。 现在,从图表中收集了所有标记后,赫兹量化调用函数 SetDealsEntry 来添加缺失的数据。

  SetDealsEntry();


量化交易软件:如何分析图表中所选择信号的交易的评论 (共 条)

分享到微博请遵守国家法律