QT实现简易ctp程序

1.开发环境

  qt5.9.9 msvc2017环境(mingw不能运行) 以及自带的Qt Creator,上期提供的穿透式api,并且导入qcustomplot库以实现图表效果。

  本程序借鉴了b站视频:BV1ET4y1L7iN。

2.效果展示

 

 

  实现了行情,委托,成交,持仓,合约,等表的展示,以及用户的登录和下单等操作。注:登录部分数据固定,可以自行拓展,可以通过下载快期交易平台来查看自己的下单等操作。程序运行后,当行情表没有数据,请使用另一个可以使用的端口登录本程序(在快期交易平台可以查看)。

3.代码简介

   引用:综合交易平台(Comprehensive Transaction Platform,CTP)是专门为期货公司开发的一套期货经纪业务管理系统,由交易、风险控制和结算三大系统组成。导入上期提供的api接口后,分别对行情,委托,成交,持仓,合约来进行实现。

CTP 的所有接口都分为 Spi 和 Api 两种,这里对其简单说明

扫描二维码关注公众号,回复: 17210283 查看本文章

API:Api 类提供了交易/行情的各种功能,但这些需要我们主动对服务器发出的请求

SPI:Spi 类提供了交易/行情相关的回调接口,我们需要继承该类并重载这些接口,以获取响应数据。

  api可以理解为是上期为我们提供的已经封装好的一类函数,我们只需直接调用这些函数,大部分无需重写,即可使用该函数功能,而spi体现了一种回调的思想,当我们的api调用后,spi会返回一些东西,我们可以通过这些返回值来判断api执行是否正常。

  举个例子,当我们需要登录行情的时候,我们需要使用RspUserLogin函数,当该函数执行完毕后,会有与之对应的OnRspUserLogin函数被自动调用,我们可以利用其中的返回值来判断登录是否成功。

  要实现行情部分,我们需要创建一个类来继承CThostFtdcMdSpi并且重写部分函数。

  举个例子,当客户端与交易后台进行通讯连接时,我们可以对OnFrontConnected重写来监听连接是否成功。

 

  同时实现行情的登录。接下来,我们通过对OnRtnDepthMarketData 的重写来实现行情信息的获取,由于涉及到多个类之间的信息通信,我们在获取到数据后将其拼接为一个由 , 隔开的字符串并且写一个带有字符串参数的信号sendData来传输数据,在主类中获取并且打印在表单上。

 

   交易部分则复杂一些。不过还是让我们从客户端登录做起,照葫芦画瓢,我们重写了tradeapi中OnFrontConnected 函数,来在信号连  接的时候就实现其登录,以下的userid也就是注册时得到的investorID可以修改为您自己的investorID。

    要实现个人账户的登录,我们在登录按钮上写一个槽函数,将正确的账户密码写上去,登陆成功。

  在登录后,程序会立马获取合约,持仓,账户等信息,三者的写法不会有很大区别,让我们以合约为例子来讲一下。

  我们需要重写OnRspQryInstrument函数,并且使用多个字符串来接受pInstrument中的数据,接下来我们将其拼接为一个字符串,同上,由于涉及到多个类之间的信息通信,我们在获取到数据后将其拼接为一个由 , 隔开的字符串并且写一个带有字符串参数的信号sendDataHy来传输数据,同时,我们也要将这些数据存储在一个两重字符串数组中以便之后使用,最后,在主类中分割字符串并将其写入表中。

   合约,持仓,账户表单操作差异不大,学会了合约之后,就可以举一反三了。我们来到很重要的一步,下单以及撤单,请继续阅读以下内容。

    要实现这一功能,我们需要自行写一个函数并且主动调用它了,我们找到ReqOrderInsert函数,发现这个函数可以用于下单,于是我们可以自己定义一个同名的ReqOrderInsert函数,但是它拥有参数以便我们调用它。

 

  

void CTraderSpi::ReqOrderInsert(QString dm,QString lx,int lots,double price)
{
    CThostFtdcInputOrderField ord ;
    memset(&ord, 0, sizeof(ord));
    strcpy_s(ord.BrokerID, "9999");
    strcpy_s(ord.InvestorID, "204925");
    strcpy_s(ord.ExchangeID, "SHFE");
    strcpy_s(ord.InstrumentID,dm.toStdString().data() );


    sprintf(ORDER_REF,"%d",iRequestID);
    strcpy_s(ord.OrderRef,ORDER_REF );

    ord.OrderPriceType = THOST_FTDC_OPT_LimitPrice;//限价

    if(lx =="kd"){
        ord.Direction = THOST_FTDC_D_Buy;//买 DIRECTION
        ord.CombOffsetFlag[0] = THOST_FTDC_OF_Open;//开
    }
    else if(lx =="pd"){
        ord.Direction = THOST_FTDC_D_Buy;//买 DIRECTION
        ord.CombOffsetFlag[0] = THOST_FTDC_OF_CloseToday;//开
    }
    else if(lx =="kk"){
        ord.Direction = THOST_FTDC_D_Sell;//买 DIRECTION
        ord.CombOffsetFlag[0] = THOST_FTDC_OF_Open;//开
    }
    else if(lx =="pk"){
        ord.Direction = THOST_FTDC_D_Sell;//买 DIRECTION
        ord.CombOffsetFlag[0] = THOST_FTDC_OF_CloseToday;//开
    }


    ord.CombHedgeFlag[0] = THOST_FTDC_HF_Speculation;//投机
    ord.LimitPrice = price;
    ord.VolumeTotalOriginal = lots;
    ord.TimeCondition = THOST_FTDC_TC_GFD;///当日有效
    ord.VolumeCondition = THOST_FTDC_VC_AV;///任意数量
    ord.MinVolume = 1;
    ord.ContingentCondition = THOST_FTDC_CC_Immediately;
    ord.StopPrice = 0;
    ord.ForceCloseReason = THOST_FTDC_FCC_NotForceClose;
    ord.IsAutoSuspend = 0;
    pUserApi->ReqOrderInsert(&ord, ++iRequestID);
};

   函数看起来非常之长,但是其中很多都是比较固定的值,对于我们新手来说,复制粘贴就完事了,参数lx是用来区分是开多,平多,还是开空,平空的,作为非金融专业的我也不是很懂这些,大家可以自行查找以进行拓展,我们将ord数据写好后调用以ord为参数的ReqOrderInsert,即可实现下单。

  再执行下单后,委托会出现数据,如果是处于还未成交的状况下,我们可以实现撤单功能,那么在委托的表单中,我们就需要实现 点击后识别点击的一栏并且出现一个撤单选项,点击撤单我们就可以进行撤单操作。

  代码如下: 

void MainWindow::OnWTmenu(const QPoint &pt)
{
    qDebug()<<"onwtmenu";
    QMenu menu;
    menu.addAction(ui->actioncd);
    menu.exec(ui->tableWT_2->mapToGlobal(pt));

}

void MainWindow::ct()
{
    if(ui->tableWT_2->rowCount()==0)return;
    int i = ui->tableWT_2->currentIndex().row();
    QString wth = ui->tableWT_2->item(i,7)->text();
    QString jys = ui->tableWT_2->item(i,8)->text();
    QString brokerid = "9999";

    qDebug()<<wth;
    qDebug()<<jys;

    if(wth == "")return;

    ptdUserSpi->ReqOrderAction(brokerid,wth,jys);
}

  撤单相较来说简单一点,我们获取到点击的行数后,通过行数来获得委托号以及交易所,最后加上brokerID即可调用撤单,撤单成功后,委托表中其状态会变为以撤单,同时,你也可以登录快期交易平台来查看交易是否撤单成功。

4.代码获取

 账号注册:   sinmow (有的时间段可能登录不上)。

api获取:上期技术官网  ,sinmow

gitee: QTctp: QT简单实现ctp程序 。

推荐阅读文章 :CTP 学习笔记_EmoryHuang的博客-CSDN博客

猜你喜欢

转载自blog.csdn.net/weixin_56108590/article/details/126690726