Пример #1
0
    def __init__(self):
        """Constructor"""
        self.eventEngine = EventEngine()  # 创建事件驱动引擎

        self.md = DemoMdApi(self.eventEngine)  # 创建API接口
        # self.md = DemoL2Api(self.ee)   # 如果使用L2行情就改为这行
        self.td = DemoTdApi(self.eventEngine)

        self.eventEngine.start()  # 启动事件驱动引擎
        self.dataEngine = DataEngine(self, self.eventEngine)

        # 循环查询持仓和账户相关
        self.countGet = 0  # 查询延时计数
        self.lastGet = 'Account'  # 上次查询的性质
        self.eventEngine.register(EVENT_TDLOGIN, self.initGet)  # 登录成功后开始初始化查询

        # 合约储存相关
        # self.dictInstrument = {}        # 字典(保存合约查询数据)
        # self.eventEngine.register(EVENT_INSTRUMENT, self.insertInstrument)
        # 接口实例
        self.gatewayDict = OrderedDict()
        self.gatewayDetailList = []

        # 应用模块实例
        self.appDict = OrderedDict()
        self.appDetailList = []

        # 风控引擎实例(特殊独立对象)
        self.rmEngine = None
Пример #2
0
class MainEngine():
    def __init__(self, event_engine:EventEngine=None):
        if event_engine:
            self.event_engine = event_engine
        else:
            self.event_engine = EventEngine()
        self.event_engine.start()

        self.gateways: dict[str, BaseGateway] = {}
        self.engines: dict[str, BaseEngine] = {}

    def add_engine(self, engine_class):
        engine = engine_class(self, self.event_engine)
        self.engines[engine.engine_name] = engine
        return engine
    
    # deal with gatewayclass same as engine
    def add_gateway(self, gateway_class):
        gateway = gateway_class(self, self.event_engine)
        self.gateways[gateway.engine_name] = gateway
        return gateway

    def connect(self, gateway_name):
        g = self.gateways[gateway_name]
        if g:
            g.start()
Пример #3
0
    def __init__(self):
        """Constructor
        :type self: object
        """
        self.ee = EventEngine()  # 创建事件驱动引擎

        self.md = DemoMdApi(self.ee)  # 创建API接口
        self.td = DemoTdApi(self.ee)

        self.ee.start()  # 启动事件驱动引擎
        self.havedposi = False
        self.position = {}
        self.todayposition = {}

        self.__orders = {}
        self.__retry = 0
        # 循环查询持仓和账户相关
        self.countGet = 0  # 查询延时计数
        self.lastGet = 'Account'  # 上次查询的性质
        self.ee.register(EVENT_TDLOGIN, self.initGet)  # 登录成功后开始初始化查询

        # 合约储存相关
        self.dictInstrument = {}  # 字典(保存合约查询数据)
        self.ee.register(EVENT_INSTRUMENT, self.insertInstrument)

        self.ee.register(EVENT_TRADE_DATA, self.get_trade)
        self.ee.register(EVENT_ORDER_DATA, self.get_order)
        self.ee.register(EVENT_ERROR, self.get_error)
        self.ee.register(EVENT_MARKETDATA_DATA, self.get_data)
        self.ee.register(EVENT_POSITION_DATA, self.get_position)
Пример #4
0
class MainEngine:
    """主引擎,负责对API的调度"""

    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        self.ee = EventEngine()  # 创建事件驱动引擎

        self.ee.start()  # 启动事件驱动引擎

        # 循环查询持仓和账户相关
        self.countGet = 0  # 查询延时计数
        self.lastGet = 'Account'  # 上次查询的性质

        # 合约储存相关
        self.dictInstrument = {}  # 字典(保存合约查询数据)

    #----------------------------------------------------------------------

    #----------------------------------------------------------------------
    def exit(self):
        """退出"""
        # 销毁API对象
        self.td = None
        self.md = None

        # 停止事件驱动引擎
        self.ee.stop()
Пример #5
0
    def __init__(self, event_engine:EventEngine=None):
        if event_engine:
            self.event_engine = event_engine
        else:
            self.event_engine = EventEngine()
        self.event_engine.start()

        self.gateways: dict[str, BaseGateway] = {}
        self.engines: dict[str, BaseEngine] = {}
Пример #6
0
    def __init__(self):
        """Constructor"""
        self.ee = EventEngine()  # 创建事件驱动引擎

        self.ee.start()  # 启动事件驱动引擎

        # 循环查询持仓和账户相关
        self.countGet = 0  # 查询延时计数
        self.lastGet = 'Account'  # 上次查询的性质

        # 合约储存相关
        self.dictInstrument = {}  # 字典(保存合约查询数据)
Пример #7
0
 def __init__(self):
     """Constructor
     :type self: object
     """
     self.ee = EventEngine()         # 创建事件驱动引擎
     
     self.md = DemoMdApi(self.ee)    # 创建API接口
     self.td = DemoTdApi(self.ee)
     
     self.ee.start()                 # 启动事件驱动引擎
     self.havedposi = False
     self.position = {}
     self.todayposition = {}
     
     self.__orders = {}
     self.__retry = 0
     # 循环查询持仓和账户相关
     self.countGet = 0               # 查询延时计数
     self.lastGet = 'Account'        # 上次查询的性质
     self.ee.register(EVENT_TDLOGIN, self.initGet)  # 登录成功后开始初始化查询
     
     # 合约储存相关
     self.dictInstrument = {}        # 字典(保存合约查询数据)
     self.ee.register(EVENT_INSTRUMENT, self.insertInstrument)
     
     self.ee.register(EVENT_TRADE_DATA, self.get_trade)
     self.ee.register(EVENT_ORDER_DATA, self.get_order)
     self.ee.register(EVENT_ERROR, self.get_error)
     self.ee.register(EVENT_MARKETDATA_DATA, self.get_data)
     self.ee.register(EVENT_POSITION_DATA, self.get_position)
Пример #8
0
    def __init__(self):
        """Constructor"""
        self.ee = EventEngine()  # 创建事件驱动引擎

        self.md = DemoMdApi(self.ee)  # 创建API接口
        self.td = DemoTdApi(self.ee)

        self.ee.start()  # 启动事件驱动引擎

        # 循环查询持仓和账户相关
        self.countGet = 0  # 查询延时计数
        self.lastGet = 'Account'  # 上次查询的性质
        self.ee.register(EVENT_TDLOGIN, self.initGet)  # 登录成功后开始初始化查询

        # 合约储存相关
        self.dictInstrument = {}  # 字典(保存合约查询数据)
        self.ee.register(EVENT_INSTRUMENT, self.insertInstrument)
Пример #9
0
    def __init__(self):
        """Constructor"""
        self.ee = EventEngine()         # 创建事件驱动引擎

        self.dsa = DemoStockApi(('192.168.16.59', 9991), self.ee)    # 现货报单
        self.dma = DemoMarketApi(('10.10.1.186', 9101), self.ee)    # 现货报单
        # self.md = DemoL2Api(self.ee)   # 如果使用L2行情就改为这行
        # self.td = DemoTdApi(self.ee)

        self.ee.start()                 # 启动事件驱动引擎

        # 循环查询持仓和账户相关
        self.countGet = 0               # 查询延时计数
        self.lastGet = 'Account'        # 上次查询的性质
        # self.ee.register(EVENT_TDLOGIN, self.initGet)  # 登录成功后开始初始化查询
        
        # 合约储存相关
        self.dictInstrument = {}        # 字典(保存合约查询数据)
Пример #10
0
def main(argv):
    ee = EventEngine()
    me = MainEngine(ee)
    me.add_gateway(Mt4Gateway)
    me.connect("Mt4Gateway")
    #ee.register("tick", debug_print)

    myEngine = me.add_engine(MyTestEngine)
    myEngine.init_engine()

    print("main...")
Пример #11
0
 def __init__(self):
     """Constructor"""
     self.ee = EventEngine()         # 创建事件驱动引擎
     
     self.md = DemoMdApi(self.ee)    # 创建API接口
     self.td = DemoTdApi(self.ee)
     
     self.ee.start()                 # 启动事件驱动引擎
     
     # 循环查询持仓和账户相关
     self.countGet = 0               # 查询延时计数
     self.lastGet = 'Account'        # 上次查询的性质
     self.ee.register(EVENT_TDLOGIN, self.initGet)  # 登录成功后开始初始化查询
     
     # 合约储存相关
     self.dictInstrument = {}        # 字典(保存合约查询数据)
     self.ee.register(EVENT_INSTRUMENT, self.insertInstrument)
Пример #12
0
    def __init__(self, ws, account, justCopySignal=False):
        """Constructor
        :type self: object
        """
        self.ee = EventEngine(account,ws)         # 创建事件驱动引擎
        self.justCopySignal = justCopySignal

        self.userid = account['userid']
        self.password = account['password']
        self.brokerid = account['brokerid']
        self.mdaddress = account['mdAddress']
        self.tdaddress = account['tdAddress']

        self.md = DemoMdApi(self.ee, self.mdaddress, self.userid, self.password, self.brokerid)    # 创建API接口
        self.td = DemoTdApi(self.ee, self.tdaddress, self.userid, self.password, self.brokerid)

        self.ee.start()                 # 启动事件驱动引擎
        self.havedposi = False
        self.position = {}
        self.todayposition = {}
        
        self.__orders = {}
        self.__retry = 0
        # 循环查询持仓和账户相关
        self.countGet = 0               # 查询延时计数
        self.lastGet = 'Account'        # 上次查询的性质
        self.ee.register(EVENT_TDLOGIN, self.initGet)  # 登录成功后开始初始化查询
        
        # 合约储存相关
        self.dictInstrument = {}        # 字典(保存合约查询数据)
        self.ee.register(EVENT_INSTRUMENT, self.insertInstrument)
        
        self.ee.register(EVENT_TRADE_DATA, self.get_trade)
        self.ee.register(EVENT_ORDER_DATA, self.get_order)
        self.ee.register(EVENT_ERROR, self.get_error)
        self.ee.register(EVENT_MARKETDATA_DATA, self.get_data)
        self.ee.register(EVENT_POSITION_DATA, self.get_position)
Пример #13
0
class MainEngine:
    """主引擎,负责对API的调度"""

    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        self.ee = EventEngine()         # 创建事件驱动引擎
        
        self.md = DemoMdApi(self.ee)    # 创建API接口
        self.td = DemoTdApi(self.ee)
        
        self.ee.start()                 # 启动事件驱动引擎
        
        # 循环查询持仓和账户相关
        self.countGet = 0               # 查询延时计数
        self.lastGet = 'Account'        # 上次查询的性质
        self.ee.register(EVENT_TDLOGIN, self.initGet)  # 登录成功后开始初始化查询
        
        # 合约储存相关
        self.dictInstrument = {}        # 字典(保存合约查询数据)
        self.ee.register(EVENT_INSTRUMENT, self.insertInstrument)
        
    #----------------------------------------------------------------------
    def login(self, userid, password, brokerid, mdAddress, tdAddress):
        """登陆"""
        self.md.login(mdAddress, userid, password, brokerid)
        self.td.login(tdAddress, userid, password, brokerid)
    
    #----------------------------------------------------------------------
    def subscribe(self, instrumentid, exchangeid):
        """订阅合约"""
        self.md.subscribe(instrumentid, exchangeid)
        
    #----------------------------------------------------------------------
    def getAccount(self):
        """查询账户"""
        self.td.getAccount()
        
    #----------------------------------------------------------------------
    def getInvestor(self):
        """查询投资者"""
        self.td.getInvestor()
        
    #----------------------------------------------------------------------
    def getPosition(self):
        """查询持仓"""
        self.td.getPosition()
    
    #----------------------------------------------------------------------
    def getInstrument(self):
        """获取合约"""
        event = Event(type_=EVENT_LOG)
        log = u'查询合约信息'
        event.dict_['log'] = log
        self.ee.put(event)          
        
        self.td.getInstrument()
        
    #----------------------------------------------------------------------
    def sendOrder(self, instrumentid, exchangeid, price, pricetype, volume, direction, offset):
        """发单"""
        ref = self.td.sendOrder(instrumentid, exchangeid, price, pricetype, volume, direction, offset)
        return str(ref)
    
    #----------------------------------------------------------------------
    def cancelOrder(self, instrumentid, exchangeid, orderref, frontid, sessionid):
        """撤单"""
        self.td.cancelOrder(instrumentid, exchangeid, orderref, frontid, sessionid)
        
    #----------------------------------------------------------------------
    def getAccountPosition(self, event):
        """循环查询账户和持仓"""
        self.countGet = self.countGet + 1
        
        # 每5秒发一次查询
        if self.countGet > 5:
            self.countGet = 0   # 清空计数
            
            if self.lastGet == 'Account':
                self.getPosition()
                self.lastGet = 'Position'
            else:
                self.getAccount()
                self.lastGet = 'Account'
    
    #----------------------------------------------------------------------
    def initGet(self, event):
        """在交易服务器登录成功后,开始初始化查询"""
        # 打开设定文件setting.vn
        f = shelve.open('setting.vn')
        
        # 尝试读取设定字典,若该字典不存在,则发出查询请求
        try:
            d = f['instrument']
            
            # 如果本地保存的合约数据是今日的,则载入,否则发出查询请求
            today = date.today()
            if d['date'] == today:
                self.dictInstrument = d['dictInstrument']
                
                event = Event(type_=EVENT_LOG)
                log = u'合约信息读取完成'
                event.dict_['log'] = log
                self.ee.put(event)            
    
                self.getInvestor()
                
                # 开始循环查询
                self.ee.register(EVENT_TIMER, self.getAccountPosition)                 
            else:
                self.getInstrument()
        except KeyError:
            self.getInstrument()
            
        f.close()
 
    #----------------------------------------------------------------------
    def insertInstrument(self, event):
        """插入合约对象"""
        data = event.dict_['data']
        last = event.dict_['last']
        
        self.dictInstrument[data['InstrumentID']] = data
        
        # 合约对象查询完成后,查询投资者信息并开始循环查询
        if last:
            # 将查询完成的合约信息保存到本地文件,今日登录可直接使用不再查询
            self.saveInstrument()
            
            event = Event(type_=EVENT_LOG)
            log = u'合约信息查询完成'
            event.dict_['log'] = log
            self.ee.put(event)            

            self.getInvestor()
            
            # 开始循环查询
            self.ee.register(EVENT_TIMER, self.getAccountPosition)              
        
    #----------------------------------------------------------------------
    def selectInstrument(self, instrumentid):
        """获取合约信息对象"""
        try:
            instrument = self.dictInstrument[instrumentid]
        except KeyError:
            instrument = None
        return instrument
    
    #----------------------------------------------------------------------
    def exit(self):
        """退出"""
        # 销毁API对象
        self.td = None
        self.md = None
        
        # 停止事件驱动引擎
        self.ee.stop()
        
    #----------------------------------------------------------------------
    def saveInstrument(self):
        """保存合约属性数据"""
        f = shelve.open('setting.vn')
        d = {}
        d['dictInstrument'] = self.dictInstrument
        d['date'] = date.today()
        f['instrument'] = d
        f.close()
Пример #14
0
    def __init__(self, ws, account, _plus_path, justCopySignal=False, useZmq = False, zmqServer = "tcp://localhost:9999"):
        """Constructor
        :type self: object
        """
        self.ee = EventEngine(account)         # 创建事件驱动引擎
        self.justCopySignal = justCopySignal

        self.userid = str(account['userid'])
        self.password = str(account['password'])
        self.brokerid = str(account['brokerid'])
        self.mdaddress = str(account['mdfront'])
        self.tdaddress = str(account['tdfront'])

        self.pluspath = _plus_path
        self.symbol = None
        self.socket = None
        self.websocket = ws             # websocket list to send msg

        if useZmq:
            context = zmq.Context()
            socket = context.socket(zmq.REQ)
            socket.connect(zmqServer)
            self.socket = socket

        self.ee.start()                 # 启动事件驱动引擎
        self.havedposi = False
        self.position = {}
        self.todayposition = {}
        self.lastError = 0
        self.lastTodo = 0

        self.__timer = time()+60
        self.__orders = {}
        self.__retry = 0
        self.__maxRetry = 5
        # 循环查询持仓和账户相关
        self.countGet = 0               # 查询延时计数
        self.lastGet = 'Account'        # 上次查询的性质
        self.ee.register(EVENT_TDLOGIN, self.initGet)  # 登录成功后开始初始化查询
        
        # 合约储存相关
        self.dictInstrument = {}        # 字典(保存合约查询数据)
        self.dictProduct = {}        # 字典(保存合约查询数据)
        self.dictExchange= {}
        self.volInstrument = {}
        self.subInstrument = set()
        self.subedInst = set()
        
        self.price = {} #   存储报价,分品种

        self.todo = 0

        self.ee.register(EVENT_ERROR,       self.get_error)
        self.ee.register(EVENT_INSTRUMENT,  self.insertInstrument)
        self.ee.register(EVENT_TIMER,       self.getAccountPosition)
        self.ee.register(EVENT_TRADE,       self.get_trade)
        self.ee.register(EVENT_ORDER,       self.get_order)
        self.ee.register(EVENT_TICK,        self.get_tick)
        self.ee.register(EVENT_POSITION,    self.get_position)

        import eventType
        for k,v in eventType.__dict__.items():
            if 'EVENT_' in k and v[0]!='_':
                self.ee.register(v,self.websocket_send)

        self.md = DemoMdApi(self.ee, self.mdaddress, self.userid, self.password, self.brokerid,plus_path=_plus_path)    # 创建API接口
        self.td = DemoTdApi(self.ee, self.tdaddress, self.userid, self.password, self.brokerid,plus_path=_plus_path)
Пример #15
0
from eventType import *
from eventEngine import EventEngine
import os
import tdxApi


def timer_fun(event):
    print("test_func:{}".format(event.type_))


if __name__ == "__main__":
    engine = EventEngine()
    engine.register(EVENT_TIMER, timer_fun)
    engine.start()
Пример #16
0
class MainEngine:

    #----------------------------------------------------------------------
    def __init__(self, account, _plus_path, bg):

        self.ee = EventEngine(account)  # 创建事件驱动引擎
        self.bridge = bg
        self.__lock = Lock()
        self.userid = str(account['userid'])
        self.password = str(account['password'])
        self.brokerid = str(account['brokerid'])
        self.mdaddress = str(account['mdfront'])
        self.tdaddress = str(account['tdfront'])
        self.instrument = account['instrument']  #   sub list str
        self.pluspath = _plus_path

        self.dictInstrument = {}  # 字典(保存合约查询数据)
        self.dictProduct = {}  # 字典(保存合约查询数据)
        self.dictExchange = {}
        self.tmpInstrument = {}  # 字典(保存合约查询数据)
        self.tmpProduct = {}  # 字典(保存合约查询数据)
        self.tmpExchange = {}
        self.dictUpdate = None
        self.subInstrument = set()
        self.subedInstrument = set()
        self.master = {}  #   记录主力合约对应关系
        self.masterSubed = False
        self.subedMaster = {}
        self.tickpass = set()
        self.now = datetime.now()
        self.socket = None
        self.coreServer = str(account['zmqserver'])
        self.corefunc = passit
        if int(account['usezmq']) > 0:
            if self.coreServer[:4] == 'tcp:':
                context = zmq.Context()
                socket = context.socket(zmq.REQ)
                socket.connect(self.coreServer)
                self.socket = socket
                self.corefunc = tcpfunc
            elif self.coreServer[:5] == 'http:':
                self.socket = True
                self.corefunc = httpfunc
        self.ee.start()  # 启动事件驱动引擎
        self.som = {}

        self.lastError = 0
        self.lastTodo = 0

        self.eq = 0

        # 循环查询持仓和账户相关
        self.countGet = 0  # 查询延时计数
        self.lastGet = 'Account'  # 上次查询的性质
        self.ee.register(EVENT_TDLOGIN, self.initGet, True)  # 登录成功后开始初始化查询

        self.__timer = time() + 3
        self.__readySubscribe = {}

        # 合约储存相关

        self.get_instrument()
        self.get_subscribe(self.instrument)
        self.ee.register(EVENT_MDLOGIN, self.ready_subscribe, True)
        self.ee.register(EVENT_TDLOGIN, self.ready_subscribe, True)
        self.ee.register(EVENT_ERROR, self.get_error, False)
        self.ee.register(EVENT_INSTRUMENT, self.insertInstrument, True)
        self.ee.register(EVENT_TIMER, self.getAccountPosition, False)
        self.ee.register(EVENT_TRADE, self.get_trade, False)
        self.ee.register(EVENT_ORDER, self.get_order, False)
        self.ee.register(EVENT_TICK, self.get_tick, True)
        self.ee.register(EVENT_POSITION, self.get_position, True)
        self.ee.register(EVENT_ACCOUNT, self.get_account, False)

        self.ee.register(EVENT_TICK, self.check_timer, False)

        import eventType
        for k, v in eventType.__dict__.items():
            if 'EVENT_' in k and v[0] != '_':
                self.ee.register(v, self.websocket_send, False)

        self.md = ctpMdApi(self,
                           self.mdaddress,
                           self.userid,
                           self.password,
                           self.brokerid,
                           plus_path=_plus_path)  # 创建API接口
        self.td = ctpTdApi(self,
                           self.tdaddress,
                           self.userid,
                           self.password,
                           self.brokerid,
                           plus_path=_plus_path)

    def get_subscribe(self, _inst):
        if '#' in _inst:
            _instlist = [(v.get('_vol_', 0), k)
                         for k, v in self.dictInstrument.items()]
            _instlist.sort(reverse=True)
            _only = set()
            for v, _instrumentid in _instlist[:10]:
                _product = self.dictInstrument[_instrumentid]['ProductID']
                if _product not in _only:
                    _exchangeid = self.dictInstrument.get(_instrumentid,
                                                          {}).get(
                                                              "ExchangeID", '')
                    self.subInstrument.add((_instrumentid, _exchangeid))
                    self.subedMaster[_instrumentid] = 1
                    self.tickpass.add(_instrumentid)
                    _only.add(_product)
            for _productid in ['IF', 'IH', 'IC']:
                if _productid in self.dictProduct and _productid not in _only:
                    _product = self.dictProduct[_productid]
                    _productlist = [(v, k) for k, v in _product.items()]
                    _productlist.sort(reverse=True)
                    _instrumentid = _productlist[0][-1]
                    _exchangeid = self.dictInstrument.get(_instrumentid,
                                                          {}).get(
                                                              "ExchangeID", '')
                    self.subInstrument.add((_instrumentid, _exchangeid))
                    self.master[_productid] = _product
                    self.subedMaster[_instrumentid] = 1
                    self.tickpass.add(_instrumentid)
            for _productid, _product in self.dictProduct.items():
                self.master[_productid] = _product

        else:
            _all = _inst.split('+')
            for one in _all:
                if '=' in one:
                    _productid = one[:-1]
                    if _productid in self.dictProduct:
                        _product = self.dictProduct[_productid]
                        _productlist = [(v, k) for k, v in _product.items()]
                        _productlist.sort(reverse=True)
                        _instrumentid = _productlist[0][-1]
                        _exchangeid = self.dictInstrument.get(
                            _instrumentid, {}).get("ExchangeID", '')
                        self.subInstrument.add((_instrumentid, _exchangeid))
                        self.master[_productid] = _product
                        self.subedMaster[_instrumentid] = 1
                        self.tickpass.add(_instrumentid)
                else:
                    _instrumentid = one
                    _exchangeid = self.dictInstrument.get(_instrumentid,
                                                          {}).get(
                                                              "ExchangeID", '')
                    self.subInstrument.add((_instrumentid, _exchangeid))
                    self.tickpass.add(_instrumentid)
            print(self.subInstrument)

    def ready_subscribe(self, event):
        self.__readySubscribe[event.type_] = 1
        if len(self.__readySubscribe) == 2:
            for one in self.subInstrument:
                if one[0] in self.subedMaster:
                    event = Event(type_=EVENT_LOG)
                    log = u'订阅主力合约:%s[%s]' % (
                        one[0], self.dictInstrument[one[0]]['InstrumentName'])
                    event.dict_['log'] = log
                    self.ee.put(event)
                else:
                    event = Event(type_=EVENT_LOG)
                    log = u'订阅合约:%s[%s]' % (
                        one[0], self.dictInstrument[one[0]]['InstrumentName'])
                    event.dict_['log'] = log
                    self.ee.put(event)
                self.subscribe(one[0], one[1])

    def get_instrument(self):
        _dict = self.bridge.get_instrument()
        self.dictInstrument = _dict.get('instrument', {})
        self.dictExchange = _dict.get('exchange', {})
        self.dictProduct = _dict.get('product', {})
        self.dictUpdate = _dict.get('day', None)

    def set_instrument(self):
        _dict = {}
        _dict['instrument'] = self.dictInstrument
        _dict['exchange'] = self.dictExchange
        _dict['product'] = self.dictProduct
        _dict['day'] = date.today()
        self.bridge.set_instrument(_dict)

    def get_som(self, event):
        try:
            symbol = event.dict_['data']['InstrumentID']
            if symbol:
                if symbol not in self.tickpass: return
                if symbol in self.som:
                    return self.som[symbol]
                else:
                    _data = None
                    if symbol in self.dictInstrument:
                        _data = self.dictInstrument[symbol]
                        event = Event(type_=EVENT_LOG)
                        log = u'初始化合约[%s]并填充其基本信息' % symbol
                        event.dict_['log'] = log
                        self.ee.put(event)
                    else:
                        _productid = filter(lambda x: x in _chars + _CHARS,
                                            symbol)
                        if _productid in self.dictProduct:
                            for _instrument in self.dictProduct[
                                    _productid].keys():
                                if _instrument in self.dictInstrument:
                                    _data = self.dictInstrument[_instrument]
                                    event = Event(type_=EVENT_LOG)
                                    log = u'注意:初始化合约[%s]但填充了<%s>的基本信息' % (
                                        symbol, _instrument)
                                    event.dict_['log'] = log
                                    self.ee.put(event)
                                    break
                    if _data:
                        one = SymbolOrdersManager(symbol, _data, self)
                        self.som[symbol] = one
                        return one
                    else:
                        event = Event(type_=EVENT_LOG)
                        log = u'警告:初始化合约[%s]失败,未发现其基本信息' % symbol
                        event.dict_['log'] = log
                        self.ee.put(event)
                        print(
                            "ctpEngine.py MainEngine get_som not found Instrument Info"
                        )
                        return None
            else:
                return None
        except Exception, e:
            print("ctpEngine.py MainEngine get_som ERROR", e)
            print(event.type_, event.dict_['data'])
Пример #17
0
    def __init__(self, account, _plus_path, bg):

        self.ee = EventEngine(account)  # 创建事件驱动引擎
        self.bridge = bg
        self.__lock = Lock()
        self.userid = str(account['userid'])
        self.password = str(account['password'])
        self.brokerid = str(account['brokerid'])
        self.mdaddress = str(account['mdfront'])
        self.tdaddress = str(account['tdfront'])
        self.instrument = account['instrument']  #   sub list str
        self.pluspath = _plus_path

        self.dictInstrument = {}  # 字典(保存合约查询数据)
        self.dictProduct = {}  # 字典(保存合约查询数据)
        self.dictExchange = {}
        self.tmpInstrument = {}  # 字典(保存合约查询数据)
        self.tmpProduct = {}  # 字典(保存合约查询数据)
        self.tmpExchange = {}
        self.dictUpdate = None
        self.subInstrument = set()
        self.subedInstrument = set()
        self.master = {}  #   记录主力合约对应关系
        self.masterSubed = False
        self.subedMaster = {}
        self.tickpass = set()
        self.now = datetime.now()
        self.socket = None
        self.coreServer = str(account['zmqserver'])
        self.corefunc = passit
        if int(account['usezmq']) > 0:
            if self.coreServer[:4] == 'tcp:':
                context = zmq.Context()
                socket = context.socket(zmq.REQ)
                socket.connect(self.coreServer)
                self.socket = socket
                self.corefunc = tcpfunc
            elif self.coreServer[:5] == 'http:':
                self.socket = True
                self.corefunc = httpfunc
        self.ee.start()  # 启动事件驱动引擎
        self.som = {}

        self.lastError = 0
        self.lastTodo = 0

        self.eq = 0

        # 循环查询持仓和账户相关
        self.countGet = 0  # 查询延时计数
        self.lastGet = 'Account'  # 上次查询的性质
        self.ee.register(EVENT_TDLOGIN, self.initGet, True)  # 登录成功后开始初始化查询

        self.__timer = time() + 3
        self.__readySubscribe = {}

        # 合约储存相关

        self.get_instrument()
        self.get_subscribe(self.instrument)
        self.ee.register(EVENT_MDLOGIN, self.ready_subscribe, True)
        self.ee.register(EVENT_TDLOGIN, self.ready_subscribe, True)
        self.ee.register(EVENT_ERROR, self.get_error, False)
        self.ee.register(EVENT_INSTRUMENT, self.insertInstrument, True)
        self.ee.register(EVENT_TIMER, self.getAccountPosition, False)
        self.ee.register(EVENT_TRADE, self.get_trade, False)
        self.ee.register(EVENT_ORDER, self.get_order, False)
        self.ee.register(EVENT_TICK, self.get_tick, True)
        self.ee.register(EVENT_POSITION, self.get_position, True)
        self.ee.register(EVENT_ACCOUNT, self.get_account, False)

        self.ee.register(EVENT_TICK, self.check_timer, False)

        import eventType
        for k, v in eventType.__dict__.items():
            if 'EVENT_' in k and v[0] != '_':
                self.ee.register(v, self.websocket_send, False)

        self.md = ctpMdApi(self,
                           self.mdaddress,
                           self.userid,
                           self.password,
                           self.brokerid,
                           plus_path=_plus_path)  # 创建API接口
        self.td = ctpTdApi(self,
                           self.tdaddress,
                           self.userid,
                           self.password,
                           self.brokerid,
                           plus_path=_plus_path)
Пример #18
0
class MainEngine:
    """主引擎,负责对API的调度"""

    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor
        :type self: object
        """
        self.ee = EventEngine()         # 创建事件驱动引擎
        
        self.md = DemoMdApi(self.ee)    # 创建API接口
        self.td = DemoTdApi(self.ee)
        
        self.ee.start()                 # 启动事件驱动引擎
        self.havedposi = False
        self.position = {}
        self.todayposition = {}
        
        self.__orders = {}
        self.__retry = 0
        # 循环查询持仓和账户相关
        self.countGet = 0               # 查询延时计数
        self.lastGet = 'Account'        # 上次查询的性质
        self.ee.register(EVENT_TDLOGIN, self.initGet)  # 登录成功后开始初始化查询
        
        # 合约储存相关
        self.dictInstrument = {}        # 字典(保存合约查询数据)
        self.ee.register(EVENT_INSTRUMENT, self.insertInstrument)
        
        self.ee.register(EVENT_TRADE_DATA, self.get_trade)
        self.ee.register(EVENT_ORDER_DATA, self.get_order)
        self.ee.register(EVENT_ERROR, self.get_error)
        self.ee.register(EVENT_MARKETDATA_DATA, self.get_data)
        self.ee.register(EVENT_POSITION_DATA, self.get_position)
        
    def set_app(self,_app):self.app = _app
    def get_order(self,event):
        _data = event.dict_['data']
        if _data['OrderStatus'] == '5':
            self.__retry += 1
            _saved = self.__orders.pop(int(_data['OrderRef'])) 
            if self.__retry>5:
                self.__retry = 0
                return 0
            print("Plus...Order")
            if _saved[6] == defineDict['THOST_FTDC_OF_Open']:
                _tr = 1
            elif _saved[6] == defineDict['THOST_FTDC_OF_Close']:
                _tr = -1
            else:
                _tr = 0
            if _saved[5] == defineDict["THOST_FTDC_D_Buy"]:
                _kr = 1
            elif _saved[5] == defineDict["THOST_FTDC_D_Sell"]:
                _kr = -1
            else:
                _kr = 0
            if _tr*_kr>0:
                price = float(_saved[2])+0.2
            else:
                price = float(_saved[2])-0.2
            _ref = self.td.sendOrder(_saved[0],_saved[1],price,_saved[3],_saved[4],_saved[5],_saved[6])
            self.__orders[_ref] = (_saved[0],_saved[1],price,_saved[3],_saved[4],_saved[5],_saved[6])
    def get_trade(self,event):
        _data = event.dict_['data']
        print('get_trade',_data['OrderRef'])
        _done = _data['Volume']
        if int(_data['OrderRef']) in self.__orders:
            _saved = self.__orders.pop(int(_data['OrderRef']))
            _goon = _saved[4] - _done
        else:
            _goon = 0
        if _goon != 0:
            self.__retry += 1
            if self.__retry>5:
                self.__retry = 0
                return 0
            print("Plus...Trade")
            if _saved[6] == defineDict['THOST_FTDC_OF_Open']:
                _tr = 1
            elif _saved[6] == defineDict['THOST_FTDC_OF_Close']:
                _tr = -1
            else:
                _tr = 0
            if _saved[5] == defineDict["THOST_FTDC_D_Buy"]:
                _kr = 1
            elif _saved[5] == defineDict["THOST_FTDC_D_Sell"]:
                _kr = -1
            else:
                _kr = 0
            if _tr*_kr>0:
                price = float(_saved[2])+0.2
            else:
                price = float(_saved[2])-0.2
            _ref = self.td.sendOrder(_saved[0],_saved[1],price,_saved[3],_goon,_saved[5],_saved[6])
            self.__orders[_ref] = (_saved[0],_saved[1],price,_saved[3],_goon,_saved[5],_saved[6])
    def set_symbol(self,_s):
        self.symbol = _s
    def set_socket(self,_s):
        self.socket = _s
    def get_position(self,event):
        _data = event.dict_['data']
        if _data['TodayPosition']:
            self.todayposition[_data['PosiDirection']] = _data['TodayPosition']
        if _data['Position']:pass
#            self.position[_data['PosiDirection']] = _data['Position']
        self.havedposi = True
        self.__orders = {}
    def openPosition(self,tr,volume):
        self.__retry = 0
        offset = defineDict['THOST_FTDC_OF_Open']
        pricetype = defineDict['THOST_FTDC_OPT_LimitPrice']
        if tr>0:
            price = self.ask+0.2*2.0
            direction = defineDict["THOST_FTDC_D_Buy"]
        else:   
            price = self.bid-0.2*2.0
            direction = defineDict["THOST_FTDC_D_Sell"]
        _ref = self.td.sendOrder(self.symbol,self.exchangeid,price,pricetype,volume,direction,offset)
        self.__orders[_ref] = (self.symbol,self.exchangeid,price,pricetype,volume,direction,offset)
    def closePosition(self,tr,volume):
        self.__retry = 0
        offset = defineDict['THOST_FTDC_OF_Close']
        pricetype = defineDict['THOST_FTDC_OPT_LimitPrice']
        if tr<0:
            price = self.ask+0.2*2.0
            direction = defineDict["THOST_FTDC_D_Buy"]
        else:   
            price = self.bid-0.2*2.0
            direction = defineDict["THOST_FTDC_D_Sell"]
        _ref = self.td.sendOrder(self.symbol,self.exchangeid,price,pricetype,volume,direction,offset)
        self.__orders[_ref] = (self.symbol,self.exchangeid,price,pricetype,volume,direction,offset)
    def closeTodayPosition(self,tr,volume):
        self.__retry = 0
        offset = defineDict['THOST_FTDC_OF_CloseToday']
        pricetype = defineDict['THOST_FTDC_OPT_LimitPrice']
        if tr<0:
            price = self.ask+0.2*2.0
            direction = defineDict["THOST_FTDC_D_Buy"]
        else:   
            price = self.bid-0.2*2.0
            direction = defineDict["THOST_FTDC_D_Sell"]
        _ref = self.td.sendOrder(self.symbol,self.exchangeid,price,pricetype,volume,direction,offset)
        self.__orders[_ref] = (self.symbol,self.exchangeid,price,pricetype,volume,direction,offset)
    def get_error(self,event):
        _err = event.dict_['ErrorID']
        self.socket.send(bytes("error_%s"%_err))
        _bk = self.socket.recv()
        print("ERROR",event.dict_)
        self.__orders = {}
    def get_data(self,event):
        _data = event.dict_['data']
        self.ask = _data['AskPrice1']
        self.bid = _data['BidPrice1']
        price = (self.ask+self.bid)/2.0
        self.socket.send(bytes(str(price)))
        _bk = int(self.socket.recv())
        self.todo = _bk
#        print '%.0f  %s  =  %d'%(time(),_data['LastPrice'],_bk)
        if self.__orders:
            print(self.__orders)
        elif self.havedposi:
            _long = defineDict["THOST_FTDC_PD_Long"]
            _short = defineDict["THOST_FTDC_PD_Short"]
            if self.todo==0:
                if self.position.get(_long,0)>0:
                    self.closePosition(1,self.position[_long])
                    self.havedposi = False
                if self.todayposition.get(_long,0)>0:
                    self.closeTodayPosition(1,self.todayposition[_long])
                    self.havedposi = False
                    
                if self.position.get(_short,0)>0:
                    self.closePosition(-1,self.position[_short])
                    self.havedposi = False
                if self.todayposition.get(_short,0)>0:
                    self.closeTodayPosition(-1,self.todayposition[_short])
                    self.havedposi = False
                    
            def do_it(_todo,_pass,_reverse,d_pass,d_reverse):
                if self.position.get(_reverse,0)>0:
                    self.closePosition(d_reverse,self.position[_reverse])
                    self.havedposi = False
                if self.todayposition.get(_reverse,0)>0:
                    self.closeTodayPosition(d_reverse,self.todayposition[_reverse])
                    self.havedposi = False
                _haved = self.position.get(_pass,0)+self.todayposition.get(_pass,0)
                if _todo>_haved:
                    self.openPosition(d_pass,_todo-_haved)
                    self.havedposi = False
                if _todo<_haved:
                    if self.position.get(_pass,0)>0:
                        self.closePosition(d_pass,min(self.position[_pass],_haved-_todo))
                        self.havedposi = False
                        if self.position[_pass]<_haved-_todo:
                            self.closeTodayPosition(d_pass,_haved-_todo-self.position[_pass])
                            self.havedposi = False
                    elif self.todayposition.get(_pass,0)>0:
                        self.closeTodayPosition(d_pass,_haved-_todo)
                        self.havedposi = False

            if self.todo>0:
                _todo = self.todo
                _pass = _long
                _reverse = _short
                d_pass = 1
                d_reverse = -1

                do_it(_todo,_pass,_reverse,d_pass,d_reverse)
                
            if self.todo<0:
                _todo = abs(self.todo)
                _pass = _short
                _reverse = _long
                d_pass = -1
                d_reverse = 1

                do_it(_todo,_pass,_reverse,d_pass,d_reverse)
                
            if not self.havedposi:
                self.todayposition = {}
                self.position = {}
    #----------------------------------------------------------------------
    def login(self, userid, password, brokerid, mdAddress, tdAddress):
        """登陆"""
        self.td.login(tdAddress, userid, password, brokerid)
        self.md.login(mdAddress, userid, password, brokerid)
    
    #----------------------------------------------------------------------
    def subscribe(self, instrumentid, exchangeid):
        """订阅合约"""
        self.md.subscribe(instrumentid, exchangeid)
        
    #----------------------------------------------------------------------
    def getAccount(self):
        """查询账户"""
        self.td.getAccount()
        
    #----------------------------------------------------------------------
    def getInvestor(self):
        """查询投资者"""
        self.td.getInvestor()
        
    #----------------------------------------------------------------------
    def getPosition(self):
        """查询持仓"""
        self.td.getPosition()
    
    #----------------------------------------------------------------------
    def getInstrument(self):
        """获取合约"""
        event = Event(type_=EVENT_LOG)
        log = u'查询合约信息'
        event.dict_['log'] = log
        self.ee.put(event)          
        
        self.td.getInstrument()
        
    #----------------------------------------------------------------------
    def sendOrder(self, instrumentid, exchangeid, price, pricetype, volume, direction, offset):
        """发单"""
        self.td.sendOrder(instrumentid, exchangeid, price, pricetype, volume, direction, offset)
        
    #----------------------------------------------------------------------
    def cancelOrder(self, instrumentid, exchangeid, orderref, frontid, sessionid):
        """撤单"""
        self.td.cancelOrder(instrumentid, exchangeid, orderref, frontid, sessionid)
        
    #----------------------------------------------------------------------
    def getAccountPosition(self, event):
        """循环查询账户和持仓"""
        self.countGet = self.countGet + 1
        
        # 每1秒发一次查询
        if self.countGet >= 20:
            self.countGet = 0
            if self.lastGet == 'Account':
                self.getPosition()
                self.lastGet = 'Position'
            else:
                self.lastGet = 'Account'
                self.getAccount()
    #----------------------------------------------------------------------
    def initGet(self, event):
        """在交易服务器登录成功后,开始初始化查询"""
        # 打开设定文件setting.vn
        f = shelve.open('setting.vn')
        
        # 尝试读取设定字典,若该字典不存在,则发出查询请求
        try:
            d = f['instrument']
            
            # 如果本地保存的合约数据是今日的,则载入,否则发出查询请求
            today = date.today()
            if d['date'] == today:
                self.dictInstrument = d['dictInstrument']
                
                event = Event(type_=EVENT_LOG)
                log = u'合约信息读取完成'
                event.dict_['log'] = log
                self.ee.put(event)            
    
                self.getInvestor()
                
                # 开始循环查询
                self.ee.register(EVENT_TIMER, self.getAccountPosition)                 
            else:
                self.getInstrument()
        except KeyError:
            self.getInstrument()
            
        f.close()
#        _exchangeid = self.dictInstrument[self.symbol]['ExchangeID']
        self.exchangeid = ""#_exchangeid
        self.subscribe(self.symbol,self.exchangeid)
    #----------------------------------------------------------------------
    def insertInstrument(self, event):
        """插入合约对象"""
        data = event.dict_['data']
        last = event.dict_['last']
        
        self.dictInstrument[data['InstrumentID']] = data
        
        # 合约对象查询完成后,查询投资者信息并开始循环查询
        if last:
            # 将查询完成的合约信息保存到本地文件,今日登录可直接使用不再查询
            self.saveInstrument()
            
            event = Event(type_=EVENT_LOG)
            log = u'合约信息查询完成'
            event.dict_['log'] = log
            self.ee.put(event)            

            self.getInvestor()
            # 开始循环查询
            self.ee.register(EVENT_TIMER, self.getAccountPosition)              
        
    #----------------------------------------------------------------------
    def selectInstrument(self, instrumentid):
        """获取合约信息对象"""
        try:
            instrument = self.dictInstrument[instrumentid]
        except KeyError:
            instrument = None
        return instrument
    
    #----------------------------------------------------------------------
    def exit(self):
        """退出"""
        # 销毁API对象
        self.td = None
        self.md = None
        
        # 停止事件驱动引擎
        self.ee.stop()
        
    #----------------------------------------------------------------------
    def saveInstrument(self):
        """保存合约属性数据"""
        f = shelve.open('setting.vn')
        d = {}
        d['dictInstrument'] = self.dictInstrument
        d['date'] = date.today()
        f['instrument'] = d
        f.close()
Пример #19
0
class MainEngine:
    """主引擎,负责对API的调度"""

    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor
        :type self: object
        """
        self.ee = EventEngine()  # 创建事件驱动引擎

        self.md = DemoMdApi(self.ee)  # 创建API接口
        self.td = DemoTdApi(self.ee)

        self.ee.start()  # 启动事件驱动引擎
        self.havedposi = False
        self.position = {}
        self.todayposition = {}

        self.__orders = {}
        self.__retry = 0
        # 循环查询持仓和账户相关
        self.countGet = 0  # 查询延时计数
        self.lastGet = 'Account'  # 上次查询的性质
        self.ee.register(EVENT_TDLOGIN, self.initGet)  # 登录成功后开始初始化查询

        # 合约储存相关
        self.dictInstrument = {}  # 字典(保存合约查询数据)
        self.ee.register(EVENT_INSTRUMENT, self.insertInstrument)

        self.ee.register(EVENT_TRADE_DATA, self.get_trade)
        self.ee.register(EVENT_ORDER_DATA, self.get_order)
        self.ee.register(EVENT_ERROR, self.get_error)
        self.ee.register(EVENT_MARKETDATA_DATA, self.get_data)
        self.ee.register(EVENT_POSITION_DATA, self.get_position)

    def set_app(self, _app):
        self.app = _app

    def get_order(self, event):
        _data = event.dict_['data']
        if _data['OrderStatus'] == '5':
            self.__retry += 1
            if int(_data['OrderRef']) in self.__orders:
                _saved = self.__orders.pop(int(_data['OrderRef']))
            else:
                self.__orders = {}
                return 0
            if self.__retry > 5:
                self.__retry = 0
                return 0
            print("Plus...Order")
            if _saved[6] == defineDict['THOST_FTDC_OF_Open']:
                _tr = 1
            elif _saved[6] == defineDict['THOST_FTDC_OF_Close']:
                _tr = -1
            else:
                _tr = 0
            if _saved[5] == defineDict["THOST_FTDC_D_Buy"]:
                _kr = 1
            elif _saved[5] == defineDict["THOST_FTDC_D_Sell"]:
                _kr = -1
            else:
                _kr = 0
            if _tr * _kr > 0:
                price = float(_saved[2]) + 0.2
            else:
                price = float(_saved[2]) - 0.2
            _ref = self.td.sendOrder(_saved[0], _saved[1], price, _saved[3],
                                     _saved[4], _saved[5], _saved[6])
            self.__orders[_ref] = (_saved[0], _saved[1], price, _saved[3],
                                   _saved[4], _saved[5], _saved[6])

    def get_trade(self, event):
        _data = event.dict_['data']
        print('get_trade', _data['OrderRef'])
        _done = _data['Volume']
        if int(_data['OrderRef']) in self.__orders:
            _saved = self.__orders.pop(int(_data['OrderRef']))
            _goon = _saved[4] - _done
        else:
            _goon = 0
        if _goon != 0:
            self.__retry += 1
            if self.__retry > 5:
                self.__retry = 0
                return 0
            print("Plus...Trade")
            if _saved[6] == defineDict['THOST_FTDC_OF_Open']:
                _tr = 1
            elif _saved[6] == defineDict['THOST_FTDC_OF_Close']:
                _tr = -1
            else:
                _tr = 0
            if _saved[5] == defineDict["THOST_FTDC_D_Buy"]:
                _kr = 1
            elif _saved[5] == defineDict["THOST_FTDC_D_Sell"]:
                _kr = -1
            else:
                _kr = 0
            if _tr * _kr > 0:
                price = float(_saved[2]) + 0.2
            else:
                price = float(_saved[2]) - 0.2
            _ref = self.td.sendOrder(_saved[0], _saved[1], price, _saved[3],
                                     _goon, _saved[5], _saved[6])
            self.__orders[_ref] = (_saved[0], _saved[1], price, _saved[3],
                                   _goon, _saved[5], _saved[6])

    def set_symbol(self, _s):
        self.symbol = _s

    def set_socket(self, _s):
        self.socket = _s

    def get_position(self, event):
        _data = event.dict_['data']
        if _data['TodayPosition']:
            self.todayposition[_data['PosiDirection']] = _data['TodayPosition']
        if _data['Position']: pass
        #            self.position[_data['PosiDirection']] = _data['Position']
        self.havedposi = True
        self.__orders = {}

    def openPosition(self, tr, volume):
        self.__retry = 0
        offset = defineDict['THOST_FTDC_OF_Open']
        pricetype = defineDict['THOST_FTDC_OPT_LimitPrice']
        if tr > 0:
            price = self.ask + 0.2 * 2.0
            direction = defineDict["THOST_FTDC_D_Buy"]
        else:
            price = self.bid - 0.2 * 2.0
            direction = defineDict["THOST_FTDC_D_Sell"]
        _ref = self.td.sendOrder(self.symbol, self.exchangeid, price,
                                 pricetype, volume, direction, offset)
        self.__orders[_ref] = (self.symbol, self.exchangeid, price, pricetype,
                               volume, direction, offset)

    def closePosition(self, tr, volume):
        self.__retry = 0
        offset = defineDict['THOST_FTDC_OF_Close']
        pricetype = defineDict['THOST_FTDC_OPT_LimitPrice']
        if tr < 0:
            price = self.ask + 0.2 * 2.0
            direction = defineDict["THOST_FTDC_D_Buy"]
        else:
            price = self.bid - 0.2 * 2.0
            direction = defineDict["THOST_FTDC_D_Sell"]
        _ref = self.td.sendOrder(self.symbol, self.exchangeid, price,
                                 pricetype, volume, direction, offset)
        self.__orders[_ref] = (self.symbol, self.exchangeid, price, pricetype,
                               volume, direction, offset)

    def closeTodayPosition(self, tr, volume):
        self.__retry = 0
        offset = defineDict['THOST_FTDC_OF_CloseToday']
        pricetype = defineDict['THOST_FTDC_OPT_LimitPrice']
        if tr < 0:
            price = self.ask + 0.2 * 2.0
            direction = defineDict["THOST_FTDC_D_Buy"]
        else:
            price = self.bid - 0.2 * 2.0
            direction = defineDict["THOST_FTDC_D_Sell"]
        _ref = self.td.sendOrder(self.symbol, self.exchangeid, price,
                                 pricetype, volume, direction, offset)
        self.__orders[_ref] = (self.symbol, self.exchangeid, price, pricetype,
                               volume, direction, offset)

    def get_error(self, event):
        _err = event.dict_['ErrorID']
        self.socket.send(bytes("error_%s" % _err))
        _bk = self.socket.recv()
        print("ERROR", event.dict_)
        self.__orders = {}

    def get_data(self, event):
        _data = event.dict_['data']
        self.ask = _data['AskPrice1']
        self.bid = _data['BidPrice1']
        price = (self.ask + self.bid) / 2.0
        self.socket.send(bytes(str(price)))
        _bk = int(self.socket.recv())
        self.todo = _bk
        #        print '%.0f  %s  =  %d'%(time(),_data['LastPrice'],_bk)
        if self.__orders:
            print(self.__orders)
        elif self.havedposi:
            _long = defineDict["THOST_FTDC_PD_Long"]
            _short = defineDict["THOST_FTDC_PD_Short"]
            if self.todo == 0:
                if self.position.get(_long, 0) > 0:
                    self.closePosition(1, self.position[_long])
                    self.havedposi = False
                if self.todayposition.get(_long, 0) > 0:
                    self.closeTodayPosition(1, self.todayposition[_long])
                    self.havedposi = False

                if self.position.get(_short, 0) > 0:
                    self.closePosition(-1, self.position[_short])
                    self.havedposi = False
                if self.todayposition.get(_short, 0) > 0:
                    self.closeTodayPosition(-1, self.todayposition[_short])
                    self.havedposi = False

            def do_it(_todo, _pass, _reverse, d_pass, d_reverse):
                if self.position.get(_reverse, 0) > 0:
                    self.closePosition(d_reverse, self.position[_reverse])
                    self.havedposi = False
                if self.todayposition.get(_reverse, 0) > 0:
                    self.closeTodayPosition(d_reverse,
                                            self.todayposition[_reverse])
                    self.havedposi = False
                _haved = self.position.get(_pass, 0) + self.todayposition.get(
                    _pass, 0)
                if _todo > _haved:
                    self.openPosition(d_pass, _todo - _haved)
                    self.havedposi = False
                if _todo < _haved:
                    if self.position.get(_pass, 0) > 0:
                        self.closePosition(
                            d_pass, min(self.position[_pass], _haved - _todo))
                        self.havedposi = False
                        if self.position[_pass] < _haved - _todo:
                            self.closeTodayPosition(
                                d_pass, _haved - _todo - self.position[_pass])
                            self.havedposi = False
                    elif self.todayposition.get(_pass, 0) > 0:
                        self.closeTodayPosition(d_pass, _haved - _todo)
                        self.havedposi = False

            if self.todo > 0:
                _todo = self.todo
                _pass = _long
                _reverse = _short
                d_pass = 1
                d_reverse = -1

                do_it(_todo, _pass, _reverse, d_pass, d_reverse)

            if self.todo < 0:
                _todo = abs(self.todo)
                _pass = _short
                _reverse = _long
                d_pass = -1
                d_reverse = 1

                do_it(_todo, _pass, _reverse, d_pass, d_reverse)

            if not self.havedposi:
                self.todayposition = {}
                self.position = {}

    #----------------------------------------------------------------------
    def login(self, userid, password, brokerid, mdAddress, tdAddress):
        """登陆"""
        self.td.login(tdAddress, userid, password, brokerid)
        self.md.login(mdAddress, userid, password, brokerid)

    #----------------------------------------------------------------------
    def subscribe(self, instrumentid, exchangeid):
        """订阅合约"""
        self.md.subscribe(instrumentid, exchangeid)

    #----------------------------------------------------------------------
    def getAccount(self):
        """查询账户"""
        self.td.getAccount()

    #----------------------------------------------------------------------
    def getInvestor(self):
        """查询投资者"""
        self.td.getInvestor()

    #----------------------------------------------------------------------
    def getPosition(self):
        """查询持仓"""
        self.td.getPosition()

    #----------------------------------------------------------------------
    def getInstrument(self):
        """获取合约"""
        event = Event(type_=EVENT_LOG)
        log = u'查询合约信息'
        event.dict_['log'] = log
        self.ee.put(event)

        self.td.getInstrument()

    #----------------------------------------------------------------------
    def sendOrder(self, instrumentid, exchangeid, price, pricetype, volume,
                  direction, offset):
        """发单"""
        self.td.sendOrder(instrumentid, exchangeid, price, pricetype, volume,
                          direction, offset)

    #----------------------------------------------------------------------
    def cancelOrder(self, instrumentid, exchangeid, orderref, frontid,
                    sessionid):
        """撤单"""
        self.td.cancelOrder(instrumentid, exchangeid, orderref, frontid,
                            sessionid)

    #----------------------------------------------------------------------
    def getAccountPosition(self, event):
        """循环查询账户和持仓"""
        self.countGet = self.countGet + 1

        # 每1秒发一次查询
        if self.countGet >= 20:
            self.countGet = 0
            if self.lastGet == 'Account':
                self.getPosition()
                self.lastGet = 'Position'
            else:
                self.lastGet = 'Account'
                self.getAccount()

    #----------------------------------------------------------------------
    def initGet(self, event):
        """在交易服务器登录成功后,开始初始化查询"""
        # 打开设定文件setting.vn
        f = shelve.open('setting.vn')

        # 尝试读取设定字典,若该字典不存在,则发出查询请求
        try:
            d = f['instrument']

            # 如果本地保存的合约数据是今日的,则载入,否则发出查询请求
            today = date.today()
            if d['date'] == today:
                self.dictInstrument = d['dictInstrument']

                event = Event(type_=EVENT_LOG)
                log = u'合约信息读取完成'
                event.dict_['log'] = log
                self.ee.put(event)

                self.getInvestor()

                # 开始循环查询
                self.ee.register(EVENT_TIMER, self.getAccountPosition)
            else:
                self.getInstrument()
        except KeyError:
            self.getInstrument()

        f.close()
        #        _exchangeid = self.dictInstrument[self.symbol]['ExchangeID']
        self.exchangeid = ""  #_exchangeid
        self.subscribe(self.symbol, self.exchangeid)

    #----------------------------------------------------------------------
    def insertInstrument(self, event):
        """插入合约对象"""
        data = event.dict_['data']
        last = event.dict_['last']

        self.dictInstrument[data['InstrumentID']] = data

        # 合约对象查询完成后,查询投资者信息并开始循环查询
        if last:
            # 将查询完成的合约信息保存到本地文件,今日登录可直接使用不再查询
            self.saveInstrument()

            event = Event(type_=EVENT_LOG)
            log = u'合约信息查询完成'
            event.dict_['log'] = log
            self.ee.put(event)

            self.getInvestor()
            # 开始循环查询
            self.ee.register(EVENT_TIMER, self.getAccountPosition)

    #----------------------------------------------------------------------
    def selectInstrument(self, instrumentid):
        """获取合约信息对象"""
        try:
            instrument = self.dictInstrument[instrumentid]
        except KeyError:
            instrument = None
        return instrument

    #----------------------------------------------------------------------
    def exit(self):
        """退出"""
        # 销毁API对象
        self.td = None
        self.md = None

        # 停止事件驱动引擎
        self.ee.stop()

    #----------------------------------------------------------------------
    def saveInstrument(self):
        """保存合约属性数据"""
        f = shelve.open('setting.vn')
        d = {}
        d['dictInstrument'] = self.dictInstrument
        d['date'] = date.today()
        f['instrument'] = d
        f.close()
Пример #20
0
    def __init__(self,
                 ws,
                 account,
                 _plus_path,
                 justCopySignal=False,
                 useZmq=False,
                 zmqServer="tcp://192.168.1.234:9999"):
        """Constructor
        :type self: object
        """
        self.ee = EventEngine(account)  # 创建事件驱动引擎
        self.justCopySignal = justCopySignal

        self.userid = str(account['userid'])
        self.password = str(account['password'])
        self.brokerid = str(account['brokerid'])
        self.mdaddress = str(account['mdfront'])
        self.tdaddress = str(account['tdfront'])

        self.pluspath = _plus_path
        self.symbol = None
        self.socket = None
        self.websocket = ws  # websocket list to send msg

        if useZmq:
            context = zmq.Context()
            socket = context.socket(zmq.REQ)
            socket.connect(zmqServer)
            self.socket = socket

        self.ee.start()  # 启动事件驱动引擎
        self.havedposi = False
        self.position = {}
        self.todayposition = {}
        self.lastError = 0
        self.lastTodo = 0

        self.__timer = time() + 60
        self.__orders = {}
        self.__retry = 0
        self.__maxRetry = 5
        # 循环查询持仓和账户相关
        self.countGet = 0  # 查询延时计数
        self.lastGet = 'Account'  # 上次查询的性质
        self.ee.register(EVENT_TDLOGIN, self.initGet)  # 登录成功后开始初始化查询

        # 合约储存相关
        self.dictInstrument = {}  # 字典(保存合约查询数据)
        self.dictProduct = {}  # 字典(保存合约查询数据)
        self.dictExchange = {}
        self.volInstrument = {}
        self.subInstrument = set()
        self.subedInst = set()

        self.todo = 0

        self.ee.register(EVENT_ERROR, self.get_error)
        self.ee.register(EVENT_INSTRUMENT, self.insertInstrument)
        self.ee.register(EVENT_TIMER, self.getAccountPosition)
        self.ee.register(EVENT_TRADE, self.get_trade)
        self.ee.register(EVENT_ORDER, self.get_order)
        self.ee.register(EVENT_TICK, self.get_tick)
        self.ee.register(EVENT_POSITION, self.get_position)

        import eventType
        for k, v in eventType.__dict__.items():
            if 'EVENT_' in k and v[0] != '_':
                self.ee.register(v, self.websocket_send)

        self.md = DemoMdApi(self.ee,
                            self.mdaddress,
                            self.userid,
                            self.password,
                            self.brokerid,
                            plus_path=_plus_path)  # 创建API接口
        self.td = DemoTdApi(self.ee,
                            self.tdaddress,
                            self.userid,
                            self.password,
                            self.brokerid,
                            plus_path=_plus_path)
Пример #21
0
class MainEngine:
    """主引擎,负责对API的调度"""

    # ----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        self.eventEngine = EventEngine()  # 创建事件驱动引擎

        self.md = DemoMdApi(self.eventEngine)  # 创建API接口
        # self.md = DemoL2Api(self.ee)   # 如果使用L2行情就改为这行
        self.td = DemoTdApi(self.eventEngine)

        self.eventEngine.start()  # 启动事件驱动引擎
        self.dataEngine = DataEngine(self, self.eventEngine)

        # 循环查询持仓和账户相关
        self.countGet = 0  # 查询延时计数
        self.lastGet = 'Account'  # 上次查询的性质
        self.eventEngine.register(EVENT_TDLOGIN, self.initGet)  # 登录成功后开始初始化查询

        # 合约储存相关
        # self.dictInstrument = {}        # 字典(保存合约查询数据)
        # self.eventEngine.register(EVENT_INSTRUMENT, self.insertInstrument)
        # 接口实例
        self.gatewayDict = OrderedDict()
        self.gatewayDetailList = []

        # 应用模块实例
        self.appDict = OrderedDict()
        self.appDetailList = []

        # 风控引擎实例(特殊独立对象)
        self.rmEngine = None

    # ----------------------------------------------------------------------
    def addGateway(self, gatewayModule):
        """添加底层接口"""
        gatewayName = gatewayModule.gatewayName

        # 创建接口实例
        self.gatewayDict[gatewayName] = gatewayModule.gatewayClass(self.eventEngine,
                                                                   gatewayName)

        # 设置接口轮询
        if gatewayModule.gatewayQryEnabled:
            self.gatewayDict[gatewayName].setQryEnabled(
                gatewayModule.gatewayQryEnabled)

        # 保存接口详细信息
        d = {
            'gatewayName': gatewayModule.gatewayName,
            'gatewayDisplayName': gatewayModule.gatewayDisplayName,
            'gatewayType': gatewayModule.gatewayType
        }
        self.gatewayDetailList.append(d)

    # ----------------------------------------------------------------------
    def addApp(self, appModule):
        """添加上层应用"""
        appName = appModule.appName

        # 创建应用实例
        self.appDict[appName] = appModule.appEngine(self, self.eventEngine)

        # 保存应用信息
        d = {
            'appName': appModule.appName,
            'appDisplayName': appModule.appDisplayName,
            'appWidget': appModule.appWidget,
            'appIco': appModule.appIco
        }
        self.appDetailList.append(d)

    # ----------------------------------------------------------------------
    def getGateway(self, gatewayName):
        """获取接口"""
        if gatewayName in self.gatewayDict:
            return self.gatewayDict[gatewayName]
        else:
            self.writeLog('{gateway}接口不存在'.format(gateway=gatewayName))
            return None

    # ----------------------------------------------------------------------
    def writeLog(self, content):
        """快速发出日志事件"""
        log = VtLogData()
        log.logContent = content
        event = Event(type_=EVENT_LOG)
        event.dict_['data'] = log
        self.eventEngine.put(event)

    # ----------------------------------------------------------------------
    def connect(self, gatewayName):
        """连接特定名称的接口"""
        gateway = self.getGateway(gatewayName)

        if gateway:
            gateway.connect()

    # ----------------------------------------------------------------------
    def login(self, userid, mdPassword, tdPassword, mdAddress, tdAddress):
        """登陆"""
        db_path = {}
        db_path['SH'] = userid
        db_path['SZ'] = mdPassword
        db_path['Order'] = tdPassword
        db_path['HB'] = mdAddress
        db_path['Acct'] = tdAddress
        print(db_path)
        self.md.login(db_path)
        self.td.login(db_path)

    # ----------------------------------------------------------------------
    def subscribe(self, instrumentid, exchangeid):
        """订阅合约"""
        self.md.subscribe(instrumentid, exchangeid)

    # ----------------------------------------------------------------------
    def getAccount(self):
        """查询账户"""
        self.dataEngine.getAccount()

    # ----------------------------------------------------------------------
    def getPosition(self):
        """查询持仓"""
        self.dataEngine.getPosition()

    # ----------------------------------------------------------------------
    def getInstrument(self):
        """获取合约"""
        event = Event(type_=EVENT_LOG)
        log = VtLogData()
        log.gatewayName = 'MainEngine'
        log.logContent = u'查询合约信息'
        event.dict_['log'] = log
        self.eventEngine.put(event)

        self.md.getInstrument()

    # ----------------------------------------------------------------------
    def sendOrder(self, instrumentid, exchangeid, price, pricetype, volume, direction):
        """发单"""
        self.td.sendOrder(instrumentid, exchangeid, price,
                          pricetype, volume, direction)

    # ----------------------------------------------------------------------
    def cancelOrder(self, orderref):
        """撤单"""

        self.td.cancelOrder(orderref)

    # ----------------------------------------------------------------------
    def getAccountPosition(self, event):
        """循环查询账户和持仓"""
        self.countGet = self.countGet + 1

        # 每5秒发一次查询
        if self.countGet > 5:
            self.countGet = 0  # 清空计数

            if self.lastGet == 'Account':
                self.getPosition()
                self.lastGet = 'Position'
            else:
                self.getAccount()
                self.lastGet = 'Account'

    # ----------------------------------------------------------------------
    def initGet(self, event):
        """在交易服务器登录成功后,开始初始化查询"""
        # 打开设定文件setting.vn
        if self.dataEngine.no_data:
            self.getInstrument()
        self.getAccount()
        self.getPosition()
        self.eventEngine.register(EVENT_TIMER, self.getAccountPosition)

    # ----------------------------------------------------------------------
    def selectInstrument(self, instrumentid):
        """获取合约信息对象"""
        return self.dataEngine.getContract(instrumentid)

    # ----------------------------------------------------------------------
    def exit(self):
        """退出"""
        # 销毁API对象
        self.td.exit()
        self.md.exit()
        self.td = None
        self.md = None

        # 停止事件驱动引擎
        self.eventEngine.stop()

    # ----------------------------------------------------------------------
    def getAllContracts(self):
        """查询所有合约(返回列表)"""
        return self.dataEngine.getAllContracts()

    # ----------------------------------------------------------------------
    def getOrder(self, vtOrderID):
        """查询委托"""
        return self.dataEngine.getOrder(vtOrderID)

    # ----------------------------------------------------------------------
    def getAllWorkingOrders(self):
        """查询所有的活跃的委托(返回列表)"""
        return self.dataEngine.getAllWorkingOrders()

    # ----------------------------------------------------------------------
    def getAllGatewayDetails(self):
        """查询引擎中所有底层接口的信息"""
        return self.gatewayDetailList

    # ----------------------------------------------------------------------
    def getAllAppDetails(self):
        """查询引擎中所有上层应用的信息"""
        return self.appDetailList

    def getacc_list(self):
        """获取账户列表"""
        return self.dataEngine.getacc_list()

    def getProtfolio(self, account):
        """获取指定账户信息"""
        return self.dataEngine.getPosition(account)
Пример #22
0
class MainEngine:

    #----------------------------------------------------------------------
    def __init__(self, account, _plus_path, bg):

        self.ee = EventEngine(account)         # 创建事件驱动引擎
        self.bridge = bg
        self.__lock = Lock()
        self.userid = str(account['userid'])
        self.password = str(account['password'])
        self.brokerid = str(account['brokerid'])
        self.mdaddress = str(account['mdfront'])
        self.tdaddress = str(account['tdfront'])
        self.instrument = account['instrument'] #   sub list str
        self.pluspath = _plus_path

        self.dictInstrument = {}        # 字典(保存合约查询数据)
        self.dictProduct = {}        # 字典(保存合约查询数据)
        self.dictExchange= {}
        self.tmpInstrument = {}        # 字典(保存合约查询数据)
        self.tmpProduct = {}        # 字典(保存合约查询数据)
        self.tmpExchange= {}
        self.dictUpdate = None
        self.subInstrument = set()
        self.subedInstrument = set()
        self.master = {}    #   记录主力合约对应关系
        self.masterSubed = False
        self.subedMaster = {}
        self.tickpass = set()
        self.now = datetime.now()
        self.socket = None
        self.coreServer = str(account['zmqserver'])
        self.corefunc = passit
        if int(account['usezmq'])>0:
            if self.coreServer[:4] == 'tcp:':
                context = zmq.Context()
                socket = context.socket(zmq.REQ)
                socket.connect(self.coreServer)
                self.socket = socket
                self.corefunc = tcpfunc
            elif self.coreServer[:5] == 'http:':
                self.socket = True
                self.corefunc = httpfunc
        self.ee.start()                 # 启动事件驱动引擎
        self.som = {}

        self.lastError = 0
        self.lastTodo = 0

        self.eq = 0

        # 循环查询持仓和账户相关
        self.countGet = 0               # 查询延时计数
        self.lastGet = 'Account'        # 上次查询的性质
        self.ee.register(EVENT_TDLOGIN, self.initGet,True)  # 登录成功后开始初始化查询

        self.__timer = time()+3
        self.__readySubscribe = {}
        
        # 合约储存相关

        self.get_instrument()
        self.get_subscribe(self.instrument)
        self.ee.register(EVENT_MDLOGIN,     self.ready_subscribe,True)
        self.ee.register(EVENT_TDLOGIN,     self.ready_subscribe,True)
        self.ee.register(EVENT_ERROR,       self.get_error,False)
        self.ee.register(EVENT_INSTRUMENT,  self.insertInstrument,True)
        self.ee.register(EVENT_TIMER,       self.getAccountPosition,False)
        self.ee.register(EVENT_TRADE,       self.get_trade,False)
        self.ee.register(EVENT_ORDER,       self.get_order,False)
        self.ee.register(EVENT_TICK,        self.get_tick,True)
        self.ee.register(EVENT_POSITION,    self.get_position,False)
        self.ee.register(EVENT_ACCOUNT,     self.get_account,False)

        self.ee.register(EVENT_TICK,        self.check_timer,False)
        self.ee.register(EVENT_ORDER,       self.check_timer,False)

        import eventType
        for k,v in eventType.__dict__.items():
            if 'EVENT_' in k and v[0]!='_':
                self.ee.register(v,self.websocket_send,False)

        self.md = ctpMdApi(self, self.mdaddress, self.userid, self.password, self.brokerid, plus_path=_plus_path)    # 创建API接口
        self.td = ctpTdApi(self, self.tdaddress, self.userid, self.password, self.brokerid, plus_path=_plus_path)

    def get_subscribe(self,_inst):
        if '#' in _inst:
            _instlist = [ (v.get('_vol_',0),k) for k,v in self.dictInstrument.items()]
            _instlist.sort(reverse=True)
            _only = set()
            for v,_instrumentid in _instlist[:10]:
                _product = self.dictInstrument[_instrumentid]['ProductID']
                if _product not in _only:
                    _exchangeid = self.dictInstrument.get(_instrumentid,{}).get("ExchangeID",'')
                    self.subInstrument.add((_instrumentid,_exchangeid))
                    self.subedMaster[_instrumentid] = 1
                    self.tickpass.add(_instrumentid)
                    _only.add(_product)
            for _productid in ['IF','IH','IC']:
                if _productid in self.dictProduct and _productid not in _only:
                    _product = self.dictProduct[_productid]
                    _productlist = [ (v,k) for k,v in _product.items()]
                    _productlist.sort(reverse=True)
                    _instrumentid = _productlist[0][-1]
                    _exchangeid = self.dictInstrument.get(_instrumentid,{}).get("ExchangeID",'')
                    self.subInstrument.add((_instrumentid,_exchangeid))
                    self.master[_productid] = _product
                    self.subedMaster[_instrumentid] = 1
                    self.tickpass.add(_instrumentid)
            for _productid,_product in self.dictProduct.items():
                self.master[_productid] = _product

        else:
            _all = _inst.split('+')
            for one in _all:
                if '=' in one:
                    _productid = one[:-1]
                    if _productid in self.dictProduct:
                        _product = self.dictProduct[_productid]
                        _productlist = [ (v,k) for k,v in _product.items()]
                        _productlist.sort(reverse=True)
                        _instrumentid = _productlist[0][-1]
                        _exchangeid = self.dictInstrument.get(_instrumentid,{}).get("ExchangeID",'')
                        self.subInstrument.add((_instrumentid,_exchangeid))
                        self.master[_productid] = _product
                        self.subedMaster[_instrumentid] = 1
                        self.tickpass.add(_instrumentid)
                else:
                    _instrumentid = one
                    _exchangeid = self.dictInstrument.get(_instrumentid,{}).get("ExchangeID",'')
                    self.subInstrument.add((_instrumentid,_exchangeid))
                    self.tickpass.add(_instrumentid)
            print(self.subInstrument)
    def ready_subscribe(self,event):
        self.__readySubscribe[event.type_] = 1
        if len(self.__readySubscribe) == 2:
            for one in self.subInstrument:
                if one[0] in self.subedMaster:
                    event = Event(type_=EVENT_LOG)
                    log = u'订阅主力合约:%s[%s]'%(one[0],self.dictInstrument[one[0]]['InstrumentName'])
                    event.dict_['log'] = log
                    self.ee.put(event)
                else:
                    event = Event(type_=EVENT_LOG)
                    log = u'订阅合约:%s[%s]'%(one[0],self.dictInstrument[one[0]]['InstrumentName'])
                    event.dict_['log'] = log
                    self.ee.put(event)
                self.subscribe(one[0],one[1])
    def get_instrument(self):
        _dict = self.bridge.get_instrument()
        self.dictInstrument = _dict.get('instrument',{})
        self.dictExchange = _dict.get('exchange',{})
        self.dictProduct = _dict.get('product',{})
        self.dictUpdate = _dict.get('day',None)
    def set_instrument(self):
        _dict = {}
        _dict['instrument'] = self.dictInstrument
        _dict['exchange'] = self.dictExchange
        _dict['product'] = self.dictProduct
        _dict['day'] = date.today()
        self.bridge.set_instrument(_dict)
    def get_som(self,event):
        try:
            symbol = event.dict_['data']['InstrumentID']
            if symbol:
                if symbol not in self.tickpass:return
                if symbol in self.som:
                    return self.som[symbol]
                else:
                    _data = None
                    if symbol in self.dictInstrument:
                        _data = self.dictInstrument[symbol]
                        event = Event(type_=EVENT_LOG)
                        log = u'初始化合约[%s]并填充其基本信息'%symbol
                        event.dict_['log'] = log
                        self.ee.put(event)
                    else:
                        _productid = filter(lambda x:x in _chars+_CHARS,symbol)
                        if _productid in self.dictProduct:
                            for _instrument in self.dictProduct[_productid].keys():
                                if _instrument in self.dictInstrument:
                                    _data = self.dictInstrument[_instrument]
                                    event = Event(type_=EVENT_LOG)
                                    log = u'注意:初始化合约[%s]但填充了<%s>的基本信息'%(symbol,_instrument)
                                    event.dict_['log'] = log
                                    self.ee.put(event)
                                    break
                    if _data:
                        one = SymbolOrdersManager(symbol,_data,self)
                        self.som[symbol] = one
                        return one
                    else:
                        event = Event(type_=EVENT_LOG)
                        log = u'警告:初始化合约[%s]失败,未发现其基本信息'%symbol
                        event.dict_['log'] = log
                        self.ee.put(event)
                        print("ctpEngine.py MainEngine get_som not found Instrument Info")
                        return None
            else:
                return None
        except Exception,e:
            print("ctpEngine.py MainEngine get_som ERROR",e)
            print(event.type_,event.dict_['data'])
Пример #23
0
class MainEngine:
    """主引擎,负责对API的调度"""

    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        self.ee = EventEngine()  # 创建事件驱动引擎

        self.md = DemoMdApi(self.ee)  # 创建API接口
        self.td = DemoTdApi(self.ee)

        self.ee.start()  # 启动事件驱动引擎

        # 循环查询持仓和账户相关
        self.countGet = 0  # 查询延时计数
        self.lastGet = 'Account'  # 上次查询的性质
        self.ee.register(EVENT_TDLOGIN, self.initGet)  # 登录成功后开始初始化查询

        # 合约储存相关
        self.dictInstrument = {}  # 字典(保存合约查询数据)
        self.ee.register(EVENT_INSTRUMENT, self.insertInstrument)

    #----------------------------------------------------------------------
    def login(self, userid, password, brokerid, mdAddress, tdAddress):
        """登陆"""
        self.md.login(mdAddress, userid, password, brokerid)
        self.td.login(tdAddress, userid, password, brokerid)

    #----------------------------------------------------------------------
    def subscribe(self, instrumentid, exchangeid):
        """订阅合约"""
        self.md.subscribe(instrumentid, exchangeid)

    #----------------------------------------------------------------------
    def getAccount(self):
        """查询账户"""
        self.td.getAccount()

    #----------------------------------------------------------------------
    def getInvestor(self):
        """查询投资者"""
        self.td.getInvestor()

    #----------------------------------------------------------------------
    def getPosition(self):
        """查询持仓"""
        self.td.getPosition()

    #----------------------------------------------------------------------
    def getInstrument(self):
        """获取合约"""
        event = Event(type_=EVENT_LOG)
        log = u'查询合约信息'
        event.dict_['log'] = log
        self.ee.put(event)

        self.td.getInstrument()

    #----------------------------------------------------------------------
    def sendOrder(self, instrumentid, exchangeid, price, pricetype, volume,
                  direction, offset):
        """发单"""
        ref = self.td.sendOrder(instrumentid, exchangeid, price, pricetype,
                                volume, direction, offset)
        return str(ref)

    #----------------------------------------------------------------------
    def cancelOrder(self, instrumentid, exchangeid, orderref, frontid,
                    sessionid):
        """撤单"""
        self.td.cancelOrder(instrumentid, exchangeid, orderref, frontid,
                            sessionid)

    #----------------------------------------------------------------------
    def getAccountPosition(self, event):
        """循环查询账户和持仓"""
        self.countGet = self.countGet + 1

        # 每5秒发一次查询
        if self.countGet > 5:
            self.countGet = 0  # 清空计数

            if self.lastGet == 'Account':
                self.getPosition()
                self.lastGet = 'Position'
            else:
                self.getAccount()
                self.lastGet = 'Account'

    #----------------------------------------------------------------------
    def initGet(self, event):
        """在交易服务器登录成功后,开始初始化查询"""
        # 打开设定文件setting.vn
        f = shelve.open('setting.vn')

        # 尝试读取设定字典,若该字典不存在,则发出查询请求
        try:
            d = f['instrument']

            # 如果本地保存的合约数据是今日的,则载入,否则发出查询请求
            today = date.today()
            if d['date'] == today:
                self.dictInstrument = d['dictInstrument']

                event = Event(type_=EVENT_LOG)
                log = u'合约信息读取完成'
                event.dict_['log'] = log
                self.ee.put(event)

                self.getInvestor()

                # 开始循环查询
                self.ee.register(EVENT_TIMER, self.getAccountPosition)
            else:
                self.getInstrument()
        except KeyError:
            self.getInstrument()

        f.close()

    #----------------------------------------------------------------------
    def insertInstrument(self, event):
        """插入合约对象"""
        data = event.dict_['data']
        last = event.dict_['last']

        self.dictInstrument[data['InstrumentID']] = data

        # 合约对象查询完成后,查询投资者信息并开始循环查询
        if last:
            # 将查询完成的合约信息保存到本地文件,今日登录可直接使用不再查询
            self.saveInstrument()

            event = Event(type_=EVENT_LOG)
            log = u'合约信息查询完成'
            event.dict_['log'] = log
            self.ee.put(event)

            self.getInvestor()

            # 开始循环查询
            self.ee.register(EVENT_TIMER, self.getAccountPosition)

    #----------------------------------------------------------------------
    def selectInstrument(self, instrumentid):
        """获取合约信息对象"""
        try:
            instrument = self.dictInstrument[instrumentid]
        except KeyError:
            instrument = None
        return instrument

    #----------------------------------------------------------------------
    def exit(self):
        """退出"""
        # 销毁API对象
        self.td = None
        self.md = None

        # 停止事件驱动引擎
        self.ee.stop()

    #----------------------------------------------------------------------
    def saveInstrument(self):
        """保存合约属性数据"""
        f = shelve.open('setting.vn')
        d = {}
        d['dictInstrument'] = self.dictInstrument
        d['date'] = date.today()
        f['instrument'] = d
        f.close()
Пример #24
0
    def __init__(self, account, _plus_path, bg):

        self.ee = EventEngine(account)         # 创建事件驱动引擎
        self.bridge = bg
        self.__lock = Lock()
        self.userid = str(account['userid'])
        self.password = str(account['password'])
        self.brokerid = str(account['brokerid'])
        self.mdaddress = str(account['mdfront'])
        self.tdaddress = str(account['tdfront'])
        self.instrument = account['instrument'] #   sub list str
        self.pluspath = _plus_path

        self.dictInstrument = {}        # 字典(保存合约查询数据)
        self.dictProduct = {}        # 字典(保存合约查询数据)
        self.dictExchange= {}
        self.tmpInstrument = {}        # 字典(保存合约查询数据)
        self.tmpProduct = {}        # 字典(保存合约查询数据)
        self.tmpExchange= {}
        self.dictUpdate = None
        self.subInstrument = set()
        self.subedInstrument = set()
        self.master = {}    #   记录主力合约对应关系
        self.masterSubed = False
        self.subedMaster = {}
        self.tickpass = set()
        self.now = datetime.now()
        self.socket = None
        self.coreServer = str(account['zmqserver'])
        self.corefunc = passit
        if int(account['usezmq'])>0:
            if self.coreServer[:4] == 'tcp:':
                context = zmq.Context()
                socket = context.socket(zmq.REQ)
                socket.connect(self.coreServer)
                self.socket = socket
                self.corefunc = tcpfunc
            elif self.coreServer[:5] == 'http:':
                self.socket = True
                self.corefunc = httpfunc
        self.ee.start()                 # 启动事件驱动引擎
        self.som = {}

        self.lastError = 0
        self.lastTodo = 0

        self.eq = 0

        # 循环查询持仓和账户相关
        self.countGet = 0               # 查询延时计数
        self.lastGet = 'Account'        # 上次查询的性质
        self.ee.register(EVENT_TDLOGIN, self.initGet,True)  # 登录成功后开始初始化查询

        self.__timer = time()+3
        self.__readySubscribe = {}
        
        # 合约储存相关

        self.get_instrument()
        self.get_subscribe(self.instrument)
        self.ee.register(EVENT_MDLOGIN,     self.ready_subscribe,True)
        self.ee.register(EVENT_TDLOGIN,     self.ready_subscribe,True)
        self.ee.register(EVENT_ERROR,       self.get_error,False)
        self.ee.register(EVENT_INSTRUMENT,  self.insertInstrument,True)
        self.ee.register(EVENT_TIMER,       self.getAccountPosition,False)
        self.ee.register(EVENT_TRADE,       self.get_trade,False)
        self.ee.register(EVENT_ORDER,       self.get_order,False)
        self.ee.register(EVENT_TICK,        self.get_tick,True)
        self.ee.register(EVENT_POSITION,    self.get_position,False)
        self.ee.register(EVENT_ACCOUNT,     self.get_account,False)

        self.ee.register(EVENT_TICK,        self.check_timer,False)
        self.ee.register(EVENT_ORDER,       self.check_timer,False)

        import eventType
        for k,v in eventType.__dict__.items():
            if 'EVENT_' in k and v[0]!='_':
                self.ee.register(v,self.websocket_send,False)

        self.md = ctpMdApi(self, self.mdaddress, self.userid, self.password, self.brokerid, plus_path=_plus_path)    # 创建API接口
        self.td = ctpTdApi(self, self.tdaddress, self.userid, self.password, self.brokerid, plus_path=_plus_path)
Пример #25
0
class MainEngine:
    """主引擎,负责对API的调度"""

    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        self.ee = EventEngine()         # 创建事件驱动引擎

        self.dsa = DemoStockApi(('192.168.16.59', 9991), self.ee)    # 现货报单
        self.dma = DemoMarketApi(('10.10.1.186', 9101), self.ee)    # 现货报单
        # self.md = DemoL2Api(self.ee)   # 如果使用L2行情就改为这行
        # self.td = DemoTdApi(self.ee)

        self.ee.start()                 # 启动事件驱动引擎

        # 循环查询持仓和账户相关
        self.countGet = 0               # 查询延时计数
        self.lastGet = 'Account'        # 上次查询的性质
        # self.ee.register(EVENT_TDLOGIN, self.initGet)  # 登录成功后开始初始化查询
        
        # 合约储存相关
        self.dictInstrument = {}        # 字典(保存合约查询数据)
        # self.ee.register(EVENT_INSTRUMENT, self.insertInstrument)



    #----------------------------------------------------------------------
    def login(self, userid, mdPassword, tdPassword, brokerid, mdAddress, tdAddress):
        """登陆"""
        self.dsa.login_req()
        # self.md.login(mdAddress, userid, mdPassword, brokerid)
        # self.td.login(tdAddress, userid, tdPassword, brokerid)
    
    #----------------------------------------------------------------------
    def subscribe(self, instrumentid, exchangeid):
        """订阅合约"""
        # self.md.subscribe(instrumentid, exchangeid)
        
    #----------------------------------------------------------------------
    def getAccount(self):
        """查询账户"""
        # self.td.getAccount()
        
    #----------------------------------------------------------------------
    def getInvestor(self):
        """查询投资者"""
        # self.td.getInvestor()
        
    #----------------------------------------------------------------------
    def getPosition(self):
        """查询持仓"""
        # self.td.getPosition()
    
    #----------------------------------------------------------------------
    def getInstrument(self):
        """获取合约"""
        # event = Event(type_=EVENT_LOG)
        # log = u'查询合约信息'
        # event.dict_['log'] = log
        # self.ee.put(event)
        
        # self.td.getInstrument()
        
    #----------------------------------------------------------------------
    def sendOrder(self, instrumentid, exchangeid, price, pricetype, volume, direction, offset):
        """发单"""
        # self.td.sendOrder(instrumentid, exchangeid, price, pricetype, volume, direction, offset)
        
    #----------------------------------------------------------------------
    def cancelOrder(self, instrumentid, exchangeid, orderref, frontid, sessionid):
        """撤单"""
        # self.td.cancelOrder(instrumentid, exchangeid, orderref, frontid, sessionid)
        
    #----------------------------------------------------------------------
    def getAccountPosition(self, event):
        """循环查询账户和持仓"""
        # self.countGet = self.countGet + 1
        #
        # # 每5秒发一次查询
        # if self.countGet > 5:
        #     self.countGet = 0   # 清空计数
        #
        #     if self.lastGet == 'Account':
        #         self.getPosition()
        #         self.lastGet = 'Position'
        #     else:
        #         self.getAccount()
        #         self.lastGet = 'Account'
    
    #----------------------------------------------------------------------
    def initGet(self, event):
        """在交易服务器登录成功后,开始初始化查询"""
        # 打开设定文件setting.vn
        # f = shelve.open('setting.vn')
        #
        # # 尝试读取设定字典,若该字典不存在,则发出查询请求
        # try:
        #     d = f['instrument']
        #
        #     # 如果本地保存的合约数据是今日的,则载入,否则发出查询请求
        #     today = date.today()
        #     if d['date'] == today:
        #         self.dictInstrument = d['dictInstrument']
        #
        #         # event = Event(type_=EVENT_LOG)
        #         # log = u'合约信息读取完成'
        #         # event.dict_['log'] = log
        #         # self.ee.put(event)
        #         #
        #         # self.getInvestor()
        #         #
        #         # # 开始循环查询
        #         # self.ee.register(EVENT_TIMER, self.getAccountPosition)
        #     else:
        #         self.getInstrument()
        # except KeyError:
        #     self.getInstrument()
        #
        # f.close()
 
    #----------------------------------------------------------------------
    def insertInstrument(self, event):
        """插入合约对象"""
        # data = event.dict_['data']
        # last = event.dict_['last']
        #
        # self.dictInstrument[data['InstrumentID']] = data
        #
        # # 合约对象查询完成后,查询投资者信息并开始循环查询
        # if last:
        #     # 将查询完成的合约信息保存到本地文件,今日登录可直接使用不再查询
        #     self.saveInstrument()
            
            # event = Event(type_=EVENT_LOG)
            # log = u'合约信息查询完成'
            # event.dict_['log'] = log
            # self.ee.put(event)
            #
            # self.getInvestor()
            #
            # # 开始循环查询
            # self.ee.register(EVENT_TIMER, self.getAccountPosition)
        
    #----------------------------------------------------------------------
    def selectInstrument(self, instrumentid):
        """获取合约信息对象"""
        # try:
        #     instrument = self.dictInstrument[instrumentid]
        # except KeyError:
        #     instrument = None
        # return instrument
    
    #----------------------------------------------------------------------
    def exit(self):
        """退出"""
        # 销毁API对象
        # self.td = None
        # self.md = None
        self.dsa = None
        
        # 停止事件驱动引擎
        self.ee.stop()
        
    #----------------------------------------------------------------------
    def saveInstrument(self):
        """保存合约属性数据"""
        # f = shelve.open('setting.vn')
        # d = {}
        # d['dictInstrument'] = self.dictInstrument
        # d['date'] = date.today()
        # f['instrument'] = d
        # f.close()