cswork / libraryOpen practice workspace

Interview guides · Arrowstreet Capital

Arrowstreet Capital Data Scientist Interview Questions & Guide 2026

Practice explaining analysis before a Arrowstreet Capital data scientist interview: the recommendation, the uncertainty, the follow-ups.

The 60-second brief

At Arrowstreet Capital, a private, systematic asset management firm, the Data Scientist role is a highly specialized and impactful position. Often overlapping with or directly supporting the Quantitative Researcher track, Data Scientists at the firm are responsible for extracting actionable investment signals from massive, complex, and highly diverse datasets. By applying advanced statistical modeling, machine learning, and econometric analysis, you will directly influence the investment strategies that manage billions of dollars in global assets.

A large share of questions open as "how would you measure X", where the real work is choosing the metric, fixing its denominator, and defining the population it applies to. Any computation comes last and is frequently not required at all.

Focus areas

  • Size positions by risk contribution, not conviction
  • Attach uncertainty to every Sharpe claim
  • Model impact and borrow before claiming capacity

Overview

The complexity of the data at Arrowstreet Capital requires more than just standard machine learning pipelines; it demands deep statistical intuition and rigorous mathematical foundations. You will work on processing alternative data, refining predictive models, and optimizing portfolio execution strategies. Because the firm operates on a systematic, data-driven philosophy, your work as a Data Scientist is not merely supportive—it is the core engine that drives the firm's competitive advantage in the global markets.

This role is ideal for individuals who thrive at the intersection of finance, mathematics, and computer science. You will collaborate closely with Quantitative Researchers, Quantitative Developers, and data engineers to take models from theoretical mathematical formulations to production-level trading systems. The environment is intellectually rigorous, collaborative, and highly rewarding for those who enjoy solving open-ended, high-stakes quantitative problems.

The Arrowstreet Capital interview process

Arrowstreet Capital candidates report 3 rounds · ≈ 3-5 weeks. The stages below are what candidates describe, not a published process.

Online Assessments

A handful of shapes account for most of what gets asked in this format: a ranking or deduplication inside groups, a running or rolling total, a period-over-period comparison, and a cohort tracked forward over time. Recognising the shape quickly is most of the speed here; deriving it from scratch while a clock runs is where the time goes. Know that a window function keeps every row while a GROUP BY collapses them, and know which one the question needs. If the exercise is in Python instead of SQL, the same shapes arrive as groupby with transform, shift and merge, and the same grain mistakes are available.

What to demonstrate

  • Whether you reach the right construct without a detour, such as ROW_NUMBER over a partition to deduplicate instead of a self-join against a MAX subquery
  • Whether you know what your window frame actually is, since adding ORDER BY inside OVER changes the default frame and silently changes a running total
  • Whether the thing runs. A near-miss that throws an error scores below a plainer query that returns the right rows.

How to prepare

  • Write each of the four shapes once from memory against a small schema and keep the working version somewhere you will reread it: dedupe with ROW_NUMBER, a running total, a month-over-month change with LAG, and a retention table
  • Compute one running total twice on data with tied timestamps, once on the default frame and once with ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW, and look at where the two disagree
  • If Python is on the table, rebuild the dedupe and the running total with groupby and cumsum, then assert the two implementations return identical rows

Technical Screens

Much of what gets scored here happens out loud while you type. Nobody can see your reasoning inside a half-written query, so five silent minutes read as being stuck even when they are not. State the plan in plain language first: which tables, what grain you are aggregating to, and the one filter that defines the population. Then write it. The narration doubles as insurance, because a wrong plan gets caught early and cheaply while a wrong query gets caught at the end with no time left to redo it. A timed statistics section, where one exists, is a separate test with its own clock.

What to demonstrate

  • Whether the query you write matches the plan you just described
  • What you do with a hint, meaning whether the correction gets absorbed or the first approach gets defended
  • Whether you can debug your own wrong output by reading the result set and naming which part of the query produced the anomaly

How to prepare

  • Solve three problems while screen-sharing into a recording, then watch it back and mark every stretch longer than thirty seconds where you said nothing
  • Practise compressing the plan into one sentence before typing, then check afterwards whether the finished query actually matched it
  • Time yourself on statistics questions that carry a business reading, such as what a confidence interval does and does not claim, rather than re-reading notes without a clock

Final On-site Interview

Where a loop includes a partner from outside the data team, that conversation usually carries the same weight as the technical ones and gets the least preparation. The person opposite you will not follow a derivation and does not need to. They are working out whether having you involved would make their decisions better or slower. The failure mode is not being too technical. It is answering a question about a decision with a description of your method, leaving the translation to them. What they carry into the debrief is the sentence you handed them, not the analysis underneath it.

What to demonstrate

  • Whether a statistical result arrives as something the partner could act on, with the one caveat that would change their decision kept and the rest left out
  • Whether you can state what you need from their side, in their terms: instrumentation that does not exist yet, a definition they own, or a holdout they have to agree to
  • Whether uncertainty is given as a range someone can plan against, rather than as hedging that invites them to ignore the result
  • Whether you ask what decision is actually on the table before explaining anything

How to prepare

  • Take a result you know well and write the version for someone who stops reading after one sentence, then the three-minute version, and check the short one is not the long one with the qualifications stripped out
  • For a past project, list everything you asked a non-technical partner for and how you phrased it, then rewrite each ask so it names what goes unmeasured without it
  • Practise saying where a result does not apply, out loud, in one sentence that a partner could repeat accurately to someone else

Where candidates lose points

Computing a t-statistic on daily observations of an h-day forward return as if the observations were independent.

Sampling an h-day forward return every day means consecutive observations share h-1 days of the same return, which induces strong positive autocorrelation. The naive standard error is too small by a factor on the order of sqrt(h), so a 5-day-horizon signal with a genuine t of 1.3 can present as 2.9. Either use non-overlapping samples, which costs power, or use a Newey-West or Hansen-Hodrick covariance with at least h-1 lags, and state which one was used.

Filtering on as_of_date rather than knowledge_ts, so restated fundamentals, revised index constituents and retroactively applied split and dividend adjustments enter the backtest before they were knowable.

Vendors overwrite history in place. A quarterly figure filed 45 days after period end is stored against period end, an index addition announced five business days before it takes effect is stored against the effective date, and a split applied tonight rewrites every prior close in the adjusted series. Each of those gives the strategy information it could not have had, and the resulting lift is concentrated in the highest-turnover, highest-apparent-alpha names. The signal_score table separates the two timestamps precisely so this filter can be written correctly.

Extrapolating a first-week lift inflated by novelty effects

Plot the treatment effect by days since first exposure instead of quoting one pooled average. A lift that decays toward zero across the test window is behaviour that will not persist, and annualising it produces a forecast that misses by an order of magnitude.

Comparing periods without accounting for seasonality or day-of-week

Compare whole weeks against whole weeks and check whether the same swing appeared in prior cycles or prior years before attributing it to anything you changed. Weekday and weekend populations often differ enough that a Tuesday-to-Saturday comparison is meaningless.

Questions & practice

How would you mathematically prove whether a given matrix is positive semi-definite, and why is this property important for portfolio optimization?

Medium · statistics and probability

Approach

  1. Sanity-check the answer against a simple bound or a simulated case.
  2. Write down the assumption the method needs before you use the method.
  3. Quantify uncertainty explicitly rather than reporting a point estimate alone.

Follow-up

  • How would you explain this result to someone who does not know statistics?
  • What sample size would you need to detect an effect half this size?

Explain the concept of expected value using a coin-toss game where the payout doubles with each consecutive head. How much would you pay to play this game?

Medium · statistics and probability

Approach

  1. Write down the assumption the method needs before you use the method.
  2. Quantify uncertainty explicitly rather than reporting a point estimate alone.
  3. Translate the result into the decision it informs, in one plain sentence.

Follow-up

  • Which assumption here is most likely to be violated in practice?
  • What sample size would you need to detect an effect half this size?

Implement a basic search or sorting algorithm from scratch and analyze its time and space complexity.

Medium · machine learning and modelling

Approach

  1. Frame the prediction: the label, the moment of prediction, and the action it triggers.
  2. Set a baseline first, so any model has something honest to beat.
  3. Say how the offline result would be validated online before it is trusted.

Follow-up

  • What would you monitor after launch to know the model is still valid?
  • How would you choose the decision threshold, and who owns that choice?

Explain the difference between heteroskedasticity and homoskedasticity. How does heteroskedasticity affect your regression coefficients and standard errors?

Medium · machine learning and modelling

Approach

  1. Set a baseline first, so any model has something honest to beat.
  2. Pick an evaluation metric that matches the cost of each error type, not a default.
  3. Check what information would not exist at prediction time, and exclude it.

Follow-up

  • What would you monitor after launch to know the model is still valid?
  • Where could label leakage enter this setup?

Permutation test for mean IC with overlapping forward returns

Hard · permutation test · signal evaluation · autocorrelation

panel has as_of_date, instrument_id, zscore_xs and fwd_ret_5d_excess, the five-trading-day forward return in excess of the universe's cap-weighted mean, for 252 dates and roughly 1,500 instruments a date. Compute the daily Spearman rank IC and its mean. Then build a permutation null from scratch and report a two-sided p-value. Compare it with a naive t-test on the 252 daily ICs and with a Newey-West t using four lags. State which null hypothesis your permutation scheme actually tests.

Approach

  1. Compute the daily IC by ranking both columns within as_of_date with method='average' and taking the Pearson correlation of the rank vectors. Decide explicitly how to treat dates where the universe shrinks, because an unweighted mean gives a 40-name date the same weight as a 1,500-name date.
  2. The obvious permutation shuffles zscore_xs within each as_of_date. That is the right exchangeability for the null 'the signal carries no cross-sectional ordering on any given day', and it preserves the daily sample size and the cross-sectional return structure, factor effects included.
  3. But it makes the permuted daily ICs independent across dates, and the real ones are not. A five-day forward return sampled every day shares four days with its neighbour, and the signal itself is persistent, so the observed IC series is strongly autocorrelated. Under an i.i.d. daily return null the variance of the mean of overlapping h-period observations inflates by a factor of h, so the within-day null is too narrow by about sqrt(5) and its p-value is anti-conservative.
  4. Fix it by permuting at the date level: circularly shift the whole signal panel's as_of_date labels by a random offset, keeping each day's cross-section and the signal's serial persistence intact while breaking its alignment with the returns. The 252 distinct shifts give an exact randomization test with a p-value floor of 1/252.
  5. Report all three numbers. The naive t and the Newey-West t with 4 lags (h-1 for h = 5) should differ by a factor near sqrt(5), and the shift-permutation p should agree with the Newey-West figure rather than the naive one. If it does not, one of the two is implemented wrongly and you have a cheap way to find out which.

Worked solution (45 min)

  1. ranks = panel.groupby('as_of_date')[['zscore_xs','fwd_ret_5d_excess']].rank(method='average'); daily IC is the per-date Pearson correlation of the two rank columns.
  2. Within-day scheme: one rng.permutation of the signal rank vector inside each date, 10,000 replications of the mean IC.
  3. Shift scheme: remap as_of_date through a circular offset over the sorted unique dates, re-join to the returns on (shifted_date, instrument_id), and record how much of the panel drops because an instrument is absent on the shifted date, since a large loss biases the null.
  4. naive_t = mean(IC)/(std(IC, ddof=1)/sqrt(252)); Newey-West t with a Bartlett kernel and 4 lags.
  5. Put the three p-values, the two t-statistics, the replication count and the p-value floor in one table.

Expected result: The within-day permutation p-value tracks the naive t and is the smallest of the three. The Newey-West t is smaller than the naive t by a factor near sqrt(5) = 2.24, and the shift-permutation p sits close to it. A mean IC of 0.03 with a daily IC standard deviation near 0.10 gives a naive t around 4.8 and a Newey-West t around 2.1, which is the difference between 'obvious' and 'worth one more year of data'.

Verify it yourself

  • Switching the forward horizon to one day should collapse the three answers toward each other; if they still differ by a factor of two, something other than the overlap is driving the gap.
  • The mean of the permuted mean-IC distribution must sit near zero under both schemes; a non-zero centre means the permutation is leaking the alignment it is meant to break.
  • The shift permutation at offset zero must reproduce the observed statistic exactly.
  • The daily IC series should show positive autocorrelation out to about four lags and near zero beyond; if it does not, the overlap correction is unnecessary here and you should say so rather than apply it anyway.

Follow-up

  • With 252 circular shifts and the observed statistic the largest among them, what is the smallest p-value you can report, and is it small enough for the decision being made?
  • How would you redo this on non-overlapping five-day samples, and how much power do you surrender?
  • The signal has a 12-day decay half-life. Does that change your shift block length or your Newey-West lag choice?

Write a function to find the longest subarray with a sum equal to a target value.

Medium · sql and data manipulation

Approach

  1. Say which table is the grain you start from, and join outward from it.
  2. Compute rates by summing numerator and denominator separately, never by averaging rates.
  3. Handle the rows that do not match: a LEFT JOIN with a NULL check is usually the question.

Follow-up

  • What breaks if events arrive late or out of order?
  • How does the query change if the join becomes one-to-many?

Write a SQL query to retrieve the top-performing assets per region from a historical database, handling null values and ties appropriately.

Medium · sql and data manipulation

Approach

  1. Handle the rows that do not match: a LEFT JOIN with a NULL check is usually the question.
  2. Say which table is the grain you start from, and join outward from it.
  3. Compute rates by summing numerator and denominator separately, never by averaging rates.

Follow-up

  • How would you verify this result without re-running the same query?
  • What breaks if events arrive late or out of order?

Order fill funnel by execution algorithm, in counts and notional

Easy · funnel · conditional-aggregation · cohorting

From parent_order (order_id, algo_name, order_qty, filled_qty, status, arrival_ts, arrival_mid_px), build a monthly funnel per algo_name over orders whose arrival_ts falls in the month: orders released, orders with any fill (filled_qty > 0), orders fully filled (status = 'filled'), and the two step conversion rates. Produce the same funnel in notional, using order_qty * arrival_mid_px. Orders with status = 'rejected' never reached the market — state how you treat them and implement that choice.

Approach

  1. Use conditional aggregation in a single pass — COUNT(*) FILTER (WHERE filled_qty > 0) and friends — rather than three subqueries joined together, so every numerator and denominator provably comes from the same row set.
  2. Make the denominator decision explicit: rejects are an order-management outcome, not an execution outcome, so exclude them from both numerator and denominator and report their count in a separate column. An exclusion you cannot see in the output is an exclusion nobody can audit.
  3. Cast before dividing. With integer counts, filled / released floors to 0 in Postgres; filled::numeric / NULLIF(released, 0) gives the rate and also handles an algo with zero orders in the month.
  4. Compute the notional funnel with the same FILTER clauses over SUM(order_qty * arrival_mid_px). Divergence between the count funnel and the notional funnel is the finding: 60 percent of orders completing but 20 percent of notional means the large orders are the ones stalling.
  5. Group by date_trunc('month', arrival_ts) and algo_name, and left-join a distinct algo list if months with zero activity must still appear as rows.

Worked solution (20 min)

  1. Write one aggregate query over the month with FILTER clauses for released, any-fill and fully-filled, plus a rejected count.
  2. Wrap it and compute the two conversion rates with explicit numeric casts and NULLIF guards.
  3. Duplicate the three FILTER clauses over SUM(order_qty * arrival_mid_px) to get the notional funnel.
  4. Reconcile: released + rejected must equal the raw count of orders with arrival_ts in the month.
  5. Scan for algos where the count rate and notional rate differ by more than 10 points and note them for follow-up.

Expected result: One row per (month, algo_name) with released, any-fill and fully-filled counts, two rates in [0, 1], the matching notional funnel, and a visible rejected count.

Verify it yourself

  • Any-fill count is greater than or equal to fully-filled count for every row.
  • Both rate columns fall in [0, 1] and are NULL rather than an error where released is zero.
  • Released plus rejected, summed across algos, equals the raw month order count.
  • An order with filled_qty > 0 and status = 'canceled' appears in any-fill but not in fully-filled.

Follow-up

  • filled_qty sits on the parent but the fills live in execution_fill. How would you find parents whose filled_qty disagrees with the sum of their non-correction fills, and which side would you trust?
  • The fully-filled rate rises after participation_rate_target is lowered. Is that an improvement, and what second metric settles it?

How would you optimize a Python script that is running slowly due to large-scale matrix operations? Explain how you would use vectorization.

Medium · product sense and metrics

Approach

  1. Restate the decision this analysis has to support, and who acts on the answer.
  2. Name one primary metric, then the guardrail that stops it being gamed.
  3. State what result would change your recommendation, so the answer is falsifiable.

Follow-up

  • How would you detect that the metric is being gamed rather than genuinely improving?
  • What would you do if the primary metric and the guardrail moved in opposite directions?

How do you identify and mitigate multicollinearity in a high-dimensional dataset?

Medium · product sense and metrics

Approach

  1. Decompose the metric into the rates that drive it, and say which one you would check first.
  2. Restate the decision this analysis has to support, and who acts on the answer.
  3. State what result would change your recommendation, so the answer is falsifiable.

Follow-up

  • Which segment would you cut first, and what would that rule out?
  • What would you do if the primary metric and the guardrail moved in opposite directions?

Size an execution algorithm test on implementation shortfall

Easy · power · mde · execution

Per-order implementation shortfall against arrival price, computed from parent_order (order_qty, filled_qty, arrival_mid_px, avg_fill_px, adv_20d) and execution_fill (commission_amt, exchange_fee_amt, rebate_amt), has averaged 12.4 bps with a standard deviation of 35 bps over the trailing twelve months. The desk releases roughly 1,900 parent orders a month. An execution team proposes a new child-order scheduler and claims a 1.5 bps improvement. Size a two-arm, order-level randomised test at 80 percent power and a two-sided 5 percent level, and say how long it has to run.

Approach

  1. Pin the response variable to the exact metric definition before touching the arithmetic: shortfall in bps versus arrival_mid_px, with commission, exchange fee and rebate included and the unfilled remainder (order_qty minus filled_qty) charged at the terminal mid. The sigma you plug in has to be the standard deviation of that quantity, not of a convenient proxy.
  2. Estimate sigma from the trailing twelve months of the same order population rather than from a remembered number. Shortfall is heavy tailed, so also compute a winsorised sigma and quote the sample size both ways, because the difference tells you how much of your power calculation rests on a handful of orders.
  3. Apply the two-sample difference-in-means formula, n per arm = 2 * sigma^2 * (z_{0.975} + z_{0.80})^2 / delta^2, which under equal allocation reduces to 15.7 * sigma^2 / delta^2.
  4. Decide whether the shipping decision is made on the equal-weighted per-order mean or the notional-weighted mean, because they have different variances. For a weighted mean the effective sample size is (sum of weights)^2 / (sum of squared weights), and notional weights in a book with a long tail of large orders can cut that well below the row count.
  5. Convert to calendar time at realised flow and check the answer against the business horizon. If nine months is unacceptable, the legitimate levers are a larger delta, lower power accepted explicitly, or variance reduction; shortening the test while keeping the same stopping rule is not one of them.

Worked solution (20 min)

  1. Compute per-order shortfall for the trailing twelve months from parent_order joined to execution_fill, charging the unfilled remainder at the terminal mid, and confirm sigma is about 35 bps.
  2. Record the notional-weighted effective sample size (sum of weights)^2 / (sum of squared weights) on the same population, so you know the discount before you commit to an estimator.
  3. Evaluate n per arm = 2 * 35^2 * (1.96 + 0.8416)^2 / 1.5^2.
  4. Divide the two-arm total by 1,900 orders a month to get calendar time.
  5. Recompute at delta = 3.0 bps to demonstrate the quadratic sensitivity to the claimed effect.

Expected result: About 8,550 orders per arm, 17,100 in total, roughly nine months at 1,900 orders a month. Doubling the claimed effect to 3.0 bps cuts the requirement by a factor of four, to about 2,140 per arm and roughly two and a quarter months.

Verify it yourself

  • (z_{0.975} + z_{0.80}) = 2.8016 and its square is 7.85, so the whole calculation collapses to n = 15.7 * sigma^2 / delta^2 per arm; 15.7 * 1225 / 2.25 should reproduce 8,548.
  • Halving the detectable effect must multiply the sample size by exactly four; if your spreadsheet does not do that, the formula is wrong.
  • Simulate: resample two arms from the empirical shortfall distribution with a 1.5 bps shift at n = 8,550 per arm and confirm the rejection rate lands within a point or two of 0.80. A materially lower rate means the normal approximation is straining on the tails.

Follow-up

  • What happens to the required sample size if the committee decides on the notional-weighted mean instead of the equal-weighted mean?
  • At 1,900 orders a month, what effect size can you detect in a single month, and would you run that test at all?
  • If the real goal is 'no worse than the incumbent', how do you set the non-inferiority margin and what changes in the test?

Information ratio rose while gross alpha stayed flat

Hard · autocorrelation · marking · risk measurement · annualization

The book's trailing-252-day net information ratio rose from 0.90 to 1.25 over a quarter. Mean daily active return is unchanged within its standard error, and realized annualized tracking error fell from 430 bps to 310 bps. Nothing in portfolio construction or the risk limits changed. Tables: position_daily (business_date, account_id, instrument_id, quantity, mark_px, mark_source, market_value_base, unrealized_pnl_base_day, realized_pnl_base_day, recon_status) and a daily benchmark return series. Decide whether risk genuinely fell, and state what you would tell the risk committee before anyone re-levers the book.

Approach

  1. Split the ratio and confirm the entire move sits in the denominator. An information ratio that improves with a static numerator is a statement about measured volatility, and measured volatility is a property of how the return series was constructed as much as of the positions held.
  2. Test the series before testing the positions. Compute the autocorrelation of daily active return in each window. Smoothed or carried-forward marks induce positive autocorrelation, and the sqrt(252) annualization assumes it is zero, so a positive rho makes annualized volatility too small by construction rather than by chance.
  3. Compare volatility across sampling frequencies. Aggregate the same daily active returns into non-overlapping weekly and monthly returns and annualize each. Under independence the three estimates agree. Under smoothing the daily estimate is the smallest and the gap widens with horizon. This is the decisive test because it needs no view on which positions are mismarked.
  4. Only then find the mechanism: tabulate the share of gross market value by mark_source per business_date, and the share of rows whose recon_status is not 'matched'. A rising share of vendor_eval, model or stale_prior_day marks is the direct cause, and the affected names are usually the least liquid in the book.
  5. Give the committee the unsmoothed volatility and the corrected information ratio next to the reported ones, and say plainly that sizing to a volatility target computed on smoothed marks applies real leverage to understated risk.

Follow-up

  • With a first-order autocorrelation of 0.25 and no higher-order terms, by how much is long-horizon volatility understated by the daily estimate? Show the arithmetic.
  • Which instruments in this book would you expect to carry a vendor_eval mark, and what does that imply about the liquidity of the risk you just re-measured?
  • The same smoothing inflates the Sharpe ratio. What does it do to reported maximum drawdown, and in which direction?

Suggested practice checklist

For someone who has spent the last year in notebooks, dashboards or modelling work and has not written raw SQL under time pressure. The first four days rebuild query fluency against a fixture you control and can verify by hand; the last three attach that fluency to the rest of the loop.

Day 1 — Build a fixture you can check answers against

  • Create a local Postgres or SQLite database with four tables (users, sessions, events, orders) holding roughly 200 rows you generated yourself, so you know the contents well enough to predict every result.
  • Deliberately seed the cases that break queries: a user with no sessions, a session with no events, two orders sharing a timestamp, a NULL in one join key, and one duplicated user row.
  • Before writing any SQL, hand-compute five answers on paper (how many users placed at least one order, median orders per ordering user, and three others) and save them as the ground truth for the week.

Deliverable: A one-command seed script plus a text file of five hand-computed answers to grade every later query against.

Day 2 — Joins, filters and NULL semantics

  • Answer "which users have no orders" three ways (LEFT JOIN with IS NULL, NOT EXISTS, NOT IN) and confirm that the NOT IN version returns zero rows once the subquery contains a NULL, because the comparison is never TRUE.
  • Reproduce the LEFT JOIN that silently collapses to an inner join by putting a right-table predicate in WHERE, then fix it by moving the predicate into the ON clause, and record both row counts.
  • Create a fan-out bug on purpose by joining orders to order_items and summing the order total, then correct it with a pre-aggregated subquery and explain in one line which table changed the grain.

Deliverable: One annotated .sql file holding the three join traps, each with the wrong result and the corrected result side by side.

Day 3 — Window functions and frames

  • Write three window queries against the fixture: a running order total per user, the rank of each order within its user by value, and the day gap to that user's previous order, then check each against the day-one ground truth.
  • Run ROW_NUMBER, RANK and DENSE_RANK over a column containing ties, print all three side by side, and write one sentence on when each is the correct choice.
  • Switch one query from the default frame (RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW, which is what you get when ORDER BY is present and no frame is written) to ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW, and explain why the output differs only when the ORDER BY column has duplicates.

Deliverable: Three verified window queries plus a short note explaining the RANGE versus ROWS difference in your own words.

Day 4 — The four analytical query patterns

  • Write a monthly retention grid: first order month per user, then months-since-first as the column, and verify that month zero equals the cohort size exactly.
  • Sessionize the events table under a 30-minute inactivity rule using LAG plus a cumulative sum over a new-session flag.
  • Build a four-step funnel that counts distinct users rather than events at each step, and state the rule you applied to a user who reaches step three without ever logging step two.

Deliverable: One file with the retention, sessionization and funnel patterns, each carrying a one-line note on the assumption it bakes in.

Day 5 — Write SQL the way you will have to write it live

  • Set a 12-minute timer and solve three medium prompts in a plain editor with no execution and no autocomplete, then run them and tally syntax errors separately from logic errors.
  • Narrate one solution aloud while writing it, stating the grain of each intermediate result (one row per user, one row per user-day) before you type its body.
  • Rewrite your slowest solution as a CTE chain where every CTE name states its grain, and time yourself re-solving it from blank.

Deliverable: A recording of one narrated solution plus an error tally that separates syntax from logic.

Day 6 — One day for everything that is not SQL

  • Write the preconditions of the two-sample t-test from memory, then check them: independent observations, and a difference in means whose sampling distribution is approximately normal, which at large sample sizes follows from the central limit theorem rather than from normality of the raw values.
  • Write the difference between an odds ratio from logistic regression and a relative risk, and state the condition under which the two are close (low outcome prevalence).
  • Prepare a 90-second answer to "how would you know this model is any good" that names the metric, the baseline you would beat, and the cost of the errors you care about.

Deliverable: One page of notes covering test preconditions, the odds-ratio caveat and the model-quality answer.

Day 7 — Full loop rehearsal

  • Run a 45-minute mock with someone willing to interrupt: 20 minutes of SQL, 15 minutes defining a metric, 10 minutes on a past project.
  • Re-solve from blank the two queries you were slowest on this week and compare the times against day five.
  • Write a five-line answer to "walk me through a project" that puts a number in the first sentence and names the decision the work changed.

Deliverable: Mock feedback notes plus a timed project narrative you can deliver without reading it.

The project you argued against

Saying no well is a senior skill and it is rarely rehearsed. Think of a time you told someone their analysis was not worth doing, or that the experiment could not answer their question at the sample size available. Explain what you offered instead. Refusal without an alternative reads as obstruction rather than judgement.

Tell me about a project where your initial model failed to produce the expected results. How did you diagnose the issue and pivot?

Medium · behavioural and stakeholder questions

Approach

  1. Quantify the outcome, including what you would not claim credit for.
  2. State the situation in two sentences and spend the rest on your reasoning.
  3. Name the disagreement or constraint, and how you resolved it with evidence.

Follow-up

  • What did you decide not to do, and why?
  • What would you do differently if you ran that project again?

Disagreeing with a product manager over an account leaderboard

Medium · stakeholder disagreement · attribution · dispersion

A product manager wants to ship a client portal widget ranking every separately managed account against its peers in the same strategy composite, by trailing 12-month net return. You believe the ranking will mostly order accounts by mandate mechanics rather than by anything a client can act on. You have position_daily, account_mandate (SCD2) and benchmark returns for 140 accounts in the composite. Build the case and bring a counter-proposal you would ship. The product manager has a launch date and a client asking for exactly this.

Approach

  1. What is probed: whether you can lose the feature and keep the working relationship, meaning your disagreement arrives with a shippable alternative rather than as a veto.
  2. Measure the dispersion before arguing about it. Compute the cross-sectional standard deviation of trailing 12-month net return across the 140 accounts. If it is small, the product manager is right and you are not, and you want to know that before the meeting rather than during it.
  3. Decompose the dispersion into causes you can name from the tables: time spent ramping between funded_date and the date gross exposure reached 90 percent of target_gross_exposure_pct, average cash weight over the period, restricted names via position_daily.is_restricted, single-name cap differences across account_mandate SCD2 versions, and fee schedule including whether a performance fee crystallised above the high-water mark. Report the share each explains and the residual.
  4. Convert the finding into the client's decision, because that is what moves a product manager. If most dispersion is mandate mechanics, the leaderboard tells a client to change managers when the honest action is to relax a constraint or fund fully. A wrong action is an argument; a noisy statistic is a preference.
  5. Bring the alternative that keeps the launch date: the same widget, showing the account's return against its own benchmark and its own constraint set, with a named driver line such as your restricted list cost 34 bps, instead of a rank. It answers what the client actually asked and it survives a phone call.
  6. Pre-commit to being wrong. If the residual dominates the decomposition, the leaderboard is measuring something real, and saying so in the same memo is what makes the rest of it credible next time.

Follow-up

  • Dispersion is 180 bps and mandate mechanics explain 40 percent of it. What do you ship?
  • The client asked for a rank by name. Do they get one, and what do you put next to it?
  • How do you keep this from becoming a standing veto on anything this product manager proposes?

Ranking three quarters of requests into one quarter of capacity

Hard · prioritisation · expected value · stakeholder management

You are the only data scientist supporting three groups for one quarter. The execution desk wants the market-impact curve recalibrated; the last fit is fourteen months old and predates a volatility regime change. A portfolio manager wants a new signal researched. The client team wants a Brinson attribution that reconciles to reported active return, because it currently leaves an unexplained residual of roughly 40 bps a year. Each group believes theirs is first. Produce a ranked plan, the decision rule you used, and what you tell the two groups who do not go first.

Approach

  1. What is probed: whether you can price work in the firm's units rather than in the requester's urgency, and whether the rule you used survives being stated out loud to the people it ranks last.
  2. Convert each request into expected basis points of net active return per year with an explicit range, then divide by weeks of your time. The impact recalibration applies to every order: at 150 percent annualized one-way turnover the book trades roughly three times average gross per year counting both sides, so a 2 bps shortfall improvement is about 6 bps of gross annually. Small, high confidence, and applies whether or not any research succeeds.
  3. Price the signal as an expected value rather than a hoped-for one. Most researched signals do not survive deflation for the number of configurations tried, since the maximum of many noisy Sharpe estimates grows roughly like the standard error times the square root of twice the natural log of the number of trials even with no true edge. A plausible 0.2 information-ratio contribution at a one-in-five survival rate is a large number heavily discounted, with a long right tail that is the reason to do it at all.
  4. Price the attribution request by what it protects rather than by what it earns. A 40 bps unexplained residual is a number clients see, and attribution that does not reconcile is a credibility cost that surfaces later in the dollar redemption rate. Defensive work can rank first without generating a single basis point of alpha.
  5. Rank, then sequence for parallelism. Put the short, high-confidence item first if it unblocks somebody else's work, and schedule the long-tailed research where a failure is cheap and discoverable early. State the rule before the numbers, so the groups who lose can argue with the inputs rather than with your loyalties.
  6. Give each deferred group something real: a date, the specific input that would change the ranking, and the smallest useful piece you will do now, such as a one-day bisection of the 40 bps residual that tells the client team whether it is pricing, cash or trade timing.

Follow-up

  • The portfolio manager escalates to your manager's manager. What do you say, and what do you not say?
  • The quarter shortens by four weeks. Which item do you drop entirely rather than shrink?
  • How do you avoid becoming the person who always picks the execution desk's work because it is the easiest to quantify?