commit 9ed735c133035e7ae580fb26e24f384debf0eb1a
Author: zipfriis <44124727+zipfriis@users.noreply.github.com>
Date: Mon Mar 16 13:08:54 2026 +0100
first
diff --git a/Trades.csv b/Trades.csv
new file mode 100644
index 0000000..b8f9942
--- /dev/null
+++ b/Trades.csv
@@ -0,0 +1,11 @@
+Trades,Header,DataDiscriminator,Asset Category,Currency,Symbol,Date/Time,Quantity,T. Price,C. Price,Proceeds,Comm/Fee,Basis,Realized P/L,MTM P/L,Code
+Trades,Data,Order,Stocks,DKK,NOVOBc,"2026-02-24, 03:05:36",8,241.7,243.65,-1933.6,-10,1943.6,0,15.6,O
+Trades,Data,Order,Stocks,DKK,NOVOBc,"2026-02-25, 07:10:24",3,239.5,238.4,-718.5,-10,728.5,0,-3.3,O
+Trades,SubTotal,,Stocks,DKK,NOVOBc,,11,,,-2652.1,-20,2672.1,0,12.3,
+Trades,Total,,Stocks,DKK,,,,,,-2652.1,-20,2672.1,0,12.3,
+Trades,Data,Order,Stocks,USD,CSIQ,"2026-01-20, 14:33:05",8,20.48,20.51,-163.84,-0.37585725,164.21585725,0,0.24,O
+Trades,SubTotal,,Stocks,USD,CSIQ,,8,,,-163.84,-0.37585725,164.21585725,0,0.24,
+Trades,Data,Order,Stocks,USD,PYPL,"2026-01-20, 14:31:34",-3,55.175,55.08,165.525,-0.35144225,-187.906957,-22.733399,0.285,C
+Trades,SubTotal,,Stocks,USD,PYPL,,-3,,,165.525,-0.35144225,-187.906957,-22.733399,0.285,
+Trades,Data,Order,Equity and Index Options,USD,RGTI 15JAN27 5.5 P,"2026-02-24, 09:34:38",1,0.53,0.5271,-53,-1.05125,54.05125,0,-0.29,O
+Trades,SubTotal,,Equity and Index Options,USD,RGTI 15JAN27 5.5 P,,1,,,-53,-1.05125,54.05125,0,-0.29,
diff --git a/U16113532_20260101_20260227.csv b/U16113532_20260101_20260227.csv
new file mode 100644
index 0000000..e38c9e6
--- /dev/null
+++ b/U16113532_20260101_20260227.csv
@@ -0,0 +1,218 @@
+Statement,Header,Field Name,Field Value
+Statement,Data,BrokerName,Interactive Brokers Ireland Limited
+Statement,Data,BrokerAddress,
+Statement,Data,Title,Activity Statement
+Statement,Data,Period,"January 1, 2026 - February 27, 2026"
+Statement,Data,WhenGenerated,"2026-03-02, 05:30:59 EST"
+Account Information,Header,Field Name,Field Value
+Account Information,Data,Name,sebastian friis
+Account Information,Data,Account,U16113532
+Account Information,Data,Account Type,Individual
+Account Information,Data,Customer Type,Individual
+Account Information,Data,Account Capabilities,Cash
+Account Information,Data,Base Currency,DKK
+Net Asset Value,Header,Asset Class,Prior Total,Current Long,Current Short,Current Total,Change
+Net Asset Value,Data,Cash ,370.525206138,94.622953248,0,94.622953248,-275.90225289
+Net Asset Value,Data,Stock,32606.96526,33734.356808,0,33734.356808,1127.391548
+Net Asset Value,Data,Options,0,316.913772,0,316.913772,316.913772
+Net Asset Value,Data,Total,32977.490466138,34145.893533248,0,34145.893533248,1168.40306711
+Net Asset Value,Header,Time Weighted Rate of Return
+Net Asset Value,Data,-4.866005514%
+Change in NAV,Header,Field Name,Field Value
+Change in NAV,Data,Starting Value,32977.490466138
+Change in NAV,Data,Mark-to-Market,-1533.453864
+Change in NAV,Data,Deposits & Withdrawals,3000
+Change in NAV,Data,Other Fees,-213.47
+Change in NAV,Data,Commissions,-31.30556903
+Change in NAV,Data,Sales Tax,-53.3675
+Change in NAV,Data,Ending Value,34145.893533248
+Mark-to-Market Performance Summary,Header,Asset Category,Symbol,Prior Quantity,Current Quantity,Prior Price,Current Price,Mark-to-Market P/L Position,Mark-to-Market P/L Transaction,Mark-to-Market P/L Commissions,Mark-to-Market P/L Other,Mark-to-Market P/L Total,Code
+Mark-to-Market Performance Summary,Data,Stocks,CSIQ,0,8,--,17.7100,-139.693072,1.529136,-2.39473688,0,-140.55867288,
+Mark-to-Market Performance Summary,Data,Stocks,DFDSc,35,35,95.6500,103.8000,285.25,0,0,0,285.25,
+Mark-to-Market Performance Summary,Data,Stocks,MAERAc,1,1,"14,640.0000","15,500.0000",860,0,0,0,860,
+Mark-to-Market Performance Summary,Data,Stocks,NOVOBc,34,45,325.2500,237.9000,-3017.4,12.3,-20,0,-3025.1,
+Mark-to-Market Performance Summary,Data,Stocks,ORSTED,20,20,122.3500,150.0000,553,0,0,0,553,
+Mark-to-Market Performance Summary,Data,Stocks,PYPL,3,0,58.3800,--,-63.407469,1.815849,-2.23917915,0,-63.83079915,
+Mark-to-Market Performance Summary,Data,Total,,,,,,-1522.250541,15.644985,-24.63391603,0,-1531.23947203,
+Mark-to-Market Performance Summary,Data,Equity and Index Options,RGTI 15JAN27 5.5 P,0,1,--,0.5012,-16.410319,-1.840456,-6.671653,0,-24.922428,
+Mark-to-Market Performance Summary,Data,Total,,,,,,-16.410319,-1.840456,-6.671653,0,-24.922428,
+Mark-to-Market Performance Summary,Data,Forex,DKK,370.525206138,94.622953248,1.0000,1.0000,0,-0.035793,0,0,-0.035793,
+Mark-to-Market Performance Summary,Data,Forex,USD,0,0,6.3590,6.3231,-8.56174,0,0,0,-8.56174,
+Mark-to-Market Performance Summary,Data,Total,,,,,,-8.56174,-0.035793,0,0,-8.597533,
+Mark-to-Market Performance Summary,Data,Total (All Assets),,,,,,-1547.2226,13.768736,-31.30556903,0,-1564.75943303,
+Mark-to-Market Performance Summary,Data,Other Fees,,,,,,,,,,-213.47,
+Total P/L for Statement Period,,,,,,,,,,,,-1778.22943303,
+Realized & Unrealized Performance Summary,Header,Asset Category,Symbol,Cost Adj.,Realized S/T Profit,Realized S/T Loss,Realized L/T Profit,Realized L/T Loss,Realized Total,Unrealized S/T Profit,Unrealized S/T Loss,Unrealized L/T Profit,Unrealized L/T Loss,Unrealized Total,Total,Code
+Realized & Unrealized Performance Summary,Data,Stocks,CSIQ,0,0,0,0,0,0,0,-142.496477397,0,0,-142.496477397,-142.496477397,
+Realized & Unrealized Performance Summary,Data,Stocks,DFDS,0,0,0,0,0,0,560.05361,-70.6,0,0,489.45361,489.45361,
+Realized & Unrealized Performance Summary,Data,Stocks,MAERSK A,0,0,0,0,0,0,3085.536223,0,0,0,3085.536223,3085.536223,
+Realized & Unrealized Performance Summary,Data,Stocks,NOVO B,0,0,0,0,0,0,0,-2844.898855,0,0,-2844.898855,-2844.898855,
+Realized & Unrealized Performance Summary,Data,Stocks,ORSTED,0,0,0,0,0,0,424,0,0,0,424,424,
+Realized & Unrealized Performance Summary,Data,Stocks,PYPL,0,0,-144.84357998,0,0,-144.84357998,0,0,0,0,0,-144.84357998,
+Realized & Unrealized Performance Summary,Data,Total,,0,0,-144.84357998,0,0,-144.84357998,4069.589833,-3057.995332397,0,0,1011.594500603,866.750920623,
+Realized & Unrealized Performance Summary,Data,Equity and Index Options,RGTI 15JAN27 5.5 P,0,0,0,0,0,0,0,-24.857686875,0,0,-24.857686875,-24.857686875,
+Realized & Unrealized Performance Summary,Data,Total,,0,0,0,0,0,0,0,-24.857686875,0,0,-24.857686875,-24.857686875,
+Realized & Unrealized Performance Summary,Data,Forex,USD,0,0,-0.035793,0,0,-0.035793,0,0,0,0,0,-0.035793,
+Realized & Unrealized Performance Summary,Data,Total,,0,0,-0.035793,0,0,-0.035793,0,0,0,0,0,-0.035793,
+Realized & Unrealized Performance Summary,Data,Total (All Assets),,0,0,-144.87937298,0,0,-144.87937298,4069.589833,-3082.853019272,0,0,986.736813728,841.857440748,
+Cash Report,Header,Currency Summary,Currency,Total,Securities,Futures,
+Cash Report,Data,Starting Cash,Base Currency Summary,370.525206138,370.525206138,0,
+Cash Report,Data,Commissions,Base Currency Summary,-31.30556903,-31.30556903,0,
+Cash Report,Data,Deposits,Base Currency Summary,3000,3000,0,
+Cash Report,Data,Trades (Sales),Base Currency Summary,1428.53983211,1428.53983211,0,
+Cash Report,Data,Trades (Purchase),Base Currency Summary,-4406.29901597,-4406.29901597,0,
+Cash Report,Data,Other Fees,Base Currency Summary,-213.47,-213.47,0,
+Cash Report,Data,Sales Tax,DKK,-53.3675,-53.3675,0,
+Cash Report,Data,Ending Cash,Base Currency Summary,94.622953248,94.622953248,0,
+Cash Report,Data,Ending Settled Cash,Base Currency Summary,94.622953248,94.622953248,0,
+Cash Report,Data,Starting Cash,DKK,370.525206138,370.525206138,0,
+Cash Report,Data,Commissions,DKK,-20,-20,0,
+Cash Report,Data,Deposits,DKK,3000,3000,0,
+Cash Report,Data,Trades (Sales),DKK,18.49044711,18.49044711,0,
+Cash Report,Data,Trades (Purchase),DKK,-3007.5552,-3007.5552,0,
+Cash Report,Data,Other Fees,DKK,-213.47,-213.47,0,
+Cash Report,Data,Sales Tax,DKK,-53.3675,-53.3675,0,
+Cash Report,Data,Ending Cash,DKK,94.622953248,94.622953248,0,
+Cash Report,Data,Ending Settled Cash,DKK,94.622953248,94.622953248,0,
+Cash Report,Data,Starting Cash,USD,0,0,0,
+Cash Report,Data,Commissions,USD,-1.7785495,-1.7785495,0,
+Cash Report,Data,Trades (Sales),USD,221.525,221.525,0,
+Cash Report,Data,Trades (Purchase),USD,-219.7464505,-219.7464505,0,
+Cash Report,Data,Ending Cash,USD,0,0,0,
+Cash Report,Data,Ending Settled Cash,USD,0,0,0,
+Open Positions,Header,DataDiscriminator,Asset Category,Currency,Symbol,Quantity,Mult,Cost Price,Cost Basis,Close Price,Value,Unrealized P/L,Code
+Open Positions,Data,Summary,Stocks,DKK,DFDSc,35,1,89.815611143,3143.54639,103.8,3633,489.45361,
+Open Positions,Data,Summary,Stocks,DKK,MAERAc,1,1,12414.463777,12414.463777,15500,15500,3085.536223,
+Open Positions,Data,Summary,Stocks,DKK,NOVOBc,45,1,301.119974556,13550.398855,237.9,10705.5,-2844.898855,
+Open Positions,Data,Summary,Stocks,DKK,ORSTED,20,1,128.8,2576,150,3000,424,
+Open Positions,Total,,Stocks,DKK,,,,,31684.409022,,32838.5,1154.090978,
+Open Positions,Data,Summary,Stocks,USD,CSIQ,8,1,20.526982125,164.215857,17.71,141.68,-22.535857,
+Open Positions,Total,,Stocks,USD,,,,,164.215857,,141.68,-22.535857,
+Open Positions,Total,,Stocks,DKK,,,,,1038.353285397,,895.856808,-142.496477397,
+Open Positions,Total,,Stocks,DKK,,,,,32722.762307397,,33734.356808,1011.594500603,
+Open Positions,Header,DataDiscriminator,Asset Category,Currency,Symbol,Quantity,Mult,Cost Price,Cost Basis,Close Price,Value,Unrealized P/L,Code
+Open Positions,Data,Summary,Equity and Index Options,USD,RGTI 15JAN27 5.5 P,1,100,0.5405125,54.05125,0.5012,50.12,-3.93125,
+Open Positions,Total,,Equity and Index Options,USD,,,,,54.05125,,50.12,-3.93125,
+Open Positions,Total,,Equity and Index Options,DKK,,,,,341.771458875,,316.913772,-24.857686875,
+Deposits & Withdrawals,Header,Currency,Settle Date,Description,Amount
+Deposits & Withdrawals,Data,DKK,2026-02-23,Electronic Fund Transfer,3000
+Deposits & Withdrawals,Data,Total,,,3000
+Fees,Header,Subtitle,Currency,Date,Description,Amount
+Fees,Data,Other Fees,DKK,2026-01-05,s*******42:US Equity and Options Add-On Streaming Bundle Non-Professional for Jan 2026,-28.62
+Fees,Data,Other Fees,DKK,2026-01-05,s*******42:Nordic Equity Non-Professional Level I for Jan 2026,-14.94
+Fees,Data,Other Fees,DKK,2026-01-05,s*******42:US Securities Snapshot and Futures Value Bundle Non-Professional for Jan 2026,-63.59
+Fees,Data,Other Fees,DKK,2026-02-04,s*******42:US Equity and Options Add-On Streaming Bundle Non-Professional for Feb 2026,-28.36
+Fees,Data,Other Fees,DKK,2026-02-04,s*******42:Nordic Equity Non-Professional Level I for Feb 2026,-14.94
+Fees,Data,Other Fees,DKK,2026-02-04,s*******42:US Securities Snapshot and Futures Value Bundle Non-Professional for Feb 2026,-63.02
+Fees,Data,Total,,,,-213.47
+Fees,Notes,"Market data is provided by Global Financial Information Services (GmbH). Your local broker collects amounts owed for fees and tax for such data on behalf of Global Financial Information Services (GmbH). Note, you are responsible for any applicable taxes relating to the provision of these services."
+Financial Instrument Information,Header,Asset Category,Symbol,Description,Conid,Security ID,Underlying,Listing Exch,Multiplier,Type,Code
+Financial Instrument Information,Data,Stocks,CSIQ,CANADIAN SOLAR INC,41498671,CA1366351098,CSIQ,NASDAQ,1,COMMON,
+Financial Instrument Information,Data,Stocks,DFDSc,DFDS A/S,206867091,DK0060655629,DFDS,CPH,1,COMMON,
+Financial Instrument Information,Data,Stocks,MAERAc,AP MOLLER-MAERSK A/S-A,25846066,DK0010244425,MAERSK.A,CPH,1,COMMON,
+Financial Instrument Information,Data,Stocks,NOVOBc,NOVO NORDISK A/S-B,652806383,DK0062498333,NOVO.B,CPH,1,COMMON,
+Financial Instrument Information,Data,Stocks,ORSTED,ORSTED A/S,242060078,DK0060094928,ORSTED,CPH,1,COMMON,
+Financial Instrument Information,Data,Stocks,PYPL,PAYPAL HOLDINGS INC,199169591,US70450Y1038,PYPL,NASDAQ,1,COMMON,
+Financial Instrument Information,Header,Asset Category,Symbol,Description,Conid,Underlying,Listing Exch,Multiplier,Expiry,Delivery Month,Type,Strike,Code
+Financial Instrument Information,Data,Equity and Index Options,RGTI 270115P00005500,RGTI 15JAN27 5.5 P,746801714,RGTI,CBOE,100,2027-01-15,2027-01,P,5.5,
+Codes,Header,Code,Meaning,Code (Cont.),Meaning (Cont.)
+Codes,Data,A,Assignment
+Codes,Data,ADR,ADR Fee Accrual
+Codes,Data,AEx,Automatic exercise for dividend-related recommendation.
+Codes,Data,AFx,AutoFX conversion resulting from trading
+Codes,Data,Adj,Adjustment
+Codes,Data,Al,Allocation
+Codes,Data,Aw,Away Trade
+Codes,Data,B,Automatic Buy-in
+Codes,Data,Bo,Direct Borrow
+Codes,Data,C,Closing Trade
+Codes,Data,CD,Cash Delivery
+Codes,Data,CP,Complex Position
+Codes,Data,Ca,Cancelled
+Codes,Data,Co,Corrected Trade
+Codes,Data,Cx,Part or all of this transaction was a Crossing executed as dual agent by IB for two IB customers
+Codes,Data,DT,Discounted Trade
+Codes,Data,De,Delivery or Conversion Action
+Codes,Data,ETF,ETF Creation/Redemption
+Codes,Data,Ep,Resulted from an Expired Position
+Codes,Data,Ex,Exercise
+Codes,Data,FP,The fractional portion of this trade was executed against IB or an affiliate.
+Codes,Data,FPA,The fractional portion of this trade was executed against IB or an affiliate. IB acted as agent for the whole share portion of this trade.
+Codes,Data,G,Trade in Guaranteed Account Segment
+Codes,Data,GEA,Exercise or Assignment resulting from offsetting positions
+Codes,Data,HC,Highest Cost tax basis election
+Codes,Data,HFI,Investment Transferred to Hedge Fund
+Codes,Data,HFR,Redemption from Hedge Fund
+Codes,Data,I,Internal Transfer
+Codes,Data,IA,The transaction was executed against IB or an affiliate
+Codes,Data,IM,A portion of the order was executed against IB or an affiliate; IB acted as agent on a portion.
+Codes,Data,INV,Investment Transfer from Investor
+Codes,Data,IPO,This transaction was executed as part of an IPO in which IB was a member of the selling group and is classified as a Principal trade.
+Codes,Data,L,Ordered by IB (Margin Violation)
+Codes,Data,LD,Adjusted by Loss Disallowed from Wash Sale
+Codes,Data,LF,Liquidation of fractional position by IB
+Codes,Data,LI,"Last In, First Out (LIFO) tax basis election"
+Codes,Data,LT,Long Term P/L
+Codes,Data,Lo,Direct Loan
+Codes,Data,M,Entered manually by IB
+Codes,Data,MEx,Manual exercise for dividend-related recommendation.
+Codes,Data,ML,Maximize Losses tax basis election
+Codes,Data,MLG,Maximize Long Term Gain tax basis election
+Codes,Data,MLL,Maximize Long Term Loss tax basis election
+Codes,Data,MSG,Maximize Short Term Gain tax basis election
+Codes,Data,MSL,Maximize Short Term Loss tax basis election
+Codes,Data,O,Opening Trade
+Codes,Data,Off,Yes and No contracts offset to $1.00 cash settlement
+Codes,Data,P,Partial Execution
+Codes,Data,PE,Perpetual Investment
+Codes,Data,PI,Price Improvement
+Codes,Data,PTA,Post Trade Allocation
+Codes,Data,Po,Interest or Dividend Accrual Posting
+Codes,Data,Pr,Part or all of this transaction was executed by the Exchange as a Crossing by IB against an IB affiliate and is therefore classified as a Principal and not an agency trade
+Codes,Data,R,Dividend Reinvestment
+Codes,Data,RED,Redemption to Investor
+Codes,Data,RI,Recurring Investment
+Codes,Data,RP,"IB acted as agent for the fractional share portion of this trade, which was executed by an IB affiliate as riskless principal."
+Codes,Data,RPA,IB acted as agent for both the fractional share portion and the whole share portion of this trade; the fractional share portion was executed by an IB Affiliate as riskless principal.
+Codes,Data,Rb,Rebill
+Codes,Data,Re,Interest or Dividend Accrual Reversal
+Codes,Data,Ri,Reimbursement
+Codes,Data,S0,Contract settled to zero value
+Codes,Data,S1,Contract settled to $1.00
+Codes,Data,SF,Trade is subject to IBKR Lite Surcharge Fee if volume of such trades exceeds 10% of the total monthly Lite trade volume
+Codes,Data,SI,This order was solicited by Interactive Brokers
+Codes,Data,SL,Specific Lot tax basis election
+Codes,Data,SO,This order was marked as solicited by your Introducing Broker
+Codes,Data,SS,Customer designated this trade for shortened settlement and so is subject to execution at prices above the prevailing market
+Codes,Data,ST,Short Term P/L
+Codes,Data,T,Transfer
+Codes,Data,Un,Unvested shares from stock grant
+Codes,Data,XCH,Mutual Fund Exchange Transaction
+Notes/Legal Notes,Header,Type,Note
+Notes/Legal Notes,Data,Notes,"Stock exchange transactions generally settle on the trade date plus one business day (T+1). Options, futures and US open-end mutual fund transactions also settle on trade date plus one business day. Some exchanges and other transaction types may have longer or shorter settlement periods. Ending settled cash reflects the cash that has actually settled."
+Notes/Legal Notes,Data,Notes,Initial and maintenance margin requirements are available within the Account Window of the Trader Workstation.
+Notes/Legal Notes,Data,Notes,"Quantities preceded by a ""-"" sign indicate sell transactions. Other transactions are purchases. "
+Notes/Legal Notes,Data,Notes,"For shares traded on US markets, Interactive Brokers Ireland Limited (IBIE) acts as agent in executing the fractional portion of your order. In certain circumstances, IBIE routes that portion to an affiliate, which may execute it either as principal or riskless principal. If an IB affiliate executes as i) principal, the order will be executed at the price displayed for the opposite side of the NBBO from your order (the offer if you are buying and the bid if you are selling) at the time of execution, ii) riskless principal, the affiliate will execute that portion of your order at the price it receives for the execution of the whole share. The way in which the fractional portion of the order is executed is indicated by the codes associated with the trade. For shares traded on European Markets, IBIE will generally act as counterparty for any fractional portion of your order for shares, which it will execute as principal, for a total consideration which is equal to (or better than), the total consideration for the execution of a full share available at the European trading venues and SIs to which IBIE has access. In certain circumstances, IBIE may route a full share order to the available European trading venues acting in an Agency capacity and the fractional portion of the order will be allocated to your account at the price traded in the trading venue and the remaining fractional portion will be allocated to an affiliate. "
+Notes/Legal Notes,Data,Notes,"In case of partial executions, commissions are charged on the total quantity executed on the original order. The commission is displayed on the first partial execution only."
+Notes/Legal Notes,Data,Notes,Trade execution times are displayed in Eastern Time.
+Notes/Legal Notes,Data,Notes,Applicable regulatory fees for your transactions are available on the IB website at www.interactivebrokers.com/en/accounts/fees/exchangeAndRegulatoryFees.php.
+Notes/Legal Notes,Data,Notes,"Borrow Fee Rate represents the cost to borrow stock expressed in percent per annum. It is applied to the collateral value on the stock borrow contract and is separate from any interest earned on credit cash balances. Similarly, Loan Fee Rate represents the benefit to lend stock. A positive rate indicates a cost to the borrower/benefit to the lender and a negative rate indicates a benefit to the borrower/cost to the lender. In general, the fee rates for hard-to-borrow stocks are higher than for normal availability stocks."
+Notes/Legal Notes,Data,Notes,Interest Rate on Customer Collateral represents the interest paid on the collateral posted to the customer's account and received from lending stock. A positive rate indicates a benefit to the lender.
+Notes/Legal Notes,Data,Notes,"The closing prices on this Activity Statement are indicative and may come from third-party sources. Interactive Brokers does not warrant the accuracy of the prices provided by third-party sources. Due to time zone differences, certain non-US mutual funds may deliver closing prices after the Activity Statement has been produced and the closing prices for such funds will reflect the previous day's price."
+Notes/Legal Notes,Data,Notes,All Market Data and Research services are provided through Global Financial Information Services (GmbH).
+Notes/Legal Notes,Data,Notes,"Market data is provided by Global Financial Information Services (GmbH). Your local broker collects amounts owed for fees and tax for such data on behalf of Global Financial Information Services (GmbH). Note, you are responsible for any applicable taxes relating to the provision of these services."
+Notes/Legal Notes,Data,Notes,"Directive 2014/65/EU and its implementing measures (MiFID II) applies to all client funds and client financial instruments (Client Assets) on this statement except those Client Assets that are not classified as segregated assets, namely securities lent under the Stock Yield Enhancement Programme as identified in the IBKR Managed Securities Lent section of this statement and Client Assets noted as Not Segregated in the Collateral for Customer Borrowing section of this statement. IBIE applies the MiFID II Client Asset protection requirements to funds and instruments that are not subject to MiFID II in the same way as it applies those requirements to Client Assets. IBIE is also subject to the client asset requirements set out in the Central Bank (Supervision and Enforcement) Act 2013 (Section 48(1))(Investment Firms) Regulations 2023 (=S.I. No. 10 of 2023)."
+Notes/Legal Notes,Data,Notes,RUS denotes Ruble balances that have been restricted by Russian authorities.
+Notes/Legal Notes,Data,Mutual Fund Notes,"All purchase and sales of mutual funds are calculated against the published NAV (Net Asset Value) of the underlying fund and is displayed on this confirmation as the ""C. Price"" (Closing Price). Due to any fees charged by a fund and/or any share rounding, the net price you pay may vary from the published NAV and is shown on this confirmation as the ""T. Price"" (Trade Price)."
+Notes/Legal Notes,Data,Fixed Income Notes,"Call features for bonds or preferred stocks may affect the yield. For zero coupon, compound interest and multiplier securities, there are no periodic payments and securities may be callable below maturity value without notice to holder unless registered. For asset-backed securities, the actual yield may vary depending on the speed at which the underlying note is pre-paid. For additional information regarding bond yield, please contact the IB Help Desk at: ibkr.com/help. If this debt security is unrated by a nationally recognized statistical rating organization, it may pose a high risk of default. You should consult an independent advisor to determine whether unrated bonds are appropriate for your portfolio in light of your goals and your financial circumstances. Fees charged by bond trading centers are included in the cost of bond transactions."
+Notes/Legal Notes,Data,Legal Notes,"Please promptly report any inaccuracy or discrepancy in this statement, or in your account, to Interactive Brokers Ireland Limited (""IBIE""). You can contact us by telephone or electronically through the IBIE website at, www.interactivebrokers.ie. If you report an error by telephone, you should re-confirm such oral communication in writing in order to protect your rights, including your rights under the Investor Compensation Scheme."
+Notes/Legal Notes,Data,Legal Notes,"Unless otherwise noted, IBIE acted as agent in the execution of the above transactions. IBIE may execute your trades through affiliates or third-party brokers who are members of the relevant exchange or market center. Please see the IBIE CAKID Bank Account List at www.ibkr.ie/cakid for custody details."
+Notes/Legal Notes,Data,Legal Notes,"IBIE acts as agent or riskless principal in foreign currency exchange transactions and CFDs. Such transactions are executed against an IBIE affiliate, which acts as principal in such transactions and may have a long or short position and may have profited or lost in connection with the transaction."
+Notes/Legal Notes,Data,Legal Notes,"IBIE routes orders in US products through its US affiliate, IBLLC. IBLLC accepts liquidity rebates or other order flow payments from Alternative Trading Systems, market makers and exchanges for certain orders in US stocks. IBLLC receives payment for some US option orders pursuant to exchange-mandated marketing fee programs or other arrangements."
+Notes/Legal Notes,Data,Legal Notes,Please promptly notify IB-IE of any material change in your investment objectives or financial situation or circumstances.
+Notes/Legal Notes,Data,Legal Notes,"An up-to-date financial statement of IBIE is available for your personal inspection at www.interactivebrokers.ie or at its offices, or a copy of the financial statement will be mailed to you upon your written request."
+Notes/Legal Notes,Data,Legal Notes,"IBIE is a member of the Investor Compensation Scheme, which provides protection for customers in the event of the failure of IBIE. Further information on the Investor Compensation Scheme can be found at www.investorcompensation.ie ."
+Notes/Legal Notes,Data,Legal Notes,IBIE is incorporated under the laws of Ireland and registered with the Irish Companies Registration Office with company registration number 657406.
+Notes/Legal Notes,Data,Legal Notes,IBIE is regulated by the Central Bank of Ireland.
+Notes/Legal Notes,Data,Legal Notes,"IBIE's Registered Office address is 91 North Wall Quay, Dublin, D01 H7V7, Ireland."
+Notes/Legal Notes,Data,Legal Notes,"IBIE is included in the Central Bank of Ireland's register of authorised firms under number C423427. The CBI's address is New Wapping Street, North Wall Quay, Dublin 1, D01 F7X3. The CBI's website is www.centralbank.ie."
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..3071bb2
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,3 @@
+module site
+
+go 1.23.4
diff --git a/main.go b/main.go
new file mode 100644
index 0000000..529cf85
--- /dev/null
+++ b/main.go
@@ -0,0 +1,361 @@
+package main
+
+import (
+ "encoding/csv"
+ "encoding/json"
+ "fmt"
+ "log"
+ "net/http"
+ "strings"
+ "sync"
+ "time"
+)
+
+// ---------- HTTP Handlers ----------
+
+func HelloHandler(w http.ResponseWriter, r *http.Request) {
+ if r.URL.Path != "/hello" {
+ http.Error(w, "404 not found", http.StatusNotFound)
+ return
+ }
+ if r.Method != "GET" {
+ http.Error(w, "method is not supported", http.StatusNotFound)
+ return
+ }
+ fmt.Fprintf(w, "Hello You")
+}
+
+func Home(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, "./static/index.html") }
+func Portfolio(w http.ResponseWriter, r *http.Request) {
+ http.ServeFile(w, r, "./static/portfolio.html")
+}
+func Infra(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, "./static/infra.html") }
+func Cyber(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, "./static/cyber.html") }
+func About(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, "./static/about.html") }
+func GitPage(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, "./static/gitpage.html") }
+func GitPageTicTacToe(w http.ResponseWriter, r *http.Request) {
+ http.ServeFile(w, r, "./static/gitpages/TicTacToe.html")
+}
+
+func Styles(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, "./static/styles.css") }
+
+// TradesHandler handles POST /trades
+// It accepts a CSV file upload (field name: "file") and returns enriched trades as JSON.
+//
+// Example curl:
+//
+// curl -X POST http://localhost:8081/trades -F "file=@trades.csv"
+func TradesHandler(w http.ResponseWriter, r *http.Request) {
+ if r.Method != http.MethodPost {
+ http.Error(w, "only POST is supported", http.StatusMethodNotAllowed)
+ return
+ }
+
+ // Parse multipart form (max 10MB)
+ if err := r.ParseMultipartForm(10 << 20); err != nil {
+ http.Error(w, "failed to parse form: "+err.Error(), http.StatusBadRequest)
+ return
+ }
+
+ file, _, err := r.FormFile("Trades.csc")
+ if err != nil {
+ http.Error(w, `missing "file" field in form-data`, http.StatusBadRequest)
+ return
+ }
+ defer file.Close()
+
+ // Parse CSV
+ reader := csv.NewReader(file)
+ reader.LazyQuotes = true
+ reader.TrimLeadingSpace = true
+ records, err := reader.ReadAll()
+ if err != nil {
+ http.Error(w, "invalid CSV: "+err.Error(), http.StatusBadRequest)
+ return
+ }
+
+ // Use most recent weekday as price date
+ priceDate := lastWeekday(time.Now().UTC().AddDate(0, 0, -1))
+
+ // Enrich and return as JSON
+ enriched, err := enrichRecords(records, priceDate)
+ if err != nil {
+ http.Error(w, "enrichment failed: "+err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ w.Header().Set("Content-Type", "application/json")
+ json.NewEncoder(w).Encode(enriched)
+}
+
+// ---------- Main ----------
+
+func main() {
+ http.HandleFunc("/styles.css", Styles)
+ http.HandleFunc("/", Home)
+ http.HandleFunc("/about", About)
+ http.HandleFunc("/portfolio", Portfolio)
+ http.HandleFunc("/infra", Infra)
+ http.HandleFunc("/cyber", Cyber)
+ http.HandleFunc("/gitpage", GitPage)
+ http.HandleFunc("/gitpage/TicTacToe", GitPageTicTacToe)
+ http.HandleFunc("/trades", TradesHandler)
+ http.HandleFunc("/api/prices", PricesHandler)
+
+ fmt.Println("running on http://localhost:8081/")
+ if err := http.ListenAndServe(":8081", nil); err != nil {
+ log.Fatal(err)
+ }
+}
+
+// ---------- Trade type ----------
+
+type Trade struct {
+ DataDiscriminator string `json:"data_discriminator"`
+ AssetCategory string `json:"asset_category"`
+ Currency string `json:"currency"`
+ Symbol string `json:"symbol"`
+ DateTime string `json:"date_time"`
+ Quantity string `json:"quantity"`
+ TradePrice string `json:"trade_price"`
+ CurrentPrice float64 `json:"current_price"` // enriched from EOD
+ Proceeds string `json:"proceeds"`
+ CommFee string `json:"comm_fee"`
+ Basis string `json:"basis"`
+ RealizedPL string `json:"realized_pl"`
+ MTMLPL string `json:"mtm_pl"`
+ Code string `json:"code"`
+}
+
+// ---------- Enrich logic ----------
+
+func enrichRecords(records [][]string, priceDate time.Time) ([]Trade, error) {
+ // Collect unique tickers from Data/Order rows
+ type key struct{ symbol, currency string }
+ needed := map[key]struct{}{}
+
+ for _, row := range records {
+ if len(row) <= colCPrice {
+ continue
+ }
+ if row[colType] == "Trades" && row[colHeader] == "Data" && row[colDataDisc] == "Order" {
+ sym := strings.TrimSpace(row[colSymbol])
+ cur := strings.TrimSpace(row[colCurrency])
+ if t := toYahooTicker(sym, cur); t != "" {
+ needed[key{t, cur}] = struct{}{}
+ }
+ }
+ }
+
+ // Fetch prices concurrently
+ prices := map[string]float64{}
+ var mu sync.Mutex
+ var wg sync.WaitGroup
+
+ for k := range needed {
+ wg.Add(1)
+ go func(ticker string) {
+ defer wg.Done()
+ eod, err := FetchEOD(ticker, priceDate)
+ mu.Lock()
+ defer mu.Unlock()
+ if err != nil {
+ log.Printf("[warn] %s: %v", ticker, err)
+ } else {
+ prices[ticker] = eod.Close
+ }
+ }(k.symbol)
+ }
+ wg.Wait()
+
+ // Build response
+ var trades []Trade
+ for _, row := range records {
+ if len(row) <= colCPrice {
+ continue
+ }
+ if row[colType] != "Trades" || row[colHeader] != "Data" || row[colDataDisc] != "Order" {
+ continue
+ }
+
+ sym := strings.TrimSpace(row[colSymbol])
+ cur := strings.TrimSpace(row[colCurrency])
+ ticker := toYahooTicker(sym, cur)
+
+ var currentPrice float64
+ if ticker != "" {
+ currentPrice = prices[ticker]
+ }
+
+ t := Trade{
+ DataDiscriminator: strings.TrimSpace(row[colDataDisc]),
+ AssetCategory: strings.TrimSpace(row[colAssetCategory]),
+ Currency: cur,
+ Symbol: sym,
+ DateTime: safeCol(row, colDateTime),
+ Quantity: safeCol(row, colQuantity),
+ TradePrice: safeCol(row, colTPrice),
+ CurrentPrice: currentPrice,
+ Proceeds: safeCol(row, 10),
+ CommFee: safeCol(row, 11),
+ Basis: safeCol(row, 12),
+ RealizedPL: safeCol(row, 13),
+ MTMLPL: safeCol(row, 14),
+ Code: safeCol(row, 15),
+ }
+ trades = append(trades, t)
+ }
+
+ return trades, nil
+}
+
+func safeCol(row []string, i int) string {
+ if i < len(row) {
+ return strings.TrimSpace(row[i])
+ }
+ return ""
+}
+
+func lastWeekday(t time.Time) time.Time {
+ for t.Weekday() == time.Saturday || t.Weekday() == time.Sunday {
+ t = t.AddDate(0, 0, -1)
+ }
+ return t
+}
+
+const (
+ colType = 0
+ colHeader = 1
+ colDataDisc = 2
+ colAssetCategory = 3
+ colCurrency = 4
+ colSymbol = 5
+ colDateTime = 6
+ colQuantity = 7
+ colTPrice = 8
+ colCPrice = 9
+)
+
+var tickerOverrides = map[string]string{
+ "NOVOBc": "NOVO-B.CO",
+}
+
+func toYahooTicker(ibkrSymbol, currency string) string {
+ if override, ok := tickerOverrides[ibkrSymbol]; ok {
+ return override
+ }
+ if strings.Contains(ibkrSymbol, " ") {
+ return "" // skip options
+ }
+ return ibkrSymbol
+}
+
+type EODPrice struct {
+ Ticker string
+ Date string
+ Open float64
+ High float64
+ Low float64
+ Close float64
+ Currency string
+ LatestPrice float64 // regularMarketPrice from meta — most recent quote
+ LatestTime time.Time
+ PreviousClose float64
+ ChangePercent float64
+}
+
+func FetchEOD(ticker string, date time.Time) (*EODPrice, error) {
+ start := time.Date(date.Year(), date.Month(), date.Day(), 0, 0, 0, 0, time.UTC)
+ end := start.Add(24 * time.Hour)
+
+ url := fmt.Sprintf(
+ "https://query1.finance.yahoo.com/v8/finance/chart/%s?period1=%d&period2=%d&interval=1d",
+ ticker, start.Unix(), end.Unix(),
+ )
+
+ req, err := http.NewRequest("GET", url, nil)
+ if err != nil {
+ return nil, err
+ }
+ req.Header.Set("User-Agent", "Mozilla/5.0")
+
+ resp, err := http.DefaultClient.Do(req)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+
+ var payload struct {
+ Chart struct {
+ Result []struct {
+ Meta struct {
+ Currency string `json:"currency"`
+ RegularMarketPrice float64 `json:"regularMarketPrice"`
+ RegularMarketTime int64 `json:"regularMarketTime"`
+ ChartPreviousClose float64 `json:"chartPreviousClose"`
+ RegularMarketChangePercent float64 `json:"regularMarketChangePercent"`
+ } `json:"meta"`
+ Indicators struct {
+ Quote []struct {
+ Open []float64 `json:"open"`
+ High []float64 `json:"high"`
+ Low []float64 `json:"low"`
+ Close []float64 `json:"close"`
+ } `json:"quote"`
+ } `json:"indicators"`
+ } `json:"result"`
+ Error *struct {
+ Description string `json:"description"`
+ } `json:"error"`
+ } `json:"chart"`
+ }
+
+ if err := json.NewDecoder(resp.Body).Decode(&payload); err != nil {
+ return nil, err
+ }
+ if payload.Chart.Error != nil {
+ return nil, fmt.Errorf("yahoo: %s", payload.Chart.Error.Description)
+ }
+ if len(payload.Chart.Result) == 0 {
+ return nil, fmt.Errorf("no data for %s on %s", ticker, date.Format("2006-01-02"))
+ }
+
+ r := payload.Chart.Result[0]
+ q := r.Indicators.Quote[0]
+
+ if len(q.Close) == 0 || q.Close[0] == 0 {
+ return nil, fmt.Errorf("no close price for %s on %s", ticker, date.Format("2006-01-02"))
+ }
+
+ return &EODPrice{
+ Ticker: ticker,
+ Date: date.Format("2006-01-02"),
+ Open: q.Open[0],
+ High: q.High[0],
+ Low: q.Low[0],
+ Close: q.Close[0],
+ Currency: r.Meta.Currency,
+ LatestPrice: r.Meta.RegularMarketPrice,
+ LatestTime: time.Unix(r.Meta.RegularMarketTime, 0).UTC(),
+ PreviousClose: r.Meta.ChartPreviousClose,
+ ChangePercent: r.Meta.RegularMarketChangePercent,
+ }, nil
+}
+
+func PricesHandler(w http.ResponseWriter, r *http.Request) {
+ var req struct {
+ Tickers []string `json:"tickers"`
+ }
+ json.NewDecoder(r.Body).Decode(&req)
+
+ priceDate := lastWeekday(time.Now().UTC().AddDate(0, 0, -1))
+ var results []EODPrice
+ for _, t := range req.Tickers {
+ eod, err := FetchEOD(t, priceDate)
+ if err == nil {
+ results = append(results, *eod)
+ }
+ }
+ w.Header().Set("Content-Type", "application/json")
+ json.NewEncoder(w).Encode(results)
+}
diff --git a/static/about.html b/static/about.html
new file mode 100644
index 0000000..66e5395
--- /dev/null
+++ b/static/about.html
@@ -0,0 +1,103 @@
+
+
+
+ Bachelor's student in Business Administration seeking an entry-level analyst or finance-related role while studying. Strong numerical skills, advanced Excel, and experience in company, risk, and financial analysis. Analytical, detail-oriented, and efficiency-focused.
+
+
+
+
+
// skills
+
+
Excel
+
Python
+
SQL
+
Go
+
Git
+
+
+
+
+
+
// experience
+
+
+
Independent Equity Research
+
Perform fundamental analysis using SEC filings (10-K, 10-Q) and earnings reports. Assess profitability, liquidity, risk factors, and long-term business sustainability. Handle incomplete or low-transparency information through structured cross-validation.
+
+
+
+
Technical Tools & Automation
+
Build lightweight backend tools to automate repetitive analytical and operational tasks. Use Python for data processing, validation, and workflow automation. Develop lightweight online services in Go, focusing on speed and reliability.
+
+
+
+
+
+
// education
+
+
+ 2025 — now
+
+
Bachelor of Economics & Business Administration (HA)
+
Aalborg University · Expected 2028
+
+
+
+
+ 2020 — 2023
+
+
HTX – Technical Upper Secondary Education
+
Viden Gymnasier · Mathematics A, Biology B Study project: Mathematics & Technology
+ Most breaches are not the result of a sophisticated exploit or a zero-day vulnerability. They are the result of a person clicking the wrong link, reusing a password, or trusting a phone call they should not have answered. Security is not primarily a technical problem. It is an organizational one.
+
+
+
Know What You Are Protecting
+
+
Before you can build a security posture, you need to understand your data. Not all information carries the same weight. Customer financial records, internal credentials, and strategic planning documents are not the same as a public press release or a shared meeting agenda. Treating all data as equally sensitive wastes resources and creates compliance fatigue. Treating it all as equally safe is how companies end up in the news.
+
+
The first step is classification. Every organization should have a clear and enforced taxonomy for what they hold — what is critical, what is sensitive, and what is routine. Once data is classified, access decisions, storage choices, and transmission policies all become considerably more straightforward.
+
+
+
+
● Critical
+
Restricted
+
Credentials, financial records, legal documents, private keys. Encrypted at rest and in transit. Need-to-know access only. Audited on access.
+
+
+
● Sensitive
+
Internal
+
Strategy documents, personnel files, client data. Role-based access. Not to leave internal systems without explicit sign-off.
+
+
+
● Standard
+
General
+
Shared documentation, public-facing content, operational guides. Normal access controls. No special handling required.
+
+
+
+
Passwords Are Not a Personal Choice
+
+
The idea that employees should be trusted to choose and manage their own passwords is one of the most persistent and destructive myths in corporate security. People are not good at passwords. They reuse them across services, they write them down, they choose predictable patterns, and they resist changing them when asked. This is not a character flaw — it is human nature operating against a task humans were never designed to do well.
+
+
The answer is a mandatory, company-wide password manager. Not recommended. Not optional. Mandatory. Every account created for company use lives in the vault. Credentials are generated by the manager — long, random, unique per service. No employee ever needs to know or remember most of them. Access to the vault itself is protected by a strong master passphrase and hardware-backed two-factor authentication.
+
+
+ A password an employee cannot remember is a password an attacker cannot guess.
+
+
+
Two-Factor Is Not Optional
+
+
Two-factor authentication is the single highest-return security investment any organization can make. A stolen password without the second factor is nearly useless. Yet an astonishing number of companies treat 2FA as something to enable "if employees want to." That framing gets it exactly backwards.
+
+
Every account with access to company systems requires 2FA, enforced at the policy level — not left to the individual. Preference should go to hardware security keys like YubiKey or authenticator apps generating time-based codes. SMS-based 2FA is better than nothing, but SIM-swap attacks make it the weakest option and it should be phased out wherever possible.
+
+
Enrollment should happen on day one, before access is granted to any system. Not after. The moment an employee has a credential without a second factor is a window of exposure that does not need to exist.
+
+
Make Access Deliberately Hard
+
+
This sounds counterintuitive. Friction is the enemy of productivity — until it is the thing standing between your database and someone who found a badge in the parking lot. The principle of least privilege is not just a compliance checkbox. It is an architecture decision.
+
+
Employees should have access to exactly what they need to do their job, and nothing more. Access should be reviewed on a schedule and revoked immediately upon role change or departure. Broad access to critical systems should require explicit justification, a second approver, and a time limit. The default answer to an access request is not yes — it is: why do you need this, for how long, and who else knows?
+
+
This friction is not about distrust. It is about reducing the blast radius of any single compromised account. If an attacker gains access to a junior analyst's credentials, they should find themselves in a narrow corridor, not a wide open floor.
+
+
Social Engineering Is the Real Attack Surface
+
+
Technical controls can be near-perfect and still fail the moment someone calls the help desk pretending to be a manager who has been locked out while traveling. Social engineering works because it exploits social instincts that are otherwise useful — the tendency to help, to defer to authority, to avoid confrontation.
+
+
Mitigating this requires two things: process and culture. Process means that no credential reset, no access grant, and no sensitive disclosure ever happens over a phone call or an email alone, regardless of how urgent it sounds or who the request appears to come from. Verification must follow a separate, pre-established channel. The louder someone insists the situation is urgent, the more carefully the process should be followed.
+
+
Culture means that employees feel safe slowing down and saying no. An employee who challenges an unusual request should be recognized for it, not made to feel obstructive. The organization needs to make it socially acceptable — even admirable — to be the person who held the line.
+
+
+
+
+
Attack Vector
+
Method
+
Countermeasure
+
+
+
+
+
Phishing
+
Fraudulent email mimicking a trusted sender to harvest credentials or deploy malware
+
Email filtering, DMARC/DKIM, regular drill simulations, no credential entry from email links
+
+
+
Vishing
+
Voice call impersonating IT, management, or a vendor to extract access or trigger an action
+
Zero verbal credential resets. All requests verified via a separate known channel, no exceptions
+
+
+
Credential Stuffing
+
Automated use of leaked passwords from other breaches against company systems
+
Mandatory password manager with unique credentials per service. 2FA blocks the rest
+
+
+
Insider Threat
+
Disgruntled or compromised employee exfiltrating data or granting unauthorized access
+
Least-privilege access, access logging and anomaly alerts, prompt offboarding procedures
+
+
+
Pretexting
+
Fabricated scenario (new hire, auditor, vendor) to gain physical or digital access
+
Visitor protocols, escort requirements, no tailgating culture, ID verification for all physical access
+
+
+
+
+
Security Is a Continuous Practice
+
+
A one-time audit followed by a certificate on the wall is not a security posture. It is a snapshot. Threat landscapes change, personnel changes, and systems change. Security needs to be a living practice — regular access reviews, periodic credential audits, tabletop exercises for breach scenarios, and honest post-mortems when something goes wrong.
+
+
The companies that handle breaches best are not necessarily the ones that prevented them — they are the ones that detected them fast, contained them well, and communicated clearly. That kind of response capability does not appear on the day of the incident. It is built over years of treating security as infrastructure, not an afterthought.
+
+
+
+
You cannot patch people. But you can build systems and cultures that make it very difficult for human error to become organizational catastrophe. Mandatory 2FA. Mandatory password managers. Minimal access by default. Verification processes that do not bend under social pressure. These are not sophisticated controls. They are disciplined ones — and discipline, consistently applied, is the closest thing to security that actually exists.
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/static/gitpage.html b/static/gitpage.html
new file mode 100644
index 0000000..71dc797
--- /dev/null
+++ b/static/gitpage.html
@@ -0,0 +1,188 @@
+
+
+
+
+
+ Git — Samantha Friis
+
+
+
+
+
A fast, minimal toolkit for processing and visualizing time-series data. Built with TypeScript, zero runtime dependencies, works in Node and the browser.
+
+
Installation
+
npm install project-name
+# or
+yarn add project-name
+ The tools a company chooses to build on top of says a lot about how serious it is about the craft. The industry-wide drift toward Word, Teams, and Microsoft 365 is not a productivity upgrade — it is a slow erosion of competence dressed up as convenience.
+
+
+
The Convenience Trap
+
+
+ Every tool that hides complexity from you takes something away. When a new hire can open a laptop running Windows, install Office in ten minutes, and be "operational" by noon, that feels like a win. But operational is not the same as capable. What that person has actually learned is how to navigate a UI. They have not learned how their machine works, how their data flows, or how to adapt when the abstraction breaks.
+
+
+
+ Large vendor ecosystems like Microsoft 365 are engineered for the lowest common denominator. They are excellent at onboarding someone with no background — and they stop there. The ceiling is built in by design. You cannot meaningfully extend Word. You cannot script Teams in any serious way. You are a tenant inside someone else's system, paying monthly for the privilege of not understanding what is happening underneath you.
+
+
+
+ Convenience optimizes for the speed of the newcomer.
+ It does not care about the ceiling of the expert.
+
+
+
What We Trade Away
+
+
+ The deeper issue is what gets lost over time. A team that has never had to configure anything has never had to understand anything. When your document pipeline is Word plus SharePoint, you never learn what a proper typesetting system looks like. When your servers are Azure with a click-through UI, you never develop intuition for networking, permissions, or failure modes. The knowledge simply does not accumulate.
+
+
+
+ The companies most dependent on big vendor stacks also tend to be the most fragile. A license change, a price increase, a deprecated feature — and suddenly nobody knows what to do. There is no internal knowledge to fall back on. The stack was always a rented abstraction.
+
+
+
+
+
Vendor-Locked Stack
+
+
Fast to start, hard to master
+
Knowledge lives in the UI, not the team
+
Expensive at scale, locked by contracts
+
No meaningful customization
+
Fragile when the vendor changes terms
+
Homogeneous — everyone works the same way
+
+
+
+
Custom Infrastructure
+
+
Slower to start, no ceiling
+
Knowledge compounds inside the team
+
Cheap at scale, you own what you build
+
Configured precisely for your workflow
+
Resilient — you understand every layer
+
Personal — the environment fits the person
+
+
+
+
+
Linux as a Philosophy
+
+
+ A Linux desktop is not just a different operating system. It is a different relationship with your machine. You configure your window manager, your keybindings, your terminal, your dotfiles. The environment becomes an extension of how you think. Two engineers on the same team can have entirely different setups that are both optimized for their own cognitive style — and that is a feature, not a problem.
+
+
+
+ This is not about being difficult or contrarian. It is about the fact that a person who has spent time configuring neovim, managing a systemd service, or writing their own shell scripts has fundamentally more understanding of computation than someone who has spent the same time clicking through GUIs. That understanding compounds. It transfers across every problem they touch.
+
+
+
Documents Should Be Code
+
+
+ The same logic applies to document production. Word processing is a GUI wrapped around formatting decisions you did not make. The output is inconsistent, the versioning is painful, and the result is never quite right. A typesetting system like Typst treats a document as source code — deterministic, version-controlled, composable. You write a template once and it is correct everywhere, forever. The document becomes a reproducible artifact.
+
+
+
+ Custom pipelines like this require an upfront investment. You have to learn the tool, build the template, establish the workflow. But once built, the leverage is enormous. Reports, invoices, analysis documents — all generated cleanly from structured data, with zero manual formatting. That is not possible in Word. It is not even imaginable in Word.
+
+
+
Own Your Servers
+
+
+ Self-hosted infrastructure demands that someone in your organization understands it. That is not a burden — it is the point. When you run your own services, you know exactly where your data lives, what it costs to run, and what happens when something fails. You build operational knowledge that no managed cloud service can give you.
+
+
+
+ This does not mean rejecting cloud entirely. It means being intentional. Use the cloud where the economics clearly favor it. Build and operate everything else yourself. The goal is a team that could reconstruct its own stack from scratch if it had to — because a team capable of that is a team that actually understands what it has built.
+
+
+
+
+
+ The best infrastructure is not the most convenient. It is the most understood. Tools that demand something from you — configuration, learning, patience — are the tools that make you better over time. Convenience is a ceiling. Complexity, embraced deliberately, is a floor that keeps getting higher.
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/static/portfolio.html b/static/portfolio.html
new file mode 100644
index 0000000..c363e1d
--- /dev/null
+++ b/static/portfolio.html
@@ -0,0 +1,589 @@
+
+
+
+
+
+ Portfolio — Samantha Friis
+
+
+
+
+
+