B
     9-e/V                 @   sl  d dl 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
 d dlm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 d d
lmZ d dlmZ G dd deZ	G dd de	ZG dd de	ZG dd de	ZG dd de	ZG dd de	Z G dd de	Z!G dd de	Z"G dd de	Z#G dd de	Z$G d d! d!eZ%G d"d# d#e&Z'd$d% Z(dS )&    N)exit)isAllLettersCapital)PrintableII	Printable)base_settings)%get_user_input_and_set_default_values)setup_services)TimeGeneratorFactory)DataProviderNameLiveBacktestTraderRunModeTimeGeneratorType
MarketName
BrokerName)BrokerClientFactory)DataProviderFactoryc               @   s$   e Zd Zdd Zdd Zdd ZdS )Configc             C   s"   x|D ]}t | |||  qW d S )N)setattr)selfdict_settingskey 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\Config\config_defs.py__init__   s    
zConfig.__init__c             C   s   x|D ]}t || trd }yt| |}W n: tk
rd } zttd|f   t  W d d }~X Y nX || }xP|D ]4}||kr|| ||< qtttd||f   t  qtW q| ||| | qW | S )NzP::override: EXIT, %s. Hint: Check Config::base_settings if it has the attribute.zZ::override: EXIT, key=%s in the file of <%s.py> does not exist in Config::base_settings.py)
isinstancedictgetattrAttributeErrorprint__name__r   	set_value)r   settingsZsettingFileNamer   ZoriginalValueseZnewValueDictkr   r   r   override    s     

zConfig.overridec             C   sH   t | |rt| || n,ttd| j||f   td| f  t  dS )z

        :param fieldName:
        :param value:
        :param settingName: string, used to display the fileName/source of the settings
        :return:
        z?::set_value: class=%s key=%s settingFileName=%s does not exist.zbase_config: %sN)hasattrr   r   r   	__class__r   )r   Z	fieldNamevaluesettingNamer   r   r   r    5   s
    
zConfig.set_valueN)r   
__module____qualname__r   r$   r    r   r   r   r   r      s   r   c               @   s   e Zd Zdd ZdS )BACKTESTER_Configc             C   s   t | | d S )N)r   r   )r   r   r   r   r   r   G   s    zBACKTESTER_Config.__init__N)r   r)   r*   r   r   r   r   r   r+   F   s   r+   c               @   s   e Zd Zdd ZdS )MARKET_MANAGER_Configc             C   s   t | | d S )N)r   r   )r   r   r   r   r   r   M   s    zMARKET_MANAGER_Config.__init__N)r   r)   r*   r   r   r   r   r   r,   L   s   r,   c               @   s   e Zd Zdd ZdS )REPEATER_Configc             C   s   t | | d S )N)r   r   )r   r   r   r   r   r   S   s    zREPEATER_Config.__init__N)r   r)   r*   r   r   r   r   r   r-   R   s   r-   c               @   s   e Zd Zdd ZdS )TIME_GENERATOR_Configc             C   s   t | | d S )N)r   r   )r   r   r   r   r   r   Y   s    zTIME_GENERATOR_Config.__init__N)r   r)   r*   r   r   r   r   r   r.   X   s   r.   c               @   s   e Zd Zdd ZdS )BROKER_SERVICE_Configc             C   s   t | | d S )N)r   r   )r   r   r   r   r   r   _   s    zBROKER_SERVICE_Config.__init__N)r   r)   r*   r   r   r   r   r   r/   ^   s   r/   c               @   s   e Zd Zdd ZdS )PROJECT_Configc             C   s   t | | d S )N)r   r   )r   r   r   r   r   r   e   s    zPROJECT_Config.__init__N)r   r)   r*   r   r   r   r   r   r0   d   s   r0   c               @   s   e Zd Zdd ZdS )TRADER_Configc             C   s   t | | d S )N)r   r   )r   r   r   r   r   r   k   s    zTRADER_Config.__init__N)r   r)   r*   r   r   r   r   r   r1   j   s   r1   c               @   s   e Zd Zdd ZdS )BROKER_CLIENT_Configc             C   s   t | | d S )N)r   r   )r   r   r   r   r   r   q   s    zBROKER_CLIENT_Config.__init__N)r   r)   r*   r   r   r   r   r   r2   p   s   r2   c               @   s   e Zd Zdd ZdS )EMAIL_CLIENT_Configc             C   s   t | | d S )N)r   r   )r   r   r   r   r   r   w   s    zEMAIL_CLIENT_Config.__init__N)r   r)   r*   r   r   r   r   r   r3   v   s   r3   c               @   sD   e 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S )UserConfigBasec             C   s   d| _ d| _d| _d| _d| _d| _d| _d| _d| _d| _	d| _
d| _d| _d| _d| _d| _d| _d| _d| _d| _d| _d| _d| _d| _t | _t | _t | _dS )z
        For example, there is a file Config::hft_settings.py Then, a possible value of addOnSettings is "hft_settings"
        N)projectConfigmarketManagerConfigrepeaterConfigbacktesterConfigtimeGeneratorConfigtraderConfigbrokerClientConfigemailClientConfiginitialize_quantopianhandle_data_quantopianbefore_trading_start_quantopianZtimeGeneratorZdataFromServerZsingleTradertraderdataProviderlogZuserLogZ
balanceLogZtransactionLogZbrokerServicedataProviderServicebrokerClientZemailClientr   brokerClientFactoryr	   timeGeneratorFactoryr   ZdataProviderFactory)r   r   r   r   r   }   s6    zUserConfigBase.__init__c             C   s  t |}xt|D ]}t|r|dkr<tt||| _q|dkrVtt||| _q|dkrpt	t||| _
q|dkrtt||| _q|dkrtt||| _q|dkrtt||| _q|dkrtt||| _q|dkrtt||| _qttd	||f   t  qW | S )
NPROJECTMARKET_MANAGER
BACKTESTERREPEATERTIME_GENERATORTRADERBROKER_CLIENTEMAIL_CLIENTz5::load_settings: EXIT, cannot handle item=%s in %s.py)	importlibimport_moduledirr   r0   r   r5   r,   r6   r+   r8   r-   r7   r.   r9   r1   r:   r2   r;   r3   r<   r   r   r   )r   str_settingsmodule_settingsitemr   r   r   load_settings   s,    

zUserConfigBase.load_settingsc             C   s8  t |}x&t|D ]}t|r|dkrB| jt||| q|dkr`| jt||| q|dkr~| jt||| q|dkr| j	t||| q|dkr| j
t||| q|dkr| jt||| q|dkr| jt||| q|dkr| jt||| qttd	||f   t  qW | S )
NrG   rH   rJ   rI   rK   rL   rM   rN   z/::overrideBy: EXIT, cannot handle item=%s in %s)rO   rP   rQ   r   r5   r$   r   r6   r7   r8   r9   r:   r;   r<   r   r   r   )r   rR   rS   rT   r   r   r   
overrideBy   s,    


zUserConfigBase.overrideByc             C   s  |d }x|D ]}|dkrH| j || | td|||| f  q|dkrz| j|| | td|||| f  q|dkr| j|| | td|||| f  q|dkr| j|| | td|||| f  q|dkr| j|| | td|||| f  q|dkrF| j|| | td|||| f  q|d	krz| j|| | td|||| f  q|d
kr| j	|| | td|||| f  qqW | S )NfileNamerG   z(special config from %s: item=%s value=%srH   rJ   rK   rL   rM   rN   rI   )
r5   r$   r   r6   r7   r9   r:   r;   r<   r8   )r   Zdict_passedInrW   rT   r   r   r   overrideByConfigDict   s8    


z#UserConfigBase.overrideByConfigDictc             C   sp  t t d | jjtjkrtd td | jj	dkrv| j
jtjkrZtj| j
_td | jjdkrvd| j_td | jjtjkr| jjd ks| jjd krtd| jj| jjf  t  | jjtjkrtd	 | jjrd
| j_td | j
jtjtjgkr$| jjdkr$td| jjf  t  | jjtjtjtjgkr\| jd kr\td| jjf | j d k	slt!d S )Nz::validate_after_build_traderzcBacktester ignores order.tif=DAY and handles them as order.tif=GTC. We are working on this feature.zPSimulate trading commission by settings.py --> BACKTESTER --> simulateCommissionTz[IBridgePy has reset the TRADER.runMode to RUN_LIKE_QUANTOPIAN for backtesting to save time!<   zCIBridgePy has reset projectConfig.repBarFreq to 60 for backtesting!z]Backtester in TimeGeneratorType.AUTO but staringTime=%s endingTime=%s They should not be NonezYWARNING: Backtester with a LIVE timeGenerator should be used to get historical data only.FzOWARNING: The feature of AutoReconnect is turned off under the backtesting mode.zEXIT, projectConfig.repBarFreq=%s It should be 60 when traderConfig.runMode is either RUN_LIKE_QUANTOPIAN or SUDO_RUN_LIKE_QUANTOPIANz2self.dataProviderClient in dataProvider_%s is None)"loggingdebugr   r5   ZliveOrBacktestr   BACKTESTr   r8   ZoverrideValuesr:   runModer   RUN_LIKE_QUANTOPIAN
repBarFreqr9   timeGeneratorTyper   ZAUTOstartingTime
endingTimer   LIVEautoReconnectPremiumSUDO_RUN_LIKE_QUANTOPIANdataProviderNamer
   IBTD	ROBINHOODrA   RuntimeErrorr@   AssertionError)r   r   r   r   validate_after_build_trader   s8    
z*UserConfigBase.validate_after_build_traderc             C   s  t t d|  x0dD ](}t||r| j|t||td  qW t|drf| jd|jtd  t|dr| j	d|j
td  t|dr| j	d|jtd  t|d	r| j	d	|jtd  t|d
r,| j	d
|jtd  |jtjkr,t|dr| j	d|jtd  nttd  t  t|dr|jtjtjgkr| jddtd  | jd|jtd  |jtjkr| jdtjtd  |j| _|j| _|j| _d S )Nz+::load_userInput_to_userConfig: user_input=)accountCoder_   rW   logLevelrf   histIngestionPlanz::load_userInput_to_userConfig
marketName	startTimera   endTimerb   freqr`   customSpotTimeListcustomz0::load_input: EXIT, customSpotTimeList is empty.r]   r_   rY   ) rZ   r[   r   r%   r5   r    r   r6   rp   r9   rq   rr   rs   r`   r   ZCUSTOMrt   r   r   r]   r   r^   re   r:   r   ZNONSTOP
initializer=   handle_datar>   Zbefore_trading_startr?   )r   Z
user_inputrT   r   r   r   load_userInput_to_userConfig  s8    





z+UserConfigBase.load_userInput_to_userConfigc             C   sX  t t d | | t|}| | | jjsB| jjt	j
kr~| jjd rt| jjd }td|f  || j_ntd n| jjt	jkr| jjd r| jjd }td|f  || j_ntd n|| jjt	jkr| jjd r| jjd }td|f  || j_ntd n0| jjt	jkr,d	| j_nttd
| jjf   t| | |   d S )Nz ::prepare_userConfig_with_traderrm   zoUser does not specify an accountCode. IBridgePy uses %s from settings.py::BROKER_CLIENT::TD_CLIENT::accountCodezsEXIT, projectConfig.accountCode is empty. Please go to settings.py --> BROKER_CLIENT --> TD_CLIENT --> accountCode.zoUser does not specify an accountCode. IBridgePy uses %s from settings.py::BROKER_CLIENT::IB_CLIENT::accountCodezsEXIT, projectConfig.accountCode is empty. Please go to settings.py --> BROKER_CLIENT --> IB_CLIENT --> accountCode.zvUser does not specify an accountCode. IBridgePy uses %s from settings.py::BROKER_CLIENT::ROBINHOOD_CLIENT::accountCodezzEXIT, projectConfig.accountCode is empty. Please go to settings.py --> BROKER_CLIENT --> ROBINHOOD_CLIENT --> accountCode.ZdummyAccountCodezV::prepare_userConfig_with_trader: EXIT, cannot handle self.projectConfig.brokerName=%s)rZ   r[   r   rX   r   rx   r5   rm   Z
brokerNamer   rh   r;   Z	TD_CLIENTr   r   rg   Z	IB_CLIENTri   ZROBINHOOD_CLIENTLOCALr   rl   )r   r@   ZglobalsVZ	userInputrm   r   r   r   prepare_userConfig_with_traderD  s8    










z-UserConfigBase.prepare_userConfig_with_traderN)
r   r)   r*   r   rU   rV   rX   rl   rx   rz   r   r   r   r   r4   |   s   $!&&r4   c               @   s$   e Zd Zedd Zedd ZdS )
UserConfigc             C   s  d }| dkr&t  ddd}n| dkrHt  ddd}n| dkrjt  ddd}n| d	krt  dd
d}n~| dkrt  ddd}n\| dkrt  ddd}n:| dkrt  ddd}nttd| f   t  |S )Nr\   zConfig.base_settingszConfig.backtest_settingsr!   HFTzConfig.hft_settingsri   zConfig.robinhood_settingsrh   zConfig.td_settingsrg   zConfig.ib_settingsZIBinsynczConfig.ibinsync_settingsry   zConfig.localBroker_settingsz)::get_config: EXIT, cannot handle name=%s)r4   rU   rV   r   r   r   )nameansr   r   r   
get_configx  s$    zUserConfig.get_configc             C   sN   t | tr| g}n| }t d}x|D ]}|d|f }q(W |d}|S )NzConfig.base_settingsz	Config.%sr!   )r   strr4   rU   rV   )ZsettingNamesZlist_settingNamer~   r(   r   r   r   choose  s    


zUserConfig.chooseN)r   r)   r*   staticmethodr   r   r   r   r   r   r{   w  s   r{   c               C   s4   t ddkstt ddks tt ddks0td S )NZ
asdfEdasdfFrM   TZBROKER_CLIENt)r   rk   r   r   r   r   test__isAllLettersCapital  s    r   ))rO   sysr   rZ   BasicPyLib.BasicToolsr   ZBasicPyLib.Printabler   r   r   r   ZConfig.configToolsr   IBridgePy.MarketManagerBaser   ZIBridgePy.TimeGeneratorr	   IBridgePy.constantsr
   r   r   r   r   r   Z*broker_client_factory.BrokerClient_factoryr   Z+data_provider_factory.data_provider_factoryr   r+   r,   r-   r.   r/   r0   r1   r2   r3   r4   objectr{   r   r   r   r   r   <module>   s2    + |'