├── LICENSE ├── event └── event.go ├── gateway └── mockGateway │ └── mockGateway.go ├── main.go ├── module └── mockModule │ └── mockModule.go └── trader ├── engine ├── dataEngine.go └── mainEngine.go ├── vtConstant.go ├── vtEngine.go ├── vtGateway.go ├── vtModule.go └── vtObject.go /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /event/event.go: -------------------------------------------------------------------------------- 1 | package event 2 | 3 | import ( 4 | "sync" 5 | "time" 6 | ) 7 | 8 | type EventType string 9 | 10 | const ( 11 | EventTimer EventType = "eTimer" 12 | EventLog EventType = "eLog" 13 | EventTick EventType = "eTick." 14 | EventTrade EventType = "eTrade." 15 | EventOrder EventType = "eOrder." 16 | EventPosition EventType = "ePostion." 17 | EventAccount EventType = "eAccount." 18 | EventContract EventType = "eContract." 19 | EventError EventType = "eError." 20 | 21 | EventCTALog EventType = "eCTALog." 22 | EventCTAStrategy EventType = "eCTAStrategy." 23 | 24 | EventDataRecorderLog EventType = "eDataRecorderLog." 25 | ) 26 | 27 | func (et EventType) String() string { 28 | return string(et) 29 | } 30 | 31 | type Event struct { 32 | Type EventType 33 | Data interface{} 34 | } 35 | 36 | func NewEvent(eventType EventType) *Event { 37 | return &Event{ 38 | Type: eventType, 39 | } 40 | } 41 | 42 | type Handler func(event *Event) error 43 | 44 | func (h Handler) Handle(event *Event) error { 45 | return h(event) 46 | } 47 | 48 | type Eventbus struct { 49 | eventChan chan *Event 50 | handlers map[EventType]map[*Handler]bool 51 | generalHandlers map[*Handler]bool 52 | active bool 53 | sync.Mutex 54 | } 55 | 56 | func NewEventbus() *Eventbus { 57 | engine := &Eventbus{ 58 | eventChan: make(chan *Event, 2048), 59 | handlers: make(map[EventType]map[*Handler]bool), 60 | generalHandlers: make(map[*Handler]bool), 61 | active: false, 62 | } 63 | return engine 64 | } 65 | 66 | func (e *Eventbus) run() { 67 | ticker := time.NewTicker(time.Second) 68 | for e.active { 69 | select { 70 | case evt := <-e.eventChan: 71 | e.process(evt) 72 | case <-ticker.C: 73 | // log.Println("ticker Now") 74 | e.eventChan <- NewEvent(EventTimer) 75 | } 76 | } 77 | ticker.Stop() 78 | } 79 | 80 | func (e *Eventbus) process(event *Event) { 81 | if handlers, ok := e.handlers[event.Type]; ok { 82 | for handler := range handlers { 83 | go handler.Handle(event) 84 | } 85 | } 86 | for handler := range e.generalHandlers { 87 | go handler.Handle(event) 88 | } 89 | } 90 | 91 | func (e *Eventbus) Start() { 92 | e.active = true 93 | go e.run() 94 | } 95 | 96 | func (e *Eventbus) Stop() { 97 | e.active = false 98 | e.clear() 99 | } 100 | 101 | func (e *Eventbus) clear() { 102 | for evt := range e.eventChan { 103 | e.process(evt) 104 | } 105 | close(e.eventChan) 106 | } 107 | 108 | func (e *Eventbus) Register(type_ EventType, handler Handler) { 109 | e.Lock() 110 | if handlers, ok := e.handlers[type_]; ok { 111 | if _, exists := handlers[&handler]; !exists { 112 | handlers[&handler] = true 113 | } 114 | } else { 115 | e.handlers[type_] = make(map[*Handler]bool) 116 | e.handlers[type_][&handler] = true 117 | } 118 | e.Unlock() 119 | } 120 | 121 | func (e *Eventbus) Unregister(type_ EventType, handler Handler) { 122 | if handlers, ok := e.handlers[type_]; ok { 123 | delete(handlers, &handler) 124 | } 125 | } 126 | 127 | func (e *Eventbus) Put(event *Event) { 128 | e.eventChan <- event 129 | 130 | } 131 | 132 | func (e *Eventbus) RegisterGeneralHandler(handler Handler) { 133 | e.Lock() 134 | if _, ok := e.generalHandlers[&handler]; !ok { 135 | e.generalHandlers[&handler] = true 136 | } 137 | e.Unlock() 138 | 139 | } 140 | 141 | func (e *Eventbus) UnregisterGeneralHandler(handler Handler) { 142 | e.Lock() 143 | delete(e.generalHandlers, &handler) 144 | e.Unlock() 145 | } 146 | -------------------------------------------------------------------------------- /gateway/mockGateway/mockGateway.go: -------------------------------------------------------------------------------- 1 | package mockGateway 2 | 3 | import ( 4 | "vngo/event" 5 | . "vngo/trader" 6 | ) 7 | 8 | type MockGateway struct { 9 | Base VtGatewayBase 10 | Name string 11 | } 12 | 13 | func NewMockGateway(name string) *MockGateway { 14 | return &MockGateway{ 15 | Name: name, 16 | } 17 | } 18 | func (g *MockGateway) Init(bus *event.Eventbus, name string) { 19 | g.Base.Init(bus, name) 20 | } 21 | 22 | func (g *MockGateway) Connect() error { 23 | return nil 24 | } 25 | 26 | func (g *MockGateway) Subscribe(subscribeReq *VtSubscribeReq) error { 27 | return nil 28 | } 29 | 30 | func (g *MockGateway) SendOrder(orderReq *VtOrderReq) error { 31 | return nil 32 | } 33 | 34 | func (g *MockGateway) CancelOrder(cancelOrderReq *VtCancelOrderReq) error { 35 | return nil 36 | } 37 | 38 | func (g *MockGateway) QueryAccount() error { 39 | return nil 40 | } 41 | 42 | func (g *MockGateway) QueryPosition() error { 43 | return nil 44 | } 45 | 46 | func (g *MockGateway) Close() error { 47 | return nil 48 | } 49 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "time" 7 | "vngo/event" 8 | "vngo/gateway/mockGateway" 9 | 10 | . "vngo/event" 11 | "vngo/module/mockModule" 12 | ) 13 | 14 | func init() { 15 | log.SetFlags(log.LstdFlags | log.Lshortfile) 16 | } 17 | 18 | func simpletest(event *Event) error { 19 | fmt.Printf("process simpletest! event_type:%v\n", event.Type) 20 | log.Printf("simple test log\n") 21 | return nil 22 | } 23 | 24 | func process1() { 25 | ee := NewEventbus() 26 | 27 | // var handler Handler = simpletest 28 | ee.RegisterGeneralHandler(Handler(simpletest)) 29 | ee.Start() 30 | 31 | for { 32 | time.Sleep(time.Second) 33 | } 34 | } 35 | 36 | func process2() { 37 | module := mockModule.NewMockModule() 38 | gateway := mockGateway.NewMockGateway("mock") 39 | eventBus := NewEventbus() 40 | eventBus.Start() 41 | gateway.Init(eventBus, "mock") 42 | module.Setup(nil, eventBus) 43 | module.Start() 44 | for { 45 | log.Println("put tick event") 46 | eventBus.Put(NewEvent(event.EventTick)) 47 | log.Println("put order event") 48 | eventBus.Put(NewEvent(event.EventOrder)) 49 | log.Println("put trade event") 50 | eventBus.Put(NewEvent(event.EventTrade)) 51 | time.Sleep(2 * time.Second) 52 | log.Println() 53 | } 54 | } 55 | 56 | func main() { 57 | fmt.Println("vn.go") 58 | 59 | // process1() 60 | process2() 61 | } 62 | -------------------------------------------------------------------------------- /module/mockModule/mockModule.go: -------------------------------------------------------------------------------- 1 | package mockModule 2 | 3 | import ( 4 | "log" 5 | "vngo/event" 6 | "vngo/trader" 7 | ) 8 | 9 | type MockModule struct { 10 | trader.VtModule 11 | engine trader.VtEngine 12 | eventbus *event.Eventbus 13 | name string 14 | } 15 | 16 | func NewMockModule() *MockModule { 17 | return &MockModule{} 18 | } 19 | 20 | func (m *MockModule) Configure(name string, configRoot string) { 21 | m.name = name 22 | } 23 | 24 | func (m *MockModule) Setup(engine trader.VtEngine, bus *event.Eventbus) error { 25 | m.engine = engine 26 | m.eventbus = bus 27 | return nil 28 | } 29 | 30 | func (m *MockModule) Start() error { 31 | m.registerEvent() 32 | return nil 33 | } 34 | 35 | func (m *MockModule) Stop() error { 36 | return nil 37 | } 38 | 39 | func (m *MockModule) Description() interface{} { 40 | return nil 41 | } 42 | 43 | func (m *MockModule) registerEvent() { 44 | m.eventbus.Register(event.EventTick, event.Handler(m.processTickEvent)) 45 | m.eventbus.Register(event.EventOrder, event.Handler(m.processOrderEvent)) 46 | m.eventbus.Register(event.EventTrade, event.Handler(m.processTradeEvent)) 47 | } 48 | 49 | func (m *MockModule) processTickEvent(event *event.Event) error { 50 | log.Printf("Process Tick Event %+v\n", event) 51 | return nil 52 | } 53 | 54 | func (m *MockModule) processOrderEvent(event *event.Event) error { 55 | log.Printf("Process Order Event %+v\n", event) 56 | return nil 57 | } 58 | 59 | func (m *MockModule) processTradeEvent(event *event.Event) error { 60 | log.Printf("Process Trade Event %+v\n", event) 61 | return nil 62 | } 63 | -------------------------------------------------------------------------------- /trader/engine/dataEngine.go: -------------------------------------------------------------------------------- 1 | package engine 2 | 3 | import "vngo/trader" 4 | 5 | type DataEngine struct { 6 | trader.VtEngine 7 | } 8 | -------------------------------------------------------------------------------- /trader/engine/mainEngine.go: -------------------------------------------------------------------------------- 1 | package engine 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | 7 | . "vngo/event" 8 | . "vngo/trader" 9 | ) 10 | 11 | type MainEngine struct { 12 | VtEngine 13 | 14 | Gateways map[string]IVtGateway 15 | Modules map[string]VtModule 16 | 17 | Eventbus *Eventbus 18 | sync.RWMutex 19 | } 20 | 21 | func NewMainEngine() *MainEngine { 22 | me := &MainEngine{ 23 | Gateways: make(map[string]IVtGateway), 24 | Modules: make(map[string]VtModule), 25 | Eventbus: NewEventbus(), 26 | } 27 | return me 28 | } 29 | 30 | func (me *MainEngine) Configure(name string, configRoot string) error { 31 | return nil 32 | } 33 | 34 | func (me *MainEngine) Start() error { 35 | me.Eventbus.Start() 36 | return nil 37 | } 38 | 39 | func (me *MainEngine) Stop() error { 40 | me.Eventbus.Stop() 41 | return nil 42 | } 43 | 44 | func (me *MainEngine) AddModule(name string, module VtModule) { 45 | me.Lock() 46 | defer me.Unlock() 47 | me.Modules[name] = module 48 | } 49 | 50 | func (me *MainEngine) AddGateway(name string, gateway IVtGateway) { 51 | me.Lock() 52 | defer me.Unlock() 53 | me.Gateways[name] = gateway 54 | } 55 | 56 | func (me *MainEngine) Connect(gatewayName string) error { 57 | gateway, err := me.getGateway(gatewayName) 58 | if err != nil { 59 | return err 60 | } 61 | return gateway.Connect() 62 | } 63 | 64 | func (me *MainEngine) Subscribe(req *VtSubscribeReq, gatewayName string) error { 65 | gateway, err := me.getGateway(gatewayName) 66 | if err != nil { 67 | return err 68 | } 69 | return gateway.Subscribe(req) 70 | } 71 | 72 | func (me *MainEngine) SendOrder(req *VtOrderReq, gatewayName string) error { 73 | gateway, err := me.getGateway(gatewayName) 74 | if err != nil { 75 | return err 76 | } 77 | return gateway.SendOrder(req) 78 | } 79 | 80 | func (me *MainEngine) CancelOrder(req *VtCancelOrderReq, gatewayName string) error { 81 | gateway, err := me.getGateway(gatewayName) 82 | if err != nil { 83 | return err 84 | } 85 | return gateway.CancelOrder(req) 86 | } 87 | 88 | func (me *MainEngine) QueryAccount(gatewayName string) error { 89 | gateway, err := me.getGateway(gatewayName) 90 | if err != nil { 91 | return err 92 | } 93 | return gateway.QueryAccount() 94 | } 95 | 96 | func (me *MainEngine) QueryPosition(gatewayName string) error { 97 | gateway, err := me.getGateway(gatewayName) 98 | if err != nil { 99 | return err 100 | } 101 | return gateway.QueryPosition() 102 | } 103 | 104 | func (me *MainEngine) Close() error { 105 | me.RLock() 106 | defer me.RUnlock() 107 | return nil 108 | } 109 | 110 | func (me *MainEngine) getGateway(gatewayName string) (IVtGateway, error) { 111 | me.RLock() 112 | defer me.RUnlock() 113 | gateway, ok := me.Gateways[gatewayName] 114 | if !ok { 115 | err := fmt.Errorf("gateway %v not exists \n", gatewayName) 116 | return nil, err 117 | } 118 | return gateway, nil 119 | } 120 | -------------------------------------------------------------------------------- /trader/vtConstant.go: -------------------------------------------------------------------------------- 1 | package trader 2 | 3 | // 默认空值 4 | const ( 5 | EMPTY_STRING = "" 6 | EMPTY_UNICODE = "" 7 | EMPTY_INT = 0 8 | EMPTY_FLOAT = 0.0 9 | 10 | // 方向常量 11 | DIRECTION_NONE = "无方向" 12 | DIRECTION_LONG = "多" 13 | DIRECTION_SHORT = "空" 14 | DIRECTION_UNKNOWN = "未知" 15 | DIRECTION_NET = "净" 16 | DIRECTION_SELL = "卖出" // IB接口 17 | DIRECTION_COVEREDSHORT = "备兑空" // 证券期权 18 | 19 | // 开平常量 20 | OFFSET_NONE = "无开平" 21 | OFFSET_OPEN = "开仓" 22 | OFFSET_CLOSE = "平仓" 23 | OFFSET_CLOSETODAY = "平今" 24 | OFFSET_CLOSEYESTERDAY = "平昨" 25 | OFFSET_UNKNOWN = "未知" 26 | 27 | // 状态常量 28 | STATUS_NOTTRADED = "未成交" 29 | STATUS_PARTTRADED = "部分成交" 30 | STATUS_ALLTRADED = "全部成交" 31 | STATUS_CANCELLED = "已撤销" 32 | STATUS_REJECTED = "拒单" 33 | STATUS_UNKNOWN = "未知" 34 | 35 | // 合约类型常量 36 | PRODUCT_EQUITY = "股票" 37 | PRODUCT_FUTURES = "期货" 38 | PRODUCT_OPTION = "期权" 39 | PRODUCT_INDEX = "指数" 40 | PRODUCT_COMBINATION = "组合" 41 | PRODUCT_FOREX = "外汇" 42 | PRODUCT_UNKNOWN = "未知" 43 | PRODUCT_SPOT = "现货" 44 | PRODUCT_DEFER = "延期" 45 | PRODUCT_ETF = "ETF" 46 | PRODUCT_WARRANT = "权证" 47 | PRODUCT_BOND = "债券" 48 | PRODUCT_NONE = "" 49 | 50 | // 价格类型常量 51 | PRICETYPE_LIMITPRICE = "限价" 52 | PRICETYPE_MARKETPRICE = "市价" 53 | PRICETYPE_FAK = "FAK" 54 | PRICETYPE_FOK = "FOK" 55 | 56 | // 期权类型 57 | OPTION_CALL = "看涨期权" 58 | OPTION_PUT = "看跌期权" 59 | 60 | // 交易所类型 61 | EXCHANGE_SSE = "SSE" // 上交所 62 | EXCHANGE_SZSE = "SZSE" // 深交所 63 | EXCHANGE_CFFEX = "CFFEX" // 中金所 64 | EXCHANGE_SHFE = "SHFE" // 上期所 65 | EXCHANGE_CZCE = "CZCE" // 郑商所 66 | EXCHANGE_DCE = "DCE" // 大商所 67 | EXCHANGE_SGE = "SGE" // 上金所 68 | EXCHANGE_INE = "INE" // 国际能源交易中心 69 | EXCHANGE_UNKNOWN = "UNKNOWN" // 未知交易所 70 | EXCHANGE_NONE = "" // 空交易所 71 | EXCHANGE_HKEX = "HKEX" // 港交所 72 | EXCHANGE_HKFE = "HKFE" // 香港期货交易所 73 | 74 | EXCHANGE_SMART = "SMART" // IB智能路由(股票、期权) 75 | EXCHANGE_NYMEX = "NYMEX" // IB 期货 76 | EXCHANGE_GLOBEX = "GLOBEX" // CME电子交易平台 77 | EXCHANGE_IDEALPRO = "IDEALPRO" // IB外汇ECN 78 | 79 | EXCHANGE_CME = "CME" // CME交易所 80 | EXCHANGE_ICE = "ICE" // ICE交易所 81 | EXCHANGE_LME = "LME" // LME交易所 82 | 83 | EXCHANGE_OANDA = "OANDA" // OANDA外汇做市商 84 | EXCHANGE_OKCOIN = "OKCOIN" // OKCOIN比特币交易所 85 | EXCHANGE_HUOBI = "HUOBI" // 火币比特币交易所 86 | EXCHANGE_LHANG = "LHANG" // 链行比特币交易所 87 | 88 | // 货币类型 89 | CURRENCY_USD = "USD" // 美元 90 | CURRENCY_CNY = "CNY" // 人民币 91 | CURRENCY_HKD = "HKD" // 港币 92 | CURRENCY_UNKNOWN = "UNKNOWN" // 未知货币 93 | CURRENCY_NONE = "" // 空货币 94 | 95 | // 数据库 96 | LOG_DB_NAME = "VnTrader_Log_Db" 97 | 98 | // 接口类型 99 | GATEWAYTYPE_EQUITY = "equity" // 股票、ETF、债券 100 | GATEWAYTYPE_FUTURES = "futures" // 期货、期权、贵金属 101 | GATEWAYTYPE_INTERNATIONAL = "international" // 外盘 102 | GATEWAYTYPE_BTC = "btc" // 比特币 103 | GATEWAYTYPE_DATA = "data" // 数据(非交易) 104 | 105 | ) 106 | 107 | const ( 108 | SAVE_DATA = "保存数据" 109 | 110 | CONTRACT_SYMBOL = "合约代码" 111 | CONTRACT_NAME = "名称" 112 | LAST_PRICE = "最新价" 113 | PRE_CLOSE_PRICE = "昨收盘" 114 | VOLUME = "成交量" 115 | OPEN_INTEREST = "持仓量" 116 | OPEN_PRICE = "开盘价" 117 | HIGH_PRICE = "最高价" 118 | LOW_PRICE = "最低价" 119 | TIME = "时间" 120 | GATEWAY = "接口" 121 | CONTENT = "内容" 122 | 123 | ERROR_CODE = "错误代码" 124 | ERROR_MESSAGE = "错误信息" 125 | 126 | TRADE_ID = "成交编号" 127 | ORDER_ID = "委托编号" 128 | DIRECTION = "方向" 129 | OFFSET = "开平" 130 | PRICE = "价格" 131 | TRADE_TIME = "成交时间" 132 | 133 | ORDER_VOLUME = "委托数量" 134 | TRADED_VOLUME = "成交数量" 135 | ORDER_STATUS = "委托状态" 136 | ORDER_TIME = "委托时间" 137 | CANCEL_TIME = "撤销时间" 138 | FRONT_ID = "前置编号" 139 | SESSION_ID = "会话编号" 140 | POSITION = "持仓量" 141 | YD_POSITION = "昨持仓" 142 | FROZEN = "冻结量" 143 | POSITION_PROFIT = "持仓盈亏" 144 | 145 | ACCOUNT_ID = "账户编号" 146 | PRE_BALANCE = "昨净值" 147 | BALANCE = "净值" 148 | AVAILABLE = "可用" 149 | COMMISSION = "手续费" 150 | MARGIN = "保证金" 151 | CLOSE_PROFIT = "平仓盈亏" 152 | 153 | TRADING = "交易" 154 | PRICE_TYPE = "价格类型" 155 | EXCHANGE = "交易所" 156 | CURRENCY = "货币" 157 | PRODUCT_CLASS = "产品类型" 158 | LAST = "最新" 159 | SEND_ORDER = "发单" 160 | CANCEL_ALL = "全撤" 161 | VT_SYMBOL = "vt系统代码" 162 | CONTRACT_SIZE = "合约大小" 163 | PRICE_TICK = "最小价格变动" 164 | STRIKE_PRICE = "行权价" 165 | UNDERLYING_SYMBOL = "标的代码" 166 | OPTION_TYPE = "期权类型" 167 | EXPIRY_DATE = "到期日" 168 | 169 | REFRESH = "刷新" 170 | SEARCH = "查询" 171 | CONTRACT_SEARCH = "合约查询" 172 | 173 | BID_1 = "买一" 174 | BID_2 = "买二" 175 | BID_3 = "买三" 176 | BID_4 = "买四" 177 | BID_5 = "买五" 178 | ASK_1 = "卖一" 179 | ASK_2 = "卖二" 180 | ASK_3 = "卖三" 181 | ASK_4 = "卖四" 182 | ASK_5 = "卖五" 183 | 184 | BID_PRICE_1 = "买一价" 185 | BID_PRICE_2 = "买二价" 186 | BID_PRICE_3 = "买三价" 187 | BID_PRICE_4 = "买四价" 188 | BID_PRICE_5 = "买五价" 189 | ASK_PRICE_1 = "卖一价" 190 | ASK_PRICE_2 = "卖二价" 191 | ASK_PRICE_3 = "卖三价" 192 | ASK_PRICE_4 = "卖四价" 193 | ASK_PRICE_5 = "卖五价" 194 | 195 | BID_VOLUME_1 = "买一量" 196 | BID_VOLUME_2 = "买二量" 197 | BID_VOLUME_3 = "买三量" 198 | BID_VOLUME_4 = "买四量" 199 | BID_VOLUME_5 = "买五量" 200 | ASK_VOLUME_1 = "卖一量" 201 | ASK_VOLUME_2 = "卖二量" 202 | ASK_VOLUME_3 = "卖三量" 203 | ASK_VOLUME_4 = "卖四量" 204 | ASK_VOLUME_5 = "卖五量" 205 | 206 | MARKET_DATA = "行情" 207 | LOG = "日志" 208 | ERROR = "错误" 209 | TRADE = "成交" 210 | ORDER = "委托" 211 | ACCOUNT = "账户" 212 | WORKING_ORDER = "可撤" 213 | 214 | SYSTEM = "系统" 215 | CONNECT_DATABASE = "连接数据库" 216 | EXIT = "退出" 217 | APPLICATION = "功能" 218 | DATA_RECORDER = "行情记录" 219 | RISK_MANAGER = "风控管理" 220 | 221 | STRATEGY = "策略" 222 | CTA_STRATEGY = "CTA策略" 223 | 224 | HELP = "帮助" 225 | RESTORE = "还原窗口" 226 | ABOUT = "关于" 227 | TEST = "测试" 228 | CONNECT = "连接" 229 | EDIT_SETTING = "编辑配置" 230 | LOAD = "读取" 231 | SAVE = "保存" 232 | 233 | CPU_MEMORY_INFO = "CPU使用率:{cpu}% 内存使用率:{memory}%" 234 | CONFIRM_EXIT = "确认退出?" 235 | 236 | GATEWAY_NOT_EXIST = "接口不存在:{gateway}" 237 | DATABASE_CONNECTING_COMPLETED = "MongoDB连接成功" 238 | DATABASE_CONNECTING_FAILED = "MongoDB连接失败" 239 | DATA_INSERT_FAILED = "数据插入失败,MongoDB没有连接" 240 | DATA_QUERY_FAILED = "数据查询失败,MongoDB没有连接" 241 | DATA_UPDATE_FAILED = "数据更新失败,MongoDB没有连接" 242 | ) 243 | -------------------------------------------------------------------------------- /trader/vtEngine.go: -------------------------------------------------------------------------------- 1 | package trader 2 | 3 | type VtEngine interface { 4 | Start() error 5 | Stop() error 6 | Connect(gatewayName string) error 7 | Subscribe(req *VtSubscribeReq, gateway string) error 8 | SendOrder(req *VtOrderReq, gateway string) error 9 | CancelOrder(req *VtCancelOrderReq, gateway string) error 10 | QueryAccount(gateway string) error 11 | QueryPosition(gateway string) error 12 | Close() error 13 | } 14 | -------------------------------------------------------------------------------- /trader/vtGateway.go: -------------------------------------------------------------------------------- 1 | package trader 2 | 3 | import . "vngo/event" 4 | 5 | //VtGateway 对接交易接口 6 | type IVtGateway interface { 7 | Init(eventbus *Eventbus, name string) 8 | 9 | Connect() error 10 | Subscribe(subscribeReq *VtSubscribeReq) error 11 | SendOrder(orderReq *VtOrderReq) error 12 | CancelOrder(cancelOrderReq *VtCancelOrderReq) error 13 | QueryAccount() error 14 | QueryPosition() error 15 | Close() error 16 | 17 | OnTick(tick *VtTickData) 18 | OnTrade(trade *VtTradeData) 19 | OnOrder(order *VtOrderData) 20 | OnPosition(position *VtPositionData) 21 | OnAccount(account *VtAccountData) 22 | OnError(err *VtErrorData) 23 | OnLog(log *VtLogData) 24 | OnContract(contract *VtContractData) 25 | 26 | Decription() interface{} 27 | Name() string 28 | } 29 | 30 | type VtGatewayBase struct { 31 | IVtGateway 32 | EventBus *Eventbus 33 | GatewayName string 34 | } 35 | 36 | func (g *VtGatewayBase) Init(eventbus *Eventbus, name string) { 37 | g.EventBus = eventbus 38 | g.GatewayName = name 39 | } 40 | 41 | //OnTick 市场行情推送 42 | func (g *VtGatewayBase) OnTick(tick *VtTickData) { 43 | 44 | event1 := NewEvent(EventTick) 45 | event1.Data = tick 46 | g.EventBus.Put(event1) 47 | 48 | // 特定合约代码的事件 49 | event2 := NewEvent(EventType(EventTick.String() + tick.VtSymbol)) 50 | event2.Data = tick 51 | g.EventBus.Put(event2) 52 | } 53 | 54 | //OnTrade 成交信息推送 55 | func (g *VtGatewayBase) OnTrade(trade *VtTradeData) { 56 | // 通用事件 57 | event1 := NewEvent(EventTrade) 58 | event1.Data = trade 59 | g.EventBus.Put(event1) 60 | 61 | // 特定合约的成交事件 62 | event2 := NewEvent(EventType(EventTrade.String() + trade.VtSymbol)) 63 | event1.Data = trade 64 | g.EventBus.Put(event2) 65 | } 66 | 67 | //OnOrder 订单变化推送 68 | func (g *VtGatewayBase) OnOrder(order *VtOrderData) { 69 | // 通用事件 70 | event1 := NewEvent(EventOrder) 71 | event1.Data = order 72 | g.EventBus.Put(event1) 73 | 74 | // 特定订单编号的事件 75 | event2 := NewEvent(EventType(EventOrder.String() + order.VtOrderID)) 76 | event1.Data = order 77 | g.EventBus.Put(event2) 78 | } 79 | 80 | //OnPosition 持仓信息推送 81 | func (g *VtGatewayBase) OnPosition(position *VtPositionData) { 82 | 83 | // 通用事件 84 | event1 := NewEvent(EventPosition) 85 | event1.Data = position 86 | g.EventBus.Put(event1) 87 | 88 | // 特定合约代码的事件 89 | event2 := NewEvent(EventType(EventPosition.String() + position.VtSymbol)) 90 | event1.Data = position 91 | g.EventBus.Put(event2) 92 | } 93 | 94 | //OnAccount 账户信息推送 95 | func (g *VtGatewayBase) OnAccount(account *VtAccountData) { 96 | // 通用事件 97 | event1 := NewEvent(EventAccount) 98 | event1.Data = account 99 | g.EventBus.Put(event1) 100 | 101 | // 特定合约代码的事件 102 | event2 := NewEvent(EventType(EventAccount.String() + account.VtAccountID)) 103 | event1.Data = account 104 | g.EventBus.Put(event2) 105 | } 106 | 107 | //OnError 错误信息推送 108 | func (g *VtGatewayBase) OnError(err *VtErrorData) { 109 | event1 := NewEvent(EventError) 110 | event1.Data = err 111 | g.EventBus.Put(event1) 112 | } 113 | 114 | //OnLog 日志推送 115 | func (g *VtGatewayBase) OnLog(log *VtLogData) { 116 | event1 := NewEvent(EventLog) 117 | event1.Data = log 118 | g.EventBus.Put(event1) 119 | } 120 | 121 | //OnContract 合约基础信息推送 122 | func (g *VtGatewayBase) OnContract(contract *VtContractData) { 123 | event1 := NewEvent(EventContract) 124 | event1.Data = contract 125 | g.EventBus.Put(event1) 126 | } 127 | 128 | func (g *VtGatewayBase) Connect() error { 129 | return nil 130 | } 131 | 132 | func (g *VtGatewayBase) Subscribe(subscribeReq *VtSubscribeReq) error { 133 | return nil 134 | } 135 | 136 | func (g *VtGatewayBase) SendOrder(orderReq *VtOrderReq) error { 137 | return nil 138 | } 139 | 140 | func (g *VtGatewayBase) CancelOrder(cancelOrderReq *VtCancelOrderReq) error { 141 | return nil 142 | } 143 | 144 | func (g *VtGatewayBase) QueryAccount() error { 145 | return nil 146 | } 147 | 148 | func (g *VtGatewayBase) QueryPosition() error { 149 | return nil 150 | } 151 | 152 | func (g *VtGatewayBase) Close() error { 153 | return nil 154 | } 155 | -------------------------------------------------------------------------------- /trader/vtModule.go: -------------------------------------------------------------------------------- 1 | package trader 2 | 3 | import . "vngo/event" 4 | 5 | type VtModule interface { 6 | Configure(name string, configRoot string) 7 | Setup(engine VtEngine, bus *Eventbus) error 8 | Start() error 9 | Stop() error 10 | 11 | Name() string 12 | Description() interface{} 13 | } 14 | -------------------------------------------------------------------------------- /trader/vtObject.go: -------------------------------------------------------------------------------- 1 | package trader 2 | 3 | import "time" 4 | 5 | //VtBaseData 基本数据 6 | type VtBaseData struct { 7 | Gateway string 8 | RawData []byte 9 | } 10 | 11 | //VtTickData Tick行情数据类 12 | type VtTickData struct { 13 | VtBaseData 14 | // 代码相关 15 | Symbol string // 合约代码 16 | Exchange string // 交易所代码 17 | VtSymbol string // 合约在vt系统中的唯一代码,通常是 合约代码.交易所代码 18 | 19 | // 成交数据 20 | LastPrice float64 //最新成交价 21 | LastVolume int64 // 最新成交量 22 | Volume int64 // 今天总成交量 23 | OpenInterest int64 // 持仓量 24 | Time string // 时间 11:20:56.5 25 | Date string // 日期 20151009 26 | Datetime time.Time // golang 的datetime时间对象 27 | 28 | // 常规行情 29 | OpenPrice float64 // 今日开盘价 30 | HighPrice float64 // 今日最高价 31 | HowPrice float64 // 今日最低价 32 | PreClosePrice float64 33 | 34 | UpperLimit float64 // 涨停价 35 | LowerLimit float64 // 跌停价 36 | 37 | // 五档行情 38 | BidPrice1 float64 39 | BidPrice2 float64 40 | BidPrice3 float64 41 | BidPrice4 float64 42 | BidPrice5 float64 43 | 44 | AskPrice1 float64 45 | AskPrice2 float64 46 | AskPrice3 float64 47 | AskPrice4 float64 48 | AskPrice5 float64 49 | 50 | BidVolume1 int64 51 | BidVolume2 int64 52 | BidVolume3 int64 53 | BidVolume4 int64 54 | BidVolume5 int64 55 | 56 | AskVolume1 int64 57 | AskVolume2 int64 58 | AskVolume3 int64 59 | AskVolume4 int64 60 | AskVolume5 int64 61 | } 62 | 63 | // VtBarData: K线数据 64 | type VtBarData struct { 65 | VtBaseData 66 | 67 | VtSymbol string // vt系统代码 68 | Symbol string // 代码 69 | Exchange string // 交易所 70 | 71 | Open float64 // OHLC 72 | High float64 73 | Low float64 74 | Close float64 75 | 76 | Date string // bar开始的时间,日期 77 | Time string // 时间 78 | Datetime time.Time // golang 的 datetime 时间对象 79 | 80 | Volume int64 // 成交量 81 | OpenInterest int64 // 持仓量 82 | 83 | } 84 | 85 | // VtTradeData 成交数据类 86 | type VtTradeData struct { 87 | VtBaseData 88 | 89 | // 代码编号相关 90 | Symbol string // 合约代码 91 | Exchange string // 交易所代码 92 | VtSymbol string // 合约在vt系统中的唯一代码,通常是 合约代码.交易所代码 93 | 94 | TradeID string // 成交编号 95 | VtTradeID string // 成交在vt系统中的唯一编号,通常是 Gateway 名.成交编号 96 | 97 | OrderID string // 订单编号 98 | VtOrderID string // 订单在vt系统中的唯一编号,通常是 Gateway 名.订单编号 99 | 100 | // 成交相关 101 | Direction string // 成交方向 102 | Offset string // 成交开平仓 103 | Price float64 // 成交价格 104 | Volume int64 // 成交数量 105 | TradeTime string // 成交时间 106 | } 107 | 108 | // VtOrderData 订单数据类 109 | type VtOrderData struct { 110 | VtBaseData 111 | 112 | // 代码编号相关 113 | Symbol string // 合约代码 114 | Exchange string // 交易所代码 115 | VtSymbol string // 合约在vt系统中的唯一代码,通常是 合约代码.交易所代码 116 | 117 | OrderID string // 订单编号 118 | VtOrderID string // 订单在vt系统中的唯一编号,通常是 Gateway名.订单编号 119 | 120 | // 报单相关 121 | Direction string // 报单方向 122 | Offset string // 报单开平仓 123 | Price float64 // 报单价格 124 | TotalVolume int64 // 报单总数量 125 | TradedVolume int64 // 报单成交数量 126 | Status string // 报单状态 127 | 128 | OrderTime string // 发单时间 129 | CancelTime string // 撤单时间 130 | 131 | // CTP/LTS相关 132 | FrontID int64 // 前置机编号 133 | SessionID int64 // 连接编号 134 | } 135 | 136 | // VtPositionData 持仓数据类 137 | type VtPositionData struct { 138 | VtBaseData 139 | 140 | // 代码编号相关 141 | Symbol string // 合约代码 142 | Exchange string // 交易所代码 143 | VtSymbol string // 合约在vt系统中的唯一代码,合约代码.交易所代码 144 | 145 | // 持仓相关 146 | Direction string // 持仓方向 147 | Position int64 // 持仓量 148 | Frozen int64 // 冻结数量 149 | Price float64 // 持仓均价 150 | VtPositionName string // 持仓在vt系统中的唯一代码,通常是vtSymbol.方向 151 | YdPosition int64 // 昨持仓 152 | PositionProfit float64 // 持仓盈亏 153 | } 154 | 155 | // VtAccountData 账户数据类 156 | type VtAccountData struct { 157 | VtBaseData 158 | 159 | // 账号代码相关 160 | AccountID string // 账户代码 161 | VtAccountID string // 账户在vt中的唯一代码,通常是 Gateway名.账户代码 162 | 163 | // 数值相关 164 | PreBalance float64 // 昨日账户结算净值 165 | Balance float64 // 账户净值 166 | Available float64 // 可用资金 167 | Commission float64 // 今日手续费 168 | Margin float64 // 保证金占用 169 | CloseProfit float64 // 平仓盈亏 170 | PositionProfit float64 // 持仓盈亏 171 | } 172 | 173 | // VtErrorData 错误数据类 174 | type VtErrorData struct { 175 | VtBaseData 176 | 177 | ErrorID string // 错误代码 178 | ErrorMsg string // 错误信息 179 | AdditionalInfo string // 补充信息 180 | 181 | ErrorTime string // 错误生成时间 182 | 183 | } 184 | 185 | func (e VtErrorData) Error() string { 186 | return "" 187 | } 188 | 189 | // VtLogData 日志数据类 190 | type VtLogData struct { 191 | VtBaseData 192 | 193 | logTime string // 日志生成时间 194 | logContent string // 日志信息 195 | logLevel string // 日志级别 196 | } 197 | 198 | // VtContractData 合约详细信息类 199 | type VtContractData struct { 200 | VtBaseData 201 | 202 | Symbol string // 代码 203 | Exchange string // 交易所代码 204 | VtSymbol string // 合约在vt系统中的唯一代码,通常是 合约代码.交易所代码 205 | Name string // 合约中文名 206 | 207 | ProductClass string // 合约类型 208 | Size int64 // 合约大小 209 | PriceTick float64 // 合约最小价格TICK 210 | 211 | // 期权相关 212 | StrikePrice float64 // 期权行权价 213 | UnderlyingSymbol string // 标的物合约代码 214 | OptionType string // 期权类型 215 | ExpiryDate string // 到期日 216 | } 217 | 218 | // VtSubscribeReq 订阅行情时传入结构体 219 | type VtSubscribeReq struct { 220 | Symbol string // 代码 221 | Exchange string // 交易所 222 | 223 | // 以下为IB相关 224 | ProductClass string // 合约类型 225 | Currency string // 合约货币 226 | Expiry string // 到期日 227 | StrikePrice float64 // 行权价 228 | OptionType string // 期权类型 229 | } 230 | 231 | // VtOrderReq 发单时传入的结构体 232 | type VtOrderReq struct { 233 | Symbol string // 代码 234 | Exchange string // 交易所 235 | VtSymbol string // VT合约代码 236 | Price float64 // 价格 237 | Volume int64 // 数量 238 | 239 | PriceType string // 价格类型 240 | Direction string // 买卖 241 | Offset string // 开平 242 | 243 | // 以下为IB相关 244 | ProductClass string // 合约类型 245 | Currency string // 合约货币 246 | Expiry string // 到期日 247 | StrikePrice float64 // 行权价 248 | OptionType string // 期权类型 249 | LastTradeDateOrContractMonth string // 合约月,IB专用 250 | Multiplier string // 乘数,IB专用 251 | } 252 | 253 | // VtCancelOrderReq 撤单时传入结构体 254 | type VtCancelOrderReq struct { 255 | Symbol string // 代码 256 | Exchange string // 交易所 257 | VtSymbol string // VT合约代码 258 | 259 | // 以下字段主要和CTP、LTS类接口相关 260 | OrderID string // 报单号 261 | FrontID string // 前置机号 262 | SessionID string // 会话号 263 | 264 | } 265 | --------------------------------------------------------------------------------