Files
mmd/__pycache__/saxo_broker.cpython-314.pyc

104 lines
15 KiB
Plaintext
Raw Normal View History

2026-05-26 22:21:27 +02:00
+
9<>j+<00> <00><><00>Rt^RIt^RIt^RIt^RIt^RIt^RIHt^RIHtH t ^RI
H t ^RI H t ] !4]P!RR4tRR lt/R
R6bR R7bR R8bR R9bRR:bRR;bRR<bRR=bRR>bRR?bRR@bRRAbRRBbRRCbRRDbRREbRRFbRRGRRHRRIRRJ/CtRtRKR ltR!tR"tR#tR$R%ltR&R'ltRLR(RR)RR*RR+R/R,R-llltRMR.R/lltR0R1ltR2tR3tR4t]R58Xd
]!4R#R#)Nu<4E>
saxo_broker.py — Saxo Bank SIM paper trading integration.
Reads SAXO_TOKEN + SAXO_BASE from .env (or environment).
Token expires after 24h — refresh at developer.saxobank.com/openapi/token
N)<01>Path)<02>datetime<6D>timezone)<01> load_dotenv)<01>get_conn<6E> SAXO_BASEz(https://gateway.saxobank.com/sim/openapic<00>$<00>V^8<>dQhR\/#<00><02><00>return)<01>str)<01>formats"<22>./home/hjess/Projects/MoneyMaker/saxo_broker.py<70> __annotate__rs<00><00>+<2B>+<2B>C<EFBFBD>+<2B>c<04>n<00>^RIHpV!4# \d\P!RR4u#i;i)uMGet valid token — prefers OAuth2 stored token, falls back to 24h env token.<2E><01> get_token<65>
SAXO_TOKEN<EFBFBD>)<05> saxo_authr<00> Exception<6F>os<6F>getenvrs r<00>
_get_tokenrs2<00><00>+<2B>'<27><18>{<7B><1A><> <14>+<2B><11>y<EFBFBD>y<EFBFBD><1C>r<EFBFBD>*<2A>*<2A>+<2B>s <00> <00>"4<03>4<03>NOVO-B<>DANSKE<4B>DSV<53>DEMANT<4E>ORSTEDzROCK-B<>VWS<57>COLOB<4F>GMABzMAERSK-BzNZYM-B<>NKT<4B>GN<47>BAVAR<41>TRYG<59>PNDORAzCARL-B<>CHR<48>FLS<4C>RBREW<45>SYDBc<00>$<00>RR\4 2RR/#)<04> AuthorizationzBearer z Content-Typezapplication/json)r<00>rr<00>_headersr/8s<00><00> <1B>w<EFBFBD>z<EFBFBD>|<7C>n<EFBFBD>5<>~<7E>GY<47> Z<>Zrc<00><><00>\P!\ V 2\4V^
R7pVP 4VP 4#)<02>
)<03>headers<72>params<6D>timeout)<06>requests<74>get<65>BASEr/<00>raise_for_status<75>json)<03>pathr3<00>rs&& r<00>_getr<<s8<00><00><10> <0C> <0C><04>v<EFBFBD>d<EFBFBD>V<EFBFBD>_<EFBFBD>h<EFBFBD>j<EFBFBD><16>QS<51>T<>A<EFBFBD><05><16><16><18> <0C>6<EFBFBD>6<EFBFBD>8<EFBFBD>Orc<00><><00>\P!\ V 2\4V^
R7pVP 4VP 4#)r1)r2r9r4)r5<00>postr7r/r8r9)r:<00>bodyr;s&& r<00>_postr@Bs7<00><00><10> <0A> <0A><14><06>t<EFBFBD>f<EFBFBD>o<EFBFBD>x<EFBFBD>z<EFBFBD><04>b<EFBFBD>Q<>A<EFBFBD><05><16><16><18> <0C>6<EFBFBD>6<EFBFBD>8<EFBFBD>Orc<04><><00>\R4pVPR.4pV'g \R4hV^,pVR,VR,3#)z3Return (ClientKey, AccountKey) for the SIM account.z/port/v1/accounts/me<6D>Datau.No accounts found — are you logged into SIM?<3F> ClientKey<65>
AccountKey)r<r6<00> RuntimeError)<03>data<74>accounts<74>accts r<00>get_account_inforIJsJ<00><00> <0F>&<26> '<27>D<EFBFBD><13>x<EFBFBD>x<EFBFBD><06><02>#<23>H<EFBFBD> <13><1A>K<>L<>L<> <13>A<EFBFBD>;<3B>D<EFBFBD> <0F> <0B> <1C>d<EFBFBD><<3C>0<> 0<>0rc<04><00>\R4#)z'Return cash balance dict from Saxo SIM.z/port/v1/balances/me)r<r.rr<00> get_balancesrKTs<00><00> <0F>&<26> '<27>'rc<00>><00>V^8<>dQhR\R\R,/#)r
<00>tickerr N)r <00>int)r s"rrr[s<00><00><10><10>S<EFBFBD><10>S<EFBFBD>4<EFBFBD>Z<EFBFBD>rc <04><><00>V\9dR#\V,wr\RRVRVRRR^/R7pVPR .4F$pVPR4V8XgKVR
,u# R#) z5Resolve our local ticker to Saxo UIC (instrument ID).Nz/ref/v1/instruments<74>Keywords<64>
ExchangeId<EFBFBD>
AssetTypes<EFBFBD>Stockz$top<6F>r3rB<00>
Identifier)<03> SAXO_SYMBOLSr<r6)rM<00>symbol<6F>exchange<67>results<74>items& r<00>find_uicr[[sx<00><00> <0A>\<5C>!<21><13>#<23>F<EFBFBD>+<2B><14>F<EFBFBD><12>(<28><12>F<EFBFBD><14>h<EFBFBD><14>g<EFBFBD><0E><01> 2<06><07>G<EFBFBD> <18> <0B> <0B>F<EFBFBD>B<EFBFBD>'<27><04> <0F>8<EFBFBD>8<EFBFBD>L<EFBFBD> !<21>X<EFBFBD> -<2D><17> <0C>%<25> %<25>(<28> rc<00>><00>V^8<>dQhR\R\R,/#)r
<00>uicr N)rN<00>float)r s"rrrls<00><00><14><14>3<EFBFBD><14>5<EFBFBD>4<EFBFBD><<3C>rc <04><><00>\RRVRRRR/R7pVPR/4PR4pV'd \V4#R # \dR #i;i)
u<EFBFBD>
Get last traded price for a UIC.
NOTE: SIM 24h tokens have no market data access — returns None.
Use yfinance for prices instead (see signals.py).
z/trade/v1/infoprices<65>Uic<69> AssetTyperS<00> FieldGroups<70>QuoterT<00>LastN)r<r6r^r)r]rF<00>lasts& r<00> get_pricerflsh<00><00> <14><13>*<2A> <11>3<EFBFBD> <17><17> <19>7<EFBFBD>4
<EFBFBD> <0B><04>
<14>x<EFBFBD>x<EFBFBD><07><12>$<24>(<28>(<28><16>0<><04>"<22>u<EFBFBD>T<EFBFBD>{<7B>,<2C><04>,<2C><> <14><14><13><14>s<00>AA <00> A <00> A<03>A<03> price_dkk<6B> signal_score<72> analyst_rec<65>notec<00><><00>V^8<>dQhR\R\R\R\R,R\R,R\R,R\R,R \/#)
r
rM<00>shares<65> directionrgNrhrirjr )r rNr^<00>dict)r s"rrr<00>sh<00><00>8<10>8<10> <0F>8<10> <0F>8<10><13>8<10>
<15>t<EFBFBD>|<7C> 8<10> <18>$<24>,<2C> 8<10><15>t<EFBFBD><1A>8<10> <0E><04>*<2A>8<10>
<EFBFBD>8rc<04><><00>\4wrx\V4p V f\RV 24hRV RRRVRVRR R
R R /R VRR/p
\RV
4p V P R4;'g*V P R/.4^,P R4p V 'dRMRp \ TVP 4TTV 'd \V 4MRV VVVR7 V #)a<>
Place a market order on Saxo SIM.
Args:
ticker: Our C25 ticker (e.g. "NOVO-B")
shares: Number of shares
direction: "Buy" or "Sell"
price_dkk: Estimated fill price in DKK (for fee calc + logging)
signal_score: NLP signal score that triggered this order
analyst_rec: Analyst recommendation label
note: Free-text note
Returns:
Saxo order response dict
NzUnknown ticker: r`rarS<00>Amount<6E>BuySell<6C> OrderType<70>Market<65> OrderDuration<6F> DurationType<70>DayOrderrD<00> ManualOrderTz/trade/v2/orders<72>OrderId<49>Orders<72>filled<65>rejected) rMrmrlrg<00> saxo_order_id<69>statusrhrirj)rIr[<00>
ValueErrorr@r6<00> log_order<65>lowerr )rMrlrmrgrhrirj<00>_<>acct_keyr]r?<00>respr|r}s&&&$$$$ r<00> place_orderr<72><00>s<><00><00>2#<23>$<24>K<EFBFBD>A<EFBFBD>
<12>6<EFBFBD>
<1A>C<EFBFBD>
<EFBFBD>{<7B><18>+<2B>F<EFBFBD>8<EFBFBD>4<>5<>5<> <0E>s<EFBFBD><13>W<EFBFBD><10>&<26><11>9<EFBFBD><13>X<EFBFBD><17>.<2E>*<2A>5<><14>h<EFBFBD><15>t<EFBFBD> <06>D<EFBFBD> <11>#<23>T<EFBFBD> *<2A>D<EFBFBD><19>H<EFBFBD>H<EFBFBD>Y<EFBFBD>'<27>U<>U<>4<EFBFBD>8<EFBFBD>8<EFBFBD>H<EFBFBD>r<EFBFBD>d<EFBFBD>+C<>A<EFBFBD>+F<>+J<>+J<>9<EFBFBD>+U<>M<EFBFBD>&<26>X<EFBFBD>J<EFBFBD>F<EFBFBD> <0A><15><1B>/<2F>/<2F>#<23><15><1B>,9<>c<EFBFBD>-<2D>(<28>t<EFBFBD><15>!<21><1F> <11>
<06> <10>Krc<00><><00>V^8<>dQhR\R\R\R\R,R\R,R\R\R,R \R,R
\R,R R/
#) r
rMrmrlrgNr|r}rhrirjr )r r^)r s"rrr<00>s<><00><00><0F><0F> <0F><0F><12><0F> <12><0F><15>t<EFBFBD>|<7C> <0F>
<17><14>:<3A> <0F> <10> <0F><18>$<24>,<2C><0F><15>t<EFBFBD><1A><0F> <0E><04>*<2A><0F>
<EFBFBD>rc <04>`<00>V'd W#,MRp V 'd\\RV R,4^4MRp
\P!\P
4P 4p \4p V PRWW#W<>WEWgW<67>3 4V P4V P4R#)zW
Write a trade record to saxo_orders table.
Fee model: max(25 DKK, total_dkk * 0.001)
Ng9@g<><67><EFBFBD><EFBFBD>MbP?z<>INSERT INTO saxo_orders
(ticker, direction, shares, price_dkk, total_dkk, fee_dkk,
saxo_order_id, status, signal_score, analyst_rec, placed_at, note)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?)) <0B>round<6E>maxr<00>nowr<00>utc<74> isoformatr<00>execute<74>commit<69>close) rMrmrlrgr|r}rhrirj<00> total_dkk<6B>fee_dkk<6B>now_ts<74>dbs &&&&&&&&& rrr<00>s<><00><00> )2<><16>#<23>t<EFBFBD>I<EFBFBD>:C<><05>c<EFBFBD>$<24> <09>E<EFBFBD> 1<>2<>A<EFBFBD>6<><14>G<EFBFBD><18> <0C> <0C>X<EFBFBD>\<5C>\<5C>*<2A>4<>4<>6<>F<EFBFBD> <11><1A>B<EFBFBD><06>J<EFBFBD>J<EFBFBD> /<2F>
<10>F<EFBFBD>y<EFBFBD> <16> <0C>6<EFBFBD> I<01> <06><07>I<EFBFBD>I<EFBFBD>K<EFBFBD><06>H<EFBFBD>H<EFBFBD>Jrc<00>:<00>V^8<>dQhR\\,/#r )<02>listrn)r s"rrr<00>s<00><00> <20> <20>t<EFBFBD>D<EFBFBD>z<EFBFBD> rc<04>D<00>\RRR/R7pVPR.4#)z$Return open positions from Saxo SIM.z/port/v1/positions/merbzPositionBase,PositionViewrTrB)r<r6)rFs r<00> get_positionsr<73><00>s&<00><00> <0F>'<27><1D>@[<5B>0\<5C> ]<5D>D<EFBFBD> <0F>8<EFBFBD>8<EFBFBD>F<EFBFBD>B<EFBFBD> <1F>rc <04><00>\4pV'g\R4R#\RRR RRR RR R
RR R
RR R
2
4\R4VF<>pVPR /4pVPR/4pVPRR4pVPR^4pVPR^4pVPR^4pVPR^4pV^8<>dRVR 2MVR p \VR RVR RVR RVR RV R
2 4K<> R#)zPretty-print open positions.u!Ingen åbne positioner i Saxo SIMN<4D>
<EFBFBD>Tickerz<12<31> <20>Antalz>6u Åbn kursz>10zAkt kurszP/L<> PositionBase<73> PositionView<65>Symbol<6F>?rp<00> OpenPrice<63> CurrentPrice<63>ProfitLossOnTrade<64>+z.0fz>10.2fz4----------------------------------------------------)r<><00>printr6)
<EFBFBD> positions<6E>p<>base<73>viewrW<00>amount<6E>
open_price<EFBFBD>current<6E>pl<70>pl_strs
r<00>print_positionsr<73><00>s<00><00><1D><0F>I<EFBFBD> <14> <0A>1<>2<><0E> <09>B<EFBFBD>x<EFBFBD><03>n<EFBFBD>A<EFBFBD>g<EFBFBD>b<EFBFBD>\<5C><11>;<3B>s<EFBFBD>*;<3B>1<EFBFBD>Z<EFBFBD><03><L<>A<EFBFBD>e<EFBFBD>TW<54>[<5B>
Y<EFBFBD>Z<> <09>(<28>O<EFBFBD> <16><01><10>u<EFBFBD>u<EFBFBD>^<5E>R<EFBFBD>(<28><04><10>u<EFBFBD>u<EFBFBD>^<5E>R<EFBFBD>(<28><04><15><18><18>(<28>C<EFBFBD>(<28><06><15><18><18>(<28>A<EFBFBD>&<26><06><19>X<EFBFBD>X<EFBFBD>k<EFBFBD>1<EFBFBD>-<2D>
<EFBFBD><16>(<28>(<28>><3E>1<EFBFBD>-<2D><07> <11>X<EFBFBD>X<EFBFBD>)<29>1<EFBFBD> -<2D><02>!#<23>q<EFBFBD><17>1<EFBFBD>R<EFBFBD><03>H<EFBFBD><1C><12>C<EFBFBD><08><06> <0A><16><03> <0C>A<EFBFBD>f<EFBFBD>R<EFBFBD>[<5B><01>*<2A>V<EFBFBD>)<<3C>A<EFBFBD>g<EFBFBD>f<EFBFBD>=M<>Q<EFBFBD>v<EFBFBD>VY<56>l<EFBFBD>[<5B>\<5C>rc<04><00>\4pVPR^4pVPR^4pVPR^4pVPRR4p\RVR RV 24\R VR RV 24\R
VR RV 24R #) zPretty-print account balances.<2E> CashBalance<63>
TotalValue<EFBFBD>MarginAvailableForTrading<6E>Currency<63>EURz
Kontant saldo: z>12,.0fr<EFBFBD>u Total portefølje: z Fri margin: N)rKr6r<>)<05>b<>cash<73>equity<74>margin<69>currencys r<00>print_balancesr<73><00>s<><00><00><14><0E>A<EFBFBD> <0C>5<EFBFBD>5<EFBFBD><1D><01> "<22>D<EFBFBD> <0E>U<EFBFBD>U<EFBFBD><<3C><11> #<23>F<EFBFBD> <0E>U<EFBFBD>U<EFBFBD>.<2E><01> 2<>F<EFBFBD><10>u<EFBFBD>u<EFBFBD>Z<EFBFBD><15>'<27>H<EFBFBD> <09> #<23>D<EFBFBD><17>><3E><11>8<EFBFBD>*<2A>
=<3D>><3E> <09> "<22>6<EFBFBD>'<27>"2<>!<21>H<EFBFBD>:<3A>
><3E>?<3F> <09> !<21>&<26><17>!1<><11>8<EFBFBD>*<2A>
=<3D>>rc<00><><00>\4\ \P 4^8<>d\P ^,MRpVR8XdJ\R4\4wr#\RV 24\RV 24\4\4R#VR8Xd<>\ \P 4^8d"\R4\P!^4\P ^,P4p\\P ^,4p\R V R
V R 24\WER 4p\R \P!V^R7 24R#VR8Xd<>\ \P 4^8d"\R4\P!^4\P ^,P4p\\P ^,4p\RV R
V R 24\WER4p\R \P!V^R7 24R#VR8Xd \4R#VR8Xd \4R#VR8Xd{\ \P 4^8<>d&\P ^,P4MRp\V4pV'd \!V4MRp\V RV RV 24R#\RV 24\R4\P!^4R# \d;p\RT 24\R4\P!^4Rp?EL=Rp?ii;i)zFEJL: uKør: python saxo_auth.py loginNr}z
=== SAXO SIM KONTO ===z ClientKey: z AccountKey: <20>buyz%Brug: saxo_broker.py buy TICKER ANTALuPlacerer KØB u × u på Saxo SIM ...<2E>BuyuOrdre bekræftet: )<01>indent<6E>sellz&Brug: saxo_broker.py sell TICKER ANTALuPlacerer SÆLG <20>Sellr<6C><00>balancesr]rz: UIC=z, pris=zUkendt kommando: zUKommandoer: status | buy TICKER N | sell TICKER N | positions | balances | uic TICKER)rrr<><00>sys<79>exit<69>len<65>argvrIr<>r<><00>upperrNr<>r9<00>dumpsr[rf) <09>e<>cmd<6D>
client_keyr<EFBFBD>rMrl<00>resultr]<00>prices r<00>mainr<6E>sn<00><00><14><12> <0C> <1D>S<EFBFBD>X<EFBFBD>X<EFBFBD><1D><11>*<2A>#<23>(<28>(<28>1<EFBFBD>+<2B><08>C<EFBFBD>
<EFBFBD>h<EFBFBD><EFBFBD> <0A>(<28>)<29>/<2F>1<><1C>
<EFBFBD> <0A> <0A>j<EFBFBD>\<5C>*<2A>+<2B> <0A><0E>x<EFBFBD>j<EFBFBD>)<29>*<2A><16><18><17><19> <0C><05><1C> <0E>s<EFBFBD>x<EFBFBD>x<EFBFBD>=<3D>1<EFBFBD> <1C> <11>9<> :<3A> <0F>H<EFBFBD>H<EFBFBD>Q<EFBFBD>K<EFBFBD><14><18><18>!<21><1B>"<22>"<22>$<24><06><14>S<EFBFBD>X<EFBFBD>X<EFBFBD>a<EFBFBD>[<5B>!<21><06> <0A><0E>v<EFBFBD>h<EFBFBD>d<EFBFBD>6<EFBFBD>(<28>2C<32>D<>E<><1C>V<EFBFBD>U<EFBFBD>3<><06> <0A>"<22>4<EFBFBD>:<3A>:<3A>f<EFBFBD>Q<EFBFBD>#?<3F>"@<40>A<>B<> <0C><06><1D> <0E>s<EFBFBD>x<EFBFBD>x<EFBFBD>=<3D>1<EFBFBD> <1C> <11>:<3A> ;<3B> <0F>H<EFBFBD>H<EFBFBD>Q<EFBFBD>K<EFBFBD><14><18><18>!<21><1B>"<22>"<22>$<24><06><14>S<EFBFBD>X<EFBFBD>X<EFBFBD>a<EFBFBD>[<5B>!<21><06> <0A><0F><06>x<EFBFBD>t<EFBFBD>F<EFBFBD>8<EFBFBD>3D<33>E<>F<><1C>V<EFBFBD>V<EFBFBD>4<><06> <0A>"<22>4<EFBFBD>:<3A>:<3A>f<EFBFBD>Q<EFBFBD>#?<3F>"@<40>A<>B<> <0C> <0B> <1B><17><19> <0C>
<EFBFBD> <1A><16><18> <0C><05><1C>(+<2B>C<EFBFBD>H<EFBFBD>H<EFBFBD> <0A><01>(9<><13><18><18>!<21><1B>"<22>"<22>$<24>x<EFBFBD><06><16>v<EFBFBD><1E><03>"%<25> <09>#<23><0E>4<EFBFBD><05> <0A><16><08><06>s<EFBFBD>e<EFBFBD>7<EFBFBD>5<EFBFBD>'<27>2<>3<> <0E>!<21>#<23><15>'<27>(<28> <0A>e<>f<> <0B><08><08><11> <0B><>k <15><14> <0A><06>q<EFBFBD>c<EFBFBD>l<EFBFBD><1B> <0A>/<2F>0<> <0B><08><08><11> <0B> <0B><><14>s<00>
L <00> M<03>/M <03> M<03>__main__)zNovo Nordisk B<>CSE)z Danske Bankr<6B>)rr<>)<02>Demantr<74>)<02>Orstedr<64>)<02>Rockwoolr<6C>)<02>Vestasr<73>)<02> Coloplastr<74>)<02>Genmabr<62>)zMaersk Br<42>)<02> Novozymesr<73>)r#r<>)z GN Store Nordr<64>)zBavarian Nordicr<63>)<02>Trygr<67>)<02>Pandorar<61>)<02> Carlsbergr<67>)z Chr. Hansenr<6E>)<02>FLSmidthr<68>)z Royal Unibrewr<77>)<02>Sydbankr<6B>)N)r<>)N<>pendingNNN) <20>__doc__rr<>r9<00>timer5<00>pathlibrrr<00>dotenvrr<>rrr7rrVr/r<r@rIrKr[rfr<>rr<>r<>r<>r<><00>__name__r.rr<00><module>r<>s<><00><01><04> 
<EFBFBD>
<EFBFBD> <0B> <0B><0F><18>'<27><1E><17> <0B> <0A> <09>y<EFBFBD>y<EFBFBD><1B>H<>I<><04>+<2B><02> <0C>2<><02> <0C>3<><02>
<EFBFBD>3<><02> <0A>3<> <02>
 <0A>3<> <02>  <0A>3<> <02>
<EFBFBD>3<><02> <0C>3<><02> <0B>3<><02><0F>3<><02> <0A>3<><02>
<EFBFBD>3<><02> <09>3<><02> <0C>3<><02> <0B>3<><02>  <0A>3<>!<02>" <0A>3<>#<02>$
<EFBFBD>3<> <09>3<> <0B>3<>
<EFBFBD>3<>+<02> <0C>2[<01><14> <14>1<>(<28><10>"<14>(8<10>
#<23> 8<10> "&<26> 8<10>#<23>8<10><1C>8<10>8<10>v<0F>F <20> ]<01>( ?<3F>8<14>v <0C>z<EFBFBD><19><08>F<EFBFBD>r