At IMC, a Data Scientist plays a pivotal role in bridging the gap between raw financial data, quantitative research, and live execution. Unlike traditional technology firms where data science might support product analytics or marketing, at IMC, your work directly impacts the core trading engine. You will be responsible for extracting actionable insights from massive, high-frequency market datasets, designing predictive models, and optimizing execution strategies that run in real-time production environments.
The scale and complexity of the data at IMC are immense. You will work with petabytes of historical tick-by-tick market data, order book dynamics, and alternative datasets to identify subtle patterns that can be translated into trading signals. The models you build will contribute to liquid market-making and proprietary trading strategies globally, requiring you to balance mathematical rigor with computational efficiency.
This role is highly collaborative, placing you at the intersection of trading desk activities and software engineering. You will work alongside and to rapidly prototype, backtest, and deploy models. Success in this position requires not only exceptional quantitative skills but also a deep curiosity about financial markets and the resilience to thrive in a fast-paced, high-stakes environment.
Online Assessment
reportedA 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
Recorded Video Interview
reportedRounds outside the standard loop often open with something deliberately under-specified: a loose business problem, an open question about a product area, a dataset described in one sentence. The common failure is surveying, listing six plausible approaches and committing to none of them. The thing that separates a strong answer is scoping out loud. State what you are treating as the goal, name the metric you would move, say what you are choosing not to do and why, then take one path through to an actual answer. An interviewer can follow you down a narrow path. Nobody can grade a menu.
What to demonstrate
- Whether you turn an ambiguous prompt into a stated question with a measurable outcome before doing any work
- The judgement visible in what you cut, and whether you say why you cut it rather than silently dropping it
- Whether you land on a concrete recommendation with its caveat attached, rather than an unranked set of options
How to prepare
- Take three vague prompts, such as 'is this feature working', 'why did retention drop', and 'should we expand into a new segment'. For each, write one sentence of goal, one primary metric with its window, and two things you are explicitly not doing.
- Practise giving the recommendation first and the reasoning second, in five minutes. Loosely defined rounds are usually time-boxed, and an answer that arrives last often does not arrive.
- Keep a running assumption list as you talk, on paper or in the shared doc, so the interviewer can challenge one assumption instead of your whole answer.
Live Technical Interviews
reportedBefore anything else, this round is a reading test. You are given a small schema and a question phrased in business language, and most of the difficulty sits in the gap between them. Who counts as an active user, does a refunded order still count as an order, is that date column an event time or a load time. Weak answers start typing immediately and compute something precise about the wrong population. Strong ones pin the definition in one sentence, name the column that encodes it, then write the query. On a timed assessment with nobody to tell, write the definition in a comment anyway.
What to demonstrate
- Whether an ambiguous term becomes a specific column and filter before any computation happens
- Whether you read the schema for keys and cardinality rather than only for column names
- Whether the result answers the question at the grain it was asked at, per user or per session or per day
How to prepare
- Take three metrics you already use and write down the exact filter and exact grain behind each, then practise stating one of them in a single sentence out loud
- On a schema you have never seen, spend the first minute writing what one row of each table means and which key it is unique on, then predict which joins can duplicate rows
- Rehearse a version where the definition changes halfway through, and edit the query you have instead of starting over
Final Round
reportedWhere a loop ends with a senior leader, that conversation is rarely another skills test. The technical signal already exists by then, so the questions tend to open up: what you would look at first, where a metric you have heard about could mislead, what you would push back on. The decision being made is scope, which in practice means level and how much you would be trusted to own unsupervised. Treating it as a formality is the usual mistake. An open question late in the day is still being scored, and a vague answer reads as someone who has not run anything themselves.
What to demonstrate
- Whether your view of the business has anything specific behind it, given that you are working only from what is public and are expected to say so
- Whether the scope of work you describe owning matches the scope of the role, instead of sitting a level below it
- Whether you can disagree with something concrete and stay useful about it, rather than agreeing with everything said in the room
- Whether your questions are ones only this person could answer, as opposed to ones the recruiter already covered
How to prepare
- Build one view you could defend for two minutes using only public information: what the funnel probably looks like, which metric likely drives decisions, and where that metric could mislead. Being wrong for a stated reason survives this round; having no view does not
- Write down the largest piece of work you have owned from question to decision, who else touched it, and what you decided alone, then check that it reads at the level you are interviewing for
- Prepare one thing you would want changed if you joined and phrase it as a question rather than a verdict, so it opens a conversation instead of closing one
13 candidate reports. Individual accounts describe a particular role and hiring cycle.
IMC Software Engineer interview with no update after round two
After I got through the early stages, the process seemed to be moving normally. I completed what I believed was round two and waited for the next step. The silence afterward threw me off. I never received an official message saying that I hadn’t made it to round three. Instead, I was left to infer what had happened, with no real closure. The lack of communication made the experience drag on even…
Read full experienceIMC Software Engineer home assignment and code review
I started with a home assignment that was split into two parts. They estimated about six hours of work and gave me three days to complete it, so it felt manageable at first. The first part involved implementing something straightforward, along with smaller requirements such as writing a README and adding unit tests. Some of the solution requirements felt subjective and depended on the approach, w…
Read full experienceIMC Software Engineer interview: seven three-minute reasoning sessions
I applied through a school career fair and online, and then received an online logical reasoning test. It was divided into seven sessions. Each session lasted three minutes and had four questions, which made the test feel rushed even though the topics were the kind of things you can practice. After I finished it, I received a second online test with three questions. This one was more technical, a…
Read full experienceIMC Network Engineer interview: modern C++ and multicast protocol questions
My process began with an asynchronous online interview and a technical test. The main technical portion started with a deeper discussion focused heavily on C++. It felt intense from the beginning. The interviewers were welcoming enough, but the questions went well beyond surface-level knowledge and dug into modern C++. I went through additional rounds, and the later stages became even more specia…
Read full experienceIMC Software Engineer interview with coding, system design, and team fit
The process was structured and felt comprehensive. After applying, I completed an online activity and then had an initial screening call. The technical portion moved into coding interviews where I could choose the programming language. The work combined problem-solving discussions with system design questions. There were also team fit and culture checks, along with a feedback step where they revi…
Read full experiencePracHub editorial advice for the preparation topics above.
Joining research panels to the current instrument master instead of its effective-dated version, so delisted, merged and bankrupt names silently disappear from the historical universe.
The names that leave a universe leave disproportionately after bad returns, so removing them raises backtested return and lowers backtested volatility at the same time. The bias is largest exactly where the strategy claims to add value, in the tails, and it is invisible in the output: the query succeeds, the row count looks plausible, and the equity curve simply looks better than it should. The fix is to resolve universe membership with a predicate on effective_from and effective_to, never on status = 'active'.
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.
Averaging per-user rates to produce a population rate
Decide which quantity you want: the mean of per-user ratios and the ratio of summed numerator to summed denominator are different estimands, and heavy users dominate one but not the other. For a ratio metric, aggregate numerator and denominator separately and use the delta method for its variance.
Ignoring interference between units in a marketplace experiment
Ask whether one unit's treatment can change another unit's outcome through shared inventory, a matching pool, a social graph or a common budget. Where it can, randomise at a level that contains the spillover, such as region or time slice, and say explicitly what that costs you in statistical power.
Choose a category, try a prompt, then open its approach, worked solution or follow-up when you need it.
Calculate the expected value of a game where you roll a fair six-sided…
Calculate the expected value of a game where you roll a fair six-sided die and have the option to roll a second time to replace your first score.
Approach
- Sanity-check the answer against a simple bound or a simulated case.
- Say what the estimate is of, and over what population it generalises.
- Write down the assumption the method needs before you use the method.
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 conditional probability and how you would apply…
Explain the concept of conditional probability and how you would apply Bayes' theorem to update a trading signal's strength.
Approach
- Write down the assumption the method needs before you use the method.
- Translate the result into the decision it informs, in one plain sentence.
- Sanity-check the answer against a simple bound or a simulated case.
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?
Solve a systems-of-equations problem using matrix algebra, and explain…
Solve a systems-of-equations problem using matrix algebra, and explain its geometric interpretation.
Approach
- Sanity-check the answer against a simple bound or a simulated case.
- Translate the result into the decision it informs, in one plain sentence.
- Say what the estimate is of, and over what population it generalises.
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?
Walk through the mathematical derivation of a basic linear regression …
Walk through the mathematical derivation of a basic linear regression model and explain how you would handle multicollinearity in high-dimensional datasets.
Approach
- Frame the prediction: the label, the moment of prediction, and the action it triggers.
- Set a baseline first, so any model has something honest to beat.
- Check what information would not exist at prediction time, and exclude it.
Follow-up
- How would you choose the decision threshold, and who owns that choice?
- What would you monitor after launch to know the model is still valid?
Implementation shortfall in basis points against arrival price
You have one month of parent_order (order_id, instrument_id, side, order_qty, filled_qty, arrival_mid_px, terminal_ts, adv_20d, algo_name, status) and execution_fill (fill_id, order_id, fill_qty, fill_px, commission_amt, exchange_fee_amt, rebate_amt, is_correction, corrects_fill_id), plus mid_1s (instrument_id, ts, mid_px) on a one-second grid. Compute notional-weighted implementation shortfall in basis points versus arrival, sliced by algo_name and participation bucket, charging unfilled quantity at the mid prevailing at terminal_ts. Canceled and rejected orders are in scope.
Approach
- Recompute avg_fill_px from the fills as a quantity-weighted mean rather than trusting the parent_order column. That column is written by the OMS at terminal time and is stale on any order that received a correction after the close.
- Resolve corrections before aggregating: drop every fill_id that appears as a corrects_fill_id target, then drop rows with fill_qty = 0, which removes busts including a bust that supersedes a real fill. Chains need no special case, because every intermediate row is also somebody's target.
- Assemble the numerator in currency, not in basis points: side_sign*(avg_fill_px - arrival_mid_px)filled_qty, plus commission_amt plus exchange_fee_amt minus rebate_amt, plus side_sign(terminal_mid_px - arrival_mid_px)(order_qty - filled_qty), with side_sign = +1 for buy and buy_to_cover and -1 for sell and sell_short. Divide by order_qtyarrival_mid_px and multiply by 10000.
- Look terminal_mid_px up as of terminal_ts per instrument in mid_1s. For a rejected order terminal_ts is the rejection instant, so its opportunity-cost term is near zero by construction and the order still belongs in the denominator.
- Aggregate as sum(numerator)/sum(order_qty*arrival_mid_px) inside each cell, which is a notional weighting, not a mean of per-order basis points. Bucket participation as filled_qty/adv_20d with edges at 1%, 5% and 15%.
Worked solution 35 min
- superseded = set(fills.corrects_fill_id.dropna()); fills = fills[~fills.fill_id.isin(superseded) & (fills.fill_qty > 0)].
- agg = fills.groupby('order_id').agg(qty=sum of fill_qty, notional=sum of fill_qty*fill_px, comm, fee, reb); avg_px = notional/qty.
- Left-join agg onto parent_order so orders with zero surviving fills keep a row with qty = 0 instead of vanishing.
- Look up terminal_mid_px by an as-of lookup of (instrument_id, terminal_ts) into mid_1s.
- Build the per-order numerator and denominator columns, then groupby([algo_name, participation_bucket]) and divide the two sums.
Follow-up
- The top participation bucket shows a shortfall three times the bottom bucket. How much of that is the algo, and how much is that hard-to-trade names get routed there in the first place?
- These same orders beat interval VWAP on average. Explain in one sentence why both numbers are correct, and say which you would put in front of a portfolio manager.
- A broker asks you to exclude orders canceled within 30 seconds. What happens to the reported number, and why would they want that?
List fills that were never corrected, and survive the NULL
execution_fill records a cancel/correct as a new row with is_correction = TRUE and corrects_fill_id referencing the original; an ordinary fill has is_correction = FALSE and corrects_fill_id IS NULL. Return every original fill for a given settle_date that was never corrected, with fill_id, order_id, fill_qty, fill_px and commission_amt. A colleague's version filters WHERE fill_id NOT IN (SELECT corrects_fill_id FROM execution_fill) and returns zero rows on a day with thousands of fills. Explain why, then write the correct query.
Approach
- Name the mechanism precisely.
x NOT IN (...)expands tox <> v1 AND x <> v2 AND .... Against a NULL element the comparison is UNKNOWN, so the conjunction is either FALSE (when x matches some value) or UNKNOWN, never TRUE. Every probe row is filtered out. It is not an error, which is why it survives review. - Rewrite as
NOT EXISTS (SELECT 1 FROM execution_fill c WHERE c.is_correction AND c.corrects_fill_id = f.fill_id). This uses plain equality, is immune to NULLs in the inner column, and is the form the planner turns into a hash anti-join. - If
NOT INhas to stay for some reason, addWHERE corrects_fill_id IS NOT NULLto the subquery. It is correct, and it is fragile: the next nullable column someone probes reintroduces the identical bug with no new symptom. - Scope the correction lookup by time, not by the same
settle_date. A correction commonly arrives a day or more after the fill it amends, so restricting the inner query to the report date reports already-corrected fills as clean. - Close with arithmetic: originals on the date, minus distinct originals referenced by any correction row, must equal the returned count. If it does not, a correction references a fill_id that does not exist, which is a feed integrity issue worth raising.
Follow-up
- Would
LEFT JOIN ... WHERE c.fill_id IS NULLgive the same answer here? What changes if a single fill is corrected twice? - A correction lands three days after the TCA report went out. How do you make the report reproducible as-of its publication date rather than silently restating it?
Deduplicate a restated signal table into a leak-free panel
signal_score may hold several rows per (signal_id, instrument_id, as_of_date) because reruns rewrite history; each row carries model_version, knowledge_ts, computed_at, is_backfilled, zscore_xs, decile_rank, coverage_flag and universe_id. Build the panel a backtest may legitimately use on trading date D: for every instrument in universe_id = 'liquid_us_1500', the single most recent score whose knowledge_ts is at or before D 21:00 UTC, preferring a live row over a backfilled one. Return instrument_id, as_of_date, zscore_xs, decile_rank.
Approach
- Filter on
knowledge_ts, never onas_of_date.as_of_datesays what the score describes;knowledge_tssays the earliest instant every input was observable. Put it in the WHERE so it prunes before the window is evaluated. - Rank within the key:
ROW_NUMBER() OVER (PARTITION BY signal_id, instrument_id ORDER BY as_of_date DESC, is_backfilled ASC, knowledge_ts DESC, computed_at DESC)and keep rank = 1. In Postgres FALSE sorts before TRUE, sois_backfilled ASCis the live-row preference, written down rather than assumed. - Prefer ROW_NUMBER to a
MAX(computed_at)group-then-rejoin: the rejoin duplicates rows whenever two reruns share acomputed_at, which is exactly what a batch job produces. - Decide what
coverage_flag IN ('stale','imputed')means for this panel and encode it. Dropping those rows silently changes the universe size day to day, which surfaces later as an unexplained jump in measured IC rather than as a missing-data problem. - Express the cutoff as a parameter and the whole thing as a CTE so the backtest loop reuses one query text per date instead of a hand-edited copy.
Worked solution 25 min
- Write the filtered CTE:
universe_id = 'liquid_us_1500'andknowledge_ts <= :cutoff. - Add the ROW_NUMBER window with the four-key ordering and select rank = 1.
- Assert one row per instrument with a COUNT(*) versus COUNT(DISTINCT instrument_id) probe.
- Run the same query with
as_of_date <= Dsubstituted for the knowledge_ts filter and count how many rows differ. - Inspect the differing rows: they should be predominantly
is_backfilled = TRUEwithcomputed_atafter D.
Follow-up
- Write the query that proves the panel is leak-free. What would a violation look like in measured IC, and roughly how large would you expect the inflation to be?
- Produce every trading date in one pass instead of one query per date. What does that cost in plan shape?
- Two
model_versionvalues are live at once during a migration. How does the tie-break change, and who decides?
How do you optimize Python code (e.g., using pandas and numpy) to proc…
How do you optimize Python code (e.g., using pandas and numpy) to process multi-gigabyte files efficiently?
Approach
- State what result would change your recommendation, so the answer is falsifiable.
- Name one primary metric, then the guardrail that stops it being gamed.
- Decompose the metric into the rates that drive it, and say which one you would check first.
Follow-up
- Which segment would you cut first, and what would that rule out?
- How would you detect that the metric is being gamed rather than genuinely improving?
Explain the process of portfolio construction and how you would optimi…
Explain the process of portfolio construction and how you would optimize asset allocation under specific volatility constraints.
Approach
- Fix the population and the time window before naming any metric.
- Decompose the metric into the rates that drive it, and say which one you would check first.
- Restate the decision this analysis has to support, and who acts on the answer.
Follow-up
- What would you do if the primary metric and the guardrail moved in opposite directions?
- Which segment would you cut first, and what would that rule out?
How would you architect a robust web-scraping pipeline to collect real…
How would you architect a robust web-scraping pipeline to collect real-time data from highly dynamic websites without getting blocked?
Approach
- Clarify what is being asked and what a complete answer would contain.
- State your assumptions explicitly before working the problem.
- Work from the decision backwards to the evidence you would need.
Follow-up
- How would you know your answer was wrong?
- What assumption would you test first?
Measure forced trimming at a compliance threshold you cannot randomise
Compliance forces a trim whenever a position's weight_pct_nav in position_daily closes above the account's max_single_name_weight_pct from account_mandate, a hard 5.00 percent cap evaluated at the close and trimmed the next morning. Portfolio managers claim forced trimming destroys alpha, and compliance cannot be randomised. Over three years about 4,100 account-instrument-days sit within one percentage point of the cap. Identify the effect of forced trimming on the position's contribution to active return over the following twenty business days, and state what your estimate is and is not.
Approach
- Set it up as a sharp regression discontinuity in weight_pct_nav centred on the cap. Treatment is a deterministic function of the running variable, so the identifying assumption is only that potential outcomes are continuous at 5.00 percent. Nothing has to be randomised, which is the whole reason the design applies here.
- Test for manipulation before estimating anything. A density test on the running variable around the cap asks whether managers shave positions to 4.95 percent to stay under it. If the density has a hole just above the threshold, the design is dead and the correct deliverable is that the effect is not identified, not a number with a caveat.
- Estimate with local linear regression on each side, a triangular kernel and a data-driven mean-squared-error-optimal bandwidth rather than one chosen by eye, using robust bias-corrected confidence intervals. Report the estimate at that bandwidth and at half and double it to show the result is not a bandwidth artefact.
- State the estimand precisely. This is a local average treatment effect at a 5.00 percent weight, for positions large enough to reach the cap, in accounts whose mandate sets the cap there. It says nothing about trimming a 2 percent position and nothing about accounts with a 3 percent cap, unless you pool across caps by re-centring each observation on its own threshold, which is legitimate and enlarges the sample at the cost of assuming the discontinuity is the same at every cap level.
- Handle the two schema traps explicitly. account_mandate is SCD2, so an account whose cap was amended mid-history has two thresholds and each observation must be compared to the cap in force on its own business_date. And weight_pct_nav is derived from mark_px, so rows with mark_source of 'stale_prior_day' or 'model' carry a running variable measured with error, which in a discontinuity design attenuates the estimate and smears the jump. Exclude those rows and report how many were dropped.
- Say what would make you switch designs. If the cap is soft in practice, with a tolerance band, a grace day or discretionary waivers, the design is fuzzy rather than sharp: the indicator for being above the cap instruments for actually being trimmed, the estimate scales by the compliance rate, and the first-stage strength becomes something you have to report.
Worked solution 45 min
- Build the panel by joining position_daily to account_mandate on business_date between effective_from and effective_to, keeping account_id, instrument_id, business_date, weight_pct_nav, max_single_name_weight_pct and mark_source, and dropping rows whose mark_source is 'stale_prior_day' or 'model'.
- Construct the running variable as weight_pct_nav minus max_single_name_weight_pct, and the outcome as the position's cumulative contribution to active return over the next twenty business days.
- Run the density test at zero and report its p-value. If it fails, stop and report non-identification.
- Estimate local linear regression discontinuity with a triangular kernel at the optimal bandwidth and at half and double it, reporting robust bias-corrected intervals for each.
- Run falsification checks: the same discontinuity estimate on pre-determined covariates such as beta_to_benchmark, adv_20d and gics_sector_code must show nothing, and placebo cutoffs at plus and minus half a percentage point must show nothing.
- Cluster standard errors on account_id by instrument_id, because the same position recurs on consecutive days and its twenty-day forward outcomes overlap almost completely.
Follow-up
- How many observations actually fall inside the optimal bandwidth, and what effect size can that number detect?
- If the density test fails, what fallback design would you accept, and what would it now assume?
- Positions that reach the cap are the highest-conviction names in the book. Does that break the design, and if not, precisely why not?
Return dispersion widened inside one strategy composite
Trailing-12-month net returns for accounts running one strategy used to sit within about 40 bps of each other. This quarter the cross-sectional standard deviation is 210 bps and the AUM-weighted mandate success rate fell. The investment team insists the model is identical across accounts. You have position_daily (business_date, account_id, strategy_id, instrument_id, market_value_base, weight_pct_nav, is_restricted, fx_rate_to_base) and account_mandate (account_id, funded_date, inception_date, status, target_gross_exposure_pct, max_single_name_weight_pct, base_currency, mgmt_fee_bps, effective_from, effective_to). Explain the dispersion with an ordered checklist and say which part is a problem.
Approach
- Rank accounts by trailing-12-month net return and inspect the tail before averaging anything. A standard deviation is a distribution statistic and two accounts out of forty can produce it; the number alone does not say whether the cause is systemic or concentrated.
- Cut by months since funded_date and by status. An account in 'ramping' holds cash and sits below target_gross_exposure_pct, so it earns a diluted version of the strategy's return. In a rising market that reads as underperformance and in a falling one as outperformance, and both are mechanical rather than informative.
- Compute realized gross exposure per account-day from position_daily, as the sum of absolute market_value_base over NAV, and compare it with target_gross_exposure_pct from the account_mandate version valid on that business_date. Join on the effective_from and effective_to range, not on the current row, because mandate terms change mid-life and the current row would apply today's target to last year's book.
- Sort the remaining explanations into expected and not expected. Names excluded by is_restricted, base_currency differences moving through fx_rate_to_base, and mgmt_fee_bps differences on a net-of-fee metric are all expected. A weight breaching max_single_name_weight_pct, or an account holding instruments the others do not, is not.
- Report dispersion decomposed by cause with dollars attached. The client question is never why sigma is 210 bps; it is why this account returned less than the one on the last page.
Follow-up
- Two accounts funded the same day diverge by 90 bps and both reached target exposure inside 20 trading days. Where do you look next?
- The AUM-weighted success rate only counts accounts with 36 months of history. How does that interact with what you just found, and does it flatter the number or penalise it?
- How would you present cash drag to a client so it reads as a fact about funding rather than an excuse?
Roughly 90 minutes a night on weekdays with one longer weekend block. The plan deliberately cuts scope rather than compressing everything, on the assumption that finishing one thing a night beats half-starting four.
Prepare, practise & reflect
One practical outcome each day. Spend longer where you need it.
0 / 7 done01Fix the scope and set a baseline
- Read the role description and write the three things the loop will almost certainly test, then write an explicit not-doing list for everything else and keep it visible all week.
- Take one 20-minute SQL prompt and one 10-minute metric question cold, and write the single sentence that says what blocked each attempt, since that sentence is what decides which two topics get the most evenings.
- Set the week's one rule: one problem finished to completion every night, including the night you only have 40 minutes.
Deliverable: A one-page scope with an explicit not-doing list and two cold attempts, each carrying one sentence on what blocked it.
Practice prompt ↗Practice prompt ↗Practice prompt ↗Worked solution ↗02One query pattern, written three times
- Choose the single pattern most likely to appear (a cohort retention grid, or a funnel counted by user) and write it three times from a blank file rather than editing the previous attempt.
- On the third attempt, write the grain of every CTE as a comment before writing its body.
- Stop at 90 minutes even if the third version is imperfect, and write the one thing you would fix with another hour.
Deliverable: Three independent versions of the same query plus a note on what changed between them.
Practice prompt ↗Practice prompt ↗03Only the statistics you will be asked to defend
- Write, in under 200 words, how you would decide whether a difference between two groups is real: the test, its assumptions, and what you would switch to when an assumption fails.
- Compute a 95 percent confidence interval for a difference in proportions by hand on realistic numbers, then write in one sentence what changes if the two samples are paired rather than independent.
- Write your answer to "what does a p-value mean", check it against a definition, and delete the version that describes it as the probability the hypothesis is true.
Deliverable: A 200-word written answer and one hand-computed interval you can reproduce under pressure.
Practice prompt ↗Practice prompt ↗04One case, and the assumptions holding it up
- Answer one product case aloud in 20 minutes with a recording running, then listen back with a pen and mark every claim you asserted without saying what it rested on: an assumed user behaviour, an assumed data source, an assumed baseline rate, an assumed grain.
- Pick the three assumptions the recommendation actually depends on, write how you would check each one against data, and say which one being wrong would flip the recommendation rather than merely weaken it.
- Write the four-step structure you used onto a card small enough to hold in working memory when you are nervous.
Deliverable: One recording, three load-bearing assumptions each with a written check, and a four-step structure card.
Practice prompt ↗Practice prompt ↗Worked solution ↗05Your own work, timed
- Write a 90-second version and a four-minute version of your main project, and time both out loud rather than reading them.
- Prepare answers to the two follow-ups that always come: what you would do differently, and how you knew it worked.
- Put one number in the first sentence and be able to say exactly where that number came from and what it excludes.
Deliverable: Two timed narratives with one defensible number in the opening line.
Practice prompt ↗Practice prompt ↗06The one full rehearsal, in a longer weekend block
- Run a 60-minute mock covering query work, a case and a behavioural question in a single sitting with no breaks, because sustained attention is the thing evenings have not trained.
- Immediately afterwards, and before hearing any feedback, write the three moments you lost the thread.
- Spend the rest of the block only on those three moments, and on nothing you merely feel shaky about.
Deliverable: Mock notes naming three failure moments with a specific fix written under each.
Practice prompt ↗Practice prompt ↗07Taper
- Write the 20-minute warm-up you will actually do on the morning of the interview: one query you can already write from a blank file, one metric you can define out loud, and nothing you have never seen before.
- Re-read only your own notes from this week, and open no new material.
- Write down the logistics: the tool you will be asked to work in, whether lookups are allowed, and the sentence you will use when you do not know something.
Deliverable: A one-page card holding the case structure, the project numbers, and the logistics.
Practice prompt ↗Practice prompt ↗Worked solution ↗Expand any day for tasks and deliverables. Your progress is saved on this device.
Interviewers here are not checking whether you can describe a project. They want the decision you made, why you made it under the information you had, and what changed afterwards that someone else could measure. A story that ends at 'I built a model' has no ending. Say what the model caused, or what you stopped doing because of it.
What is your deepest professional or technical passion, and what steps…
What is your deepest professional or technical passion, and what steps have you taken to actively pursue it?
Approach
- Close with what you would do differently, concretely.
- Quantify the outcome, including what you would not claim credit for.
- Pick a story where you drove the decision, not one where you observed it.
Follow-up
- What would you do differently if you ran that project again?
- How did you know the outcome was caused by your change?
Describe a time when you received harsh or critical feedback on your w…
Describe a time when you received harsh or critical feedback on your work. How did you react and what did you learn?
Approach
- Name the disagreement or constraint, and how you resolved it with evidence.
- State the situation in two sentences and spend the rest on your reasoning.
- Quantify the outcome, including what you would not claim credit for.
Follow-up
- What would you do differently if you ran that project again?
- How did you know the outcome was caused by your change?
Writing an impact statement that survives a hostile reading
Write your own annual impact statement. Your work: a market-impact recalibration the desk adopted in March; a signal you researched that a portfolio manager sized and traded; and a rewrite of the nightly position reconciliation that reduced unreconciled rows in position_daily. Realized implementation shortfall fell from 21 bps to 14 bps after March. Market volatility also fell over the same period. State what you added, in basis points where the attribution supports it, and be explicit about where it does not.
Approach
- What is probed: whether you can separate correlation from contribution when the correlation favours you, which is the one place almost everyone's standards slip.
- Build a counterfactual for the shortfall claim instead of a before-and-after. Shortfall scales with volatility, so a pre and post comparison across a regime change partly measures the market. Use orders that kept the old routing or the old parameters as a control over the same window, matched on participation bucket (order_qty over adv_20d) and side, and report the difference-in-differences rather than the raw 7 bps.
- State the part you cannot claim before anyone asks. The signal was sized by the portfolio manager, so its P and L is a joint product. Claim the research decision itself: what you tested, what you rejected, the number of configurations tried, and the standard error you attached. Volunteering the boundary is what makes the claims inside it credible.
- Give the reconciliation work a number that is not basis points. Report unreconciled and break rows in position_daily before and after, plus the downstream consequence: marks that fell back to stale_prior_day, and client reports restated. Inventing a basis-point figure for operational work costs you the basis-point figures that are real.
- Write a falsifier next to each claim, naming the evidence that would show you added nothing. A reviewer who watches you name your own weakest claim stops auditing the strong ones.
Follow-up
- Your control group is 8 percent of order flow. Is the difference-in-differences credible at that size, and what would you need to make it so?
- The signal lost money this year. Does it appear in the statement, and in what form?
- What did you get wrong this year, and what did it cost?
- 01
What is your deepest professional or technical passion, and what steps have you taken to actively pursue it?
- 02
Describe a time when you received harsh or critical feedback on your work. How did you react and what did you learn?
- 03
Write your own annual impact statement. Your work: a market-impact recalibration the desk adopted in March; a signal you researched that a portfolio manager sized and traded; and a rewrite of the nightly position reconciliation that reduced unreconciled rows in position_daily. Realized implementation shortfall fell from 21 bps to 14 bps after March. Market volatility also fell over the same period. State what you added, in basis points where the attribution supports it, and be explicit about where it does not.
Is this an official Imc interview guide?
No. It is PracHub's own research and practice material for the Data Scientist role at Imc. Rounds and questions reflect what candidates have reported, not a process Imc has published, and they change over time. Confirm the current format and scope with your recruiter.
PracHub interview research ↗How difficult is the IMC Data Scientist interview process?
The process is highly challenging and rated as difficult by most candidates. It requires a strong combination of fast-paced mathematical puzzle-solving, practical coding tests, and deep conceptual knowledge of systematic trading and data engineering.
PracHub interview research ↗What is the online assessment (OA) like?
The OA consists of approximately 15 quantitative, logical, and coding questions that must be completed within 60 minutes. It is designed to test your speed, accuracy, and core mathematical foundations under tight time pressure.
PracHub interview research ↗Do I need a background in finance to apply?
While prior knowledge of financial markets or systematic trading is highly beneficial, it is not a strict requirement. IMC values raw quantitative talent, analytical problem-solving skills, and a strong willingness to learn the complexities of market-making on the job.
PracHub interview research ↗What is the company culture like for Data Scientists?
The culture at IMC is fast-paced, highly collaborative, and meritocratic. However, the trading floor environment can be intense and direct. Successful candidates are those who welcome feedback, communicate transparently, and remain calm under pressure.
PracHub interview research ↗Sources & methodology 3 sources ↗
Official role evidence, timestamped platform data and clearly labeled preparation advice.
- 01PracHub interview research ↗
PracHub editorial research into this company and role, maintained with this guide. Candidate-reported, not an employer publication.
platform · Accessed 2026-09-22 - 02PracHub Data Scientist practice ↗
Cross-company practice questions for this role.
platform · Accessed 2026-09-22 - 03PracHub interview preparation framework ↗
The framework the preparation plan follows.
platform · Accessed 2026-09-22