opt_serve.py.20160509 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699
  1. # -*- coding: utf-8 -*-
  2. import sys, traceback
  3. import logging
  4. import os
  5. import ast
  6. import urllib, urllib2, cookielib
  7. import datetime, time
  8. import re
  9. import json
  10. import cherrypy
  11. import hashlib
  12. import uuid
  13. import redis
  14. import json
  15. import optcal
  16. import ConfigParser
  17. import portfolio
  18. from comms.alert_bot import AlertHelper
  19. from ws4py.server.cherrypyserver import WebSocketPlugin, WebSocketTool
  20. from ws4py.websocket import WebSocket
  21. from ws4py.websocket import EchoWebSocket
  22. from sets import Set
  23. import thread
  24. class QServer(object):
  25. config = None
  26. r_conn = None
  27. def __init__(self, r_conn, config):
  28. super(QServer, self).__init__()
  29. QServer.r_conn = r_conn
  30. QServer.config = config
  31. #print QServer.r_conn
  32. @cherrypy.expose
  33. def index(self):
  34. #s_line = 'welcome!'
  35. #r_host = cherrypy.request.app.config['redis']['redis.server']
  36. #r_port = cherrypy.request.app.config['redis']['redis.port']
  37. #r_db = cherrypy.request.app.config['redis']['redis.db']
  38. #r_sleep = cherrypy.request.app.config['redis']['redis.sleep']
  39. #rs = redis.Redis(r_host, r_port, r_db)
  40. rs = QServer.r_conn
  41. s_line = rs.info()
  42. html =''
  43. for k, v in cherrypy.request.app.config.iteritems():
  44. html = html + '<dt>%s</dt><dd>%s</dd>' % (k, v)
  45. impl_link = "<a href=./opt_implv><img src='public/chart.png' width='42' height=42'/>options implied vol curves</a>"
  46. pos_link = "<a href=./ws_position_chart><img src='public/moneyup.png' width='42' height='42'/>Positions</a>"
  47. stackpos_link = "<a href=./ws_position_chart_ex><img src='public/scale.png' width='42' height='42' />Positions (Stacked View)</a>"
  48. bubble_link = "<a href=./port_bubble_chart><img src='public/Market-Risk-Icon.png' width='42' height='42' />Risk Distributions</a>"
  49. html = ''
  50. s_line = ''
  51. return """<html><body><li>%s</li><li>%s</li><li>%s</li><li>%s</li><br><dl>%s</dl></br>%s</body></html>""" % (bubble_link, impl_link, pos_link, stackpos_link, html, s_line)
  52. @cherrypy.expose
  53. def opt_chains(self):
  54. r_host = cherrypy.request.app.config['redis']['redis.server']
  55. r_port = cherrypy.request.app.config['redis']['redis.port']
  56. r_db = cherrypy.request.app.config['redis']['redis.db']
  57. r_sleep = cherrypy.request.app.config['redis']['redis.sleep']
  58. opt_chains = cherrypy.request.app.config['redis']['redis.datastore.key.option_chains']
  59. rs = redis.Redis(r_host, r_port, r_db)
  60. opt_chain_tmpl = '%s%s/opt-chains-tmpl.html' % (cherrypy.request.app.config['/']['tools.staticdir.root'], cherrypy.request.app.config['/static']['tools.staticdir.tmpl'])
  61. f = open(opt_chain_tmpl)
  62. html_tmpl = f.read()
  63. s_dict = rs.get(opt_chains)
  64. matrix = json.loads(s_dict)
  65. strike = matrix.keys()[0]
  66. print matrix
  67. num_months = len(matrix[strike])
  68. s = '["strike",'
  69. # for i in range(num_months):
  70. # s = s + "'P-%s', 'C-%s', " % (matrix[strike].keys()[i], matrix[strike].keys()[i])
  71. s = s + '],'
  72. for month, strikes in sorted(matrix.iteritems()):
  73. l = ''
  74. for strike, cp in sorted(strikes.iteritems()):
  75. l = l + '[%s,%s,%s,%s,%s],' % (strike, cp['P']['0'], cp['P']['1'], cp['P']['2'], cp['P']['3'])
  76. s = s + l + '],\n'
  77. print s
  78. html_tmpl = html_tmpl.replace('{{{data}}}', s)
  79. return html_tmpl
  80. @cherrypy.expose
  81. def opt_implv(self):
  82. #r_host = cherrypy.request.app.config['redis']['redis.server']
  83. #r_port = cherrypy.request.app.config['redis']['redis.port']
  84. #r_db = cherrypy.request.app.config['redis']['redis.db']
  85. #r_sleep = cherrypy.request.app.config['redis']['redis.sleep']
  86. opt_implv = cherrypy.request.app.config['redis']['redis.datastore.key.option_implv']
  87. #rs = redis.Redis(r_host, r_port, r_db)
  88. rs = QServer.r_conn
  89. opt_implv_tmpl = '%s%s/opt-chains-tmpl.html' % (cherrypy.request.app.config['/']['tools.staticdir.root'], cherrypy.request.app.config['/static']['tools.staticdir.tmpl'])
  90. f = open(opt_implv_tmpl)
  91. html_tmpl = f.read()
  92. s_dict = rs.get(opt_implv)
  93. # sample value
  94. # {u'25400': {u'20150828': {u'P': [u'null', 1400.0], u'C': [0.21410911336791702, 29.0]}, u'20150929': {u'P': [u'null', u'null'], u'C': [0.1934532406732742, 170.0]}}, ...
  95. matrix = json.loads(s_dict)
  96. strike = matrix.keys()[0]
  97. print matrix
  98. num_months = len(matrix[strike])
  99. s = '["strike",'
  100. sorted_months = sorted(matrix[strike].keys())
  101. for i in range(num_months):
  102. s = s + "'P-%s', 'C-%s', " % (sorted_months[i], sorted_months[i])
  103. s = s + '],'
  104. for strike, items in sorted(matrix.iteritems()):
  105. s = s + '[%s,' % str(strike)
  106. l = ''
  107. for month, cp in sorted(items.iteritems()):
  108. print month, cp
  109. l = l + ''.join('%s,%s,' % (cp['P'][0], cp['C'][0]))
  110. s = s + l + '],\n'
  111. html_tmpl = html_tmpl.replace('{{{data}}}', s)
  112. s = '["strike",'
  113. for i in range(num_months):
  114. s = s + "'P-%s', 'C-%s', " % (sorted_months[i], sorted_months[i])
  115. s = s + '],'
  116. for strike, items in sorted(matrix.iteritems()):
  117. s = s + '[%s,' % str(strike)
  118. l = ''
  119. for month, cp in sorted(items.iteritems()):
  120. l = l + ''.join('%s,%s,' % (cp['P'][1], cp['C'][1]))
  121. s = s + l + '],\n'
  122. print 'sorted months' + sorted_months[0]
  123. html_tmpl = html_tmpl.replace('{{{dataPremium}}}', s)
  124. html_tmpl = html_tmpl.replace('{{{thisContractMonth}}}', sorted_months[0])
  125. return html_tmpl
  126. @cherrypy.expose
  127. def opt_implv_ex(self):
  128. #r_host = cherrypy.request.app.config['redis']['redis.server']
  129. #r_port = cherrypy.request.app.config['redis']['redis.port']
  130. #r_db = cherrypy.request.app.config['redis']['redis.db']
  131. #r_sleep = cherrypy.request.app.config['redis']['redis.sleep']
  132. opt_implv = cherrypy.request.app.config['redis']['redis.datastore.key.option_implv']
  133. #rs = redis.Redis(r_host, r_port, r_db)
  134. rs = QServer.r_conn
  135. opt_implv_tmpl = '%s%s/opt-chains-ex-tmpl.html' % (cherrypy.request.app.config['/']['tools.staticdir.root'], cherrypy.request.app.config['/static']['tools.staticdir.tmpl'])
  136. f = open(opt_implv_tmpl)
  137. html_tmpl = f.read()
  138. s_dict = rs.get(opt_implv)
  139. # sample value
  140. # {u'25400': {u'20150828': {u'P': [u'null', 1400.0], u'C': [0.21410911336791702, 29.0]}, u'20150929': {u'P': [u'null', u'null'], u'C': [0.1934532406732742, 170.0]}}, ...
  141. matrix = json.loads(s_dict)
  142. strike = matrix.keys()[0]
  143. print matrix
  144. num_months = len(matrix[strike])
  145. s = '["strike",'
  146. sorted_months = sorted(matrix[strike].keys())
  147. for i in range(num_months):
  148. s = s + "'P-%s', 'C-%s', " % (sorted_months[i], sorted_months[i])
  149. s = s + '],'
  150. for strike, items in sorted(matrix.iteritems()):
  151. s = s + '[%s,' % str(strike)
  152. l = ''
  153. for month, cp in sorted(items.iteritems()):
  154. print month, cp
  155. l = l + ''.join('%s,%s,' % (cp['P'][0], cp['C'][0]))
  156. s = s + l + '],\n'
  157. html_tmpl = html_tmpl.replace('{{{data}}}', s)
  158. s = '[{label:"strikes",type:"number"},'
  159. for i in range(num_months):
  160. s = s + "{label: 'P-%s', type:'number'},\
  161. {label: 'Pb-%s', id:'i0', type:'number', role:'interval'},\
  162. {label: 'Pa-%s', id:'i0', type:'number', role:'interval'},\
  163. {label: 'C-%s', type:'number', },\
  164. {label: 'Cb-%s', id:'i0', type:'number', role:'interval'},\
  165. {label: 'Ca-%s', id:'i0',type:'number', role:'interval'},"\
  166. % (sorted_months[i], sorted_months[i],sorted_months[i], sorted_months[i],sorted_months[i], sorted_months[i])
  167. s = s + '],'
  168. for strike, items in sorted(matrix.iteritems()):
  169. s = s + '[%s,' % str(strike)
  170. l = ''
  171. for month, cp in sorted(items.iteritems()):
  172. l = l + ''.join('%s,%s,%s,%s,%s,%s,' % (cp['P'][1], cp['P'][2],cp['P'][3],cp['C'][1],cp['C'][2],cp['C'][3]))
  173. s = s + l + '],\n'
  174. html_tmpl = html_tmpl.replace('{{{dataPremium}}}', s)
  175. html_tmpl = html_tmpl.replace('{{{thisContractMonth}}}', sorted_months[0])
  176. return html_tmpl
  177. @cherrypy.expose
  178. def ws_cal_implvol(self, s, x, cp, ed, xd, r, d, v, p, out='iv'):
  179. try:
  180. #spot, strike, callput, evaldate, exdate, rate, div, vol, premium
  181. rs = optcal.cal_implvol(float(s), float(x), cp, ed, xd, float(r), float(d), float(v), float(p))
  182. return str(rs['imvol'])
  183. except:
  184. return
  185. @cherrypy.expose
  186. def ws_cal_option(self, s, x, cp, ed, xd, r, d, v, out='npv'):
  187. #spot, strike, callput, evaldate, exdate, rate, div, vol
  188. keys = ['npv', 'delta', 'gamma', 'theta', 'vega'];
  189. try:
  190. rs = optcal.cal_option(float(s), float(x), cp, ed, xd, float(r), float(d), float(v))
  191. if out == 'csv':
  192. logging.debug('ws_cal_option: ' + ','.join(str(rs[s]) for s in keys))
  193. return ','.join(str(rs[s]) for s in keys)
  194. elif out == 'json':
  195. return json.dumps(rs)
  196. else:
  197. return str(rs[out])
  198. except:
  199. #exc_type, exc_value, exc_traceback = sys.exc_info()
  200. return traceback.format_exc()
  201. @cherrypy.expose
  202. def ws_get_hist_implv(self, dataAt):
  203. # given a date string YYMMDDHHMM, this routine returns an array of
  204. # implied vols arranged in a format like the below
  205. # [["strike",'P-20150828', 'C-20150828', 'P-20150929', 'C-20150929', ],
  206. # [21800,0.29153118077,null,0.241032122988,null,],
  207. # [22000,0.284002011642,null,0.238145680311,null,],
  208. # [22200,0.270501965746,null,0.222647164832,null,]]
  209. pass
  210. @cherrypy.expose
  211. def ws_market_data(self, r_ckey, fid):
  212. if str(fid).upper() == 'ALL':
  213. return QServer.r_conn.get(r_ckey)
  214. val = QServer.r_conn.get(r_ckey)
  215. if val is None:
  216. return 'invalid request. Check your input again!'
  217. dict = json.loads(QServer.r_conn.get(r_ckey))
  218. return str(dict[fid])
  219. @cherrypy.expose
  220. def ws_position_chart(self):
  221. p = portfolio.PortfolioManager(config)
  222. p.retrieve_position()
  223. opt_pos_chart_tmpl = '%s%s/opt-pos-chart-tmpl.html' % (cherrypy.request.app.config['/']['tools.staticdir.root'], cherrypy.request.app.config['/static']['tools.staticdir.tmpl'])
  224. f = open(opt_pos_chart_tmpl)
  225. html_tmpl = f.read()
  226. html_tmpl = html_tmpl.replace('{{{dataPCpos}}}', p.get_grouped_options_str_array())
  227. html_tmpl = html_tmpl.replace('{{{dataTablePos}}}', p.get_tbl_pos_csv())
  228. html_tmpl = html_tmpl.replace('{{{option_months}}}', ''.join(('%s, ' % m) for m in p.get_traded_months()))
  229. v = p.group_pos_by_right()
  230. html_tmpl = html_tmpl.replace('{{{PRvsCR}}}}', '%0.2f : %0.2f' % (v[0][1], v[1][1]))
  231. #print p.get_portfolio_summary()
  232. #html_tmpl = html_tmpl.replace('{{{pos_summary}}}', ''.join('<li>%s: %s</li>' % (x[0],x[1]) for x in p.get_portfolio_summary() ))
  233. #print '\n'.join('%s:\t\t%s' % (k,v) for k,v in sorted(json.loads(DataMap.rs.get(port_key)).iteritems()))
  234. return html_tmpl
  235. #
  236. # ws_position_chart_ex
  237. #
  238. #
  239. # this is an extended version of ws_position_chart
  240. # shows options by month, strikes, right instead of just strikes and right
  241. # 2016-03-23
  242. def generate_garray(self, plist):
  243. # generate a key map with month-right-strike
  244. # example: ('20160330-C-20000', 0.2),...
  245. klist = map(lambda x: ('%s-%s-%s' % (x[2], x[3], x[4]), float(x[5])/50.0*float(x[6])), plist)
  246. # for e in sorted(klist):
  247. # print e
  248. # get the unique keys in klist
  249. unique_keys= Set(map(lambda x:x[0], klist))
  250. strikes =[e for e in Set(map(lambda x:x[4], plist))]
  251. # sort the months in ascending order
  252. months = sorted([e for e in Set(map(lambda x:x[2], plist))])
  253. print klist
  254. print strikes
  255. # print months
  256. # print len(klist), len(s)
  257. # group and sum position by month, strike, right
  258. grouped_pos = []
  259. for elem in unique_keys:
  260. grp1 = filter(lambda x: x[0] == elem, klist)
  261. print grp1
  262. # sum items with same key
  263. # example: [('20160330-P-19600', -1.0), ('20160330-P-19600', 0.2)]
  264. grouped_pos.append( grp1[0] if len(grp1) == 1 else reduce(lambda x,y: (x[0], x[1]+y[1]), grp1) )
  265. print '---'
  266. print grouped_pos
  267. garr = {}
  268. def init_garray(x):
  269. garr[x] = {}
  270. map(init_garray, sorted(strikes))
  271. print garr
  272. def set_garray(x):
  273. vals = x[0].split(('-'))
  274. if vals[0] == months[0]:
  275. if vals[1] == 'C':
  276. garr[vals[2]]['NEAR_C'] = x[1]
  277. else:
  278. garr[vals[2]]['NEAR_P'] = x[1]
  279. elif vals[0] == months[1]:
  280. if vals[1] == 'C':
  281. garr[vals[2]]['FAR_C'] = x[1]
  282. else:
  283. garr[vals[2]]['FAR_P'] = x[1]
  284. # find all C of near month
  285. map(set_garray, grouped_pos)
  286. print garr
  287. s=''
  288. for k, v in garr.iteritems():
  289. s+= '[%s, %s,%s,%s,%s],' % (k, v['NEAR_P'] if 'NEAR_P' in v else 'null',
  290. v['NEAR_C'] if 'NEAR_C' in v else 'null',
  291. v['FAR_P'] if 'FAR_P' in v else 'null',
  292. v['FAR_C'] if 'FAR_C' in v else 'null', )
  293. return s
  294. @cherrypy.expose
  295. def ws_position_chart_ex(self):
  296. p = portfolio.PortfolioManager(config)
  297. p.retrieve_position()
  298. opt_pos_chart_tmpl = '%s%s/opt-pos-chart-stacked-tmpl.html' % (cherrypy.request.app.config['/']['tools.staticdir.root'], cherrypy.request.app.config['/static']['tools.staticdir.tmpl'])
  299. f = open(opt_pos_chart_tmpl)
  300. html_tmpl = f.read()
  301. html_tmpl = html_tmpl.replace('{{{dataPCpos}}}', self.generate_garray(p.get_tbl_pos_list()))
  302. html_tmpl = html_tmpl.replace('{{{dataTablePos}}}', p.get_tbl_pos_csv())
  303. html_tmpl = html_tmpl.replace('{{{option_months}}}', ''.join(('%s, ' % m) for m in p.get_traded_months()))
  304. v = p.group_pos_by_right()
  305. html_tmpl = html_tmpl.replace('{{{PRvsCR}}}}', '%0.2f : %0.2f' % (v[0][1], v[1][1]))
  306. #print p.get_portfolio_summary()
  307. #html_tmpl = html_tmpl.replace('{{{pos_summary}}}', ''.join('<li>%s: %s</li>' % (x[0],x[1]) for x in p.get_portfolio_summary() ))
  308. #print '\n'.join('%s:\t\t%s' % (k,v) for k,v in sorted(json.loads(DataMap.rs.get(port_key)).iteritems()))
  309. return html_tmpl
  310. @cherrypy.expose
  311. def ws_position_summary(self):
  312. p = portfolio.PortfolioManager(config)
  313. keys = [("delta_1percent","number"),("delta_all","number"),("delta_c","number"),("delta_p","number"),\
  314. ("theta_1percent","number"),("theta_all","number"),("theta_c","number"),("theta_p","number"),\
  315. ("unreal_pl","number"),("last_updated","string"),("status","string")]
  316. d = p.get_portfolio_summary()
  317. dict= {}
  318. dict['cols'] = [{'label': x[0], 'type': x[1]} for x in keys]
  319. dict['rows'] = [{'v': d[x[0]]} for x in keys]
  320. print json.dumps(dict)
  321. return json.dumps(dict)
  322. @cherrypy.expose
  323. def ws_recal_pos(self, force_refresh=False):
  324. p = portfolio.PortfolioManager(config)
  325. if force_refresh:
  326. p.retrieve_position()
  327. l_gmap = p.recal_port()
  328. print l_gmap
  329. return json.dumps(l_gmap)
  330. @cherrypy.expose
  331. def ws_pos_csv(self):
  332. p = portfolio.PortfolioManager(config)
  333. p.retrieve_position()
  334. s = "%s" % p.get_tbl_pos_csv_old()
  335. #s = "%s" % p.get_tbl_pos_csv()
  336. #print s
  337. s = s.replace(',[', '').replace(']', '<br>')
  338. print s
  339. return s[1:len(s)-3]
  340. @cherrypy.expose
  341. def getSHquote(self, qs):
  342. #http://api.money.126.net/data/feed/0000001,1399001,1399300
  343. #_ntes_quote_callback({"0000001":{"code": "0000001", "percent": 0.015468, "askvol1": 0, "askvol3": 0, "askvol2": 0, "askvol5": 0,
  344. # "askvol4": 0, "price": 2972.57, "open": 2978.03, "bid5": 0, "bid4": 0, "bid3": 0, "bid2": 0, "bid1": 0, "high": 3014.41, "low": 2929.0,
  345. #"updown": 45.28, "type": "SH", "bidvol1": 0, "status": 0, "bidvol3": 0, "bidvol2": 0, "symbol": "000001", "update": "2015/08/27 12:43:00",
  346. #"bidvol5": 0, "bidvol4": 0, "volume": 19800251400, "ask5": 0, "ask4": 0, "ask1": 0, "name": "\u4e0a\u8bc1\u6307\u6570", "ask3": 0, "ask2": 0,
  347. # "arrow": "\u2191", "time": "2015/08/27 12:42:57", "yestclose": 2927.29, "turnover": 204156106776} });
  348. url = 'http://api.money.126.net/data/feed/%s?callback=ne3587367b7387dc' % qs
  349. print url
  350. pg = urllib2.urlopen(url.encode('utf-8'))
  351. s = pg.read().replace('ne3587367b7387dc(', '')
  352. s = s[:len(s)-2]
  353. print s
  354. return s
  355. @cherrypy.expose
  356. def ws_port_summary(self):
  357. rs = QServer.r_conn
  358. ps_key = cherrypy.request.app.config['redis']['redis.datastore.key.port_summary']
  359. s_portsum = rs.get(ps_key)
  360. #dict = json.loads(s_portsum)
  361. return s_portsum
  362. @cherrypy.expose
  363. def ws_port_items(self):
  364. rs = QServer.r_conn
  365. key = cherrypy.request.app.config['redis']['redis.datastore.key.port_items']
  366. s_portitems = rs.get(key)
  367. #dict = json.loads(s_portsum)
  368. return s_portitems
  369. @cherrypy.expose
  370. def port_bubble_chart(self):
  371. s_data = self.ws_bubble_data()
  372. bubble_chart_tmpl = '%s%s/bubble-port.html' % (cherrypy.request.app.config['/']['tools.staticdir.root'], cherrypy.request.app.config['/static']['tools.staticdir.tmpl'])
  373. f = open(bubble_chart_tmpl)
  374. html_tmpl = f.read()
  375. html_tmpl = html_tmpl.replace('{{{bubble_data}}}', s_data)
  376. contract_month = eval(cherrypy.request.app.config['market']['option.underlying.month_price'])[0][0]
  377. html_tmpl = html_tmpl.replace('{{{FUT_CONTRACT}}}', 'HSI-%s-FUT-' % (contract_month))
  378. s_acctitems, last_updated, account_no = self.ws_acct_data()
  379. print s_acctitems, last_updated, account_no
  380. html_tmpl = html_tmpl.replace('{{{barAcct}}}', s_acctitems)
  381. html_tmpl = html_tmpl.replace('{{{account_no}}}', account_no)
  382. html_tmpl = html_tmpl.replace('{{{last_updated}}}', last_updated)
  383. return html_tmpl
  384. @cherrypy.expose
  385. def ws_bubble_data(self):
  386. # Tick Value Description
  387. # 5001 impl vol
  388. # 5002 delta
  389. # 5003 gamma
  390. # 5004 theta
  391. # 5005 vega
  392. # 5006 premium
  393. # 6001 avgCost
  394. # 6002 pos
  395. # 6003 totCost
  396. # 6004 avgPx
  397. # 6005 pos delta
  398. # 6006 pos theta
  399. # 6007 multiplier
  400. # 6009 curr_port_value
  401. # 6008 unreal_pl
  402. # 6020 pos value impact +1% vol change
  403. # 6021 pos value impact -1% vol change
  404. s_portitems = self.ws_port_items()
  405. litems = json.loads(s_portitems)
  406. # only interested in unrealized items, pos != 0
  407. ldict = filter(lambda x: x['6002'] <> 0, litems)
  408. lcontract = map(lambda x: x['contract'], ldict)
  409. lpos_delta = map(lambda x: x['6005'], ldict)
  410. lstrike = map(lambda x: x['contract'].split('-')[2], ldict)
  411. ltheta = map(lambda x: x['6006'], ldict)
  412. lupl = map(lambda x: x['6008'], ldict)
  413. colnames = "[['contract', 'strike', 'unreal PL', 'theta', 'delta'],"
  414. print '----------------------'
  415. s_data = colnames + ''.join('["%s",%s,%s,%s,%s],' % (lcontract[i], lstrike[i], lupl[i], ltheta[i], abs(lpos_delta[i])) for i in range(len(lcontract)))+ ']'
  416. return s_data
  417. @cherrypy.expose
  418. def ws_acct_data(self):
  419. rs = QServer.r_conn
  420. key = cherrypy.request.app.config['redis']['redis.datastore.key.acct_summary']
  421. s_acctitems = rs.get(key)
  422. dict = json.loads(s_acctitems)
  423. colnames = "[['Category', 'Value', { role: 'style' } ],"
  424. unwanted_cols = ['DayTradesRemaining','last_updated', 'AccountType']
  425. s_data = colnames + ''.join('["%s", %s, "%s"],' % (k, '%s'%(v[0]), '#3366CC' if float(v[0]) > 500000 else '#DC3912') if k not in unwanted_cols else '' for k, v in dict.iteritems() )+ ']'
  426. return (s_data, dict['last_updated'], dict['AccountType'][2])
  427. @cherrypy.expose
  428. def ws_msg_bot(self, msg):
  429. a = AlertHelper(self.config)
  430. a.post_msg(msg)
  431. @cherrypy.expose
  432. def ws(self):
  433. logging.info('at ws')
  434. # you can access the class instance through
  435. handler = cherrypy.request.ws_handler
  436. while handler.opened == False:
  437. logging.info( 'not opened')
  438. logging.info( 'opened')
  439. @cherrypy.expose
  440. def ws_entry(self):
  441. html = '%s%s/wstest.html' % (cherrypy.request.app.config['/']['tools.staticdir.root'], cherrypy.request.app.config['/static']['tools.staticdir.tmpl'])
  442. f = open(html)
  443. return f.read()
  444. class OptWebSocket(WebSocket):
  445. # def __init__(self):
  446. # logging.debug('instantiated.')
  447. def received_message(self, message):
  448. self.send(message.data, message.is_binary)
  449. logging.info('received %s' % message.data)
  450. # def opened(self):
  451. # logging.info('web socket opened')
  452. #self.send('hello')
  453. # while 1:
  454. # self.send('%f' % time.time(), False)
  455. # time.sleep(2)
  456. def opened(self):
  457. logging.info('web socket opened')
  458. def data_provider():
  459. while 1:
  460. # print ('%f' % time.time())
  461. # time.sleep(2)
  462. def cb():
  463. #for i in range(1, 200, 25):
  464. # yield "#" * i
  465. yield '%f' % time.time()
  466. self.send(cb())
  467. logging.info('--- here')
  468. time.sleep(2)
  469. thread.start_new_thread(data_provider())
  470. def closed(self, code, reason=None):
  471. print "Closed down", code, reason
  472. if __name__ == '__main__':
  473. # logging.basicConfig(filename = "log/opt.log", filemode = 'a',
  474. # level=logging.DEBUG,
  475. # format='%(asctime)s %(levelname)-8s %(message)s')
  476. #
  477. #
  478. # config = ConfigParser.ConfigParser()
  479. # config.read("config/app.cfg")
  480. # host = config.get("redis", "redis.server").strip('"').strip("'")
  481. # port = config.get("redis", "redis.port")
  482. # db = config.get("redis", "redis.db")
  483. # r_conn = redis.Redis(host,port,db)
  484. # cherrypy.quickstart(QServer(r_conn, config), '/', "config/app.cfg")
  485. if len(sys.argv) != 2:
  486. print("Usage: %s <config file>" % sys.argv[0])
  487. exit(-1)
  488. cfg_path= sys.argv[1:]
  489. config = ConfigParser.ConfigParser()
  490. if len(config.read(cfg_path)) == 0:
  491. raise ValueError, "Failed to open config file"
  492. logconfig = eval(config.get("opt_serve", "opt_serve.logconfig").strip('"').strip("'"))
  493. logconfig['format'] = '%(asctime)s %(levelname)-8s %(message)s'
  494. logging.basicConfig(**logconfig)
  495. host = config.get("redis", "redis.server").strip('"').strip("'")
  496. port = config.get("redis", "redis.port")
  497. db = config.get("redis", "redis.db")
  498. r_conn = redis.Redis(host,port,db)
  499. WebSocketPlugin(cherrypy.engine).subscribe()
  500. cherrypy.tools.websocket = WebSocketTool()
  501. cherrypy.quickstart(QServer(r_conn, config), '/', cfg_path[0])