mirror of
https://github.com/wassname/catalyst.git
synced 2026-07-09 18:01:50 +08:00
cleanup
This commit is contained in:
+14
@@ -0,0 +1,14 @@
|
||||
.bundle
|
||||
db/*.sqlite3
|
||||
log/*.log
|
||||
*.log
|
||||
tmp/**/*
|
||||
tmp/*
|
||||
doc/api
|
||||
doc/app
|
||||
*.swp
|
||||
*~
|
||||
.DS_Store
|
||||
*.pyc
|
||||
.tddium
|
||||
.tddium-deploy-key
|
||||
@@ -52,10 +52,15 @@ A backtesting session is comprised of:
|
||||
|
||||
## Pre-requisites
|
||||
You need to have the tornado and pymongo eggs installed:
|
||||
easy_install tornado pymongo
|
||||
|
||||
easy_install tornado pymongo pyzmq
|
||||
|
||||
You need to have mongodb installed and running. Find your system at http://www.mongodb.org/downloads and set it up.
|
||||
|
||||
You need to have zeromq installed - http://www.zeromq.org/intro:get-the-software. If you are on mac, get homebrew https://github.com/mxcl/homebrew then:
|
||||
|
||||
brew install zeromq
|
||||
|
||||
### Database and Collections expected in MongoDB ###
|
||||
QBT requires a running mongodb instance with a few collections:
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
"""
|
||||
Small classes to assist with db access, timezone calculations, and so on.
|
||||
"""
|
||||
|
||||
class DocWrap():
|
||||
"""
|
||||
Provides attribute access style on top of dictionary results from pymongo.
|
||||
Allows you to access result['field'] as result.field.
|
||||
Aliases result['_id'] to result.id.
|
||||
|
||||
"""
|
||||
def __init__(self, store=None):
|
||||
if(store == None):
|
||||
self.store = {}
|
||||
else:
|
||||
self.store = store.copy()
|
||||
if(self.store.has_key('_id')):
|
||||
self.store['id'] = self.store['_id']
|
||||
del(self.store['_id'])
|
||||
|
||||
def __setitem__(self,key,value):
|
||||
if(key == '_id'):
|
||||
self.store['id'] = value
|
||||
else:
|
||||
self.store[key] = value
|
||||
|
||||
def __getitem__(self, key):
|
||||
if self.store.has_key(key):
|
||||
return self.store[key]
|
||||
|
||||
def __getattr__(self,attrname):
|
||||
if self.store.has_key(attrname):
|
||||
return self.store[attrname]
|
||||
else:
|
||||
raise AttributeError("No attribute named {name}".format(name=attrname))
|
||||
@@ -0,0 +1,36 @@
|
||||
"""
|
||||
qbt runs backtests using multiple processes and zeromq messaging.
|
||||
|
||||
Backtest is the primary process. It maintains both server and client sockets:
|
||||
zmq sockets for internal processing:
|
||||
====================================
|
||||
- data sink, ZMQ.PULL. Port = port_start + 1
|
||||
- backtest will connect to socket, and then spawn one process per datasource, passing the data sink url as a startup arg. Each
|
||||
datasource process will bind to the socket, and start processing
|
||||
- backtest is responsible for merging the data events from all sources into a serialized stream and relaying it to the
|
||||
aggregators, merging agg results, and transmitting consolidated stream to event feed.
|
||||
- agg source, ZMQ.PUSH. Port = port_start + 2
|
||||
- agg sink, ZMQ.PULL. Port = port_start + 3
|
||||
- control source, ZMQ.PUB. Port = port_start + 4
|
||||
- all child processes must subscribe to this socket. Control commands:
|
||||
- START -- begin processing
|
||||
- KILL -- exit immediately
|
||||
|
||||
zmq sockets for backtest clients:
|
||||
=================================
|
||||
- orders sink, ZMQ.RESP. Port = port_start + 5
|
||||
- backtest will connect (can you bind?) to this socket and await orders from the client. Order data will be processed against the streaming datafeed.
|
||||
- event feed, ZMQ.RESP. Port = port_start + 6
|
||||
- backtest will bind to this socket and respond to requests from client for more data. Response data will be the queue of events that
|
||||
transpired since the last request.
|
||||
|
||||
|
||||
"""
|
||||
import multiprocessing
|
||||
import zmq
|
||||
|
||||
class Backtest(object):
|
||||
|
||||
def __init__(self, port_start=10000):
|
||||
|
||||
40B8729046
|
||||
+15
-3
@@ -11,8 +11,8 @@ import uuid
|
||||
import os
|
||||
import logging
|
||||
import datetime
|
||||
import multiprocessing
|
||||
|
||||
logging.getLogger().setLevel(logging.DEBUG)
|
||||
logger = logging.getLogger()
|
||||
|
||||
define("port", default=8888, help="run the qbt on the given port", type=int)
|
||||
@@ -47,6 +47,7 @@ class Application(tornado.web.Application):
|
||||
handlers = [
|
||||
(r"/", MainHandler),
|
||||
(r"/login", LoginHandler),
|
||||
(r"/backtest", BacktestHandler)
|
||||
]
|
||||
settings = dict(
|
||||
template_path=os.path.join(os.path.dirname(__file__), "templates"),
|
||||
@@ -81,8 +82,8 @@ class BaseHandler(tornado.web.RequestHandler):
|
||||
class MainHandler(BaseHandler):
|
||||
@tornado.web.authenticated
|
||||
def get(self):
|
||||
self.write("Hello, world")
|
||||
|
||||
self.write("Hello, world. Try launching a <a href='/backtest'>backtest</a>.")
|
||||
|
||||
class LoginHandler(BaseHandler):
|
||||
def get(self):
|
||||
self.write('<html><body><form action="/login" method="post">'
|
||||
@@ -113,6 +114,17 @@ class LoginHandler(BaseHandler):
|
||||
logger.debug("setting user_id cookie to {id}".format(id=user_record['_id']))
|
||||
self.set_secure_cookie(u"user_id", unicode(user_record['_id']))
|
||||
|
||||
class BacktestHandler(BaseHandler):
|
||||
@tornado.web.authenticated
|
||||
def get(self):
|
||||
self.write('<html><body><form action="/backtest" method="post">'
|
||||
'<input type="submit" value="Launch">'
|
||||
'</form></body></html>')
|
||||
@tornado.web.authenticated
|
||||
def post(self):
|
||||
|
||||
|
||||
|
||||
def main():
|
||||
tornado.options.parse_command_line()
|
||||
http_server = tornado.httpserver.HTTPServer(Application())
|
||||
|
||||
Reference in New Issue
Block a user