Skip to content

IBrokers Risk Management Backend Solution Help with twsPortfolioValue

8 messages · Gei Lin, G See, JohnnyPaper +1 more

#
Hi Everyone,

I have a couple of questions to ask, and I absolutely don't mind if this
gets resubmitted anywhere else.  It seems as though this may be helpful for
many people trying to manage portfolio risk with IBrokers, which as I may
add is an excellent addition to R.  Very nice work on Jeff's part, and many
many thanks.

I am just trying to keep a loop monitoring my position and shutting them
down if they hit a stop or profit target based on my position value.  Mind
you I am submitting these orders after my offline analysis is done at the
EOD.  So they are market orders executed at the open, hence the reason for
management of the portfolio in this sense through the twsPortfolioValue
updates in the data.frame .

Here is the code I am using and the results:

con <- twsConnect()

while (TRUE){
    Offset<-50
    Val<-twsPortfolioValue(reqAccountUpdates(con),zero.pos=FALSE)
        for (i in 1:nrow(Val)){
            if ( 0.01 * -abs(Val[i,4]) > Val[i,8] ){
                if (Val[i,6] < 0){
                    IBrokers:::.placeOrder( con, twsSTK(toString(Val[i,1])),
twsOrder((i+Offset),"BUY",abs(Val[i,6]),"MKT") )
                    Offset<- Offset +1
                } else if (Val[i,6] > 0){
                    IBrokers:::.placeOrder( con, twsSTK(toString(Val[i,1])),
twsOrder((i+Offset),"SELL",abs(Val[i,6]),"MKT") )
                    Offset<- Offset +1
                }
            } else if (    0.03 * abs(Val[i,4]) < Val[i,8] ){
                if (Val[i,6] < 0){
                    IBrokers:::.placeOrder( con, twsSTK(toString(Val[i,1])),
twsOrder((i+Offset),"BUY",abs(Val[i,6]),"MKT") )
                    Offset<- Offset +1
                } else if (Val[i,6] > 0){
                    IBrokers:::.placeOrder( con, twsSTK(toString(Val[i,1])),
twsOrder((i+Offset),"SELL",abs(Val[i,6]),"MKT") )
                    Offset<- Offset +1
                }
            }
        }
    print(Val)
    Sys.sleep(5)
}

2 -1 2104 Market data farm connection is OK:usfarm
2 -1 2106 HMDS data farm connection is OK:ushmds
   local sectype marketValue averageCost        return position realizedPNL
unrealizedPNL
2   AKAM     STK    -8022.18   -8011.965 -0.0012749681     -227           0       
-10.22
6   ETFC     STK    -7964.32   -7987.240  0.0028695755     -728           0        
22.92
8   FISV     STK    -8048.00   -7994.000 -0.0067550663     -100           0       
-54.00
9     GS     STK    -8006.97   -7985.040 -0.0027463856      -53           0       
-21.93
10   HAR     STK    -8066.78   -8015.330 -0.0064189493     -177           0       
-51.45
11   HNZ     STK    -7987.07   -7990.070  0.0003754658     -131           0         
3.00
12   ICE     STK     8047.89    8042.140  0.0007149839       54           0         
5.75
14  MOLX     STK    -8024.33   -8004.405 -0.0024892541     -291           0       
-19.92
15   MRK     STK    -8017.43   -8007.650 -0.0012213320     -195           0        
-9.78
16   MWV     STK     8053.07    8009.890  0.0053908356      254           0        
43.18
19   OXY     STK    -8041.22   -8027.020 -0.0017690250      -91           0       
-14.20
21  SIAL     STK     8081.32    8013.160  0.0085060074      104           0        
68.16
23   VFC     STK    -7962.50   -8028.320  0.0081984775      -52           0        
65.82
25   ZMH     STK    -8115.41   -8060.680 -0.0067897497     -107           0       
-54.73

2 -1 2100 API client has been unsubscribed from account data.
   local sectype marketValue averageCost        return position realizedPNL
unrealizedPNL
2   AKAM     STK    -8022.18   -8011.965 -0.0012749681     -227           0       
-10.22
6   ETFC     STK    -7964.32   -7987.240  0.0028695755     -728           0        
22.92
8   FISV     STK    -8048.00   -7994.000 -0.0067550663     -100           0       
-54.00
9     GS     STK    -8006.97   -7985.040 -0.0027463856      -53           0       
-21.93
10   HAR     STK    -8066.78   -8015.330 -0.0064189493     -177           0       
-51.45
11   HNZ     STK    -7987.07   -7990.070  0.0003754658     -131           0         
3.00
12   ICE     STK     8047.89    8042.140  0.0007149839       54           0         
5.75
14  MOLX     STK    -8024.33   -8004.405 -0.0024892541     -291           0       
-19.92
15   MRK     STK    -8017.43   -8007.650 -0.0012213320     -195           0        
-9.78
16   MWV     STK     8053.07    8009.890  0.0053908356      254           0        
43.18
19   OXY     STK    -8041.22   -8027.020 -0.0017690250      -91           0       
-14.20
21  SIAL     STK     8081.32    8013.160  0.0085060074      104           0        
68.16
23   VFC     STK    -7962.50   -8028.320  0.0081984775      -52           0        
65.82
25   ZMH     STK    -8115.41   -8060.680 -0.0067897497     -107           0       
-54.73


The main issue that I am having is the connection gets shut down after the
first query where I am getting Val populated so that I can monitor the
positions and take care of orders as need be.  There is the 2100 error
message after the first query...you can see it is shut down. So my question
is this... What is it I need to change for the socket to remain open and
this loop to stay in tact throughout the trading day?  (Also as a side...is
there any way to get around the box that pops up asking to "Allow incoming
API connections" in IB that you may have found?)

Thanks very much for any help to get this issue resolved.

Kind Regards,

Brad



--
View this message in context: http://r.789695.n4.nabble.com/IBrokers-Risk-Management-Backend-Solution-Help-with-twsPortfolioValue-tp4658101.html
Sent from the Rmetrics mailing list archive at Nabble.com.
#
To get around the dialog box for incoming connections make sure the TWS is set with the local host being trusted 127.0.0.1, this will stop it from asking since the request is coming from your local host.

Sent from my iPhone
On 10 Feb 2013, at 18:33, JohnnyPaper <brad.saterfiel at gmail.com> wrote:
Hi Everyone,

I have a couple of questions to ask, and I absolutely don't mind if this
gets resubmitted anywhere else.  It seems as though this may be helpful for
many people trying to manage portfolio risk with IBrokers, which as I may
add is an excellent addition to R.  Very nice work on Jeff's part, and many
many thanks.

I am just trying to keep a loop monitoring my position and shutting them
down if they hit a stop or profit target based on my position value.  Mind
you I am submitting these orders after my offline analysis is done at the
EOD.  So they are market orders executed at the open, hence the reason for
management of the portfolio in this sense through the twsPortfolioValue
updates in the data.frame .

Here is the code I am using and the results:

con <- twsConnect()

while (TRUE){
   Offset<-50
   Val<-twsPortfolioValue(reqAccountUpdates(con),zero.pos=FALSE)
       for (i in 1:nrow(Val)){
           if ( 0.01 * -abs(Val[i,4]) > Val[i,8] ){
               if (Val[i,6] < 0){
                   IBrokers:::.placeOrder( con, twsSTK(toString(Val[i,1])),
twsOrder((i+Offset),"BUY",abs(Val[i,6]),"MKT") )
                   Offset<- Offset +1
               } else if (Val[i,6] > 0){
                   IBrokers:::.placeOrder( con, twsSTK(toString(Val[i,1])),
twsOrder((i+Offset),"SELL",abs(Val[i,6]),"MKT") )
                   Offset<- Offset +1
               }
           } else if (    0.03 * abs(Val[i,4]) < Val[i,8] ){
               if (Val[i,6] < 0){
                   IBrokers:::.placeOrder( con, twsSTK(toString(Val[i,1])),
twsOrder((i+Offset),"BUY",abs(Val[i,6]),"MKT") )
                   Offset<- Offset +1
               } else if (Val[i,6] > 0){
                   IBrokers:::.placeOrder( con, twsSTK(toString(Val[i,1])),
twsOrder((i+Offset),"SELL",abs(Val[i,6]),"MKT") )
                   Offset<- Offset +1
               }
           }
       }
   print(Val)
   Sys.sleep(5)
}

2 -1 2104 Market data farm connection is OK:usfarm
2 -1 2106 HMDS data farm connection is OK:ushmds
  local sectype marketValue averageCost        return position realizedPNL
unrealizedPNL
2   AKAM     STK    -8022.18   -8011.965 -0.0012749681     -227           0       
-10.22
6   ETFC     STK    -7964.32   -7987.240  0.0028695755     -728           0        
22.92
8   FISV     STK    -8048.00   -7994.000 -0.0067550663     -100           0       
-54.00
9     GS     STK    -8006.97   -7985.040 -0.0027463856      -53           0       
-21.93
10   HAR     STK    -8066.78   -8015.330 -0.0064189493     -177           0       
-51.45
11   HNZ     STK    -7987.07   -7990.070  0.0003754658     -131           0         
3.00
12   ICE     STK     8047.89    8042.140  0.0007149839       54           0         
5.75
14  MOLX     STK    -8024.33   -8004.405 -0.0024892541     -291           0       
-19.92
15   MRK     STK    -8017.43   -8007.650 -0.0012213320     -195           0        
-9.78
16   MWV     STK     8053.07    8009.890  0.0053908356      254           0        
43.18
19   OXY     STK    -8041.22   -8027.020 -0.0017690250      -91           0       
-14.20
21  SIAL     STK     8081.32    8013.160  0.0085060074      104           0        
68.16
23   VFC     STK    -7962.50   -8028.320  0.0081984775      -52           0        
65.82
25   ZMH     STK    -8115.41   -8060.680 -0.0067897497     -107           0       
-54.73

2 -1 2100 API client has been unsubscribed from account data.
  local sectype marketValue averageCost        return position realizedPNL
unrealizedPNL
2   AKAM     STK    -8022.18   -8011.965 -0.0012749681     -227           0       
-10.22
6   ETFC     STK    -7964.32   -7987.240  0.0028695755     -728           0        
22.92
8   FISV     STK    -8048.00   -7994.000 -0.0067550663     -100           0       
-54.00
9     GS     STK    -8006.97   -7985.040 -0.0027463856      -53           0       
-21.93
10   HAR     STK    -8066.78   -8015.330 -0.0064189493     -177           0       
-51.45
11   HNZ     STK    -7987.07   -7990.070  0.0003754658     -131           0         
3.00
12   ICE     STK     8047.89    8042.140  0.0007149839       54           0         
5.75
14  MOLX     STK    -8024.33   -8004.405 -0.0024892541     -291           0       
-19.92
15   MRK     STK    -8017.43   -8007.650 -0.0012213320     -195           0        
-9.78
16   MWV     STK     8053.07    8009.890  0.0053908356      254           0        
43.18
19   OXY     STK    -8041.22   -8027.020 -0.0017690250      -91           0       
-14.20
21  SIAL     STK     8081.32    8013.160  0.0085060074      104           0        
68.16
23   VFC     STK    -7962.50   -8028.320  0.0081984775      -52           0        
65.82
25   ZMH     STK    -8115.41   -8060.680 -0.0067897497     -107           0       
-54.73


The main issue that I am having is the connection gets shut down after the
first query where I am getting Val populated so that I can monitor the
positions and take care of orders as need be.  There is the 2100 error
message after the first query...you can see it is shut down. So my question
is this... What is it I need to change for the socket to remain open and
this loop to stay in tact throughout the trading day?  (Also as a side...is
there any way to get around the box that pops up asking to "Allow incoming
API connections" in IB that you may have found?)

Thanks very much for any help to get this issue resolved.

Kind Regards,

Brad



--
View this message in context: http://r.789695.n4.nabble.com/IBrokers-Risk-Management-Backend-Solution-Help-with-twsPortfolioValue-tp4658101.html
Sent from the Rmetrics mailing list archive at Nabble.com.

_______________________________________________
R-SIG-Finance at r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-sig-finance
-- Subscriber-posting only. If you want to post, subscribe first.
-- Also note that this is not the r-help list where general R questions should go.
#
Hi Gabe,

Thanks for the fast reply...I will definitely get that under control after
the forex opens up here in a bit.  Should this be the type of fix that would
allow me to continuously open and close the connection to IB so that I can
1) Open the connection, 2) Get a snapshot, 3) Close the connection ,4)Pause
for a couple of seconds, reopen the connection 5)Do anlysis and close orders
if need be, and 6)repeat?  As long as I am opening and closing the
connection that should be ok right? All I am trying to do is maintain a
portfolio monitor on my positions and send in market orders to close
positions once thresholds are hit one way or the other.  I'm also trying to
work out in my head how this will function in a while loop.  There seems
like there should be an easy fix to all of this.  However, I wasn't able to
see any other mentions of this type of order management or examples
anywhere.

Kind Regards,

Brad



--
View this message in context: http://r.789695.n4.nabble.com/IBrokers-Risk-Management-Backend-Solution-Help-with-twsPortfolioValue-tp4658101p4658106.html
Sent from the Rmetrics mailing list archive at Nabble.com.
#
I don't think the socket connection is shut down.

R> invisible(reqAccountUpdates(con))
2 -1 2100 API client has been unsubscribed from account data.
R> isConnected(con)
[1] TRUE

Why does your loop break?  Do you get an error in R?

The 2100 message is a warning
http://www.interactivebrokers.com/php/apiUsersGuide/apiguide/tables/api_message_codes.htm

Garrett
On Sun, Feb 10, 2013 at 12:33 PM, JohnnyPaper <brad.saterfiel at gmail.com> wrote:
#
Hi Garrett,

I suppose I was assuming that since the 2104 and 2106 messages were coming
and then the 2100 message was next and it said that I was unsubscribed to
account data after every successive attempt to query the portfolio value (as
well from Friday I remember that it looked to me as though the portfolio
data wasn't' changing in each successive query posted to the R console as it
was on the TWS display) .  So if the connection isn't getting closed, can
you see any type of solution in the code to work in so that I am getting
updated portfolio information to perform the risk checks?  I really
appreciate the help.  I'm sure there is some sort of small change that needs
to be made and things will run just fine.  This really is the last step for
me to get things nearly fully automated, and I am extremely excited to do
so.

Kind Regards,

Brad



--
View this message in context: http://r.789695.n4.nabble.com/IBrokers-Risk-Management-Backend-Solution-Help-with-twsPortfolioValue-tp4658101p4658109.html
Sent from the Rmetrics mailing list archive at Nabble.com.
#
I don't recall this as "fact" per se, but in my experience the account updates aren't updated as they happen. It's more of a when IB wants to send/update. 

I've typically watched the risk from the market data feed (reqMktData or reqRealTimeBars)

HTH
Jeff

Jeffrey Ryan    |    Founder    |    jeffrey.ryan at lemnica.com

www.lemnica.com
On Feb 10, 2013, at 1:21 PM, JohnnyPaper <brad.saterfiel at gmail.com> wrote:

            
2 days later
#
Hi Everyone,

Ok so I have pretty much thoroughly (at least to my knowledge) tested a
couple of ways to get this solution under control.  However, I cannot seem
to get around the problems of the code executing more than 1 order which
seems very strange to me.  As I have mentioned in earlier posts, this is
what I need to have manage the positions.  So what I did was try and create
a function to manage a futures position (ES only), which can currently be
tried out in paper at this moment.  Please, will someone just help me finish
up this solution so that I can move forward.  I really am trying here.  As
well, Jeff (if you read this) I have sent you an email at lemnica.  

Here is the code.

tws<-twsConnect()

OrderStatesFutures<-function(twsConnection,StopVal,ProfitVal){
Vals<-twsPortfolioValue(reqAccountUpdates(twsConnection),zero.pos=FALSE)
if (nrow(Vals) != 0){
ManagementData<-matrix(0,nrow(Vals),8)
	for(i in 1:nrow(Vals)){
		if (substr(Vals[i,1],1,2) == "ES"){
			FillPrice<-abs(Vals[i,4]/(Vals[i,6]))/50
		}
	
ManagementData[i,1:4]<-cbind(toString(substr(Vals[i,1],1,2)),toString(Vals[i,2]),toString(abs(Vals[i,6])),FillPrice)
			if (Vals[i,6] < 0){
				ManagementData[i,5]<-round(FillPrice*(1+StopVal),digits=2)
				ManagementData[i,6]<-round(FillPrice*(1-ProfitVal),digits=2)
				ManagementData[i,7]<-("SHORT")
				ManagementData[i,8]<-("BUY")
			} else if (Vals[i,6] >0){
				ManagementData[i,5]<-round(FillPrice*(1-StopVal),digits=2)
				ManagementData[i,6]<-round(FillPrice*(1+ProfitVal),digits=2)
				ManagementData[i,7]<-("LONG")
				ManagementData[i,8]<-("SELL")
			}
	}

colnames(ManagementData)<-c("Stock","IBType","NumShares","FillPrice","StopPrice","ProfitTarget","Currently","ToClose")
	return(ManagementData)
}
}

OSFutures<-OrderStatesFutures(tws,.00025,.00025)

while(TRUE){
	Flag<-1
	if ( nrow(OSFutures) != 0){
	Ding1<-reqMktData(tws,
twsFUT("ES","GLOBEX","201303"),eventWrapper=eWrapper.data(1),snapshot=TRUE)	
	PositionMonitor<-cbind(OSFutures,Ding1[,7]);print(PositionMonitor)
		for (i in 1:nrow(PositionMonitor)){
			if( Flag == 1 & PositionMonitor[i,7] == "LONG" & (PositionMonitor[i,9] <=
PositionMonitor[i,5])){
			
IBrokers:::.placeOrder(tws,twsFUT(PositionMonitor[i,1],"GLOBEX","201303"),twsOrder(Offset,"SELL",PositionMonitor[i,3],"MKT"))
				Flag<-2
				Offset<-Offset + 1
				#Sys.sleep(1)
				#break
			} else if ( Flag == 1 & PositionMonitor[i,7] == "LONG" &
(PositionMonitor[i,9] >= PositionMonitor[i,6])){
			
IBrokers:::.placeOrder(tws,twsFUT(PositionMonitor[i,1],"GLOBEX","201303"),twsOrder(Offset,"SELL",PositionMonitor[i,3],"MKT"))
				Flag<-2
				Offset<-Offset + 1
				#Sys.sleep(1)
				#break
			} else if ( Flag == 1 & PositionMonitor[i,7] == "SHORT" &
(PositionMonitor[i,9] >= PositionMonitor[i,5])){
			
IBrokers:::.placeOrder(tws,twsFUT(PositionMonitor[i,1],"GLOBEX","201303"),twsOrder(Offset,"BUY",PositionMonitor[i,3],"MKT"))
				Flag<-2
				Offset<-Offset + 1
				#Sys.sleep(1)
				#break
			} else if ( Flag == 1 &  PositionMonitor[i,7] == "SHORT" &
(PositionMonitor[i,9] <= PositionMonitor[i,6])){
			
IBrokers:::.placeOrder(tws,twsFUT(PositionMonitor[i,1],"GLOBEX","201303"),twsOrder(Offset,"BUY",PositionMonitor[i,3],"MKT"))
				Flag<-2
				Offset<-Offset + 1
				#Sys.sleep(1)
				#break
			}
			#break
		}
	
	}
	Sys.sleep(1)
	OSFutures<-OrderStatesFutures(tws,.00025,.00025)
	if(nrow(OSFutures) == 0){
		break
	}
}


I'd seriously like to thank anyone with some input to help me get this
solved.

Best to All,

Brad



--
View this message in context: http://r.789695.n4.nabble.com/IBrokers-Risk-Management-Backend-Solution-Help-with-twsPortfolioValue-tp4658101p4658357.html
Sent from the Rmetrics mailing list archive at Nabble.com.
#
Hi Everyone,

Shame on me.  A couple of things: 1) I left out a key as.numeric() variable
coercion, and 2) the Sys.sleep(1) seems to be very important.  However, I
was able to have it run as it was seemingly intended with both the ES and NQ
contracts traded at the same time.  I have updated the code for the equities
trading tomorrow.  Hopefully everything is rather smooth.  

Thanks again for all the help.

Kind Regards,

Brad



--
View this message in context: http://r.789695.n4.nabble.com/IBrokers-Risk-Management-Backend-Solution-Help-with-twsPortfolioValue-tp4658101p4658371.html
Sent from the Rmetrics mailing list archive at Nabble.com.