Browse Source

TGIF coding hero

bobhk 8 years ago
parent
commit
c883bdbf8b
4 changed files with 91 additions and 70 deletions
  1. 54 8
      src/rethink/portfolio_item.py
  2. 8 2
      src/rethink/portfolio_monitor.py
  3. 22 42
      src/ws/client_g.html
  4. 7 18
      src/ws/ws_server.py

+ 54 - 8
src/rethink/portfolio_item.py

@@ -163,10 +163,7 @@ class PortfolioItem():
                                 
                 pos_theta = 0
                 gamma_percent = 0
-<<<<<<< HEAD
-                
-=======
->>>>>>> branch 'ironfly' of https://github.com/laxaurus/finopt.git
+
                 # (S - X) * pos * multiplier
                 unreal_pl = (spot_px * multiplier - self.get_average_cost() ) * self.get_quantity() 
                                
@@ -193,7 +190,7 @@ class PortfolioItem():
         self.set_port_field(PortfolioItem.AVERAGE_COST, average_cost)
         if extra_info:
             self.set_port_field(PortfolioItem.MARKET_VALUE, extra_info['market_value'])
-        
+
         
         
     def dump(self):
@@ -211,7 +208,8 @@ class Portfolio(AbstractTableModel):
                            'header':{...},
                            'row_index': <curr_index>,
                            'ckey_to_row_index':{<contract_key>: <row_id>}, 
-                           'row_to_ckey_index':{<row_id>: <contract_key>}
+                           'row_to_ckey_index':{<row_id>: <contract_key>},
+                'port_v': port_v
                                             
              }   
                 
@@ -224,7 +222,10 @@ class Portfolio(AbstractTableModel):
     TOTAL_THETA_C   = 9012
     TOTAL_THETA_P   = 9013
     TOTAL_GAMMA_PERCENT = 9020
-    PUT_CALL_RATIO  = 9030
+    NUM_CALLS       = 9031
+    NUM_PUTS       = 9032
+    TOTAL_GAIN_LOSS = 9040
+    
      
     
     def __init__(self, account):
@@ -284,8 +285,53 @@ class Portfolio(AbstractTableModel):
         self.port['port_items'][contract_key].calculate_pl(contract_key)
         
     def calculate_port_pl(self):
+
+
+        p1_items = filter(lambda x: x[1].get_symbol_id() in PortfolioRules.rule_map['interested_position_types']['symbol'], self.port['port_items'].items())
+        p2_items = filter(lambda x: x[1].get_instrument_type() in  PortfolioRules.rule_map['interested_position_types']['instrument_type'], p1_items)
         
-        pass
+        port_v = {
+              Portfolio.TOTAL_DELTA     : 0.0,
+              Portfolio.TOTAL_DELTA_F   : 0.0,
+              Portfolio.TOTAL_DELTA_C   : 0.0,
+              Portfolio.TOTAL_DELTA_P   : 0.0,
+              Portfolio.TOTAL_THETA     : 0.0,
+              Portfolio.TOTAL_THETA_C   : 0.0,
+              Portfolio.TOTAL_THETA_P   : 0.0,
+              Portfolio.TOTAL_GAMMA_PERCENT : 0.0,
+              Portfolio.NUM_CALLS       : 0,
+              Portfolio.NUM_PUTS       : 0,
+              Portfolio.TOTAL_GAIN_LOSS : 0.0
+              
+            } 
+        def cal_port(x_tuple):
+    
+            x = x_tuple[1]
+            if x.get_right() == 'C':
+                port_v[Portfolio.TOTAL_DELTA_C] += x.get_port_field(PortfolioItem.POSITION_DELTA)
+                port_v[Portfolio.TOTAL_THETA_C] += x.get_port_field(PortfolioItem.POSITION_THETA)
+                ##
+                # hard coded logic
+                #
+                port_v[Portfolio.NUM_CALLS] += (
+                    x.get_quantity() * PortfolioRules.rule_map['option_structure'][x.get_symbol_id()]['multiplier'] / 50)
+
+            elif x.get_right() == 'P':
+                port_v[Portfolio.TOTAL_DELTA_P] += x.get_port_field(PortfolioItem.POSITION_DELTA)
+                port_v[Portfolio.TOTAL_THETA_P] += x.get_port_field(PortfolioItem.POSITION_THETA)
+                port_v[Portfolio.NUM_PUTS] += (
+                    x.get_quantity() * PortfolioRules.rule_map['option_structure'][x.get_symbol_id()]['multiplier'] / 50)
+            elif x.get_instrument_type() == 'FUT':
+                port_v[Portfolio.TOTAL_DELTA_F] += x.get_port_field(PortfolioItem.POSITION_DELTA)
+                
+            port_v[Portfolio.TOTAL_DELTA] += x.get_port_field(PortfolioItem.POSITION_DELTA)
+            port_v[Portfolio.TOTAL_THETA] += x.get_port_field(PortfolioItem.POSITION_THETA)
+            port_v[Portfolio.TOTAL_GAIN_LOSS] += x.get_port_field(PortfolioItem.UNREAL_PL)
+            port_v[Portfolio.TOTAL_GAMMA_PERCENT] += x.get_port_field(PortfolioItem.GAMMA_PERCENT)
+            
+        map(cal_port, p2_items)            
+        self.port['port_v'] = port_v 
+        return self.port['port_v']
 
     def dump_portfolio(self):
         #<account_id>: {'port_items': {<contract_key>, instrument}, 'opt_chains': {<oc_id>: option_chain}}

+ 8 - 2
src/rethink/portfolio_monitor.py

@@ -2,11 +2,10 @@
 import sys, traceback
 import logging
 import json, threading
-import time, datetime
 import copy
 from optparse import OptionParser
 from time import sleep
-from misc2.observer import Subscriber, Publisher
+import time
 from misc2.helpers import ContractHelper
 from finopt.instrument import Symbol, Option
 from rethink.option_chain import OptionsChain
@@ -88,6 +87,7 @@ class PortfolioMonitor(AbstractGatewayListener, AbstractPortfolioTableModelListe
                     elif selection == '2': 
                         for port in self.portfolios.values():
                             print port.dump_portfolio()
+                            print ''.join('%d:[%6.2f]\n' % (k, v) for k, v in port.calculate_port_pl().iteritems())
                     elif selection == '3': 
                         
                         print self.tds.dump()
@@ -186,6 +186,12 @@ class PortfolioMonitor(AbstractGatewayListener, AbstractPortfolioTableModelListe
             port_item.update_position(position, average_cost, extra_info)
             port_item.calculate_pl(contract_key)
             
+            # if the function call is triggered by accountUpdates from TWS
+            # (that is extra_info is not null)
+            if extra_info:
+                logging.info('PortfolioMonitor:process_position Recal overall port figures...')
+                port.calculate_port_pl()
+                
             
             # dispatch the update to internal listeners
             # and also send out the kafka message to external parties

+ 22 - 42
src/ws/client_g.html

@@ -8,7 +8,7 @@
 </head>
 
 <body>
-   <div id="table_div" style="height:500"></div>
+   <div id="table_div" style="height:600"></div>
    <button id="change-btn">change columns</button>
    <button id="test-btn">test</button>
   <form onsubmit="onSubmit(); return false;">
@@ -25,7 +25,9 @@
 	var view = null;
 	var data = null;
 	var table= null;   
-    var options = {allowHtml: true, sortColumn:1, showRowNumber: true, width: '100%', height: '100%'};
+    var options = {allowHtml: true, sortColumn:1, 
+    		showRowNumber: true, width: '100%', height: '100%'};
+    
 	google.load("visualization", "1.1", {packages:["corechart", 'table','gauge']});
 	   //google.setOnLoadCallback(drawTable);
 	google.setOnLoadCallback(init);
@@ -56,34 +58,22 @@
     	var colorF = new google.visualization.ColorFormat();
     	colorF.addRange(-100, 0, 'white', 'red');
     	colorF.addRange(0, 100, 'white', 'blue');
-<<<<<<< HEAD
-
 
-	var colorGF = new google.visualization.ColorFormat();
-	colorGF.addGradientRange(null, null, 'white', 'orange', 'blue');
 
-    	 	    
-	    numF.format(data, 2);  //avg cost
-	    numF.format(data, 3);  //market value
-	    colorF.format(data, 6); // position
-	    percentF.format(data, 7); //delta		
-	    
-	    numF.format(data, 10); // position delta
-	    numF.format(data, 11); // position theta
-	    numF.format(data, 12); // position gamma
-	    colorGF.format(data, 13); //unreal p/l
-=======
-    	 	    
-	    
-	    numF.format(data, 3);  //market value
-	    colorF.format(data, 6); // position
-	    percentF.format(data, 7); //delta		
-	    percentF.format(data, 8); //theta    
-	    numF.format(data, 10); // position delta
-	    numF.format(data, 11); // position theta
-	    numF.format(data, 13); //unreal p/l
->>>>>>> branch 'ironfly' of https://github.com/laxaurus/finopt.git
-	    barF.format(data, 14) //% gain loss
+		var colorGF = new google.visualization.ColorFormat();
+		colorGF.addGradientRange(null, null, 'white', 'orange', 'blue');
+	
+	    	 	    
+		    numF.format(data, 2);  //avg cost
+		    numF.format(data, 3);  //market value
+		    colorF.format(data, 6); // position
+		    percentF.format(data, 7); //delta		
+		    
+		    numF.format(data, 10); // position delta
+		    numF.format(data, 11); // position theta
+		    numF.format(data, 12); // position gamma
+		    colorGF.format(data, 13); //unreal p/l
+		    barF.format(data, 14) //% gain loss
 		
 	}	   
 	   
@@ -111,17 +101,10 @@
 			console.log(d1);
 			data = new google.visualization.DataTable(d1.value);
 			view = new google.visualization.DataView(data);
-<<<<<<< HEAD
+
 			view.setRows(view.getFilteredRows([{column: 15, test: function(value, row, column, table) {
-=======
-			/*view.setRows(view.getFilteredRows([{column: 14, test: function(value, row, column, table) {
->>>>>>> branch 'ironfly' of https://github.com/laxaurus/finopt.git
-        return (value == 'HSI' || value == 'MHI') 
-<<<<<<< HEAD
-    }}]));
-=======
-    }}]));*/
->>>>>>> branch 'ironfly' of https://github.com/laxaurus/finopt.git
+		        return (value == 'HSI' || value == 'MHI') 
+		    }}]));
     		setupFormatter(data);
 			table = new google.visualization.Table(document.getElementById('table_div'));
 			table.draw(view, options);
@@ -129,7 +112,7 @@
            
         } else if (d1.event == 'event_tm_table_row_updated'){
 
-			//console.log(d1.value.row.toString()+ ':' + d1.value.row_values[0]['v']);
+			console.log(d1.value.row.toString()+ ':' + d1.value.row_values[0]['v']);
 			for (var c=2; c < d1.value.row_values.length; c++){
 				data.setCell(d1.value.row, c, d1.value.row_values[c]["v"]);
 
@@ -140,7 +123,6 @@
 			table.draw(view, options);
 //			table.draw(data);           
 
-<<<<<<< HEAD
         } else if (d1.event == 'event_tm_table_row_inserted'){
         	var newRow = d1.value.row_values.map(function(x){
         		return x['v'];
@@ -149,8 +131,6 @@
         	data.addRow(newRow);
         	options.sortColumn = table.getSortInfo().column;
         	table.draw(view, options);
-=======
->>>>>>> branch 'ironfly' of https://github.com/laxaurus/finopt.git
         }
         
       };

File diff suppressed because it is too large
+ 7 - 18
src/ws/ws_server.py


Some files were not shown because too many files changed in this diff