
    'ih8                         d dl mZmZmZmZ d dlZd dlmZ d dlZd dl	Z
d dlZd dlmZ d dlmZmZ  G d dej"                        Z G d d	 eee            Z G d
 dej*                        Z G d d eee            Zy)    )absolute_importdivisionprint_functionunicode_literalsN)OrderedDict)	TimeFrame)MAXINTwith_metaclassc                   (     e Zd Z fdZ fdZ xZS )MetaAnalyzerc                    t        t        | 
  |i |\  }}}t               |_        t
        j                  j                  |t
        j                        x|_	        }t
        j                  j                  |t              |_        t
        j                  j                  |t
        j                        }||j                  |       |j                  |_        |j                  r|j                  d   x|_        }t!        |j"                        D ]8  \  }}|j%                  |      }	|	rt'        |d|	z  |       t'        |d|z  |       : t!        |j                        D ]i  \  }
}t'        |d|
z  |       t!        |j"                        D ]<  \  }}|j%                  |      }	|	rt'        |d|
|	fz  |       t'        |d|
|fz  |       > k |j)                          |||fS )z2
        Intercept the strategy parameter
        r   zdata_%szdata_%dzdata%dz	data%d_%sz	data%d_%d)superr   donewlist	_childrenbtmetabase	findownerStrategystrategyAnalyzer_parentObserver_register_analyzerdatasdata	enumeratelines_getlinealiassetattrcreate_analysis)clsargskwargs_objr   	masterobsr   lline	linealiasd	__class__s              Q/var/www/app/trading-bot/venv/lib/python3.12/site-packages/backtrader/analyzer.pyr   zMetaAnalyzer.donew#   s   
 #<;TLVLdF#%;;#8#8r{{#KK{{,,T8< KK))$<	 ((.^^
 ::#zz!},DI$TZZ0 34 ..q1	D)i"7>i!mT2	3 %TZZ0 >4hlD1(4 >GAt $ 2 21 5I kQ	N&BDID+A"6=	>> 	 T6!!    c                     t        t        | 
  |g|i |\  }}}|j                  |j                  j	                  |       |||fS N)r   r   
dopostinitr   	_register)r"   r%   r#   r$   r+   s       r,   r0   zMetaAnalyzer.dopostinitN   sT    ,/FtFvF 	dF <<#LL""4( T6!!r-   )__name__
__module____qualname__r   r0   __classcell__r+   s   @r,   r   r   "   s    )"V" "r-   r   c                       e Zd ZdZdZd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zy)r   a  Analyzer base class. All analyzers are subclass of this one

    An Analyzer instance operates in the frame of a strategy and provides an
    analysis for that strategy.

    Automagically set member attributes:

      - ``self.strategy`` (giving access to the *strategy* and anything
        accessible from it)

      - ``self.datas[x]`` giving access to the array of data feeds present in
        the the system, which could also be accessed via the strategy reference

      - ``self.data``, giving access to ``self.datas[0]``

      - ``self.dataX`` -> ``self.datas[X]``

      - ``self.dataX_Y`` -> ``self.datas[X].lines[Y]``

      - ``self.dataX_name`` -> ``self.datas[X].name``

      - ``self.data_name`` -> ``self.datas[0].name``

      - ``self.data_Y`` -> ``self.datas[0].lines[Y]``

    This is not a *Lines* object, but the methods and operation follow the same
    design

      - ``__init__`` during instantiation and initial setup

      - ``start`` / ``stop`` to signal the begin and end of operations

      - ``prenext`` / ``nextstart`` / ``next`` family of methods that follow
        the calls made to the same methods in the strategy

      - ``notify_trade`` / ``notify_order`` / ``notify_cashvalue`` /
        ``notify_fund`` which receive the same notifications as the equivalent
        methods of the strategy

    The mode of operation is open and no pattern is preferred. As such the
    analysis can be generated with the ``next`` calls, at the end of operations
    during ``stop`` and even with a single method like ``notify_trade``

    The important thing is to override ``get_analysis`` to return a *dict-like*
    object containing the results of the analysis (the actual format is
    implementation dependent)

    Tc                 ,    t        | j                        S )zSupport for invoking ``len`` on analyzers by actually returning the
        current length of the strategy the analyzer operates on)lenr   selfs    r,   __len__zAnalyzer.__len__   s     4==!!r-   c                 :    | j                   j                  |       y r/   )r   appendr;   childs     r,   r1   zAnalyzer._register   s    e$r-   c                 f    | j                   D ]  }|j                           | j                          y r/   )r   _prenextprenextr?   s     r,   rB   zAnalyzer._prenext   s*    ^^ 	ENN	 	r-   c                 n    | j                   D ]  }|j                  ||        | j                  ||       y r/   )r   _notify_cashvaluenotify_cashvalue)r;   cashvaluer@   s       r,   rE   zAnalyzer._notify_cashvalue   s7    ^^ 	1E##D%0	1 	dE*r-   c                 v    | j                   D ]  }|j                  ||||        | j                  ||||       y r/   )r   _notify_fundnotify_fund)r;   rG   rH   	fundvaluesharesr@   s         r,   rJ   zAnalyzer._notify_fund   s?    ^^ 	?EtUIv>	? 	ui8r-   c                 j    | j                   D ]  }|j                  |        | j                  |       y r/   )r   _notify_tradenotify_trade)r;   trader@   s      r,   rO   zAnalyzer._notify_trade   3    ^^ 	'E&	' 	% r-   c                 j    | j                   D ]  }|j                  |        | j                  |       y r/   )r   _notify_ordernotify_order)r;   orderr@   s      r,   rT   zAnalyzer._notify_order   rR   r-   c                 f    | j                   D ]  }|j                           | j                          y r/   )r   
_nextstart	nextstartr?   s     r,   rX   zAnalyzer._nextstart   s-    ^^ 	E	 	r-   c                 f    | j                   D ]  }|j                           | j                          y r/   )r   _nextnextr?   s     r,   r[   zAnalyzer._next   )    ^^ 	EKKM	 			r-   c                 f    | j                   D ]  }|j                           | j                          y r/   )r   _startstartr?   s     r,   r_   zAnalyzer._start   s)    ^^ 	ELLN	 	

r-   c                 f    | j                   D ]  }|j                           | j                          y r/   )r   _stopstopr?   s     r,   rb   zAnalyzer._stop   r]   r-   c                      y)z;Receives the cash/value notification before each next cycleN )r;   rG   rH   s      r,   rF   zAnalyzer.notify_cashvalue       r-   c                      y)z;Receives the current cash, value, fundvalue and fund sharesNre   )r;   rG   rH   rL   rM   s        r,   rK   zAnalyzer.notify_fund   rf   r-   c                      y)z3Receives order notifications before each next cycleNre   )r;   rV   s     r,   rU   zAnalyzer.notify_order   rf   r-   c                      y)z3Receives trade notifications before each next cycleNre   )r;   rQ   s     r,   rP   zAnalyzer.notify_trade   rf   r-   c                      y)zpInvoked for each next invocation of the strategy, once the minum
        preiod of the strategy has been reachedNre   r:   s    r,   r\   zAnalyzer.next        	r-   c                 $    | j                          y)zInvoked for each prenext invocation of the strategy, until the minimum
        period of the strategy has been reached

        The default behavior for an analyzer is to invoke ``next``
        Nr\   r:   s    r,   rC   zAnalyzer.prenext   s     			r-   c                 $    | j                          y)zInvoked exactly once for the nextstart invocation of the strategy,
        when the minimum period has been first reached
        Nrm   r:   s    r,   rY   zAnalyzer.nextstart   s     			r-   c                      y)zgInvoked to indicate the start of operations, giving the analyzer
        time to setup up needed thingsNre   r:   s    r,   r`   zAnalyzer.start   rk   r-   c                      y)zfInvoked to indicate the end of operations, giving the analyzer
        time to shut down needed thingsNre   r:   s    r,   rc   zAnalyzer.stop   rk   r-   c                 "    t               | _        y)zMeant to be overriden by subclasses. Gives a chance to create the
        structures that hold the analysis.

        The default behaviour is to create a ``OrderedDict`` named ``rets``
        N)r   retsr:   s    r,   r!   zAnalyzer.create_analysis   s      M	r-   c                     | j                   S )a  Returns a *dict-like* object with the results of the analysis

        The keys and format of analysis results in the dictionary is
        implementation dependent.

        It is not even enforced that the result is a *dict-like object*, just
        the convention

        The default implementation returns the default OrderedDict ``rets``
        created by the default ``create_analysis`` method

        )rr   r:   s    r,   get_analysiszAnalyzer.get_analysis   s     yyr-   c                     t        j                  |i |}|j                          t               }| j	                         || j
                  j                  <   |j                  |       |j                          y)zPrints the results returned by ``get_analysis`` via a standard
        ``Writerfile`` object, which defaults to writing things to standard
        output
        N)	r   
WriterFiler`   dictrt   r+   r2   	writedictrc   )r;   r#   r$   writerpdcts        r,   printzAnalyzer.print  s[    
 //v(,(9(9(;T^^$$%r-   c                 R    t        j                  | j                         g|i | y)zpPrints the results returned by ``get_analysis`` using the pretty
        print Python module (*pprint*)
        N)pppprintrt   )r;   r#   r$   s      r,   r~   zAnalyzer.pprint  s#     			$##%777r-   N)r2   r3   r4   __doc__csvr<   r1   rB   rE   rJ   rO   rT   rX   r[   r_   rb   rF   rK   rU   rP   r\   rC   rY   r`   rc   r!   rt   r{   r~   re   r-   r,   r   r   Y   s    /` C"
%+9!!


"
8r-   r   c                        e Zd Z fdZ xZS )MetaTimeFrameAnalyzerBasec                 `    d|v r|j                  d      |d<   t        t        |   | |||      S )N_on_dt_over
on_dt_over)popr   r   __new__)metanamebasesdctr+   s       r,   r   z!MetaTimeFrameAnalyzerBase.__new__"  s>    C # 6C.=dD>CSJ 	Jr-   )r2   r3   r4   r   r5   r6   s   @r,   r   r   !  s    J Jr-   r   c                   L     e Zd ZdZ fdZd Zd Zd Zd Zd Z	d Z
d	 Z xZS )
TimeFrameAnalyzerBase))	timeframeN)compressionN)
_doprenextTc                 b   | j                   j                  xs | j                  j                  | _        | j                   j                  xs | j                  j
                  | _        | j                  t        j                  j                        \  | _	        | _
        t        t        | 7          y r/   )pr   r   
_timeframer   _compression_get_dt_cmpkeydatetimemindtcmpdtkeyr   r   r_   )r;   r+   s    r,   r_   zTimeFrameAnalyzerBase._start3  sw    ))ATYY-A-A66--G1G1G!%!4!4X5F5F5J5J!K
DJ#T13r-   c                     | j                   D ]  }|j                           | j                         r| j                          | j                  j
                  r| j                          y y r/   )r   rB   _dt_overr   r   r   rC   r?   s     r,   rB   zTimeFrameAnalyzerBase._prenext;  sO    ^^ 	ENN	 ==?OO66LLN r-   c                     | j                   D ]  }|j                           | j                         s| j                  j                  s| j                          | j                          y r/   )r   rX   r   r   r   r   rY   r?   s     r,   rX   z TimeFrameAnalyzerBase._nextstartE  sL    ^^ 	E	 ==?$&&"3"3OOr-   c                     | j                   D ]  }|j                           | j                         r| j                          | j	                          y r/   )r   r[   r   r   r\   r?   s     r,   r[   zTimeFrameAnalyzerBase._nextN  s<    ^^ 	EKKM	 ==?OO		r-   c                      y r/   re   r:   s    r,   r   z TimeFrameAnalyzerBase.on_dt_overW  s    r-   c                    | j                   t        j                  k(  r!t        t        j                  j
                  }}n8| j                  j                  j	                         }| j                  |      \  }}| j                  || j                  kD  r3|| j                  c| _	        | _
        || j                  c| _        | _        yy)NTF)r   r   NoTimeFramer	   r   maxr   r   r   r   dtkey1dtcmp1)r;   r   r   dts       r,   r   zTimeFrameAnalyzerBase._dt_overZ  s    >>Y222!8#4#4#8#85E ''002B..r2LE5::!3&+TZZ#DJ&+TZZ#DJr-   c                 T   | j                   t        j                  k(  ry| j                   t        j                  k(  r1|j                  }t        j                  |j                  dd      }||fS | j                   t        j                  k(  rx|j                  dz  |j                  z   }t        j                  |j                  |j                        \  }}t        j
                  |j                  |j                  |      }||fS | j                   t        j                  k(  rq|j                         \  }}}|dz  |z   }|t        j                  d|z
        z   }	t        j
                  |	j                  |	j                  |	j                        }||fS | j                   t        j                  k(  re|j                  dz  |j                  dz  z   |j                  z   }t        j
                  |j                  |j                  |j                        }||fS | j!                  |      \  }}||fS )N)NN      d      daysi'  )r   r   r   Yearsyearr   dateMonthsmonthcalendar
monthrangeWeeksisocalendar	timedeltadayDays_get_subday_cmpkey)
r;   r   r   r   _lastdayisoyearisoweek
isoweekdaysundays
             r,   r   z$TimeFrameAnalyzerBase._get_dt_cmpkeyi  s   >>Y222>>Y__,GGEMM"''2r2E( e|% ^^y///GGcMBHH,E!,,RWWbhh?JAw%%bggrxxAE e| ^^y.+->>+;(GWjcMG+E(,,!j.AAF%%fkk6<<LE e| ^^y~~-GGeObhhn4rvv=E%%bggrxx@E
 e|  2226LE5e|r-   c                    |j                   dz  |j                  z   }| j                  t        j                  k  r|dz  |j
                  z   }| j                  t        j                  k  r|dz  |j                  z   }|| j                  z  }|dz  }|| j                  z  }| j                  t        j                  k(  rt        |d      \  }}d}d}n| j                  t        j                  k(  r!t        |d      \  }}t        |d      \  }}d}nJ| j                  t        j                  k(  r-t        |d      \  }}t        |d      \  }}t        |d      \  }}d}dkD  r
|d	z  }|d	z  }t        j                  | j                  t        j                  k(  | j                  t        j                  k(  | j                  t        j                  k(  
      }	|r|t        j                  |      z  }|j                  |      }
|
|	z  }
|
}|
|fS )N<   g    .A   r   i  g   tAg    8A      )minutessecondsmicrosecondsr   )hourminutesecondmicrosecond)r   r   r   r   Minutesr   Secondsr   r   divmodMicroSecondsr   r   replace)r;   r   pointphpmpspuspsec	extradaystadjustr   r   s               r,   r   z(TimeFrameAnalyzerBase._get_subday_cmpkey  s   "ryy(>>I---BJ*E>>I---CK"..0E ))) 	
 	!!! >>Y...E2&FBBC^^y000E7+FBB^FBC^^y555E=1FBb(+HBT3'GB	7bI"HB $$NNi&7&77NNi&7&779+A+AAC ($$)44B 

2bc
Je|r-   )r2   r3   r4   paramsr_   rB   rX   r[   r   r   r   r   r5   r6   s   @r,   r   r   +  s2    F489r-   r   )
__future__r   r   r   r   r   collectionsr   r   r~   r}   
backtraderr   r   backtrader.utils.py3r	   r
   
MetaParamsr   objectr   r+   r   r   re   r-   r,   <module>r      sz   ** *  #      74"2== 4"nE8~lF3 E8PJ 2 2 JSN+D+35 Sr-   