
    T>qj>              	          d Z ddlZddlZddlZddlZddlZddlZddlZddl	m
Z
mZ ddlmZmZmZmZmZmZmZ ddlZ	 ddlmZ  ej4                         Z	  ej                  dddej8                  j:                        Zd	Zej@                  jB                  Z"eej                  ej                  f   Z#d9d
eee$      fdZ%de&fdZ'de(fdZ)de&fdZ*de+fdZ,de$fdZ-d Z.d Z/d:dZ0d Z1ejd                  fdZ3ejd                  fdZ4de5de6fdZ7de5de$fdZ8 G d d      Z9ddded ee5   fd!Z:d"e#dej                  fd#Z;d"e#d$efd%Z<d;d&e5de6fd'Z=d(e#d)e#d*e5deej                     fd+Z>d,e#de6fd-Z?d(e#d)e#d*e5deej                     fd.Z@d,e#de6fd/ZAd0 ZBd1 ZCd2 ZDd<d3e$d4e5fd5ZEd,eej                  ej                  e$df   de$fd6ZGd7e$deej                  ej                  f   fd8ZHy# e$ r
 ddlmZ Y w xY w)=z
Utilities.    N)fieldsis_dataclass)AsyncIterator	AwaitableCallableIteratorListOptionalUnion)ZoneInfoi     tzinfoilabelsc                 6   ddl }ddlm} | rt        |       } | d   }t	        |      rK|j
                  j                  d | D              }t        |      D cg c]  }|j                   c}|_	        nJt        ||      r#|j
                  j                  d | D              }n|j
                  j                  |       }t        |t              rt        |dd      }|r
||_	        nd}|r'|D cg c]	  }||vs| }	}|j                  |	d      }|S c c}w c c}w )	z
    Create pandas DataFrame from the sequence of same-type objects.

    Args:
      labels: If supplied, retain only the given labels and drop the rest.
    r   Nr   )DynamicObjectc              3   2   K   | ]  }t        |        y wN)dataclassAsTuple.0os     M/opt/rentech/trading_bot/.venv/lib/python3.12/site-packages/ib_insync/util.py	<genexpr>zdf.<locals>.<genexpr>/   s     *M1+;A+>*Ms   c              3   4   K   | ]  }|j                     y wr   )__dict__r   s     r   r   zdf.<locals>.<genexpr>2   s     *D!1::*Ds   _fields)axis)pandasobjectsr   listr   	DataFramefrom_recordsr   namecolumns
isinstancetuplegetattrdrop)
objsr   pdr   objdffieldr   labelexcludes
             r   r-   r-   "   s     &Dz1g***M*MMB28+>%**>BJ]+***Dt*DDB**40Bc5!c9d3G$
&(@UE,?5@@WWW1W%I ? As   D,	D6Dreturnc                     t        |       st        d|  d      t        |       D ci c]#  }|j                  t	        | |j                        % c}S c c}w )zm
    Return dataclass values as ``dict``.
    This is a non-recursive variant of ``dataclasses.asdict``.
    Object  is not a dataclass)r   	TypeErrorr   r$   r(   )r,   r.   s     r   dataclassAsDictr6   B   sM    
 '#&9:;;>DSkJUEJJUZZ00JJJs   (Ac                 r     t               st        d  d      t         fdt               D              S )zo
    Return dataclass values as ``tuple``.
    This is a non-recursive variant of ``dataclasses.astuple``.
    r3   r4   c              3   J   K   | ]  }t        |j                          y wr   )r(   r$   )r   r.   r,   s     r   r   z#dataclassAsTuple.<locals>.<genexpr>S   s     Ceejj)Cs    #)r   r5   r'   r   )r,   s   `r   r   r   L   s7    
 '#&9:;;Cvc{CCC    c                 \   t        |       st        d|  d      t        |       D cg c]  }t        | |j                         }}t        t        |       |      D ci c];  \  }}||j                  k7  r'||k(  r"t        |t              r|g k(  s|j                  |= c}}S c c}w c c}}w )z|
    For a ``dataclass`` instance get the fields that are different from the
    default values and return as ``dict``.
    r3   r4   )	r   r5   r   r(   r$   zipdefaultr&   r!   )r,   r.   valuesvalues       r   dataclassNonDefaultsr?   V   s    
 '#&9:;;4:3K@5gc5::&@F@.1&+v.F;*eUEMM!UNE4(Ub[ 	

E; ; A;s   B#A B(c                     t        |       st        d|  d      |D ]&  }| j                  j                  t	        |             (  | j                  j                  di | | S )z
    Update fields of the given ``dataclass`` object from zero or more
    ``dataclass`` source objects and/or from keyword arguments.
    r3   r4    )r   r5   r   updater6   )r,   srcObjskwargssrcObjs       r   dataclassUpdaterF   e   sc    
 '#&9:;; 5OF345CLL!&!Jr9   c                     t        |       }| j                  j                  }dj                  d |j	                         D              }| d| dS )z
    Provide a culled representation of the given ``dataclass`` instance,
    showing only the fields with a non-default value.
    z, c              3   0   K   | ]  \  }}| d |  yw)=NrA   )r   kvs      r   r   z dataclassRepr.<locals>.<genexpr>y   s     >1!AaU|>s   ())r?   	__class____qualname__joinitems)r,   attrsclsNamerD   s       r   dataclassReprrT   r   sJ    
 !%Emm((GYY>>>FYaxq!!r9   c                     t        |       }|j                  }t        |      dk7  s|d   t        k7  ryt	        |dd      }t        |t              syt        d |D              S )z0From https://stackoverflow.com/a/2166841/6067848r   r   Fr   Nc              3   @   K   | ]  }t        |      t        k(    y wr   )typestr)r   ns     r   r   z'isnamedtupleinstance.<locals>.<genexpr>   s     )!tAw#~)s   )rW   	__bases__lenr'   r(   r&   all)xtbfs       r   isnamedtupleinstancera   }   sX    QA	A
1v{adem9d#Aa)q)))r9   c           
         t        | t        t        t        t        t
        f      r| S t        | t        j                  t        j                  f      r| j                         S t        | t              r-| j                         D ci c]  \  }}|t        |       c}}S t        |       r.| j                  D ci c]  }|t        t        | |             c}S t        | t         t"        t$        f      r| D cg c]  }t        |       c}S t'        |       r*| j(                  j*                  t        t-        |             iS t	        |       S c c}}w c c}w c c}w )zo
    Convert object to a tree of lists, dicts and simple values.
    The result can be serialized to JSON.
    )r&   boolintfloatrX   bytesdtdatetime	isoformatdictrQ   treera   r   r(   r!   r'   setr   rN   rO   r?   )r,   rJ   rK   r`   is        r   rl   rl      s    
 #c5#u56
	C"''277+	,}}	C	'*yy{3tq!47
33	c	"25++>Q4Q((>>	C$s+	,!$%AQ%%	c	**D1Ec1J,KLL3x 4>%s   E8E7Ec           
         ddl }ddlm} ddlm} ddlm} t        | |j                        r(| g d   j                  D cg c]  }t        |       }	}n| rKt        | d   d      r<| D 
cg c]0  }
|
j                  |
j                  |
j                  |
j                  f2 }	}
n;| D 
cg c]0  }
|
j                   |
j                  |
j                  |
j                  f2 }	}
|j#                         \  }}|j%                  |       |j'                  d       |j)                  dd	       t+        |	      D ]  \  }\  }}}}||k\  r|}||}}n|}||}} |||f||f|d
      }|j-                  |        |||f||f|d
      }|j-                  |        ||dz
  |fd||z
  ||dd      }|j/                  |        |j1                          |S c c}w c c}
w c c}
w )z{
    Create candlestick plot for the given bars. The bars can be given as
    a DataFrame or as a list of bar objects.
    r   N)Line2D)	Rectangle)openhighlowcloseopen_T
      r   )xdataydatacolor	linewidthg333333?g333333?g?)xywidthheight	edgecolor	facecoloralphaantialiased)r   matplotlib.pyplotpyplotmatplotlib.linesrp   matplotlib.patchesrq   r&   r"   r=   r'   hasattrrv   rs   rt   ru   rr   subplots	set_titlegridset_size_inches	enumerateadd_line	add_patchautoscale_view)barstitleupColor	downColorr+   pltrp   rq   rK   ohlcTupsr_   figaxrY   rv   rs   rt   ru   r{   bodyHibodyLolinerects                          r   barplotr      s   
 #',$%"#CDKKME!HM M	'$q'7+?CD!QWWaffaeeQWW5DD>BCQVVQVVQUUAGG4CCllnGCLLGGDMA(1((; $$E4eE>E"EFFE"EFFa&-	
 	Da&.	
 	DC F?
 	T9< JUM ECs    G
*5G&5Gc                  h    t        j                   t         j                  t         j                         y)zAllow Control-C to end program.N)signalSIGINTSIG_DFLrA   r9   r   
allowCtrlCr      s    
MM&--0r9   c                 H   t        j                         }|j                  r%t        j                  d      j                  |       n|j                  |       t        j                  d      }t        j
                  |       }|j                  |       |j                  |       y)z1Create a log handler that logs to the given file.	ib_insync.%(asctime)s %(name)s %(levelname)s %(message)sN)logging	getLoggerhandlerssetLevel	FormatterFileHandlersetFormatter
addHandler)pathlevellogger	formatterhandlers        r   	logToFiler      s{     F+&//6!!8:I!!$'G#
gr9   c                    t        j                         }|j                  D cg c];  }t        |      t         j                  u r|j
                  t        j                  u r|= }}|r%t        j                  d      j                  |        y|j                  |        t        j                  d      }t        j                         }|j                  |       |j                  |       yc c}w )z.Create a log handler that logs to the console.r   r   N)r   r   r   rW   StreamHandlerstreamsysstderrr   r   r   r   )r   r   hstdHandlersr   r   s         r   logToConsoler      s     F??H7g+++CJJ0F 	
HK H  	+&//6 	%%<>	'')Y''"Hs   A C)r]   c                     | | k7  S )zNot a number test.rA   )r]   s    r   isNanr      s    6Mr9   rY   c                    d}| dk  r|  } |dz  }t        |       t        u r| dk  rt        |       dz   }|S | dk  rd}|S | dk  sJ t        t        j                  t        j
                  |                   }t        |d	      \  }}t        d
      D ]2  }dj                  d
|z
        }|| dd|z  z  z  z  }|dk7  r n	|dz  }d}4 |dz   z  }|dk7  r|d|dz      z  }|S )zBFormat the integer or float n to 3 significant digits + SI prefix. r   -i   g^ 9^;z0.00 g ҉E      z%.{}frw   1000r   zyzafpnum kMGTPEZY   )	rW   rd   rX   mathfloorlog10divmodrangeformat)rY   slogrn   j_trytemplvals           r   formatSIr     s   
A1uB	SAw#~!d(FSL" H! 
U H 7{{$**TZZ]+,c1~1!H 	DNN1q5)E1rb1f~-.Cf}FAA	 	
S3Y6$QU++AHr9   c                   $    e Zd ZdZddZd Zd Zy)timeitzContext manager for timing.c                     || _         y r   )r   )selfr   s     r   __init__ztimeit.__init__   s	    
r9   c                 6    t        j                          | _        y r   )ri   t0)r   s    r   	__enter__ztimeit.__enter__#  s    ))+r9   c                     t        | j                  dz   t        t        j                         | j                  z
        z   dz          y )Nz took r   )printr   r   ri   r   )r   _argss     r   __exit__ztimeit.__exit__&  s1    djj8#htyy{TWW/D&EEKLr9   N)Run)__name__
__module__rO   __doc__r   r   r   rA   r9   r   r   r     s    %Mr9   r   )timeout
awaitablesr   c                 `  	 t               }|s|j                         ry|j                          d}t        j                  dk\  rt        j                  |      }nt
        j                  j                         }|r6t        j                  | }|j                          	 |j                  |       |S |S t        |      dk(  r|d   }nt        j                  | }| rt        j                  ||       }t        j                  |      		fd}t        j!                  |       	 |j                  	      }	 t        j%                  |       |S # t
        j                  $ r Y |S w xY w# t
        j                  $ r}t        j#                         xs |d}~ww xY w# t        j%                  |       w xY w)a]  
    By default run the event loop forever.

    When awaitables (like Tasks, Futures or coroutines) are given then
    run the event loop until each has completed and return their results.

    An optional timeout (in seconds) can be given that will raise
    asyncio.TimeoutError if the awaitables are not ready within the
    timeout period.
    N)r      r   r   c                 &    j                          y r   )cancel)_tasks    r   onErrorzrun.<locals>.onErrorP  s    KKMr9   )getLoop
is_runningrun_foreverr   version_infoasyncio	all_tasksTaskgatherr   run_until_completeCancelledErrorr[   wait_forensure_futureglobalErrorEventconnectr>   
disconnect)
r   r   loopresultr   r`   futurer   er   s
            @r   runr   *  s{    9D??v%))$/I..0I	*AHHJ''*. M6M' z?a]F^^Z0F%%fg6F$$V,	 	  )	1,,T2F ''0M- )) * M-" %% 	0"((*/a/	0 ''0s6   E	  E# 	E E #F6FFF F-ri   c                     t        | t        j                        r>t        j                  j	                  t        j
                  j                         |       }|S | }|S r   )r&   rg   ri   datetimecombinerh   today)ri   r^   s     r   	_fillDater  ^  sC    $ KK6 H Hr9   callbackc                     t        |       }t        j                  j                  |j                        }||z
  j                         }t               } |j                  ||g| S )aY  
    Schedule the callback to be run at the given time with
    the given arguments.
    This will return the Event Handle.

    Args:
        time: Time to run callback. If given as :py:class:`datetime.time`
            then use today as date.
        callback: Callable scheduled to run.
        args: Arguments for to call callback with.
    )r  rg   r  nowr   total_secondsr   
call_later)ri   r  argsr^   r  delayr   s          r   scheduler  g  sT     	$A
++//!((
#CW##%E9D4??5(2T22r9   secsc                 @    t        t        j                  |              y)z
    Wait for the given amount of seconds while everything still keeps
    processing in the background. Never use time.sleep().

    Args:
        secs (float): Time in seconds to wait.
    T)r   r   sleep)r  s    r   r  r  z  s     dr9   startendstepc              #   n  K   |dkD  sJ t        j                  |      }t        |       }|j                  rt         j                  j
                  nd}t         j                  j                  |      }||k  r||z  }||k  r|t        |      k  r$t        |       | ||z  }|t        |      k  r#yyw)a  
    Iterator that waits periodically until certain time points are
    reached while yielding those time points.

    Args:
        start: Start time, can be specified as datetime.datetime,
            or as datetime.time in which case today is used as the date
        end: End time, can be specified as datetime.datetime,
            or as datetime.time in which case today is used as the date
        step (float): The number of seconds of each period
    r   secondsN)	rg   	timedeltar  r   timezoneutcr  r  	waitUntilr  r  r  deltar^   tzr  s          r   	timeRanger    s      !8O8LL&E%AHH$B
++//"
C
c'	U
 c'
y~
!	U
 y~
s   A?B50B53B5r^   c                     t         j                  j                  | j                        }t	        |       |z
  j                         }t        t        j                  |             y)z
    Wait until the given time t is reached.

    Args:
        t: The time t can be specified as datetime.datetime,
            or as datetime.time in which case today is used as the date.
    T)	rg   r  r  r   r  r	  r   r   r  r^   r  r  s      r   r  r    sE     ++//!((
#CaL3--/Ddr9   c                  K   |dkD  sJ t        j                  |      }t        |       }|j                  rt         j                  j
                  nd}t         j                  j                  |      }||k  r||z  }||k  r|t        |      k  r-t        |       d{    | ||z  }|t        |      k  r,yy7 w)z#Async version of :meth:`timeRange`.r   r  N)	rg   r  r  r   r  r  r  r  waitUntilAsyncr  s          r   timeRangeAsyncr#    s     
 !8O8LL&E%AHH$B
++//"
C
c'	U
 c'
y~
Q	U
 y~
s   A?C C B>C <C c                    K   t         j                  j                  | j                        }t	        |       |z
  j                         }t        j                  |       d{    y7 w)z#Async version of :meth:`waitUntil`.NT)rg   r  r  r   r  r	  r   r  r   s      r   r"  r"    sM     
++//!((
#CaL3--/D
--
 s   AA( A&!A(c                  ,    ddl } | j                          y)z*Patch asyncio to allow nested event loops.r   N)nest_asyncioapply)r&  s    r   patchAsyncior(    s    r9   c                  F    t        j                         j                         S )z2Get the asyncio event loop for the current thread.)r   get_event_loop_policyget_event_looprA   r9   r   r   r     s    ((*99;;r9   c                      t                y)z4Use nested asyncio event loop for Jupyter notebooks.N)r(  rA   r9   r   	startLoopr-    s    Nr9   qtLibperiodc                      fd dvrt        d        ddlm}  | dz          | dz         }|j                  j	                         xs |j                  t
        j                        at               g          y)	z
    Run combined Qt5/asyncio event loop.

    Args:
        qtLib: Name of Qt library to use:

          * PyQt5
          * PyQt6
          * PySide2
          * PySide6
        period: Period in seconds to poll Qt.
    c                     j                         sXj                         } j                         }|j                  j	                  | j
                         j                  | |f       j                         \  } }|j                  d       dk(  r| j                         n| j                          |j                          j                  | |f       t        j                          y )Nr   PyQt6)r
  
QEventLoopQTimerr   r   quitappendpopr  execexec_stopqAppprocessEvents)qlooptimerr   r/  qcr.  qt_stepstacks     r   r@  zuseQt.<locals>.qt_step  s    (MMOEIIKEMM!!%**-LL%(yy{uA(

ekkm

eU^$r9   )PyQt5r2  PySide2PySide6zUnknown Qt library: r   )import_modulez.QtCorez
.QtWidgetsN)	RuntimeError	importlibrE  QApplicationinstancer   argvr;  r   )r.  r/  rE  qwr   r?  r@  rA  s   ``  @@@@r   useQtrL    s      <<1%9::'	uy(	)B	u|+	,BOO$$& )sxx( 	9DEIr9   c                    | sd}|S t        | t        j                        r=| j                  t        j                  j
                        } | j                  d      }|S t        | t        j                        rst        j                  | j                  | j                  | j                  ddd      j                  t        j                  j
                        } | j                  d      }|S | }|S )z/Format date or datetime to string that IB uses.r   )r  z%Y%m%d %H:%M:%S UTC   ;   )r&   rg   r  
astimezoner  r  strftimerh   yearmonthday)r^   r   s     r   formatIBDatetimerU     s     H 
Ar{{	#LLBKKOOL,JJ,- H 
Arww	KKFFAGGQUUBB00:
bkkoo
0N 	
JJ,- H Hr9   r   c                    t        |       dk(  rCt        | dd       }t        | dd       }t        | dd       }t        j                  |||      }|S | j	                         rCt        j
                  j                  t        |       t        j                  j                        }|S | j                  d      dk\  rZd| vrV| j                  dd      \  }}}t        j
                  j                  ||z   d      }|j                  t        |      	      }|S | j                  dd
      j                  dd
      dd }t        j
                  j                  |d      }|S )z7Parse string in IB date or datetime format to datetime.r   r      rx   r   r   z  z%Y%m%d%H:%M:%Sr   r   r   N   )r[   rd   rg   rh   isdigitr  fromtimestampr  r  countsplitstrptimereplacer   )	r   ymdr^   s0s1s2sss	            r   parseIBDatetimerf    s,   
1v{!AK!AK!AKGGAq! H 
KK%%c!fbkkoo> H 
	t1}WWS!_
BKK  b*:;IIXb\I* H YYsB''R0"5KK  %56Hr9   r   )r   bluered)g{Gz?)rB  g{Gz?)Ir   r   r  rg   r   r   r   r   ri   dataclassesr   r   typingr   r   r   r   r	   r
   r   eventkitevzoneinfor   ImportErrorbackports.zoneinfoEventr   r  r  EPOCHUNSET_INTEGER
float_infomaxUNSET_DOUBLETime_trX   r-   rk   r6   r'   r   r?   objectrF   rT   ra   rl   r   r   INFOr   r   re   rc   r   r   r   r   r  r  r  r  r  r#  r"  r(  r   r-  rL  rh   rU  rf  rA   r9   r   <module>ry     s         
  ,I I I ,!
 288:  	D!Qr{{7~~!!	rww#	$Xd3i( @KD KDU D; ;
 
"# "	**5p1
 ",,  || #(U t 
 # 6
M 
M <@ 1Y 1% 1hF r{{ 36 3X 3&	 	 	V &  BKK 4 D   &bkk2$F t <

% % %Pbggr{{C=> 3 "s uRWWbkk%9:   ,++,s   G- -G<;G<