B
     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\02 Python 3.7 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 )zB
        Name of the broker

        :return: string name
        N)r'   r$   )r   r   r   r    
brokerName7   s    zBrokerService.brokerNamec             C   s   | j jS )N)r#   versionNumber)r   r   r   r    r)   @   s    zBrokerService.versionNumberc             C   s   | j S )N)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 )N)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 k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   r5   r   r   r4   )r   r6   r7   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   r6   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   r5   r   r3   r   get_positionr(   )r   r-   r6   Zadj_securityr   r   r    _get_position^   s    zBrokerService._get_positionc             C   sD   | j | j|}i }x*|D ]"}|| j}t|}|| ||< qW |S )N)r   get_all_positionsr(   contractr	   )r   r-   ZallPositionsr8   Zstr_securityrA   r6   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   r5   r   r   get_all_ordersr(   )r   r-   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   r5   r   r3   symbolStatusr   SUPER_SYMBOLr#   Zappend_security_infoZadd_primaryExchange_to_securityZadd_exchange_to_security)r   r6   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   r5   r   submit_requestsr
   )r   ibpyOrderIdr   r   r    cancel_order   s    zBrokerService.cancel_orderc             C   s   | j td  | j S )Nz	::connect)r   r5   r   r#   ZconnectWrapper)r   r   r   r    connect   s    zBrokerService.connectc             C   s    | j t d | j  d S )Nz::disconnect: )r   r5   r   r#   disconnectWrapper)r   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_time)r   r   r   r    rN      s    zBrokerService.get_next_timec             C   sh   | j td||f   t|tr0| |||S t|trdg }x |D ]}|| ||| qDW |S d S )Nz*::get_account_info: accountCode=%s tags=%s)r   r5   r   
isinstancestrr0   listappend)r   r-   tagsr/   r8   r.   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   r8   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   r5   r   r   Zget_all_active_accountCodesr(   )r   r   r   r    get_active_accountCodes   s    z%BrokerService.get_active_accountCodesc             C   sj   | j td|f   | |}g }x@|D ]8}|| j}|tjtjtjtj	tj
gkr*|||  q*W |S )Nz%::get_all_open_orders: accountCode=%s)r   r5   r   rC   statusr   
APIPENDINGPENDINGSUBMITPENDINGCANCELPRESUBMITTED	SUBMITTEDrR   )r   r-   Z	allOrdersr8   rI   rW   r   r   r    get_all_open_orders   s    


z!BrokerService.get_all_open_ordersc             C   s   t | jd S )N)r'   r$   )r   r-   r   r   r    rC      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
        N)r'   r$   )r   r-   r   r   r    r@      s    zBrokerService.get_all_positions   c             C   s   t | jd S )N)r'   r$   )r   r6   fieldwaitForFeedbackInSecondsr   r   r    get_contract_details   s    z"BrokerService.get_contract_detailsc             C   s
   | j  S )N)r#   get_heart_beats)r   r   r   r    rb      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_expiry)r   r   r   r    get_ibpy_expiry_in_days   s    z%BrokerService.get_ibpy_expiry_in_daysc             C   s   ddddddddd	d
dddddddddddg}i }x |D ]}||kr8|| ||< q8W |  t||d}|  t|d  | j|d S )NZnumberOfRowsZ
instrumentZlocationCodeZscanCodeZ
abovePriceZ
belowPriceZaboveVolumeZmarketCapAboveZmarketCapBelowZmoodyRatingAboveZmoodyRatingBelowZspRatingAboveZspRatingBelowZmaturityDateAboveZmaturityDateBelowZcouponRateAboveZcouponRateBelowZexcludeConvertibleZaverageOptionVolumeAboveZscannerSettingPairsZstockTypeFilter)r`   r   )rH   r   r   r#   get_submit_requests_result)r   r`   kwargstagListZsubscriptionct	reqIdListr   r   r    get_scanner_results   s    

z!BrokerService.get_scanner_resultsc             C   s
   | j  S )N)r#   "get_TD_access_token_expiry_in_days)r   r   r   r    rj      s    z0BrokerService.get_TD_access_token_expiry_in_daysc             C   s
   | j  S )N)r#   get_new_TD_refresh_token)r   r   r   r    rk      s    z&BrokerService.get_new_TD_refresh_tokenN    Tc	       
      C   s   | j td|||||||f   |dk	rt|dkrt|jdk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=%sNrl   z>::request_historical_data: EXIT, endTime=%s must have timezone)tzz%Y%m%d %H:%M:%S %Z)followUpr   )r   r5   r   tzinfoerrorr   
astimezonepytzutcdtdatetimestrftimer   ZsecTyperH   r   r#   rd   )
r   r6   barSizeZgoBackendTime
whatToShowZuseRTHr`   ro   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
        N)r'   r$   )r   rI   r   r   r    	get_order  s    zBrokerService.get_orderc             C   s   t | jd S )N)r'   r$   )r   r-   r6   r   r   r    r>     s    zBrokerService.get_positionc             C   s   t | jd S )N)r'   r$   )r   r6   r7   ro   r   r   r    get_real_time_price"  s    z!BrokerService.get_real_time_pricec             C   s   t | jd S )N)r'   r$   )r   r6   r7   ro   r   r   r    r<   %  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   r6   r7   r   r   r    get_timestamp(  s    zBrokerService.get_timestampc             C   s   t | jd S )N)r'   r$   )r   r6   r7   ro   r   r   r    get_real_time_size+  s    z BrokerService.get_real_time_sizec             C   s   t | jd S )N)r'   r$   )r   rI   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 }x|D ]}|dkrn| j	
|tjj|||< qH|dkr| j	
|tjjd||< qH|dkr| j	
|tjjd||< qHttd| |f   qHW |S )Nz(::get_option_info: security=%s fields=%s)r`   )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   r5   r   r3   rP   r#   Zis_real_time_price_requestedrH   r   r   r4   r   ZTickTypeZLAST_OPTION_COMPUTATIONZOPTION_CALL_OPEN_INTERESTZOPTION_PUT_OPEN_INTERESTr   )r   r6   fieldsr`   r8   	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   )rA   orderro   r`   z4No order was placed because order.totalQuantity = 0.ZNoOrderPlaced)r   r5   r   ZrequestedContractZrequestedOrderr   rH   r   r#   rd   info)r   ZibridgePyOrderro   r`   rA   r   rh   r   r   r    place_orderC  s    zBrokerService.place_orderc             C   s   | j |S )N)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    rH   R  s    zBrokerService.submit_requestsc             C   s
   | j  S )N)r#   use_next_id)r   r   r   r    r   [  s    zBrokerService.use_next_id)r,   )r,   )r^   )Nrl   rm   r^   T)T)T)T)r^   )r^   )Tr^   )1r   
__module____qualname__r!   propertyr#   r&   r$   r(   r)   r*   r+   r0   r9   r;   r=   r?   rB   rD   rG   rJ   rK   rM   rN   rT   rU   rV   r]   rC   r@   ra   rb   rc   ri   rj   rk   r{   r|   r>   r}   r<   r~   r   r   r   r   r   rH   r   r   r   r   r    r      s\   		
			
	
 
 





	r   )__doc__rv   ru   sysr   decimalr   rs   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    