c++和python混合编程,调用了CTP的附加库 (windows,c++的CTP接口)(应该是全网第一篇)

这是一个连接券商的代码,simnow提供的包,windows版,linux的话,下一篇文章介绍
听起来就很复杂,所以需要大家有点功底,不懂的东西,多多百度,因为很多细节,我不可能还教怎么使用visual studio

 

visual studo一定是要安装的,我安装的是visual studio2019

python不建议用比python3.7高版本的

 

c++的文件目录是这样

 

有基础的人会发现,里面有几个文件是github就有的,其他是我自己加的

我代码里面被注解了的代码都是没用的,你可以删了,

该项目点击右键,就能生成python使用的dll,然后里面很多细节,

举几个例子,1、dll是windows才有的东西,linux是没dll这说法的;

2、生成的时候要选择debug的64位,因为python是64位的,同时你去simnow下载的CTP包,也需要选择64位的

 

 

 把这个圈着的包复制到你的项目,怎么复制呢,就正常导包,下面的截图是我项目的文件截图

 

 

 复制到箭头的文件

 

 

 

 

 到这里都没涉及到代码,下面是代码,上面有什么不懂可以在评论去评论,就正常的c++导包然后编译成dll,没啥难的,多多百度就好

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
//ctp_cpyDLL.h
 
 
#pragma once
#include <string>
using namespace std;
 
 
 
class pyApi
{
 
public:
    void Account();
    void Position();
    void init_(char* pyrun, char* pyfile, char* klinesEntity_name2,
        char* gBrokerID2, char* gInvesterID2, char* gInvesterPassword2, char* gMdFrontAddr2, char* gTradeFrontAddr2, char* symbol);
 
    void tickCall(double c);
};
 
 
 
 
 
extern "C" {
     
    pyApi obj;
    EXPORT void Account() {
        obj.Account();
    }
    EXPORT void init_(char* pyrun, char* pyfile, char* klinesEntity_name2,
        char* gBrokerID2, char* gInvesterID2, char* gInvesterPassword2, char* gMdFrontAddr2, char* gTradeFrontAddr2, char* symbol) {
        obj.init_(pyrun, pyfile, klinesEntity_name2,gBrokerID2,gInvesterID2,gInvesterPassword2,gMdFrontAddr2,gTradeFrontAddr2,symbol);
    }
 
    EXPORT void Position() {
        obj.Position();
    }
  
}

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
//CustomMdSpi.h
 
 
#pragma once
 
 
#include <vector>
#include "./CTP_API/ThostFtdcMdApi.h"
 
 
 
class CustomMdSpi : public CThostFtdcMdSpi
{
    // ---- 继承自CTP父类的回调接口并实现 ---- //
public:
    ///当客户端与交易后台建立起通信连接时(还未登录前),该方法被调用。
    void OnFrontConnected();
 
    ///当客户端与交易后台通信连接断开时,该方法被调用。当发生这个情况后,API会自动重新连接,客户端可不做处理。
    ///@param nReason 错误原因
    ///        0x1001 网络读失败
    ///        0x1002 网络写失败
    ///        0x2001 接收心跳超时
    ///        0x2002 发送心跳失败
    ///        0x2003 收到错误报文
    void OnFrontDisconnected(int nReason);
 
    ///心跳超时警告。当长时间未收到报文时,该方法被调用。
    ///@param nTimeLapse 距离上次接收报文的时间
    void OnHeartBeatWarning(int nTimeLapse);
 
    ///登录请求响应
    void OnRspUserLogin(CThostFtdcRspUserLoginField* pRspUserLogin, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast);
 
    ///登出请求响应
    void OnRspUserLogout(CThostFtdcUserLogoutField* pUserLogout, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast);
 
    ///错误应答
    void OnRspError(CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast);
 
    ///订阅行情应答
    void OnRspSubMarketData(CThostFtdcSpecificInstrumentField* pSpecificInstrument, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast);
 
    ///取消订阅行情应答
    void OnRspUnSubMarketData(CThostFtdcSpecificInstrumentField* pSpecificInstrument, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast);
 
    ///订阅询价应答
    void OnRspSubForQuoteRsp(CThostFtdcSpecificInstrumentField* pSpecificInstrument, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast);
 
    ///取消订阅询价应答
    void OnRspUnSubForQuoteRsp(CThostFtdcSpecificInstrumentField* pSpecificInstrument, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast);
 
    ///深度行情通知
    void OnRtnDepthMarketData(CThostFtdcDepthMarketDataField* pDepthMarketData);
 
    ///询价通知
    void OnRtnForQuoteRsp(CThostFtdcForQuoteRspField* pForQuoteRsp);
};

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
//CustomTradeSpi.h
 
#pragma once
 
#include "./CTP_API/ThostFtdcTraderApi.h"
 
class CustomTradeSpi : public CThostFtdcTraderSpi
{
    // ---- ctp_api部分回调接口 ---- //
public:
    ///当客户端与交易后台建立起通信连接时(还未登录前),该方法被调用。
    void OnFrontConnected();
 
    ///登录请求响应
    void OnRspUserLogin(CThostFtdcRspUserLoginField* pRspUserLogin, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast);
 
    ///错误应答
    void OnRspError(CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast);
 
    ///当客户端与交易后台通信连接断开时,该方法被调用。当发生这个情况后,API会自动重新连接,客户端可不做处理。
    void OnFrontDisconnected(int nReason);
 
    ///心跳超时警告。当长时间未收到报文时,该方法被调用。
    void OnHeartBeatWarning(int nTimeLapse);
 
    ///登出请求响应
    void OnRspUserLogout(CThostFtdcUserLogoutField* pUserLogout, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast);
 
    ///投资者结算结果确认响应
    void OnRspSettlementInfoConfirm(CThostFtdcSettlementInfoConfirmField* pSettlementInfoConfirm, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast);
 
    ///请求查询合约响应
    void OnRspQryInstrument(CThostFtdcInstrumentField* pInstrument, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast);
 
    ///请求查询资金账户响应
    void OnRspQryTradingAccount(CThostFtdcTradingAccountField* pTradingAccount, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast);
 
    ///请求查询投资者持仓响应
    void OnRspQryInvestorPosition(CThostFtdcInvestorPositionField* pInvestorPosition, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast);
 
    ///报单录入请求响应
    void OnRspOrderInsert(CThostFtdcInputOrderField* pInputOrder, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast);
 
    ///报单操作请求响应
    void OnRspOrderAction(CThostFtdcInputOrderActionField* pInputOrderAction, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast);
 
    ///报单通知
    void OnRtnOrder(CThostFtdcOrderField* pOrder);
 
    ///成交通知
    void OnRtnTrade(CThostFtdcTradeField* pTrade);
 
    // ---- 自定义函数 ---- //
public:
    bool loginFlag; // 登陆成功的标识
    void reqOrderInsert(
        TThostFtdcInstrumentIDType instrumentID,
        TThostFtdcPriceType price,
        TThostFtdcVolumeType volume,
        TThostFtdcDirectionType direction); // 个性化报单录入,外部调用
 
    void reqQueryTradingAccount(); // 请求查询资金帐户
    void reqQueryInvestorPosition(); // 请求查询投资者持仓
 
private:
    void reqUserLogin(); // 登录请求
    void reqUserLogout(); // 登出请求
    void reqSettlementInfoConfirm(); // 投资者结果确认
    //void reqQueryInstrument(); // 请求查询合约
 
 
    void reqOrderInsert(); // 请求报单录入
 
    void reqOrderAction(CThostFtdcOrderField* pOrder); // 请求报单操作
    bool isErrorRspInfo(CThostFtdcRspInfoField* pRspInfo); // 是否收到错误信息
    bool isMyOrder(CThostFtdcOrderField* pOrder); // 是否我的报单回报
    bool isTradingOrder(CThostFtdcOrderField* pOrder); // 是否正在交易的报单
};

  

1
2
3
4
5
6
7
8
9
10
11
12
13
//ReplyPy.h
#pragma once
#include <string>
using namespace std;
 
 
class pyApiReply
{
 
public:
 
    void tickCall(double c);
};

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
//ctp_cpyDLL.cpp
 
 
 
 
#pragma once
 
#define EXPORT __declspec(dllexport)
 
#include <iostream>
#include <pthread.h>
#include<Python.h>
//#include <windows.h>
#include <string>
 
#include "ctp_cpyDLL.h"
#include "CustomMdSpi.h"
#include "CustomTradeSpi.h"
 
 
 
using namespace std;
 
#pragma comment (lib, "./CTP_API/thostmduserapi_se.lib")
#pragma comment (lib, "./CTP_API/thosttraderapi_se.lib")
 
 
PyObject* pModule = NULL;//声明变量
 
 
 
// ---- 全局变量 ---- //
pthread_t tids[1];
 
//PyObject* pModule = NULL;//声明变量
TThostFtdcBrokerIDType gBrokerID;
TThostFtdcInvestorIDType gInvesterID;
TThostFtdcPasswordType gInvesterPassword;
 
CThostFtdcMdApi* g_pMdUserApi;
char gMdFrontAddr[40];
char* g_pInstrumentID[1];
int instrumentNum;
 
 
CThostFtdcTraderApi* g_pTradeUserApi;
char gTradeFrontAddr[40];
TThostFtdcInstrumentIDType g_pTradeInstrumentID;        // 所交易的合约代码
 
 
CThostFtdcMdSpi* pMdUserSpi = new CustomMdSpi;
CustomTradeSpi* pTradeSpi = new CustomTradeSpi;
pyApi* pyapi = new pyApi;
 
string klinesEntity_name;
 
 
void start_init() {
    g_pMdUserApi = CThostFtdcMdApi::CreateFtdcMdApi();
    g_pMdUserApi->RegisterSpi(pMdUserSpi);
    g_pMdUserApi->RegisterFront(gMdFrontAddr);
    g_pMdUserApi->Init();
 
    g_pTradeUserApi = CThostFtdcTraderApi::CreateFtdcTraderApi();
    g_pTradeUserApi->RegisterSpi(pTradeSpi);
    g_pTradeUserApi->SubscribePublicTopic(THOST_TERT_RESTART);
    g_pTradeUserApi->SubscribePrivateTopic(THOST_TERT_RESTART);
    g_pTradeUserApi->RegisterFront(gTradeFrontAddr);
    g_pTradeUserApi->Init();
 
}
 
 
 
 
 
const wchar_t* GetWC(char* c)
{
    size_t cSize = strlen(c) + 1;
    wchar_t* wc = new wchar_t[cSize];
    mbstowcs(wc, c, cSize);
 
    return wc;
}
 
 
 
 
void pyApi::Account() {
    pTradeSpi->reqQueryTradingAccount();
}
 
void pyApi::Position() {
    pTradeSpi->reqQueryInvestorPosition();
}
 
//char* pyrun, char* pyfile, char* gBrokerID2, char* gInvesterID2, char* gInvesterPassword2, char* gMdFrontAddr2, char* gTradeFrontAddr2
void pyApi::init_(char* pyrun, char* pyfile, char* klinesEntity_name2,
      char* gBrokerID2, char* gInvesterID2, char* gInvesterPassword2, char* gMdFrontAddr2, char* gTradeFrontAddr2, char* symbol) {
 
 
    cout << "初始化行情..." << endl;
 
    Py_SetPythonHome(GetWC(pyrun));
 
    Py_Initialize();
    PyEval_InitThreads();
 
    PyGILState_STATE state = PyGILState_Ensure();
    PyRun_SimpleString("import sys");
    PyRun_SimpleString("sys.path.append('./')");
 
    klinesEntity_name = (string)klinesEntity_name2;
    
 
    pModule = PyImport_ImportModule(pyfile);
    PyGILState_Release(state);
 
 
    strcpy(gBrokerID, gBrokerID2);
    strcpy(gInvesterID, gInvesterID2);
    strcpy(gInvesterPassword, gInvesterPassword2);
    strcpy(gMdFrontAddr, gMdFrontAddr2);
 
    g_pInstrumentID[0] = symbol;
    instrumentNum = 1;
 
    strcpy(gTradeFrontAddr, gTradeFrontAddr2);
    strcpy(g_pTradeInstrumentID, symbol);
 
 
    start_init();
}

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
//CustomMdSpi.cpp
 
#pragma once
 
#include <iostream>
#include <fstream>
#include <unordered_map>
 
#include "CustomMdSpi.h"
#include "ReplyPy.h"
 
 
 
 
extern CThostFtdcMdApi* g_pMdUserApi;            // 行情指针
extern char gMdFrontAddr[];                      // 模拟行情前置地址
extern TThostFtdcBrokerIDType gBrokerID;         // 模拟经纪商代码
extern TThostFtdcInvestorIDType gInvesterID;     // 投资者账户名
extern TThostFtdcPasswordType gInvesterPassword; // 投资者密码
extern char* g_pInstrumentID[];                  // 行情合约代码列表,中、上、大、郑交易所各选一种
extern int instrumentNum;
 
 
pyApiReply* pyApireply = new pyApiReply;
 
 
 
 
 
// ---- ctp_api回调函数 ---- //
// 连接成功应答
void CustomMdSpi::OnFrontConnected()
{
    std::cout << "=====建立网络连接成功=====" << std::endl;
    // 开始登录
    CThostFtdcReqUserLoginField loginReq;
    memset(&loginReq, 0, sizeof(loginReq));
    strcpy(loginReq.BrokerID, gBrokerID);
    strcpy(loginReq.UserID, gInvesterID);
    strcpy(loginReq.Password, gInvesterPassword);
    static int requestID = 0; // 请求编号
    int rt = g_pMdUserApi->ReqUserLogin(&loginReq, requestID);
    if (!rt)
        std::cout << ">>>>>>发送登录请求成功" << std::endl;
    else
        std::cerr << "--->>>发送登录请求失败" << std::endl;
}
 
// 断开连接通知
void CustomMdSpi::OnFrontDisconnected(int nReason)
{
    std::cerr << "=====网络连接断开=====" << std::endl;
    std::cerr << "错误码: " << nReason << std::endl;
}
 
// 心跳超时警告
void CustomMdSpi::OnHeartBeatWarning(int nTimeLapse)
{
    std::cerr << "=====网络心跳超时=====" << std::endl;
    std::cerr << "距上次连接时间: " << nTimeLapse << std::endl;
}
 
// 登录应答
void CustomMdSpi::OnRspUserLogin(
    CThostFtdcRspUserLoginField* pRspUserLogin,
    CThostFtdcRspInfoField* pRspInfo,
    int nRequestID,
    bool bIsLast)
{
    bool bResult = pRspInfo && (pRspInfo->ErrorID != 0);
    if (!bResult)
    {
        std::cout << "=====账户登录成功=====" << std::endl;
        std::cout << "交易日: " << pRspUserLogin->TradingDay << std::endl;
        std::cout << "登录时间: " << pRspUserLogin->LoginTime << std::endl;
        std::cout << "经纪商: " << pRspUserLogin->BrokerID << std::endl;
        std::cout << "帐户名: " << pRspUserLogin->UserID << std::endl;
        // 开始订阅行情
        int rt = g_pMdUserApi->SubscribeMarketData(g_pInstrumentID, instrumentNum);
        if (!rt)
            std::cout << ">>>>>>发送订阅行情请求成功" << std::endl;
        else
            std::cerr << "--->>>发送订阅行情请求失败" << std::endl;
    }
    else
        std::cerr << "返回错误--->>> ErrorID=" << pRspInfo->ErrorID << ", ErrorMsg=" << pRspInfo->ErrorMsg << std::endl;
}
 
// 登出应答
void CustomMdSpi::OnRspUserLogout(
    CThostFtdcUserLogoutField* pUserLogout,
    CThostFtdcRspInfoField* pRspInfo,
    int nRequestID,
    bool bIsLast)
{
    bool bResult = pRspInfo && (pRspInfo->ErrorID != 0);
    if (!bResult)
    {
        std::cout << "=====账户登出成功=====" << std::endl;
        std::cout << "经纪商: " << pUserLogout->BrokerID << std::endl;
        std::cout << "帐户名: " << pUserLogout->UserID << std::endl;
    }
    else
        std::cerr << "返回错误--->>> ErrorID=" << pRspInfo->ErrorID << ", ErrorMsg=" << pRspInfo->ErrorMsg << std::endl;
}
 
// 错误通知
void CustomMdSpi::OnRspError(CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast)
{
    bool bResult = pRspInfo && (pRspInfo->ErrorID != 0);
    if (bResult)
        std::cerr << "返回错误--->>> ErrorID=" << pRspInfo->ErrorID << ", ErrorMsg=" << pRspInfo->ErrorMsg << std::endl;
}
 
// 订阅行情应答
void CustomMdSpi::OnRspSubMarketData(
    CThostFtdcSpecificInstrumentField* pSpecificInstrument,
    CThostFtdcRspInfoField* pRspInfo,
    int nRequestID,
    bool bIsLast)
{
    bool bResult = pRspInfo && (pRspInfo->ErrorID != 0);
    if (!bResult)
    {
 
    }
    else
        std::cerr << "返回错误--->>> ErrorID=" << pRspInfo->ErrorID << ", ErrorMsg=" << pRspInfo->ErrorMsg << std::endl;
}
 
// 取消订阅行情应答
void CustomMdSpi::OnRspUnSubMarketData(
    CThostFtdcSpecificInstrumentField* pSpecificInstrument,
    CThostFtdcRspInfoField* pRspInfo,
    int nRequestID,
    bool bIsLast)
{
    bool bResult = pRspInfo && (pRspInfo->ErrorID != 0);
    if (!bResult)
    {
        std::cout << "=====取消订阅行情成功=====" << std::endl;
        std::cout << "合约代码: " << pSpecificInstrument->InstrumentID << std::endl;
    }
    else
        std::cerr << "返回错误--->>> ErrorID=" << pRspInfo->ErrorID << ", ErrorMsg=" << pRspInfo->ErrorMsg << std::endl;
}
 
// 订阅询价应答
void CustomMdSpi::OnRspSubForQuoteRsp(
    CThostFtdcSpecificInstrumentField* pSpecificInstrument,
    CThostFtdcRspInfoField* pRspInfo,
    int nRequestID,
    bool bIsLast)
{
    bool bResult = pRspInfo && (pRspInfo->ErrorID != 0);
    if (!bResult)
    {
        std::cout << "=====订阅询价成功=====" << std::endl;
        std::cout << "合约代码: " << pSpecificInstrument->InstrumentID << std::endl;
    }
    else
        std::cerr << "返回错误--->>> ErrorID=" << pRspInfo->ErrorID << ", ErrorMsg=" << pRspInfo->ErrorMsg << std::endl;
}
 
// 取消订阅询价应答
void CustomMdSpi::OnRspUnSubForQuoteRsp(CThostFtdcSpecificInstrumentField* pSpecificInstrument, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast)
{
    bool bResult = pRspInfo && (pRspInfo->ErrorID != 0);
    if (!bResult)
    {
        std::cout << "=====取消订阅询价成功=====" << std::endl;
        std::cout << "合约代码: " << pSpecificInstrument->InstrumentID << std::endl;
    }
    else
        std::cerr << "返回错误--->>> ErrorID=" << pRspInfo->ErrorID << ", ErrorMsg=" << pRspInfo->ErrorMsg << std::endl;
}
 
// 行情详情通知
void CustomMdSpi::OnRtnDepthMarketData(CThostFtdcDepthMarketDataField* pDepthMarketData)
{
    // 打印行情,字段较多,截取部分
    //std::cout << "=====获得深度行情=====" << std::endl;
    //std::cout << "交易日: " << pDepthMarketData->TradingDay << std::endl;
    //std::cout << "合约代码: " << pDepthMarketData->InstrumentID << std::endl;
 
    //std::cout << "最新价: " << pDepthMarketData->LastPrice << std::endl;
    //std::cout << "数量: " << pDepthMarketData->Volume << std::endl;
 
    //std::cout << "买一: " << pDepthMarketData->BidPrice1 << std::endl;
    //std::cout << "买一量: " << pDepthMarketData->BidVolume1 << std::endl;
 
    //std::cout << "卖一: " << pDepthMarketData->AskPrice1 << std::endl;
    //std::cout << "卖一量: " << pDepthMarketData->AskVolume1 << std::endl;
 
    pyApireply->tickCall(pDepthMarketData->LastPrice);
 
    // 取消订阅行情
    //int rt = g_pMdUserApi->UnSubscribeMarketData(g_pInstrumentID, instrumentNum);
    //if (!rt)
    //  std::cout << ">>>>>>发送取消订阅行情请求成功" << std::endl;
    //else
    //  std::cerr << "--->>>发送取消订阅行情请求失败" << std::endl;
}
 
 
// 询价详情通知
void CustomMdSpi::OnRtnForQuoteRsp(CThostFtdcForQuoteRspField* pForQuoteRsp)
{
    // 部分询价结果
    std::cout << "=====获得询价结果=====" << std::endl;
    std::cout << "交易日: " << pForQuoteRsp->TradingDay << std::endl;
    std::cout << "交易所代码: " << pForQuoteRsp->ExchangeID << std::endl;
    std::cout << "合约代码: " << pForQuoteRsp->InstrumentID << std::endl;
    std::cout << "询价编号: " << pForQuoteRsp->ForQuoteSysID << std::endl;
}

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
//CustomTradeSpi.cpp
 
#include <iostream>
#include <time.h>
#include <thread>
#include <chrono>
#include "CustomTradeSpi.h"
 
// ---- 全局参数声明 ---- //
extern TThostFtdcBrokerIDType gBrokerID;                      // 模拟经纪商代码
extern TThostFtdcInvestorIDType gInvesterID;                  // 投资者账户名
extern TThostFtdcPasswordType gInvesterPassword;              // 投资者密码
extern CThostFtdcTraderApi* g_pTradeUserApi;                  // 交易指针
extern char gTradeFrontAddr[];                                // 模拟交易前置地址
extern TThostFtdcInstrumentIDType g_pTradeInstrumentID;       // 所交易的合约代码
TThostFtdcDirectionType gTradeDirection = NULL;               // 买卖方向
TThostFtdcPriceType gLimitPrice = NULL;                       // 交易价格
 
// 会话参数
TThostFtdcFrontIDType   trade_front_id; //前置编号
TThostFtdcSessionIDType session_id; //会话编号
TThostFtdcOrderRefType  order_ref;  //报单引用
time_t lOrderTime;
time_t lOrderOkTime;
 
 
 
void CustomTradeSpi::OnFrontConnected()
{
    std::cout << "=====建立网络连接成功=====" << std::endl;
    // 开始登录
    reqUserLogin();
}
 
void CustomTradeSpi::OnRspUserLogin(
    CThostFtdcRspUserLoginField* pRspUserLogin,
    CThostFtdcRspInfoField* pRspInfo,
    int nRequestID,
    bool bIsLast)
{
    if (!isErrorRspInfo(pRspInfo))
    {
        std::cout << "=====账户登录成功=====" << std::endl;
        loginFlag = true;
        std::cout << "交易日: " << pRspUserLogin->TradingDay << std::endl;
        std::cout << "登录时间: " << pRspUserLogin->LoginTime << std::endl;
        std::cout << "经纪商: " << pRspUserLogin->BrokerID << std::endl;
        std::cout << "帐户名: " << pRspUserLogin->UserID << std::endl;
        // 保存会话参数
        trade_front_id = pRspUserLogin->FrontID;
        session_id = pRspUserLogin->SessionID;
        strcpy(order_ref, pRspUserLogin->MaxOrderRef);
 
        // 投资者结算结果确认
        reqSettlementInfoConfirm();
    }
}
 
void CustomTradeSpi::OnRspError(CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast)
{
    isErrorRspInfo(pRspInfo);
}
 
void CustomTradeSpi::OnFrontDisconnected(int nReason)
{
    std::cerr << "=====网络连接断开=====" << std::endl;
    std::cerr << "错误码: " << nReason << std::endl;
}
 
void CustomTradeSpi::OnHeartBeatWarning(int nTimeLapse)
{
    std::cerr << "=====网络心跳超时=====" << std::endl;
    std::cerr << "距上次连接时间: " << nTimeLapse << std::endl;
}
 
void CustomTradeSpi::OnRspUserLogout(
    CThostFtdcUserLogoutField* pUserLogout,
    CThostFtdcRspInfoField* pRspInfo,
    int nRequestID,
    bool bIsLast)
{
    if (!isErrorRspInfo(pRspInfo))
    {
        loginFlag = false; // 登出就不能再交易了
        std::cout << "=====账户登出成功=====" << std::endl;
        std::cout << "经纪商: " << pUserLogout->BrokerID << std::endl;
        std::cout << "帐户名: " << pUserLogout->UserID << std::endl;
    }
}
 
void CustomTradeSpi::OnRspSettlementInfoConfirm(
    CThostFtdcSettlementInfoConfirmField* pSettlementInfoConfirm,
    CThostFtdcRspInfoField* pRspInfo,
    int nRequestID,
    bool bIsLast)
{
    if (!isErrorRspInfo(pRspInfo))
    {
        std::cout << "=====投资者结算结果确认成功=====" << std::endl;
        std::cout << "确认日期: " << pSettlementInfoConfirm->ConfirmDate << std::endl;
        std::cout << "确认时间: " << pSettlementInfoConfirm->ConfirmTime << std::endl;
        // 请求查询合约
        //reqQueryInstrument();
    }
}
 
void CustomTradeSpi::OnRspQryInstrument(
    CThostFtdcInstrumentField* pInstrument,
    CThostFtdcRspInfoField* pRspInfo,
    int nRequestID,
    bool bIsLast)
{
    if (!isErrorRspInfo(pRspInfo))
    {
        std::cout << "=====查询合约结果成功=====" << std::endl;
        std::cout << "111111111: " << pInstrument << std::endl;
        //std::cout << "交易所代码: " << pInstrument->ExchangeID << std::endl;
        //std::cout << "合约代码: " << pInstrument->InstrumentID << std::endl;
        //std::cout << "合约在交易所的代码: " << pInstrument->ExchangeInstID << std::endl;
        //std::cout << "执行价: " << pInstrument->StrikePrice << std::endl;
        //std::cout << "到期日: " << pInstrument->EndDelivDate << std::endl;
        //std::cout << "当前交易状态: " << pInstrument->IsTrading << std::endl;
        // 请求查询投资者资金账户
        reqQueryTradingAccount();
    }
}
 
void CustomTradeSpi::OnRspQryTradingAccount(
    CThostFtdcTradingAccountField* pTradingAccount,
    CThostFtdcRspInfoField* pRspInfo,
    int nRequestID,
    bool bIsLast)
{
    if (!isErrorRspInfo(pRspInfo))
    {
        std::cout << "=====查询投资者资金账户成功=====" << std::endl;
        std::cout << "投资者账号: " << pTradingAccount->AccountID << std::endl;
        std::cout << "可用资金: " << pTradingAccount->Available << std::endl;
        std::cout << "可取资金: " << pTradingAccount->WithdrawQuota << std::endl;
        std::cout << "当前保证金: " << pTradingAccount->CurrMargin << std::endl;
        std::cout << "平仓盈亏: " << pTradingAccount->CloseProfit << std::endl;
        // 请求查询投资者持仓
        //reqQueryInvestorPosition();
    }
}
 
void CustomTradeSpi::OnRspQryInvestorPosition(
    CThostFtdcInvestorPositionField* pInvestorPosition,
    CThostFtdcRspInfoField* pRspInfo,
    int nRequestID,
    bool bIsLast)
{
    if (!isErrorRspInfo(pRspInfo))
    {
        std::cout << "=====查询投资者持仓成功=====" << std::endl;
        if (pInvestorPosition)
        {
            std::cout << "合约代码: " << pInvestorPosition->InstrumentID << std::endl;
            std::cout << "开仓价格: " << pInvestorPosition->OpenAmount << std::endl;
 
            std::cout << "开仓量: " << pInvestorPosition->OpenVolume << std::endl;
            std::cout << "开仓量: " << pInvestorPosition->YdPosition << std::endl;
            std::cout << "开仓量: " << pInvestorPosition->Position << std::endl;
            std::cout << "开仓量: " << pInvestorPosition->CloseVolume << std::endl;
            std::cout << "开仓量: " << pInvestorPosition->TodayPosition << std::endl;
            std::cout << "开仓量: " << pInvestorPosition->YdStrikeFrozen << std::endl;
            std::cout << "开仓量: " << pInvestorPosition->TasPosition << std::endl;
 
 
            std::cout << "开仓方向: " << pInvestorPosition->PosiDirection << std::endl;
            std::cout << "占用保证金:" << pInvestorPosition->UseMargin << std::endl;
        }
        else
            std::cout << "----->该合约未持仓" << std::endl;
 
 
    }
}
 
void CustomTradeSpi::OnRspOrderInsert(
    CThostFtdcInputOrderField* pInputOrder,
    CThostFtdcRspInfoField* pRspInfo,
    int nRequestID,
    bool bIsLast)
{
    if (!isErrorRspInfo(pRspInfo))
    {
        std::cout << "=====报单录入成功=====" << std::endl;
        std::cout << "合约代码: " << pInputOrder->InstrumentID << std::endl;
        std::cout << "价格: " << pInputOrder->LimitPrice << std::endl;
        std::cout << "数量: " << pInputOrder->VolumeTotalOriginal << std::endl;
        std::cout << "开仓方向: " << pInputOrder->Direction << std::endl;
    }
}
 
void CustomTradeSpi::OnRspOrderAction(
    CThostFtdcInputOrderActionField* pInputOrderAction,
    CThostFtdcRspInfoField* pRspInfo,
    int nRequestID,
    bool bIsLast)
{
    if (!isErrorRspInfo(pRspInfo))
    {
        std::cout << "=====报单操作成功=====" << std::endl;
        std::cout << "合约代码: " << pInputOrderAction->InstrumentID << std::endl;
        std::cout << "操作标志: " << pInputOrderAction->ActionFlag;
    }
}
 
void CustomTradeSpi::OnRtnOrder(CThostFtdcOrderField* pOrder)
{
    char str[10];
    sprintf(str, "%d", pOrder->OrderSubmitStatus);
    int orderState = atoi(str) - 48;    //报单状态0=已经提交,3=已经接受
 
    std::cout << "=====收到报单应答=====" << std::endl;
 
    if (isMyOrder(pOrder))
    {
        if (isTradingOrder(pOrder))
        {
            std::cout << "--->>> 等待成交中!" << std::endl;
            //reqOrderAction(pOrder); // 这里可以撤单
            //reqUserLogout(); // 登出测试
        }
        else if (pOrder->OrderStatus == THOST_FTDC_OST_Canceled)
            std::cout << "--->>> 撤单成功!" << std::endl;
    }
}
 
void CustomTradeSpi::OnRtnTrade(CThostFtdcTradeField* pTrade)
{
    std::cout << "=====报单成功成交=====" << std::endl;
    std::cout << "成交时间: " << pTrade->TradeTime << std::endl;
    std::cout << "合约代码: " << pTrade->InstrumentID << std::endl;
    std::cout << "成交价格: " << pTrade->Price << std::endl;
    std::cout << "成交量: " << pTrade->Volume << std::endl;
    std::cout << "开平仓方向: " << pTrade->Direction << std::endl;
}
 
bool CustomTradeSpi::isErrorRspInfo(CThostFtdcRspInfoField* pRspInfo)
{
    bool bResult = pRspInfo && (pRspInfo->ErrorID != 0);
    if (bResult)
        std::cerr << "返回错误--->>> ErrorID=" << pRspInfo->ErrorID << ", ErrorMsg=" << pRspInfo->ErrorMsg << std::endl;
    return bResult;
}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
void CustomTradeSpi::reqUserLogin()
{
    CThostFtdcReqUserLoginField loginReq;
    memset(&loginReq, 0, sizeof(loginReq));
    strcpy(loginReq.BrokerID, gBrokerID);
    strcpy(loginReq.UserID, gInvesterID);
    strcpy(loginReq.Password, gInvesterPassword);
    static int requestID = 0; // 请求编号
    int rt = g_pTradeUserApi->ReqUserLogin(&loginReq, requestID);
    if (!rt)
        std::cout << ">>>>>>发送登录请求成功" << std::endl;
    else
        std::cerr << "--->>>发送登录请求失败" << std::endl;
}
 
void CustomTradeSpi::reqUserLogout()
{
    CThostFtdcUserLogoutField logoutReq;
    memset(&logoutReq, 0, sizeof(logoutReq));
    strcpy(logoutReq.BrokerID, gBrokerID);
    strcpy(logoutReq.UserID, gInvesterID);
    static int requestID = 0; // 请求编号
    int rt = g_pTradeUserApi->ReqUserLogout(&logoutReq, requestID);
    if (!rt)
        std::cout << ">>>>>>发送登出请求成功" << std::endl;
    else
        std::cerr << "--->>>发送登出请求失败" << std::endl;
}
 
 
void CustomTradeSpi::reqSettlementInfoConfirm()
{
    CThostFtdcSettlementInfoConfirmField settlementConfirmReq;
    memset(&settlementConfirmReq, 0, sizeof(settlementConfirmReq));
    strcpy(settlementConfirmReq.BrokerID, gBrokerID);
    strcpy(settlementConfirmReq.InvestorID, gInvesterID);
    static int requestID = 0; // 请求编号
    int rt = g_pTradeUserApi->ReqSettlementInfoConfirm(&settlementConfirmReq, requestID);
    if (!rt)
        std::cout << ">>>>>>发送投资者结算结果确认请求成功" << std::endl;
    else
        std::cerr << "--->>>发送投资者结算结果确认请求失败" << std::endl;
}
 
 
 
void CustomTradeSpi::reqQueryTradingAccount()
{
    CThostFtdcQryTradingAccountField tradingAccountReq;
    memset(&tradingAccountReq, 0, sizeof(tradingAccountReq));
    strcpy(tradingAccountReq.BrokerID, gBrokerID);
    strcpy(tradingAccountReq.InvestorID, gInvesterID);
    static int requestID = 0; // 请求编号
    std::this_thread::sleep_for(std::chrono::milliseconds(700)); // 有时候需要停顿一会才能查询成功
    int rt = g_pTradeUserApi->ReqQryTradingAccount(&tradingAccountReq, requestID);
    if (!rt)
        std::cout << ">>>>>>发送投资者资金账户查询请求成功" << std::endl;
    else
        std::cerr << "--->>>发送投资者资金账户查询请求失败" << std::endl;
}
 
void CustomTradeSpi::reqQueryInvestorPosition()
{
    std::cout << gBrokerID << std::endl;
    std::cout << gInvesterID << std::endl;
    std::cout << g_pTradeInstrumentID << std::endl;
 
    CThostFtdcQryInvestorPositionField postionReq;
    memset(&postionReq, 0, sizeof(postionReq));
    strcpy(postionReq.BrokerID, gBrokerID);
    strcpy(postionReq.InvestorID, gInvesterID);
    strcpy(postionReq.InstrumentID, g_pTradeInstrumentID);
    static int requestID = 0; // 请求编号
    std::this_thread::sleep_for(std::chrono::milliseconds(700)); // 有时候需要停顿一会才能查询成功
    int rt = g_pTradeUserApi->ReqQryInvestorPosition(&postionReq, requestID);
    if (!rt)
        std::cout << ">>>>>>发送投资者持仓查询请求成功" << std::endl;
    else
        std::cerr << "--->>>发送投资者持仓查询请求失败" << std::endl;
}
 
void CustomTradeSpi::reqOrderInsert()
{
    CThostFtdcInputOrderField orderInsertReq;
    memset(&orderInsertReq, 0, sizeof(orderInsertReq));
    ///经纪公司代码
    strcpy(orderInsertReq.BrokerID, gBrokerID);
    ///投资者代码
    strcpy(orderInsertReq.InvestorID, gInvesterID);
    ///合约代码
    strcpy(orderInsertReq.InstrumentID, g_pTradeInstrumentID);
    ///报单引用
    strcpy(orderInsertReq.OrderRef, order_ref);
    ///报单价格条件: 限价
    orderInsertReq.OrderPriceType = THOST_FTDC_OPT_LimitPrice;
    ///买卖方向:
    orderInsertReq.Direction = gTradeDirection;
    ///组合开平标志: 开仓
    orderInsertReq.CombOffsetFlag[0] = THOST_FTDC_OF_Open;
    ///组合投机套保标志
    orderInsertReq.CombHedgeFlag[0] = THOST_FTDC_HF_Speculation;
    ///价格
    orderInsertReq.LimitPrice = gLimitPrice;
    ///数量:1
    orderInsertReq.VolumeTotalOriginal = 1;
    ///有效期类型: 当日有效
    orderInsertReq.TimeCondition = THOST_FTDC_TC_GFD;
    ///成交量类型: 任何数量
    orderInsertReq.VolumeCondition = THOST_FTDC_VC_AV;
    ///最小成交量: 1
    orderInsertReq.MinVolume = 1;
    ///触发条件: 立即
    orderInsertReq.ContingentCondition = THOST_FTDC_CC_Immediately;
    ///强平原因: 非强平
    orderInsertReq.ForceCloseReason = THOST_FTDC_FCC_NotForceClose;
    ///自动挂起标志: 否
    orderInsertReq.IsAutoSuspend = 0;
    ///用户强评标志: 否
    orderInsertReq.UserForceClose = 0;
 
    static int requestID = 0; // 请求编号
    int rt = g_pTradeUserApi->ReqOrderInsert(&orderInsertReq, ++requestID);
    if (!rt)
        std::cout << ">>>>>>发送报单录入请求成功" << std::endl;
    else
        std::cerr << "--->>>发送报单录入请求失败" << std::endl;
}
 
void CustomTradeSpi::reqOrderInsert(
    TThostFtdcInstrumentIDType instrumentID,
    TThostFtdcPriceType price,
    TThostFtdcVolumeType volume,
    TThostFtdcDirectionType direction)
{
    CThostFtdcInputOrderField orderInsertReq;
    memset(&orderInsertReq, 0, sizeof(orderInsertReq));
    ///经纪公司代码
    strcpy(orderInsertReq.BrokerID, gBrokerID);
    ///投资者代码
    strcpy(orderInsertReq.InvestorID, gInvesterID);
    ///合约代码
    strcpy(orderInsertReq.InstrumentID, instrumentID);
    ///报单引用
    strcpy(orderInsertReq.OrderRef, order_ref);
    ///报单价格条件: 限价
    orderInsertReq.OrderPriceType = THOST_FTDC_OPT_LimitPrice;
    ///买卖方向:
    orderInsertReq.Direction = direction;
    ///组合开平标志: 开仓
    orderInsertReq.CombOffsetFlag[0] = THOST_FTDC_OF_Open;
    ///组合投机套保标志
    orderInsertReq.CombHedgeFlag[0] = THOST_FTDC_HF_Speculation;
    ///价格
    orderInsertReq.LimitPrice = price;
    ///数量:1
    orderInsertReq.VolumeTotalOriginal = volume;
    ///有效期类型: 当日有效
    orderInsertReq.TimeCondition = THOST_FTDC_TC_GFD;
    ///成交量类型: 任何数量
    orderInsertReq.VolumeCondition = THOST_FTDC_VC_AV;
    ///最小成交量: 1
    orderInsertReq.MinVolume = 1;
    ///触发条件: 立即
    orderInsertReq.ContingentCondition = THOST_FTDC_CC_Immediately;
    ///强平原因: 非强平
    orderInsertReq.ForceCloseReason = THOST_FTDC_FCC_NotForceClose;
    ///自动挂起标志: 否
    orderInsertReq.IsAutoSuspend = 0;
    ///用户强评标志: 否
    orderInsertReq.UserForceClose = 0;
 
    static int requestID = 0; // 请求编号
    int rt = g_pTradeUserApi->ReqOrderInsert(&orderInsertReq, ++requestID);
    if (!rt)
        std::cout << ">>>>>>发送报单录入请求成功" << std::endl;
    else
        std::cerr << "--->>>发送报单录入请求失败" << std::endl;
}
 
void CustomTradeSpi::reqOrderAction(CThostFtdcOrderField* pOrder)
{
    static bool orderActionSentFlag = false; // 是否发送了报单
    if (orderActionSentFlag)
        return;
 
    CThostFtdcInputOrderActionField orderActionReq;
    memset(&orderActionReq, 0, sizeof(orderActionReq));
    ///经纪公司代码
    strcpy(orderActionReq.BrokerID, pOrder->BrokerID);
    ///投资者代码
    strcpy(orderActionReq.InvestorID, pOrder->InvestorID);
    ///报单操作引用
    //  TThostFtdcOrderActionRefType    OrderActionRef;
    ///报单引用
    strcpy(orderActionReq.OrderRef, pOrder->OrderRef);
    ///请求编号
    //  TThostFtdcRequestIDType RequestID;
    ///前置编号
    orderActionReq.FrontID = trade_front_id;
    ///会话编号
    orderActionReq.SessionID = session_id;
    ///交易所代码
    //  TThostFtdcExchangeIDType    ExchangeID;
    ///报单编号
    //  TThostFtdcOrderSysIDType    OrderSysID;
    ///操作标志
    orderActionReq.ActionFlag = THOST_FTDC_AF_Delete;
    ///价格
    //  TThostFtdcPriceType LimitPrice;
    ///数量变化
    //  TThostFtdcVolumeType    VolumeChange;
    ///用户代码
    //  TThostFtdcUserIDType    UserID;
    ///合约代码
    strcpy(orderActionReq.InstrumentID, pOrder->InstrumentID);
    static int requestID = 0; // 请求编号
    int rt = g_pTradeUserApi->ReqOrderAction(&orderActionReq, ++requestID);
    if (!rt)
        std::cout << ">>>>>>发送报单操作请求成功" << std::endl;
    else
        std::cerr << "--->>>发送报单操作请求失败" << std::endl;
    orderActionSentFlag = true;
}
 
bool CustomTradeSpi::isMyOrder(CThostFtdcOrderField* pOrder)
{
    return ((pOrder->FrontID == trade_front_id) &&
        (pOrder->SessionID == session_id) &&
        (strcmp(pOrder->OrderRef, order_ref) == 0));
}
 
bool CustomTradeSpi::isTradingOrder(CThostFtdcOrderField* pOrder)
{
    return ((pOrder->OrderStatus != THOST_FTDC_OST_PartTradedNotQueueing) &&
        (pOrder->OrderStatus != THOST_FTDC_OST_Canceled) &&
        (pOrder->OrderStatus != THOST_FTDC_OST_AllTraded));
}

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
//ReplyPy.cpp
 
 
 
#include "ReplyPy.h"
#include<Python.h>
 
extern PyObject* pModule;
extern string klinesEntity_name;
 
void pyApiReply::tickCall(double c) {
 
    PyObject* pFunc = NULL;
    //pFunc = PyObject_GetAttrString(pModule, "tickCall");
 
 
    PyGILState_STATE state = PyGILState_Ensure();
         
 /*       PyObject* args = PyTuple_New(1);
 
        PyObject* arg1 = PyLong_FromLong(c);
 
        PyTuple_SetItem(args, 0, arg1);*/
 
 
   /*     PyObject* pDict = PyModule_GetDict(pModule);
        PyObject* bentity = PyDict_GetItemString(pDict, "klinesEntity");
       if (!bentity) {
            printf("Cant find second class./n");
       }
        PyObject_CallMethod(bentity, "set_c", "O", args);*/
     
        string simpleString = klinesEntity_name+ ".set_c(" + to_string(c) + ")";
        char* simpleString2 = (char*)simpleString.data();
        PyRun_SimpleString(simpleString2);
 
 
 
 
        //PyObject* pRet = PyObject_CallObject(pFunc, args);
 
    PyGILState_Release(state);
 
 
}

  

 

上面就是c++的文件代码,复制粘贴后,右键项目,然后生成dll

 

 

 

然后创一个文件夹是写python

 

 

 文件夹里面只需要放着3个箭头里面的东西就好,第一个CTP_API直接copy,dll也是从c++项目里面复制过来

python代码如下#cpy2.py

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#cpy2.py
 
 
 
import ctypes
import time
import os
from threading import Thread
 
 
 
# p3=Thread(target=, args=())                    
# p3.setDaemon(True)
# p3.start()
 
 
 
 
class klinesEntity():
    close=0
    def __init__(self) -> None:
        pass
 
    def set_c(self,c):
 
        print(c)
        self.close=c
 
    def get_c(self):
        return self.close
 
 
 
# def tickCall(c,bid1):
#     global bentity
#     bentity.set_c(float(c))
 
 
 
 
def c_change(str):
    return bytes(str,encoding='utf-8')
 
 
 
 
 
if __name__ == '__main__':
 
    bentity=klinesEntity()
     
 
    os.environ['path'] += ';'+os.getcwd()+"\CTP_API"
 
 
    lib=ctypes.CDLL(r"./ctp_cpyDLL.dll")
 
 
     
 
 
    pyrun=c_change("C:/Users/ccy/Anaconda3")
    pyfile=c_change("cpy2")
    klinesEntity_name=c_change("bentity")
 
 
    gBrokerID=c_change("")
    gInvesterID=c_change("")
    gInvesterPassword=c_change("")
    gMdFrontAddr=c_change("tcp://180.168.146.187:10212")
    gTradeFrontAddr=c_change("tcp://180.168.146.187:10202")
    symbol=c_change("rb2210")
 
 
 
    lib.init_(pyrun,pyfile,klinesEntity_name,
                gBrokerID,gInvesterID,gInvesterPassword,gMdFrontAddr,gTradeFrontAddr,
                symbol)
 
    while 1:
        print(bentity.get_c())
        time.sleep(1)
 
 
# def add(a,b): 
#     print ("These consequences are from Python code.") 
#     print ("a = " + str(a)) 
#     print ("b = " + str(b)) 
#     print ("ret = " + str(a+b)) 
#     return a + b

  

 

 

需要你输入gBrokerID,gInvesterID,gInvesterPassword,这3个东东是simnow要注册的,vnpy也是需要这3个东东的,

直接python cpy2.py就能运行了,(tips:一定要安装visual studio)

会一直打印最新的期货价格,原因是c++一直向python推送

1
string simpleString = klinesEntity_name+ ".set_c(" + to_string(c) + ")";

这句话一直推到python的class里面

 

有什么问题都可以问下我,我qq3475400294@qq.com  觉得我写得好记得点赞,代码那块需要自己看了,

 效果是这样的

 

 

 

 

 

 

 

 

 

posted @   毕业到现在的量化之路  阅读(962)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
点击右上角即可分享
微信分享提示