根据CTP接口计算现手、增仓、开平、对手盘 (2)

12 篇文章 1 订阅
7 篇文章 5 订阅

接上一篇,本文主要是实现计算的Python代码和C++代码

1、Python代码

Python代码逻辑主要参考《用CTP接口实现期货交易明细分析(1)》《用CTP接口实现期货交易明细分析(2)》,请知悉。但是原文中运用了vnpy的框架,我是用的自己编译的PythonAPI《CTP Python API(利用Swig 封装)Windows版(mduserapi)

代码如下:

# -*- coding:utf-8 -*-
import time
import thostmduserapi as mdapi
import copy


def enum(**enums):
    return type('Enum', (), enums)


# 仓位变化方向
open_interest_delta_forward_enum = enum(OPEN="Open", CLOSE="Close", EXCHANGE="Exchange", NONE="None",
                                        OPENFWDOUBLE="OpenFwDouble", CLOSEFWDOUBLE="CloseFwDOuble")
# 订单成交区域,决定是多还是空
order_forward_enum = enum(UP="Up", DOWN="Down", MIDDLE="Middle")

# 最终需要的tick方向
tick_type_enum = enum(OPENLONG="OpenLong", OPENSHORT="OpenShort", OPENDOUBLE="OpenDouble",
                      CLOSELONG="CloseLong", CLOSESHORT="CloseShort", CLOSEDOUBLE="CloseDouble",
                      EXCHANGELONG="ExchangeLong", EXCHANGESHORT="ExchangeShort",
                      OPENUNKOWN="OpenUnkown", CLOSEUNKOWN="CloseUnkown", EXCHANGEUNKOWN="ExchangeUnkown",
                      UNKOWN="Unkown", NOCHANGE="NoChange")

tick_color_enum = enum(RED="Red", GREEN="Green", WHITE="White")

tick_type_key_enum = enum(TICKTYPE="TickType", TICKCOLOR="TickColor")

# 只与计算对手单的组成相关
opponent_key_enum = enum(OPPOSITE="Opposite", SIMILAR="Similar")

# 只做翻译成中文使用,对应 tick_type_enum
tick_type_str_dict = {tick_type_enum.OPENLONG: "多开", tick_type_enum.OPENSHORT: "空开",
                      tick_type_enum.OPENDOUBLE: "双开",
                      tick_type_enum.CLOSELONG: "多平", tick_type_enum.CLOSESHORT: "空平",
                      tick_type_enum.CLOSEDOUBLE: "双平",
                      tick_type_enum.EXCHANGELONG: "多换", tick_type_enum.EXCHANGESHORT: "空换",
                      tick_type_enum.OPENUNKOWN: "未知开仓", tick_type_enum.CLOSEUNKOWN: "未知平仓",
                      tick_type_enum.EXCHANGEUNKOWN: "未知换仓",
                      tick_type_enum.UNKOWN: "未知", tick_type_enum.NOCHANGE: "没有变化",
                      tick_color_enum.RED: "红", tick_color_enum.GREEN: "绿", tick_color_enum.WHITE: "白"}

# 根据 open_interest_delta_forward_enum 和 order_forward_enum 计算出tick类型的字典
tick_type_cal_dict = {
    open_interest_delta_forward_enum.NONE:
        {
            order_forward_enum.UP: {tick_type_key_enum.TICKTYPE: tick_type_enum.NOCHANGE,
                                    tick_type_key_enum.TICKCOLOR: tick_color_enum.WHITE},
            order_forward_enum.DOWN: {tick_type_key_enum.TICKTYPE: tick_type_enum.NOCHANGE,
                                      tick_type_key_enum.TICKCOLOR: tick_color_enum.WHITE},
            order_forward_enum.MIDDLE: {tick_type_key_enum.TICKTYPE: tick_type_enum.NOCHANGE,
                                        tick_type_key_enum.TICKCOLOR: tick_color_enum.WHITE}
        },
    open_interest_delta_forward_enum.EXCHANGE:
        {
            order_forward_enum.UP: {tick_type_key_enum.TICKTYPE: tick_type_enum.EXCHANGELONG,
                                    tick_type_key_enum.TICKCOLOR: tick_color_enum.RED},
            order_forward_enum.DOWN: {tick_type_key_enum.TICKTYPE: tick_type_enum.EXCHANGESHORT,
                                      tick_type_key_enum.TICKCOLOR: tick_color_enum.GREEN},
            order_forward_enum.MIDDLE: {tick_type_key_enum.TICKTYPE: tick_type_enum.EXCHANGEUNKOWN,
                                        tick_type_key_enum.TICKCOLOR: tick_color_enum.WHITE}
        },
    open_interest_delta_forward_enum.OPENFWDOUBLE:
        {
            order_forward_enum.UP: {tick_type_key_enum.TICKTYPE: tick_type_enum.OPENDOUBLE,
                                    tick_type_key_enum.TICKCOLOR: tick_color_enum.RED},
            order_forward_enum.DOWN: {tick_type_key_enum.TICKTYPE: tick_type_enum.OPENDOUBLE,
                                      tick_type_key_enum.TICKCOLOR: tick_color_enum.GREEN},
            order_forward_enum.MIDDLE: {tick_type_key_enum.TICKTYPE: tick_type_enum.OPENDOUBLE,
                                        tick_type_key_enum.TICKCOLOR: tick_color_enum.WHITE}
        },
    open_interest_delta_forward_enum.OPEN:
        {
            order_forward_enum.UP: {tick_type_key_enum.TICKTYPE: tick_type_enum.OPENLONG,
                                    tick_type_key_enum.TICKCOLOR: tick_color_enum.RED},
            order_forward_enum.DOWN: {tick_type_key_enum.TICKTYPE: tick_type_enum.OPENSHORT,
                                      tick_type_key_enum.TICKCOLOR: tick_color_enum.GREEN},
            order_forward_enum.MIDDLE: {tick_type_key_enum.TICKTYPE: tick_type_enum.OPENUNKOWN,
                                        tick_type_key_enum.TICKCOLOR: tick_color_enum.WHITE}
        },
    open_interest_delta_forward_enum.CLOSEFWDOUBLE:
        {
            order_forward_enum.UP: {tick_type_key_enum.TICKTYPE: tick_type_enum.CLOSEDOUBLE,
                                    tick_type_key_enum.TICKCOLOR: tick_color_enum.RED},
            order_forward_enum.DOWN: {tick_type_key_enum.TICKTYPE: tick_type_enum.CLOSEDOUBLE,
                                      tick_type_key_enum.TICKCOLOR: tick_color_enum.GREEN},
            order_forward_enum.MIDDLE: {tick_type_key_enum.TICKTYPE: tick_type_enum.CLOSEDOUBLE,
                                        tick_type_key_enum.TICKCOLOR: tick_color_enum.WHITE}
        },
    open_interest_delta_forward_enum.CLOSE:
        {
            order_forward_enum.UP: {tick_type_key_enum.TICKTYPE: tick_type_enum.CLOSESHORT,
                                    tick_type_key_enum.TICKCOLOR: tick_color_enum.RED},
            order_forward_enum.DOWN: {tick_type_key_enum.TICKTYPE: tick_type_enum.CLOSELONG,
                                      tick_type_key_enum.TICKCOLOR: tick_color_enum.GREEN},
            order_forward_enum.MIDDLE: {tick_type_key_enum.TICKTYPE: tick_type_enum.CLOSEUNKOWN,
                                        tick_type_key_enum.TICKCOLOR: tick_color_enum.WHITE}
        },
}

# 只与计算对手单的组成相关,只有4种tick类型才需要计算对手单的组成
handicap_dict = {tick_type_enum.OPENLONG: {opponent_key_enum.OPPOSITE: tick_type_enum.CLOSELONG,
                                           opponent_key_enum.SIMILAR: tick_type_enum.OPENSHORT},
                 tick_type_enum.OPENSHORT: {opponent_key_enum.OPPOSITE: tick_type_enum.CLOSESHORT,
                                            opponent_key_enum.SIMILAR: tick_type_enum.OPENLONG},
                 tick_type_enum.CLOSELONG: {opponent_key_enum.OPPOSITE: tick_type_enum.OPENLONG,
                                            opponent_key_enum.SIMILAR: tick_type_enum.CLOSESHORT},
                 tick_type_enum.CLOSESHORT: {opponent_key_enum.OPPOSITE: tick_type_enum.OPENSHORT,
                                             opponent_key_enum.SIMILAR: tick_type_enum.CLOSELONG}
                 }


class CFtdcMdSpi(mdapi.CThostFtdcMdSpi):
    tapi=''
    def __init__(self,tapi):
        mdapi.CThostFtdcMdSpi.__init__(self)
        self.tapi=tapi
        self.PreDepthMarketData = None
		
    def OnRspUserLogin(self, *args):
        print "OnRspUserLogin"
        rsploginfield=args[0]
        rspinfofield=args[1]
        print "SessionID=",rsploginfield.SessionID
        print "ErrorID=",rspinfofield.ErrorID
        print "ErrorMsg=",rspinfofield.ErrorMsg
        mdapi.SubscribeMarketDataByManual(self.tapi,"T1803")
		
	def onFrontConnected(self):
		print "onFrontConnected"

    # ----------------------------------------------------------------------
	def onFrontDisconnected(self, *args):
		print "onFrontDisconnected"

    def OnRtnDepthMarketData(self, *args):        
        depthdata={}
        depthdata['AskPrice1']=args[0].AskPrice1
        depthdata['AskVolume1']=args[0].AskVolume1
        depthdata['BidPrice1']=args[0].BidPrice1
        depthdata['BidVolume1']=args[0].BidVolume1
        depthdata['BidVolume1']=args[0].BidVolume1
        depthdata['LastPrice']=args[0].LastPrice
        depthdata['Volume']=args[0].Volume
        depthdata['OpenInterest']=args[0].OpenInterest
        depthdata['UpdateTime']=args[0].UpdateTime
        depthdata['UpdateMillisec']=args[0].UpdateMillisec
        if self.PreDepthMarketData is not None:
            # 计算两tick之间的差值
            ask_price_delta = self.PreDepthMarketData['AskPrice1'] - depthdata['AskPrice1']
            ask_volume_delta = self.PreDepthMarketData['AskVolume1'] - depthdata['AskVolume1']
            bid_price_delta = self.PreDepthMarketData['BidPrice1'] - depthdata['BidPrice1']
            bid_volume_delta = self.PreDepthMarketData['BidVolume1'] - depthdata['BidVolume1']
            last_price_delta = self.PreDepthMarketData['LastPrice'] - depthdata['LastPrice']
            volume_delta = depthdata['Volume'] - self.PreDepthMarketData['Volume']
            open_interest_delta = int(depthdata['OpenInterest'] - self.PreDepthMarketData['OpenInterest'])

            # 编移量的显示字符串
            ask_price_delta_str = self.get_delta_str(self.PreDepthMarketData['AskPrice1'], depthdata['AskPrice1'])
            ask_volume_delta_str = self.get_delta_str(self.PreDepthMarketData['AskVolume1'], depthdata['AskVolume1'])
            bid_price_delta_str = self.get_delta_str(self.PreDepthMarketData['BidPrice1'], depthdata['BidPrice1'])
            bid_volume_delta_str = self.get_delta_str(self.PreDepthMarketData['BidVolume1'], depthdata['BidVolume1'])
            last_price_delta_str = self.get_delta_str(self.PreDepthMarketData['LastPrice'], depthdata['LastPrice'])

            # 如果ask或者bid价格对比上一个tick都发生了变化则不显示价格变化幅度
            if ask_price_delta != 0:
                ask_volume_delta_str = ''
            if bid_price_delta != 0:
                bid_volume_delta_str = ''
            # input1 计算订单是在ask范围内成交还是在bid范围内成交
            order_forward = self.get_order_forward(depthdata['LastPrice'], depthdata['AskPrice1'], depthdata['BidPrice1'],
                                                           self.PreDepthMarketData['LastPrice'],
                                                           self.PreDepthMarketData['AskPrice1'],
                                                           self.PreDepthMarketData['BidPrice1']) 
			# input2 计算仓位变化方向
            open_interest_delta_forward = self.get_open_interest_delta_forward(open_interest_delta,
                                                                                       volume_delta)  
            # f(input1,input2) = output1 根据成交区域和仓位变化方向计算出tick的类型
            tick_type_dict = tick_type_cal_dict[open_interest_delta_forward][order_forward]
            if open_interest_delta_forward != open_interest_delta_forward_enum.NONE:
                # 输出相关变量
                print "Ask\t" + str(depthdata['AskPrice1']) + ask_price_delta_str + "\t" + str(
                    depthdata['AskVolume1']) + ask_volume_delta_str \
                      + "\tBid\t" + str(depthdata['BidPrice1']) + bid_price_delta_str + "\t" + str(
                    depthdata['BidVolume1']) + bid_volume_delta_str

                print str(depthdata['UpdateTime']) + "." + str(depthdata['UpdateMillisec']) \
                      + "\t" + str(depthdata['LastPrice']) + last_price_delta_str \
                      + "\t成交 " + str(volume_delta) \
                      + "\t增仓 " + str(open_interest_delta) \
                      + "\t" + tick_type_str_dict[tick_type_dict[tick_type_key_enum.TICKTYPE]] \
                      + "\t" + tick_type_str_dict[tick_type_dict[tick_type_key_enum.TICKCOLOR]]

                if tick_type_dict[tick_type_key_enum.TICKTYPE] in handicap_dict.keys():
                    order_opposite, order_similar = CFtdcMdSpi.get_order_combination(open_interest_delta,
                                                                                       volume_delta)
                    print "对手单:" + tick_type_str_dict[
                              handicap_dict[tick_type_dict[tick_type_key_enum.TICKTYPE]][opponent_key_enum.OPPOSITE]] \
                          + " " + str(order_opposite) \
                          + "\t" + tick_type_str_dict[
                              handicap_dict[tick_type_dict[tick_type_key_enum.TICKTYPE]][opponent_key_enum.SIMILAR]] \
                          + " " + str(order_similar)

                print '--------------------------------------'  
        self.PreDepthMarketData = copy.copy(depthdata)
		
	# -----------------------------------------------------------------------
    @staticmethod
    def float_smaller_equal(smaller, bigger):
        return CFtdcMdSpi.float_bigger_equal(bigger, smaller)

    @staticmethod
    def float_bigger_equal(bigger, smaller):
        """ float型的数不能直接相等
        http://www.sharejs.com/codes/python/223
        """
        ret = False
        if abs(bigger - smaller) < 0.00001:
            ret = True
        elif bigger > smaller:
            ret = True

        return ret

    # ----------------------------------------------------------------------
    @staticmethod
    def get_open_interest_delta_forward(open_interest_delta, volume_delta):
        """根据成交量的差和持仓量的差来获取仓位变化的方向
            return: open_interest_delta_forward_enum
        """
        if open_interest_delta == 0 and volume_delta == 0:
            local_open_interest_delta_forward = open_interest_delta_forward_enum.NONE
        elif open_interest_delta == 0 and volume_delta > 0:
            local_open_interest_delta_forward = open_interest_delta_forward_enum.EXCHANGE
        elif open_interest_delta > 0:
            if open_interest_delta - volume_delta == 0:
                local_open_interest_delta_forward = open_interest_delta_forward_enum.OPENFWDOUBLE
            else:
                local_open_interest_delta_forward = open_interest_delta_forward_enum.OPEN
        elif open_interest_delta < 0:
            if open_interest_delta + volume_delta == 0:
                local_open_interest_delta_forward = open_interest_delta_forward_enum.CLOSEFWDOUBLE
            else:
                local_open_interest_delta_forward = open_interest_delta_forward_enum.CLOSE
        return local_open_interest_delta_forward

    # ----------------------------------------------------------------------
    @staticmethod
    def get_order_forward(last_price, ask_price1, bid_price1, pre_last_price, pre_ask_price1, pre_bid_price1):
        """获取成交的区域,根据当前tick的成交价和上个tick的ask和bid价格进行比对
           return: order_forward_enum
        """
        if CFtdcMdSpi.float_bigger_equal(last_price, pre_ask_price1):
            local_order_forward = order_forward_enum.UP
        elif CFtdcMdSpi.float_smaller_equal(last_price, pre_bid_price1):
            local_order_forward = order_forward_enum.DOWN
        else:
            if CFtdcMdSpi.float_bigger_equal(last_price, ask_price1):
                local_order_forward = order_forward_enum.UP
            elif CFtdcMdSpi.float_smaller_equal(last_price, bid_price1):
                local_order_forward = order_forward_enum.DOWN
            else:
                local_order_forward = order_forward_enum.MIDDLE

        return local_order_forward

    # ----------------------------------------------------------------------
    @staticmethod
    def get_order_combination(open_interest_delta, volume_delta):
        """根据成交量变化和持仓量的变化计算出对手单的组合

            仓位变化方向相反的单
                order_opposite
            仓位变化方向相同的单
                order_similar

        """
        open_interest_delta = open_interest_delta if open_interest_delta > 0 else -open_interest_delta
        volume_delta_single_side = volume_delta / 2.0
        open_close_delta = open_interest_delta - volume_delta_single_side + 0.0
        order_similar = volume_delta_single_side / 2 + open_close_delta / 2
        order_opposite = volume_delta_single_side / 2 - open_close_delta / 2

        return int(order_opposite), int(order_similar)

    @staticmethod
    def get_delta_str(pre, data):
        offset_str = ''
        if data > pre:
            offset_str = '(+' + str(data - pre) + ")"
        elif data < pre:
            offset_str = '(-' + str(pre - data) + ")"
        else:
            pass
        return offset_str		

def main():
    mduserapi=mdapi.CThostFtdcMdApi_CreateFtdcMdApi()
    mduserspi=CFtdcMdSpi(mduserapi)
    loginfield = mdapi.CThostFtdcReqUserLoginField()
    loginfield.BrokerID=""
    loginfield.UserID=""
    loginfield.Password=""
    loginfield.UserProductInfo="python dll"
    mduserapi.RegisterFront("tcp://180.168.146.187:10010")
    mduserapi.RegisterSpi(mduserspi)
    mduserapi.Init()
    time.sleep(1)
    mduserapi.ReqUserLogin(loginfield,0)
    mduserapi.Join()

if __name__ == '__main__':
    main()


2、C++代码

C++这块对手单的计算我没写。

#include <stdio.h>
#include <iostream>
#include <string>
#include <map>
using namespace std;
#include "ThostFtdcMdApi.h"
#pragma warning(disable:4996)


#define SIMNOW "tcp://180.168.146.187:10010"
TThostFtdcBrokerIDType g_chBrokerID = "";
TThostFtdcUserIDType g_chUserID = "";
TThostFtdcInvestorIDType g_chInvestorID = "";
TThostFtdcPasswordType g_chPassword = "";

class CSimpleHandler : public CThostFtdcMdSpi
{
public:
	enum open_interest_delta_forward_enum
	{
		OPEN, CLOSE, EXCHANGE, NONE, OPENFWDOUBLE, CLOSEFWDOUBLE
	};
	enum order_forward_enum
	{
		UP, DOWN, MIDDLE
	};
	enum tick_type_enum
	{
		OPENLONG, OPENSHORT, OPENDOUBLE,
		CLOSELONG, CLOSESHORT, CLOSEDOUBLE,
		EXCHANGELONG, EXCHANGESHORT,
		OPENUNKOWN, CLOSEUNKOWN, EXCHANGEUNKOWN,
		UNKOWN, NOCHANGE
	};
	enum tick_color_enum
	{
		RED, GREEN, WHITE
	};
	enum tick_type_key_enum
	{
		TICKTYPE, TICKCOLOR
	};
	enum opponent_key_enum
	{
		OPPOSITE, SIMILAR
	};

	// 构造函数,需要一个有效的指向CThostFtdcMduserApi实例的指针
	CSimpleHandler(CThostFtdcMdApi *pUserApi) :
		m_pUserApi(pUserApi) {
		memset(&m_preDepthMarketData, 0, sizeof(m_preDepthMarketData));
		init_tick_type_dict();
		init_tick_type_str_dict();
		init_handicap_dict();
	}
	~CSimpleHandler() {}
	// 当客户端与交易托管系统建立起通信连接,客户端需要进行登录
	virtual void OnFrontConnected()
	{
		printf("OnFrontConnected. \n");
		CThostFtdcReqUserLoginField reqUserLogin;
		memset(&reqUserLogin, 0, sizeof(reqUserLogin));
		strcpy(reqUserLogin.BrokerID, g_chBrokerID);
		strcpy(reqUserLogin.UserID, g_chUserID);
		strcpy(reqUserLogin.Password, g_chPassword);
		// 发出登陆请求
		int ret = m_pUserApi->ReqUserLogin(&reqUserLogin, 1234);


	}
	// 当客户端与交易托管系统通信连接断开时,该方法被调用
	virtual void OnFrontDisconnected(int nReason)
	{
		// 当发生这个情况后,API会自动重新连接,客户端可不做处理
		printf("OnFrontDisconnected.\n");
	}
	// 当客户端发出登录请求之后,该方法会被调用,通知客户端登录是否成功
	virtual void OnRspUserLogin(CThostFtdcRspUserLoginField
		*pRspUserLogin, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool
		bIsLast)
	{

		if (pRspInfo->ErrorID != 0) {
			// 端登失败,客户端需进行错误处理
			printf("Failed to login, errorcode=%d errormsg=%s requestid = %d chain = %d", pRspInfo->ErrorID, pRspInfo->ErrorMsg, nRequestID, bIsLast);
			return;
		}
		printf("OnRspUserLogin success.\n");
		printf("bIsLast[%d]", bIsLast);
		printf("nRequestID[%d]", nRequestID);
		printf("BrokerID[%s]", pRspUserLogin->BrokerID);
		printf("UserID[%s]", pRspUserLogin->UserID);
		printf("FrontID[%d]", pRspUserLogin->FrontID);
		printf("SessionID[%d]\n\n", pRspUserLogin->SessionID);

		char *ppInstrumentID[1];		
		ppInstrumentID[0] = "T1803";
		//ppInstrumentID[0] = "IF1803";		
                m_pUserApi->SubscribeMarketData(ppInstrumentID, 1);
	}
	virtual void OnRspError(CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
	{

		if (pRspInfo->ErrorID != 0) {
			// 端登失败,客户端需进行错误处理
			printf("OnRspError, errorcode=%d errormsg=%s requestid = %d chain = %d", pRspInfo->ErrorID, pRspInfo->ErrorMsg, nRequestID, bIsLast);
			return;
		}
	}

	virtual void OnRspSubMarketData(CThostFtdcSpecificInstrumentField *pSpecificInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
	{
		if (pSpecificInstrument)
		{
			printf("InstrumentID[%s]\n", pSpecificInstrument->InstrumentID);
		}
		else
		{
			printf("Null OnRspSubMarketData\n");
		}

	}


	virtual void OnRtnDepthMarketData(CThostFtdcDepthMarketDataField *pDepthMarketData)
	{
		if (pDepthMarketData && m_preDepthMarketData.LastPrice != 0)
		{
			// 计算两tick之间的差值
			cout << "Volume" << pDepthMarketData->Volume << "PreVolume" << m_preDepthMarketData.Volume << endl;
			cout << "OpenInterest" << pDepthMarketData->OpenInterest << "PreOpenInterest" << m_preDepthMarketData.OpenInterest << endl;
			double ask_price_delta = m_preDepthMarketData.AskPrice1 - pDepthMarketData->AskPrice1;
			int ask_volume_delta = m_preDepthMarketData.AskVolume1 - pDepthMarketData->AskVolume1;
			double	bid_price_delta = m_preDepthMarketData.BidPrice1 - pDepthMarketData->BidPrice1;
			int bid_volume_delta = m_preDepthMarketData.BidVolume1 - pDepthMarketData->BidVolume1;
			double last_price_delta = m_preDepthMarketData.LastPrice - pDepthMarketData->LastPrice;
			int volume_delta = pDepthMarketData->Volume - m_preDepthMarketData.Volume;
			int open_interest_delta = int(pDepthMarketData->OpenInterest - m_preDepthMarketData.OpenInterest);

			//编移量的显示字符串
			string ask_price_delta_str = get_delta_str(m_preDepthMarketData.AskPrice1, pDepthMarketData->AskPrice1);
			string	ask_volume_delta_str = get_delta_str(m_preDepthMarketData.AskVolume1, pDepthMarketData->AskVolume1);
			string bid_price_delta_str = get_delta_str(m_preDepthMarketData.BidPrice1, pDepthMarketData->BidPrice1);
			string bid_volume_delta_str = get_delta_str(m_preDepthMarketData.BidVolume1, pDepthMarketData->BidVolume1);
			string last_price_delta_str = get_delta_str(m_preDepthMarketData.LastPrice, pDepthMarketData->LastPrice);

			//如果ask或者bid价格对比上一个tick都发生了变化则不显示价格变化幅度
			if (ask_price_delta != 0)
				ask_volume_delta_str = "";
			if (bid_price_delta != 0)
				bid_volume_delta_str = "";

			//input1 计算订单是在ask范围内成交还是在bid范围内成交
			order_forward_enum	order_forward = get_order_forward(pDepthMarketData->LastPrice,
				pDepthMarketData->AskPrice1, pDepthMarketData->BidPrice1,
				m_preDepthMarketData.LastPrice, m_preDepthMarketData.AskPrice1, m_preDepthMarketData.BidPrice1);

			//input2 计算仓位变化方向
			open_interest_delta_forward_enum open_interest_delta_forward = get_open_interest_delta_forward(open_interest_delta,
				volume_delta);

			//f(input1, input2) = output1 根据成交区域和仓位变化方向计算出tick的类型
			TICK_TYPE tick_type_dict = m_tick_type_dict[open_interest_delta_forward][order_forward];
			
			if (open_interest_delta_forward != open_interest_delta_forward_enum::NONE)
			{	//# 输出相关变量
				cout << "Ask\t" << pDepthMarketData->AskPrice1 << ask_price_delta_str << "\t" << pDepthMarketData->AskVolume1
					<< ask_volume_delta_str << "\tBid\t" << pDepthMarketData->BidPrice1 << bid_price_delta_str << "\t" <<
					pDepthMarketData->BidVolume1 << bid_volume_delta_str << endl;

				cout << pDepthMarketData->UpdateTime << "." << pDepthMarketData->UpdateMillisec
					<< "\t" << pDepthMarketData->LastPrice << last_price_delta_str
					<< "\t成交 " << volume_delta
					<< "\t增仓 " << open_interest_delta << endl;
				
				cout << m_tick_type_str_dict[tick_type_dict[tick_type_key_enum::TICKTYPE]]
					<< "\t" << m_color_type_str_dict[tick_type_dict[tick_type_key_enum::TICKCOLOR]] << endl;

				cout<< "--------------------------------------" <<endl;
			}			
		}
		else
		{
			printf("Null depthMarketdata\n");
		}
		memcpy(&m_preDepthMarketData, pDepthMarketData, sizeof(m_preDepthMarketData));
	}

	template <typename T>
	string get_delta_str(T pre,T data)
	{
		string offset_str = "";
		if (data > pre)
		{
			offset_str = "(+" + to_string(data - pre) + ")";
		}
		else if (data < pre)
		{
			offset_str = "(-" + to_string(pre - data) + ")";
		}
		return offset_str;
	}

	open_interest_delta_forward_enum get_open_interest_delta_forward(int open_interest_delta,int volume_delta)
	{	/*根据成交量的差和持仓量的差来获取仓位变化的方向
		return : open_interest_delta_forward_enum
		*/
		open_interest_delta_forward_enum local_open_interest_delta_forward;
		if (open_interest_delta == 0 && volume_delta == 0)
			local_open_interest_delta_forward = open_interest_delta_forward_enum::NONE;
		else if (open_interest_delta == 0 && volume_delta > 0)
			local_open_interest_delta_forward = open_interest_delta_forward_enum::EXCHANGE;
		else if (open_interest_delta > 0)
		{ 
			if (open_interest_delta - volume_delta == 0)
				local_open_interest_delta_forward = open_interest_delta_forward_enum::OPENFWDOUBLE;
			else
				local_open_interest_delta_forward = open_interest_delta_forward_enum::OPEN;
		}
		else if (open_interest_delta < 0 )
		{
			if (open_interest_delta + volume_delta == 0)
				local_open_interest_delta_forward = open_interest_delta_forward_enum::CLOSEFWDOUBLE;
			else
				local_open_interest_delta_forward = open_interest_delta_forward_enum::CLOSE;
		}
		return local_open_interest_delta_forward;
	}
	
	order_forward_enum get_order_forward(double last_price, double ask_price1, double bid_price1,
		double pre_last_price, double pre_ask_price1, double pre_bid_price1)
	{
		enum order_forward_enum local_order_forward;
		//获取成交的区域,根据当前tick的成交价和上个tick的ask和bid价格进行比对
		if (last_price >= pre_ask_price1)
		{
			local_order_forward = order_forward_enum::UP;
		}
		else if (last_price <= pre_bid_price1)
		{
			local_order_forward = order_forward_enum::DOWN;
		}
		else
		{
			if (last_price >= ask_price1)
			{
				local_order_forward = order_forward_enum::UP;
			}
			else if (last_price <= bid_price1)
			{
				local_order_forward = order_forward_enum::DOWN;
			}
			else
			{
				local_order_forward = order_forward_enum::MIDDLE;
			}
		}
		return local_order_forward;
	}

	void init_tick_type_dict()
	{
		TICK_TYPE tick_type;
		tick_type[tick_type_key_enum::TICKTYPE] = tick_type_enum::NOCHANGE;
		tick_type[tick_type_key_enum::TICKCOLOR] = tick_color_enum::WHITE;
		m_tick_type_dict[open_interest_delta_forward_enum::NONE][order_forward_enum::UP] = tick_type;
		m_tick_type_dict[open_interest_delta_forward_enum::NONE][order_forward_enum::DOWN] = tick_type;
		m_tick_type_dict[open_interest_delta_forward_enum::NONE][order_forward_enum::MIDDLE] = tick_type;

		tick_type[tick_type_key_enum::TICKTYPE] = tick_type_enum::EXCHANGELONG;
		tick_type[tick_type_key_enum::TICKCOLOR] = tick_color_enum::RED;
		m_tick_type_dict[open_interest_delta_forward_enum::EXCHANGE][order_forward_enum::UP] = tick_type;
		tick_type[tick_type_key_enum::TICKTYPE] = tick_type_enum::EXCHANGESHORT;
		tick_type[tick_type_key_enum::TICKCOLOR] = tick_color_enum::GREEN;
		m_tick_type_dict[open_interest_delta_forward_enum::EXCHANGE][order_forward_enum::DOWN] = tick_type;
		tick_type[tick_type_key_enum::TICKTYPE] = tick_type_enum::EXCHANGEUNKOWN;
		tick_type[tick_type_key_enum::TICKCOLOR] = tick_color_enum::WHITE;
		m_tick_type_dict[open_interest_delta_forward_enum::EXCHANGE][order_forward_enum::MIDDLE] = tick_type;

		tick_type[tick_type_key_enum::TICKTYPE] = tick_type_enum::OPENDOUBLE;
		tick_type[tick_type_key_enum::TICKCOLOR] = tick_color_enum::RED;
		m_tick_type_dict[open_interest_delta_forward_enum::OPENFWDOUBLE][order_forward_enum::UP] = tick_type;
		tick_type[tick_type_key_enum::TICKTYPE] = tick_type_enum::OPENDOUBLE;
		tick_type[tick_type_key_enum::TICKCOLOR] = tick_color_enum::GREEN;
		m_tick_type_dict[open_interest_delta_forward_enum::OPENFWDOUBLE][order_forward_enum::DOWN] = tick_type;
		tick_type[tick_type_key_enum::TICKTYPE] = tick_type_enum::OPENDOUBLE;
		tick_type[tick_type_key_enum::TICKCOLOR] = tick_color_enum::WHITE;
		m_tick_type_dict[open_interest_delta_forward_enum::OPENFWDOUBLE][order_forward_enum::MIDDLE] = tick_type;

		tick_type[tick_type_key_enum::TICKTYPE] = tick_type_enum::OPENLONG;
		tick_type[tick_type_key_enum::TICKCOLOR] = tick_color_enum::RED;
		m_tick_type_dict[open_interest_delta_forward_enum::OPEN][order_forward_enum::UP] = tick_type;
		tick_type[tick_type_key_enum::TICKTYPE] = tick_type_enum::OPENSHORT;
		tick_type[tick_type_key_enum::TICKCOLOR] = tick_color_enum::GREEN;
		m_tick_type_dict[open_interest_delta_forward_enum::OPEN][order_forward_enum::DOWN] = tick_type;
		tick_type[tick_type_key_enum::TICKTYPE] = tick_type_enum::OPENUNKOWN;
		tick_type[tick_type_key_enum::TICKCOLOR] = tick_color_enum::WHITE;
		m_tick_type_dict[open_interest_delta_forward_enum::OPEN][order_forward_enum::MIDDLE] = tick_type;

		tick_type[tick_type_key_enum::TICKTYPE] = tick_type_enum::CLOSEDOUBLE;
		tick_type[tick_type_key_enum::TICKCOLOR] = tick_color_enum::RED;
		m_tick_type_dict[open_interest_delta_forward_enum::CLOSEFWDOUBLE][order_forward_enum::UP] = tick_type;
		tick_type[tick_type_key_enum::TICKTYPE] = tick_type_enum::CLOSEDOUBLE;
		tick_type[tick_type_key_enum::TICKCOLOR] = tick_color_enum::GREEN;
		m_tick_type_dict[open_interest_delta_forward_enum::CLOSEFWDOUBLE][order_forward_enum::DOWN] = tick_type;
		tick_type[tick_type_key_enum::TICKTYPE] = tick_type_enum::CLOSEDOUBLE;
		tick_type[tick_type_key_enum::TICKCOLOR] = tick_color_enum::WHITE;
		m_tick_type_dict[open_interest_delta_forward_enum::CLOSEFWDOUBLE][order_forward_enum::MIDDLE] = tick_type;

		tick_type[tick_type_key_enum::TICKTYPE] = tick_type_enum::CLOSESHORT;
		tick_type[tick_type_key_enum::TICKCOLOR] = tick_color_enum::RED;
		m_tick_type_dict[open_interest_delta_forward_enum::CLOSE][order_forward_enum::UP] = tick_type;
		tick_type[tick_type_key_enum::TICKTYPE] = tick_type_enum::CLOSELONG;
		tick_type[tick_type_key_enum::TICKCOLOR] = tick_color_enum::GREEN;
		m_tick_type_dict[open_interest_delta_forward_enum::CLOSE][order_forward_enum::DOWN] = tick_type;
		tick_type[tick_type_key_enum::TICKTYPE] = tick_type_enum::CLOSEUNKOWN;
		tick_type[tick_type_key_enum::TICKCOLOR] = tick_color_enum::WHITE;
		m_tick_type_dict[open_interest_delta_forward_enum::CLOSE][order_forward_enum::MIDDLE] = tick_type;
	}

	void init_handicap_dict()
	{
		m_handicap_dict[tick_type_enum::OPENLONG][opponent_key_enum::OPPOSITE] = tick_type_enum::CLOSELONG;
		m_handicap_dict[tick_type_enum::OPENLONG][opponent_key_enum::SIMILAR] = tick_type_enum::OPENSHORT;
	
		m_handicap_dict[tick_type_enum::OPENSHORT][opponent_key_enum::OPPOSITE] = tick_type_enum::CLOSESHORT;
		m_handicap_dict[tick_type_enum::OPENSHORT][opponent_key_enum::SIMILAR] = tick_type_enum::OPENLONG;

		m_handicap_dict[tick_type_enum::CLOSELONG][opponent_key_enum::OPPOSITE] = tick_type_enum::OPENLONG;
		m_handicap_dict[tick_type_enum::CLOSELONG][opponent_key_enum::SIMILAR] = tick_type_enum::CLOSESHORT;

		m_handicap_dict[tick_type_enum::CLOSESHORT][opponent_key_enum::OPPOSITE] = tick_type_enum::OPENSHORT;
		m_handicap_dict[tick_type_enum::CLOSESHORT][opponent_key_enum::SIMILAR] = tick_type_enum::CLOSELONG;
	}

	void init_tick_type_str_dict()
	{
		m_tick_type_str_dict[tick_type_enum::OPENLONG] = "多开";
		m_tick_type_str_dict[tick_type_enum::OPENSHORT] = "空开";
		m_tick_type_str_dict[tick_type_enum::OPENDOUBLE] = "双开";
		m_tick_type_str_dict[tick_type_enum::CLOSELONG] = "多平";
		m_tick_type_str_dict[tick_type_enum::CLOSESHORT] = "空平";
		m_tick_type_str_dict[tick_type_enum::CLOSEDOUBLE] = "双平";
		m_tick_type_str_dict[tick_type_enum::EXCHANGELONG] = "多换";
		m_tick_type_str_dict[tick_type_enum::EXCHANGESHORT] = "空换";
		m_tick_type_str_dict[tick_type_enum::OPENUNKOWN] = "未知开仓";
		m_tick_type_str_dict[tick_type_enum::CLOSEUNKOWN] = "未知平仓";
		m_tick_type_str_dict[tick_type_enum::EXCHANGEUNKOWN] = "未知换仓";
		m_tick_type_str_dict[tick_type_enum::UNKOWN] = "未知";
		m_tick_type_str_dict[tick_type_enum::NOCHANGE] = "没有变化";

		m_color_type_str_dict[tick_color_enum::RED] = "红";
		m_color_type_str_dict[tick_color_enum::GREEN] = "绿";
		m_color_type_str_dict[tick_color_enum::WHITE] = "白";
	}

private:
	// 指向CThostFtdcMduserApi实例的指针
	CThostFtdcMdApi *m_pUserApi;
	CThostFtdcDepthMarketDataField m_preDepthMarketData;
	typedef map<tick_type_key_enum, int> TICK_TYPE;
	typedef map<open_interest_delta_forward_enum, map<order_forward_enum, TICK_TYPE>> TICK_TYPE_DICT;
	TICK_TYPE_DICT m_tick_type_dict;
	typedef map<tick_type_enum, map<opponent_key_enum, int> > HANDICAP_DICT;
	HANDICAP_DICT m_handicap_dict;
	typedef map<int, string> TICK_TYPE_STR_DICT;
	TICK_TYPE_STR_DICT m_tick_type_str_dict;
	TICK_TYPE_STR_DICT m_color_type_str_dict;
};

int main()
{
	// 产生一个CThostFtdcTraderApi实例
	CThostFtdcMdApi *pUserApi = CThostFtdcMdApi::CreateFtdcMdApi();
	printf("ApiVersion[%s]\n", pUserApi->GetApiVersion());
	// 产生一个事件处理的实例
	CSimpleHandler sh(pUserApi);
	// 注册一事件处理的实例
	pUserApi->RegisterSpi(&sh);
	pUserApi->RegisterFront(SIMNOW);
	pUserApi->Init();
	pUserApi->Join();
	// 释放API实例
	pUserApi->Release();
	return 0;
}









评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值