Code Monkey home page Code Monkey logo

open-trade-gateway's Introduction

Introduction

Open Trade Gateway 是一套主要用于期货交易的中继服务器系统. 它可以接受客户端以 DIFF协议 (Differential Information Flow for Finance) 接入, 完成用户终端与期货柜台系统的数据交互.

本项目目前支持的期货交易柜台系统包括:

  • CTP
  • Femas 主席系统 (测试中)
  • 恒生 UFX 系统 (测试中)

DIFF Collection 中列出了一些支持本系统的终端产品

Install

本服务必须在Linux环境下安装运行。下面的安装步骤以 Debian 9 为例,其它 linux 发行版可能需要相应调整.

安装 openssl, libcurl, boost 等依赖库

用apt命令安装 openssl 和 libcurl:

sudo apt install libcurl4-openssl-dev

2019-03-21前的版本需要安装 boost 1.68.0, 参见 https://www.boost.org/doc/libs/1_68_0/more/getting_started/unix-variants.html

2019-03-21后的版本需要安装 boost 1.70.0, 参见 https://www.boost.org/users/history/version_1_70_0.html

安装 open-trade-gateway

获取 open-trade-gateway 代码:

git clone https://github.com/shinnytech/open-trade-gateway.git
编译与安装::
cd open-trade-gateway sudo make sudo make install

第一次安装后需要将如下两个路径加入/etc/ld.so.conf文件中

  • /usr/local/bin/
  • /usr/local/lib/

然后执行命令:ldconfig

Config

本系统运行需要两个配置文件:

/etc/open-trade-gateway/config.json,用于服务进程的一些配置项:

{
  "host": "0.0.0.0",                                      //提供服务的IP地址
  "port": 7788,                                           //提供服务的端口号
  "auto_confirm_settlement": false,                       //是否自动确认结算单
  "user_file_path": "/var/local/lib/open-trade-gateway",  //存放用户文件的目录,必须事先创建好
  "log_price_info":true,                                              //是否打印行情日志
  "use_new_inst_service":false                                                        //是否启用新版的合约服务
}

/etc/open-trade-gateway/broker_list.json 中可以设置一组或多组期货公司前置机:

[
  {
    "name": "simnow",//一个系统中要保证唯一性
    "type": "ctp",//交易系统类型,目前支持ctp(ctp非穿管版)、ctpse13(ctp穿管版6.3.13版)、ctpse(ctp穿管版6.3.15)、sim(快期模拟)四种
    "is_fens":false,//前置地址是否是Fens地址,只对type=ctp,ctpse或者ctpse13时有效,type=sim时忽略
    "broker_id": "9999",//broker_id,必须与交易系统中的设置一致
    "product_info": "abcd",//如果type=ctp,这里填写从期货公司申请的产品UserProductInfo;如果type=ctpse、或者ctpse13,这里填写从期货公司审请的中继产品RelayAppID;type=sim时忽略
    "auth_code":"VUZMGH==",//如果type=ctp,这里填写从期货公司申请的产品AuthCode(由对应的UserProductInfo生成);如果type=ctpse、或者ctpse13,这里填写从期货公司申请的中继产品AuthCode(由对应的RelayAppId生成);type=sim时忽略
    "trading_fronts": [//如果is_fens=false,这里填写ctp的交易前置机地址,如果is_fens=true,则这里填写ctp的命名服务地址,type=sim时忽略
    "tcp://218.202.237.33:10002"
    ]
  }
]

/etc/open-trade-gateway/broker_list.json中的一组配置也可以用/etc/open-trade-gateway/broker_list/目录下的一个文件来代替,如可以用simnow.json文件代替上面的配置:

{
  "name": "simnow",
  "type": "ctp",
  "is_fens":false,
  "broker_id": "9999",
  "product_info": "abcd",
  "auth_code":"VUZMGH==",
  "trading_fronts": [
  "tcp://218.202.237.33:10002"
  ]
}

Run

在命令行下运行服务器主程序:

open_trade_gateway

系统运行日志将输出到文件 /var/log/open-trade-gateway/open-trade-gateway.log 中,如果目录 /var/log/open-trade-gateway/ 不存在,请手工创建.

Test

主程序启动后,用任意websocket client 连接到服务端口,应该收到这样的信息:

{
  "aid": "rtn_brokers",
  "brokers": ["simnow"]
}

表示服务器主程序启动正常

负载均衡服务配置

1、首先按上述配置步骤在一台或者多台服务器上配置一个或者多个open_trade_gateway实例;

2、按下面的配置文件(文件名config-ms.json,需要安装在/etc/open-trade-gateway/下)的说明配置负载均衡服务器结点;

{
        "host":"0.0.0.0",//提供负载均衡服务的IP地址
        "port":5566,//负载均衡服务的端口号
        "slaveNodeList":[//在第1步中已经配好的open_trade_gateway实例列表
        {
                "name":"135",//结点名称,不能重复
                "host":"192.168.1.35",//open_trade_gateway实例的IP地址
                "port":"7788", //open_trade_gateway实例的端口号(注意:这里是字符串)
                "path":"/", //open_trade_gateway实例的路径,默认为"/"
                "bids": ["simnow","nhqhsopt"]   //bid名称列表,来自于broker_list.json的name字段
        },
        {
                "name":"136",
                "host":"192.168.1.36",
                "port":"7788",
                "path":"/",
                "bids": ["simnow","shzq"]
        },
        {
                "name":"137",
                "host":"192.168.1.37",
                "port":"7788",
                "path":"/",
                "bids": ["simnow","simsy"]
        }
        ]
}

3、上述配置的负载均衡服务器结点名称不可重复,如果重复,按步骤2中结点配置的顺序,先出现的有效,后出现的忽略;

4、一个bid可以出现在一个或者多个结点的bid名称列表中,如果一个bid只出现在一个结点中,则该bid的用户只会分配到该结点中;

5、如果一个bid出现在多个结点中,则该bid的用户会分别分配到不同的结点中,按当时总用户最少优先的原则分配;

6、如果一个bid没有出现在任何结点中,则该bid的用户会在所有结点中进行分配,按当时总用户最少优先的原则分配;

7、首先正确启动上述结点上的open_trade_gateway实例,最后启动负载均衡服务器open-trade-gateway-ms;

8、采用DIFF协议的客户端应用连接open-trade-gateway-ms的服务端口(上例中的5566)发送请求,open-trade-gateway-ms会根据请求的bid自动将请求转发到不同的open-trade-gateway结点进行处理,实现负载均衡;

条件单服务配置

1、目前,条件单服务只是一个逻辑上的服务,因此正常编译安装了open-trade-gateway之后就同时安装了条件单服务;

2、按下面的配置文件(文件名config-condition-order.json,需要安装在/etc/open-trade-gateway/下)的说明配置条件单服务;

{
 "run_server":true,
 "max_new_cos_per_day":20,
 "max_valid_cos_all":50,
 "auto_start_ctp_time": [{"weekday":1,"timespan":[{"begin":835,"end":840},{"begin":2040,"end":2045}]},
 {"weekday":2,"timespan":[{"begin":835,"end":840},{"begin":2040,"end":2045}]},
 {"weekday":3,"timespan":[{"begin":835,"end":840},{"begin":2040,"end":2045}]},
 {"weekday":4,"timespan":[{"begin":835,"end":840},{"begin":2040,"end":2045}]},
  {"weekday":5,"timespan":[{"begin":835,"end":840},{"begin":2040,"end":2045}]}
 ],
 "auto_close_ctp_time": [{"weekday":1,"timespan":[{"begin":1535,"end":1540}]},
 {"weekday":2,"timespan":[{"begin":235,"end":240},{"begin":1535,"end":1540}]},
 {"weekday":3,"timespan":[{"begin":235,"end":240},{"begin":1535,"end":1540}]},
 {"weekday":4,"timespan":[{"begin":235,"end":240},{"begin":1535,"end":1540}]},
 {"weekday":5,"timespan":[{"begin":235,"end":240},{"begin":1535,"end":1540}]},
 {"weekday":6,"timespan":[{"begin":235,"end":240}]}
 ],
 "auto_restart_process_time":  [{"weekday":1,"timespan":[{"begin":900,"end":1530},{"begin":2100,"end":2359}]},
 {"weekday":2,"timespan":[{"begin":0,"end":230},{"begin":900,"end":1530},{"begin":2100,"end":2359}]},
 {"weekday":3,"timespan":[{"begin":0,"end":230},{"begin":900,"end":1530},{"begin":2100,"end":2359}]},
 {"weekday":4,"timespan":[{"begin":0,"end":230},{"begin":900,"end":1530},{"begin":2100,"end":2359}]},
 {"weekday":5,"timespan":[{"begin":0,"end":230},{"begin":900,"end":1530},{"begin":2100,"end":2359}]},
 {"weekday":6,"timespan":[{"begin":0,"end":230}]}
 ]
}
  • "run_server"表示是否启用条件单服务,true表示启用,false表示不启用;
  • "max_new_cos_per_day"表示单个用户一个交易日能够添加的最大条件单数量限制,默认为20条;
  • "max_valid_cos_all"表示单个用户最多可同时持有的最大未触发条件单数量限制,包括非本交易日添加的,默认为50条;
  • "auto_start_ctp_time"表示自动重登录用户的时间段配置,在配置的时间段内,如果发现用户还没有登录交易系统,且用户有条件单数据,条件单服务会自动登录交易系统,以保证条件单能够正常被触发;
  • "auto_close_ctp_time": 表示自动关闭CTP实例的时间段配置,在配置的时间段内,系统会自动关闭CTP实例,以防止CTP在非交易时间段内发生崩溃,关闭CTP实例后用户仍然能够登录交易系统并查询用户截面数据,但不能下单;
  • "auto_restart_process_time":表示自动重启交易实例进程的时间段配置,在配置的时间段内,如果用户的交易实例进程崩溃,open-trade-gateway会自动重启该进程;如果open-trade-gateway进程在该配置项的时间段内重新启动,也会自动启动有条件单的用户进程;
  • 上述的三个时间段配置全部采用{"weekday":1,"timespan":[{"begin":835,"end":840},{"begin":2040,"end":2045}]的形式;
  • "weekday":XX定义一周的某一天,0表示周日,1表示周一,依次类推;
  • "timespan":[{"begin":835,"end":840},{"begin":2040,"end":2045}]表示一个时间区间的列表,列表项表示一天中的某个时间段,如{"begin":835,"end":840}表示早上8:30到8:40之间;

3、条件单服务配置文件修改后需要重启交易系统,open-trade-gateway只会在启动时加载config-condition-order.json配置文件;

Q&A

1、执行open_trade_gateway后,未启动重新返回命令行

解决:基本出现在编译完成后的首次运行,请检查是否对broker_list.json 、config.json重命名并配置。出现该问题时,一般/var/log/open-trade-gateway//open-trade-gateway.log中的提示信息是找不到config.json文件

open-trade-gateway's People

Contributors

kingmo888 avatar shinny-chengzhi avatar shinny-songyachao avatar shinny-yangyang avatar yymailb avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

open-trade-gateway's Issues

notify中部分通知增加一些信息

  1. 下单、撤单成功或失败信息的通知,包含信息:合约代码、下单方向、开平标志、手数,委托价格,
  2. 成交的通知,包含的信息:合约代码、下单方向、开平标志、成交价格、成交手数、

补充一个连接示例 (python)

在python中 做一个websocket_client 即可实现简单的登陆

注意 python有一个websockets的库不能用在这里, websockets是自己定义client/server 用socket来回传

使用 pip install websocket-client 来安装

websocket-client 详见websocket-client

=============================================

代码环境:

win10/ bash子系统搭建的debian 端口在7988
python 3.6.7 64位

simnow账号 可以替换成自己的

import websocket
try:
    import thread
except ImportError:
    import _thread as thread
import time
#PS:登陆人太多了 改了密码 使用自己的账户连吧
def login(name='xxxxxxx', password='xxxxx', broker='simnow'):
    return json.dumps({
        "aid": "req_login",
        "bid": str(broker),
        "user_name": str(name),
        "password": str(password),
    })

def on_message(ws, message):
    print(message)

def on_error(ws, error):
    print(error)

def on_close(ws):
    print("### closed ###")

def on_open(ws):
    def run(*args):
        for i in range(3):
            msg = login()
            ws.send(msg)
        time.sleep(1)
        ws.close()
        print("thread terminating...")
    thread.start_new_thread(run, ())

# PS:登陆人太多了 改了密码 使用自己的账户连吧
if __name__ == "__main__":
    websocket.enableTrace(True)
    ws = websocket.WebSocketApp("ws://127.0.0.1:7988",
                              on_message = on_message,
                              on_error = on_error,
                              on_close = on_close)
    ws.on_open = on_open
    ws.run_forever()

[bug] 持仓盈亏在开盘前计算有误

到下一个交易日的时候,开始撮合交易之前,所有昨仓的持仓盈亏应该都是0。
现在貌似是 持仓盈亏 = 上一个交易日的 (最新价-结算价) * 手数 * 合约乘数 ,这个时候实际是没有最新价的,盈亏应该是 0。

最新版本编译错误

环境 debian9
boost: 1.68.0


yutiansut@yutiansut:~/open-trade-gateway$ sudo make
g++ -o bin/open-trade-gateway -std=c++17 -pthread -g -O2 -flto -Icontrib/include/ -Isrc/ -Lcontrib/lib obj/datetime.o obj/http.o obj/trade_server.o obj/config.o obj/log.o obj/utility.o obj/trader_base.o obj/md_service.o obj/encoding.o obj/main.o obj/numset.o obj/ctp/ctp_define.o obj/ctp/ctp_spi.o obj/ctp/trader_ctp.o obj/sim/trader_sim.o -lssl -lcrypto -lthosttraderapi -lcurl -lboost_system -lstdc++fs -lrt
/tmp/cc1WV5p0.ltrans12.ltrans.o: In function `GenerateUniqFileName[abi:cxx11]()':
/home/yutiansut/open-trade-gateway/src/utility.cpp:20: warning: the use of `mktemp' is dangerous, better use `mkstemp' or `mkdtemp'
/usr/bin/ld: warning: libssl.so.1.0.2, needed by /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libcurl.so, may conflict with libssl.so.1.1
/usr/bin/ld: warning: libcrypto.so.1.0.2, needed by /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libcurl.so, may conflict with libcrypto.so.1.1
/tmp/cc1WV5p0.ltrans0.ltrans.o: In function `boost::system::error_code::error_code()':
/home/yutiansut/open-trade-gateway/contrib/include/boost/system/error_code.hpp:636: undefined reference to `boost::system::detail::system_category_instance'
/tmp/cc1WV5p0.ltrans0.ltrans.o: In function `__base_dtor ':
/home/yutiansut/open-trade-gateway/contrib/include/boost/asio/detail/object_pool.hpp:78: undefined reference to `boost::system::detail::system_category_instance'
/home/yutiansut/open-trade-gateway/contrib/include/boost/asio/detail/object_pool.hpp:79: undefined reference to `boost::system::detail::system_category_instance'
/home/yutiansut/open-trade-gateway/contrib/include/boost/asio/detail/object_pool.hpp:78: undefined reference to `boost::system::detail::system_category_instance'
/home/yutiansut/open-trade-gateway/contrib/include/boost/asio/detail/object_pool.hpp:79: undefined reference to `boost::system::detail::system_category_instance'
/tmp/cc1WV5p0.ltrans0.ltrans.o: In function `boost::system::error_category::std_category::equivalent(std::error_code const&, int) const':
/home/yutiansut/open-trade-gateway/contrib/include/boost/system/error_code.hpp:908: undefined reference to `boost::system::detail::generic_category_instance'
/home/yutiansut/open-trade-gateway/contrib/include/boost/system/error_code.hpp:923: undefined reference to `boost::system::detail::generic_category_instance'
/tmp/cc1WV5p0.ltrans0.ltrans.o: In function `boost::system::error_code::error_code(int, boost::system::error_category const&)':
/home/yutiansut/open-trade-gateway/contrib/include/boost/system/error_code.hpp:638: undefined reference to `boost::system::detail::generic_category_instance'
/tmp/cc1WV5p0.ltrans0.ltrans.o: In function `boost::system::error_category::std_category::equivalent(int, std::error_condition const&) const':
/home/yutiansut/open-trade-gateway/contrib/include/boost/system/error_code.hpp:878: undefined reference to `boost::system::detail::generic_category_instance'
/tmp/cc1WV5p0.ltrans0.ltrans.o: In function `boost::system::error_condition::error_condition(int, boost::system::error_category const&)':
/home/yutiansut/open-trade-gateway/contrib/include/boost/system/error_code.hpp:528: undefined reference to `boost::system::detail::generic_category_instance'
/tmp/cc1WV5p0.ltrans0.ltrans.o: In function `boost::asio::detail::op_queue<boost::asio::detail::scheduler_operation>::~op_queue() [clone .lto_priv.673]':
/home/yutiansut/open-trade-gateway/contrib/include/boost/asio/detail/op_queue.hpp:76: undefined reference to `boost::system::detail::system_category_instance'
/tmp/cc1WV5p0.ltrans0.ltrans.o: In function `boost::system::error_code::error_code()':
/home/yutiansut/open-trade-gateway/contrib/include/boost/system/error_code.hpp:636: undefined reference to `boost::system::detail::system_category_instance'
/tmp/cc1WV5p0.ltrans0.ltrans.o: In function `long boost::asio::detail::socket_ops::error_wrapper<long>(long, boost::system::error_code&)':
/home/yutiansut/open-trade-gateway/contrib/include/boost/asio/detail/impl/socket_ops.ipp:85: undefined reference to `boost::system::detail::system_category_instance'
/tmp/cc1WV5p0.ltrans0.ltrans.o: In function `int boost::asio::detail::socket_ops::error_wrapper<int>(int, boost::system::error_code&)':
/home/yutiansut/open-trade-gateway/contrib/include/boost/asio/detail/impl/socket_ops.ipp:85: undefined reference to `boost::system::detail::system_category_instance'
/tmp/cc1WV5p0.ltrans0.ltrans.o: In function `boost::enable_if<boost::system::is_error_code_enum<boost::asio::error::basic_errors>, boost::system::error_code>::type& boost::system::error_code::operator=<boost::asio::error::basic_errors>(boost::asio::error::basic_errors)':
/home/yutiansut/open-trade-gateway/contrib/include/boost/system/error_code.hpp:659: undefined reference to `boost::system::detail::system_category_instance'
/tmp/cc1WV5p0.ltrans0.ltrans.o:/home/yutiansut/open-trade-gateway/contrib/include/boost/asio/detail/impl/socket_ops.ipp:85: more undefined references to `boost::system::detail::system_category_instance' follow
collect2: error: ld returned 1 exit status
Makefile:15: recipe for target 'bin/open-trade-gateway' failed
make: *** [bin/open-trade-gateway] Error 1
yutiansut@yutiansut:~/open-trade-gateway$

新版本make报错 bind_front_handler’ is not a member of ‘boost::beast’

root@QATRADESERVER01:/home/yutiansut/open-trade-gateway# make
g++ -o obj/trade_server.o -MMD -MP -std=c++17 -pthread -g -O2 -flto -Icontrib/include/ -Isrc/ -c src/trade_server.cpp
src/trade_server.cpp: In member function ‘void trade_server::TradeSession::Run()’:
src/trade_server.cpp:85:9: error: ‘bind_front_handler’ is not a member of ‘boost::beast’
boost::beast::bind_front_handler(
^~~~~
src/trade_server.cpp: In member function ‘void trade_server::TradeSession::DoRead()’:
src/trade_server.cpp:106:9: error: ‘bind_front_handler’ is not a member of ‘boost::beast’
boost::beast::bind_front_handler(
^~~~~
src/trade_server.cpp: In member function ‘void trade_server::TradeSession::DoWrite()’:
src/trade_server.cpp:200:9: error: ‘bind_front_handler’ is not a member of ‘boost::beast’
boost::beast::bind_front_handler(
^~~~~
Makefile:19: recipe for target 'obj/trade_server.o' failed
make: *** [obj/trade_server.o] Error 1

SIM_TRADE 的疑似bug

在simtrade的时候, 于2019-03-08日 22:29:05发了一个订单给otg的sim

yutiansut@QATRADESERVER01:/var/log/open-trade-gateway$ cat log.0 | grep 2019-03-08T22:29                                                          
{"time": "2019-03-08T22:29:05.719401215+08:00", "level": "info", "msg": "trade session received package, session=0x555986d13c00", "pack": {"aid": 
"insert_order", "user_id": "100003", "order_id": "QA_DT_0201_NoexqGbC", "exchange_id": "DCE", "instrument_id": "j1905", "direction": "SELL", "offs
et": "OPEN", "volume": 1, "price_type": "LIMIT", "limit_price": 1993.0, "volume_condition": "ANY", "time_condition": "GFD"}}                      
{"time": "2019-03-08T22:29:05.745876265+08:00", "level": "info", "msg": "trade server send message success, session=0x555986d13c00, len=2022"}    
{"time": "2019-03-08T22:29:05.747768058+08:00", "level": "info", "msg": "trade session received package, session=0x555986d13c00", "pack": {"aid": 
"peek_message"}}                                                                                                                                  
{"time": "2019-03-08T22:29:06.213876732+08:00", "level": "info", "msg": "trade session received package, session=0x555986d13c00", "pack": {"aid": 
"insert_order", "user_id": "100003", "order_id": "QA_DT_0201_STMEtRcv", "exchange_id": "DCE", "instrument_id": "j1905", "direction": "BUY", "offse
t": "CLOSETODAY", "volume": 1, "price_type": "LIMIT", "limit_price": 2013.0, "volume_condition": "ANY", "time_condition": "GFD"}}                 
{"time": "2019-03-08T22:29:06.346292452+08:00", "level": "info", "msg": "trade server send message success, session=0x555986d13c00, len=1758"}    
{"time": "2019-03-08T22:29:06.348253524+08:00", "level": "info", "msg": "trade session received package, session=0x555986d13c00", "pack": {"aid": 
"peek_message"}}                                                                                                                                  

首先 观察日志 我们可以看到 OTG接受到了一个

SELL_OPEN的 J1905 焦煤1905的限价单 限价 1993 在 2019-03-08 22:29:05:719 接收到

此时我们查看接收到的 OTG返回的消息

 {'topic': 'sendorder', 'account_cookie': '100003', 'strategy_id': 'QA_DT_0201', 'order_direction': 'SELL', 'code': 'j1905', 'price': 1993.0, 'order_time': '2019-03-08 22:29:05.567753', 'exchange_id': 'DCE', 'order_offset': 'OPEN', 'volume': 1, 'order_id': 'QA_DT_0201_NoexqGbC'}
22:29:05 QUANTAXIS>>> {'100003': {'user_id': '100003', 'trading_day': '20190307', 'trade_more_data': False, 'accounts': {'CNY': {'user_id': '100003', 'currency': 'CNY', 'pre_balance': 0.0, 'deposit': 1000000.0, 'withdraw': 0.0, 'close_profit': 0.0, 'commission': 3.9, 'premium': 0.0, 'static_balance': 1000000.0, 'position_profit': 0.0, 'float_profit': 0.0, 'balance': 999996.1, 'margin': 11050.0, 'frozen_margin': 0.0, 'frozen_commission': 0.0, 'frozen_premium': 0.0, 'available': 988946.1, 'risk_ratio': 0.011050043095168105}}, 'positions': {'DCE.j1905': {'user_id': '100003', 'exchange_id': 'DCE', 'instrument_id': 'j1905', 'volume_long_today': 0, 'volume_long_his': 0, 'volume_long': 0, 'volume_long_frozen_today': 0, 'volume_long_frozen_his': 0, 'volume_long_frozen': 0, 'volume_short_today': 1, 'volume_short_his': 0, 'volume_short': 1, 'volume_short_frozen_today': 0, 'volume_short_frozen_his': 0, 'volume_short_frozen': 0, 'open_price_long': 0.0, 'open_price_short': 2023.5, 'open_cost_long': 0.0, 'open_cost_short': 202350.0, 'position_price_long': 0.0, 'position_price_short': 2023.5, 'position_cost_long': 0.0, 'position_cost_short': 202350.0, 'last_price': 2023.5, 'float_profit_long': 0.0, 'float_profit_short': 0.0, 'float_profit': 0.0, 'position_profit_long': 0.0, 'position_profit_short': 0.0, 'position_profit': 0.0, 'margin_long': 0.0, 'margin_short': 11050.0, 'margin': 11050.0}}, 'orders': {'QA_DT_0201_NoexqGbC': {'seqno': 4, 'user_id': '100003', 'order_id': 'QA_DT_0201_NoexqGbC', 'exchange_id': 'DCE', 'instrument_id': 'j1905', 'direction': 'SELL', 'offset': 'OPEN', 'volume_orign': 1, 'price_type': 'LIMIT', 'limit_price': 1993.0, 'time_condition': 'GFD', 'volume_condition': 'ANY', 'insert_date_time': 1552055345719513349, 'exchange_order_id': 'QA_DT_0201_NoexqGbC', 'status': 'FINISHED', 'volume_left': 0, 'last_msg': ''}}, 'trades': {'2': {'seqno': 3, 'user_id': '100003', 'trade_id': '2', 'exchange_id': 'DCE', 'instrument_id': 'j1905', 'order_id': 'QA_DT_0201_NoexqGbC', 'exchange_trade_id': '2', 'direction': 'SELL', 'offset': 'OPEN', 'volume': 1, 'price': 2023.5, 'trade_date_time': 1552055345745815359, 'commission': 3.9}}, 'banks': {}, 'transfers': {}}}

提取其中的有效trade字段 我们可以发现 OTG成功撮合了这笔单子 但是价格是2023.5

'trades': {'2': {'seqno': 3, 'user_id': '100003', 'trade_id': '2', 'exchange_id': 'DCE', 'instrument_id': 'j1905', 'order_id': 'QA_DT_0201_NoexqGbC', 'exchange_trade_id': '2', 'direction': 'SELL', 'offset': 'OPEN', 'volume': 1, 'price': 2023.5, 'trade_date_time': 1552055345745815359, 'commission': 3.9}}

这里就有很大的问题 因为从2018-03-08 晚上21:00开始 J1905品种的价格就没有超过2013 因此, 这个撮合价格非常可疑

回到OTG的 撮合代码来查看
https://github.com/shinnytech/open-trade-gateway/blob/master/src/sim/trader_sim.cpp#L375

void TraderSim::CheckOrderTrade(Order* order)
{
    auto ins = md_service::GetInstrument(order->symbol());
    if (order->price_type == kPriceTypeLimit){
        if (order->limit_price - 0.0001 > ins->upper_limit) {
            OutputNotify(1, u8"下单,已被服务器拒绝,原因:已撤单报单被拒绝价格超出涨停板", "WARNING");
            order->status = kOrderStatusFinished;
            UpdateOrder(order);
            return;
        }
        if (order->limit_price + 0.0001 < ins->lower_limit) {
            OutputNotify(1, u8"下单,已被服务器拒绝,原因:已撤单报单被拒绝价格跌破跌停板", "WARNING");
            order->status = kOrderStatusFinished;
            UpdateOrder(order);
            return;
        }
    }
    if (order->direction == kDirectionBuy && IsValid(ins->ask_price1)
        && (order->price_type == kPriceTypeAny || order->limit_price >= ins->ask_price1))
        DoTrade(order, order->volume_left, ins->ask_price1);
    if (order->direction == kDirectionSell && IsValid(ins->bid_price1)
        && (order->price_type == kPriceTypeAny || order->limit_price <= ins->bid_price1))
        DoTrade(order, order->volume_left, ins->bid_price1);
}

该函数调用了一个 md_service来获取此订单品种的行情,
而去行情部分代码https://github.com/shinnytech/open-trade-gateway/blob/master/src/md_service.cpp#L132
我们可以发现他连得是天勤的官方维护的行情端

所以怀疑是不是天勤的行情端的价格出错? 讲道理也不是很可能 因此报issue

大佬,咨询两点

  1. 是否有现成的golang的sdk。

  2. 该网关设计上是否可以支持扩展接入现货交易渠道。

  3. 最后感叹下,在中低频中使用这种网关来统一集成整合接入的交易所方案真的很好。

增加持仓、委托单字段

  1. 持仓信息增加字段:
    pos : 净持仓手数
    pos_long :多头持仓手数
    pos_short : 空头持仓手数
    orders :与此持仓相关的开仓/平仓挂单

  2. 委托单信息增加字段:
    is_dead :判定这个委托单是否确定已死亡(以后一定不会再产生成交)
    is_online : 判定这个委托单是否确定已报入交易所(即下单成功,无论是否成交)
    is_error :判定这个委托单是否确定是错单(即下单失败,一定不会有成交)
    trade_price : 平均成交价
    trade_records :成交记录

拼接key时没有使用分隔符

例如 OnRtnOrder 中

	std::stringstream ss;
	ss << pOrder->FrontID
		<< pOrder->SessionID
		<< pOrder->OrderRef
		<< pOrder->OrderSubmitStatus
		<< pOrder->OrderStatus;
	std::string strKey = ss.str();

[运维优化]boost 1.68.0 安装脚本

ECHO "install boost 1.68.0" 
cd ~

wget https://dl.bintray.com/boostorg/release/1.68.0/source/boost_1_68_0.tar.gz && tar -zxvf boost_1_68_0.tar.gz

cd boost_1_68_0 && ./bootstrap.sh && ./b2 && ./b2 install && ldconfig

之前能部署成功 现在报错

g++ -o bin/open-trade-gateway -std=c++17 -pthread -g -O2 -flto -Icontrib/include/ -Isrc/ -Lcontrib/lib obj/datetime.o obj/http.o obj/trade_server.o obj/config.o obj/log.o obj/utility.o obj/trader_base.o obj/md_service.o obj/encoding.o obj/main.o obj/numset.o obj/ctp/ctp_define.o obj/ctp/ctp_spi.o obj/ctp/trader_ctp.o obj/sim/trader_sim.o -lssl -lcrypto -lthosttraderapi -lcurl -lstdc++fs
lto1: fatal error: bytecode stream in file ‘obj/datetime.o’ generated with LTO version 5.2 instead of the expected 7.0
compilation terminated.

疑似bug : 关于昨仓的模拟的处理

因为自己的账户也在用python实现postion类的diff支持 因此来看看源代码的时候发现似乎有点问题:

https://github.com/shinnytech/open-trade-gateway/blob/master/open-trade-sim/tradersim2.cpp#L478 中, 会发现在sim 模拟的模式下,

  1. 没有对于平仓类型进行处理 [没有close/ close_today]的处理
  2. 似乎对于历史仓位没有任何处理

比如平仓的时候 应该先平掉昨仓(中金所的那种不考虑) 但是似乎全部是按close_today来算的

然后就导致昨仓的 volume_long_his / volume_short_his 只是个假字段...

这俩his字段只是用来增加到 volume_long/ volume_short 上 用于判断单子能不能发出去
这个问题略大 不知道是不是我不会c++所以没看懂

疑似bug

天勤的simtrade的loadUserDataFiles中会进行账户的处理

观察一个日志字段, 我们发现 trading_day 居然可以不是交易日

root@QATRADESERVER01:/var/local/lib/open-trade-gateway/QUANTAXIS# cat 100003
{"user_id":"100003","trading_day":"20190310","trade_more_data":false,"accounts":{"CNY":{"user_id":"100003","currency":"CNY","pre_balance":999996.1,"deposit":0.0,"withdraw":0.0,"close_profit":0.0,"commission":0.0,"premium":0.0,"static_balance":999996.1,"position_profit":3400.0,"float_profit":3400.0,"balance":1003396.1,"margin":11050.0,"frozen_margin":0.0,"frozen_commission":0.0,"frozen_premium":0.0,"available":992346.1,"risk_ratio":0.011012600108770588}},"positions":{"DCE.j1905":{"user_id":"100003","exchange_id":"DCE","instrument_id":"j1905","volume_long_today":0,"volume_long_his":0,"volume_long":0,"volume_long_frozen_today":0,"volume_long_frozen_his":0,"volume_long_frozen":0,"volume_short_today":0,"volume_short_his":1,"volume_short":1,"volume_short_frozen_today":0,"volume_short_frozen_his"

就导致 周五夜盘的order、trade被清除

实际上 周五夜盘是的trading_day应该是下周一的
因此这里存在bug

请教:快期v2客户端如何实现的自动登录期货保证金监控中心

你好,我最近在开发期货账户信息采集的东东,不过有个东西卡壳了,那就是期货保证金监控中心是怎么自动登录的?
我发现使用快期V2版本的时候,快期登录期货账户之后,立马就弹出期货保证金监控中心的页面,据我所知这个页面不是有个验证码么?快期如何实现的呢?
难道需要使用一些验证码识别库进行验证码的识别么?还是说快期和保证金监控中心有协议合作,可以直接免验证码登录。
希望可以给我点开发指导,谢谢啦!

改善资金数据字段更新不同步的情形

在目前版本中, 每次平仓成交后, 会先查询持仓记录, 再查询账户资金. 查询持仓记录返回时, 会重算position.position_profit, 并重算 account.position_profit, account.balance, account.available. 这会导致 account.balance 产生异常波动.

考虑以下改善方案:

  • 设置两个计数器 account_req_no 和 account_rsp_no, 初值均为0.
  • 每当收到成交记录时, account_req_no ++
  • 发起查账户资金请求时, 以 account_req_no 为 RequestId
  • 收到查账户资金成功回应时, 将回包的RequestId填回 account_rsp_no
  • 只有 account_rsp_no >= account_req_no 时, 才可以使用position中的字段更新account

position增加开盘持仓手数字段

给每个 position 增加两个字段: volume_long_yd 和 volume_short_yd, 分别表示今日开盘前某合约的双向持仓手数. 这两个值在整个交易日中应保持不变.

编译时报错,已经安装了相关的依赖包

make
g++ -o bin/open-trade-ctp -std=c++17 -pthread -g -O2 -flto -Icontrib/include/ -Iopen-trade-common/ -Lcontrib/lib -Lbin/ obj/ctp/ctp_define.o obj/ctp/tradectp.o obj/ctp/main.o -lssl -lcrypto -lcurl -lboost_system -lstdc++fs -lrt -lopen-trade-common -lboost_thread -lboost_filesystem -lboost_regex -lboost_chrono -lthosttraderapi
/usr/bin/ld: bin//libopen-trade-common.so: undefined reference to curl_easy_perform' /usr/bin/ld: bin//libopen-trade-common.so: undefined reference to curl_easy_init'
/usr/bin/ld: bin//libopen-trade-common.so: undefined reference to curl_slist_append' /usr/bin/ld: bin//libopen-trade-common.so: undefined reference to curl_easy_cleanup'
/usr/bin/ld: bin//libopen-trade-common.so: undefined reference to curl_slist_free_all' /usr/bin/ld: bin//libopen-trade-common.so: undefined reference to curl_easy_setopt'
collect2: error: ld returned 1 exit status
make: *** [Makefile:64: bin/open-trade-ctp] Error 1

[运维优化]使用killall 来快速关闭所有的otg实例

RT:

因为otg会自动开启多个子进程,来对应连进去的account, 而如果client没有关闭ws连接似乎无法直接销毁otg子进程, 使用KILLALL来解决运维问题

killall 命令需要先安装 psmisc包

sudo  apt install psmisc


root@QATRADESERVER01:/home/yutiansut/open-trade-gateway# ps -aux | grep open
root     15465  0.0  0.1 232800 25248 pts/3    S    10:45   0:00 /usr/local/bin/open-trade-gateway
root     15467  0.1  0.1 233908 18656 pts/3    Sl   10:45   0:28 /usr/local/bin/open-trade-gateway
root     15557  0.0  0.0 232800 16272 pts/3    Sl   12:59   0:02 /usr/local/bin/open-trade-gateway
root     15670  0.0  0.0  12784   972 pts/3    S+   16:14   0:00 grep open
root@QATRADESERVER01:/home/yutiansut/open-trade-gateway# killall -9 open-trade-gateway
root@QATRADESERVER01:/home/yutiansut/open-trade-gateway# ps -aux | grep open
root     15673  0.0  0.0  12784   980 pts/3    S+   16:15   0:00 grep open
[1]+  Killed                  nohup /usr/local/bin/open-trade-gateway
root@QATRADESERVER01:/home/yutiansut/open-trade-gateway#

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.