推倒再推倒 不断尝试才能不断进步

细数一下,自己尝试写基于CTP的程序化交易软件有以下:
1、第一次,是基于控制台的,就是网上找回来的别人写的demo,再修修改改而成的。
2、第二次,基于前面的版本,做了个有界面的,当然,这界面只是为了输出一些数据更容易查看,控制台的输出是怎样的,大学应该都知道的。
3、第三次,基于第一次的版本,做成Linux平台版本
4、第四次,基于第二次版本,做成了一个只记录行情数据的DataRecorder,尝试把行情分离出来
5、第五次,基于第四次和第二次,做成了有界面的,但行情数据没有分离的一个集合,而且添加了画K线,画指标的显示。
6、现在又有新想法,准备开第六次尝试,在尝试之前,写个文章,理顺一下思路

首先,展示一下第五次版本的样子
https://www.bilibili.com/video/BV1WB4y1w71g/
然后,第五次遇到的问题:
1,指标TR和ATR的计算公式算出来的值与TB内部的函数算出来的值有区别,这个问题还在作对比
2,CTP行情登录之后,前面5分钟内是可以获取到行情数据的,但这分钟之后,行情就没有了,就算是在OnRtnDepthMarketData这回调函数上加断点也进不到来,所以数据就没有更新了,这个问题排查了一个多星期,还没有结果,找个行情服务器IP也是不行,现在还没有解决。但是这个问题也暴露了一个问题,如果软件把行情放在一起了,那么,假如行情服务器出了问题,那么,程序有可能就要重启,那么重启这段时间的行情数据将会丢失,那么,重启后,K线数据会变形,策略信号等都一定有问题,所以这里提示我,一定要把行情另外做起来,而不能嵌入到交易程序中。另外,行情服务器最好还是多启用几个服务器,以防止一个服务器不行了,还有后备的,当然,最好还是多个期货公司提供的行情服务器。

所以第六次尝试,首先,把行情服务分离出来,然后通过网络或本地进程通信来传输行情数据。如果通过网络的话,那么,为了提高速度,行情服务器只合成K线数据(1分钟单一周期,不计算指标),尽可能的让行情服务器单纯一点。而客户端再负责把1分钟周期数据合成其它周期数据,并计算需要的指标。
目前在尝试的代码:
行情服务端:

#include <WinSock2.h>
#include <stdio.h>





SOCKET sockcli[10];		//全局变量,启动时,自动设置为0


SOCKET socketConnected[10];		//全局变量,启动时,自动设置为0


DWORD WINAPI RefeshData(LPVOID)
{
	int i = 0;
	char buff[100];

	//实验证明,如果客户端窗口关闭了,服务器端还是照样发信息,而且不会自动停下来
	while (true)
	{
		while (i < 10)
		{
			//向客户端发信息
			if (sockcli[i] > 0)
			{
				sprintf_s(buff, "This is the %d time to send sockcli[%d]!\n",i,i);
				send(sockcli[i], buff, strlen(buff), 0);
				printf(buff);
				memset(buff, 0, sizeof(buff));
			}

			i++;
		}
		i = 0;
		Sleep(1000);
	}

	return 0;

}




void ReFillData(SOCKET socketClient)
{
	//逐个合约逐个分钟Bar传送出去
	int i = 0;
	while (!strcmp("afc",""))
	{
		int SizeVec = 0;
	}
}
void AddClient(SOCKET socketClient)
{


}

void main()
{
	WORD wVersionRequested;
	WSAData wsaData;

	int err;

	wVersionRequested = MAKEWORD(1, 1);

	err = WSAStartup(wVersionRequested, &wsaData);		//加载Winsock库

	if (err != 0)
	{
		return;
	}

	if (LOBYTE(wsaData.wVersion) != 1 || \
		HIBYTE(wsaData.wVersion) != 1)
	{
		WSACleanup();		//终止Winsock库的使用
		return;
	}

	//创建套接字
	SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0);

	//绑定套接字到IP端口
	sockaddr_in addrSrv;
	addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
	addrSrv.sin_family = AF_INET;
	addrSrv.sin_port = htons(9527);

	if (SOCKET_ERROR == bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(sockaddr_in)) )
	{
		printf("bind socket failed. err == %d\n", ::GetLastError());
		closesocket(sockSrv);
		WSACleanup();
		return;
	}

	listen(sockSrv, 3);		//第二参数表示最大等待请求队列的大小
	sockaddr_in addrCli;
	int len = sizeof(sockaddr_in);
	printf("This is before accept!\n");

	
	int i = 0;
	while (true)
	{
		if (i >= 10)
		{
			break;	//目前调试时使用最大客户端数量为10
		}
		sockcli[i] = accept(sockSrv, (SOCKADDR*)&addrCli, &len);		//等待连接
		if (sockcli[i] != SOCKET_ERROR)
		{
			ReFillData(sockcli[i]);
			AddClient(sockcli[i]);
			if (i == 0)
			{
				//只在第一次成功时才启动子线程
				CreateThread(NULL,0,RefeshData, NULL,0,NULL);	//定时发送最新行情
			}
		}
		i++;
	}
}

客户端:

#include <WinSock2.h>
#include <stdio.h>
#include "SelfDefine/CustomStructType.h"

void main()
{
	WORD wVersionRequested;
	WSAData wsaData;

	int err;

	wVersionRequested = MAKEWORD(1, 1);

	err = WSAStartup(wVersionRequested, &wsaData);		//加载Winsock库

	if (err != 0)
	{
		return;
	}

	if (LOBYTE(wsaData.wVersion) != 1 || \
		HIBYTE(wsaData.wVersion) != 1)
	{
		WSACleanup();		//终止Winsock库的使用
		return;
	}

	//创建套接字
	SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0);

	//connect函数需要服务器端的信息
	sockaddr_in addrSrv;
	addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");		//inet_addr函数可以将点分十进制的IP字符串转成u long类型
	addrSrv.sin_family = AF_INET;
	addrSrv.sin_port = htons(9527);

	//连接服务器
	if (SOCKET_ERROR == connect(sockSrv, (SOCKADDR*)&addrSrv, sizeof(sockaddr_in)))
	{
		//连接错误
	}

	//现在以单一合约为例
	while (true)
	{
		BarData bar = { 0 };
		if (SOCKET_ERROR != recv(sockSrv, (char*)&bar, sizeof(BarData), 0))
		{//如果接收没问题,则处理数据

		}
	}

	closesocket(sockSrv);
	WSACleanup();
	
}

以上代码都是不完整的,现在只是大概的框架,因为是自己用的,所以性能上没有作过多要求。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值