需求:
用网页打开
登陆框:brokerId,investorId,密码,登陆
下单框:选择方向:买、卖,选择开平:开,平,平今,价格,数量。
持仓框:合约名称,多空,手数,可平,持仓均价,持仓盈亏
挂单框:合约名称,开平,委托价,委托量,挂单量?
委托框:合约名称,状态,开平,委托价,委托量,已成交,已撤单,委托时间
成交框:合约名称,开平,成交价,成交量,成交时间
思路:
新建一个Web的项目,基于Spring框架。
一方面,后端通过WebSocket与网页(HTML5)建立连接,通过STOMP协议交换数据。网页将登陆信息,下单操作信息发送给后端。后端将得到的持仓、挂单、委托、成交错误等信息实时的发送给网页。
另一方面,后端通过CTP API,将前端发送过来的登陆、下单请求发给交易服务器。再计算各种状态,将结果通知给前端。(也可以单独新建一个项目,单独实现CTP API的功能,然后通过ActiveMQ(或其他方式)进行处理。本文中,假设CTP API已经实现,这里会使用假的接口假装实现一下。
开搞:
因为所有的功能基本上是表格,很自然的就找到了ag-grid这个东西。
先画一个:
<!DOCTYPE html> <html> <head> <script src="https://unpkg.com/ag-grid-community/dist/ag-grid-community.min.noStyle.js"></script> <link rel="stylesheet" href="https://unpkg.com/ag-grid-community/dist/styles/ag-grid.css"> <link rel="stylesheet" href="https://unpkg.com/ag-grid-community/dist/styles/ag-theme-balham.css"> </head> <body> <div id="orderPanel" style="height: 50px; width:1280px;">这里是下单框</div> <div id="positionGrid" style="height: 120px;width:1280px;" class="ag-theme-balham">这是持仓框</div> <div id="pendingOrdersGrid" style="height: 120px;width:1280px;" class="ag-theme-balham">这是挂单框</div> <div id="allOrdersGrid" style="height: 120px;width:1280px;" class="ag-theme-balham">这是委托框</div> <br/> <div id="tradedGrid" style="height: 120px;width:1280px;" class="ag-theme-balham">这是成交框</div> <script type="text/javascript" charset="utf-8"> var positionColumnDefs = [ { headerName: "合约名称", field: "InstrumentID" }, { headerName: "多空", field: "PosiDirection" }, { headerName: "手数", field: "Volume" }, { headerName: "可平", field: "Volume1" }, { headerName: "持仓均价", field: "OpenCost" }, { headerName: "持仓盈亏", field: "PositionProfit" } ]; // specify the data var positionRowData = [ { InstrumentID: "i1901", PosiDirection: "多",Volume:39,Volume1:20, OpenCost:3311,PositionProfit: 35000 }, { InstrumentID: "m1901", PosiDirection: "空",Volume:39,Volume1:20, OpenCost:3311,PositionProfit: 35000 } ]; var positionGridOptions = { columnDefs: positionColumnDefs, rowData: positionRowData, enableSorting: true, rowSelection: 'single' }; // lookup the container we want the Grid to use var positionGridDiv = document.querySelector('#positionGrid'); // create the grid passing in the div to use together with the columns & data we want to use new agGrid.Grid(positionGridDiv, positionGridOptions); ///挂单框/// var pendingOrdersColumnDefs = [ { headerName: "合约名称", field: "InstrumentID" }, { headerName: "开平", field: "CombOffsetFlag" }, { headerName: "委托价", field: "LimitPrice" }, { headerName: "委托量", field: "VolumeTotalOriginal" }, { headerName: "挂单量", field: "VolumeTotal" } ]; // specify the data var pendingOrdersRowData = [ { InstrumentID: "i1901", CombOffsetFlag: "开",LimitPrice:5555,VolumeTotalOriginal:20, VolumeTotal:20}, { InstrumentID: "m1901", CombOffsetFlag: "平",LimitPrice:3721,VolumeTotalOriginal:20, VolumeTotal:10} ]; var pendingOrdersGridOptions = { columnDefs: pendingOrdersColumnDefs, rowData: pendingOrdersRowData, enableSorting: true, rowSelection: 'single' }; // lookup the container we want the Grid to use var pendingOrdersGridDiv = document.querySelector('#pendingOrdersGrid'); // create the grid passing in the div to use together with the columns & data we want to use new agGrid.Grid(pendingOrdersGridDiv, pendingOrdersGridOptions); //委托框// var allOrdersColumnDefs = [ { headerName: "合约名称", field: "InstrumentID" }, { headerName: "状态", field: "OrderStatus" }, { headerName: "开平", field: "CombOffsetFlag" }, { headerName: "委托价", field: "LimitPrice" }, { headerName: "委托量", field: "VolumeTotalOriginal" }, { headerName: "已成交", field: "VolumeTraded" }, { headerName: "已撤单", field: "VolumeCancelled" }, { headerName: "委托时间", field: "InsertTime" } ]; // specify the data var allOrdersRowData = [ { InstrumentID: "i1901", OrderStatus: "已成",CombOffsetFlag:"开",LimitPrice:509, VolumeTotalOriginal:2,VolumeTraded: 2, VolumeCancelled:0,InsertTime:"22:18:00"}, { InstrumentID: "m1901", OrderStatus: "已成",CombOffsetFlag:"平",LimitPrice:509, VolumeTotalOriginal:2,VolumeTraded: 2, VolumeCancelled:0,InsertTime:"23:18:00"}, ]; var allOrdersGridOptions = { columnDefs: allOrdersColumnDefs, rowData: allOrdersRowData, enableSorting: true }; // lookup the container we want the Grid to use var allOrdersGridDiv = document.querySelector('#allOrdersGrid'); // create the grid passing in the div to use together with the columns & data we want to use new agGrid.Grid(allOrdersGridDiv, allOrdersGridOptions); ///成交框/ var tradedColumnDefs = [ { headerName: "合约名称", field: "InstrumentID" }, { headerName: "开平", field: "OffsetFlag" }, { headerName: "成交价", field: "Price" }, { headerName: "成交量", field: "Volume" }, { headerName: "成交时间", field: "TradeTime" } ]; // specify the data var tradedRowData = [ { InstrumentID: "i1901", OffsetFlag: "平",Price:501,Volume:20, TradeTime:"09:00:01" }, { InstrumentID: "m1901", OffsetFlag: "开",Price:501,Volume:20, TradeTime:"09:00:02" }, { InstrumentID: "rb1901", OffsetFlag: "平",Price:501,Volume:20, TradeTime:"09:00:01" }, { InstrumentID: "i1901", OffsetFlag: "开",Price:501,Volume:20, TradeTime:"13:33:01" }, { InstrumentID: "i1901", OffsetFlag: "平",Price:501,Volume:20, TradeTime:"09:00:01" }, { InstrumentID: "i1901", OffsetFlag: "开",Price:501,Volume:20, TradeTime:"14:00:01" }, { InstrumentID: "i1901", OffsetFlag: "平",Price:501,Volume:20, TradeTime:"09:00:01" }, { InstrumentID: "i1901", OffsetFlag: "开",Price:501,Volume:20, TradeTime:"10:00:01" }, { InstrumentID: "i1901", OffsetFlag: "开",Price:501,Volume:20, TradeTime:"11:00:01" }, { InstrumentID: "i1901", OffsetFlag: "平",Price:501,Volume:20, TradeTime:"22:00:01" }, { InstrumentID: "i1901", OffsetFlag: "平",Price:501,Volume:20, TradeTime:"09:00:01" }, ]; var tradedGridOptions = { columnDefs: tradedColumnDefs, rowData: tradedRowData, enableSorting: true }; // lookup the container we want the Grid to use var tradedGridDiv = document.querySelector('#tradedGrid'); // create the grid passing in the div to use together with the columns & data we want to use new agGrid.Grid(tradedGridDiv, tradedGridOptions); </script> </body> </html>
这是效果图:
持仓框和挂单框可以选择,通知下单框当前选中的那个合约,可以进行相应的平仓、修改委托和撤单操作。