
    i'N                        d Z ddl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m	Z	 ddl
mZ ddZddZddZdd	Zdd
Zddd	 	 	 	 	 ddZddZddZedk(  r ej*                   e              yy)u  
APEX V16 — Entry point.

CLI argument parsing, environment loading, config validation,
and bot lifecycle handoff to orchestrator.

Usage:
    python main.py --mode dry
    python main.py --mode paper --asset MES,MNQ
    python main.py --mode live --account ineligible
    python main.py --mode live --account express   # requires confirmation
    python main.py --mode paper --fresh-start

For full options, run: python main.py --help
    )annotationsN)Path)Optionalc                   | j                         syd}| j                  d      j                         D ]  }|j                         }|r|j	                  d      r'd|vr,|j                  d      \  }}}|j                         }|j                         j                  d      j                  d      }|s|t        j                  vs|t        j                  |<   |dz  } |S )	z
    Load KEY=VALUE pairs from a .env file into os.environ.
    Existing env vars are NOT overridden (they win).

    Returns the number of variables loaded.
    r   zutf-8)encoding#="'   )exists	read_text
splitlinesstrip
startswith	partitionosenviron)env_pathloadedlinekey_values         /home/work/apex_v16/main.pyload_env_filer       s     ??F""G"4??A zz|ts+d?s+Qiik##C(..s33bjj(#BJJsOaKF M    c                    t        j                  ddt         j                  d      } | j                  dg ddd	       | j                  d
ddgdd       | j                  ddd       | j                  dt        dd       | j                  dt
        t        j                         dz  dz  d       | j                  dt        dd       | S )z3Build the argparse parser with all V16 CLI options.apex_v16u>   APEX V16 — Trading bot for CME futures via TopstepX/ProjectXzExamples:
  python main.py --mode dry
  python main.py --mode paper --asset MES,MNQ
  python main.py --mode live --account ineligible
  python main.py --mode live --account express   # requires confirmation)progdescriptionformatter_classepilogz--modedrypaperliveTzKRun mode: dry (connected, no trades), paper (simulated), live (real trades))choicesrequiredhelpz	--account
ineligibleexpresszNTopstep account: ineligible (burned) or express (FUNDED). Default: ineligible.)r(   defaultr*   z--fresh-start
store_truezFIgnore previous state file and start fresh (deletes state and backup).)actionr*   z--assetNzPComma-separated asset filter (e.g. 'MES,MNQ'). Default: all from config_futures.)typer-   r*   z
--env-fileapex_v15z.envz8Path to .env file. Default: ~/apex_v15/.env (V15 reuse).z--max-trades-sessionz9Hard cap on trades for this session (dev/testing safety).)argparseArgumentParserRawDescriptionHelpFormatteradd_argumentstrr   homeint)ps    r   build_parserr:   >   s    T <<W	A NN(Z	   NNy)]	   NNU   NN_	   NN		j(61G	   NNH	   Hr   c           
        ddl m}m}m}m}  | || j
                         || j                        | j                  | j                  r7| j                  j                  d      D cg c]  }|j                          c}nd      }| j                  | j                  |_        |j                  r|j                  r ||      }|S c c}w )z}
    Build RuntimeConfig from CLI args.
    Applies EXPRESS profile (tightened risk) automatically when account=express.
    r   )RuntimeConfigRunModeAccountKindapply_express_profile,Nmodeaccountfresh_startasset_filter)core.configr<   r=   r>   r?   rB   rC   rD   assetsplitr   max_trades_sessionis_live
is_express)argsr<   r=   r>   r?   acfgs          r   build_configrO      s     WV
TYYDLL)$$CG::)9)9#)>?Aaggi?SW	C *!%!8!8 {{s~~#C(J @s   %Cc           	        ddl m} | j                  st        |j	                               S t        | j                        }|D cg c]	  }||v s| }}|D cg c]	  }||vs| }}|rqt        ddj                  |       t        j                         t        ddj                  t        |j	                                      t        j                         |S c c}w c c}w )u  
    Resolve the effective tradable asset list.

      --asset MES,MNQ  -> intersect with ASSETS_MAP, warn on unknowns.
      (no --asset)     -> all keys of ASSETS_MAP.

    Returns [] if every requested asset was unknown — caller exits.
    Lazy import keeps --help fast.
    r   )
ASSETS_MAPz6WARNING: --asset contained unknown symbols (ignored): , filez  Known symbols: )
core.config_futuresrQ   rE   listkeysprintjoinsysstderrsorted)rN   rQ   	requestedrM   knownunknowns         r   resolve_asset_listr`      s     /JOO%&&S%%&I!51Q*_Q5E5#;Qq
':q;G;Dyy!"$	

 			&1B*C DEF	
 L 6;s   	CC	C##C#c                   d}dddd| j                   j                     }ddd| j                  j                     }t        |       t        d	       t        |       t        d
|        t        d|        t        d| j                          t        d| j
                          t        d| j                          t        d| j                          t        d| j                  dz  dd       t        d| j                  dd| j                  d       t        d| j                  rdnd        | j                  rdnd}t        ddj                  |       dt        |       d|        t        |       y )!z'Print configuration summary at startup.z<============================================================zDRY RUN (no trades placed)zPAPER (simulated)zLIVE (real trades)r$   z!INELIGIBLE (burned $100K combine)z,EXPRESS (FUNDED $100K)  *** REAL CAPITAL ***)r+   r,   zAPEX PREDATOR V16zMode:      zAccount:   zAccount #: zState:     zLogs:      zFresh:     zRisk:      d   .2fz% per tradezDaily:     target $z.0fz / hard stop $zCorrelat.: ONOFFz (filter: --asset) zAssets:    rR    ()N)rB   r   rC   rX   
account_id
state_filelog_dirrD   risk_per_tradedaily_profit_targetdaily_loss_hard_stopenable_correlationrE   rY   len)rN   
asset_listbar
mode_labelaccount_labelsuffixs         r   print_bannerrv      su   
C-$% 
hhnn	J :D 
kkM
 
#J	
	#J	K
|
$%	K
'(	K'
()	K'
()	K}
%&	K(
)*	K**3.s3;
?@	 7 7<N3KcKcdgJh
ij	K 6 6EB
CD%(%5%5!2F	K		*-.bZ0A6(
KL	#Jr      )   
      )max_attemptsdelays_secondsc                 K   t        d|dz         D ]  }	 | j                          d{   }|r#|dkD  r|j                  j                  d|        y|j                  j	                  d||       ||k  sd|t        |dz
  t        |      dz
           }t        j                  |       d{     y7 # t
        $ r(}|j                  j	                  d|||       Y d}~rd}~ww xY w7 =w)a$  
    Attempt broker.connect() up to max_attempts times with exponential-ish
    backoff. Returns True on success, False after the last failed attempt.
    Used for startup robustness against transient Topstep / network issues.
    BACKLOG: longer maintenance windows -> calibrate delays.
    r   Nz&broker.connect succeeded on attempt %dTz+broker.connect attempt %d/%d returned Falsez'broker.connect attempt %d/%d raised: %sF)
rangeconnectsysteminfowarning	Exceptionminrp   asynciosleep)brokerloggerr{   r|   attemptokedelays           r   _connect_with_retryr      s      L1,- '	~~''BQ;MM&&'OQXYMM!!= \!"3w{C4G!4K#LME--&&&%'& # (  	MM!!9q 	 's\   C,B6B4'B6C,B60C,66C,,C*-C,4B66	C'?C"C,"C''C,c                   ,-K   ddl m} j                  j                  d j                  j
                   d j                  j
                   d       j                  d j                  j
                   j                  j
                   j                   j                         ddl
m}m}  j                  r+|j                          j                  j                  d	        |||j                   j                  
      }j                  j                  dt!        |j"                         d|j$                  j&                  dd|j(                          ddlm}  |t/         d      r j0                  nd      }	|	j3                          d{   sj                  j5                  d       yddlm}
m} ddlm}  |        tA        jB                  dd      dk(  }d} j                  |jD                  k(  s j                  |jF                  k(  rddl$m%}  ||      }tM        |       d{   }|s/j                  j5                  d       j                  dd        y! j                  |jF                  k(  r,dd"l'm(}  ||      }j                  j                  d#       n|}|rKdd$l)m*}  |tA        jB                  d%      tA        jB                  d&      tA        jB                  d'      (      }n |
|      }d)}nW|rKdd$l)m*}  |tA        jB                  d%      tA        jB                  d&      tA        jB                  d'      (      }n |i       }d*}tW        |      jX                  }|d+k(  rJ|jZ                  rd,}n|j\                  r|j^                  rd-}nd.}j                  j                  d/||       nj                  j                  d0|       dd1l0m1} dd2l2m3}  | |	       | |	      d3}dd4l4m5} dd5l6m7} dd6l8m9}  |||7      } |||7      } | |      } d}!|dd8l:m;}"  |"||| 9      }!	 |!jy                          d{   }#j                  j                  d:t!        |#jz                        t!        |#j|                        t!        |#j~                        |#j                  t!        |#j                        t!        |#j                        t!        |#j                               dd<lFmG}%  |% |	||||||| ||!=      ,| fd>}&|&,_H        ddlI}'t        j                         }(i -dD,-fd?})|'j                  |'j                  fD ]%  }*	 |(j                  |* |)|*j                               ' 	 ,j                          d{   }+|	 |j                          d{    j                  dA-j                  dBdC              |+S 7 S7 7 # t        $ r'}$j                  j                  d;|$       Y d}$~$d}$~$ww xY w# t        t        f$ r Y w xY w7 7 |# t        $ r&}$j                  j                  d@|$       Y d}$~$d}$~$ww xY w# |M	 |j                          d{  7   n2# t        $ r&}$j                  j                  d@|$       Y d}$~$nd}$~$ww xY wj                  dA-j                  dBdC              w xY ww)Ez
    Async entry point: connect AI client, build market data provider,
    instantiate brains, then hand off to Orchestrator.run().
    Phase C1 wires broker.connect (LIVE/DRY) + signal handlers.
    r   )r=   zV16 starting in z	 mode on z accountsession_startedrA   )StateLoadMode
load_statezState reset (--fresh-start))rB   auto_daily_resetzState loaded: active_trades=z, daily_pnl=$rc   z	, halted=)AIClientai_modelN)modelr   z+AI client failed to connect; cannot proceedr   )BrokerMarketDataProviderFakeMarketDataProvider)apply_sdk_patchesUSE_TV_FEED01)TopstepXBroker)instruments)r   z-broker.connect failed after retries; abortingsession_failedbroker_connectreasonrw   )DryRunBrokerz/DRY mode: broker reads real, writes intercepted)TVDataFeedProviderTV_USERNAMETV_PASSWORDTV_TOKEN)usernamepasswordtokenFTr   r   credsanonzMarketDataProvider: %s (%s)zMarketDataProvider: %s)BrainTF)BrainMR)TFMR)TradeOpener)TradeCloser)RiskManager)r   is_paperr   )
Reconciler)r   staterisk_managerr   zVReconcile: case_i=%d case_ii=%d (recovered %d, $%.2f) case_iii=%d case_iv=%d case_v=%dz(Reconcile startup failed (non-fatal): %s)Orchestrator)config	ai_clientmarket_data_providerr   storer   brain_dispatchopenercloserr   r   
reconcilerc                   K   	 | j                          d {    t        | t        j                        t        j                               d {   S 7 A# t        $ r Y Jw xY w7 w)N)r   r{   r|   )
disconnectr   r   r8   mid_loop_reconnect_max_attemptstuple!mid_loop_reconnect_delays_seconds)brN   r   s    r   _mid_loop_reconnectz'async_main.<locals>._mid_loop_reconnect  sl     lln$$ -& !D!DE$S%J%JK   % sC   A-A AA 8A-A+A-A 	A(%A-'A((A-c                      fd}|S )Nc                 h    d<    j                   j                  d       j                          y )Nlastz%Received %s; requesting graceful stop)r   r   stop)r   nameorchestratorsignal_reasonss   r   _hz-async_main.<locals>._make_handler.<locals>._h  s.    %)N6"MM!!"I4Pr    )r   r   r   r   r   s   ` r   _make_handlerz!async_main.<locals>._make_handler  s    	  	r   zbroker.disconnect failed: %ssession_endedr   orchestrator_returned)r   r6   )UrF   r=   r   r   rB   r   rC   log_session_eventrD   rE   persistence.state_storer   r   resetRESUMErJ   rp   active_tradesdaily	daily_pnlhaltedbrain.ai_clientr   hasattrr   r   erroranalysis.market_datar   r   broker._sdk_patchesr   r   getenvLIVEDRYbroker.topstepx_v16r   r   broker.dry_run_brokerr   analysis.tv_data_providerr   r0   __name__r   r   r   brain.brain_tfr   brain.brain_mrr   trading.trade_openerr   trading.trade_closerr   trading.risk_managerr   broker.reconciliationr   reconcile_startup	case_i_okcase_ii_state_open_broker_flatcase_ii_recovered_via_historypnl_recovered_usdcase_iii_state_flat_broker_opencase_iv_size_mismatchcase_v_naked_ordersr   r   r   r   _reconnect_fnsignalr   get_running_loopSIGTERMSIGINTadd_signal_handlerr   NotImplementedError
ValueErrorrunr   get).rN   r   state_storerq   r=   r   r   r   r   r   r   r   r   use_tv_feedr   r   real_brokerr   r   r   providerr   provider_nametv_authr   r   brainsr   r   r   r   r   r   r   r   reportr   r   r   r   loopr   sigrcr   r   s.   ``                                          @@r   
async_mainr
    s7     $
MM)#((..)93;;CTCTBUU]^_
XX^^!!OO%%   B
89!!E
 MM
&s5+>+>'?&@ Akk++C0	%,,	I )wsJ/Gs||T &(I""$$$IJ
 6
 ))M3/36KF
xx7<<388w{{#:6$<&{6BBMM OP$$%5>N$O88w{{":!+f=FMMPQ FD)=1=1ii
+H 07H D)=1=1ii
+H .b1H
 N++M,,>>G8#4#4GG8-Q3]C '&c9f-c9f-F 100&IF&IFsE&9L J4%f

	Q%7799FMM3F$$%F99:F889((F::;F001F../
 *ih;vf<*L 		 &9"
 ##%D%'N . 	##Csxx)@A
##%% I''))) 	  !%%f.EF 	! 	

 Iw %4 Ch :  	QMM!!"LaPP	Q\ $Z0 	 	 &
 * I%%&DaHHI I''))) I%%&DaHHI  !%%f.EF 	! 	
s$  F[)W+B![):W.;H[)W4 $W1%B"W4 A&[)."X'[)Y2 &X<'Y2 +[).Y  X>Y  &[).[)1W4 4	X$=X[)X$$[)'X96[)8X99[)<Y2 >Y   	Y/	Y*%[)*Y//[)2[&6Z	Z
Z[&	Z?Z:5[&:Z??'[&&[)c                    t               } | j                         }t        |j                        }t        j
                  j                  d      sct        dt        j                         t        d|j                   d| dt        j                         t        dt        j                         yt        |      }|j                          t        |      }|st        d	t        j                         yt        ||       d
dlm} d
dlm}  ||j$                        } ||j&                        }d}		 t)        j,                  t/        ||||            S # t0        $ r1 |j2                  j5                  d       |j7                  dd       Y yt8        $ rD}
|j2                  j;                  d|
        |j=                  dt?        |
             Y d}
~
yd}
~
ww xY w)zDSynchronous entry point. Parses CLI, builds config, runs async main.ANTHROPIC_API_KEYz!ERROR: ANTHROPIC_API_KEY not set.rS   z  Tried .env file: rg   z vars loaded)z-  Set it in .env or export it before running.   zlERROR: no tradable assets after resolving --asset. Check the symbols against core/config_futures.ASSETS_MAP.r   )build_logger_bundle)
StateStoreNzInterrupted by user (Ctrl+C)r   keyboard_interruptr      zUnhandled exception: main)wherer   r   ) r:   
parse_argsr   env_filer   r   r   rX   rZ   r[   rO   require_express_confirmationr`   rv   persistence.logging_setupr  r   r  rk   rj   r   Eventr   r
  KeyboardInterruptr   r   r   r   	exception	log_errorr6   )parserrL   n_loadedrN   rq   r  r  r   r   shutdown_eventr   s              r   r  r    s   ^FD T]]+H ::>>-.1D#DMM?"XJmLSVS]S]^=SZZP t
C $$& $C(JH	

  j! >2 -FS^^,K 48N	{{:c6;
KLL <=  9M N "7s ;<vSV4s   5 E 7GG:GG__main__)r   r   returnr8   )r   zargparse.ArgumentParser)rL   zargparse.Namespace)r   	list[str])rq   r!  r   None)r{   r8   r|   ztuple[int, ...]r   bool)rq   r!  r   r8   )r   r8   )__doc__
__future__r   r2   r   r   r   rZ   pathlibr   typingr   r   r:   rO   r`   rv   r   r
  r  r   exitr   r   r   <module>r)     s     #   	  
  <>J2FN &1  	 
 $  
 F^B7t zCHHTV r   