diff --git a/vn.ib/ibapi/client/shared_ptr.h b/vn.ib/ibapi/client/shared_ptr.h index c1bea151..5cbe7d31 100644 --- a/vn.ib/ibapi/client/shared_ptr.h +++ b/vn.ib/ibapi/client/shared_ptr.h @@ -90,6 +90,17 @@ public: use_ = Use(); } + //灏佽娣诲姞 + bool operator==(const shared_ptr const & a) + { + return a.get() == this->get(); + } + + bool operator!=(const shared_ptr const & a) + { + return a.get() != this->get(); + } + private: X *ptr_; diff --git a/vn.ib/test/vnib.pyd b/vn.ib/test/vnib.pyd index 76c49916..a3e68e25 100644 Binary files a/vn.ib/test/vnib.pyd and b/vn.ib/test/vnib.pyd differ diff --git a/vn.ib/vnib/Visual Studio 2013/settings/Windows Azure Subscriptions.xml b/vn.ib/vnib/Visual Studio 2013/settings/Windows Azure Subscriptions.xml index c99985de..eb248928 100644 --- a/vn.ib/vnib/Visual Studio 2013/settings/Windows Azure Subscriptions.xml +++ b/vn.ib/vnib/Visual Studio 2013/settings/Windows Azure Subscriptions.xml @@ -1,5 +1,5 @@ - AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAhuIZgFnYcU6wvp5DI4FozAAAAAACAAAAAAAQZgAAAAEAACAAAAAP+ZejtWt08T4CHAObG1FMrnjuDrDgxp3Kgz3p0GFTiAAAAAAOgAAAAAIAACAAAADnqXDqufrv721M+KR/tLuCYzN6ynSphcMeiL+hw9/zfBAAAAA0xC0ncTgoWKgyHhV01sFjQAAAAHPVrjN2gp4P8U/lDH6S7DXnH0r85ILsW5BB0pf0XLyQTdX5KoNz8//d+jBnTKg15QzO9mS8Bc1TVIuzVWasdjI= + AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAhuIZgFnYcU6wvp5DI4FozAAAAAACAAAAAAAQZgAAAAEAACAAAACfxQZLqGgIlYaHRNvaMP1104wne69yDm3hT5jSkViJrwAAAAAOgAAAAAIAACAAAACEoYIxmu9X+z/pKyvKYVXdWTl6zqCrHe3ExYUwAcJwxxAAAABGePzLyKMDeM4WJVJQQCN+QAAAAEywH3Ecv+0PlTkK8x594oWHzQCnUgiXkPjdiAJHqE3sO/L19xiNs2JqW9giCiOVPNL2VS6Pue9CQLjRouK8HHE= \ No newline at end of file diff --git a/vn.ib/vnib/vnib/vnib.cpp b/vn.ib/vnib/vnib/vnib.cpp index 4018d2dd..42644a2c 100644 --- a/vn.ib/vnib/vnib/vnib.cpp +++ b/vn.ib/vnib/vnib/vnib.cpp @@ -4,6 +4,13 @@ #include "StdAfx.h" #include "vnib.h" +#include "Contract.h" +#include "OrderState.h" +#include "Execution.h" +#include "CommissionReport.h" +#include "ScannerSubscription.h" +#include "TagValue.h" + ///------------------------------------------------------------------------------------- ///C++的回调函数将数据保存到队列中 @@ -416,10 +423,52 @@ struct IbApiWrap : VnIbApi, wrapper < VnIbApi > }; + + +struct TagValue_Wrapper : TagValue +{ + TagValue_Wrapper(PyObject* self_) : self(self_) {} + PyObject* self; +}; + + +// 特殊封装相关 +namespace boost { + namespace python { + template struct pointee< ibapi::shared_ptr > + { + typedef T type; + }; + } +} + +template inline T * get_pointer(ibapi::shared_ptr const & p) +{ + return p.get(); +} + +/* +template +bool ibapi::shared_ptr::operator==(ibapi::shared_ptr const & a) +{ + return a.get() == this->get(); +} + +template +bool ibapi::shared_ptr::operator!=(ibapi::shared_ptr const & a) +{ + return a.get() != this->get(); +} +*/ + BOOST_PYTHON_MODULE(vnib) { - PyEval_InitThreads(); //导入时运行,保证先创建GIL + using namespace boost::python; + //导入时运行,保证先创建GIL + PyEval_InitThreads(); + + //API类封装 class_("IbApi") .def("eConnect", &IbApiWrap::eConnect) .def("eDisconnect", &IbApiWrap::eDisconnect) @@ -435,5 +484,111 @@ BOOST_PYTHON_MODULE(vnib) .def("accountSummary", pure_virtual(&IbApiWrap::accountSummary)) .def("accountSummaryEnd", pure_virtual(&IbApiWrap::accountSummaryEnd)) ; + + //结构体封装 + class_("OrderState") + .def_readwrite("status", &OrderState::status) + .def_readwrite("initMargin", &OrderState::initMargin) + .def_readwrite("maintMargin", &OrderState::maintMargin) + .def_readwrite("equityWithLoan", &OrderState::equityWithLoan) + .def_readwrite("commission", &OrderState::commission) + .def_readwrite("minCommission", &OrderState::minCommission) + .def_readwrite("maxCommission", &OrderState::maxCommission) + .def_readwrite("commissionCurrency", &OrderState::commissionCurrency) + .def_readwrite("warningText ", &OrderState::warningText) + ; + + class_("Execution") + .def_readwrite("execId", &Execution::execId) + .def_readwrite("time", &Execution::time) + .def_readwrite("acctNumber", &Execution::acctNumber) + .def_readwrite("exchange", &Execution::exchange) + .def_readwrite("side", &Execution::side) + .def_readwrite("shares", &Execution::shares) + .def_readwrite("price", &Execution::price) + .def_readwrite("permId", &Execution::permId) + .def_readwrite("clientId ", &Execution::clientId) + .def_readwrite("orderId ", &Execution::orderId) + .def_readwrite("liquidation ", &Execution::liquidation) + .def_readwrite("cumQty ", &Execution::cumQty) + .def_readwrite("avgPrice ", &Execution::avgPrice) + .def_readwrite("orderRef ", &Execution::orderRef) + .def_readwrite("evRule ", &Execution::evRule) + .def_readwrite("evMultiplier ", &Execution::evMultiplier) + .def_readwrite("modelCode ", &Execution::modelCode) + ; + + class_("UnderComp") + .def_readwrite("conId", &UnderComp::conId) + .def_readwrite("delta", &UnderComp::delta) + .def_readwrite("price", &UnderComp::price) + ; + + class_("CommissionReport") + .def_readwrite("execId", &CommissionReport::execId) + .def_readwrite("commission", &CommissionReport::commission) + .def_readwrite("currency", &CommissionReport::currency) + .def_readwrite("realizedPNL", &CommissionReport::realizedPNL) + .def_readwrite("yield", &CommissionReport::yield) + .def_readwrite("yieldRedemptionDate", &CommissionReport::yieldRedemptionDate) + ; + + class_("ExecutionFilter") + .def_readwrite("m_clientId", &ExecutionFilter::m_clientId) + .def_readwrite("m_acctCode", &ExecutionFilter::m_acctCode) + .def_readwrite("m_time", &ExecutionFilter::m_time) + .def_readwrite("m_symbol", &ExecutionFilter::m_symbol) + .def_readwrite("m_secType", &ExecutionFilter::m_secType) + .def_readwrite("m_exchange", &ExecutionFilter::m_exchange) + .def_readwrite("m_side", &ExecutionFilter::m_side) + ; + + class_("ScannerSubscription") + .def_readwrite("numberOfRows", &ScannerSubscription::numberOfRows) + .def_readwrite("instrument", &ScannerSubscription::instrument) + .def_readwrite("locationCode", &ScannerSubscription::locationCode) + .def_readwrite("scanCode", &ScannerSubscription::scanCode) + .def_readwrite("abovePrice", &ScannerSubscription::abovePrice) + .def_readwrite("belowPrice", &ScannerSubscription::belowPrice) + .def_readwrite("aboveVolume", &ScannerSubscription::aboveVolume) + .def_readwrite("marketCapAbove", &ScannerSubscription::marketCapAbove) + .def_readwrite("marketCapBelow", &ScannerSubscription::marketCapBelow) + .def_readwrite("moodyRatingAbove", &ScannerSubscription::moodyRatingAbove) + .def_readwrite("moodyRatingBelow", &ScannerSubscription::moodyRatingBelow) + .def_readwrite("spRatingAbove", &ScannerSubscription::spRatingAbove) + .def_readwrite("spRatingBelow", &ScannerSubscription::spRatingBelow) + .def_readwrite("maturityDateAbove", &ScannerSubscription::maturityDateAbove) + .def_readwrite("maturityDateBelow", &ScannerSubscription::maturityDateBelow) + .def_readwrite("couponRateAbove", &ScannerSubscription::couponRateAbove) + .def_readwrite("couponRateBelow", &ScannerSubscription::couponRateBelow) + .def_readwrite("excludeConvertible", &ScannerSubscription::excludeConvertible) + .def_readwrite("averageOptionVolumeAbove", &ScannerSubscription::averageOptionVolumeAbove) + .def_readwrite("scannerSettingPairs", &ScannerSubscription::scannerSettingPairs) + .def_readwrite("stockTypeFilter", &ScannerSubscription::stockTypeFilter) + ; + + class_("TagValue") + //class_("TagValue") + .def_readwrite("tag", &TagValue::tag) + .def_readwrite("value", &TagValue::value) + ; + + class_("TagValueList") + //class_("TagValueList") + .def(vector_indexing_suite()); //这个true非常重要 + + //register_ptr_to_python(); + //register_ptr_to_python(); + + class_("ComboLeg") + .def_readwrite("conId", &ComboLeg::conId) + .def_readwrite("ratio", &ComboLeg::ratio) + .def_readwrite("action", &ComboLeg::action) + .def_readwrite("exchange", &ComboLeg::exchange) + .def_readwrite("openClose", &ComboLeg::openClose) + .def_readwrite("shortSaleSlot", &ComboLeg::shortSaleSlot) + .def_readwrite("designatedLocation", &ComboLeg::designatedLocation) + .def_readwrite("exemptCode", &ComboLeg::exemptCode) + ; }; diff --git a/vn.ib/vnib/vnib/vnib.h b/vn.ib/vnib/vnib/vnib.h index 65230917..f316d9eb 100644 --- a/vn.ib/vnib/vnib/vnib.h +++ b/vn.ib/vnib/vnib/vnib.h @@ -9,10 +9,17 @@ #include //python封装 #include //python封装 #include //python封装 + +#include //Python封装 +#include //Python封装 + #include //python封装 #include //任务队列的线程功能 #include //任务队列的线程功能 +#include + + //API #include "EWrapper.h" #include "EClientSocket.h" @@ -50,6 +57,14 @@ public: }; +///------------------------------------------------------------------------------------- +///强制转化相关 +///------------------------------------------------------------------------------------- + +boost::python::list tagvaluelist_to_pylist(); + +TagValueListSPtr pylist_to_tagvaluelist(); + ///------------------------------------------------------------------------------------- ///声明类 ///------------------------------------------------------------------------------------- @@ -58,7 +73,6 @@ class VnIbApi; class IbWrapper; - ///------------------------------------------------------------------------------------- ///C++ SPI的回调函数方法实现 ///------------------------------------------------------------------------------------- diff --git a/vn.trader/uiMainWindow.py b/vn.trader/uiMainWindow.py index d48dd06b..a2f9914b 100644 --- a/vn.trader/uiMainWindow.py +++ b/vn.trader/uiMainWindow.py @@ -23,7 +23,7 @@ class MainWindow(QtGui.QMainWindow): self.widgetDict = {} # 鐢ㄦ潵淇濆瓨瀛愮獥鍙g殑瀛楀吀 self.initUi() - self.loadWindowSettings() + self.loadWindowSettings('custom') #---------------------------------------------------------------------- def initUi(self): @@ -55,6 +55,9 @@ class MainWindow(QtGui.QMainWindow): # 杩炴帴缁勪欢涔嬮棿鐨勪俊鍙 widgetPositionM.itemDoubleClicked.connect(widgetTradingW.closePosition) + # 淇濆瓨榛樿璁剧疆 + self.saveWindowSettings('default') + #---------------------------------------------------------------------- def initMenu(self): """鍒濆鍖栬彍鍗""" @@ -65,9 +68,6 @@ class MainWindow(QtGui.QMainWindow): connectLtsAction = QtGui.QAction(u'杩炴帴LTS', self) connectLtsAction.triggered.connect(self.connectLts) - connectXtpAction = QtGui.QAction(u'杩炴帴XTP', self) - connectXtpAction.triggered.connect(self.connectXtp) - connectKsotpAction = QtGui.QAction(u'杩炴帴閲戜粫杈炬湡鏉', self) connectKsotpAction.triggered.connect(self.connectKsotp) @@ -117,7 +117,10 @@ class MainWindow(QtGui.QMainWindow): ctaAction.triggered.connect(self.openCta) rmAction = QtGui.QAction(u'椋庨櫓绠$悊', self) - rmAction.triggered.connect(self.openRm) + rmAction.triggered.connect(self.openRm) + + restoreAction = QtGui.QAction(u'杩樺師绐楀彛', self) + restoreAction.triggered.connect(self.restoreWindow) # 鍒涘缓鑿滃崟 menubar = self.menuBar() @@ -128,8 +131,6 @@ class MainWindow(QtGui.QMainWindow): sysMenu.addAction(connectCtpAction) if 'LTS' in self.mainEngine.gatewayDict: sysMenu.addAction(connectLtsAction) - if 'XTP' in self.mainEngine.gatewayDict: - sysMenu.addAction(connectXtpAction) if 'FEMAS' in self.mainEngine.gatewayDict: sysMenu.addAction(connectFemasAction) if 'XSPEED' in self.mainEngine.gatewayDict: @@ -166,6 +167,7 @@ class MainWindow(QtGui.QMainWindow): # 甯姪 helpMenu = menubar.addMenu(u'甯姪') + helpMenu.addAction(restoreAction) helpMenu.addAction(aboutAction) helpMenu.addAction(testAction) @@ -209,11 +211,6 @@ class MainWindow(QtGui.QMainWindow): """杩炴帴LTS鎺ュ彛""" self.mainEngine.connect('LTS') - #---------------------------------------------------------------------- - def connectXtp(self): - """杩炴帴XTP鎺ュ彛""" - self.mainEngine.connect('XTP') - #---------------------------------------------------------------------- def connectKsotp(self): """杩炴帴閲戜粫杈炬湡鏉冩帴鍙""" @@ -320,7 +317,7 @@ class MainWindow(QtGui.QMainWindow): if reply == QtGui.QMessageBox.Yes: for widget in self.widgetDict.values(): widget.close() - self.saveWindowSettings() + self.saveWindowSettings('custom') self.mainEngine.exit() event.accept() @@ -339,16 +336,16 @@ class MainWindow(QtGui.QMainWindow): return widget, dock #---------------------------------------------------------------------- - def saveWindowSettings(self): + def saveWindowSettings(self, settingName): """淇濆瓨绐楀彛璁剧疆""" - settings = QtCore.QSettings('vn.py', 'vn.trader') + settings = QtCore.QSettings('vn.trader', settingName) settings.setValue('state', self.saveState()) settings.setValue('geometry', self.saveGeometry()) #---------------------------------------------------------------------- - def loadWindowSettings(self): + def loadWindowSettings(self, settingName): """杞藉叆绐楀彛璁剧疆""" - settings = QtCore.QSettings('vn.py', 'vn.trader') + settings = QtCore.QSettings('vn.trader', settingName) # 杩欓噷鐢变簬PyQt4鐨勭増鏈笉鍚岋紝settings.value('state')璋冪敤杩斿洖鐨勭粨鏋滃彲鑳芥槸锛 # 1. None锛堝垵娆¤皟鐢紝娉ㄥ唽琛ㄩ噷鏃犵浉搴旇褰曪紝鍥犳涓虹┖锛 # 2. QByteArray锛堟瘮杈冩柊鐨凱yQt4锛 @@ -360,6 +357,12 @@ class MainWindow(QtGui.QMainWindow): self.restoreGeometry(settings.value('geometry').toByteArray()) except AttributeError: pass + + #---------------------------------------------------------------------- + def restoreWindow(self): + """杩樺師榛樿绐楀彛璁剧疆锛堣繕鍘熷仠闈犵粍浠朵綅缃級""" + self.loadWindowSettings('default') + self.showMaximized() ########################################################################