B
     9-et/  ã               @   sx   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 dd„ Z	G dd	„ d	e
ƒZG d
d„ de
ƒZG dd„ de
ƒZdS )é    )ÚAccountInfo)ÚKeyedIbridgePyOrders)ÚKeyedPositionRecords)Úcopy)Úexitc             C   s   t | ƒ}d|_d|_|S )NÚ )r   ÚexchangeÚprimaryExchange)ÚsecurityÚcopy_security© r   úµG:\My Drive\STUDY\EPAT\09 TBP - Trading & Back-testing Platforms\TBP04 - Backtesting & Live Trading\IB IBridgePy API\02 Python 3.7 IBridgePy_Win_Anaconda37_64\models\SingleTrader.pyÚ-stripe_exchange_primaryExchange_from_security	   s    r   c               @   s²   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd d!„ Zd"d#„ Zd,d%d&„Zd'd(„ Zd)d*„ Zd+S )-ÚSingleTraderz0
    The interface for outside world to use
    c             C   s   i | _ || _d | _tƒ | _d S )N)Ú_brokerNameDictÚ_logÚ_accountCodeDictÚsetÚ*_account_codes_with_real_value_from_broker)ÚselfÚlogr   r   r   Ú__init__   s    zSingleTrader.__init__c             C   sV   dt | ƒf }| js$|d d… d }x$| jD ]}|t| j| ƒd 7 }q,W |d d… S )NzSingleTrader id=%s
éÿÿÿÿz{Empty self._brokerNameDict}Ú
)Úidr   Ústr)r   ÚansÚ
brokerNamer   r   r   Ú__str__%   s    zSingleTrader.__str__c             C   s”   | j  td||f  ¡ t|tƒs>| j  td|f  ¡ tƒ  || jkr^t||f| j ƒ| j|< | j|  	¡ | _
|| j
krŠt|| j ƒ| j
|< | j
| S )NzK::_find_account_by_brokerName_and_accountCode: brokerName=%s accountCode=%szQ::_find_account_by_brokerName_and_accountCode: EXIT, cannot handle accountCode=%s)r   ÚnotsetÚ__name__Ú
isinstancer   Úerrorr   r   ÚBrokerÚgetAccountCodeDictr   ÚAccount)r   r   ÚaccountCoder   r   r   Ú+_find_account_by_brokerName_and_accountCode-   s    


z8SingleTrader._find_account_by_brokerName_and_accountCodec             C   s   |   ||¡}|j |¡ d S )N)r'   ÚkeyedIbridgePyOrdersÚcreateFromPlaceOrder)r   r   r&   ÚibpyOrderIdÚaccountr   r   r   Úset_from_send_req_to_server:   s    z(SingleTrader.set_from_send_req_to_serverc             C   s   |   ||¡}|j |¡ d S )N)r'   ÚkeyedPositionRecordsÚupdate)r   r   r&   ZpositionRecordr+   r   r   r   Úset_position>   s    zSingleTrader.set_positionc             C   s6   | j  td|||f  ¡ |  ||¡}|j |¡ d S )NzE::set_orderStatus: _brokerName=%s accountCode=%s orderStatusRecord=%s)r   Údebugr    r'   r(   ÚupdateFromOrderStatus)r   r   r&   ÚorderStatusRecordr+   r   r   r   Úset_orderStatusB   s    
zSingleTrader.set_orderStatusc             C   s6   | j  td|||f  ¡ |  ||¡}|j |¡ d S )NzA::set_openOrder: _brokerName=%s accountCode=%s openOrderRecord=%s)r   r   r    r'   r(   ÚupdateFromOpenOrder)r   r   r&   ÚopenOrderRecordr+   r   r   r   Úset_openOrderH   s    
zSingleTrader.set_openOrderc             C   s*   |   ||¡}| ¡  |¡ | j |¡ d S )N)r'   ÚgetAccountInfoÚupdate_from_accountSummaryr   Úadd)r   r   r&   ÚaccountSummaryRecordr+   r   r   r   Úset_accountSummaryN   s    zSingleTrader.set_accountSummaryc             C   sD   | j  td|||f  ¡ |  ||¡}| ¡  |¡ | j |¡ d S )NzR::set_updateAccountValue: brokerName=%s accountCode=%s updateAccountValueRecord=%s)r   r   r    r'   r7   Úupdate_from_updateAccountValuer   r9   )r   r   r&   ÚupdateAccountValueRecordr+   r   r   r   Úset_updateAccountValueS   s    z#SingleTrader.set_updateAccountValuec             C   s   |   ||¡}|j |¡ d S )N)r'   r(   ÚupdateFromExecDetails)r   r   r&   ÚexecDetailsRecordr+   r   r   r   Úset_execDetailsY   s    zSingleTrader.set_execDetailsc             C   s:   | j  td|||f  ¡ |  ||¡}t|ƒ}|j |¡S )Nz9::get_position: _brokerName=%s accountCode=%s security=%s)r   r   r    r'   r   r-   ZgetPositionRecord)r   r   r&   r
   r+   Úadj_securityr   r   r   Úget_position]   s
    zSingleTrader.get_positionc             C   s   |   ||¡}|j ¡ S )zW

        :param brokerName:
        :param accountCode:
        :return: bool
        )r'   r-   Úhold_any_position)r   r   r&   r+   r   r   r   rD   d   s    zSingleTrader.hold_any_positionc             C   s   |   ||¡}|j ¡  dS )aC  
        To run algo continuously, the positions must be always fresh. If a position is sell off, it will still stay in
        keyedPositionRecords forever. Then, iterating all keys will cause issues. The solution is to delete all positions
        before get_all_positions so that the positions are always fresh.
        N)r'   r-   Údelete_every_position)r   r   r&   r+   r   r   r   rE   n   s    z"SingleTrader.delete_every_positionc             C   s   |   ||¡}|j ¡ S )zT
        :return: dictionary, keyed by str_security, value = PositionRecord
        )r'   r-   Úget_all_positions)r   r   r&   r+   r   r   r   rF   w   s    zSingleTrader.get_all_positionsc             C   s@   |   ||¡}| |¡r | |¡S | j td||f  ¡ dS dS )zƒ

        :param brokerName:
        :param accountCode:
        :param str_ibpyOrderId:
        :return: None if not find
        zp::SingleTrader::find_order: account=%s does not have an OPEN order ibpyOrderId=%s. Maybe it is executed already.N)r'   Úhas_ibpyOrderIdÚget_ibridgePyOrderr   r0   r    )r   r   r&   Ústr_ibpyOrderIdr+   r   r   r   Ú
find_order~   s
    	

zSingleTrader.find_orderc             C   s   |   ||¡}|j ¡  dS )aÔ  
        Web api bases brokers may not have all order info. For example, TD only keeps the orders for the latest 7 days.
        And get_all_order from broker will only return recent orders.
        It means that orders' latest status may not be updated if the order was placed a few days ago.
        The solution is to delete every order and request latest order info from broker.
        :param brokerName:
        :param accountCode:
        :return: None
        N)r'   r(   Údelete_every_order)r   r   r&   r+   r   r   r   rK   Ž   s    
zSingleTrader.delete_every_orderc             C   sN   |   ||¡}|j ¡ }t|ƒdkr&g S i }x|D ]}|  |||¡||< q0W |S )zx

        :param brokerName:
        :param accountCode:
        :return: list of models::Order::IbridgePyOrder
        r   )r'   r(   Úget_all_ibpyOrderIdÚlenrJ   )r   r   r&   r+   ÚorderIdListr   ÚorderIdr   r   r   Úget_all_orders›   s    

zSingleTrader.get_all_ordersÚvaluec             C   sB   |   ||¡}|dkr"| ¡  |¡S | j td|f  ¡ tƒ ‚d S )NrQ   z ::get_account_info: EXIT meta=%s)r'   r7   Ú	get_valuer   r"   r    ÚNotImplementedError)r   r   r&   ÚtagÚmetar+   r   r   r   Úget_account_info¬   s
    zSingleTrader.get_account_infoc             C   sÞ   | j  td||f  ¡ || jkr4| j|  ¡ | _nttd| j ¡ f  ƒ tƒ  x(| jD ]}|  	|||¡}|dk	rZ|S qZW | j  
td|f  ¡ t| jƒdkr²t| j ¡ ƒd S x | jD ]}| j  
d|f ¡ qºW tƒ  dS )zœ
        This is a search logic, Exit if cannot find an accountCode
        :param str_brokerName:
        :param str_ibpyOrderId:
        :return:
        zB::get_accountCode_by_ibpyOrderId: str_brokerName=%s ibpyOrderId=%sz8::SingleTrader::get_accountCode_by_ibpyOrderId: EXIT, %sNzK::get_accountCode_by_ibpyOrderId: Cannot find accountCode by ibpyOrderId=%sé   r   zPossible accountCode=%s)r   r   r    r   r$   r   ÚprintÚkeysr   rJ   r"   rM   Úlist)r   Zstr_brokerNamerI   r&   ÚibridgePyOrderZacctCoder   r   r   Úget_accountCode_by_ibpyOrderIdµ   s    
z+SingleTrader.get_accountCode_by_ibpyOrderIdc             C   s   | j S )N)r   )r   r   r   r   r   Úget_all_active_accountCodesÏ   s    z(SingleTrader.get_all_active_accountCodesN)rQ   )r    Ú
__module__Ú__qualname__Ú__doc__r   r   r'   r,   r/   r3   r6   r;   r>   rA   rC   rD   rE   rF   rJ   rK   rP   rV   r\   r]   r   r   r   r   r      s*   
	
	r   c               @   s$   e Zd Zdd„ Zdd„ Zdd„ ZdS )r#   c             C   s6   || _ || _i | _x|D ]}t|| j ƒ| j|< qW d S )N)r   Ú_brokerNamer   r%   )r   r   Ztuple_accountCodesr   ZaccountCr   r   r   r   Ö   s
    
zBroker.__init__c             C   sV   d| j t| ƒf }| js(|d d… d }x | jD ]}|d| j|  7 }q0W |d d… S )NzBroker=%s id=%s
r   z{Empty self._accountCodeDict}z%s
)ra   r   r   )r   r   r&   r   r   r   r   Ý   s    zBroker.__str__c             C   s   | j S )N)r   )r   r   r   r   r$   å   s    zBroker.getAccountCodeDictN)r    r^   r_   r   r   r$   r   r   r   r   r#   Õ   s   r#   c               @   s4   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ ZdS )r%   c             C   s6   || _ || _t| jƒ| _t|| jƒ| _t| jƒ| _d S )N)r&   r   r   r-   r   r(   r   Ú_accountInfo)r   r&   r   r   r   r   r   ê   s
    zAccount.__init__c             C   sF   d| j t| ƒf }x&| j| j| jgD ]}|d|f 7 }q$W |d d… S )NzPrint models::Account=%s id=%s
z%s
r   )r&   r   r-   r(   rb   )r   r   Úitemr   r   r   r   ñ   s    zAccount.__str__c             C   s   | j S )N)rb   )r   r   r   r   r7   ÷   s    zAccount.getAccountInfoc             C   s   | j  |¡S )N)r(   rG   )r   r*   r   r   r   rG   ú   s    zAccount.has_ibpyOrderIdc             C   s   | j  |¡S )N)r(   rH   )r   r*   r   r   r   rH   ý   s    zAccount.get_ibridgePyOrderN)r    r^   r_   r   r   r7   rG   rH   r   r   r   r   r%   é   s
   r%   N)Úmodels.AccountInfor   Úmodels.Orderr   Zmodels.Positionr   r   Úsysr   r   Úobjectr   r#   r%   r   r   r   r   Ú<module>   s    <