diff --git a/vnpy/api/femas/vnfemas/vnfemasmd/vnfemasmd.cpp b/vnpy/api/femas/vnfemas/vnfemasmd/vnfemasmd.cpp
index ead42f4f..4ec0ddc9 100644
--- a/vnpy/api/femas/vnfemas/vnfemasmd/vnfemasmd.cpp
+++ b/vnpy/api/femas/vnfemas/vnfemasmd/vnfemasmd.cpp
@@ -53,7 +53,6 @@ void MdApi::OnRspUserLogin(CUstpFtdcRspUserLoginField *pRspUserLogin, CUstpFtdcR
}
if (pRspInfo)
{
- cout << "md OnRspUserLogin pRspInfo" << endl;
CUstpFtdcRspInfoField *task_error = new CUstpFtdcRspInfoField();
*task_error = *pRspInfo;
task.task_error = task_error;
@@ -314,7 +313,6 @@ void MdApi::processRspUserLogin(Task *task)
dict error;
if (task->task_error)
{
- cout << "md processRspUserLogin task_error" << endl;
CUstpFtdcRspInfoField *task_error = (CUstpFtdcRspInfoField*)task->task_error;
error["ErrorID"] = task_error->ErrorID;
error["ErrorMsg"] = toUtf(task_error->ErrorMsg);
diff --git a/vnpy/api/femas/vnfemas/vnfemasmd/vnfemasmd.vcxproj b/vnpy/api/femas/vnfemas/vnfemasmd/vnfemasmd.vcxproj
index 7d639493..dea02d7d 100644
--- a/vnpy/api/femas/vnfemas/vnfemasmd/vnfemasmd.vcxproj
+++ b/vnpy/api/femas/vnfemas/vnfemasmd/vnfemasmd.vcxproj
@@ -80,8 +80,8 @@
true
- C:\ProgramData\VNConda\include;$(SolutionDir);$(SolutionDir)..\include;$(SolutionDir)..\include\femas;$(IncludePath)
- C:\ProgramData\VNConda\libs;$(SolutionDir)..\libs;$(LibraryPath)
+ C:\Python37\include;$(SolutionDir);$(SolutionDir)..\include;$(SolutionDir)..\include\femas;$(IncludePath)
+ C:\Python37\libs;$(SolutionDir)..\libs;$(LibraryPath)
.pyd
$(SolutionDir)..\
@@ -95,10 +95,10 @@
false
- C:\ProgramData\VNConda\include;$(SolutionDir);$(SolutionDir)..\include;$(SolutionDir)..\include\femas;$(IncludePath)
+ C:\Python37\include;$(SolutionDir);$(SolutionDir)..\include;$(SolutionDir)..\include\femas;$(IncludePath)
$(ReferencePath)
.pyd
- C:\ProgramData\VNConda\libs;$(SolutionDir)..\libs;$(LibraryPath)
+ C:\Python37\libs;$(SolutionDir)..\libs;$(LibraryPath)
$(SolutionDir)..\
@@ -110,6 +110,7 @@
NOMINMAX;_CRT_SECURE_NO_WARNINGS;NOMINMAX;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;VNFEMASMD_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
true
stdafx.h
+ true
Console
@@ -125,6 +126,7 @@
NOMINMAX;_CRT_SECURE_NO_WARNINGS;NOMINMAX;_CRT_SECURE_NO_WARNINGS;_DEBUG;VNFEMASMD_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
true
stdafx.h
+ true
Console
@@ -145,6 +147,9 @@
true
stdafx.h
MultiThreaded
+ true
+ AnySuitable
+ Speed
Console
@@ -167,6 +172,9 @@
stdafx.h
MultiThreaded
+ true
+ AnySuitable
+ Speed
Console
diff --git a/vnpy/api/femas/vnfemas/vnfemasmd/vnfemasmd.vcxproj.filters b/vnpy/api/femas/vnfemas/vnfemasmd/vnfemasmd.vcxproj.filters
index 8578d85d..6f061d28 100644
--- a/vnpy/api/femas/vnfemas/vnfemasmd/vnfemasmd.vcxproj.filters
+++ b/vnpy/api/femas/vnfemas/vnfemasmd/vnfemasmd.vcxproj.filters
@@ -21,24 +21,24 @@
头文件
-
- 头文件
-
-
- 头文件
-
-
- 头文件
-
-
- 头文件
-
头文件
头文件
+
+ 头文件
+
+
+ 头文件
+
+
+ 头文件
+
+
+ 头文件
+
diff --git a/vnpy/api/femas/vnfemas/vnfemasmd/vnfemasmd.vcxproj.user b/vnpy/api/femas/vnfemas/vnfemasmd/vnfemasmd.vcxproj.user
index be250787..baf24173 100644
--- a/vnpy/api/femas/vnfemas/vnfemasmd/vnfemasmd.vcxproj.user
+++ b/vnpy/api/femas/vnfemas/vnfemasmd/vnfemasmd.vcxproj.user
@@ -1,4 +1,6 @@
-
+
+ false
+
\ No newline at end of file
diff --git a/vnpy/api/femas/vnfemas/vnfemastd/vnfemastd.cpp b/vnpy/api/femas/vnfemas/vnfemastd/vnfemastd.cpp
index e02fcda5..a071f8c1 100644
--- a/vnpy/api/femas/vnfemas/vnfemastd/vnfemastd.cpp
+++ b/vnpy/api/femas/vnfemas/vnfemastd/vnfemastd.cpp
@@ -91,11 +91,8 @@ void TdApi::OnRspUserLogin(CUstpFtdcRspUserLoginField *pRspUserLogin, CUstpFtdcR
}
if (pRspInfo)
{
- cout << "td OnRspUserLogin pRspInfo" << endl;
CUstpFtdcRspInfoField *task_error = new CUstpFtdcRspInfoField();
*task_error = *pRspInfo;
- cout << "td OnRspUserLogin pRspInfo errorid" <ErrorID << endl;
task.task_error = task_error;
}
task.task_id = nRequestID;
@@ -630,15 +627,12 @@ void TdApi::OnRspQryInvestorAccount(CUstpFtdcRspInvestorAccountField *pRspInvest
task.task_name = ONRSPQRYINVESTORACCOUNT;
if (pRspInvestorAccount)
{
- cout << "OnRspQryInvestorAccount" << endl;
- cout << pRspInvestorAccount->AccountID << endl;
CUstpFtdcRspInvestorAccountField *task_data = new CUstpFtdcRspInvestorAccountField();
*task_data = *pRspInvestorAccount;
task.task_data = task_data;
}
if (pRspInfo)
{
- cout << pRspInfo->ErrorMsg << endl;
CUstpFtdcRspInfoField *task_error = new CUstpFtdcRspInfoField();
*task_error = *pRspInfo;
task.task_error = task_error;
@@ -1427,7 +1421,6 @@ void TdApi::processRspUserLogin(Task *task)
dict error;
if (task->task_error)
{
- cout << "td processRspUserLogin task_error" << endl;
CUstpFtdcRspInfoField *task_error = (CUstpFtdcRspInfoField*)task->task_error;
error["ErrorID"] = task_error->ErrorID;
error["ErrorMsg"] = toUtf(task_error->ErrorMsg);
diff --git a/vnpy/api/femas/vnfemas/vnfemastd/vnfemastd.vcxproj b/vnpy/api/femas/vnfemas/vnfemastd/vnfemastd.vcxproj
index 73b0ea91..8fc2e28a 100644
--- a/vnpy/api/femas/vnfemas/vnfemastd/vnfemastd.vcxproj
+++ b/vnpy/api/femas/vnfemas/vnfemastd/vnfemastd.vcxproj
@@ -80,8 +80,8 @@
true
- C:\ProgramData\VNConda\include;$(SolutionDir);$(SolutionDir)..\include;$(SolutionDir)..\include\femas;$(IncludePath)
- C:\ProgramData\VNConda\libs;$(SolutionDir)..\libs;$(LibraryPath)
+ C:\Python37\include;$(SolutionDir);$(SolutionDir)..\include;$(SolutionDir)..\include\femas;$(IncludePath)
+ C:\Python37\libs;$(SolutionDir)..\libs;$(LibraryPath)
.pyd
$(SolutionDir)..\
@@ -95,8 +95,8 @@
false
.pyd
- C:\ProgramData\VNConda\include;$(SolutionDir);$(SolutionDir)..\include;$(SolutionDir)..\include\femas;$(IncludePath)
- C:\ProgramData\VNConda\libs;$(SolutionDir)..\libs;$(LibraryPath)
+ C:\Python37\include;$(SolutionDir);$(SolutionDir)..\include;$(SolutionDir)..\include\femas;$(IncludePath)
+ C:\Python37\libs;$(SolutionDir)..\libs;$(LibraryPath)
$(SolutionDir)..\
@@ -108,6 +108,7 @@
NOMINMAX;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;VNFEMASTD_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
true
stdafx.h
+ true
Console
@@ -123,6 +124,7 @@
NOMINMAX;_CRT_SECURE_NO_WARNINGS;_DEBUG;VNFEMASTD_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
true
stdafx.h
+ true
Console
@@ -142,6 +144,9 @@
true
stdafx.h
MultiThreaded
+ true
+ AnySuitable
+ Speed
Console
@@ -164,6 +169,9 @@
stdafx.h
MultiThreaded
+ true
+ AnySuitable
+ Speed
Console
diff --git a/vnpy/api/femas/vnfemas/vnfemastd/vnfemastd.vcxproj.filters b/vnpy/api/femas/vnfemas/vnfemastd/vnfemastd.vcxproj.filters
index e3ccc39a..ffdc3ec2 100644
--- a/vnpy/api/femas/vnfemas/vnfemastd/vnfemastd.vcxproj.filters
+++ b/vnpy/api/femas/vnfemas/vnfemastd/vnfemastd.vcxproj.filters
@@ -21,21 +21,21 @@
头文件
-
- 头文件
-
-
- 头文件
-
-
- 头文件
-
-
- 头文件
-
头文件
+
+ 头文件
+
+
+ 头文件
+
+
+ 头文件
+
+
+ 头文件
+
diff --git a/vnpy/api/femas/vnfemas/vnfemastd/vnfemastd.vcxproj.user b/vnpy/api/femas/vnfemas/vnfemastd/vnfemastd.vcxproj.user
index be250787..baf24173 100644
--- a/vnpy/api/femas/vnfemas/vnfemastd/vnfemastd.vcxproj.user
+++ b/vnpy/api/femas/vnfemas/vnfemastd/vnfemastd.vcxproj.user
@@ -1,4 +1,6 @@
-
+
+ false
+
\ No newline at end of file
diff --git a/vnpy/api/femas/vnfemasmd.pyd b/vnpy/api/femas/vnfemasmd.pyd
index a833a8e6..42069546 100644
Binary files a/vnpy/api/femas/vnfemasmd.pyd and b/vnpy/api/femas/vnfemasmd.pyd differ
diff --git a/vnpy/api/femas/vnfemastd.pyd b/vnpy/api/femas/vnfemastd.pyd
index d835714c..13222642 100644
Binary files a/vnpy/api/femas/vnfemastd.pyd and b/vnpy/api/femas/vnfemastd.pyd differ
diff --git a/vnpy/gateway/femas/femas_gateway.py b/vnpy/gateway/femas/femas_gateway.py
index 53a97415..9e2acc3e 100644
--- a/vnpy/gateway/femas/femas_gateway.py
+++ b/vnpy/gateway/femas/femas_gateway.py
@@ -14,7 +14,7 @@ from vnpy.api.femas import (
USTP_FTDC_OS_PartTradedQueueing,
USTP_FTDC_OS_AllTraded,
USTP_FTDC_OS_Canceled,
- USTP_FTDC_D_Buy,
+ USTP_FTDC_D_Buy,
USTP_FTDC_D_Sell,
USTP_FTDC_OPT_LimitPrice,
USTP_FTDC_OPT_AnyPrice,
@@ -30,7 +30,7 @@ from vnpy.api.femas import (
USTP_FTDC_VC_AV,
USTP_FTDC_TC_IOC,
USTP_FTDC_VC_CV,
- USTP_FTDC_AF_Delete
+ USTP_FTDC_AF_Delete,
)
from vnpy.trader.constant import (
Direction,
@@ -39,7 +39,7 @@ from vnpy.trader.constant import (
OrderType,
Product,
Status,
- OptionType
+ OptionType,
)
from vnpy.trader.gateway import BaseGateway
from vnpy.trader.object import (
@@ -56,8 +56,8 @@ from vnpy.trader.object import (
from vnpy.trader.utility import get_folder_path
from vnpy.trader.event import EVENT_TIMER
-USTP_FTDC_PD_Long = '2'
-USTP_FTDC_PD_Short = '3'
+USTP_FTDC_PD_Long = "2"
+USTP_FTDC_PD_Short = "3"
STATUS_FEMAS2VT = {
USTP_FTDC_CAS_Submitted: Status.SUBMITTING,
@@ -66,21 +66,21 @@ STATUS_FEMAS2VT = {
USTP_FTDC_OS_NoTradeQueueing: Status.NOTTRADED,
USTP_FTDC_OS_PartTradedQueueing: Status.PARTTRADED,
USTP_FTDC_OS_AllTraded: Status.ALLTRADED,
- USTP_FTDC_OS_Canceled: Status.CANCELLED
+ USTP_FTDC_OS_Canceled: Status.CANCELLED,
}
DIRECTION_VT2FEMAS = {
- Direction.LONG: USTP_FTDC_D_Buy,
- Direction.SHORT: USTP_FTDC_D_Sell
+ Direction.LONG: USTP_FTDC_D_Buy,
+ Direction.SHORT: USTP_FTDC_D_Sell,
}
ORDERTYPE_VT2FEMAS = {
OrderType.LIMIT: USTP_FTDC_OPT_LimitPrice,
- OrderType.MARKET: USTP_FTDC_OPT_AnyPrice
+ OrderType.MARKET: USTP_FTDC_OPT_AnyPrice,
}
OFFSET_VT2FEMAS = {
- Offset.OPEN: USTP_FTDC_OF_Open,
+ Offset.OPEN: USTP_FTDC_OF_Open,
Offset.CLOSE: USTP_FTDC_OF_Close,
Offset.CLOSETODAY: USTP_FTDC_OF_CloseYesterday,
Offset.CLOSEYESTERDAY: USTP_FTDC_OF_CloseToday,
@@ -92,18 +92,17 @@ DIRECTION_FEMAS2VT[USTP_FTDC_PD_Long] = Direction.LONG
DIRECTION_FEMAS2VT[USTP_FTDC_PD_Short] = Direction.SHORT
-
EXCHANGE_FEMAS2VT = {
"CFFEX": Exchange.CFFEX,
"SHFE": Exchange.SHFE,
"CZCE": Exchange.CZCE,
"DCE": Exchange.DCE,
- "INE": Exchange.INE
+ "INE": Exchange.INE,
}
OPTIONTYPE_FEMAS2VT = {
USTP_FTDC_OT_CallOptions: OptionType.CALL,
- USTP_FTDC_OT_PutOptions: OptionType.PUT
+ USTP_FTDC_OT_PutOptions: OptionType.PUT,
}
@@ -122,7 +121,7 @@ class FemasGateway(BaseGateway):
"password": "",
"brokerid": "",
"td_address": "",
- "md_address": ""
+ "md_address": "",
}
def __init__(self, event_engine):
@@ -140,15 +139,14 @@ class FemasGateway(BaseGateway):
td_address = setting["td_address"]
md_address = setting["md_address"]
-
if not td_address.startswith("tcp://"):
td_address = "tcp://" + td_address
if not md_address.startswith("tcp://"):
md_address = "tcp://" + md_address
-
+
self.td_api.connect(td_address, userid, password, brokerid)
self.md_api.connect(md_address, userid, password, brokerid)
-
+
self.init_query()
def subscribe(self, req: SubscribeRequest):
@@ -176,24 +174,31 @@ class FemasGateway(BaseGateway):
self.td_api.close()
self.md_api.close()
- def write_error(self, msg: str, error: dict):
- """"""
- error_id = error["ErrorID"]
- error_msg = error["ErrorMsg"]
+ def write_error(self, msg: str, error_id: int, error_msg: str):
msg = f"{msg},代码:{error_id},信息:{error_msg}"
- self.write_log(msg)
-
+ self.write_log(msg)
+
+ def if_error_write_error(self, msg: str, error: dict):
+ """
+ 当有错误的时候就输出错误,并返回True
+ """
+ error_id = error["ErrorID"]
+ if error_id:
+ error_msg = error["ErrorMsg"]
+ self.write_error(msg, error_id, error_msg)
+ return True
+
def process_timer_event(self, event):
""""""
self.count += 1
if self.count < 2:
return
self.count = 0
-
+
func = self.query_functions.pop(0)
func()
self.query_functions.append(func)
-
+
def init_query(self):
""""""
self.count = 0
@@ -207,20 +212,20 @@ class FemasMdApi(MdApi):
def __init__(self, gateway):
"""Constructor"""
super(FemasMdApi, self).__init__()
-
+
self.gateway = gateway
self.gateway_name = gateway.gateway_name
-
+
self.reqid = 0
-
+
self.connect_status = False
self.login_status = False
self.subscribed = set()
-
+
self.userid = ""
self.password = ""
self.brokerid = 0
-
+
def onFrontConnected(self):
"""
Callback when front server is connected.
@@ -241,28 +246,25 @@ class FemasMdApi(MdApi):
"""
Callback when user is logged in.
"""
- if not error["ErrorID"]:
- self.login_status = True
- self.gateway.write_log("onRspUserLogin行情服务器登录成功")
- self.gateway.write_log("行情服务器登录成功")
-
- for symbol in self.subscribed:
- self.subMarketData(symbol)
- else:
- self.gateway.write_error("行情登录失败", error)
-
+ if self.gateway.if_error_write_error("行情登录失败", error):
+ return
+ self.login_status = True
+ self.gateway.write_log("onRspUserLogin行情服务器登录成功")
+ self.gateway.write_log("行情服务器登录成功")
+
+ for symbol in self.subscribed:
+ self.subMarketData(symbol)
+
def onRspError(self, error: dict, reqid: int, last: bool):
"""
Callback when error occured.
"""
- self.gateway.write_error("行情接口报错", error)
-
+ self.gateway.if_error_write_error("行情接口报错", error)
+
def onRspSubMarketData(self, data: dict, error: dict, reqid: int, last: bool):
""""""
- if not error or not error["ErrorID"]:
+ if self.gateway.if_error_write_error("行情订阅失败", error):
return
-
- self.gateway.write_error("行情订阅失败", error)
def onRtnDepthMarketData(self, data: dict):
"""
@@ -274,7 +276,7 @@ class FemasMdApi(MdApi):
return
timestamp = f"{data['TradingDay']} {data['UpdateTime']}.{int(data['UpdateMillisec']/100)}"
-
+
tick = TickData(
symbol=symbol,
exchange=exchange,
@@ -292,9 +294,9 @@ class FemasMdApi(MdApi):
ask_price_1=data["AskPrice1"],
bid_volume_1=data["BidVolume1"],
ask_volume_1=data["AskVolume1"],
- gateway_name=self.gateway_name
+ gateway_name=self.gateway_name,
)
- self.gateway.on_tick(tick)
+ self.gateway.on_tick(tick)
def connect(self, address: str, userid: str, password: str, brokerid: int):
"""
@@ -303,7 +305,7 @@ class FemasMdApi(MdApi):
self.userid = userid
self.password = password
self.brokerid = brokerid
-
+
# If not connected, then start connection first.
if not self.connect_status:
path = get_folder_path(self.gateway_name.lower())
@@ -315,7 +317,7 @@ class FemasMdApi(MdApi):
# If already connected, then login immediately.
elif not self.login_status:
self.login()
-
+
def login(self):
"""
Login onto server.
@@ -323,12 +325,12 @@ class FemasMdApi(MdApi):
req = {
"UserID": self.userid,
"Password": self.password,
- "BrokerID": self.brokerid
+ "BrokerID": self.brokerid,
}
-
+
self.reqid += 1
self.reqUserLogin(req, self.reqid)
-
+
def subscribe(self, req: SubscribeRequest):
"""
Subscribe to tick data update.
@@ -336,7 +338,7 @@ class FemasMdApi(MdApi):
if self.login_status:
self.subMarketData(req.symbol)
self.subscribed.add(req.symbol)
-
+
def close(self):
"""
Close the connection.
@@ -351,58 +353,59 @@ class FemasTdApi(TdApi):
def __init__(self, gateway):
"""Constructor"""
super(FemasTdApi, self).__init__()
-
+
self.gateway = gateway
self.gateway_name = gateway.gateway_name
-
- self.reqid = 0
- self.localID = 0
-
+
+ self.reqid = int(10e5)
+ self.localID = int(10e5 + 8888)
+
self.connect_status = False
self.login_status = False
self.login_failed = False
-
+
self.userid = ""
self.password = ""
self.brokerid = 0
-
+
self.order_data = []
self.trade_data = []
self.positions = {}
self.sysid_orderid_map = {}
-
+
def onFrontConnected(self):
""""""
self.connect_status = True
self.gateway.write_log("onFrontConnected交易连接成功")
self.login()
-
+
def onFrontDisconnected(self, reason: int):
""""""
self.connect_status = False
self.login_status = False
self.gateway.write_log(f"交易连接断开,原因{reason}")
-
+
def onRspUserLogin(self, data: dict, error: dict, reqid: int, last: bool):
""""""
if not error["ErrorID"]:
- for k, v in data.items():
- print(k, ':', v)
-
- if data['MaxOrderLocalID']:
- self.localID = int(data['MaxOrderLocalID']) # 目前最大本地报单号
+ if data["MaxOrderLocalID"]:
+ self.localID = max(
+ self.localID, int(data["MaxOrderLocalID"])
+ ) # 目前最大本地报单号
self.login_status = True
self.gateway.write_log("onRspUserLogin交易登录成功")
self.reqid += 1
self.reqQryInstrument({}, self.reqid)
else:
self.login_failed = True
-
- self.gateway.write_error("交易登录失败", error)
-
+
+ self.gateway.if_error_write_error("交易登录失败", error)
+
def onRspOrderInsert(self, data: dict, error: dict, reqid: int, last: bool):
""""""
+ if self.gateway.if_error_write_error("交易委托失败", error):
+ return
orderid = data["UserOrderLocalID"]
symbol = data["InstrumentID"]
@@ -416,34 +419,35 @@ class FemasTdApi(TdApi):
price=data["LimitPrice"],
volume=data["Volume"],
status=Status.REJECTED,
- gateway_name=self.gateway_name
+ gateway_name=self.gateway_name,
)
self.gateway.on_order(order)
- self.gateway.write_error("交易委托失败", error)
-
def onRspOrderAction(self, data: dict, error: dict, reqid: int, last: bool):
""""""
- self.gateway.write_error("交易撤单失败", error)
-
+ if self.gateway.if_error_write_error("交易撤单失败", error):
+ return
+
def onRspQueryMaxOrderVolume(self, data: dict, error: dict, reqid: int, last: bool):
""""""
pass
-
- def onRspSettlementInfoConfirm(self, data: dict, error: dict, reqid: int, last: bool):
+
+ def onRspSettlementInfoConfirm(
+ self, data: dict, error: dict, reqid: int, last: bool
+ ):
"""
Callback of settlment info confimation.
"""
self.gateway.write_log("结算信息确认成功")
-
+
self.reqid += 1
self.reqQryInstrument({}, self.reqid)
-
+
def onRspQryInvestorPosition(self, data: dict, error: dict, reqid: int, last: bool):
""""""
if not data:
return
-
+
# Get buffered position object
key = f"{data['InstrumentID'], data['Direction']}"
position = self.positions.get(key, None)
@@ -452,50 +456,49 @@ class FemasTdApi(TdApi):
symbol=data["InstrumentID"],
exchange=symbol_exchange_map[data["InstrumentID"]],
direction=DIRECTION_FEMAS2VT[data["Direction"]],
- gateway_name=self.gateway_name
+ gateway_name=self.gateway_name,
)
self.positions[key] = position
position.yd_volume = data["YdPosition"]
# Calculate previous position cost
cost = position.price * position.volume
-
+
# Update new position volume
position.volume += data["Position"]
-
+
# Calculate average position price
if position.volume:
cost += data["PositionCost"]
position.price = cost / position.volume
-
+
# Get frozen volume
position.frozen += data["FrozenPosition"]
-
+
if last:
for position in self.positions.values():
self.gateway.on_position(position)
-
+
self.positions.clear()
-
+
def onRspQryInvestorAccount(self, data: dict, error: dict, reqid: int, last: bool):
""""""
- print ("onRspQryInvestorAccount")
account = AccountData(
accountid=data["AccountID"],
- frozen = data['LongMargin']+data['ShortMargin'],
- balance= data['PreBalance'],
- gateway_name=self.gateway_name
+ frozen=data["LongMargin"] + data["ShortMargin"],
+ balance=data["PreBalance"],
+ gateway_name=self.gateway_name,
)
-
+ # todo: check for error
self.gateway.on_account(account)
-
+
def onRspQryInstrument(self, data: dict, error: dict, reqid: int, last: bool):
"""
Callback of instrument query.
"""
contract = ContractData(
- product = data["ProductID"],
+ product=data["ProductID"],
symbol=data["InstrumentID"],
exchange=EXCHANGE_FEMAS2VT[data["ExchangeID"]],
name=data["InstrumentName"],
@@ -505,15 +508,15 @@ class FemasTdApi(TdApi):
option_type=OPTIONTYPE_FEMAS2VT.get(data["OptionsType"], None),
option_strike=data["StrikePrice"],
option_expiry=datetime.strptime(data["ExpireDate"], "%Y%m%d"),
- gateway_name=self.gateway_name
+ gateway_name=self.gateway_name,
)
-
+
self.gateway.on_contract(contract)
-
+
symbol_exchange_map[contract.symbol] = contract.exchange
symbol_name_map[contract.symbol] = contract.name
symbol_size_map[contract.symbol] = contract.size
-
+
if last:
self.gateway.write_log("合约信息查询成功")
@@ -522,7 +525,7 @@ class FemasTdApi(TdApi):
Callback of order status update.
"""
# 更新最大报单编号
- self.localID = max(self.localID, int(data['UserOrderLocalID'])) # 检查并增加本地报单编号
+ self.localID = max(self.localID, int(data["UserOrderLocalID"])) # 检查并增加本地报单编号
symbol = data["InstrumentID"]
exchange = symbol_exchange_map.get(symbol, "")
@@ -530,8 +533,7 @@ class FemasTdApi(TdApi):
self.order_data.append(data)
return
- orderid = data['UserOrderLocalID']
- print ("---------onRtnOrder-----------")
+ orderid = data["UserOrderLocalID"]
order = OrderData(
symbol=symbol,
exchange=exchange,
@@ -543,12 +545,12 @@ class FemasTdApi(TdApi):
traded=data["VolumeTraded"],
status=STATUS_FEMAS2VT[data["OrderStatus"]],
time=data["InsertTime"],
- gateway_name=self.gateway_name
+ gateway_name=self.gateway_name,
)
self.gateway.on_order(order)
-
+
self.sysid_orderid_map[data["OrderSysID"]] = orderid
-
+
def onRtnTrade(self, data: dict):
"""
Callback of trade status update.
@@ -560,7 +562,7 @@ class FemasTdApi(TdApi):
return
orderid = self.sysid_orderid_map[data["OrderSysID"]]
-
+
trade = TradeData(
symbol=symbol,
exchange=exchange,
@@ -571,10 +573,10 @@ class FemasTdApi(TdApi):
price=data["TradePrice"],
volume=data["TradeVolume"],
time=data["TradeTime"],
- gateway_name=self.gateway_name
+ gateway_name=self.gateway_name,
)
- self.gateway.on_trade(trade)
-
+ self.gateway.on_trade(trade)
+
def connect(self, address: str, userid: str, password: str, brokerid: int):
"""
Start connection to server.
@@ -584,21 +586,20 @@ class FemasTdApi(TdApi):
self.brokerid = brokerid
self.address = address
-
if not self.connect_status:
path = get_folder_path(self.gateway_name.lower())
self.createFtdcTraderApi(str(path) + "\\Td")
-
+
self.subscribePrivateTopic(0)
self.subscribePublicTopic(0)
self.subscribeUserTopic(0)
-
+
self.registerFront(address)
- self.init()
+ self.init()
else:
if not self.login_status:
- self.login()
-
+ self.login()
+
def login(self):
"""
Login onto server.
@@ -609,22 +610,21 @@ class FemasTdApi(TdApi):
req = {
"UserID": self.userid,
"Password": self.password,
- "BrokerID": self.brokerid
+ "BrokerID": self.brokerid,
}
-
+
self.reqid += 1
self.reqUserLogin(req, self.reqid)
-
+
def send_order(self, req: OrderRequest):
"""
Send new order.
"""
self.localID += 1
- strLocalID = str(self.localID)
- print ('----femasgateway type' + str(req.type))
+ strLocalID = str(self.localID).rjust(12, "0")
femas_req = {
"InstrumentID": req.symbol,
- "ExchangeID": str(req.exchange).split('.')[1],
+ "ExchangeID": str(req.exchange).split(".")[1],
"BrokerID": self.brokerid,
"InvestorID": self.userid,
"UserID": self.userid,
@@ -639,55 +639,48 @@ class FemasTdApi(TdApi):
"IsAutoSuspend": 0,
"TimeCondition": USTP_FTDC_TC_GFD,
"VolumeCondition": USTP_FTDC_VC_AV,
- "MinVolume": 1
+ "MinVolume": 1,
}
-
+
if req.type == OrderType.FAK:
femas_req["OrderPriceType"] = USTP_FTDC_OPT_LimitPrice
femas_req["TimeCondition"] = USTP_FTDC_TC_IOC
femas_req["VolumeCondition"] = USTP_FTDC_VC_AV
- print ("------------fak")
elif req.type == OrderType.FOK:
femas_req["OrderPriceType"] = USTP_FTDC_OPT_LimitPrice
femas_req["TimeCondition"] = USTP_FTDC_TC_IOC
femas_req["VolumeCondition"] = USTP_FTDC_VC_CV
- print ("------------fok")
-
- for key in femas_req:
- print(key + ':' + str(femas_req[key]))
self.reqid += 1
self.reqOrderInsert(femas_req, self.reqid)
-
+
orderid = femas_req["UserOrderLocalID"]
req.volume = femas_req["Volume"]
order = req.create_order_data(orderid, self.gateway_name)
self.gateway.on_order(order)
-
+
return order.vt_orderid
-
+
def cancel_order(self, req: CancelRequest):
"""
Cancel existing order.
"""
self.localID += 1
strLocalID = str(self.localID)
- print ('--cancel exchange--' + str(req.exchange).split('.')[1])
- print ('--cancel orderid--' + req.orderid)
femas_req = {
"InstrumentID": req.symbol,
- "ExchangeID": str(req.exchange).split('.')[1],
+ "ExchangeID": str(req.exchange).split(".")[1],
"UserOrderLocalID": req.orderid,
"UserOrderActionLocalID": strLocalID,
"ActionFlag": USTP_FTDC_AF_Delete,
"BrokerID": self.brokerid,
"InvestorID": self.userid,
- "UserID": self.userid
+ "UserID": self.userid,
}
-
+
self.reqid += 1
self.reqOrderAction(femas_req, self.reqid)
-
+
def query_account(self):
"""
Query account balance data.
@@ -695,27 +688,27 @@ class FemasTdApi(TdApi):
req = {
"BrokerID": self.brokerid,
"InvestorID": self.userid,
- "UserID": self.userid
+ "UserID": self.userid,
}
self.reqid += 1
self.reqQryInvestorAccount(req, self.reqid)
-
+
def query_position(self):
"""
Query position holding data.
"""
if not symbol_exchange_map:
return
-
+
req = {
"BrokerID": self.brokerid,
"InvestorID": self.userid,
- "UserID": self.userid
+ "UserID": self.userid,
}
-
- self.reqid += 1
+
+ self.reqid += 1
self.reqQryInvestorPosition(req, self.reqid)
-
+
def close(self):
""""""
if self.connect_status: