[转载]通达信插件选股(基于通达信插件编程规范的简单分析)

[转载]通达信插件选股(基于通达信插件编程规范的简单分析)

原文地址:通达信插件选股(基于通达信插件编程规范的简单分析)作者:哈尔滨猫猫

首先声明,鄙人是编程人员,不是股民。对选股概念了解甚少。本文仅作编程人员学习借鉴之用。不对选股理论进行探讨和解释。

以前有客户找我做过通达信插件选股的小任务,当时第一次接触面向接口(此类“接口”)编程,也是第一次接触到股票里相关的概念。最近由于接手一个任务,与上次开发相类似,故旧事重提,仔细研究一番。将个人学习研究所得知识与大家分享。在网上搜相关资料,可用的、有价值的甚少。希望此文能给将要研究通达信插件选股的编程人员一点点帮助。

编程环境:Viusal Studio 2010

证券终端:广发证券至强版v6.06

一、首先说一下在VS2010下,调试DLL的方法:

1,将Debug目录下的dll(例如:MyPlugin.dll)文件复制到通达信根目录下的plugin文件夹下,此步骤可以手动,不过既然是开发程序,肯定要调试N遍,会输出N次dll文件,我们可以在VS写个后期生成事件,例如:copy "C:Documents and SettingsAdministrator桌面choice2Debugchoice2.dll" D:通达信pluginchoice2.dll。此步设置如下图。

2,设置附加进程所在目录,如下图。

经过以上设置,即可调试我们开发的dll,监视变量的值。编译成功后,设置断点,启动调试,然后操作通达信进行选股,选股开始即会跳到VS调试界面。

二、通达信官方提供的插件选股例子解析。(网上可以下载到)
    接口文档里,已经清楚的写出了接口函数的相关说明。但是某些概念依然模糊,说一下我的理解。

1,必须足够了解的几个导出函数:

RegisterDataInterface  注册回调函数,也就是PDATAIOFUNC,这个回调函数用来申请历史数据

GetCopyRightInfo       填写插件信息的函数,很easy

InputInfoThenCalc1     默认调用此函数,使用全部本地历史数据

InputInfoThenCalc2     指定日期段的时候,调用此函数进行选股

2,必须足够清楚的内容:

示例程序里的m_pfn(Code,nSetCode,DataType,pHisDat,nDataNum,tmpTime,tmpTime,nTQ,0)函数,其中非常重要的参数是DataType,pHisDat,nDataNum。分别表示:想要申请的数据类型,数据存储缓冲区(内存),想要获取数据的个数上限(实际上得到的很可能没有那么多),此函数的返回值就是实际上获取到的数据个数。

InputInfoThenCalc1(char * Code,short nSetCode,int Value[4],short DataType,short nDataNum,BYTE nTQ,unsigned long unused)    以下讲解中,以全部本地历史数据为例,即选股调用此函数

InputInfoThenCalc2(char * Code,short nSetCode,int Value[4],short DataType,NTime time1,NTime time2,BYTE nTQ,unsigned long unused)

通过下断点监视,得到结论:1.插件选股过程,针对每支股票调用一次InputInfoThenCalc1函数,如果返回值为TRUE,表示该股票被选中,反之,不被选中。2.插件选股最多支持四个参数,四个参数的值,在插件的代码里用Value[4]来存储。3.当我用日线数据获取数据时,nDataNum被赋值为2000,这个数据个数上限,基本足够我们编写简单的选股程序所用。

三、选出涨幅大于指定值的股票例子

BOOL InputInfoThenCalc1(char * Code,short nSetCode,int Value[4],short DataType,short nDataNum,BYTE nTQ,unsigned long unused) //按最近数据计算
{
 BOOL nRet = FALSE;
 NTime tmpTime;
 memset(&tmpTime,0,sizeof(NTime));  //时间结构置为0,获取全部本地历史数据

LPREPORTDAT pReport = new REPORTDAT;
 if(m_pfn(Code,nSetCode,REPORT_DAT,pReport,1,tmpTime,tmpTime,0,0) == 1)
 {
  if(pReport->Close > 0.001 && (100*(pReport->Now-pReport->Close)/pReport->Close) > Value[0])
   nRet = TRUE;
 }
 delete pReport;
 return nRet;
}

特别注意:计算涨幅时,要使用行情数据,所以将数据类型指定为REPORT_DAT,返回数据个数上限指定为1即可,因为我们只用当前的数据就够了。涨幅的计算公式,百度一堆一堆。相对来说,这个是最简单的。很容易理解。

四、选出换手率在指定范围之内的股票

BOOL InputInfoThenCalc1(char * Code,short nSetCode,int Value[4],short DataType,short nDataNum,BYTE nTQ,unsigned long unused) //按最近数据计算
{
 BOOL nRet = FALSE;
 NTime tmpTime;
 memset(&tmpTime,0,sizeof(NTime));
 LPREPORTDAT pReport = new REPORTDAT;
 long readnum = m_pfn(Code,nSetCode,REPORT_DAT,pReport,1,tmpTime,tmpTime,0,0);
 LPSTOCKINFO pStockInfo = new STOCKINFO;
 long readnum1 = m_pfn(Code,nSetCode,STKINFO_DAT,pStockInfo,1,tmpTime,tmpTime,0,0);
 float HuanShou = ( pReport->Volume / pStockInfo->ActiveCapital ) * 10000;

if( HuanShou > Value[0] && HuanShou < Value[1] )
 {
  nRet = TRUE;
 }
 //delete pReportDat;
 delete pStockInfo;
 delete pReport;
 return nRet;
}

换手率=某一段时期内的成交量/发行总股数×100% (在我国:成交量/流通总股数×100%)(引用百度百科)

按照上面的公式来计算,然后根据我们需要的小数点位置来计算扩大或缩小的比例即可。同上例,我们一定要注意我们想要的数据,要指定的数据类型。计算换手率,需要成交量和总股数两个数据,成交量使用当前的值,所以我们获取一个当前的即可,数据类型指定为REPORT_DAT行情数据;总股数我并不知道是属于哪个数据类型的,一遍一遍尝试改变数据类型之后,终于得到了一个准确的值,此时,数据类型指定为STKINFO_DAT。(有时候,我们对几种可能不是很了解的时候,可以一个一个去尝试,前提是,我们要知道正确的结果是什么样的。一个办法就是,先记录下通达信界面上显示的该数据的值)。

本来是打算顺便计算一下量比数据的,也指定个范围进行选股。经过尝试后,发现通达信的接口貌似有问题。获取成交量的时候,只能利用行情数据来获取当前的成交量,无法获取历史成交量。查阅资料:量比=现成交总手/〖(过去5个交易日平均每分钟成交量)×当日累计开市时间(分)〗。(摘自百度百科)按照以上公式,我们需要获取到今日止连续6天的成交量。所以得到如下代码:

LPREPORTDAT pReportDat = new REPORTDAT[nDataNum];
 long readnum2 = m_pfn(Code,nSetCode,DataType,pReportDat,nDataNum,tmpTime,tmpTime,0,0);
 float * VolPoint= new float[readnum2];
 for(int i=0;i < readnum2;i++)
 {
  VolPoint[i]=pReportDat[i].Volume;
 }
 float VolPerDay = VolPoint[readnum2-2]+VolPoint[readnum2-3]+VolPoint[readnum2-4]+VolPoint[readnum2-5]+VolPoint[readnum2-6];
 float liangbi = VolPoint[readnum2-1] / (VolPerDay/5);

仔细分析,也许您会发现,代码表达的意思,并不是查阅资料所给出的公式。是的,如果按照公式来算,我们应该得到每天的,每分钟的成交量数据,才能算出分钟平均值。这样的情况,我们就不能使用日线数据。就需要下载分时图数据,按照标准的公式计算,保证您不会出错。但是这里,我仔细观察计算得到,以上代码计算方法得到的数据和通达信界面上显示的量比是相吻合的。

重点指出:以上计算量比的代码,并不能正常工作。因为历史成交量无法获取,我尝试过各种数据类型。当我获取历史成交量时,Volume字段的值都是莫名其妙的数字。但是更奇怪的是,其他字段的值都正常。琢磨了好久,去了通达信官网论坛,发现一个帖子和我所遇到的问题一样。帖子地址http://tdx.com.cn/dispbbs.asp?boardid=15&Id=173264  尝试过各种结构体和数据类型组合后。我觉得以上求量比的代码应该没有问题。结果如下图所示:


在这种情况下,勉强利用了行情数据得到了当前成交量,才得以计算出换手率。

五、计算CLOSE的EMA进行选股

//选股函数,参照官方例子程序+百度EMA算法得出如下代码

BOOL InputInfoThenCalc1(char * Code,short nSetCode,int Value[4],short DataType,short nDataNum,BYTE nTQ,unsigned long unused) //按最近数据计算
{
 BOOL nRet = FALSE;
 NTime tmpTime={0};

LPHISDAT pHisDat = new HISDAT[nDataNum];  //数据缓冲区
 long readnum = m_pfn(Code,nSetCode,DataType,pHisDat,nDataNum,tmpTime,tmpTime,nTQ,0);  //利用回调函数申请数据,返回得到的数据个数
 
 if( readnum > max(Value[0],Value[1]) )
 {
  float *pMa1 = new float[readnum];
  float *pMa2 = new float[readnum];
  for(int i=0;i < readnum;i++)
  {
   pMa1[i] = pHisDat[i].Close;
   pMa2[i] = pHisDat[i].Close;
  }
  float *EmaPoint1 = new float[readnum-Value[0]+1];
  float *EmaPoint2 = new float[readnum-Value[1]+1];
  memset( EmaPoint1 , 0 , readnum-Value[0]+1 );
  memset( EmaPoint2 , 0 , readnum-Value[1]+1 );
  AfxCalcEma( pMa1 , readnum , Value[0] , EmaPoint1);
  AfxCalcEma( pMa2 , readnum , Value[1] , EmaPoint2);
  if( AfxCross( EmaPoint1 , readnum-Value[0]+1 , EmaPoint2 , readnum-Value[1]+1 , Value[2] ) == 1 )
  {
   nRet = TRUE;
  }
  delete []EmaPoint1;EmaPoint1=NULL;
  delete []EmaPoint2;EmaPoint2=NULL;
  delete []pMa1;pMa1=NULL;
  delete []pMa2;pMa2=NULL;
 }
 delete []pHisDat;pHisDat=NULL;
 return nRet;
}
//计算CLOSE的EMA函数实现如下

void AfxCalcEma(float *pData , int nDataNum , int nDays , float *EmaPoint)
{
 int nSumOfDays = 0;
 int flag = 0;
 int iCount =0;
 for(iCount=nDays;iCount>0;iCount--)
 {
  nSumOfDays+=iCount;
 }
 for(iCount=nDays;iCount>0;iCount--)
 {
  float temp = (iCount/(float)nSumOfDays)*pData[iCount-1];
  EmaPoint[0] += temp;
 }
 for(iCount = 1 , flag = nDays; iCount<nDataNum-nDays+1; iCount++ , flag++)
 {
  EmaPoint[iCount] = (2*pData[flag]+(nDays-1)*EmaPoint[iCount-1])/(nDays+1);
 }
}

//计算指定之间范围内,短线是否从下方穿越长线

int AfxCross( float *pMaPoint1 , int DataNum1 , float *pMaPoint2 , int DataNum2 , int nDaysNum )
{
 int flag1 = DataNum1-1;
 int flag2 = DataNum2-1;
 if( pMaPoint1[flag1] > pMaPoint2[flag2] )
 {
  flag1--;
  flag2--;
  for(int iCount = nDaysNum; iCount>0; iCount--)
  {
   if( pMaPoint1[flag1] < pMaPoint2[flag2] )
   {
    return 1;
    break;
   }
   else
   {
    flag1--;
    flag2--;
   }
  }
 }
 else
 {
  return 0;
 }
}

此例相对比较复杂,不过复杂的地方是算法部分,并不是程序技术,主要是数学方面的知识。您有好的选股理念,在某种情况下,是可以用通达信插件选股的方式实现的。

结束语:谨以此文,献给打算研究、正在研究和曾经研究过通达信插件选股的朋友们。这只是编程里的冰山一角。希望我们都能做一个优秀的开发人员,编写出高质量的程序。处女作,大家多多批评指正。

时间: 2024-12-28 08:59:11

[转载]通达信插件选股(基于通达信插件编程规范的简单分析)的相关文章

(HTTP)金牌信通V8-生意虎信验证码插件

金牌信通V8-生意虎信验证码插件 (HTTP) 客户接口说明 1 第一章  发送接口 2 1.1 请求地址 2 1.2参数说明 2 1.3返回值 2 第二章 余额及已发送量查询接口 3 2.1 请求地址 3 2.2参数说明 3 2.3返回值 3 第三章 非法关键词查询 4 3.1 请求地址 4 3.2参数说明 4 3.3返回值 4 第四章 状态报告接口 5 4.1 请求地址 5 4.2参数说明 5 4.3返回值 5 4.4错误返回值--状态报告请求错误返回格式及对应值 6 第五章 上行接口 6

【插件分享】 短信如何对接SHOPSN_V2.2.5验证码功能

在互亿无线短信平台找到一个插件,在这边分享一下,有需要可以了解,比自己开发要容易很多哦.http://www.ihuyi.com/ 插件说明本插件系互亿无线针对SHOPSN_V2.2.5开源商城短信插件开发,插件内的所有文件均为对原文件的修改,如果你的系统经过二次开发,安装本插件之前,请仔细核对修改. 功能介绍1.用户注册验证2.找回密码3.绑定手机4.修改密码5.登录验证6.订单发货提示7.余额支付提示 安装步骤1:本插件针对SHOPSN_V2.2.5开源商城开发,安装前请仔细核对你的系统版本

阿里云短信验证_基于阿里云OpenAPI实现

阿里云短信服务 背景简介: 短信验证以及短信通知,目前已经应用的非常广泛,最近因项目需要,需要将原来的短信接口换成阿里云的的短信服务,原项目集成的短信服务能够实现短信的发送以及短信的验证整个过程,简单的来说,原来的短息服务,只需应用申请获取短信,短息服务器会发送短信到指定的手机,用户将验证码发送到短信服务商的服务器,服务器做出验证返回是否通过,而阿里云仅提供短信发送服务,需要自己开发短信的验证.下面简单的介绍一下: 1.获取阿里云AccessKey 用户->Accesskeys:需要自己创建一个

信析宝智能短信是什么 智能短信成互联网新的场景流量入口

信析宝是直接纳入手机系统的SDK 产品,可以改造手机自带短信 信析宝是一套基于语义识别技术的场景化构建平台,该平台由语义解析引擎,场景构建引擎,算法生成引擎和云端运营平台组成. 信析宝以SDK的方式输出语义解析和场景构建服务,能将接收到的文字形态的企业短信.IM消息.邮件等信息进行智能识别,生成结构化数据,并为之匹配相应的场景,让阅读和处理信息变得更高效,给用户更好的应用体验. 信析宝目前主要应用在手机系统原生的短信.IM社交软件.邮件.手机桌面上,将传统的短信.邮件的内容进行智能识别,并根据内

智能短信服务授权 信析宝智能短信是否收费

智能短信是移动互联网新的智能化服务分发及场景化流量入口 智能短信是在移动终端设备上搭载信析宝应用程序和能力,将传统文本短信解析重构成卡片式短信,可实现双向交互,提供生活场景服务的新一代短信产品. 它包含短信公众号.卡片短信.短信浮窗.短信通知栏.短信浮窗.短信卡夹.短信分类.智能穿戴方案等产品形态. 珠海市小源科技有限公司 智能短信概念提出者与先行者 珠海市小源科技有限公司(以下简称小源科技)成立于2011年,是一家专注于移动互联网领域产品研发和运营的创业公司.公司总部位于珠海,分别在北京和深圳

多口8口16口短信猫池设备与短信猫开发包

多口短信猫池是指集成了8路或16口等多短信通讯模块的短信猫设备,要支持短信猫池二次开发需要相应的短信猫开发包支持,在这里推荐给大家:企业短信平台8.2 支持单口短信猫.8口短信猫和16口短信猫池全系列短信猫设备(GSM短信猫和CDMA短信猫.GPRS短信猫等) 多口8口16口短信猫池设备实物如图: 多口8口16口短信猫池设备所采用的短信猫开发包与普通单口GSM短信猫开发包不所不同,需要相应的短信猫开发包支持多口短信猫池设备才可以,给大家推荐:企业短信平台8.2 此款短信猫开发包基于系统数据库的开

在VC6中基于dll开发插件用于各种图片显示(BMP/TGA/JPG/GIF/PNG/TIF/ICO/WMF/EMF/...)

一.图片显示 图片显示的方法: 1.  直接写程序 2.  第3方库 3.  调用COM组件的IPicture接口 4.  使用MFC的CPictureHolder类 5.  使用GDI+的CImage类(VC6无,从VS2003开始有) 测试过的方法有1.3.5. 测试过的格式有BMP/TGA/JPG/GIF/PNG/TIF/ICO/WMF/EMF. IPicture接口不支持的格式有:PNG和TIF. GDI+支持全部格式. 二.插件的实现(VC6) 只做了基于DLL的插件实现试验,基于“公

基于AppDomain的&quot;插件式&quot;开发

很多时候,我们都想使用(开发)USB式(热插拔)的应用,例如,开发一个WinForm应用,并且这个WinForm应用能允许开发人员定制扩展插件,又例如,我们可能维护着一个WinService管理系统,这个WinService系统管理的形形色色各种各样的服务,这些服务也是各个"插件式"的类库,例如: public interface IJob { void Run(DateTime time); } public class CollectUserInfo : IJob { public

基于JQuery.timer插件实现一个计时器

基于JQuery.timer插件实现一个计时器,需要的朋友可以参考下. 先去官网下载jQuery Timers插件 ,然后引用到html中.这里是1.2 version 复制代码代码如下: <script src="../Javascripts/Plugins/jquery.timers-1.2.js" type="text/javascript"></script> 然后是HTML,我们可以放一个hidden 的server control