
    bAj                        d Z ddlmZ ddlmZ ddlmZ ddlmZ ddl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 ddlmZmZ  ee      Z e       Ze G d d             Ze G d d             Z G d d      Z e       Zy)z+Backtesting engine for strategy validation.    )	dataclass)datetime)Decimal)AnyN)get_settings)
get_logger)	OrderSideSignalAction)indicators_service)statistics_service)StrategyEngineStrategyTypec                   r    e Zd ZU eed<   eed<   eed<   eed<   eed<   eed<   eed<   eed<   eed	<   eed
<   y)BacktestTradesideentry_price
exit_pricequantitypnlpnl_pct
commission
entry_time	exit_timeexit_reasonN)__name__
__module____qualname__r	   __annotations__floatr   str     JC:\xampp\htdocs\tradingbinance\backend\app\services\backtesting_service.pyr   r      s:    
OO	JNr"   r   c                   L    e Zd ZU ee   ed<   ee   ed<   eee	f   ed<   e
ed<   y)BacktestResulttradesequity_curvemetricsallowed_for_productionN)r   r   r   listr   r   r   dictr    r   boolr!   r"   r#   r%   r%   #   s+    u+#s(^  r"   r%   c                       e Zd ZdZd Z	 	 ddee   dedededz  de	f
d	Z
d
edededz  fdZd
ededefdZd
edededededefdZy)BacktestingEnginez
    Simulates strategy on historical candles with commissions and slippage.
    Production is NOT allowed if backtest is negative vs buy-and-hold.
    c                     t               | _        t        j                  dz  | _        t        j
                  dz  | _        y )Nd   )r   strategy_enginesettingsbacktest_commission_pctcommission_pctbacktest_slippage_pctslippage_pct)selfs    r#   __init__zBacktestingEngine.__init__1   s3    -/&>>D$::S@r"   Ncandlesstrategy_typeinitial_capitalparamsreturnc                    t        |      dk  rt        dt        |             |}|g}g }d }d}	t        |	t        |            D ]  }
||
|	z
  |
dz    }t        j                  ||      }d|v r*| j
                  j                  |||      }||
   }t        |d         }|d   }|rL| j                  |||      }|r7| j                  |||||      }||j                  z  }|j                  |       d }|s|j                  t        j                  k(  r|j                  dk\  r|j                   r|j"                  r||j                   z
  }|dkD  ru|t$        j&                  dz  z  }||z  }|d	z  |z  }t)        ||      }|d| j*                  z   z  }||z  | j,                  z  }||z  }|||j                   |j"                  ||d
}|j                  ||r| j/                  ||      ndz           |rLt        |d   d         }| j                  |||d   d   d|      }||j                  z  }|j                  |       t        ||	   d         }t        |d   d         }t1        j2                  ||      }|D cg c]  }|j                   }}t1        j4                  ||||      }||d<   |d   dkD  xr |j7                  dd      }t8        j;                  d|t        |      |d   |       t=        ||||      S c c}w )Nr0   zNeed at least 100 candles, got    errorclose	open_timeK   r   g?)r   r   	stop_losstake_profitr   r   end_of_datafinal_capitaltotal_return_pctbeats_buy_holdFbacktest_completed)strategyr&   
return_pctallowed)r&   r'   r(   r)   )len
ValueErrorranger   calculate_allr1   evaluater   _check_exit_close_positionr   appendactionr
   BUY
confidencerD   rE   r2   max_risk_per_trade_pctminr6   r4   _unrealized_pnlr   
pct_returncompute_backtest_metricsgetloggerinfor%   ) r7   r9   r:   r;   r<   capitalr'   r&   positionwindow_sizeiwindow
indicatorssignalcurrentprice	timestampr   traderisk_per_unitrisk_amountqtymax_qtyr   r   
last_pricefirst_pricebuy_holdt
trade_pnlsr(   rN   s                                    r#   runzBacktestingEngine.run6   sU    w<#>s7|nMNN!y&( ${CL1AQ_q1u5F+99&&IJ*$))22=*fUFajG''*+E,I"..xG 005)[ZabEuyy(GMM%(#H1A1A AfFWFW[]F]##(:(:$)F,<,<$<M$q(&-1P1PSV1V&W)M9#*S=E"9!#w/&+q43D3D/D&E%03%69L9L%L
:-+6(+)/)9)9+1+=+=*3*4$ T\4+?+?%+Pbc deO 2R wr{734J((:wr{;?WYfhopEuyy GMM% GK09:72;w/0
%00jI%+,VaeeV
,$==*ox
 $+ ,-1ZgkkBRTY6Z "v;12 	 	
 %#*	
 	
! -s   7K:rc   rj   c                     ||d   k  ry||d   k\  ry|j                   t        j                  k(  r|j                  dk  ryy )NrD   rE   (   signal_sell)rW   r
   SELLscore)r7   rc   rj   rh   s       r#   rT   zBacktestingEngine._check_exit   sE    H[))H]++ ==L---&,,"2D r"   c                     ||d   z
  |d   z  S )Nr   r   r!   )r7   rc   rj   s      r#   r\   z!BacktestingEngine._unrealized_pnl   s    //8J3GGGr"   rk   reasonrb   c                    |d| j                   z
  z  }||d   z  | j                  z  }||d   z
  |d   z  |z
  |d   z
  }||d   |d   z  z  dz  }	t        t        j                  |d   ||d   ||	||d   z   |d   ||
      S )Nr?   r   r   r   r0   r   )
r   r   r   r   r   r   r   r   r   r   )r6   r4   r   r	   rX   )
r7   rc   rj   rk   r}   rb   r   r   r   r   s
             r#   rU   z!BacktestingEngine._close_position   s     a$"3"334
(:"669L9LL
H]33x
7KKjX[cdp[qq-08J3GGH3N /!j)!H\$::-
 	
r"   )g     @N)r   r   r   __doc__r8   r*   r+   r    r   r%   rv   rT   r\   r   r   rU   r!   r"   r#   r.   r.   +   s    
A ")"X
dX
 X
 	X

 tX
 
X
tD  3: H HU Hu H

%*
7?
IL
W\
	
r"   r.   )r   dataclassesr   r   decimalr   typingr   pandaspdapp.core.configr   app.core.loggingr   
app.modelsr	   r
   app.services.indicators_servicer   app.services.statistics_servicer   app.services.strategy_enginer   r   r   r`   r2   r   r%   r.   backtesting_enginer!   r"   r#   <module>r      s    1 !     ( ' . > > E	H	> 
 
 
 ! ! !D
 D
N '( r"   