a
     9-e(B                     @   s   d Z ddlZddlmZ ddlmZ ddlZddlm	Z	 ddl
mZmZ ddlmZmZ ddlmZ dd	lmZmZmZmZmZmZ G d
d deZdS )zC
Created on Thu Aug 17 23:50:16 2017

@author: IBridgePy@gmail.com
    N)exit)Decimal)IBCpp)-stripe_exchange_primaryExchange_from_securitychoose_whatToShow)SymbolStatusOrderStatus)from_contract_to_security)CancelOrderReqHistoricalData
PlaceOrder
ReqMktDataReqScannerSubscriptionCancelScannerSubscriptionc                   @   s  e Zd Zdd Zedd Zdd Zedd Zed	d
 Zedd Z	dd Z
dd Zdad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dbd*d+Zd,d- Zd.d/ Zd0d1 Zd2d3 Zd4d5 Zdcd7d8Zd9d: Zd;d< Z d=d> Z!d?d@ Z"dAdB Z#dddGdHZ$dIdJ Z%dKdL Z&dedMdNZ'dfdOdPZ(dQdR Z)dgdSdTZ*dhdUdVZ+didWdXZ,djdYdZZ-d[d\ Z.d]d^ Z/d_d` Z0dCS )kBrokerServicec                 C   s8   || _ || _|| _|| _|| _| jtd  d| _d S )Nz
::__init__F)_userConfig_log_timeGenerator_singleTrader_dataFromServernotset__name___asDataProviderService)self
userConfiglogtimeGeneratorsingleTraderdataFromServer r   G:\My Drive\STUDY\EPAT\09 TBP - Trading & Back-testing Platforms\TBP04 - Backtesting & Live Trading\IB IBridgePy API\IBridgePy_Win_Anaconda37_64\broker_service_factory\BrokerService.py__init__   s    zBrokerService.__init__c                 C   s   | j jS N)r   brokerClientr   r   r   r    _brokerClient'   s    zBrokerService._brokerClientc                 C   s   d| j t| | j| jf S )Nz0{name=%s id=%s brokerClient=%s timeGenerator=%s})nameidr%   r   r$   r   r   r    __str__+   s    zBrokerService.__str__c                 C   s   t | jdS zB
        Name of the broker

        :return: string name
        NNotImplementedErrorr&   r$   r   r   r    r&   .   s    zBrokerService.namec                 C   s   t | jdS r)   r*   r$   r   r   r    
brokerName7   s    zBrokerService.brokerNamec                 C   s   | j jS r"   )r%   versionNumberr$   r   r   r    r-   @   s    zBrokerService.versionNumberc                 C   s   | j S r"   )r%   r$   r   r   r    getBrokerClientD   s    zBrokerService.getBrokerClientc                 C   s
   d| _ d S )NT)r   r$   r   r   r    setAsDataProviderServiceG   s    z&BrokerService.setAsDataProviderServicevaluec                 C   s   t d S r"   )r+   )r   accountCodetagmetar   r   r    _get_account_info_one_tagJ   s    z'BrokerService._get_account_info_one_tagc                 C   sV   | j td| |f   | j||d}|d u r8d}| j td|||f   |S )NzC::_get_real_time_price_from_dataFromServer: security=%s tickType=%spricezT::_get_real_time_price_from_dataFromServer: security=%s tickType=%s returnedValue=%s)r   r   r   
full_printr   	get_valuedebug)r   securitytickTypeansr   r   r    (_get_real_time_price_from_dataFromServerM   s    z6BrokerService._get_real_time_price_from_dataFromServerc                 C   s(   | j td||f   | j||dS )Nz/::_from_dataFromServer: security=%s tickType=%ssize)r   r9   r   r   r8   r   r:   r;   r   r   r    '_get_real_time_size_from_dataFromServerV   s    z5BrokerService._get_real_time_size_from_dataFromServerc                 C   s"   | j t d|  | j|S )Nz;::_get_5_second_real_time_bar_from_dataFromServe: security=)r   r   r   r   get_5_second_real_time_barr   r:   r   r   r    /_get_5_second_real_time_bar_from_dataFromServerZ   s    z=BrokerService._get_5_second_real_time_bar_from_dataFromServerc                 C   s4   t |}| jtd| f   | j| j||S )z
        Guarantee to return a PositionRecord even if there is no current position.
        :param accountCode:
        :param security:
        :return: Guarantee to return a PositionRecord
        z ::_get_position: adj_security=%s)r   r   r9   r   r7   r   get_positionr,   )r   r1   r:   Zadj_securityr   r   r    _get_position^   s    zBrokerService._get_positionc                 C   s@   | j | j|}i }|D ]"}|| j}t|}|| ||< q|S r"   )r   get_all_positionsr,   contractr	   )r   r1   ZallPositionsr<   Zstr_securityrG   r:   r   r   r    _get_all_positionsi   s    
z BrokerService._get_all_positionsc                 C   s&   | j td|f   | j| j|S )zx

        :param accountCode:
        :return: dict Keyed by ibpyOrderId, value = models::Order::IbridgePyOrder
        z!::_get_all_orders: accountCode=%s)r   r9   r   r   get_all_ordersr,   r   r1   r   r   r    _get_all_orderst   s    zBrokerService._get_all_ordersc                 C   sP   | j td| f   |jtjkr4| j| n| j	| | j
| d S )Nz7::add_exchange_primaryExchange_to_security: security=%s)r   r9   r   r7   symbolStatusr   SUPER_SYMBOLr%   Zappend_security_infoZadd_primaryExchange_to_securityZadd_exchange_to_securityrB   r   r   r    (add_exchange_primaryExchange_to_security}   s
    z6BrokerService.add_exchange_primaryExchange_to_securityc                 C   s(   | j td|f   | t| dS )zj
        Cancel order by its ibpyOrderId
        :param ibpyOrderId: string
        :return: None
        z::cancel_order: ibpyOrderId=%sN)r   r9   r   submit_requestsr
   r   ibpyOrderIdr   r   r    cancel_order   s    zBrokerService.cancel_orderc                 C   s   | j td  | j S )Nz	::connect)r   r9   r   r%   ZconnectWrapperr$   r   r   r    connect   s    zBrokerService.connectc                 C   s    | j t d | j  d S )Nz::disconnect: )r   r9   r   r%   disconnectWrapperr$   r   r   r    
disconnect   s    zBrokerService.disconnectc                 C   s   | j td  | j S )Nz::get_next_time)r   r   r   r   get_next_timer$   r   r   r    rV      s    zBrokerService.get_next_timec                 C   sd   | j td||f   t|tr0| |||S t|tr`g }|D ]}|| ||| qB|S d S )Nz*::get_account_info: accountCode=%s tags=%s)r   r9   r   
isinstancestrr4   listappend)r   r1   tagsr3   r<   r2   r   r   r    get_account_info   s    

zBrokerService.get_account_infoc                 C   s$   | j  }| jtd|f   |S )zN
        Get IB server time
        :return: datetime in UTC timezone
        z::get_datetime=%s)r   Zget_current_timer   r   r   )r   r<   r   r   r    get_datetime   s    
zBrokerService.get_datetimec                 C   s   | j td  | j| jS )z
        get a list of accountCodes from IB server to check if the user-input accountCode is acceptable.
        :return:
        z::get_active_accountCodes)r   r9   r   r   Zget_all_active_accountCodesr,   r$   r   r   r    get_active_accountCodes   s    z%BrokerService.get_active_accountCodesc                 C   sf   | j td|f   | |}g }|D ]8}|| j}|tjtjtjtj	tj
fv r(|||  q(|S )Nz%::get_all_open_orders: accountCode=%s)r   r9   r   rI   statusr   
APIPENDINGPENDINGSUBMITPENDINGCANCELPRESUBMITTED	SUBMITTEDrZ   )r   r1   Z	allOrdersr<   rQ   r_   r   r   r    get_all_open_orders   s    

z!BrokerService.get_all_open_ordersc                 C   s   t | jd S r"   r*   rJ   r   r   r    rI      s    zBrokerService.get_all_ordersc                 C   s   t | jdS )z
        Get all of positionRecords associated with the accountCode
        :param accountCode:
        :return: dictionary, keyed by Security object with exchange info!!!, value = PositionRecord
        Nr*   rJ   r   r   r    rF      s    zBrokerService.get_all_positions   c                 C   s   t | jd S r"   r*   )r   r:   fieldwaitForFeedbackInSecondsr   r   r    get_contract_details   s    z"BrokerService.get_contract_detailsc                 C   s
   | j  S r"   )r%   get_heart_beatsr$   r   r   r    rj      s    zBrokerService.get_heart_beatsc                 C   s
   | j  S )zO

        :return: int, number of days of IBridgePy passcode to expiry
        )r%   Zget_authed_expiryr$   r   r   r    get_ibpy_expiry_in_days   s    z%BrokerService.get_ibpy_expiry_in_daysc                 C   s^   g d}i }|D ]}||v r|| ||< q|  t||d}|  t|d  | j|d S )N)ZnumberOfRowsZ
instrumentZlocationCodeZscanCodeZ
abovePriceZ
belowPriceZaboveVolumeZmarketCapAboveZmarketCapBelowZmoodyRatingAboveZmoodyRatingBelowZspRatingAboveZspRatingBelowZmaturityDateAboveZmaturityDateBelowZcouponRateAboveZcouponRateBelowZexcludeConvertibleZaverageOptionVolumeAboveZscannerSettingPairsZstockTypeFilterrh   r   )rO   r   r   r%   get_submit_requests_result)r   rh   kwargstagListZsubscriptionct	reqIdListr   r   r    get_scanner_results   s    z!BrokerService.get_scanner_resultsc                 C   s
   | j  S r"   )r%   "get_TD_access_token_expiry_in_daysr$   r   r   r    rs      s    z0BrokerService.get_TD_access_token_expiry_in_daysc                 C   s
   | j  S r"   )r%   get_new_TD_refresh_tokenr$   r   r   r    rt      s    z&BrokerService.get_new_TD_refresh_tokenN    Tc	           
      C   s   | j td|||||||f   |durt|dkrt|jdu rX| j td|f   t  |jtjd}t	j
|d}|dkrt|j}| t||||||||d}	| j|	d S )	a  
        :param followUp:
        :param security: Security
        :param barSize: string
        barSize can be any of the following values(string)
        1 sec, 5 secs,15 secs,30 secs,1 min,2 mins,3 mins,5 mins,15 mins,30 mins,1 hour,1 day
        :param goBack: string
        :param endTime: default value is '', IB server deems '' as the current server time.
        If user wants to supply a value, it must be a datetime with timezone
        :param whatToShow: string
        whatToShow: see IB documentation for choices
        TRADES,MIDPOINT,BID,ASK,BID_ASK,HISTORICAL_VOLATILITY,OPTION_IMPLIED_VOLATILITY
        :param useRTH: int 1=within regular trading hours, 0=ignoring RTH
        :param waitForFeedbackInSeconds:
        :return: a dataFrame, keyed by a datetime with timezone UTC, columns = ['open', 'high', 'low', 'close', 'volume']
                The latest time record at the bottom of the dateFrame.
        zv::get_historical_data: security=%s barSize=%s goBack=%s endTime=%s whatToShow=%s useRTH=%s waitForFeedbackInSeconds=%sNru   z>::request_historical_data: EXIT, endTime=%s must have timezone)tzz%Y%m%d %H:%M:%S %Z)followUpr   )r   r9   r   tzinfoerrorr   
astimezonepytzutcdtdatetimestrftimer   ZsecTyperO   r   r%   rm   )
r   r:   barSizeZgoBackendTime
whatToShowZuseRTHrh   rx   ZorderIdListr   r   r    get_historical_data   s    "

z!BrokerService.get_historical_datac                 C   s   t | jdS )zj

        :param ibpyOrderId: string
        :return: broker_factory::records_def::IBridgePyOrder
        Nr*   rP   r   r   r    	get_order  s    zBrokerService.get_orderc                 C   s   t | jd S r"   r*   )r   r1   r:   r   r   r    rD     s    zBrokerService.get_positionc                 C   s   t | jd S r"   r*   r   r:   r;   rx   r   r   r    get_real_time_price"  s    z!BrokerService.get_real_time_pricec                 C   s   t | jd S r"   r*   r   r   r   r    rA   %  s    z(BrokerService.get_5_second_real_time_barc                 C   s   t td| jf  d S )Nz::get_timestamp: %s)r+   r   r&   r?   r   r   r    get_timestamp(  s    zBrokerService.get_timestampc                 C   s   t | jd S r"   r*   r   r   r   r    get_real_time_size+  s    z BrokerService.get_real_time_sizec                 C   s   t | jd S r"   r*   )r   rQ   Ztarget_statusZwaitingTimeInSecondsr   r   r    order_status_monitor.  s    z"BrokerService.order_status_monitorc                 C   s   | j td| t|f   | j|s>| t||d i }|D ]}|dv rl| j	
|tjj|||< qF|dv r| j	
|tjjd||< qF|dv r| j	
|tjjd||< qFttd| |f   qF|S )Nz(::get_option_info: security=%s fields=%srl   )deltagammaZvegathetaZ
impliedVolZoptPriceZundPrice)Zoption_call_open_interestr>   )Zoption_put_open_interestz?::get_option_info: EXIT, cannot handle security=%s fieldName=%s)r   r9   r   r7   rX   r%   Zis_real_time_price_requestedrO   r   r   r8   r   ZTickTypeZLAST_OPTION_COMPUTATIONZOPTION_CALL_OPEN_INTERESTZOPTION_PUT_OPEN_INTERESTr   )r   r:   fieldsrh   r<   	fieldNamer   r   r    get_option_info1  s     zBrokerService.get_option_infoc                 C   sl   | j td|f   |j}|j}t|d dkrX| t||||d}| j	|d S | j 
d dS d S )Nz ::place_order: ibridgePyOrder=%sZtotalQuantityr   )rG   orderrx   rh   z4No order was placed because order.totalQuantity = 0.ZNoOrderPlaced)r   r9   r   ZrequestedContractZrequestedOrderr   rO   r   r%   rm   info)r   ZibridgePyOrderrx   rh   rG   r   rq   r   r   r    place_orderC  s    zBrokerService.place_orderc                 C   s   | j |S r"   )r%   ZprocessMessagesWrapper)r   ZtimeNowr   r   r    processMessagesN  s    zBrokerService.processMessagesc                 G   s"   | j t d|  | jj| S )zu

        :param args: broker_client_factory::BrokerClientDefs::Request
        :return: a list of reqId !!!
        z::submit_requests: args=)r   r   r   r%   Zrequest_data)r   argsr   r   r    rO   R  s    zBrokerService.submit_requestsc                 C   s
   | j  S r"   )r%   use_next_idr$   r   r   r    r   [  s    zBrokerService.use_next_id)r0   )r0   )rf   )Nru   rv   rf   T)T)T)T)rf   )rf   )Trf   )1r   
__module____qualname__r!   propertyr%   r(   r&   r,   r-   r.   r/   r4   r=   r@   rC   rE   rH   rK   rN   rR   rS   rU   rV   r\   r]   r^   re   rI   rF   ri   rj   rk   rr   rs   rt   r   r   rD   r   rA   r   r   r   r   r   r   rO   r   r   r   r   r    r      sf   




			
	
  
!





	r   )__doc__r   r~   sysr   decimalr   r|   Z	IBridgePyr   IBridgePy.IbridgepyToolsr   r   IBridgePy.constantsr   r   IBridgePy.quantopianr	   Z&broker_client_factory.BrokerClientDefsr
   r   r   r   r   r   objectr   r   r   r   r    <module>   s    