
    'ihV                        d dl mZmZmZmZ d dlZd dl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 d dlmZmZ d dlmZ  G d dej.                        Z G d	 d
ej.                        Z G d dej.                        Z G d dej.                        Z G d dej8                        Z G d dej:                        Z G d de      Z G d d eee            Z y)    )absolute_importdivisionprint_functionunicode_literalsN)datetime	timedelta)
MetaParams)queuewith_metaclass)AutoDictc                        e Zd Z fdZ xZS )OandaRequestErrorc                 T    t        ddd      }t        | j                  |   |       y )NiW  zRequest Error codemessagedescriptiondictsuper	__class____init__selferr   s     Z/var/www/app/trading-bot/venv/lib/python3.12/site-packages/backtrader/stores/oandastore.pyr   zOandaRequestError.__init__*   $    sODdnnd,R0    __name__
__module____qualname__r   __classcell__r   s   @r   r   r   )       1 1r   r   c                         e Zd Zd fd	Z xZS )OandaStreamErrorc                 T    t        dd|      }t        | j                  |   |       y )NiV  zFailed Streamingr   r   r   contentr   r   s      r   r   zOandaStreamError.__init__0   s%    s$6GLdnnd,R0r   )r   r    r%   s   @r   r(   r(   /   s    1 1r   r(   c                        e Zd Z fdZ xZS )OandaTimeFrameErrorc                 T    t        ddd      }t        | j                  |   |       y )NiU  zNot supported TimeFramer   r   r   r*   s      r   r   zOandaTimeFrameError.__init__6   s%    s$=2Ndnnd,R0r   r    r%   s   @r   r-   r-   5   r&   r   r-   c                        e Zd Z fdZ xZS )OandaNetworkErrorc                 T    t        ddd      }t        | j                  |   |       y )NiT  zNetwork Errorr   r   r   r   s     r   r   zOandaNetworkError.__init__<   r   r   r    r%   s   @r   r0   r0   ;   r&   r   r0   c                       e Zd ZddZy)APINc                    | j                   d|}|j                         }|xs i }t        | j                  |      }i }|dk(  r||d<   n||d<   	  ||fi |}|j                  j                  d      }	t        j                  |	      }	|j                  dk\  rt        j                  |	      j                  S |	S # t        j
                  $ r}t               j                  cY d }~S d }~ww xY w)N/getparamsdatautf-8i  )api_urllowergetattrclientrequestsRequestExceptionr   error_responser+   decodejsonloadsstatus_codeoandapy
OandaError)
r   endpointmethodr7   urlfuncrequest_argsresponseer+   s
             r   requestzAPI.requestB   s     x02t{{F+U?%+L"#)L 	6C0<0H ""))'2**W% 3&%%g.=== (( 	6$&555	6s   	B: :C+C& C+&C+)GETN)r!   r"   r#   rN    r   r   r3   r3   A   s    r   r3   c                   4     e Zd Zd fd	ZddZd Zd Z xZS )Streamerc                     t        t        | 
  |i | |r%| j                  j                  j                  |       || _        y N)r   rR   r   r=   headersupdateq)r   rW   rU   argskwargsr   s        r   r   zStreamer.__init__d   s9    h&77KK&&w/r   c                    d| _         |xs i }d }d|v r|d   }i }||d<   | j                  d|}| j                   r	  | j                  j                  |fi |}|j                  dk7  r| j                  |j                         y 	 |j                  d       D ]O  }| j                   s nA|st        j                  |j!                  d            }	|rd|	v r?| j#                  |	       Q | j                   ry y # t        j
                  $ r7}| j                  j                  t               j                         Y d }~y d }~ww xY w#  | j                  j                  t%               j                         Y y xY w)	NTignore_heartbeatr7   r5      )
chunk_sizer9   	heartbeat)	connectedr:   r=   r6   r>   r?   rW   putr   r@   rD   on_errorr+   
iter_linesrB   rC   rA   
on_successr(   )
r   rG   r7   r[   rK   rI   rL   rM   liner8   s
             r   runzStreamer.runm   sR    2'%&89!'Xx0nn*4;;??3?,?
 ##s*h../$//4/@ 2D>>#zz$++g*>? 0[D5H OOD12 nn ,, 

,.==>&

+-<<=s/   C: %E -*E E :E-D??E/E8c                     d|v r| j                   j                  |d          y d|v r| j                   j                  |d          y y )Nticktransaction)rW   r`   r   r8   s     r   rc   zStreamer.on_success   s?    T>FFJJtF|$d"FFJJtM*+ #r   c                     | j                          | j                  j                  t        |      j                         y rT   )
disconnectrW   r`   r(   r@   ri   s     r   ra   zStreamer.on_error   s(    

#D)889r   rT   )r!   r"   r#   r   re   rc   ra   r$   r%   s   @r   rR   rR   c   s    )V,:r   rR   c                   ,     e Zd ZdZ fdZ fdZ xZS )MetaSingletonz1Metaclass to make a metaclassed class a singletonc                 >    t         t        |   |||       d | _        y rT   )r   rm   r   
_singleton)clsnamebasesdctr   s       r   r   zMetaSingleton.__init__   s    mS*4<r   c                 d    | j                   t        t        |   |i || _         | j                   S rT   )ro   r   rm   __call__)rp   rX   rY   r   s      r   ru   zMetaSingleton.__call__   s4    >>!mS2DCFC N ~~r   )r!   r"   r#   __doc__r   ru   r$   r%   s   @r   rm   rm      s    ; r   rm   c            	           e Zd ZdZdZdZdZ eddd      ZdZ	dZ
ed        Zed	        Z fd
ZdHdZd Zd Zd Zi ej(                  j*                  dfdej(                  j*                  dfdej(                  j*                  dfdej(                  j*                  dfdej(                  j,                  dfdej(                  j,                  dfdej(                  j,                  dfdej(                  j,                  dfdej(                  j,                  dfdej(                  j,                  dfdej(                  j,                  dfdej(                  j,                  dfdej(                  j,                  dfdej(                  j,                  d fd!ej(                  j,                  d"fd#ej(                  j,                  d$fd%ej(                  j,                  d&fd'ej(                  j,                  d(fd)ej(                  j.                  dfd*ej(                  j0                  dfd+ej(                  j2                  dfd,iZd- Zd. Zd/ ZdId0ZdId1ZdId2Z d3 Z!d4 Z"dId5Z#d6 Z$d7 Z%d8 Z&ejN                  jP                  d9ejN                  jR                  d:ejN                  jT                  d;ejN                  jV                  d;iZ,d< Z-d= Z.dHd>Z/g d?Z0d@gZ1dA Z2dB Z3dC Z4dDZ5dE Z6dFZ7dG Z8 xZ9S )J
OandaStoreag  Singleton class wrapping to control the connections to Oanda.

    Params:

      - ``token`` (default:``None``): API access token

      - ``account`` (default: ``None``): account id

      - ``practice`` (default: ``False``): use the test environment

      - ``account_tmout`` (default: ``10.0``): refresh period for account
        value/cash refresh
    N))tokenr   )accountr   )practiceF)account_tmoutg      $@i     r{   livec                 &     | j                   |i |S )z%Returns ``DataCls`` with args, kwargs)DataClsrp   rX   rY   s      r   getdatazOandaStore.getdata   s     s{{D+F++r   c                 &     | j                   |i |S )zAReturns broker with *args, **kwargs from registered ``BrokerCls``)	BrokerClsr   s      r   	getbrokerzOandaStore.getbroker   s     s}}d-f--r   c                 d   t         t        |           t        j                         | _        d | _        d | _        t               | _	        t        j                         | _        t        j                         | _        t        j                  t        j                        | _        | j                  j                   r| j"                  n| j$                  | _        t)        | j&                  | j                  j*                  ddi      | _        d| _        d| _        t3        j4                         | _        y )NX-Accept-Datetime-FormatUNIXenvironmentaccess_tokenrU   g        )r   rx   r   collectionsdequenotifs_envbrokerlistdatasOrderedDict_orders
_ordersrevdefaultdict
_transpendpr{   _ENVPRACTICE_ENVLIVE_oenvr3   ry   oapi_cash_value	threadingEvent	_evt_acct)r   r   s    r   r   zOandaStore.__init__   s    j$(*!'')	V
"..0%113%11+2C2CD*.&&//T&&t}}
DJJ%)VV\\!;V DF	 
"*r   c                    |
|d | _         y |U|j                  | _        | j                  j                  |       | j                  | j                  j                  |       y y |(|| _        | j                          | j                          y y rT   )cashr   r   appendr   data_startedstreaming_eventsbroker_threads)r   r8   r   s      r   startzOandaStore.start   s    <FNDI		DIJJd#{{&((. '  DK!!#!  r   c                     | j                   R| j                  j                  d        | j                  j                  d        | j                  j                  d        y y rT   )r   q_ordercreater`   q_orderclose	q_accountr   s    r   stopzOandaStore.stop  sK    ;;"""4(!!$'NNt$ #r   c                 @    | j                   j                  |||f       y rT   )r   r   )r   msgrX   rY   s       r   put_notificationzOandaStore.put_notification  s    Cv./r   c                     | j                   j                  d       t        | j                   j                  d      D cg c]  }| c}S c c}w )z(Return the pending "store" notificationsN)r   r   iterpopleft)r   xs     r   get_notificationszOandaStore.get_notifications  s9    4  3 3T:;a;;;s   	A
   S5
   S10   S15   S30M1   M3      M4M5<   H1x   H2   H3   H4ih  H6i  H8DWMc                     	 | j                   j                  | j                  j                        }|j                  dg       }|S # t        j
                  t        f$ r Y y w xY w)N	positions)r   get_positionsr   rz   rE   rF   r   r6   )r   r   poslists      r   r   zOandaStore.get_positions)  sZ    			//?I --R0	 ""$57 		s   /A A! A!c                 >    | j                   j                  ||fd       S rT   )_GRANULARITIESr6   )r   	timeframecompressions      r   get_granularityzOandaStore.get_granularity2  s     ""&&	;'?FFr   c                     	 | j                   j                  | j                  j                  |      }|j                  di g      }|d   xs d S # t        j
                  t        f$ r Y y w xY w)Ninstrumentsr   r   )r   get_instrumentsr   rz   rE   rF   r   r6   )r   datanameinstsis       r   get_instrumentzOandaStore.get_instrument5  sp    	II--dffnn:B . DE
 IImbT*t|t	 ""$57 		s   1A A+*A+c                    t        j                         }||d}t        j                  | j                  |      }d|_        |j                          t        j                  | j                  |      }d|_        |j                          |S )N)rW   tmouttargetrY   T)r
   Queuer   Thread_t_streaming_listenerdaemonr   _t_streaming_events)r   r   rW   rY   ts        r   r   zOandaStore.streaming_events?  sl    KKM5)D$>$>vN		D$<$<VL		r   c                 H    	 |j                         }| j                  |       "rT   )r6   _transaction)r   rW   r   transs       r   r   z OandaStore._t_streaming_listenerL  s#    EEGEe$ r   c                     |t        j                  |       t        || j                  | j                  j
                  ddi      }|j                  d       y )Nr   r   r   F)r[   )_timesleeprR   r   r   ry   events)r   rW   r   streamers       r   r   zOandaStore._t_streaming_eventsQ  sK    KKA(,

)-%?$HJ
 	/r   c                     t               j                         }|j                  d       t        j                         x|d<   }	t        j                  | j                  |      }
d|
_        |
j                          |	S )Nr   rW   r   T)
localscopypopr
   r   r   r   
_t_candlesr   r   )r   r   dtbegindtendr   r   candleFormatincludeFirstrY   rW   r   s              r   candleszOandaStore.candles\  s\     

6++-'saDOOFC		r   c	                 t   | j                  ||      }	|	&t               }
|j                  |
j                         y i }|)t	        || j
                  z
  j                               |d<   |)t	        || j
                  z
  j                               |d<   	  | j                  j                  d||	|d|}|j                  dg       D ]  }|j                  |        |j                  i        y # t        j                  $ r6}
|j                  |
j                         |j                  d        Y d }
~
y d }
~
ww xY w)Nr   end)
instrumentgranularityr   r   rP   )r   r-   r`   r@   int_DTEPOCHtotal_secondsr   get_historyrE   rF   r6   )r   r   r   r   r   r   r   r   rW   r  rM   dtkwargsrL   candles                 r   r   zOandaStore._t_candlesg  s)    **9kB#%AEE!""# #Wt}}%<$K$K$M NHW!54==#8"G"G"IJHUO		,tyy,, 99D:F9 089H ll9b1 	FEE&M	 	
b	 !! 	EE!""#EE$K	s    C. .D7,D22D7c                     t        j                         }|||d}t        j                  | j                  |      }d|_        |j                          |S )N)rW   r   r   r   T)r
   r   r   r   _t_streaming_pricesr   r   )r   r   r   rW   rY   r   s         r   streaming_priceszOandaStore.streaming_prices  sF    KKMh?D$<$<VL		r   c                     |t        j                  |       t        || j                  | j                  j
                  ddi      }|j                  | j                  j                  |       y )Nr   r   r   r   )r   r   rR   r   r   ry   ratesrz   )r   r   rW   r   r   s        r   r  zOandaStore._t_streaming_prices  sT    KKA4::)-%?$HJ 	tvv~~8<r   c                     | j                   S rT   )r   r   s    r   get_cashzOandaStore.get_cash  s    zzr   c                     | j                   S rT   )r   r   s    r   	get_valuezOandaStore.get_value  s    {{r   marketlimitr   c                 x   t        j                         | _        | j                  j                  d       t	        j
                  | j                        }d|_        |j                          t        j                         | _	        t	        j
                  | j                        }d|_        |j                          t        j                         | _        t	        j
                  | j                        }d|_        |j                          | j                  j                  | j                  j                          y )NT)r   )r
   r   r   r`   r   r   
_t_accountr   r   r   _t_order_creater   _t_order_cancelr   waitr   r|   )r   r   s     r   r   zOandaStore.broker_threads  s    4 DOO4		"[[]D$8$89		!KKMD$8$89		 	DFF001r   c                    	 	 | j                   j                  | j                  j                        }|y 	 	 | j                  j                  | j                  j                        }	 |d   | _        |d   | _        | j                  j                          # t        j
                  $ r Y uw xY w# t        $ r}| j                  |       Y d }~d }~ww xY w# t        $ r Y fw xY w)N)timeoutmarginAvailbalance)r   r6   r   r|   r
   Emptyr   get_accountrz   	Exceptionr   r   r   KeyErrorr   set)r   r   accinforM   s       r   r  zOandaStore._t_account  s    nn((1E1E(F; 
))//?
$]3
%i0 NN ) 
 ;; 
  %%a(  s:   2B /B0 (C B-,B-0	C9CC	C#"C#c                 B   t               }|j                  j                  |d<   t        |j                  j
                        |d<   |j                         rdnd|d<   | j                  |j                     |d<   |j                  t        j                  j                  k7  r|j                  j                  |d<   |j                  "t        j                         t!        d	      z   }n%|j                  j#                  |j                        }t%        || j&                  z
  j)                               |d
<   |j                  t        j                  j*                  k(  r2|j                  j,                  |d<   |j                  j,                  |d<   |j                  t        j                  j.                  k(  r|j0                  |d<   ||j                  |d<   ||j                  |d<    |j2                  di | | j4                  j7                  |j8                  |f       |S )Nr  unitsbuysellsidetypepricer   )daysexpiry
lowerBound
upperBoundtrailingStopstopLoss
takeProfitrP   )r   r8   	_datanameabscreatedsizeisbuy_ORDEREXECSexectypebtOrderMarketr*  validr   utcnowr   num2dater  r  r  	StopLimit
pricelimit	StopTrailtrailamountrV   r   r`   ref)r   orderstopsidetakesiderY   okwargsr<  s          r   order_createzOandaStore.order_create  s   & %

 4 4u}}112#(;;=%f**5>>:>>RXX__,$}}22GG{{" )I2,>>

++EKK8 #UT]]%:$I$I$K LGH>>RXX///$)MM$<$<GL!$)MM$<$<GL!>>RXX///&+&7&7GN#"*..GJ$,NNGL!  		745r   )orderOpenedtradeOpenedtradeReducedtradesClosedc                    	 | j                   j                         }|y |\  }}	  | j                  j                  | j                  j
                  fi |}t               }| j                  D ]&  }||v sd||   v s|j                  ||   d          ( | j                  D ]%  }||v s||   D ]  }|j                  |d           ' |s| j                  j                  |       y |d   | j                  |<   | j                  j                  |       |d   dk(  r| j                  j!                  |       |D ]W  }	|| j"                  |	<   | j$                  |	   }
|
j                  d        	 |
j'                         }|F| j)                  |	|       & # t        $ r6}| j                  |       | j                  j                  |       Y d }~y d }~ww xY w)Nidr   r)  r  )r   r6   r   create_orderr   rz   r   r   r   _rejectr   
_OIDSINGLEr   _OIDMULTIPLEr   _submit_acceptr   r   r   _process_transaction)r   r   orefrG  orM   oidsoidfieldsuboidfieldoidtpendingr   s               r   r  zOandaStore._t_order_create  s   $$((*C{MD'*DII**466>>EWE 6D OO 3q=TQx[%8KK(D 123 !-- 7q='({ 7K$5677
 ##D)!%aDLLKK%v(*##D) 
:'+$  ??3/%$,,.E}--c59	 
:E   %%a(##D)s   1F 	G,GGc                 P    | j                   j                  |j                         |S rT   )r   r`   rC  )r   rD  s     r   order_cancelzOandaStore.order_cancel%  s    eii(r   c                 B   	 | j                   j                         }|y | j                  j                  |d       }|=	 | j                  j	                  | j
                  j                  |      }| j                  j                  |       # t        $ r
}Y d }~d }~ww xY wrT   )
r   r6   r   r   close_orderr   rz   r   r   _cancel)r   rV  r[  rW  rM   s        r   r  zOandaStore._t_order_cancel)  s    $$((*D|,,""4.C{II))$&&..#> KK%   s   0B 	BB)STOP_ORDER_CREATELIMIT_ORDER_CREATEMARKET_IF_TOUCHED_ORDER_CREATEc                 R   |d   }|dk(  r
	 |d   d   }n|| j                  v r|d   }nv|dk(  r|d   }nk|dk(  r|d   }n`|d	k(  r.|d   }|d
   }|| j                  v r	 d}| j                  ||       y 	 |d   }d}|j	                  ||      }| j                  ||       y 	 | j
                  |   }| j                  ||       y # t         $ r 	 |d   d   }n# t         $ r Y Y y w xY wY Hw xY w# t         $ r d}Y w xY w# t         $ r! | j                  |   j                  |       Y y w xY w)Nr)  MARKET_ORDER_CREATErK  rN  rJ  ORDER_FILLEDorderIdORDER_CANCELTRADE_CLOSEtradeIdzYReceived TRADE_CLOSE for unknown order, possibly generated over a different client or GUINonez*Received {} with oid {}. Unknown situation)	r!  _X_ORDER_CREATEr   r   formatr   rU  r   r   )r   r   ttyper[  pidr   rV  s          r   r   zOandaStore._transaction<  s    f))N+D1 d***+Cn$	"Cn$	"Cm#+C	"Cdll"u5C!!#u-Dk ?C**UC(C!!#u-	/??3'D%%c51W  .t4C  B    	/OOC ''.	/sY   C 3C+  !C< 	C(CC(	C"C(!C""C('C(+C98C9<'D&%D&)rf  rg  TAKE_PROFIT_FILLEDSTOP_LOSS_FILLEDTRAILING_STOP_FILLEDc                 6   	 | j                   j                  |      }|d   }|| j                  v r5|d   }|d   dk(  r| }|d   }| j                  j                  ||||       y || j                  v r+| j                  j                  |       || j                   |<   y |dv ri|d   }|d	k(  ry |d
k(  r| j                  j                  |       y |dk(  r| j                  j                  |       y | j                  j                  |       y y # t        $ r Y y w xY w)Nr)  r%  r(  r'  r*  )ro  ri  reasonrg  TIME_IN_FORCE_EXPIREDCLIENT_REQUEST)r   r   r!  _X_ORDER_FILLEDr   _fillrm  rT  _expirera  rP  )r   r[  r   rV  ro  r5  r*  ru  s           r   rU  zOandaStore._process_transactionw  s   	??&&s+D fD(((>DV}&u'NEKKdD%u=d***KK%#'DOOC n$8_F'22##D)++##D)##D) %!  		s   D 	DD)NNrT   ):r!   r"   r#   rv   r   r   r7   r   r  r   r   classmethodr   r   r   r   r   r   r   r9  	TimeFrameSecondsMinutesDaysWeeksMonthsr   r   r   r   r   r   r   r   r   r  r  r  r  r:  r;  LimitStopr?  r7  r   r  rH  rQ  rR  r  r^  r  rm  r   rx  rU  r$   r%   s   @r   rx   rx      sa    IGF a#HLH, , . .+,"&%0<			q!4			r"E 
		r"E 
		r"E	
 
		q!4 
		q!4 
		q!4 
		q!4 
		q!4 
		r"D 
		r"D 
		r"D 
		r"D 
		s#T 
		s#T  
		s#T!" 
		s#T#$ 
		s#T			A			Q			a #+N0G%
	0	@= 	

v
F	K2(!. D @J"#L-:^& PO5/nDO*r   rx   )!
__future__r   r   r   r   r   r   r   timer   rB   r   rE   r>   
backtraderr9  backtrader.metabaser	   backtrader.utils.py3r
   r   backtrader.utilsr   rF   r   r(   r-   r0   r3   rR   rm   objectrx   rP   r   r   <module>r     s   ** *  (       * 6 %
1** 11w)) 11',, 11** 1'++ D=:w =:@J b*v6 b*r   