
    'i                     t   d dl mZmZmZm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mZmZmZmZmZmZmZ d dlZddlmZmZ ddlmZ ddlmZ ddlmZm Z  dd	l!m"Z" dd
l#m$Z$m%Z%m&Z&  G d dejN                        Z( G d d ee(e            Z) G d de)jN                        Z* G d d ee*e)            Z+y)    )absolute_importdivisionprint_functionunicode_literalsN   )	filterkeysinteger_types	iteritems
itervaluesmapMAXINTstring_typeswith_metaclass)LineIteratorStrategyBase)
LineSingle)LineSeriesStub)ItemCollection	findowner)Trade)OrderedDictAutoOrderedDictAutoDictListc                   T     e Zd Z e       Z fdZ fdZ fdZ fdZ fdZ	 xZ
S )MetaStrategyc                     d|v r|j                  d      |d<   d|v r|j                  d      |d<   t        t        |   | |||      S )Nnotifynotify_ordernotify_operationnotify_trade)popsuperr   __new__)metanamebasesdct	__class__s       Q/var/www/app/trading-bot/venv/lib/python3.12/site-packages/backtrader/strategy.pyr$   zMetaStrategy.__new__.   sQ    s?"%''("3C$"%''*<"=C\40tUCHH    c                     t         t        |   |||       | j                  s(|dk7  r"|j	                  d      s| | j
                  |<   yyyy)zH
        Class has already been created ... register subclasses
        Strategy_N)r#   r   __init__aliased
startswith_indcol)clsr&   r'   r(   r)   s       r*   r/   zMetaStrategy.__init__9   sM    
 	lC)$s;{{:dooc&: #CKK '; r+   c                     t        t        | 
  |i |\  }}}t        |t        j
                        x|_        x|_        }|j                         |_	        |||fS N)
r#   r   donewr   btCerebroenvcerebro
_next_stid_id)r3   argskwargs_objr:   r)   s        r*   r6   zMetaStrategy.donewD   s]    "<;TLVLdF -6dBJJ,GGG4<'%%'T6!!r+   c                 :   t        t        | 
  |g|i |\  }}}|j                  j                  |_        t
        j                  j                         |_        t               |_
        t               |_        t        j                  t              |_        t               |_        t#               x|_        |_        t#               |_        t        j                  t*        j,                        |_        t               |_        t               |_        d|_        |||fS )NF)r#   r   	dopreinitr9   brokerr7   sizers	FixedSize_sizerlist_orders_orderspendingcollectionsdefaultdictr   _trades_tradespendingr   stats	observers	analyzers	itertoolscount_alnameswriters_slave_analyzers_tradehistoryonr3   r?   r=   r>   r)   s       r*   rA   zMetaStrategy.dopreinitM   s    ,.tEdEfE 	dFhhooii))+v"f"..|<"f&4&66
T^')#//	@v $$T6!!r+   c                     t        t        | 
  |g|i |\  }}}|j                  j	                  ||j
                         |||fS r5   )r#   r   
dopostinitrE   setrB   rV   s       r*   rX   zMetaStrategy.dopostinitb   sL    ,/FtFvF 	dF 	dkk*T6!!r+   )__name__
__module____qualname__dictr2   r$   r/   r6   rA   rX   __classcell__r)   s   @r*   r   r   +   s)    fG	I	$""*" "r+   r   c                       e Zd ZdZej
                  ZdZdZdZ	dAd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 fdZd Z fdZdBdZdBdZd Zd Zd Zd Z d Z!d Z"d Z#d  Z$dCd!Z%d" Z&dBd#Z'g g fd$Z( e)jT                          e)jT                         g dg dd%d%df	d&Z+d' Z,d( Z-d) Z.d* Z/d+ Z0d, Z1d- Z2d. Z3d/ Z4d0 Z5	 	 	 	 	 dDd1Z6	 	 	 	 	 dDd2Z7dEd3Z8d%d%d%d%e9jt                  jv                  d%dd%d%i d%e9jt                  jx                  i d%e9jt                  jv                  i fd4Z=d%d%d%d%e9jt                  jv                  d%dd%d%i d%e9jt                  jx                  i d%e9jt                  jv                  i fd5Z>dFd6Z?dGd7Z@dHd8ZAdEd9ZB eCeB      ZDdEd:ZE eCeE      ZFdId;ZG eCeG      ZHdId<ZI eCeI      ZJd= ZKd> ZLd? ZM eCeMeL      ZNdJd@ZO xZPS )Kr-   zB
    Base class to be subclassed for user defined strategies.
    TF)datetimer   c                    |dk  r`| j                   | j                     D ]C  }t        |t        f      }|s|dk  r|j                  j
                   }|j                  |       E y|dkD  r~| j                  D ]  }|j                  |        | j                  D ]  }|j                  d        | j                   D ](  }| j                   |   D ]  }|j                  d        * yy)aS  Enable the memory saving schemes. Possible values for ``savemem``:

          0: No savings. Each lines object keeps in memory all values

          1: All lines objects save memory, using the strictly minimum needed

        Negative values are meant to be used when plotting is required:

          -1: Indicators at Strategy Level and Observers do not enable memory
              savings (but anything declared below it does)

          -2: Same as -1 plus activation of memory saving for any indicators
              which has declared *plotinfo.plot* as False (will not be plotted)
        r   )savemem)	replayingr   N)	_lineiteratorsIndType
isinstancer   plotinfoplotqbufferdataslines)	selfrd   re   indsubsavedatalineitclsits	            r*   rk   zStrategy.qbufferx   s     Q;**4<<8 -$S:-87R<"%,,"3"33GG,	- q[

 2y12 

 (Q'( ,, *--e4 *BJJqJ)** r+   c                    | j                   D cg c]  }t        |       }}t        j                  t              }| j
                  t        j                     D ]  }t        |dd       }|t        |j                  dd       }|,	 t        |      |v rn,t        |dd       }|t        |j                  dd       }|n|}:|jt        |t              r|j                  d   }||   j                  |j                          t	               | _        | j                   D ]p  }||   }|j                  D ]  }||v s|||   z  } |rt!        |      gng ||<   t!        ||   xs |j                  g      }	| j                  j                  |	       r | j
                  t        j                     D 
cg c]  }
|
j                   c}
}t!        |xs | j                  g      | _        y c c}w c c}
w )N_clockr   )rl   idrI   rJ   rF   rf   r   rg   getattr_ownerrh   r   rm   append
_minperiod_minperiodsmax)rn   rq   dataids_dminperiodslineiterclkclk2dlminperiodsl
dminperiodx
minperiodss               r*   
_periodsetzStrategy._periodset   s   (,

32d833"..t4++L,@,@A 	:H (Hd3C{hoox>;c7g% sHd3<"3::x>D<  { #~.iil$$X%8%89?	:B  6JJ 	0D (-LZZ 4$ LO3L4
 9E#l"3!4"L\$/DDOO3DEJ##J/#	0* $(#6#6|7K7K#LMaQ\\M 	j=T__,=>w 4t Ns   G%/G*c                 :    | j                   j                  |       y)z
        Unlike the other _addxxx functions this one receives an instance
        because the writer works at cerebro level and is only passed to the
        strategy to simplify the logic
        N)rS   rz   )rn   writers     r*   
_addwriterzStrategy._addwriter   s     	F#r+   c                      ||i | y r5    )rn   indclsindargs	indkwargss       r*   _addindicatorzStrategy._addindicator   s    %9%r+   c                 L     ||i |}| j                   j                  |       |S )a  Like _addanalyzer but meant for observers (or other entities) which
        rely on the output of an analyzer for the data. These analyzers have
        not been added by the user and are kept separate from the main
        analyzers

        Returns the created analyzer
        rT   rz   )rn   anclsanargsankwargsanalyzers        r*   _addanalyzer_slavezStrategy._addanalyzer_slave   s,     &-H-$$X.r+   c                 4    | j                   j                  |   S r5   r   )rn   idxs     r*   _getanalyzer_slavezStrategy._getanalyzer_slave   s    $$++C00r+   c                     |j                  dd      xs |j                  j                         }t        | j                  |         }|t        |xs d      z  } ||i |}| j                  j                  ||       y )N_name )r"   rZ   lowernextrR   strrO   rz   )rn   r   r   r   annamensuffixr   s          r*   _addanalyzerzStrategy._addanalyzer   sm    gr*Denn.B.B.Dt}}V,-#gm$$&-H-h/r+   c                    |j                  dd      }|s|j                  j                         }|sNt        t	        j
                  | j                  |            } ||i |}| j                  j                  ||       y t        | j                  |t                      t        | j                  |      }| j                  D ]  }	 ||	g|i |}|j                  |       ! y )Nobsnamer   )r"   rZ   r   rF   rP   chainrl   rM   rz   setattrrx   )
rn   multiobsclsobsargs	obskwargsr   newargsobsr   rq   s
             r*   _addobserverzStrategy._addobserver   s    --	2.oo++-G9??4::w?@G'/Y/CJJc7+

GTV,DJJ(JJ 	D5595CHHSM	r+   c                     t        t        j                  | j                  t        t        | j
                              }t        |      x| _        }|S r5   )r   operatorsubr|   lenrl   r}   _minperstatus)rn   dlensminperstatuss      r*   _getminperstatuszStrategy._getminperstatus  s<    HLL$"2"2CTZZ4HI,/J6\r+   c                      y r5   r   rn   s    r*   prenext_openzStrategy.prenext_open      r+   c                 $    | j                          y r5   )	next_openr   s    r*   nextstart_openzStrategy.nextstart_open  s    r+   c                      y r5   r   r   s    r*   r   zStrategy.next_open  r   r+   c                     | j                   }|dk  r| j                          y |dk(  r| j                          y | j                          y Nr   r   r   r   r   rn   r   s     r*   _oncepost_openzStrategy._oncepost_open  ?    ))!NNQ!r+   c                 \   | j                   t        j                     D ]4  }t        |j                        t        |      kD  s%|j                          6 | j                  r| j                          n| j                          || j                  j                  d<   | j                          | j                         }|dk  r| j                          n&|dk(  r| j                          n| j                          | j                  |d       | j!                  |d       | j#                          y )Nr   T)once)rf   r   rg   r   rv   advance_oldsyncforwardrm   ra   _notifyr   r   	nextstartprenext_next_analyzers_next_observersclear)rn   dt	indicatorr   s       r*   	_oncepostzStrategy._oncepost$  s    ,,\-A-AB 	$I9##$s9~5!!#	$ ==LLN LLN!#

A,,.!IIKQNNLLN\5\5

r+   c                    | j                   rGt        t        |          }t	        d | j
                  D              | j                  j                  d<   |S | j
                  D cg c]  }t        |       }}t        d t        | j                  |      D              r| j                          t	        d | j
                  D              | j                  j                  d<   || _        t        |       S c c}w )Nc              3   P   K   | ]  }t        |      r|j                  d       ywr   Nr   ra   .0ds     r*   	<genexpr>z'Strategy._clk_update.<locals>.<genexpr>C  s(      )H-.A *+A )H   $&r   c              3   ,   K   | ]  \  }}||kD    y wr5   r   )r   r   nls      r*   r   z'Strategy._clk_update.<locals>.<genexpr>H  s     >%!RrAv>   c              3   P   K   | ]  }t        |      r|j                  d       ywr   r   r   s     r*   r   z'Strategy._clk_update.<locals>.<genexpr>K  s(      %D)*CF &'ZZ] %Dr   )r   r#   r-   _clk_updater}   rl   rm   ra   r   anyzip_dlensr   )rn   clk_lenr   newdlensr)   s       r*   r   zStrategy._clk_update@  s    ==Hd79G%( )H26**)H &HDJJ"N$(JJ/qCF//>3t{{H#=>>LLN!$ %D.2jj%D "D

A4y 0s   #C2c                     | j                   }|dk  r| j                          y |dk(  r| j                          y | j                          y r   r   r   s     r*   
_next_openzStrategy._next_openQ  r   r+   c                     t         t        |           | j                         }| j	                  |       | j                  |       | j                          y r5   )r#   r-   _nextr   r   r   r   )rn   r   r)   s     r*   r   zStrategy._nextZ  sC    h#%,,.\*\*

r+   c                     | j                   t        j                     D ]  }|j                  D ]>  }|dk  r|j	                          |dk(  r|j                          /|j                          @ |rt        |       t        |      kD  r-| j                  r|j                          n|j                          |dk  r|j                          |dk(  r|j                          t        |      s|j                          |j	                           y r   )rf   r   ObsType
_analyzersr   
_nextstart_prenextr   r   r   r   r   r   r   )rn   r   r   observerr   s        r*   r   zStrategy._next_observersc  s    ++L,@,@A 	!H$// (!#NN$!Q&'')%%'( t9s8},}} ((* ((*!#MMO!Q&&&(]$$& /	!r+   c                     | j                   D ]>  }|dk  r|j                          |dk(  r|j                          /|j                          @ y r   )rO   r   r   r   )rn   r   r   r   s       r*   r   zStrategy._next_analyzers}  sG     	$Ha "##%!!#	$r+   c                 N    | j                   j                  j                  |       y r5   )rm   ra   _settz)rn   tzs     r*   r   zStrategy._settz  s    

""2&r+   c                    | j                          t        j                  | j                  | j                        D ]  }|j                           | j                  D ],  }t        |t              s|g}|D ]  }|j                           . | j                          | j                  D cg c]  }t        |       c}| _        t        | _        | j                          y c c}w r5   )r   rP   r   rO   rT   _startrN   rh   rF   _stage2rl   r   r   r   r   start)rn   r   r   orq   s        r*   r   zStrategy._start  s    !8M8MN 	HOO	 >> 	Cc4(e 
		 	-1ZZ8Ts4y8#

	 9s   )Cc                      y)z;Called right before the backtesting is about to be started.Nr   r   s    r*   r   zStrategy.start      r+   c                    | g| _         t        j                  | j                         | j	                               }| j                   j                  t        d |             t               }| j                   D ]q  }|j                  j                  xs |j                  j                  }|j                  |       |j                  d       |j                  |j                                s |S )Nc                     | j                   S r5   )csv)r   s    r*   <lambda>z+Strategy.getwriterheaders.<locals>.<lambda>  s
    quu r+   r   )	indobscsvrP   r   getindicators_linesgetobserversextendr   rF   ri   plotnamer)   rZ   rz   getlinealiases)rn   indobsheadersiocsvr&   s        r*   getwriterheaderszStrategy.getwriterheaders  s    $$&(9(9(;=f_f=>& ^^ 	3E>>**Feoo.F.FDNN4 NN5!NN5//12		3 r+   c                    t               }| j                  D ]  }|j                  j                  xs |j                  j
                  }|j                  |       t        |      }|j                  |       |r5|j                  t        d |j                  j                                      |j                  dg|j                  j                         z          |S )Nc                     | d   S r   r   )r   s    r*   r   z*Strategy.getwritervalues.<locals>.<lambda>  s
    AaD r+   r   )rF   r   ri   r  r)   rZ   rz   r   r  r   rm   itersizesize)rn   valuesr  r&   lios        r*   getwritervalueszStrategy.getwritervalues  s    ^^ 	9E>>**Feoo.F.FDMM$e*CMM#c.%++2F2F2HIJrdU[[%5%5%778	9 r+   c                     t               }| j                  j                         |d<   d| j                         gd| j	                         gg}|D ]s  \  }}||   }|D ]d  }|j
                  j                  }|j                  j                         xs d ||   _	        |j                  j                         xs d ||   _
        f u |j                  }| j                  j                  |j                  _        | j                  j!                         |j                  _        | j$                  j'                         D ]C  \  }	}
|
j                  j                         xs d ||	   _
        |
j)                         ||	   _        E |S )NParams
Indicators	Observers)r   p
_getkwargsr  r  r)   rZ   rm   r  Linesr  	AnalyzersrB   startingcashValueBegingetvalueEndrO   getitemsget_analysisAnalysis)rn   wrinfosectionssectname	sectitemssinfoitemitnameainfoanamer   s              r*   getwriterinfozStrategy.getwriterinfo  sc    "66,,.x 43356$++-.

 $, 	CHi8$E! C00&*jj&?&?&A&ITf#'+vv'8'8':'Bdf$C	C    !KK44++..0  $~~668 	<OE8"***"7"7"9"ATE%L$,$9$9$;E%L!	< r+   c                     | j                          t        j                  | j                  | j                        D ]  }|j                           | j                          y r5   )stoprP   r   rO   rT   _stop_stage1)rn   r   s     r*   r-  zStrategy._stop  sD    		!8M8MN 	HNN	 	r+   c                      y)z:Called right before the backtesting is about to be stoppedNr   r   s    r*   r,  zStrategy.stop  r   r+   c                     || _         y r5   )rU   )rn   onoffs     r*   set_tradehistoryzStrategy.set_tradehistory  s
    $r+   c                     | j                   j                  | j                         t               | _        t               | _        y r5   )rG   r  rH   rF   rL   r   s    r*   r   zStrategy.clear  s.    D//0"f"fr+   c           
         |j                   j                  s| j                  j                  |       |r|g}g }|j                  j
                  s|r| j                         y |j                  j                  }||j                  }| j                  |   |j                     }|s4t        ||j                  | j                        }|j                  |       n|d   }|j                  j                         D ]+  }| n&|j                  r|j                  ||j                  |j                   |j"                  |j$                  |j&                  |j(                         |j*                  rT| j,                  j                  t/        j.                  |             |r$j                  t/        j.                  |             |j0                  r|j*                  r3t        ||j                  | j                        }|j                  |       |j                  ||j0                  |j                   |j2                  |j4                  |j&                  |j(                         |j*                  rT| j,                  j                  t/        j.                  |             |r$j                  t/        j.                  |             |j6                  s| j,                  j                  t/        j.                  |             |sj                  t/        j.                  |             . |r| j                         y y )Nqordersqtrades)rq   tradeid	historyonrc   )comminfo)r  	simulatedrH   rz   executedr  r   rq   _compensaterK   r8  r   rU   iterpendingclosedupdatepriceclosedvalue
closedcommpnlr:  isclosedrL   copyopenedopenedvalue
openedcomm
justopened)	rn   orderquicknotifyr6  r7  	tradedata
datatradestradeexbits	            r*   _addnotificationzStrategy._addnotification  s|   ww  &&u-gGG~~""Wg>JJ**	

I\\),U]];
y%--$($8$8:Ee$rNE^^//1 ,	5E}||U"\\"[[".."--"YY&+nn  6 >>''..tyy/?@"tyy'78 ||>>!y%--,0,@,@BE%%e,U"\\"[[".."--"YY&+nn  6 >>''..tyy/?@"tyy'78##**499U+;<NN499U#34Y,	5\ LL'L: r+   c                    | j                   j                  j                  r|}|}n| j                  }| j                  }|D ]x  }|j
                  |j                  k7  s|j                  r| j                  |       t        j                  | j                  | j                        D ]  }|j                  |        z |D ]S  }| j                  |       t        j                  | j                  | j                        D ]  }|j                  |        U |ry | j                   j#                         }| j                   j%                         }	| j                   j&                  }
| j                   j(                  }| j+                  ||	       | j-                  ||	|
|       t        j                  | j                  | j                        D ](  }|j/                  ||	       |j1                  ||	|
|       * y r5   )r:   r  rL  rH   rL   exectype
Historical
histnotifyr   rP   r   rO   rT   _notify_orderr!   _notify_traderB   getcashr  	fundvalue
fundsharesnotify_cashvaluenotify_fund_notify_cashvalue_notify_fund)rn   r6  r7  
procorders
proctradesrK  r   rO  cashvaluerY  rZ  s               r*   r   zStrategy._notifyA  s   <<>>%% !J J,,J,,J 	.E~~!1!11U5E5E!!%(%OODNN,0,A,AC .&&u-.	.   	.Ee$%OODNN,0,A,AC .&&u-.	. {{""$$$&KK))	[[++
dE*ui<!8M8MN 	FH&&tU3!!$y*E	Fr+   Nc                 T     | j                   j                  || |||||||||	d|
d|S )a  
        **Note**: can be called during ``__init__`` or ``start``

        Schedules a timer to invoke either a specified callback or the
        ``notify_timer`` of one or more strategies.

        Arguments:

          - ``when``: can be

            - ``datetime.time`` instance (see below ``tzdata``)
            - ``bt.timer.SESSION_START`` to reference a session start
            - ``bt.timer.SESSION_END`` to reference a session end

         - ``offset`` which must be a ``datetime.timedelta`` instance

           Used to offset the value ``when``. It has a meaningful use in
           combination with ``SESSION_START`` and ``SESSION_END``, to indicated
           things like a timer being called ``15 minutes`` after the session
           start.

          - ``repeat`` which must be a ``datetime.timedelta`` instance

            Indicates if after a 1st call, further calls will be scheduled
            within the same session at the scheduled ``repeat`` delta

            Once the timer goes over the end of the session it is reset to the
            original value for ``when``

          - ``weekdays``: a **sorted** iterable with integers indicating on
            which days (iso codes, Monday is 1, Sunday is 7) the timers can
            be actually invoked

            If not specified, the timer will be active on all days

          - ``weekcarry`` (default: ``False``). If ``True`` and the weekday was
            not seen (ex: trading holiday), the timer will be executed on the
            next day (even if in a new week)

          - ``monthdays``: a **sorted** iterable with integers indicating on
            which days of the month a timer has to be executed. For example
            always on day *15* of the month

            If not specified, the timer will be active on all days

          - ``monthcarry`` (default: ``True``). If the day was not seen
            (weekend, trading holiday), the timer will be executed on the next
            available day.

          - ``allow`` (default: ``None``). A callback which receives a
            `datetime.date`` instance and returns ``True`` if the date is
            allowed for timers or else returns ``False``

          - ``tzdata`` which can be either ``None`` (default), a ``pytz``
            instance or a ``data feed`` instance.

            ``None``: ``when`` is interpreted at face value (which translates
            to handling it as if it where UTC even if it's not)

            ``pytz`` instance: ``when`` will be interpreted as being specified
            in the local time specified by the timezone instance.

            ``data feed`` instance: ``when`` will be interpreted as being
            specified in the local time specified by the ``tz`` parameter of
            the data feed instance.

            **Note**: If ``when`` is either ``SESSION_START`` or
              ``SESSION_END`` and ``tzdata`` is ``None``, the 1st *data feed*
              in the system (aka ``self.data0``) will be used as the reference
              to find out the session times.

          - ``cheat`` (default ``False``) if ``True`` the timer will be called
            before the broker has a chance to evaluate the orders. This opens
            the chance to issue orders based on opening price for example right
            before the session starts

          - ``*args``: any extra args will be passed to ``notify_timer``

          - ``**kwargs``: any extra kwargs will be passed to ``notify_timer``

        Return Value:

          - The created timer

        F)ownerwhenoffsetrepeatweekdays	weekcarry	monthdays
monthcarryallowtzdatastratscheat)r:   
_add_timer)rn   re  rf  rg  rh  ri  rj  rk  rl  rm  ro  r=   r>   s                r*   	add_timerzStrategy.add_timerg  sL    x 't||&&  T&J%u  	r+   c                      y)a  Receives a timer notification where ``timer`` is the timer which was
        returned by ``add_timer``, and ``when`` is the calling time. ``args``
        and ``kwargs`` are any additional arguments passed to ``add_timer``

        The actual ``when`` time can be later, but the system may have not be
        able to call the timer before. This value is the timer value and no the
        system time.
        Nr   )rn   timerre  r=   r>   s        r*   notify_timerzStrategy.notify_timer  s     	r+   c                      y)zX
        Receives the current fund value, value status of the strategy's broker
        Nr   )rn   ra  rb  s      r*   r[  zStrategy.notify_cashvalue       	r+   c                      y)zM
        Receives the current cash, value, fundvalue and fund shares
        Nr   )rn   ra  rb  rY  sharess        r*   r\  zStrategy.notify_fund  rv  r+   c                      y)zK
        Receives an order whenever there has been a change in one
        Nr   rn   rK  s     r*   r   zStrategy.notify_order  rv  r+   c                      y)zJ
        Receives a trade whenever there has been a change in one
        Nr   )rn   rO  s     r*   r!   zStrategy.notify_trade  rv  r+   c                      y)z-Receives a notification from a store providerNr   )rn   msgr=   r>   s       r*   notify_storezStrategy.notify_store  r   r+   c                      y)z!Receives a notification from dataNr   )rn   rq   statusr=   r>   s        r*   notify_datazStrategy.notify_data  r   r+   c                 @    t        | j                  j                        S )z;
        Returns a list of the existing data names
        )r	   r9   datasbynamer   s    r*   getdatanameszStrategy.getdatanames  s     DHH(())r+   c                 4    | j                   j                  |   S )zN
        Returns a given data by name using the environment (cerebro)
        )r9   r  )rn   r&   s     r*   getdatabynamezStrategy.getdatabyname  s     xx##D))r+   c                 :    | j                   j                  |       y)zCancels the order in the brokerN)rB   cancelrz  s     r*   r  zStrategy.cancel  s    5!r+   c                    t        |t              r| j                  |      }||n| j                  d   }||n| j	                  |d      }|r3 | j
                  j                  | |ft        |      |||||||	|
||d|S y)a-  Create a buy (long) order and send it to the broker

          - ``data`` (default: ``None``)

            For which data the order has to be created. If ``None`` then the
            first data in the system, ``self.datas[0] or self.data0`` (aka
            ``self.data``) will be used

          - ``size`` (default: ``None``)

            Size to use (positive) of units of data to use for the order.

            If ``None`` the ``sizer`` instance retrieved via ``getsizer`` will
            be used to determine the size.

          - ``price`` (default: ``None``)

            Price to use (live brokers may place restrictions on the actual
            format if it does not comply to minimum tick size requirements)

            ``None`` is valid for ``Market`` and ``Close`` orders (the market
            determines the price)

            For ``Limit``, ``Stop`` and ``StopLimit`` orders this value
            determines the trigger point (in the case of ``Limit`` the trigger
            is obviously at which price the order should be matched)

          - ``plimit`` (default: ``None``)

            Only applicable to ``StopLimit`` orders. This is the price at which
            to set the implicit *Limit* order, once the *Stop* has been
            triggered (for which ``price`` has been used)

          - ``trailamount`` (default: ``None``)

            If the order type is StopTrail or StopTrailLimit, this is an
            absolute amount which determines the distance to the price (below
            for a Sell order and above for a buy order) to keep the trailing
            stop

          - ``trailpercent`` (default: ``None``)

            If the order type is StopTrail or StopTrailLimit, this is a
            percentage amount which determines the distance to the price (below
            for a Sell order and above for a buy order) to keep the trailing
            stop (if ``trailamount`` is also specified it will be used)

          - ``exectype`` (default: ``None``)

            Possible values:

            - ``Order.Market`` or ``None``. A market order will be executed
              with the next available price. In backtesting it will be the
              opening price of the next bar

            - ``Order.Limit``. An order which can only be executed at the given
              ``price`` or better

            - ``Order.Stop``. An order which is triggered at ``price`` and
              executed like an ``Order.Market`` order

            - ``Order.StopLimit``. An order which is triggered at ``price`` and
              executed as an implicit *Limit* order with price given by
              ``pricelimit``

            - ``Order.Close``. An order which can only be executed with the
              closing price of the session (usually during a closing auction)

            - ``Order.StopTrail``. An order which is triggered at ``price``
              minus ``trailamount`` (or ``trailpercent``) and which is updated
              if the price moves away from the stop

            - ``Order.StopTrailLimit``. An order which is triggered at
              ``price`` minus ``trailamount`` (or ``trailpercent``) and which
              is updated if the price moves away from the stop

          - ``valid`` (default: ``None``)

            Possible values:

              - ``None``: this generates an order that will not expire (aka
                *Good till cancel*) and remain in the market until matched or
                canceled. In reality brokers tend to impose a temporal limit,
                but this is usually so far away in time to consider it as not
                expiring

              - ``datetime.datetime`` or ``datetime.date`` instance: the date
                will be used to generate an order valid until the given
                datetime (aka *good till date*)

              - ``Order.DAY`` or ``0`` or ``timedelta()``: a day valid until
                the *End of the Session* (aka *day* order) will be generated

              - ``numeric value``: This is assumed to be a value corresponding
                to a datetime in ``matplotlib`` coding (the one used by
                ``backtrader``) and will used to generate an order valid until
                that time (*good till date*)

          - ``tradeid`` (default: ``0``)

            This is an internal value applied by ``backtrader`` to keep track
            of overlapping trades on the same asset. This ``tradeid`` is sent
            back to the *strategy* when notifying changes to the status of the
            orders.

          - ``oco`` (default: ``None``)

            Another ``order`` instance. This order will become part of an OCO
            (Order Cancel Others) group. The execution of one of the orders,
            immediately cancels all others in the same group

          - ``parent`` (default: ``None``)

            Controls the relationship of a group of orders, for example a buy
            which is bracketed by a high-side limit sell and a low side stop
            sell. The high/low side orders remain inactive until the parent
            order has been either executed (they become active) or is
            canceled/expires (the children are also canceled) bracket orders
            have the same size

          - ``transmit`` (default: ``True``)

            Indicates if the order has to be **transmitted**, ie: not only
            placed in the broker but also issued. This is meant for example to
            control bracket orders, in which one disables the transmission for
            the parent and 1st set of children and activates it for the last
            children, which triggers the full placement of all bracket orders.

          - ``**kwargs``: additional broker implementations may support extra
            parameters. ``backtrader`` will pass the *kwargs* down to the
            created order objects

            Example: if the 4 order execution types directly supported by
            ``backtrader`` are not enough, in the case of for example
            *Interactive Brokers* the following could be passed as *kwargs*::

              orderType='LIT', lmtPrice=10.0, auxPrice=9.8

            This would override the settings created by ``backtrader`` and
            generate a ``LIMIT IF TOUCHED`` order with a *touched* price of 9.8
            and a *limit* price of 10.0.

        Returns:
          - the submitted order

        Nr   Tisbuyr  rA  plimitrS  validr8  ocotrailamounttrailpercentparenttransmit)rh   r   r  rl   	getsizingrB   buyabsrn   rq   r  rA  r  rS  r  r8  r  r  r  r  r  r>   s                 r*   r  zStrategy.buy  s    p dL)%%d+D'tTZZ]'tT^^D^-M"4;;??dYeF!S'l   r+   c                    t        |t              r| j                  |      }||n| j                  d   }||n| j	                  |d      }|r3 | j
                  j                  | |ft        |      |||||||	|
||d|S y)z
        To create a selll (short) order and send it to the broker

        See the documentation for ``buy`` for an explanation of the parameters

        Returns: the submitted order
        Nr   Fr  r  )rh   r   r  rl   r  rB   sellr  r  s                 r*   r  zStrategy.sell  s     dL)%%d+D'tTZZ]'tT^^D^-N#4;;##dYeF!S'l   r+   c                 6   t        |t              r| j                  |      }n|| j                  }| j	                  || j
                        j                  }t        ||n|      }|dkD  r | j                  d||d|S |dk  r | j                  d||d|S y)aI  
        Counters a long/short position closing it

        See the documentation for ``buy`` for an explanation of the parameters

        Note:

          - ``size``: automatically calculated from the existing position if
            not provided (default: ``None``) by the caller

        Returns: the submitted order
        Nr   rq   r  r   )
rh   r   r  rq   getpositionrB   r  r  r  r  )rn   rq   r  r>   possizes        r*   closezStrategy.close  s     dL)%%d+D\99D""45::4+49Q;499<$T<V<<q[488;D;F;;r+   c                 B   t        |||||||||		      }|j                  |
       |j                  |       |du xr |du |d<    | j                  di |}|`t        |||||      }|j                  |       |j                  |       ||d<   |du |d<   |j                  |d<    | j                  di |}nd}|^t        |||||      }|j                  |       |j                  |       ||d<   d|d<   |j                  |d<    | j                  di |}nd}|||gS )	a  
        Create a bracket order group (low side - buy order - high side). The
        default behavior is as follows:

          - Issue a **buy** order with execution ``Limit``

          - Issue a *low side* bracket **sell** order with execution ``Stop``

          - Issue a *high side* bracket **sell** order with execution
            ``Limit``.

        See below for the different parameters

          - ``data`` (default: ``None``)

            For which data the order has to be created. If ``None`` then the
            first data in the system, ``self.datas[0] or self.data0`` (aka
            ``self.data``) will be used

          - ``size`` (default: ``None``)

            Size to use (positive) of units of data to use for the order.

            If ``None`` the ``sizer`` instance retrieved via ``getsizer`` will
            be used to determine the size.

            **Note**: The same size is applied to all 3 orders of the bracket

          - ``price`` (default: ``None``)

            Price to use (live brokers may place restrictions on the actual
            format if it does not comply to minimum tick size requirements)

            ``None`` is valid for ``Market`` and ``Close`` orders (the market
            determines the price)

            For ``Limit``, ``Stop`` and ``StopLimit`` orders this value
            determines the trigger point (in the case of ``Limit`` the trigger
            is obviously at which price the order should be matched)

          - ``plimit`` (default: ``None``)

            Only applicable to ``StopLimit`` orders. This is the price at which
            to set the implicit *Limit* order, once the *Stop* has been
            triggered (for which ``price`` has been used)

          - ``trailamount`` (default: ``None``)

            If the order type is StopTrail or StopTrailLimit, this is an
            absolute amount which determines the distance to the price (below
            for a Sell order and above for a buy order) to keep the trailing
            stop

          - ``trailpercent`` (default: ``None``)

            If the order type is StopTrail or StopTrailLimit, this is a
            percentage amount which determines the distance to the price (below
            for a Sell order and above for a buy order) to keep the trailing
            stop (if ``trailamount`` is also specified it will be used)

          - ``exectype`` (default: ``bt.Order.Limit``)

            Possible values: (see the documentation for the method ``buy``

          - ``valid`` (default: ``None``)

            Possible values: (see the documentation for the method ``buy``

          - ``tradeid`` (default: ``0``)

            Possible values: (see the documentation for the method ``buy``

          - ``oargs`` (default: ``{}``)

            Specific keyword arguments (in a ``dict``) to pass to the main side
            order. Arguments from the default ``**kwargs`` will be applied on
            top of this.

          - ``**kwargs``: additional broker implementations may support extra
            parameters. ``backtrader`` will pass the *kwargs* down to the
            created order objects

            Possible values: (see the documentation for the method ``buy``

            **Note**: this ``kwargs`` will be applied to the 3 orders of a
            bracket. See below for specific keyword arguments for the low and
            high side orders

          - ``stopprice`` (default: ``None``)

            Specific price for the *low side* stop order

          - ``stopexec`` (default: ``bt.Order.Stop``)

            Specific execution type for the *low side* order

          - ``stopargs`` (default: ``{}``)

            Specific keyword arguments (in a ``dict``) to pass to the low side
            order. Arguments from the default ``**kwargs`` will be applied on
            top of this.

          - ``limitprice`` (default: ``None``)

            Specific price for the *high side* stop order

          - ``stopexec`` (default: ``bt.Order.Limit``)

            Specific execution type for the *high side* order

          - ``limitargs`` (default: ``{}``)

            Specific keyword arguments (in a ``dict``) to pass to the high side
            order. Arguments from the default ``**kwargs`` will be applied on
            top of this.

        High/Low Side orders can be suppressed by using:

          - ``limitexec=None`` to suppress the *high side*

          - ``stopexec=None`` to suppress the *low side*

        Returns:

          - A list containing the 3 orders [order, stop side, limit side]

          - If high/low orders have been suppressed the return value will still
            contain 3 orders, but those suppressed will have a value of
            ``None``
        	r  rq   rA  r  rS  r  r8  r  r  Nr  rq   rA  rS  r  r8  r  r  Tr   )r]   r@  r  r  r  rn   rq   r  rA  r  rS  r  r8  r  r  oargs	stoppricestopexecstopargs
limitprice	limitexec	limitargsr>   kargsr   ostopolimits                         r*   buy_bracketzStrategy.buy_bracket  sS   R $eFX '!,<I 	UV%-B(d2BjDHHud)h$g7ELL"LL E(O )T 1E*FFE&MDII&&EE d*y$g7ELL#LL E(O $E*FFE&MTYY''FF5&!!r+   c                 B   t        |||||||||		      }|j                  |
       |j                  |       |du xr |du |d<    | j                  di |}|`t        |||||      }|j                  |       |j                  |       ||d<   |du |d<   |j                  |d<    | j                  di |}nd}|^t        |||||      }|j                  |       |j                  |       ||d<   d|d<   |j                  |d<    | j                  di |}nd}|||gS )	aT  
        Create a bracket order group (low side - buy order - high side). The
        default behavior is as follows:

          - Issue a **sell** order with execution ``Limit``

          - Issue a *high side* bracket **buy** order with execution ``Stop``

          - Issue a *low side* bracket **buy** order with execution ``Limit``.

        See ``bracket_buy`` for the meaning of the parameters

        High/Low Side orders can be suppressed by using:

          - ``stopexec=None`` to suppress the *high side*

          - ``limitexec=None`` to suppress the *low side*

        Returns:

          - A list containing the 3 orders [order, stop side, limit side]

          - If high/low orders have been suppressed the return value will still
            contain 3 orders, but those suppressed will have a value of
            ``None``
        r  Nr  r  r  r  Tr   )r]   r@  r  r  r  r  s                         r*   sell_bracketzStrategy.sell_bracket  sS   F $eFX '!,<I 	UV%-B(d2BjDIId)h$g7ELL"LL E(O )T 1E*FFE&MDHH%u%EE d*y$g7ELL#LL E(O $E*FFE&MTXX&&FF5&!!r+   c                 V   t        |t              r| j                  |      }n|| j                  }| j	                  || j
                        j                  }|s|r | j                  d||d|S ||kD  r | j                  d|||z
  d|S ||k  r | j                  d|||z
  d|S y)a  
        Place an order to rebalance a position to have final size of ``target``

        The current ``position`` size is taken into account as the start point
        to achieve ``target``

          - If ``target`` > ``pos.size`` -> buy ``target - pos.size``

          - If ``target`` < ``pos.size`` -> sell ``pos.size - target``

        It returns either:

          - The generated order

          or

          - ``None`` if no order has been issued (``target == position.size``)
        Nr  r   )
rh   r   r  rq   r  rB   r  r  r  r  rn   rq   targetr>   r  s        r*   order_target_sizezStrategy.order_target_size  s    & dL)%%d+D\99D""45::'4::@4g@@@g488GFW,<GGGg499H$Wv-=HHHr+   c                 :   t        |t              r| j                  |      }n|| j                  }| j	                  || j
                        j                  }|s|r | j                  d|||d|S | j
                  j                  |g      }| j
                  j                  |      }||n|j                  d   }||kD  r+|j                  |||z
        } | j                  d|||d|S ||k  r+|j                  |||z
        } | j                  d|||d|S y)a  
        Place an order to rebalance a position to have final value of
        ``target``

        The current ``value`` is taken into account as the start point to
        achieve ``target``

          - If no ``target`` then close postion on data
          - If ``target`` > ``value`` then buy on data
          - If ``target`` < ``value`` then sell on data

        It returns either:

          - The generated order

          or

          - ``None`` if no order has been issued
        N)rq   r  rA  )rl   r   r   )rh   r   r  rq   r  rB   r  r  r  getcommissioninfogetsizer  r  )	rn   rq   r  rA  r>   r  rb  r:  r  s	            r*   order_target_valuezStrategy.order_target_value  s&   * dL)%%d+D\99D""45::'4::M4gUMfMM KK((v(6E{{44T:H #.EDJJqME~''v~>txxLTELVLL%''uv~> tyyMdUMfMMr+   c                    t        |t              r| j                  |      }n|| j                  }| j	                  || j
                        j                  }|| j
                  j                         z  } | j                  d||d|S )a  
        Place an order to rebalance a position to have final value of
        ``target`` percentage of current portfolio ``value``

        ``target`` is expressed in decimal: ``0.05`` -> ``5%``

        It uses ``order_target_value`` to execute the order.

        Example:
          - ``target=0.05`` and portfolio value is ``100``

          - The ``value`` to be reached is ``0.05 * 100 = 5``

          - ``5`` is passed as the ``target`` value to ``order_target_value``

        The current ``value`` is taken into account as the start point to
        achieve ``target``

        The ``position.size`` is used to determine if a position is ``long`` /
        ``short``

          - If ``target`` > ``value``
            - buy if ``pos.size >= 0`` (Increase a long position)
            - sell if ``pos.size < 0`` (Increase a short position)

          - If ``target`` < ``value``
            - sell if ``pos.size >= 0`` (Decrease a long position)
            - buy if ``pos.size < 0`` (Decrease a short position)

        It returns either:

          - The generated order

          or

          - ``None`` if no order has been issued (``target == position.size``)
        )rq   r  r   )	rh   r   r  rq   r  rB   r  r  r  r  s        r*   order_target_percentzStrategy.order_target_percent2  s}    L dL)%%d+D\99D""45::$++&&((&t&&JDJ6JJr+   c                 j    ||n| j                   d   }|xs | j                  }|j                  |      S )z
        Returns the current position for a given data in a given broker.

        If both are None, the main data and the default broker will be used

        A property ``position`` is also available
        r   )rl   rB   r  )rn   rq   rB   s      r*   r  zStrategy.getpositionb  s7     'tTZZ]&4;;!!$''r+   c                     |s| j                   d   n| j                  |      }|xs | j                  }|j                  |      S )z
        Returns the current position for a given name in a given broker.

        If both are None, the main data and the default broker will be used

        A property ``positionbyname`` is also available
        r   )rl   r  rB   r  )rn   r&   rB   rq   s       r*   getpositionbynamezStrategy.getpositionbynamep  s?     %)tzz!}d.@.@.F&4;;!!$''r+   c                 :    |xs | j                   }|j                  S )z
        Returns the current by data positions directly from the broker

        If the given ``broker`` is None, the default broker will be used

        A property ``positions`` is also available
        )rB   	positions)rn   rB   s     r*   getpositionszStrategy.getpositions~  s     &4;;r+   c                     |xs | j                   }|j                  }t        j                         }t	        | j
                  j                        D ]  \  }}||   ||<    |S )z
        Returns the current by name positions directly from the broker

        If the given ``broker`` is None, the default broker will be used

        A property ``positionsbyname`` is also available
        )rB   r  rI   r   r   r9   r  )rn   rB   r  	posbynamer&   rq   s         r*   getpositionsbynamezStrategy.getpositionsbyname  sb     &4;;$$	++-	#DHH$8$89 	.JD$'oIdO	. r+   c                     |.| j                  t        j                  j                                y | j                   ||i |       y r5   )setsizerr7   rC   rD   )rn   sizerr=   r>   s       r*   	_addsizerzStrategy._addsizer  s6    =MM"))--/0MM%001r+   c                 L    || _         |j                  | | j                         |S )z9
        Replace the default (fixed stake) sizer
        )rE   rY   rB   )rn   r  s     r*   r  zStrategy.setsizer  s"     		$$r+   c                     | j                   S )z
        Returns the sizer which is in used if automatic statke calculation is
        used

        Also available as ``sizer``
        )rE   r   s    r*   getsizerzStrategy.getsizer  s     {{r+   c                 b    ||n| j                   d   }| j                  j                  ||      S )ze
        Return the stake calculated by the sizer instance for the current
        situation
        r   r  )rl   rE   r  )rn   rq   r  s      r*   r  zStrategy.getsizing  s2    
 'tTZZ]{{$$T$77r+   )r   F)F)T)NNNNNNr   NNNNT)NNr   )N        N)Nr  r5   )NT)QrZ   r[   r\   __doc__r   	StratType_ltyper   r   rm   rk   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r	  r  r*  r-  r,  r2  r   rQ  r   ra   	timedeltarq  rt  r[  r\  r   r!   r~  r  r  r  r  r  r  r  r7   OrderLimitStopr  r  r  r  r  r  propertypositionr  positionbynamer  r  r  positionsbynamer  r  r  r  r  r^   r_   s   @r*   r-   r-   k   ss    ##F
CH E!*F<?|$&
10$ 8" !4$',$<%%
H;T !" $FN ,++-6Hh6H6H6J4UbH	**" *.6:+/"&	gR +/7;,0#'	<8  $$d4XX^^4 $4r"RXX]]R#rxx~~	l"\ !%d4 hhnnD!!%D#bhhmmb $"F"P"H-^.K`
( $H
( /0N	  &I" 12O2 Xx(E8r+   r-   c                   2     e Zd Z fdZ fdZ fdZ xZS )MetaSigStrategyc                     d|v r|j                  d      |d<   t        t        |   | |||      }|j                  |_        |S )Nr   _next_custom)r"   r#   r  r$   _next_catchr   )r%   r&   r'   r(   r3   r)   s        r*   r$   zMetaSigStrategy.__new__  sE    S="%''&/COT24ucJ ??
r+   c                    t        t        | 
  |g|i |\  }}}t        j                  t
              |_        |j                  j                  }||j                  |_
        nt        |t              r|j                  |   |_
        nZt        |t              r|j                  |      |_
        n3t        |t         j"                        r||_
        n|j                  |_
        |||fS r5   )r#   r  rA   rI   rJ   rF   _signalsr  _datadata0_dtargetrh   r
   rl   r   r  r7   LineRoot)r3   r?   r=   r>   r  r)   s        r*   rA   zMetaSigStrategy.dopreinit  s    /31$HHH 	dF $//5= JJDM}- JJu-DM|, ..u5DMr{{+!DM JJDMT6!!r+   c                 z   t        t        | 
  |g|i |\  }}}|j                  j                  D ]+  \  }}}}|j
                  |   j                   ||i |       - t        |j
                  t        j                           |_
        t        |j
                  t        j                           |_        t        |j
                  t        j                           |_        t        |j
                  t        j                           |_        t        |j
                  t        j"                           |_        |||fS r5   )r#   r  rX   r  signalsr  rz   boolr7   SIGNAL_LONGSHORT
_longshortSIGNAL_LONG_longSIGNAL_SHORT_shortSIGNAL_LONGEXIT	_longexitSIGNAL_SHORTEXIT
_shortexit)	r3   r?   r=   r>   sigtypesigclssigargs	sigkwargsr)   s	           r*   rX   zMetaSigStrategy.dopostinit  s    /324I$I&I 	dF 4866>> 	I/GVWiMM'"))&'*GY*GH	I t}}R-@-@AB$--78
4==9:dmmB,>,>?@t}}R-@-@ABT6!!r+   )rZ   r[   r\   r$   rA   rX   r^   r_   s   @r*   r  r    s    	"(" "r+   r  c                   T     e Zd ZdZdg fdddfZ fdZd Zg g f fd	Zd	 Zd
 Z	 xZ
S )SignalStrategyat
  This subclass of ``Strategy`` is meant to to auto-operate using
    **signals**.

    *Signals* are usually indicators and the expected output values:

      - ``> 0`` is a ``long`` indication

      - ``< 0`` is a ``short`` indication

    There are 5 types of *Signals*, broken in 2 groups.

    **Main Group**:

      - ``LONGSHORT``: both ``long`` and ``short`` indications from this signal
        are taken

      - ``LONG``:
        - ``long`` indications are taken to go long
        - ``short`` indications are taken to *close* the long position. But:

          - If a ``LONGEXIT`` (see below) signal is in the system it will be
            used to exit the long

          - If a ``SHORT`` signal is available and no ``LONGEXIT`` is available
            , it will be used to close a ``long`` before opening a ``short``

      - ``SHORT``:
        - ``short`` indications are taken to go short
        - ``long`` indications are taken to *close* the short position. But:

          - If a ``SHORTEXIT`` (see below) signal is in the system it will be
            used to exit the short

          - If a ``LONG`` signal is available and no ``SHORTEXIT`` is available
            , it will be used to close a ``short`` before opening a ``long``

    **Exit Group**:

      This 2 signals are meant to override others and provide criteria for
      exitins a ``long``/``short`` position

      - ``LONGEXIT``: ``short`` indications are taken to exit ``long``
        positions

      - ``SHORTEXIT``: ``long`` indications are taken to exit ``short``
        positions

    **Order Issuing**

      Orders execution type is ``Market`` and validity is ``None`` (*Good until
      Canceled*)

    Params:

      - ``signals`` (default: ``[]``): a list/tuple of lists/tuples that allows
        the instantiation of the signals and allocation to the right type

        This parameter is expected to be managed through ``cerebro.add_signal``

      - ``_accumulate`` (default: ``False``): allow to enter the market
        (long/short) even if already in the market

      - ``_concurrent`` (default: ``False``): allow orders to be issued even if
        orders are already pending execution

      - ``_data`` (default: ``None``): if multiple datas are present in the
        system which is the target for orders. This can be

        - ``None``: The first data in the system will be used

        - An ``int``: indicating the data that was inserted at that position

        - An ``str``: name given to the data when creating it (parameter
          ``name``) or when adding it cerebro with ``cerebro.adddata(...,
          name=)``

        - A ``data`` instance

    r  )_accumulateF)_concurrentF)r  Nc                 8    d | _         t        t        |           y r5   )	_sentinelr#   r  r   )rn   r)   s    r*   r   zSignalStrategy._startL  s    nd*,r+   c                 @    | j                   |   j                  |       y r5   )r  rz   )rn   r  signals      r*   
signal_addzSignalStrategy.signal_addP  s    g%%f-r+   c                     |xs | j                   }| j                  0|D ]+  }|| j                  k(  s|j                         r$d | _         n t        t        |   ||       y )Nr5  )rH   r  aliver#   r  r   )rn   r6  r7  r_  rK  r)   s        r*   r   zSignalStrategy._notifyS  s`    3 3 3
>>%# DNN*5;;=%)DN
 	nd+GW+Mr+   c                 ^    | j                          t        | d      r| j                          y y )Nr  )_next_signalhasattrr  r   s    r*   r  zSignalStrategy._next_catch^  s)    4( )r+   c                 
   | j                   | j                  j                  sy | j                  }dgg}t	        d |t
        j                     xs |D              }t	        d |t
        j                     xs |D              }t	        d |t
        j                     xs |D              }t	        d |t
        j                     xs |D              }t	        d |t
        j                     xs |D              }|xs |xs |}t	        d |t
        j                     xs |D              }	t	        d |t
        j                     xs |D              }
t	        d	 |t
        j                     xs |D              }|	xs |
xs |}t	        d
 |t
        j                     xs |D              }t	        d |t
        j                     xs |D              }t	        d |t
        j                     xs |D              }|xs |xs |}t	        d |t
        j                      xs |D              }t	        d |t
        j"                     xs |D              }t	        d |t
        j$                     xs |D              }|xs |xs |}| j&                   xr |}| j(                   xr |}t	        d |t
        j                     xs |D              }t	        d |t
        j                     xs |D              }t	        d |t
        j                     xs |D              }|xs |xs |}t	        d |t
        j                     xs |D              }t	        d |t
        j                     xs |D              }t	        d |t
        j                     xs |D              }|xs |xs |}| j&                   xr |}| j(                   xr |}| j+                  | j,                        j.                  }|sK|s|r!| j1                  | j,                        | _         y |s|r!| j3                  | j,                        | _         y y |dkD  r|s|s|s|r| j5                  | j,                         |s|r | j3                  | j,                        | _         |s|r8| j                  j6                  r!| j1                  | j,                        | _         y y y |dk  r|s|s|s|r| j5                  | j,                         |s|r | j1                  | j,                        | _         |s|r8| j                  j6                  r!| j3                  | j,                        | _         y y y y )Nr  c              3   ,   K   | ]  }|d    dkD    ywr   r  Nr   r   r   s     r*   r   z.SignalStrategy._next_signal.<locals>.<genexpr>k       MQadSjMr   c              3   ,   K   | ]  }|d    dk    ywr  r   r  s     r*   r   z.SignalStrategy._next_signal.<locals>.<genexpr>l       NaqtczNr   c              3   ,   K   | ]  }|d    dkD    ywr  r   r  s     r*   r   z.SignalStrategy._next_signal.<locals>.<genexpr>n  s     IaqtczIr   c              3   ,   K   | ]  }|d    dk    ywr  r   r  s     r*   r   z.SignalStrategy._next_signal.<locals>.<genexpr>o  s     MaqtczMr   c              3   &   K   | ]	  }|d      ywr   r   r  s     r*   r   z.SignalStrategy._next_signal.<locals>.<genexpr>p  s     GqtG   c              3   ,   K   | ]  }|d    dk    ywr  r   r  s     r*   r   z.SignalStrategy._next_signal.<locals>.<genexpr>s  s     JaqtczJr   c              3   ,   K   | ]  }|d    dkD    ywr  r   r  s     r*   r   z.SignalStrategy._next_signal.<locals>.<genexpr>t  r  r   c              3   &   K   | ]	  }|d      ywr   r   r  s     r*   r   z.SignalStrategy._next_signal.<locals>.<genexpr>u  s     HqtHr  c              3   ,   K   | ]  }|d    dk    ywr  r   r  s     r*   r   z.SignalStrategy._next_signal.<locals>.<genexpr>x  s     J1AaD3JJr   c              3   ,   K   | ]  }|d    dkD    ywr  r   r  s     r*   r   z.SignalStrategy._next_signal.<locals>.<genexpr>y  s     N1AaD3JNr   c              3   &   K   | ]	  }|d      ywr   r   r  s     r*   r   z.SignalStrategy._next_signal.<locals>.<genexpr>z  s     HQAaDHr  c              3   ,   K   | ]  }|d    dkD    ywr  r   r  s     r*   r   z.SignalStrategy._next_signal.<locals>.<genexpr>}  s     K1AaD3JKr   c              3   ,   K   | ]  }|d    dk    ywr  r   r  s     r*   r   z.SignalStrategy._next_signal.<locals>.<genexpr>~  s     O1AaD3JOr   c              3   &   K   | ]	  }|d      ywr   r   r  s     r*   r   z.SignalStrategy._next_signal.<locals>.<genexpr>  s     IQAaDIr  c              3   ,   K   | ]  }|d    dk    ywr  r   r  s     r*   r   z.SignalStrategy._next_signal.<locals>.<genexpr>  s     HQadSjHr   c              3   ,   K   | ]  }|d    dkD    ywr  r   r  s     r*   r   z.SignalStrategy._next_signal.<locals>.<genexpr>  s     LQadSjLr   c              3   &   K   | ]	  }|d      ywr   r   r  s     r*   r   z.SignalStrategy._next_signal.<locals>.<genexpr>  s     FqadFr  c              3   ,   K   | ]  }|d    dkD    ywr  r   r  s     r*   r   z.SignalStrategy._next_signal.<locals>.<genexpr>  s     IQadSjIr   c              3   ,   K   | ]  }|d    dk    ywr  r   r  s     r*   r   z.SignalStrategy._next_signal.<locals>.<genexpr>  r  r   c              3   &   K   | ]	  }|d      ywr   r   r  s     r*   r   z.SignalStrategy._next_signal.<locals>.<genexpr>  s     GqadGr  r   )r  r  r  r  allr7   r  r  SIGNAL_LONG_INVSIGNAL_LONG_ANYr  SIGNAL_SHORT_INVSIGNAL_SHORT_ANYr  SIGNAL_LONGEXIT_INVSIGNAL_LONGEXIT_ANYr  SIGNAL_SHORTEXIT_INVSIGNAL_SHORTEXIT_ANYr  r  r  r  r  r  r  r  r  ) rn   sigsnosigls_longls_shortl_enter0l_enter1l_enter2l_enters_enter0s_enter1s_enter2s_enterl_ex0l_ex1l_ex2l_exits_ex0s_ex1s_ex2s_exitl_revs_revl_leav0l_leav1l_leav2l_leaves_leav0s_leav1s_leav2s_leaver  s                                    r*   r  zSignalStrategy._next_signalc  s|   >>%dff.@.@}} M$r/B/B*C*LuMMN40C0C+D+MNNI4+?+H5IIM40B0B+C+LuMMGT"*<*<%=%FGG2h2(J4+@+IEJJN40C0C+D+MNNHT"*=*=%>%G%HH2h2(JR-?-?(@(IEJJNR-C-C(D(MNNH$r'='=">"G%HH(%(5KR-@-@(A(JUKKOR-D-D(E(NOOI$r'>'>"?"H5II(%(5 NN".wOO#/ H$r~~*>*G%HHL$r/A/A*B*KeLLFD););$<$EFF/W/I$r*?*H5IIM$r/B/B*C*LuMMGD)<)<$=$FGG/W/ nn$0oo%1' .33'!%$--!8W!%4==!9 % AX6Ug

4==)5!%4==!9'66%%%)XXdmm%<DN & " AX&EW

4==)%!%$--!8766%%%)YYt}}%=DN & # r+   )rZ   r[   r\   r  paramsr   r  r   r  r  r^   r_   s   @r*   r  r    sE    Nb 
B	F-. !" 	N 
S>r+   r  ),
__future__r   r   r   r   rI   rF  ra   inspectrP   r   	utils.py3r   r	   r
   r   r   r   r   r   r   
backtraderr7   lineiteratorr   r   linerootr   
lineseriesr   metabaser   r   rO  r   utilsr   r   r   r)   r   r-   r  r  r   r+   r*   <module>rL     s   ** *      C C C  4   & /  = =="<)) ="@R8~lL9 R8j*1"h(( 1"hB>^OX> B>r+   