Bladeren bron

all pyc files removed

mchan927@home 8 jaren geleden
bovenliggende
commit
2777e7aad4

BIN
comms/__init__.pyc


BIN
comms/alert_bot.pyc


+ 2 - 7
comms/epc.py

@@ -119,7 +119,7 @@ class ExternalProcessComm(threading.Thread):
                                          message.offset, message.key,
                                          message.value))
 
-            print ("received %s:%d:%d: key=%s value=%s" % (message.topic, message.partition,
+            print ("%s:%d:%d: key=%s value=%s" % (message.topic, message.partition,
                                          message.offset, message.key,
                                          message.value))
 
@@ -141,9 +141,4 @@ if __name__ == '__main__':
     e = ExternalProcessComm(config)
     e.start()
     
-    e.post_msg(ExternalProcessComm.EPC_TOPICS['EPC_PORT_SUMMARY_TOPIC'], 'test msg')
-    
-    e2 = ExternalProcessComm(config)
-    e2.start()
-
-    
+    e.post_msg(ExternalProcessComm.EPC_TOPICS['EPC_PORT_SUMMARY_TOPIC'], 'test msg')

BIN
comms/epc.pyc


+ 0 - 2
comms/ib_heartbeat.py

@@ -82,8 +82,6 @@ class IbHeartBeat():
 
 
 
-        
-    
 
 if __name__ == '__main__':
            

BIN
comms/ib_heartbeat.pyc


BIN
comms/redisQueue.pyc


BIN
comms/tws_client.pyc


BIN
comms/tws_gateway.pyc


BIN
comms/tws_protocol_helper.pyc


+ 16 - 15
config/app.cfg

@@ -30,7 +30,7 @@ redis.datastore.key.hkex_holiday_prefix: 'hkex_holiday_'
  
 [/]
 tools.sessions.on : True
-tools.staticdir.root : '/home/larry-13.04/workspace/finopt/src/'
+tools.staticdir.root : '/home/itchyape/mchan927/finopt/'
 #tools.staticdir.root : '/home/larry-13.04/production/finopt/'
 
 [/static]
@@ -49,16 +49,17 @@ tools.websocket.handler_cls: opt_serve.OptWebSocket
 
 
 [options_data]
-options_data.logconfig: "{'filename': '/home/larry-13.04/workspace/finopt/log/opt.log', 'filemode': 'w','level': logging.DEBUG}"
+options_data.logconfig: "{'filename': '/home/itchyape/mchan927/findata/log/opt.log', 'filemode': 'w','level': logging.DEBUG}"
 
 [portfolio]
-portfolio.logconfig: "{'filename': '/home/larry-13.04/workspace/finopt/log/port.log', 'filemode': 'w','level': logging.INFO}"
+#portfolio.logconfig: "{'filename': '/home/itchyape/mchan927/findata/log/port.log', 'filemode': 'w','level': logging.INFO}"
+portfolio.logconfig: "{'filename': '/home/itchyape/mchan927/findata/log/port.log', 'filemode': 'w','level': logging.DEBUG}"
 portfolio.epc: "{'stream_to_Kafka': True}"   
 portfolio.account_summary_tags: "['AccountType','NetLiquidation','TotalCashValue','SettledCash','AccruedCash','BuyingPower','EquityWithLoanValue','PreviousDayEquityWithLoanValue','GrossPositionValue','RegTEquity','RegTMargin','SMA','InitMarginReq','MaintMarginReq','AvailableFunds','ExcessLiquidity','Cushion','FullInitMarginReq','FullMaintMarginReq','FullAvailableFunds','FullExcessLiquidity','LookAheadNextChange','LookAheadInitMarginReq','LookAheadMaintMarginReq','LookAheadAvailableFunds','LookAheadExcessLiquidity','HighestSeverity','DayTradesRemaining','Leverage']"
 
 
 [opt_serve]
-opt_serve.logconfig: "{'filename': '/home/larry-13.04/workspace/finopt/log/serve.log', 'filemode': 'w','level': logging.INFO}"
+opt_serve.logconfig: "{'filename': '/home/itchyape/mchan927/findata/log/serve.log', 'filemode': 'w','level': logging.INFO}"
 
 
 [cep]
@@ -66,11 +67,11 @@ kafka.host: 'vsu-01'
 kafka.port: 9092
 kafka.ib.topic.tick_price: 'ib_tick_price'
 kafka.ib.topic.tick_size: 'ib_tick_size'
-ib.subscription.fileloc: '/home/larry-13.04/workspace/finopt/data/subscription.txt'
+ib.subscription.fileloc: '/home/itchyape/mchan927/finopt/data/subscription.txt'
 
 
 [market]
-hkex.openhours: '{"morning":[915,1200], "afternoon":[1300,1615]}'
+hkex.openhours: '{"morning":[915,1200], "afternoon":[1300,1630]}'
 
 
 
@@ -93,8 +94,8 @@ option.underlying = "('HSI', 'FUT', 'HKFE', 'HKD', '', 0, '')"
 # the month value is no longer required as the system
 # will auto retrieve holidays from hk gov website
 # and deduce the near and next month options last trading date
-option.underlying.month_price = "[['20160629', 20100, '^HSI'], ['20160728', 20100.0, '^HSI']]"
-option.underlying.yahoo_ws = "{'use_yahoo': True, 'func': 'ystockquote.get_price'}"
+option.underlying.month_price = "[['20180130', 30200, '^HSI'], ['20180227', 30200, '^HSI']]"
+option.underlying.yahoo_ws = "{'use_yahoo': False, 'func': 'ystockquote.get_price'}"
 option.underlying.tick_size = 200
 
 # refer to this link for rate and div
@@ -114,22 +115,22 @@ msg_bot.redis_prefix: 'alert_bot'
 msg_bot.logconfig: "{'level': logging.INFO}"
 
 [epc]
-kafka.host: 'vsu-01'
+kafka.host: 'localhost'
 kafka.port: 9092
 
 [ib_mds]
-ib_mds.logconfig: "{'filename': '/home/larry-13.04/workspace/finopt/log/ib_mds.log', 'filemode': 'w','level': logging.INFO}"
+ib_mds.logconfig: "{'filename': '/home/itchyape/mchan927/findata/log/ib_mds.log', 'filemode': 'w','level': logging.INFO}"
 ib_mds.ib_port: 7496
 #ib_mds.ib_port: 4001
 ib_mds.appid.id: 9800
 ib_mds.gateway: 'localhost'
 #ib_mds.gateway: '192.168.1.118'
 ib_mds.is_persist: 1
-ib_mds.persist_dir: '/home/larry-13.04/workspace/finopt/data/mds_files'
+ib_mds.persist_dir: '/home/itchyape/mchan927/finopt/data/mds_files'
 ib_mds.spill_over_limit: 10000
 
 [ib_heartbeat]
-ib_heartbeat.logconfig: "{'filename': '/home/larry-13.04/workspace/finopt/log/ib_mds.log', 'filemode': 'w','level': logging.INFO}"
+ib_heartbeat.logconfig: "{'filename': '/home/itchyape/mchan927/findata/log/ib_mds.log', 'filemode': 'w','level': logging.INFO}"
 #ib_heartbeat.ib_port: 4001
 ib_heartbeat.ib_port: 7496
 ib_heartbeat.appid.id: 9911
@@ -139,16 +140,16 @@ ib_heartbeat.try_interval: 60
 ib_heartbeat.suppress_msg_interval: 120
 
 [smart_order]
-smart_order.logconfig: "{'filename': '/home/larry-13.04/workspace/finopt/log/smart_order.log', 'filemode': 'w','level': logging.INFO}"
+smart_order.logconfig: "{'filename': '/home/itchyape/mchan927/findata/log/smart_order.log', 'filemode': 'w','level': logging.INFO}"
 
 
 [tws_gateway]
 subscription_manager.subscriptions.redis_key: 'subscriptions'  
-tws_gateway.logconfig: "{'filename': '/home/larry-13.04/workspace/finopt/log/tws_gateway.log', 'filemode': 'w','level': logging.INFO}"
+tws_gateway.logconfig: "{'filename': '/home/itchyape/mchan927/findata/log/tws_gateway.log', 'filemode': 'w','level': logging.INFO}"
 tws_gateway.order_transmit: False
 
 
 [options_chain]
-options_calculation_engine.logconfig: "{'filename': '/home/larry-13.04/workspace/finopt/log/oce.log', 'filemode': 'w','level': logging.INFO}"
+options_calculation_engine.logconfig: "{'filename': '/home/itchyape/mchan927/findata/log/oce.log', 'filemode': 'w','level': logging.INFO}"
 option_chain_id.redis_key_prefix: 'optchain-'
 clear_redis_on_start: True

BIN
finopt/__init__.pyc


BIN
finopt/finopt.pyc


BIN
finopt/misc/__init__.pyc


+ 95 - 2
finopt/opt_serve.py

@@ -345,7 +345,7 @@ class QServer(object):
         strikes =[e for e in Set(map(lambda x:x[4], plist))]
         # sort the months in ascending order
         months = sorted([e for e in Set(map(lambda x:x[2], plist))])
-	print klist
+        print klist
         print strikes
         # print months
         # print len(klist), len(s)
@@ -396,6 +396,96 @@ class QServer(object):
         return s    
     
     
+    def generate_garray_ex(self, plist):
+    
+    #[['HSI', 'FUT', '20170126', 'None', '0', '50.0', '0.0000', '0.0000'], 
+    # ['HSI', 'OPT', '20170126', 'C', '23000', '50.0', '-4.0000', '3240.3350'], ['HSI', 'OPT', '20170126', 'P', '22600', '50.0', '-1.0000', '1330.9600'], ['HSI', 'OPT', '20170227', 'C', '23400', '50.0', '-2.0000', '9880.9600'], ['HSI', 'OPT', '20170227', 'C', '23600', '50.0', '-1.0000', '9530.9600'], ['HSI', 'OPT', '20170227', 'P', '20200', '50.0', '-3.0000', '980.9600'], ['HSI', 'OPT', '20170227', 'P', '20400', '50.0', '-1.0000', '7664.2933'], ['HSI', 'OPT', '20170227', 'P', '21800', '50.0', '-3.0000', '5197.6267'], ['MHI', 'FUT', '20170126', 'None', '0', '10.0', '5.0000', '230459.6680']]
+        
+        
+        # generate a key map with month-right-strike
+        # example: ('20160330-C-20000', 0.2),...
+        
+        #klist = map(lambda x: ('%s-%s-%s' % (x[2], x[3] if x[3] <> 'None' else 'F', x[4]), float(x[5])/50.0*float(x[6])), plist)
+        
+        # 2017 - handle futures price 
+        
+        def getX(x):
+            val = x[4] if x[3] <> 'None' else str(int(round(float(x[7])/ float(x[5]),-1)))
+    #        print val
+            return val
+        
+        plist = filter(lambda x: int(float(x[6])) <> 0, plist)
+        klist = map(lambda x: ('%s-%s-%s' % (x[2], x[3] if x[3] <> 'None' else 'F', getX(x)), float(x[5])/50.0*float(x[6])), plist)
+        # for e in sorted(klist):
+        #     print e
+    
+        # get the unique keys in klist
+        unique_keys= Set(map(lambda x:x[0], klist))
+        
+        
+        #strikes =[e for e in Set(map(lambda x:x[4], plist))]
+        # 2017 
+        strikes = [e for e in Set(map(lambda x:getX(x), plist))]
+        
+         
+        # sort the months in ascending order
+        months = sorted([e for e in Set(map(lambda x:x[2], plist))])
+        print klist
+        print strikes
+        # print months
+        # print len(klist), len(s)
+        
+        # group and sum position by month, strike, right
+        grouped_pos = []
+        for elem in unique_keys:
+            grp1 = filter(lambda x: x[0] == elem, klist)
+            print grp1
+            # sum items with same key
+            # example: [('20160330-P-19600', -1.0), ('20160330-P-19600', 0.2)]
+            grouped_pos.append( grp1[0] if len(grp1) == 1 else reduce(lambda x,y: (x[0], x[1]+y[1]), grp1) )
+            print '---'
+        
+        print grouped_pos    
+            
+        garr = {}
+        def init_garray(x):
+            garr[x] = {}
+        map(init_garray, sorted(strikes))
+        print garr
+        
+        def set_garray(x):
+            vals = x[0].split(('-'))
+            
+            if vals[0] == months[0]:
+                
+                if vals[1] == 'C':
+                    garr[vals[2]]['NEAR_C'] = x[1]
+                elif vals[1] =='P':
+                    garr[vals[2]]['NEAR_P'] = x[1]
+                else:
+                    garr[vals[2]]['NEAR_F'] = x[1]
+            elif vals[0] == months[1]:
+        
+                if vals[1] == 'C':
+                    garr[vals[2]]['FAR_C'] = x[1]
+                elif vals[1] =='P':
+                    garr[vals[2]]['FAR_P'] = x[1]
+                else:
+                    garr[vals[2]]['FAR_F'] = x[1]
+        # find all C of near month
+        map(set_garray, grouped_pos)
+        print garr
+        s=''
+        for k, v in garr.iteritems():
+            s+= '[%s, %s,%s,%s,%s,%s,%s],' % (k, v['NEAR_P'] if 'NEAR_P' in v else '0',
+                                         v['NEAR_C'] if 'NEAR_C' in v else '0',  
+                                         v['FAR_P'] if 'FAR_P' in v else '0', 
+                                         v['FAR_C'] if 'FAR_C' in v else '0', 
+                                         v['NEAR_F'] if 'NEAR_F' in v else '0', 
+                                         v['FAR_F'] if 'FAR_F' in v else '0', )
+                                         
+        return s        
+    
     @cherrypy.expose
     def ws_position_chart_ex(self):
         p = portfolio.PortfolioManager(config)
@@ -404,7 +494,10 @@ class QServer(object):
         f = open(opt_pos_chart_tmpl)
         html_tmpl = f.read()
 
-        html_tmpl = html_tmpl.replace('{{{dataPCpos}}}', self.generate_garray(p.get_tbl_pos_list()))
+        #html_tmpl = html_tmpl.replace('{{{dataPCpos}}}', self.generate_garray(p.get_tbl_pos_list()))
+        # 2017 - handles futures
+
+        html_tmpl = html_tmpl.replace('{{{dataPCpos}}}', self.generate_garray_ex(p.get_tbl_pos_list()))
         
         html_tmpl = html_tmpl.replace('{{{dataTablePos}}}', p.get_tbl_pos_csv())
         

BIN
finopt/opt_serve.pyc


+ 10 - 4
finopt/optcal.py

@@ -105,7 +105,10 @@ def get_hk_holidays(year):
         if str(year) == (Date().todaysDate() + Period("1y")).ISO()[0:4]:
             url = 'http://www.gov.hk/en/about/abouthk/holiday/'
         else:
-            url = 'http://www.gov.hk/en/about/abouthk/holiday/{{year}}.htm'
+            #url = 'http://www.gov.hk/en/about/abouthk/holiday/{{year}}.htm'
+	    # lc 2017-01-03
+	    # just use the same url for both cases
+            url = 'http://www.gov.hk/en/about/abouthk/holiday/'
             url = url.replace('{{year}}', str(year))
 
 
@@ -120,8 +123,9 @@ def get_hk_holidays(year):
         soup = BeautifulSoup(html, 'html5lib')
         
         tds = soup.findAll('h3')[0].parent.findAll('td', 'date')
-        
-        d1 = map(lambda x: (int(x.text.split(' ')[0]), x.text.split(' ')[1]), tds[1:])
+        #d1 = map(lambda x: (int(x.text.split(' ')[0]), x.text.split(' ')[1]), tds[1:])
+	#2017 fix
+        d1 = map(lambda x: (int(x.text.split()[0]), x.text.split()[1]), tds[1:])
         holidays =  map(lambda x: '%d%02d%02d' % (year, int(month_names[x[1]]), int(x[0]) ), d1)
         #return map(lambda x: strftime('%Y%m%d', time.strptime('%s %s %s' % (month_names.index(x[1])+1, x[0], year), "%m %d %Y")), d1)
         #print d1
@@ -326,4 +330,6 @@ if __name__ == '__main__':
     for i in month_names:
         dd = get_HSI_last_trading_day(holidays, i, 2017)
         print dd
-        
+        
+    print holidays	
+    print get_HSI_last_trading_day(['20170128'], 1, 2017)

BIN
finopt/optcal.pyc


BIN
finopt/options_analytics.pyc


BIN
finopt/options_chain.pyc


+ 18 - 5
finopt/options_data.py

@@ -188,14 +188,20 @@ class OptionsMarketDataManager():
         
         def derive_mid_price(field_id):
             bidask = 2 if (field_id == 1) else 1
+	    logging.debug("********** dump %s" % str(DataMap().get(msg.tickerId)))
+	    # 2018 lc
+            mid = None 
             if bidask in DataMap().get(msg.tickerId):
                 if DataMap().get(msg.tickerId)[bidask] > 0.0:
                     mid = (DataMap().get(msg.tickerId)[bidask] + msg.price) / 2
                 else:
                     mid = msg.price
-            logging.debug("OptionsMarketDataManager: incoming price field%d == %0.4f datamap field%d ==2 %0.4f"\
+            	logging.debug("OptionsMarketDataManager: incoming price field%d == %0.4f datamap field%d ==2 %0.4f"\
                            % (field_id, msg.price, bidask, DataMap().get(msg.tickerId)[bidask]))                                 
-            return mid
+		
+	    #return mid
+	    # 2018 lc - fix no mid assigned error
+            return mid if (mid != None) else msg.price 
         
         premium = derive_mid_price(msg.field)
         
@@ -549,7 +555,9 @@ class DataMap():
         holiday_key = '%s%s' % (holiday_key_prefix, year)
         holidays = rs.get(holiday_key)
                     
-        if holidays == None:
+#        if holidays == None:
+#	fix 2017-01-03
+        if holidays == 'null':
             holidays = optcal.get_hk_holidays(year)
             logging.info("options_data:set_option_calendar: retrieved from gov.hk --> update Redis: [%s]: %s", holiday_key, json.dumps(holidays))
             rs.set(holiday_key, json.dumps(holidays))    
@@ -563,7 +571,12 @@ class DataMap():
         undly_months_prices = eval(config.get("market", "option.underlying.month_price").strip('"').strip("'"))
         
         undly_months_prices[0][0] = optcal.get_HSI_last_trading_day(holidays, month, year)
-        undly_months_prices[1][0] = optcal.get_HSI_last_trading_day(holidays, (month + 1) % 12, year)
+	next_month = (month + 1) % 12 if (month + 1) % 12 <> 0 else (month + 1) % 12 + 12
+#2016/12 lc - fix year end bug 
+	year = year if next_month <> 1 else year + 1
+	
+        logging.info("options_data:set_option_calendar: next month: year %s:%s " % (next_month, year))
+        undly_months_prices[1][0] = optcal.get_HSI_last_trading_day(holidays, next_month, year)
         
         logging.info("options_data:set_option_calendar:  %s " % str(undly_months_prices))
         return undly_months_prices
@@ -1100,7 +1113,7 @@ def add_portfolio_subscription(config, omd):
     p = portfolio.PortfolioManager(config)
     p.retrieve_position()
     
-    
+    logging.debug("************ complete retrieve pos ****") 
 #    undly_months_prices = eval(config.get("market", "option.underlying.month_price").strip('"').strip("'"))
     # 20160612
     undly_months_prices = DataMap().rskeys['option.underlying.month_price']

BIN
finopt/options_data.pyc


+ 276 - 52
finopt/portfolio.py

@@ -340,28 +340,36 @@ class PortfolioManager():
         # 2016/06/11
         # add 2 new columns: avgcost in points, unreal_pl ratio
         #s = '["symbol","right","avgcost","spotpx","pos","delta","theta","pos_delta","pos_theta","unreal_pl","last_updated"],'
-        s = '["symbol","right","avgcost","avgpx","spotpx","pos","delta","theta","pos_delta","pos_theta","unreal_pl","unreal%","last_updated"],'
+        s = '["symbol","right","avgcost","avgpx","spotpx","pos","delta","theta","pos_delta","pos_theta","unreal_pl","%gain/loss" ],'
         
         def split_toks(x):
             try: # 
                 pmap = json.loads(self.r_conn.get(x))
-                #print pmap
+            #    print pmap
                 gmap = json.loads(self.r_conn.get(x[3:]))
-                #print gmap
-#                 s = '["%s","%s",%f,%f,%f,%f,%f,%f,%f,%f,"%s"],' % (x[3:], x[len(x)-1:], pmap['6001'], gmap['5006'], pmap['6002'],\
-#                                                                              gmap['5002'],gmap['5004'],\
-#                                                                              pmap['6005'],pmap['6006'],pmap['6008'],pmap['last_updated'])
-        # 2016/06/11        
-                s = '["%s","%s",%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,"%s"],' % (x[3:], x[len(x)-1:], pmap['6001'], pmap['6001'] / pmap['6007'], gmap['5006'], pmap['6002'],\
-                                                                             gmap['5002'],gmap['5004'],\
-                                                                             pmap['6005'],pmap['6006'],pmap['6008'],
-                                                                             
-                                                                             (gmap['5002'] - (pmap['6001'] / pmap['6007'])) / pmap['6001'] / pmap['6007'],
-                                                                             pmap['last_updated'])                
+            #    print gmap
+                str = None
+                if not 'FUT' in x:
+                    pl_percent = (1 - gmap['5006'] / (pmap['6001'] / pmap['6007'])) * 100.0 if pmap['6002'] < 0 else  (gmap['5006'] - pmap['6001'] / pmap['6007']) / (pmap['6001'] / pmap['6007']) * 100  
+    
+    #                 s = '["%s","%s",%f,%f,%f,%f,%f,%f,%f,%f,"%s"],' % (x[3:], x[len(x)-1:], pmap['6001'], gmap['5006'], pmap['6002'],\
+    #                                                                              gmap['5002'],gmap['5004'],\
+    #                                                                              pmap['6005'],pmap['6006'],pmap['6008'],pmap['last_updated'])
+            # 2016/06/11        
+                    str = '["%s","%s",%f,%f,%f,%f,%f,%f,%f,%f,%f,%f],' % (x[3:], x[len(x)-1:], pmap['6001'], pmap['6001'] / pmap['6007'], gmap['5006'], pmap['6002'],\
+                                                                                 gmap['5002'],gmap['5004'],\
+                                                                                 pmap['6005'],pmap['6006'],pmap['6008'],
+                                                                                 pl_percent)
+                else:
+                    str = '["%s","%s",%f,%f,%f,%f,%f,%f,%f,%f,%f,%f],' % (x[3:], 'F', pmap['6001'], pmap['6001'] / pmap['6007'], 0, pmap['6002'],\
+                                                                                 0, 0,\
+                                                                                 pmap['6005'],0,-1,
+                                                                                 -1)
+                    
             except:
-                logging.error('entry %s skipped due to an exception. Please validate your position' % x)
+                logging.error('split_toks: entry %s skipped due to an exception. Please validate your position' % x)
                 return ''
-            return s                                                          
+            return str                                                         
             
         end_s = s + ''.join (split_toks( x ) for x in pall)
         return end_s 
@@ -394,7 +402,12 @@ class PortfolioManager():
         for l in sorted(self.port):
             content = []    
             toks= l.split(',')
- #           print toks
+            #
+            # lc - 2017
+            # skip futures entries 
+#             if toks[1] == 'FUT':
+#                 continue
+
             for i in s_cols:
                 content.append(toks[i])
             for i in i_cols:
@@ -417,17 +430,181 @@ class PortfolioManager():
         logging.debug('recal_port: acquiring lock...%s' % threading.currentThread())
         self.tlock.acquire()
         try:
-            s = self.recal_port_rentrant_unsafe()
+            #s = self.recal_port_rentrant_unsafe()
+            s = self.recal_port_rentrant_unsafe_ex()
         finally:
             logging.debug('recal_port: completed recal. releasing lock...')
             self.tlock.release()  
             
         return s
 
-    def recal_port_rentrant_unsafe(self):
+#     def recal_port_rentrant_unsafe(self):
+#         
+#         
+#         logging.debug('PortfolioManager: recal_port')
+# 
+#         # retrieve the portfolio entries from redis, strip the prefix in front
+#         plines = map(lambda k: (k.replace(self.rs_port_keys['port_prefix'] + '_', '')),\
+#                                  self.r_conn.keys(pattern=('%s*'% self.rs_port_keys['port_prefix'])))
+#                                  
+# 	# lc 2017
+# 	# temp fix to bypass errors when encountering futures contract
+# 	plines = filter(lambda k: not 'FUT' in k, plines)
+#         logging.info ("PortfolioManager: recal_port-> gathering position entries from redis %s" % plines)
+#         
+#         
+#         # 2017 added a new colum delta_f
+#         pos_summary = {'delta_c': 0.0, 'delta_p': 0.0, 'delta_all': 0.0, \
+#                        'theta_c': 0.0, 'theta_p': 0.0, 'theta_all': 0.0,\
+#                        'delta_1percent' : 0.0, 'theta_1percent' : 0.0,\
+#                        'iv_plus1p': 0.0, 'iv_minus1p': 0.0, 'unreal_pl': 0.0}
+#         l_gmap = []
+#         l_skipped_pos =[]       
+#         t_pos_multiplier = 0.0
+#         
+#         for ckey in plines:
+#         
+#             gmap = self.get_greeks(ckey)
+#             logging.debug('PortfolioManager: recal_port greeks market data %s->%s ' % (ckey, gmap))
+#             logging.debug('PortfolioManager: recal_port position-map->%s' % (self.r_get(ckey)))
+#             pmap = json.loads(self.r_get(ckey)) 
+#             
+#             
+#             
+#             if gmap:
+#             
+#             # Tick Value      Description
+#             # 5001            impl vol
+#             # 5002            delta
+#             # 5003            gamma
+#             # 5004            theta
+#             # 5005            vega
+#             # 5006            premium        
+#             # 6001            avgCost
+#             # 6002            pos
+#             # 6003            totCost
+#             # 6004            avgPx
+#             # 6005            pos delta
+#             # 6006            pos theta
+#             # 6007            multiplier
+#             # 6009            curr_port_value
+#             # 6008            unreal_pl
+#             # 6020            pos value impact +1% vol change
+#             # 6021            pos value impact -1% vol change
+#             
+#            
+#                 def pos_delta():                 
+#                     pd = pmap['6002'] * gmap['5002'] * pmap['6007']
+#                     logging.debug('PortfolioManager: recal_port: pos_delta: %f' % pd)
+#                     return pd
+#                 
+#                 def pos_theta():
+#                     pd = pmap['6002'] * gmap['5004'] * pmap['6007']
+#                     logging.debug('PortfolioManager: recal_port: pos_theta: %f' % pd)
+#                     return pd
+#  
+#                 def pos_avg_px():
+#                     pd = pmap['6001'] / pmap['6007']
+#                     logging.debug('PortfolioManager: recal_port: pos_avg_px: %f' % pd)
+#                     return pd                   
+#                     
+#                 def pos_tot_cost():
+#                     pd = pmap['6001'] * pmap['6002'] * pmap['6007']
+#                     logging.debug('PortfolioManager: recal_port: pos_tot_cost: %f' % pd)
+#                     return pd                   
+#                 
+#                 def pos_unreal_pl():
+#                     #(spot premium * multiplier - avgcost) * pos) 
+#                     v = (gmap['5006'] * pmap['6007'] - pmap['6001']) * pmap['6002'] 
+#                     return v 
+#     
+#                 
+#     
+#                 #logging.debug('PortfolioManager: recal_port greeks %f' % pos_delta(gmap))
+#                 
+#                 pmap['6005'] = pos_delta()
+#                 pmap['6006'] = pos_theta()
+#                 pmap['6004'] = pos_avg_px()
+#                 pmap['6003'] = pos_tot_cost()
+#                 pmap['6008'] = pos_unreal_pl()
+#                 pmap['last_updated'] = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
+#                 
+#                 l_gmap.append(pmap)          
+# 
+#                 #t_pos_multiplier += (pmap['6002'] * pmap['6007'])
+# 
+#                 right = ckey.split('-')[3].lower()
+#                 pos_summary['delta_' + right] += pmap['6005']
+#                 pos_summary['delta_all'] += pmap['6005']
+#                 pos_summary['theta_' + right] += pmap['6006']
+#                 pos_summary['theta_all'] += pmap['6006']
+#                 pos_summary['unreal_pl'] += pmap['6008']
+# 
+#                 
+#                 
+#                 #pos_summary['delta_1percent'] += (pos_summary['delta_all'] / (pmap['6002'] * pmap['6007']))
+#                 # delta_1% = pos_ / (pos * multiplier)
+#                 
+#                 
+#                 #print 'con,right,avgcost,spot px,pos,delta,theta, pos_delta,pos_theta,pos_unreal_pl,last_updated'
+# #                 print ( 'PT_entries: %s,%s,%f,%f,%f,%f,%f,%f,%f,%f,%s' % (ckey, right, pmap['6001'], gmap['5006'], pmap['6002'],\
+# #                                                                      gmap['5002'],gmap['5004'],\
+# #                                                                      pmap['6005'],pmap['6006'],pmap['6008'],pmap['last_updated']
+# #                                                                      ))
+# #20150911                
+#                 #print pmap
+#                 #print json.dumps(pmap)
+#                 self.r_set(ckey, json.dumps(pmap))
+#                 
+#                 logging.debug('PortfolioManager: update position in redis %s' % self.r_get(ckey))
+#                 
+#             else:
+#                 l_skipped_pos.append(ckey)
+# 
+#             
+# #            self.r_set(ckey, json.dumps(pmap))
+# #            logging.debug('PortfolioManager: update position in redis %s' % self.r_get(ckey))
+# 
+#  
+#         #pos_summary['delta_1percent'] = (pos_summary['delta_all'] / t_pos_multiplier)
+#         
+#         
+# 
+#  
+#         if len(l_skipped_pos) > 0:
+#             logging.warn('***************** PortfolioManager: recal_port. SOME POSITIONS WERE NOT PROCESSED!')
+#             logging.warn('----------------- DO NOT rely on the numbers in the Summary dictionary (pos_summary)')
+#             logging.warn('----------------- Please check your portfolio through other means or subscribe missing')
+#             logging.warn('----------------- market data in options_serve.py console. ')
+#         logging.info('-------------- POSITION SUMMARY')
+#         pos_summary['last_updated'] = datetime.datetime.now().strftime('%Y%m%d%H%M%S')    
+#         pos_summary['entries_skipped'] = l_skipped_pos
+#         pos_summary['status'] = 'OK' if len(l_skipped_pos) == 0 else 'NOT_OK'
+#         #self.r_set(self.rs_port_keys['port_summary'], json.dumps(pos_summary) )
+#         t_pos_summary = json.dumps(pos_summary)
+#         self.r_conn.set(self.rs_port_keys['port_summary'], t_pos_summary )
+#         self.r_conn.set(self.rs_port_keys['port_items'], json.dumps(l_gmap))
+#         #print pos_summary
+#         #print l_gmap      
+#         # broadcast 
+#         if self.epc['epc']:
+#             try:
+#                 self.epc['epc'].post_portfolio_summary(pos_summary)
+#                 self.epc['epc'].post_portfolio_items(l_gmap)
+#             except:
+#                 logging.exception("Exception in function: recal_port_rentrant_unsafe")
+# 
+#         #logging.info(pos_summary)
+#         
+#         logging.warn('-------------- Entries for which the greeks are not computed!! %s' %\
+#                         ','.join(' %s' % k for k in l_skipped_pos))
+#         
+#         return l_gmap
+ 
+    def recal_port_rentrant_unsafe_ex(self):
         
         
-        logging.debug('PortfolioManager: recal_port')
+        logging.debug('PortfolioManager: recal_port_ex')
 
         # retrieve the portfolio entries from redis, strip the prefix in front
         plines = map(lambda k: (k.replace(self.rs_port_keys['port_prefix'] + '_', '')),\
@@ -435,7 +612,10 @@ class PortfolioManager():
                                  
         logging.info ("PortfolioManager: recal_port-> gathering position entries from redis %s" % plines)
         
-        pos_summary = {'delta_c': 0.0, 'delta_p': 0.0, 'delta_all': 0.0,\
+        
+        # 2017 lc
+        # add a new column: delta_f
+        pos_summary = {'delta_c': 0.0, 'delta_p': 0.0, 'delta_f': 0.0, 'delta_all': 0.0,\
                        'theta_c': 0.0, 'theta_p': 0.0, 'theta_all': 0.0,\
                        'delta_1percent' : 0.0, 'theta_1percent' : 0.0,\
                        'iv_plus1p': 0.0, 'iv_minus1p': 0.0, 'unreal_pl': 0.0}
@@ -446,15 +626,18 @@ class PortfolioManager():
         for ckey in plines:
         
             gmap = self.get_greeks(ckey)
-            logging.debug('PortfolioManager: recal_port greeks market data %s->%s ' % (ckey, gmap))
-            logging.debug('PortfolioManager: recal_port position-map->%s' % (self.r_get(ckey)))
-            pmap = json.loads(self.r_get(ckey)) 
-            
             
+            print "*** ckey %s gmap %s" % (ckey,str(gmap))
             
-            if gmap:
-            
-            # Tick Value      Description
+            # if gmap is not None, it implies it could be either an option with greek values in the redis map OR
+            # a futures contract (no option greeks but contains market data fields in the gmap)
+            # if gmap is None, it implies that the entry is either an option with no greek values OR
+            # a MHI contract 
+            # 
+            # why so complicate? the original design did not save MHI into the redis map
+            # the next if stmt tests for an entry and test whether it is a HSI, MHI, or an option with greeks map
+            if gmap or (not gmap and 'MHI' in ckey): 
+                # Tick Value      Description
             # 5001            impl vol
             # 5002            delta
             # 5003            gamma
@@ -472,33 +655,63 @@ class PortfolioManager():
             # 6008            unreal_pl
             # 6020            pos value impact +1% vol change
             # 6021            pos value impact -1% vol change
-            
+                def is_futures(ckey):
+                    return 'FUT' in ckey
            
-                def pos_delta():                 
-                    pd = pmap['6002'] * gmap['5002'] * pmap['6007']
+                def pos_delta():
+                    delta = 0.0     
+                    if not is_futures(ckey):
+                        
+                        delta = gmap['5002']
+                    else:
+                        delta = 1.0
+                          
+                    print "***** delta chosen %f" % delta         
+                    pd = pmap['6002'] * delta * pmap['6007']
                     logging.debug('PortfolioManager: recal_port: pos_delta: %f' % pd)
                     return pd
                 
                 def pos_theta():
-                    pd = pmap['6002'] * gmap['5004'] * pmap['6007']
+                    pd = pmap['6002'] * gmap['5004'] * pmap['6007'] if not is_futures(ckey) else 0
                     logging.debug('PortfolioManager: recal_port: pos_theta: %f' % pd)
                     return pd
  
                 def pos_avg_px():
-                    pd = pmap['6001'] / pmap['6007']
+                    pd = pmap['6001'] / pmap['6007'] # if not is_futures(ckey) else pmap['6001'] 
                     logging.debug('PortfolioManager: recal_port: pos_avg_px: %f' % pd)
                     return pd                   
                     
                 def pos_tot_cost():
-                    pd = pmap['6001'] * pmap['6002'] * pmap['6007']
+                    pd = pmap['6001'] * pmap['6002'] * pmap['6007'] if not is_futures(ckey) else pmap['6001'] * pmap['6002'] 
                     logging.debug('PortfolioManager: recal_port: pos_tot_cost: %f' % pd)
                     return pd                   
                 
                 def pos_unreal_pl():
                     #(spot premium * multiplier - avgcost) * pos) 
-                    v = (gmap['5006'] * pmap['6007'] - pmap['6001']) * pmap['6002'] 
+                    if not is_futures(ckey):
+                        v = (gmap['5006'] * pmap['6007'] - pmap['6001']) * pmap['6002']
+                    else: 
+                        try:
+                            v = 0
+                            nkey = ckey.replace('MHI', 'HSI')
+                            data = self.r_conn.get(nkey)
+                            
+                            if data != None:
+                                #
+                                # (S - X) * pos * multiplier
+                                
+                                spot = json.loads(data)['4']
+                                v = (spot - pmap['6001']) * pmap['6007'] * pmap['6002']                         
+                        except:
+                            # there could be no data before market open
+                            # the look up for last price could have failed. 
+                            logging.error("PortfolioManager:pos_unreal_pl error: unable to calculate futures P/L!")
+                            
                     return v 
     
+                logging.debug('PortfolioManager: recal_port greeks market data %s->%s ' % (ckey, gmap))
+                logging.debug('PortfolioManager: recal_port position-map->%s' % (self.r_get(ckey)))
+                pmap = json.loads(self.r_get(ckey)) 
                 
     
                 #logging.debug('PortfolioManager: recal_port greeks %f' % pos_delta(gmap))
@@ -514,19 +727,18 @@ class PortfolioManager():
 
                 #t_pos_multiplier += (pmap['6002'] * pmap['6007'])
 
-                right = ckey.split('-')[3].lower()
-                pos_summary['delta_' + right] += pmap['6005']
-                pos_summary['delta_all'] += pmap['6005']
-                pos_summary['theta_' + right] += pmap['6006']
-                pos_summary['theta_all'] += pmap['6006']
-                pos_summary['unreal_pl'] += pmap['6008']
+                if not is_futures(ckey):
+                    right = ckey.split('-')[3].lower()
+                    pos_summary['delta_' + right] += pmap['6005']
+                    pos_summary['delta_all'] += pmap['6005']
+                    pos_summary['theta_' + right] += pmap['6006']
+                    pos_summary['theta_all'] += pmap['6006']
+                    pos_summary['unreal_pl'] += pmap['6008']
+                else:
+                    pos_summary['delta_f'] += pmap['6005']
+                    pos_summary['delta_all'] += pmap['6005']
+                    print "**** adding delta %f cum_delta_f %f cum_delta_all %f" % (pmap['6005'], pos_summary['delta_f'], pos_summary['delta_all'])
 
-                
-                
-                #pos_summary['delta_1percent'] += (pos_summary['delta_all'] / (pmap['6002'] * pmap['6007']))
-                # delta_1% = pos_ / (pos * multiplier)
-                
-                
                 #print 'con,right,avgcost,spot px,pos,delta,theta, pos_delta,pos_theta,pos_unreal_pl,last_updated'
 #                 print ( 'PT_entries: %s,%s,%f,%f,%f,%f,%f,%f,%f,%f,%s' % (ckey, right, pmap['6001'], gmap['5006'], pmap['6002'],\
 #                                                                      gmap['5002'],gmap['5004'],\
@@ -538,9 +750,13 @@ class PortfolioManager():
                 self.r_set(ckey, json.dumps(pmap))
                 
                 logging.debug('PortfolioManager: update position in redis %s' % self.r_get(ckey))
+ 
+            else: # greeks entry not found
                 
-            else:
                 l_skipped_pos.append(ckey)
+            
+           
+                
 
             
 #            self.r_set(ckey, json.dumps(pmap))
@@ -562,7 +778,10 @@ class PortfolioManager():
         pos_summary['entries_skipped'] = l_skipped_pos
         pos_summary['status'] = 'OK' if len(l_skipped_pos) == 0 else 'NOT_OK'
         #self.r_set(self.rs_port_keys['port_summary'], json.dumps(pos_summary) )
+        
         t_pos_summary = json.dumps(pos_summary)
+        
+        print "****** %s" % t_pos_summary
         self.r_conn.set(self.rs_port_keys['port_summary'], t_pos_summary )
         self.r_conn.set(self.rs_port_keys['port_items'], json.dumps(l_gmap))
         #print pos_summary
@@ -581,7 +800,7 @@ class PortfolioManager():
                         ','.join(' %s' % k for k in l_skipped_pos))
         
         return l_gmap
- 
+
 
     def construct_port(self, pos_msg):
         # port structure
@@ -610,7 +829,10 @@ class PortfolioManager():
         
 #         print toks
 #         print '---> %s' % s
-        self.port.append(s)
+        
+	# 2018.1.2 fix to discard duplicate position message entries
+	if s not in self.port:
+        	self.port.append(s)
                 
         ckey = options_data.ContractHelper.makeRedisKey(pos_msg.contract)
         multiplier = 50.0 if toks[0][1:] == 'HSI' else 10.0
@@ -668,9 +890,11 @@ if __name__ == '__main__':
     p.retrieve_position()
     print p.get_portfolio_summary()
     print p.get_tbl_pos_csv()
-    p.group_pos_by_strike_by_month()
-    print p.grouped_options
-    print p.get_grouped_options_str_array_stacked()
+    print "***********************"
+    print p.get_tbl_pos_list()
+#     p.group_pos_by_strike_by_month()
+#     print p.grouped_options
+#     print p.get_grouped_options_str_array_stacked()
 
     # sample ouput    
 # ["exch","type","contract_mth","right","strike","con_ration","pos","avgcost"],["HSI","OPT","20150828","C","22600",50.0,0.0000,0.0000,],["HSI","OPT","20150828","C","23000",50.0,-1.0000,1770.0000,],["HSI","OPT","20150828","C","23600",50.0,-2.0000,1470.0000,],["HSI","OPT","20150828","C","23800",50.0,-1.0000,920.0000,],["HSI","OPT","20150828","C","24000",50.0,-2.0000,1820.0000,],["HSI","OPT","20150828","C","24200",50.0,-1.0000,3120.0000,],["HSI","OPT","20150828","C","24800",50.0,-1.0000,220.0000,],["HSI","OPT","20150828","P","18000",50.0,-2.0000,1045.0000,],["HSI","OPT","20150828","P","18600",50.0,-1.0000,1120.0000,],["HSI","OPT","20150828","P","18800",50.0,-1.0000,1570.0000,],["HSI","OPT","20150828","P","19800",50.0,-1.0000,870.0000,],["HSI","OPT","20150828","P","20200",50.0,-1.0000,970.0000,],["HSI","OPT","20150828","P","20800",50.0,-2.0000,970.0000,],["HSI","OPT","20150828","P","21600",50.0,-1.0000,1570.0000,],["HSI","OPT","20150828","P","21800",50.0,-7.0000,1955.7143,],["HSI","OPT","20150828","P","23200",50.0,1.0000,25930.0000,],["HSI","OPT","20150929","C","24400",50.0,1.0000,24880.0000,],["HSI","OPT","20150929","P","21600",50.0,0.0000,0.0000,],["HSI","OPT","20150929","P","21800",50.0,2.0000,52713.3333,],["HSI","OPT","20150929","P","22600",50.0,3.0000,39763.3333,],["MHI","OPT","20150828","C","24400",10.0,-1.0000,2603.0000,],["MHI","OPT","20150828","P","20800",10.0,-1.0000,313.0000,],["MHI","OPT","20150828","P","21000",10.0,-1.0000,363.0000,],["MHI","OPT","20150828","P","23600",10.0,5.0000,4285.0000,],["MHI","OPT","20150929","C","24400",10.0,1.0000,4947.0000,],["MHI","OPT","20150929","P","21600",10.0,1.0000,12657.0000,],["MHI","OPT","20150929","P","22600",10.0,1.0000,9877.0000,],["MHI","OPT","20150929","P","23600",10.0,4.0000,7757.0000,],

BIN
finopt/portfolio.pyc


BIN
finopt/ystockquote.pyc


+ 2 - 2
html/opt-chains-tmpl.html

@@ -3,7 +3,7 @@
   <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
   <title> Trading Options Monitor </title>
     <script type="text/javascript" src="https://www.google.com/jsapi"></script>
-    <script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/mathjs/2.1.1/math.min.js"></script>
+    <script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/mathjs/3.18.1/math.min.js"></script>
     <script type="text/javascript">
       google.load("visualization", "1", {packages:["corechart"]});
       google.load('visualization', '1', {'packages':['table']});
@@ -228,7 +228,7 @@
     <div id="chartPremium" style="height: 350px; width: 850px"></div>
 <li>
 <label for=haxis_from>H-Axis Range Starts At:</label>
-<input type=range id=haxis_range min=10000 value=20000 max=25000 step=500>
+<input type=range id=haxis_range min=22000 value=28000 max=35000 step=500>
 <output id=haxis_from_value></output>
 </li>
 <h2> Implied volatilities for this and next month HSI options</h2>

+ 38 - 5
html/opt-pos-chart-stacked-tmpl.html

@@ -9,7 +9,7 @@
       google.setOnLoadCallback(drawChart);
       function drawChart() {
         var data = google.visualization.arrayToDataTable([
-          ['strike', 'Near-P', 'Near-C', 'Far-P', 'Far-C'],
+           ['strike', 'Near-P', 'Near-C', 'Far-P', 'Far-C','Near-F', 'Far-F'],
 {{{dataPCpos}}}
         ]);
 
@@ -49,13 +49,26 @@
 
        //var portTbl = new google.visualization.Table(document.getElementById('portTblDiv'));
 
+	var formatterColor = new google.visualization.ColorFormat();
+	formatterColor.addRange(-100, 0, 'white', 'red');
+	formatterColor.addRange(0, 100, 'white', 'blue');
+	formatterColor.format(dataTbl, 5); 
+
+	var formatterColor2 = new google.visualization.ColorFormat();
+	formatterColor2.addGradientRange(null, null, 'white', 'orange', 'blue');
+	formatterColor2.format(dataTbl, 10); 
+
 	var formatter = new google.visualization.NumberFormat({pattern:'0.00'});
-	for (var i = 2; i < 9; i++)
+	for (var i = 2; i < 12; i++){
 		formatter.format(dataTbl, i); 
+	}
         var options2 = {
           displayAnnotations: true,
 	  showRowNumber: true, width: '100%', height: '100%', allowHtml: true,
         };
+        var formatterBar = new google.visualization.BarFormat({width: 80,
+				colorPositive: 'green', max:100 });       
+        formatterBar.format(dataTbl, 11);
 	chartTbl.draw(dataTbl, options2);
 
 	$('input[id="b_reload"]').click();
@@ -68,6 +81,7 @@
 		var dataG = google.visualization.arrayToDataTable([
 		  ['Label', 'Value'],
 		  ['Delta', 0],
+		  ['Delta-F', 0],
 		  ['Delta-C', 0],
 		  ['Delta-P', 0]
 		]);
@@ -117,8 +131,9 @@
 				//alert(jdata.delta_all);
 				
 				dataG.setValue(0, 1, Math.round(jdata.delta_all*100)/100);
-				dataG.setValue(1, 1, Math.round(jdata.delta_c*100)/100);
-				dataG.setValue(2, 1, Math.round(jdata.delta_p*100)/100);
+				dataG.setValue(1, 1, Math.round(jdata.delta_f*100)/100);
+				dataG.setValue(2, 1, Math.round(jdata.delta_c*100)/100);
+				dataG.setValue(3, 1, Math.round(jdata.delta_p*100)/100);
 				gchart.draw(dataG, optionsG);
 
 				dataT.setValue(0, 1, Math.round(jdata.theta_all));
@@ -133,8 +148,26 @@
 
 		};
 
+		function isMarketOpen(now){
+			var hkex_mstart_hhmm = '0915';
+			var hkex_mend_hhmm = '1200';
+			var hkex_astart_hhmm = '1300';
+			var hkex_aend_hhmm = '1630';
+
+			var now_hhmm = ('0' + now.getHours()).slice(-2) + '' + ('0' + now.getMinutes()).slice(-2);
+			rc = ( 
+				(hkex_mstart_hhmm < now_hhmm && now_hhmm < hkex_mend_hhmm) || 
+				(hkex_astart_hhmm < now_hhmm && now_hhmm < hkex_aend_hhmm)
+		       	) ? true : false;
+			return rc;
+		}
+
 		setInterval(function() {
-			refreshPortSummary();
+			//var rc = isMarketOpen(new Date());
+			if (isMarketOpen(new Date())){
+			//if (rc){
+				refreshPortSummary();
+			}
 		}, 9500);    
 
 

BIN
misc2/__init__.pyc


+ 2 - 2
misc2/helpers.py

@@ -122,8 +122,8 @@ class ContractHelper(BaseHelper):
     def makeRedisKey(contract):
         #print "makerediskey %s" % ContractHelper.printContract(contract)
 #20150904        
-        #contract.m_strike = int(contract.m_strike)
-        contract.m_strike = contract.m_strike
+        contract.m_strike = int(contract.m_strike)
+        #contract.m_strike = contract.m_strike
         
         if contract.m_secType == 'OPT':
             s = '%s-%s-%s-%s' % (contract.m_symbol,

BIN
misc2/helpers.pyc


+ 1 - 1
sh/portfolio.sh

@@ -1,4 +1,4 @@
 #!/bin/bash
-ROOT=/home/larry/l1304/workspace/finopt/src
+ROOT=~/mchan927/finopt
 export PYTHONPATH=$ROOT
 python $ROOT/finopt/portfolio.py $ROOT/config/app.cfg

+ 3 - 3
sh/run_mds.sh

@@ -1,8 +1,8 @@
 #!/bin/bash
-ROOT=$FINOPT_HOME
-export PYTHONPATH=$FINOPT_HOME:$PYTHONPATH
+ROOT=~/mchan927/finopt
+export PYTHONPATH=$ROOT:$PYTHONPATH
 # real time mode
-python $FINOPT_HOME/cep/ib_mds.py $FINOPT_HOME/config/mds.cfg
+python $ROOT/cep/ib_mds.py $ROOT/config/mds.cfg
 # replay mode
 #python $FINOPT_HOME/cep/ib_mds.py -r $FINOPT_HOME/../data/mds_files/20151006 $FINOPT_HOME/config/mds.cfg
 

+ 4 - 2
sh/run_opt_serve.sh

@@ -1,4 +1,6 @@
 #!/bin/bash
-ROOT=$FINOPT_HOME
+ROOT=~/mchan927/finopt
 export PYTHONPATH=$ROOT
-python $ROOT/finopt/opt_serve.py $ROOT/config/app.cfg
+python $ROOT/finopt/opt_serve.py $ROOT/config/app.cfg & echo $! > $ROOT/opt_serve.pid
+
+echo $(cat $ROOT/opt_serve.pid)

+ 3 - 3
sh/run_options_data.sh

@@ -1,5 +1,5 @@
 #!/bin/bash
 #ROOT={replace-path}
-ROOT=~/l1304/workspace/finopt
-export PYTHONPATH=$ROOT/src
-python $ROOT/src/finopt/options_data.py $ROOT/src/config/app.cfg
+ROOT=~/mchan927/finopt
+export PYTHONPATH=$ROOT
+python $ROOT/finopt/options_data.py $ROOT/config/app.cfg