[profitpy commit] r325 - in trunk/profit: lib models session strategy workbench

0 views
Skip to first unread message

codesite...@google.com

unread,
Aug 4, 2008, 4:40:48 AM8/4/08
to profitp...@googlegroups.com
Author: troy.melhase
Date: Mon Aug 4 01:40:09 2008
New Revision: 325

Modified:
trunk/profit/lib/__init__.py
trunk/profit/models/ticker.py
trunk/profit/models/tickers.py
trunk/profit/session/__init__.py
trunk/profit/strategy/builder.py
trunk/profit/workbench/connectiondisplay.py
trunk/profit/workbench/main.py
trunk/profit/workbench/strategydisplay.py

Log:
Work in progress.

Modified: trunk/profit/lib/__init__.py
==============================================================================
--- trunk/profit/lib/__init__.py (original)
+++ trunk/profit/lib/__init__.py Mon Aug 4 01:40:09 2008
@@ -116,6 +116,7 @@

class contract:
added = SIGNAL('contractAdded(int, PyQt_PyObject)')
+ created = SIGNAL('createdContract')

class histdata:
start = SIGNAL('historicalDataStart')
@@ -132,6 +133,9 @@
loadFailed = SIGNAL('strategyLoadFaield(PyQt_PyObject)')
fileUpdated = SIGNAL('strategyFileUpdated(PyQt_PyObject)')
requestActivate = SIGNAL('strategyActivated(PyQt_PyObject, bool)')
+
+ class ticker:
+ created = SIGNAL('tickerCreated_')

class tws:
connected = SIGNAL('connectedTWS')

Modified: trunk/profit/models/ticker.py
==============================================================================
--- trunk/profit/models/ticker.py (original)
+++ trunk/profit/models/ticker.py Mon Aug 4 01:40:09 2008
@@ -8,6 +8,8 @@
from profit.lib import valueAlign
from profit.models import BasicItem, BasicItemModel

+## This model isn't used yet. It should morph into a replacement
+## for the plot controls model in profit.lib.widgets.plot.

class TickerModel(BasicItemModel):
""" Model for a single ticker.
@@ -17,5 +19,64 @@
BasicItemModel.__init__(self, TickerRootItem(), parent)
self.symbolIcon = lambda x:None
self.session = session
+ self.data = {}
if session is not None:
session.registerMeta(self)
+
+ def __contains__(self, item):
+ return item in self.data
+
+ def __getitem__(self, name):
+ return self.data[name]
+
+ def __setitem__(self, name, value):
+ self.data[name] = value
+
+ def keys(self):
+ return self.data.keys()
+
+ def items(self):
+ return self.data.items()
+
+ def data(self, index, role=Qt.DecorationRole):
+ """ Framework hook to retrieve information from this model.
+
+ @param index QModelIndex instance
+ @param role=Qt.DecorationRole
+ @return QVariant of some kind
+ """
+ if not index.isValid():
+ return QVariant()
+ item = index.internalPointer()
+ column = index.column()
+ data = QVariant()
+ return data
+
+ def on_session_TickPrice_TickSize(self, message):
+ tickerId = message.tickerId
+ try:
+ tickerdata = self[tickerId]
+ except (KeyError, ):
+ tickerdata = self[tickerId] = \
+ self.session.strategy.makeTicker(tickerId)
+ self.emit(Signals.createdTicker, tickerId, tickerdata)
+ try:
+ value = message.price
+ except (AttributeError, ):
+ value = message.size
+ field = message.field
+ try:
+ seq = tickerdata.series[field]
+ except (KeyError, ):
+ seq = tickerdata.series[field] = \
+ self.session.strategy.makeTickerSeries(tickerId, field)
+ self.emit(Signals.createdSeries, tickerId, field)
+ seq.append(value)
+
+
+class TickerItem(BasicItem):
+ pass
+
+
+class TickerRootItem(TickerItem):
+ pass

Modified: trunk/profit/models/tickers.py
==============================================================================
--- trunk/profit/models/tickers.py (original)
+++ trunk/profit/models/tickers.py Mon Aug 4 01:40:09 2008
@@ -7,6 +7,7 @@
from re import split as rxsplit
from PyQt4.QtCore import Qt, QModelIndex, QObject, QVariant, QString
from ib.ext.TickType import TickType
+from ib.opt.message import TickPrice
from profit.lib import valueAlign
from profit.models import BasicItem, BasicItemModel

@@ -73,6 +74,20 @@
"""
return self.tickerIdItemMap.get(tickerId, None)

+ def on_session_createdContract(self, tickerId, contract):
+ """ Called when the session creates a contract object.
+
+ @param tickerId id associated with data request
+ @param contract ib.opt.Contract
+ """
+ item = self.findTicker(tickerId)
+ if not item:
+ root = self.invisibleRootItem
+ item = TickersItem.fromContract(tickerId, contract, root)
+ self.tickerIdItemMap[tickerId] = item
+ root.append(item)
+ self.reset()
+
def on_session_TickPrice_TickSize(self, message):
""" Called with new ticker size or price.

@@ -169,6 +184,21 @@
BasicItem.__init__(self, data, parent)
self.message = message
self.previousValues = {}
+
+ @classmethod
+ def fromContract(cls, tickerId, contract, parent):
+ """ New instance from a contract (probably created elsewhere)
+
+ @param cls class object
+ @param tickerId id associated with data request
+ @param contract ib.opt.Contract
+ @param parent parent of this item
+ @return new instance of cls
+ """
+ message = TickPrice(tickerId=tickerId, field=0, price=0)
+ values = [tickerId, contract.m_symbol] + \
+ ['' for spec in cls.columnLookups][2:]
+ return cls(values, parent, message)

@classmethod
def fromMessage(cls, message, parent):

Modified: trunk/profit/session/__init__.py
==============================================================================
--- trunk/profit/session/__init__.py (original)
+++ trunk/profit/session/__init__.py Mon Aug 4 01:40:09 2008
@@ -60,6 +60,8 @@
self.savedLength = 0
self.maps = DataMaps(self)
self.models = DataModels(self)
+ self.connect(self.strategy, Signals.contract.created,
+ self, Signals.contract.created)

def __str__(self):
""" x.__str__() <==> str(x)
@@ -227,6 +229,7 @@
connection = self.connection
if connection and connection.isConnected():
for tickerId, contract in self.strategy.makeContracts():
+ self.emit(Signals.contract.created, tickerId, contract)
connection.reqMktData(tickerId, contract, '', False)
connection.reqMktDepth(tickerId, contract, 1)

@@ -422,11 +425,12 @@
yield msgTimeIndex


- def testContract(self, orderId, price=30.0, symbol='MSFT'):
+ def testContract(self, orderId, price=30.0, symbol='MSFT',
+ orderType='MKT'):
strategy = self.strategy
contract = strategy.makeContract(symbol)
order = strategy.makeOrder(action='SELL',
- orderType='MKT',
+ orderType=orderType,
totalQuantity='100',
openClose='O',
)

Modified: trunk/profit/strategy/builder.py
==============================================================================
--- trunk/profit/strategy/builder.py (original)
+++ trunk/profit/strategy/builder.py Mon Aug 4 01:40:09 2008
@@ -11,8 +11,8 @@

from PyQt4.QtCore import QObject

-from profit.lib import Signals, instance
-from profit.series import Series, MACDHistogram
+from profit.lib import Signals, instance, logging
+from profit.series import Series, MACDHistogram, EMA

from ib.ext.Contract import Contract
from ib.ext.Order import Order
@@ -91,6 +91,7 @@

def makeTickerSeries(self, tickerId, field):
s = Series()
+ s.addIndex('ema-40', EMA, s, 40)
return s

def symbols(self):
@@ -112,7 +113,12 @@
try:
call(item)
except (TypeError, ):
- pass
+ logging.debug('Could not load strategy item: %s', item)
+ for tickerId, contract in self.makeContracts():
+ self.emit(Signals.contract.created, tickerId, contract)
+
+ def load_RunnerItem(self, item):
+ pass

def load_TickerItem(self, item):
self.tickerItems.append(item)
@@ -123,7 +129,11 @@
if activate:
if filename:
self.load(filename)
+ ## cheater!
self.parent().requestTickers()
+ else:
+ ## must deactivate somehow
+ pass

def externalFileUpdated(self, filename):
print '## strategy external file updated'

Modified: trunk/profit/workbench/connectiondisplay.py
==============================================================================
--- trunk/profit/workbench/connectiondisplay.py (original)
+++ trunk/profit/workbench/connectiondisplay.py Mon Aug 4 01:40:09 2008
@@ -121,8 +121,14 @@
session.connection.TwsConnectionTime())
else:
logging.warn('Exception during connect')
- QMessageBox.critical(
- self, 'Connection Error', 'Unable to connect.')
+ port = self.portNumberSpin.value()
+ if port == session.specialPortNo:
+ port = 7496
+ host = self.hostNameEdit.text()
+ text = 'Unable to connect.\n\nEnsure TWS is running'
+ text += ' on %s and is configured to accept socket ' % host
+ text += 'connections on port %s.' % port
+ QMessageBox.critical(self, 'Connection Error', text)
self.setConnectControlsEnabled(True, False)

@pyqtSignature('')

Modified: trunk/profit/workbench/main.py
==============================================================================
--- trunk/profit/workbench/main.py (original)
+++ trunk/profit/workbench/main.py Mon Aug 4 01:40:09 2008
@@ -87,7 +87,7 @@
text += ' and is connected and receiving messages.'
else:
text += '.'
- text += '\nDo you want to save your changes?'
+ text += '\n\nDo you want to save your changes?'
msg = QMessageBox.question(
self, applicationName(), text, buttons, QMessageBox.Save)
if msg == QMessageBox.Discard:

Modified: trunk/profit/workbench/strategydisplay.py
==============================================================================
--- trunk/profit/workbench/strategydisplay.py (original)
+++ trunk/profit/workbench/strategydisplay.py Mon Aug 4 01:40:09 2008
@@ -17,6 +17,8 @@
from profit.lib.gui import StandardItem
from profit.workbench.widgets.ui_strategydisplay import Ui_StrategyDisplay

+## This model can be (almost) easily replaced with an abstract item
+## model. Use profit.models.BasicItemModel.

class StrategyDisplayModel(QStandardItemModel):
""" Model for strategy display table.

Reply all
Reply to author
Forward
0 new messages