
    'iS                        d dl mZmZmZmZ d dlZd dlmZ d dlmZmZm	Z	 d dl
Z
d dlZd dlZd dlmZ d dlmZ d dlmZmZmZmZmZmZmZ d dlmZmZmZmZm Z  d dl!m"Z" d d	l#m$Z$ d d
l%m&Z& d dl'm(Z( d dl)m*Z*m+Z+ d d	l#m$Z$ eZ G d de,      Z- G d deej\                  j0                  j0                        Z/ G d de$      Z0 G d dejb                        Z2 G d d ee2e            Z3y)    )absolute_importdivisionprint_functionunicode_literalsN)copy)datedatetime	timedelta)DataBase)	TimeFramenum2datedate2num
BrokerBaseOrder	OrderBase	OrderData)bytesbstrwith_metaclassqueueMAXFLOAT)
MetaParams)CommInfoBase)Position)ibstore)AutoDictAutoOrderedDictc                        e Zd Zg dZd Zd Zy)IBOrderState)	status
initMarginmaintMarginequityWithLoan
commissionminCommissionmaxCommissioncommissionCurrencywarningTextc           	      ^    | j                   D ]  }d|z   }t        | |t        ||               y )Nm_)_fieldssetattrgetattr)self
orderstateffnames       Y/var/www/app/trading-bot/venv/lib/python3.12/site-packages/backtrader/brokers/ibbroker.py__init__zIBOrderState.__init__5   s1     	=A1HED%U!;<	=    c           
         t               }|j                  d       | j                  D ]@  }d|z   }|j                  dj                  |j	                         t        | |                   B |j                  d       dj                  |      S )Nz--- ORDERSTATE BEGINr*   z{}: {}z--- ORDERSTATE END
)listappendr+   format
capitalizer-   join)r.   txtr0   r1   s       r2   __str__zIBOrderState.__str__:   su    f

)* 	NA1HEJJxq||~wtU7KLM	N 	

'(yy~r4   N)__name__
__module____qualname__r+   r3   r=    r4   r2   r   r   /   s    4G=
r4   r   c                   <    e Zd ZdZ fdZd ed      ej                   ed      ej                   ed      ej                   ed      ej                   ed      ej                   ed      ej                   ed	      ej                   ed
      iZ fdZ xZS )IBOrdera	  Subclasses the IBPy order to provide the minimum extra functionality
    needed to be compatible with the internally defined orders

    Once ``OrderBase`` has processed the parameters, the __init__ method takes
    over to use the parameter values and set the appropriate values in the
    ib.ext.Order.Order object

    Any extra parameters supplied with kwargs are applied directly to the
    ib.ext.Order.Order object, which could be used as follows::

      Example: if the 4 order execution types directly supported by
      ``backtrader`` are not enough, in the case of for example
      *Interactive Brokers* the following could be passed as *kwargs*::

        orderType='LIT', lmtPrice=10.0, auxPrice=9.8

      This would override the settings created by ``backtrader`` and
      generate a ``LIMIT IF TOUCHED`` order with a *touched* price of 9.8
      and a *limit* price of 10.0.

    This would be done almost always from the ``Buy`` and ``Sell`` methods of
    the ``Strategy`` subclass being used in ``Cerebro``
    c                 D   t         t        |          }|g}|j                  dj	                  | j
                               |j                  dj	                  | j                               |j                  dj	                  | j                               |j                  dj	                  | j                               |j                  dj	                  | j                               |j                  dj	                  | j                               |j                  dj	                  | j                               |j                  dj	                  | j                               |j                  d	j	                  | j                               d
j                  |      S )zRGet the printout from the base class and add some ib.Order specific
        fieldszRef: {}zorderId: {}z
Action: {}zSize (ib): {}zLmt Price: {}zAux Price: {}zOrderType: {}zTif (Time in Force): {}zGoodTillDate: {}r6   )superrC   r=   r8   r9   ref	m_orderIdm_actionm_totalQuantity
m_lmtPrice
m_auxPricem_orderTypem_tifm_goodTillDater;   )r.   basetxttojoin	__class__s      r2   r=   zIBOrder.__str__]   s%    .0i&&txx01m**4>>:;l))$--89o,,T-A-ABCo,,T__=>o,,T__=>o,,T-=-=>?/66tzzBC(//0C0CDEyy  r4   NMKTLMTMOCSTPSTPLMTTRAILzTRAIL LIMITc                 
   d| _         |dk(  r| j                  n| j                  | _        t        t
        |           t        j                  j                  j                  j                  |        | j                  | j                     | _        d| _        t        |      | _        d| _        d| _        | j                  | j$                  k(  rn| j                  | j&                  k(  rnl| j                  | j(                  k(  r| j*                  | _        n@| j                  | j,                  k(  r| j*                  | _        n| j                  | j.                  k(  r#| j0                  | _        | j*                  | _        n| j                  | j2                  k(  r?| j4                  | j4                  | _        n| j6                  | j6                  dz  | _        n| j                  | j:                  k(  rg| j*                  x| _        | _        | j0                  | _        | j4                  | j4                  | _        n | j6                  | j6                  dz  | _        t?        | j@                        | _!        | jD                  | _#        | jH                  | jH                  jJ                  | _&        | jN                  d}ntQ        | jN                  tR        tT        f      r,d}t        | jN                  jW                  d            | _,        ntQ        | jN                  tZ        f      r_| jN                  | j\                  k(  rd	}nd}tS        j^                         | jN                  z   }t        |jW                  d            | _,        nH| jN                  dk(  rd	}n6d}ta        | jN                        }t        |jW                  d            | _,        t        |      | _1        d
| _2        |D ]#  }tg        | ti        | |       dz  |z   ||          % y )NFBUYr           g      Y@GTCGTDz%Y%m%d %H:%M:%SDAY   r*   )5_willexpireBuySellordtyperE   rC   r3   ibextr   _IBOrdTypesexectyperL   m_permidr   rH   rJ   rK   MarketCloseLimitpriceStop	StopLimit
pricelimit	StopTrailtrailamounttrailpercentm_trailingPercentStopTrailLimitm_trailStopPriceabssizerI   transmit
m_transmitparentrG   
m_parentIdvalid
isinstancer	   r   strftimerN   r
   r]   nowr   rM   	m_ocaTyper,   hasattr)r.   actionkwargstifr{   krQ   s         r2   r3   zIBOrder.__init__y   s   
 !#)U?txx		gt%'
##D)  ++DMM: f ==DKK']]djj(]]djj("jjDO]]dii'"jjDO]]dnn,"ooDO"jjDO]]dnn,+"&"2"2"".)-):):U)B&]]d1116:jj@D!DO"ooDO+"&"2"2"".)-):):U)B&"499~--;;""kk33DO ::C

Xt$45C"'

(;(;<M(N"OD

YL1zzTXX% 3&+ENN;L,M&N#ZZ1_CCTZZ(E"'7H(I"JD3Z
   	HADwtQ//47!;VAYG	Hr4   )r>   r?   r@   __doc__r=   r   r   rh   rj   ri   rl   rm   ro   rs   re   r3   __classcell__rQ   s   @r2   rC   rC   D   s    0!$ 	eEleElU5\U5\

E%LxweM2	KTH THr4   rC   c                       e Zd ZdZd Zd Zy)
IBCommInfoae  
    Commissions are calculated by ib, but the trades calculations in the
    ```Strategy`` rely on the order carrying a CommInfo object attached for the
    calculation of the operation cost and value.

    These are non-critical informations, but removing them from the trade could
    break existing usage and it is better to provide a CommInfo objet which
    enables those calculations even if with approvimate values.

    The margin calculation is not a known in advance information with IB
    (margin impact can be gotten from OrderState objects) and therefore it is
    left as future exercise to get itc                     t        |      |z  S Nru   r.   rv   rk   s      r2   getvaluesizezIBCommInfo.getvaluesize   s    4y5  r4   c                     t        |      |z  S )z9Returns the needed amount of cash an operation would costr   r   s      r2   getoperationcostzIBCommInfo.getoperationcost   s     4y5  r4   N)r>   r?   r@   r   r   r   rA   r4   r2   r   r      s    )!!r4   r   c                        e Zd Z fdZ xZS )MetaIBBrokerc                 Z    t         t        |   |||       | t        j                  _        y)z+Class has already been created ... registerN)rE   r   r3   r   IBStore	BrokerCls)clsnamebasesdctrQ   s       r2   r3   zMetaIBBroker.__init__   s$     	lC)$s;$'!r4   )r>   r?   r@   r3   r   r   s   @r2   r   r      s    ( (r4   r   c                        e Zd ZdZdZ fdZ fdZ fdZd ZddZ	ddZ
d	 Zd
 Zd Zd Z	 	 	 ddZ	 	 ddZ	 	 ddZd Zd Zd Zd\  ZZZZZZZd Zd Zd Zd Zd Z d Z! xZ"S )IBBrokera  Broker implementation for Interactive Brokers.

    This class maps the orders/positions from Interactive Brokers to the
    internal API of ``backtrader``.

    Notes:

      - ``tradeid`` is not really supported, because the profit and loss are
        taken directly from IB. Because (as expected) calculates it in FIFO
        manner, the pnl is not accurate for the tradeid.

      - Position

        If there is an open position for an asset at the beginning of
        operaitons or orders given by other means change a position, the trades
        calculated in the ``Strategy`` in cerebro will not reflect the reality.

        To avoid this, this broker would have to do its own position
        management which would also allow tradeid with multiple ids (profit and
        loss would also be calculated locally), but could be considered to be
        defeating the purpose of working with a live broker
    rA   c                    t         t        |           t        j                  di || _        dx| _        | _        dx| _        | _	        t        j                         | _        t               | _        t               | _        t!        j"                  t              | _        t'        j(                         | _        t!        j,                         | _        y )NrZ   rA   )rE   r   r3   r   r   rc   startingcashcashstartingvaluevalue	threadingLock_lock_ordersdict	orderbyid
executionscollectionsdefaultdict	ordstatusr   Queuenotifsdequetonotify)r.   r   rQ   s     r2   r3   zIBBroker.__init__	  s    h&(//+F+(++DI*--TZ%NN,&$006kkm#))+r4   c                    t         t        |           | j                  j                  |        | j                  j	                         rg| j                  j                          | j                  j                         x| _        | _        | j                  j                         x| _
        | _        y dx| _        | _        dx| _
        | _        y )N)brokerrZ   )rE   r   startrc   	connectedreqAccountUpdatesget_acc_cashr   r   get_acc_valuer   r   r.   rQ   s    r2   r   zIBBroker.start  s    h#%T"77GG%%',0GG,@,@,BBD	.2gg.C.C.EED,//D	.11Dr4   c                 ^    t         t        |           | j                  j                          y r   )rE   r   stoprc   r   s    r2   r   zIBBroker.stop$  s    h"$r4   c                 X    | j                   j                         | _        | j                  S r   )rc   r   r   r.   s    r2   getcashzIBBroker.getcash(  s     GG((*	yyr4   c                 X    | j                   j                         | _        | j                  S r   )rc   r   r   )r.   datass     r2   getvaluezIBBroker.getvalue-  s     WW**,
zzr4   c                 P    | j                   j                  |j                  |      S )Nclone)rc   getpositiontradecontract)r.   datar   s      r2   r   zIBBroker.getposition1  s"    ww""4#5#5U"CCr4   c                     	 | j                   |j                     }|j                  t
        j                  k(  ry | j                  j                  |j                         y # t        t        f$ r Y y w xY wr   )	r   rG   
ValueErrorKeyErrorr    r   	Cancelledrc   cancelOrderr.   orderos      r2   cancelzIBBroker.cancel4  s]    	u/A <<5??*EOO, H% 		s   A A10A1c                     	 | j                   |j                     }|j                  S # t        t        f$ r |}Y |j                  S w xY wr   )r   rG   r   r   r    r   s      r2   orderstatuszIBBroker.orderstatus?  sH    	u/A xx H% 	Axx	s   ' AAc                    |j                  |        |j                  #t        t        j                               |_        n2| j                  |j                  j                     j
                  |_        || j                  |j                  <   | j                  j                  |j                  |j                  j                  |       | j                  |       |S r   )submitocor   uuiduuid4
m_ocaGroupr   rG   rc   
placeOrderr   r   notifyr.   r   s     r2   r   zIBBroker.submitG  s    T 99$TZZ\2E#~~eii.A.ABMME*/u'5??EJJ,D,DeLEr4   c                     |j                   }	 t        |j                        }|j
                  dv}t        ||      S # t        t        f$ r d}Y .w xY w)Ng      ?)FUTOPTFOP)mult	stocklike)r   floatm_multiplierr   	TypeError	m_secTyper   )r.   r   contractr   r   s        r2   getcommissioninfozIBBroker.getcommissioninfoV  s]    %%	../D &&.DD	ty99 I& 	D	s   > AAc
                     t        |f||||||||	| j                  j                  | j                  j                         d
|
}|j	                  | j                  |             |S )N)
ownerr   rv   rk   rn   rf   r{   tradeid
m_clientIdrG   )rC   rc   clientIdnextOrderIdaddcomminfor   )r.   r   r   r   rv   rk   plimitrf   r{   r   r   r   s               r2   
_makeorderzIBBroker._makeordera  so    
  "e$!6!) '#'77#3#3"&''"5"5"7" !" 	$0067r4   c	                 Z     | j                   d||||||||f	i |	}
| j                  |
      S )NrY   r   r   r.   r   r   rv   rk   r   rf   r{   r   r   r   s              r2   buyzIBBroker.buyq  sC    
  4ufhw 
 {{5!!r4   c	                 Z     | j                   d||||||||f	i |	}
| j                  |
      S )NSELLr   r   s              r2   sellzIBBroker.sell}  sC    
  4ufhw 
 {{5!!r4   c                 V    | j                   j                  |j                                y r   )r   putr   r   s     r2   r   zIBBroker.notify  s    &r4   c                 l    	 | j                   j                  d      S # t        j                  $ r Y y w xY w)NF)r   getr   Emptyr   s    r2   get_notificationzIBBroker.get_notification  s3    	;;??5)){{ 		s    33c                 :    | j                   j                  d        y r   )r   r   r   s    r2   nextzIBBroker.next  s    r4   )	SubmittedFilledr   InactivePendingSubmitPendingCancelPreSubmittedc                 t   	 | j                   |j                     }|j                  | j                  k(  rL|j
                  dk(  r=|j                  |j                  k(  ry |j                  |        | j                  |       y |j                  | j                  k(  rd|j                  |j                  |j                  fv ry |j                  r|j                          n|j                          | j                  |       y |j                  | j                  k(  r|j                  |j                  k(  ry y |j                  | j                   k(  r=|j                  |j"                  k(  ry |j%                  |        | j                  |       y |j                  | j                  | j&                  fv r'|| j(                  |j                     |j
                  <   y |j                  | j*                  | j,                  fv r4|j
                  r'|| j(                  |j                     |j
                  <   y y y # t        $ r Y y w xY w)Nr   )r   orderIdr   r    	SUBMITTEDfilledAcceptedacceptr   	CANCELLEDr   Expiredr_   expirer   PENDINGCANCELINACTIVERejectedrejectFILLEDr   PENDINGSUBMITPRESUBMITTEDr.   msgr   s      r2   push_orderstatuszIBBroker.push_orderstatus  s   	NN3;;/E ::'CJJ!O||u~~-LLKKZZ4>>)||??    KKZZ4--- ||u. / ZZ4==( ||u~~-LLKKZZDNNDKK88 7:DNN3;;'

3ZZD..0A0ABB zz:=s{{+CJJ7  u  		s   H+ +	H76H7c                 6    || j                   |j                  <   y r   )r   m_execId)r.   exs     r2   push_executionzIBBroker.push_execution  s    ')$r4   c                 p   | j                   5  | j                  j                  |j                        }|j                  }| j
                  |   }| j                  |   j                  |j                        }| j                  |j                  d      }|j                  }|j                  d   dk(  r|j                  n|j                   }|j                  }	|j                  ||	      \  }
}}}|j                  }||z  |z  }||z
  }|j                   }|j#                  ||      }|j#                  ||	      }|r|j$                  nd}t'        t)        j*                  |j,                  d            }|j                  j.                  d   }|j1                  |||	|||||||||
|       |j2                  | j4                  k(  r,|j7                          | j                  j                  |       n|j9                          || j:                  vr| j:                  j=                  |       d d d        y # 1 sw Y   y xY w)NFr   r   BrZ   z%Y%m%d  %H:%M:%S)r   r   popr  rG   r   r   m_cumQtyr   r   rk   m_sidem_sharesm_priceupdatem_commissioncomminfor   m_realizedPNLr   r	   strptimem_timecloseexecuter    r  	completedpartialr   r8   )r.   crr  oidr   ostatuspositionpprice_origrv   rk   psizeppriceopenedclosedcomm
closedcomm
openedcommr"  closedvalueopenedvaluepnldtmargins                          r2   push_commissionreportzIBBroker.push_commissionreport  s    1	*$$R[[1B,,CNN3'EnnS)--bkk:G''

%'@H"..K"$))A,#"52;;BKK<DJJE,4OOD%,H)E666 ??D-J
*J~~H"33FKHK"33FEBK '-"""#C (++BII7IJKB ZZ%%a(FMM"dE +z +z #	) ~~,!""3'$--'$$S)c1	* 1	* 1	*s   HH,,H5c                     | j                   5  | j                  rG| j                  j                         }| j                  |   }| j	                  |       | j                  rGd d d        y # 1 sw Y   y xY wr   )r   r   popleftr   r   )r.   r+  r   s      r2   push_portupdatezIBBroker.push_portupdate  s^    
  	#--mm++-s+E" --	# 	# 	#s   AA**A3c                    | j                   5  	 | j                  |j                     }|j
                  dk(  r+|j                         s
	 d d d        y |j                          nS|j
                  dk(  r4|j                  |j                  k(  r
	 d d d        y |j                          n|j                          | j                  |       d d d        y # t        t        f$ r Y d d d        y w xY w# 1 sw Y   y xY w)N      )r   r   idr   AttributeError	errorCodealiver   r    r  r  r   r  s      r2   push_ordererrorzIBBroker.push_ordererror  s     	svv. }}#{{}	 	 #%<<5>>1	 	  KK'	 	 n- 		 		 	s9   C,C C,:C,2C,C)C,(C))C,,C5c                     | j                   5  	 | j                  |j                     }|j
                  j                  dv rd|_        d d d        y # t        t        f$ r Y d d d        y w xY w# 1 sw Y   y xY w)N)r   r   CanceledT)r   r   r  r   rC  
orderStatem_statusr_   r  s      r2   push_orderstatezIBBroker.push_orderstate5  s     		)s{{3 ~~&& +7 7 %)!		) 		) n- 			) 		)		) 		)s-   A-AA-A*A-)A**A--A6r   )T)NNNNr   )#r>   r?   r@   r   paramsr3   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r  r  r  r  r  r;  r>  rF  rK  r   r   s   @r2   r   r      s    , F,
2
D	-	: -1(," &*/0
" '+01
"'
4<1Y	8M<>@*2*h	#,
)r4   r   )4
__future__r   r   r   r   r   r   r	   r   r
   r   r   ib.ext.Orderrc   ib.optoptiboptbacktrader.feedr   
backtraderr   r   r   r   r   r   r   backtrader.utils.py3r   r   r   r   r   backtrader.metabaser   backtrader.comminfor   backtrader.positionr   backtrader.storesr   backtrader.utilsr   r   objectr   rd   rC   r   rQ   r   r   rA   r4   r2   <module>r[     s   ** *   . .     $5 5 5 M M * , ( % 6 ,6 *IHi++ IHX! !0(:'' (O)~lJ7 O)r4   