<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: KX</title>
    <description>The latest articles on DEV Community by KX (@godzilla_dev).</description>
    <link>https://dev.to/godzilla_dev</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4013220%2Fc2b22d7b-7c44-455b-acce-5c00f658e169.jpg</url>
      <title>DEV Community: KX</title>
      <link>https://dev.to/godzilla_dev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/godzilla_dev"/>
    <language>en</language>
    <item>
      <title>godzilla.dev - AI Quant Trader Series - Day 12 - How Matching Engines Work?</title>
      <dc:creator>KX</dc:creator>
      <pubDate>Tue, 21 Jul 2026 13:44:36 +0000</pubDate>
      <link>https://dev.to/godzilla_dev/godzilladev-ai-x-quant-trader-series-day-12-how-matching-engines-work-1j20</link>
      <guid>https://dev.to/godzilla_dev/godzilladev-ai-x-quant-trader-series-day-12-how-matching-engines-work-1j20</guid>
      <description>&lt;p&gt;source: &lt;a href="https://godzilla.dev/learning/ai_quant_traders_series_12/" rel="noopener noreferrer"&gt;https://godzilla.dev/learning/ai_quant_traders_series_12/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;See below for godzilla.dev materials about: AI x Quant Trader Series - Day 12&lt;/p&gt;

&lt;p&gt;How Matching Engines Work&lt;br&gt;
Reading time: ~15 minutes&lt;br&gt;
Prerequisites: What is High Frequency Trading, What is Market Microstructure, What is an Order Book, What is Market Data&lt;br&gt;
Focus: understanding the core engine behind every electronic exchange&lt;/p&gt;

&lt;p&gt;Part 1: Introduction&lt;br&gt;
Every electronic exchange has one component responsible for turning orders into trades.&lt;/p&gt;

&lt;p&gt;The Matching Engine.&lt;/p&gt;

&lt;p&gt;Whether you are trading:&lt;/p&gt;

&lt;p&gt;Stocks&lt;br&gt;
Futures&lt;br&gt;
Options&lt;br&gt;
ETFs&lt;br&gt;
Cryptocurrencies&lt;br&gt;
every submitted order eventually reaches the matching engine.&lt;/p&gt;

&lt;p&gt;Its responsibility is surprisingly simple:&lt;/p&gt;

&lt;p&gt;Receive orders, match buyers with sellers, and update the market.&lt;br&gt;
Despite this simple objective, the matching engine is one of the most performance-critical software systems ever built.&lt;/p&gt;

&lt;p&gt;Modern exchanges process hundreds of thousands—or even millions—of orders every second while maintaining strict fairness and deterministic behavior.&lt;/p&gt;

&lt;p&gt;Part 2: What is a Matching Engine?&lt;br&gt;
A matching engine is the core software component of an electronic exchange.&lt;/p&gt;

&lt;p&gt;It continuously receives:&lt;/p&gt;

&lt;p&gt;New Orders&lt;br&gt;
Cancel Orders&lt;br&gt;
Modify Orders&lt;br&gt;
and determines whether a trade should occur.&lt;/p&gt;

&lt;p&gt;Whenever a compatible buy and sell order exist, the matching engine executes the trade automatically.&lt;/p&gt;

&lt;p&gt;Everything happens electronically.&lt;/p&gt;

&lt;p&gt;There are no human traders approving transactions.&lt;/p&gt;

&lt;p&gt;Part 3: The Matching Process&lt;br&gt;
Suppose the order book currently contains:&lt;/p&gt;

&lt;p&gt;ASK&lt;/p&gt;

&lt;p&gt;101.20    5&lt;/p&gt;

&lt;p&gt;101.10    10&lt;/p&gt;




&lt;p&gt;100.90    8&lt;/p&gt;

&lt;p&gt;100.80    12&lt;/p&gt;

&lt;p&gt;BID&lt;br&gt;
A trader submits:&lt;/p&gt;

&lt;p&gt;Buy&lt;/p&gt;

&lt;p&gt;10&lt;/p&gt;

&lt;p&gt;@&lt;/p&gt;

&lt;p&gt;101.10&lt;br&gt;
The matching engine immediately compares the incoming order against the best available sell orders.&lt;/p&gt;

&lt;p&gt;Buy 10 @ 101.10&lt;/p&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;p&gt;Matches&lt;/p&gt;

&lt;p&gt;Sell 10 @ 101.10&lt;/p&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;p&gt;Trade Executed&lt;br&gt;
The remaining order book is updated automatically.&lt;/p&gt;

&lt;p&gt;This entire process usually completes in microseconds.&lt;/p&gt;

&lt;p&gt;Part 4: Order Types&lt;br&gt;
Matching engines typically support several order types.&lt;/p&gt;

&lt;p&gt;Market Order&lt;br&gt;
Execute immediately.&lt;/p&gt;

&lt;p&gt;The engine consumes the best available liquidity.&lt;/p&gt;

&lt;p&gt;Market Buy&lt;/p&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;p&gt;Execute Now&lt;br&gt;
Limit Order&lt;br&gt;
Execute only if a specified price is available.&lt;/p&gt;

&lt;p&gt;Otherwise, the order rests inside the order book.&lt;/p&gt;

&lt;p&gt;Buy&lt;/p&gt;

&lt;p&gt;100&lt;/p&gt;

&lt;p&gt;@&lt;/p&gt;

&lt;p&gt;99.50&lt;br&gt;
If no seller accepts that price,&lt;/p&gt;

&lt;p&gt;the order simply waits.&lt;/p&gt;

&lt;p&gt;Cancel Order&lt;br&gt;
Removes an existing order from the order book.&lt;/p&gt;

&lt;p&gt;No trade occurs.&lt;/p&gt;

&lt;p&gt;Liquidity decreases.&lt;/p&gt;

&lt;p&gt;Modify Order&lt;br&gt;
Changes the price or quantity of an existing order.&lt;/p&gt;

&lt;p&gt;Many exchanges internally implement this as:&lt;/p&gt;

&lt;p&gt;Cancel&lt;/p&gt;

&lt;p&gt;+&lt;/p&gt;

&lt;p&gt;New Order&lt;br&gt;
Part 5: Price-Time Priority&lt;br&gt;
Most electronic exchanges follow one matching rule.&lt;/p&gt;

&lt;p&gt;Price-Time Priority&lt;/p&gt;

&lt;p&gt;This means:&lt;/p&gt;

&lt;p&gt;Higher bid prices execute first.&lt;/p&gt;

&lt;p&gt;Lower ask prices execute first.&lt;/p&gt;

&lt;p&gt;If multiple orders exist at the same price,&lt;/p&gt;

&lt;p&gt;the earliest submitted order executes first.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;Trader A&lt;/p&gt;

&lt;p&gt;Buy&lt;/p&gt;

&lt;p&gt;100&lt;/p&gt;

&lt;p&gt;09:30:01&lt;/p&gt;

&lt;p&gt;Trader B&lt;/p&gt;

&lt;p&gt;Buy&lt;/p&gt;

&lt;p&gt;100&lt;/p&gt;

&lt;p&gt;09:30:03&lt;br&gt;
Trader A receives priority.&lt;/p&gt;

&lt;p&gt;This rule guarantees fairness and deterministic execution.&lt;/p&gt;

&lt;p&gt;Part 6: Partial Fills&lt;br&gt;
Not every order executes completely.&lt;/p&gt;

&lt;p&gt;Suppose the order book contains:&lt;/p&gt;

&lt;p&gt;Sell&lt;/p&gt;

&lt;p&gt;5&lt;/p&gt;

&lt;p&gt;@&lt;/p&gt;

&lt;p&gt;101&lt;br&gt;
A trader submits:&lt;/p&gt;

&lt;p&gt;Buy&lt;/p&gt;

&lt;p&gt;10&lt;/p&gt;

&lt;p&gt;@&lt;/p&gt;

&lt;p&gt;101&lt;br&gt;
The result becomes:&lt;/p&gt;

&lt;p&gt;Executed&lt;/p&gt;

&lt;p&gt;5&lt;/p&gt;

&lt;p&gt;Remaining&lt;/p&gt;

&lt;p&gt;5&lt;br&gt;
The remaining quantity either:&lt;/p&gt;

&lt;p&gt;waits in the order book&lt;br&gt;
or&lt;/p&gt;

&lt;p&gt;continues matching against higher prices&lt;br&gt;
depending on the order type.&lt;/p&gt;

&lt;p&gt;Part 7: Matching Engine Architecture&lt;br&gt;
A simplified exchange architecture looks like:&lt;/p&gt;

&lt;p&gt;Client&lt;/p&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;p&gt;Gateway&lt;/p&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;p&gt;Risk Checks&lt;/p&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;p&gt;Matching Engine&lt;/p&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;p&gt;Trade&lt;/p&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;p&gt;Market Data Feed&lt;/p&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;p&gt;Participants&lt;br&gt;
Every successful trade generates new market data.&lt;/p&gt;

&lt;p&gt;That market data is immediately distributed back to every participant.&lt;/p&gt;

&lt;p&gt;This feedback loop runs continuously throughout the trading day.&lt;/p&gt;

&lt;p&gt;Part 8: Why Matching Engines Must Be Fast&lt;br&gt;
Imagine an exchange processing:&lt;/p&gt;

&lt;p&gt;2 million&lt;/p&gt;

&lt;p&gt;orders&lt;/p&gt;

&lt;p&gt;per second&lt;br&gt;
The matching engine must:&lt;/p&gt;

&lt;p&gt;Validate orders&lt;br&gt;
Maintain the order book&lt;br&gt;
Match orders&lt;br&gt;
Generate trades&lt;br&gt;
Publish market data&lt;br&gt;
without introducing latency.&lt;/p&gt;

&lt;p&gt;Every additional microsecond affects every market participant.&lt;/p&gt;

&lt;p&gt;This is why matching engines are typically written in:&lt;/p&gt;

&lt;p&gt;C++&lt;br&gt;
Rust&lt;br&gt;
Java (low-latency implementations)&lt;br&gt;
with careful optimization of:&lt;/p&gt;

&lt;p&gt;CPU cache usage&lt;br&gt;
Memory allocation&lt;br&gt;
Lock-free data structures&lt;br&gt;
Network I/O&lt;br&gt;
Part 9: Determinism Is More Important Than Speed&lt;br&gt;
Many beginners believe the fastest matching engine is always the best.&lt;/p&gt;

&lt;p&gt;In reality,&lt;/p&gt;

&lt;p&gt;professional exchanges prioritize:&lt;/p&gt;

&lt;p&gt;Correctness&lt;br&gt;
Fairness&lt;br&gt;
Deterministic execution&lt;br&gt;
A matching engine that occasionally pauses for 10 milliseconds is far more dangerous than one that consistently responds within 50 microseconds.&lt;/p&gt;

&lt;p&gt;Consistency builds trust.&lt;/p&gt;

&lt;p&gt;Determinism builds reliable markets.&lt;/p&gt;

&lt;p&gt;Part 10: Matching Engine vs Trading Engine&lt;br&gt;
These two terms are often confused.&lt;/p&gt;

&lt;p&gt;A Matching Engine belongs to the exchange.&lt;/p&gt;

&lt;p&gt;Its job is to match orders.&lt;/p&gt;

&lt;p&gt;A Trading Engine belongs to the trader.&lt;/p&gt;

&lt;p&gt;Its job is to:&lt;/p&gt;

&lt;p&gt;Receive market data&lt;br&gt;
Generate trading signals&lt;br&gt;
Manage positions&lt;br&gt;
Send orders&lt;br&gt;
The trading engine never decides how orders are matched.&lt;/p&gt;

&lt;p&gt;That responsibility belongs entirely to the exchange.&lt;/p&gt;

&lt;p&gt;Part 11: Where godzilla.dev Fits&lt;br&gt;
Although godzilla.dev is not an exchange,&lt;/p&gt;

&lt;p&gt;many of its architectural principles are inspired by exchange design.&lt;/p&gt;

&lt;p&gt;Professional trading systems require:&lt;/p&gt;

&lt;p&gt;High-performance market data processing&lt;br&gt;
Local order book maintenance&lt;br&gt;
Deterministic event processing&lt;br&gt;
Risk management&lt;br&gt;
Ultra-low latency order routing&lt;br&gt;
These components interact continuously with external matching engines.&lt;/p&gt;

&lt;p&gt;Rather than implementing exchange logic itself, godzilla.dev provides the infrastructure required to build production-grade trading systems capable of interacting with modern electronic markets efficiently.&lt;/p&gt;

&lt;p&gt;Part 12: Key Takeaways&lt;br&gt;
The matching engine is the heart of every electronic exchange.&lt;/p&gt;

&lt;p&gt;It continuously:&lt;/p&gt;

&lt;p&gt;Receives orders&lt;br&gt;
Maintains the order book&lt;br&gt;
Matches buyers and sellers&lt;br&gt;
Executes trades&lt;br&gt;
Publishes market data&lt;br&gt;
Modern financial markets would not exist without highly optimized matching engines.&lt;/p&gt;

&lt;p&gt;Understanding how they operate is essential for anyone building professional quantitative trading systems.&lt;/p&gt;

&lt;p&gt;What's Next?&lt;br&gt;
The next article explores how trading systems communicate with exchanges:&lt;/p&gt;

&lt;p&gt;What is an Exchange Gateway?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>web3</category>
    </item>
    <item>
      <title>godzilla.dev - AI Quant Trader Series - Day 11 - What is Market Data?</title>
      <dc:creator>KX</dc:creator>
      <pubDate>Tue, 14 Jul 2026 14:26:54 +0000</pubDate>
      <link>https://dev.to/godzilla_dev/godzilladev-ai-x-quant-trader-series-day-11-what-is-market-data-32ik</link>
      <guid>https://dev.to/godzilla_dev/godzilladev-ai-x-quant-trader-series-day-11-what-is-market-data-32ik</guid>
      <description>&lt;p&gt;source: &lt;a href="https://godzilla.dev/learning/ai_quant_traders_series_11/" rel="noopener noreferrer"&gt;https://godzilla.dev/learning/ai_quant_traders_series_11/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;See below for godzilla.dev materials about: AI x Quant Trader Series - Day 11&lt;/p&gt;

&lt;p&gt;What is Market Data?¶&lt;br&gt;
Reading time: ~15 minutes&lt;br&gt;
Prerequisites: What is High Frequency Trading, What is Market Microstructure, What is an Order Book&lt;br&gt;
Focus: understanding the data flowing through modern electronic trading systems&lt;/p&gt;

&lt;p&gt;Part 1: Introduction¶&lt;br&gt;
Every quantitative trading system begins with one thing.&lt;/p&gt;

&lt;p&gt;Market Data.&lt;/p&gt;

&lt;p&gt;Before a strategy can decide whether to buy or sell, it must first understand the current state of the market.&lt;/p&gt;

&lt;p&gt;That information comes from market data.&lt;/p&gt;

&lt;p&gt;Whether you are trading:&lt;/p&gt;

&lt;p&gt;Stocks&lt;br&gt;
Futures&lt;br&gt;
Options&lt;br&gt;
ETFs&lt;br&gt;
Cryptocurrencies&lt;br&gt;
every trading decision ultimately depends on a continuous stream of market events.&lt;/p&gt;

&lt;p&gt;For High Frequency Trading, market data is not just information.&lt;/p&gt;

&lt;p&gt;It is the raw material from which every trading opportunity is created.&lt;/p&gt;

&lt;p&gt;Part 2: What is Market Data?¶&lt;br&gt;
Market Data is the real-time information published by an exchange describing everything happening in the market.&lt;/p&gt;

&lt;p&gt;Typical market data includes:&lt;/p&gt;

&lt;p&gt;Best Bid&lt;br&gt;
Best Ask&lt;br&gt;
Trade Price&lt;br&gt;
Trade Size&lt;br&gt;
Order Book Updates&lt;br&gt;
Volume&lt;br&gt;
Market Status&lt;br&gt;
Instrument Information&lt;br&gt;
Every update represents a new event occurring inside the exchange.&lt;/p&gt;

&lt;p&gt;Unlike historical datasets, market data never stops arriving.&lt;/p&gt;

&lt;p&gt;It is an infinite stream of events.&lt;/p&gt;

&lt;p&gt;Part 3: Types of Market Data¶&lt;br&gt;
Modern exchanges usually provide several categories of market data.&lt;/p&gt;

&lt;p&gt;Trade Data¶&lt;br&gt;
Trade data records completed transactions.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;Price: 101.20&lt;/p&gt;

&lt;p&gt;Quantity: 5 BTC&lt;/p&gt;

&lt;p&gt;Time: 09:30:15.123456&lt;br&gt;
Trade data answers one question:&lt;/p&gt;

&lt;p&gt;What actually traded?&lt;br&gt;
Quote Data¶&lt;br&gt;
Quote data describes the current market.&lt;/p&gt;

&lt;p&gt;Typical information includes:&lt;/p&gt;

&lt;p&gt;Best Bid&lt;br&gt;
Bid Size&lt;br&gt;
Best Ask&lt;br&gt;
Ask Size&lt;br&gt;
Example:&lt;/p&gt;

&lt;p&gt;Bid&lt;/p&gt;

&lt;p&gt;101.18&lt;/p&gt;

&lt;p&gt;Size 25&lt;/p&gt;

&lt;p&gt;Ask&lt;/p&gt;

&lt;p&gt;101.20&lt;/p&gt;

&lt;p&gt;Size 40&lt;br&gt;
Most execution algorithms continuously monitor quote updates.&lt;/p&gt;

&lt;p&gt;Order Book Data¶&lt;br&gt;
Rather than publishing only the best prices,&lt;/p&gt;

&lt;p&gt;many exchanges provide multiple price levels.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;Ask&lt;/p&gt;

&lt;p&gt;101.30&lt;/p&gt;

&lt;p&gt;101.20&lt;/p&gt;

&lt;p&gt;101.10&lt;/p&gt;




&lt;p&gt;100.90&lt;/p&gt;

&lt;p&gt;100.80&lt;/p&gt;

&lt;p&gt;100.70&lt;/p&gt;

&lt;p&gt;Bid&lt;br&gt;
This information allows trading systems to reconstruct the entire local order book.&lt;/p&gt;

&lt;p&gt;Part 4: Snapshot vs Incremental Updates¶&lt;br&gt;
Exchanges generally publish market data in two formats.&lt;/p&gt;

&lt;p&gt;Snapshot¶&lt;br&gt;
A snapshot contains the complete market state.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;Entire Order Book&lt;/p&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;p&gt;One Message&lt;br&gt;
Snapshots are simple but expensive to transmit frequently.&lt;/p&gt;

&lt;p&gt;Incremental Updates¶&lt;br&gt;
Incremental updates publish only changes.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;Before&lt;/p&gt;

&lt;p&gt;101.20&lt;/p&gt;

&lt;p&gt;Size 30&lt;/p&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;p&gt;Update&lt;/p&gt;

&lt;p&gt;Size 18&lt;br&gt;
Only the modified information is transmitted.&lt;/p&gt;

&lt;p&gt;Nearly every modern HFT platform relies primarily on incremental updates because they minimize bandwidth and latency.&lt;/p&gt;

&lt;p&gt;Part 5: Market Data Feed¶&lt;br&gt;
Exchanges distribute market data through specialized data feeds.&lt;/p&gt;

&lt;p&gt;A simplified architecture looks like:&lt;/p&gt;

&lt;p&gt;Exchange&lt;/p&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;p&gt;Market Data Feed&lt;/p&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;p&gt;Decoder&lt;/p&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;p&gt;Local Order Book&lt;/p&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;p&gt;Trading Strategy&lt;br&gt;
The market data feed is responsible for delivering every market event to participants as quickly as possible.&lt;/p&gt;

&lt;p&gt;For High Frequency Trading,&lt;/p&gt;

&lt;p&gt;the market data feed is often the most latency-sensitive component of the entire system.&lt;/p&gt;

&lt;p&gt;Part 6: Why Latency Matters¶&lt;br&gt;
Imagine two trading firms receive the same market update.&lt;/p&gt;

&lt;p&gt;Firm A processes the update in:&lt;/p&gt;

&lt;p&gt;8 μs&lt;br&gt;
Firm B processes it in:&lt;/p&gt;

&lt;p&gt;120 μs&lt;br&gt;
Both firms observe the same opportunity.&lt;/p&gt;

&lt;p&gt;Only one is likely to execute first.&lt;/p&gt;

&lt;p&gt;This is why HFT engineers spend enormous effort optimizing:&lt;/p&gt;

&lt;p&gt;Message parsing&lt;br&gt;
Memory allocation&lt;br&gt;
Cache locality&lt;br&gt;
Lock-free queues&lt;br&gt;
Network I/O&lt;br&gt;
Every microsecond matters.&lt;/p&gt;

&lt;p&gt;Part 7: Market Data Processing¶&lt;br&gt;
Receiving market data is only the beginning.&lt;/p&gt;

&lt;p&gt;A production trading system must also:&lt;/p&gt;

&lt;p&gt;Decode exchange protocols&lt;br&gt;
Validate messages&lt;br&gt;
Handle sequence numbers&lt;br&gt;
Detect packet loss&lt;br&gt;
Recover missing data&lt;br&gt;
Maintain synchronization&lt;br&gt;
Update the local order book&lt;br&gt;
These operations occur continuously throughout the trading day.&lt;/p&gt;

&lt;p&gt;For active markets, this may involve millions of messages every second.&lt;/p&gt;

&lt;p&gt;Part 8: Local Market Data¶&lt;br&gt;
Professional trading systems rarely query the exchange whenever market information is needed.&lt;/p&gt;

&lt;p&gt;Instead, they maintain an in-memory representation of the market.&lt;/p&gt;

&lt;p&gt;Exchange&lt;/p&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;p&gt;Market Data Feed&lt;/p&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;p&gt;Incremental Updates&lt;/p&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;p&gt;Local Memory&lt;/p&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;p&gt;Trading Strategy&lt;br&gt;
Strategies then read data directly from memory.&lt;/p&gt;

&lt;p&gt;This architecture eliminates unnecessary network latency and dramatically improves performance.&lt;/p&gt;

&lt;p&gt;Part 9: Market Data in High Frequency Trading¶&lt;br&gt;
For long-term investors,&lt;/p&gt;

&lt;p&gt;market data is simply information.&lt;/p&gt;

&lt;p&gt;For HFT systems,&lt;/p&gt;

&lt;p&gt;market data is an event stream.&lt;/p&gt;

&lt;p&gt;Strategies react to:&lt;/p&gt;

&lt;p&gt;New trades&lt;br&gt;
Quote changes&lt;br&gt;
Order book updates&lt;br&gt;
Liquidity changes&lt;br&gt;
Spread changes&lt;br&gt;
Market imbalance&lt;br&gt;
Many HFT strategies process thousands of events before placing a single order.&lt;/p&gt;

&lt;p&gt;Understanding event flow is often more important than predicting future prices.&lt;/p&gt;

&lt;p&gt;Part 10: Where godzilla.dev Fits¶&lt;br&gt;
Efficient market data processing is one of the foundations of every ultra-low latency trading platform.&lt;/p&gt;

&lt;p&gt;A production implementation must:&lt;/p&gt;

&lt;p&gt;Decode exchange messages&lt;br&gt;
Process incremental updates&lt;br&gt;
Maintain local market state&lt;br&gt;
Synchronize order books&lt;br&gt;
Distribute events across multiple strategies&lt;br&gt;
Minimize memory copies&lt;br&gt;
Maintain deterministic latency&lt;br&gt;
These requirements define much of the architecture behind godzilla.dev.&lt;/p&gt;

&lt;p&gt;Rather than rebuilding market data infrastructure for every project, developers can focus on strategy research while relying on a modular, high-performance framework designed for modern electronic markets.&lt;/p&gt;

&lt;p&gt;Part 11: Key Takeaways¶&lt;br&gt;
Market Data is the real-time information published by exchanges describing market activity.&lt;/p&gt;

&lt;p&gt;It includes:&lt;/p&gt;

&lt;p&gt;Trades&lt;br&gt;
Quotes&lt;br&gt;
Order Book Updates&lt;br&gt;
Market Status&lt;br&gt;
Instrument Information&lt;br&gt;
Professional trading systems transform this continuous stream of events into an in-memory representation of the market, allowing strategies to react with minimal latency.&lt;/p&gt;

&lt;p&gt;Understanding market data is the first step toward building production-grade trading infrastructure.&lt;/p&gt;

&lt;p&gt;What's Next?¶&lt;br&gt;
The next article explores the component responsible for turning incoming orders into completed trades:&lt;/p&gt;

&lt;p&gt;How Matching Engines Work&lt;/p&gt;

</description>
      <category>ai</category>
      <category>web3</category>
    </item>
    <item>
      <title>That 300% funding APR is not free money: screening for squeeze traps on Binance perpetuals</title>
      <dc:creator>KX</dc:creator>
      <pubDate>Wed, 08 Jul 2026 07:14:56 +0000</pubDate>
      <link>https://dev.to/godzilla_dev/that-300-funding-apr-is-not-free-money-screening-for-squeeze-traps-on-binance-perpetuals-a1o</link>
      <guid>https://dev.to/godzilla_dev/that-300-funding-apr-is-not-free-money-screening-for-squeeze-traps-on-binance-perpetuals-a1o</guid>
      <description>&lt;p&gt;In late December 2023, TRB went from around $200 to over $600 in a single session on Binance, then collapsed just as fast. Hundreds of millions in short positions were liquidated on the way up. In the days before the move, TRB's perpetual had been flashing exactly the kind of numbers that make a funding rate arbitrageur's eyes light up: deeply skewed funding, fat annualized carry, seemingly free money for anyone willing to take the other side.&lt;/p&gt;

&lt;p&gt;Anyone who took that carry trade got carried out.&lt;/p&gt;

&lt;p&gt;This post is about the screening layer I run &lt;em&gt;before&lt;/em&gt; any funding rate position goes on: a Python script that scores every USDT perpetual on Binance against five structural risk signals, using only public endpoints. No API keys, no paid data. The full script is at the end; the interesting part is &lt;em&gt;why&lt;/em&gt; each signal works.&lt;/p&gt;

&lt;h2&gt;
  
  
  The trap, mechanically
&lt;/h2&gt;

&lt;p&gt;The standard funding rate arbitrage is delta-neutral on paper. Funding is printing high positive? Short the perp, buy spot, collect the payments. Deeply negative? Long the perp, hedge with a spot short. Price risk cancels, funding accrues. In liquid majors this is a boring, capacity-constrained, mostly honest trade.&lt;/p&gt;

&lt;p&gt;In a low-float token it can be bait.&lt;/p&gt;

&lt;p&gt;Here is the failure mode. A token has a small circulating supply, and a large share of that float sits with a few wallets. Extreme funding appears — often &lt;em&gt;because&lt;/em&gt; positioning is already crowded on one side. Carry traders pile in, shorting the perp against spot. Then the float holders push the spot price, hard. Three things break at once:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The perp leg gets margin-called before the hedge helps you.&lt;/strong&gt; Your spot leg is profitable, but it's sitting in a wallet; your perp short is sitting on an exchange with leverage, being marked against a price that someone else controls. Liquidation doesn't wait for your rebalancing script.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The basis blows out.&lt;/strong&gt; Perp and spot are supposed to converge via funding. During a squeeze the perp can trade at absurd premiums for hours. "Delta-neutral" assumes the two legs move together; in the tail they don't.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The exit is a door one person wide.&lt;/strong&gt; Thin spot books mean unwinding the hedge leg costs you a chunk of the carry you came for — if you can unwind at all.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The nasty part: the trade &lt;em&gt;looks&lt;/em&gt; most attractive exactly when it is most dangerous. Extreme funding is both the lure and the symptom. So the job of a screener is not to find high funding — that's one API call — but to answer a different question: &lt;strong&gt;is this a market where the other side can hurt me on purpose?&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Five signals
&lt;/h2&gt;

&lt;p&gt;The screener scores each perpetual on five structural signals. Each one has a "warning" and a "danger" threshold; warning adds 1 point, danger adds 2. The thresholds come from going back over historical squeeze events and asking what the market looked like &lt;em&gt;before&lt;/em&gt; the candle.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Open interest vs. circulating market cap
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;oi_mcap_ratio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;open_interest_notional&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;circulating_market_cap&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the single most informative number. If the notional value of open perpetual contracts exceeds half the circulating market cap of the underlying token, the derivative tail is wagging the spot dog. Above 1.0 — more paper exposure than actual float value — a determined actor doesn't need to fight the market to move the mark price; the market is smaller than the bet on it.&lt;/p&gt;

&lt;p&gt;Warning above 0.5, danger above 1.0. For reference, majors like BTC and ETH sit far below these levels; the tokens that end up in squeeze post-mortems almost always screened hot here first.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Perp-to-spot volume ratio
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;perp_spot_ratio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;perp_volume_24h&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;spot_volume_24h&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Healthy markets discover price on spot and lever it on derivatives. When 24h perp volume runs 15–40x spot volume, price discovery has effectively moved to the perp, and the spot print — the thing your hedge depends on, and often the input to the mark price — is thin enough to be pushed cheaply. Warning above 15, danger above 40.&lt;/p&gt;

&lt;p&gt;There's an important edge case here, covered below: tokens whose perp trades on Binance but whose spot &lt;em&gt;doesn't&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Funding rate extremity
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;funding_apr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;last_funding_rate&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;365&lt;/span&gt;   &lt;span class="c1"&gt;# 8h funding, annualized
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Annualized funding above 100% is a warning; above 300% is danger territory. Not because the carry isn't real — it is, for as long as it lasts — but because triple-digit APRs don't survive in efficient markets. If the number looks like a DeFi farm from 2021, someone is being paid that much to hold a position nobody sane wants, and you should ask why the other side is this desperate.&lt;/p&gt;

&lt;p&gt;Note the &lt;code&gt;abs()&lt;/code&gt;: deeply negative funding is scored the same as deeply positive. Squeezes come in both directions.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Listing age
&lt;/h3&gt;

&lt;p&gt;Contracts live for under 60 days score danger; under 180, warning. New listings combine every risk factor: no funding history to judge what "normal" looks like, concentrated early float, immature spot liquidity, and maximum attention from exactly the kind of trader who runs squeezes. A disproportionate share of historical trap events happened within the first two quarters of a perp's life.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Circulating market cap, absolute
&lt;/h3&gt;

&lt;p&gt;Below $100M warning, below $30M danger. Small caps aren't automatically manipulated, but manipulation is a fixed-cost business — the smaller the float, the cheaper the squeeze. This signal overlaps with signal 1 by construction, and that's intentional: a token that trips both is small &lt;em&gt;and&lt;/em&gt; over-levered, which is the full trap setup.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bonus signal: no market cap data at all
&lt;/h3&gt;

&lt;p&gt;If a token's perp trades on Binance but the token doesn't rank in CoinGecko's top ~2000 by market cap, the screener can't compute signals 1 and 5 — and that absence is itself worth a point. A perpetual contract on an asset too small or too new to have reliable supply data is not where a delta-neutral strategy goes to earn a quiet carry.&lt;/p&gt;

&lt;h2&gt;
  
  
  The unglamorous parts (where the bugs live)
&lt;/h2&gt;

&lt;p&gt;Three implementation details caused more trouble than the actual scoring logic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Symbol collision on CoinGecko.&lt;/strong&gt; Matching Binance base assets to CoinGecko entries by ticker symbol is a minefield — ticker symbols aren't unique, and a $20M token can share a symbol with a $2B one. The screener pulls CoinGecko's markets endpoint ordered by market cap descending and keeps the &lt;em&gt;first&lt;/em&gt; (largest) match per symbol:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;sym&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;symbol&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;sym&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;wanted&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;market_cap&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# on symbol collision, keep the highest-mcap match
&lt;/span&gt;        &lt;span class="n"&gt;mcap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setdefault&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sym&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;market_cap&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This biases toward &lt;em&gt;under&lt;/em&gt;-flagging (you might attribute a big token's mcap to a small impostor and miss a trap), which is the conservative direction for a screener whose job is to justify a "no" — but know the limitation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The 1000x prefix.&lt;/strong&gt; Binance lists some low-price tokens as &lt;code&gt;1000PEPE&lt;/code&gt;, &lt;code&gt;1000SHIB&lt;/code&gt; etc. — the contract multiplies the price by 1000. For market cap lookups the prefix has to be stripped:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;cg_base&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;:]&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startswith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1000&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Miss this and every 1000-prefixed contract silently gets zero market cap and a spurious flag.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Orphan perps.&lt;/strong&gt; Some perpetuals trade on Binance futures with &lt;em&gt;no corresponding Binance spot pair at all&lt;/em&gt;. For these, the perp/spot ratio is set to infinity rather than skipped:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;spot_vol&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;perp_spot_ratio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;perp_vol&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;spot_vol&lt;/span&gt;
&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;perp_vol&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;perp_spot_ratio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;inf&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# perp exists, spot doesn't
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A perp whose hedge leg would have to live on a &lt;em&gt;different exchange&lt;/em&gt; is a materially worse trade — cross-exchange transfer time is exactly the window in which a squeeze kills you. Infinity, not N/A.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scoring and output
&lt;/h2&gt;

&lt;p&gt;The scoring function is deliberately dumb — transparent beats clever in a risk filter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;score_row&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cond_hi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cond_mid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;cond_hi&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
            &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;!!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;cond_mid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
            &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;oi_mcap_ratio&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;oi_mcap_ratio&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;OI/MCAP&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;perp_spot_ratio&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;perp_spot_ratio&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PERP/SPOT&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;abs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;funding_apr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mf"&gt;3.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;abs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;funding_apr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;EXTREME_FUNDING&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;listing_days&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;listing_days&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;180&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;NEW_LISTING&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mcap&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mf"&gt;3e7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;3e7&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mcap&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mf"&gt;1e8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MICRO_CAP&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mcap&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;NO_MCAP_DATA&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Maximum score is 11. In practice I treat the bands roughly as: &lt;strong&gt;0–1&lt;/strong&gt; normal market, size the carry trade on its own merits; &lt;strong&gt;2–3&lt;/strong&gt; proceed with reduced size and tighter liquidation buffers; &lt;strong&gt;4+&lt;/strong&gt; the funding is not the opportunity, it's the advertisement. The point of a screener is to make "no" cheap.&lt;/p&gt;

&lt;p&gt;Running it takes about a minute for the full universe (the per-symbol open interest endpoint is the bottleneck; a small thread pool keeps it tolerable, and CoinGecko's free tier wants a 1.2s pause between pages):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ python trap_screener.py --min-score 3
Fetching contract list...
530 perpetuals, fetching tickers...
Fetching market caps (CoinGecko)...
Fetching open interest...

CONTRACT         RISK  MCAP($M)  OI/MCAP    P/S  FUND APR  AGE(d)  FLAGS
------------------------------------------------------------------------
SLXUSDT             6      45.8     0.18    inf     -113%      37  PERP/SPOT!!,EXTREME_FUNDING,NEW_LISTING!!,MICRO_CAP
DATAIPUSDT          6       0.0     0.00    inf     -104%       5  PERP/SPOT!!,EXTREME_FUNDING,NEW_LISTING!!,NO_MCAP_DATA
EVAAUSDT            6      20.4     1.82    inf       40%     277  OI/MCAP!!,PERP/SPOT!!,MICRO_CAP!!
STARUSDT            6      27.3     0.05    inf        5%      55  PERP/SPOT!!,NEW_LISTING!!,MICRO_CAP!!
CTRUSDT             6      12.9     0.08    inf        5%      40  PERP/SPOT!!,NEW_LISTING!!,MICRO_CAP!!
GWEIUSDT            5     202.4     0.06    inf     -314%     160  PERP/SPOT!!,EXTREME_FUNDING!!,NEW_LISTING
ARXUSDT             5      38.4     0.08    inf      -49%      15  PERP/SPOT!!,NEW_LISTING!!,MICRO_CAP
BIRBUSDT            5      17.0     0.10    inf       -8%     160  PERP/SPOT!!,NEW_LISTING,MICRO_CAP!!
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What this doesn't catch
&lt;/h2&gt;

&lt;p&gt;Honesty section. The screener reads market structure; it cannot see intent. It won't catch a coordinated squeeze on a mid-cap with healthy-looking ratios, an exchange listing announcement that turns structure upside down in an hour, or unlock-schedule cliffs (that data lives elsewhere and is worth adding). It also scores a snapshot — a token can screen clean at noon and be a trap by dinner. This is a pre-trade filter, not a substitute for position-level risk management: liquidation buffers, basis monitoring, and an exit plan sized to actual spot depth.&lt;/p&gt;

&lt;p&gt;The full script (~200 lines, &lt;code&gt;requests&lt;/code&gt; is the only dependency) is here: &lt;strong&gt;&lt;a href="https://github.com/godzilla-foundation/godzilla-community/blob/main/strategies/trap_screener/trap_screener.py" rel="noopener noreferrer"&gt;https://github.com/godzilla-foundation/godzilla-community/blob/main/strategies/trap_screener/trap_screener.py&lt;/a&gt;&lt;/strong&gt;. Run it, argue with the thresholds, send patches.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I maintain &lt;a href="https://godzilla.dev" rel="noopener noreferrer"&gt;godzilla.dev&lt;/a&gt;, an open-source C++/Python framework for self-hosted funding rate arbitrage and market making. The screener in this post is the research side of the problem; execution — actually running the delta-neutral legs with microsecond-level latency without becoming the exit liquidity — is a different one.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>cryptocurrency</category>
      <category>algorithms</category>
    </item>
    <item>
      <title>godzilla.dev - AI Quant Trader Series - Day 10 - What is an Order Book?</title>
      <dc:creator>KX</dc:creator>
      <pubDate>Tue, 07 Jul 2026 13:30:11 +0000</pubDate>
      <link>https://dev.to/godzilla_dev/godzilladev-ai-x-quant-trader-series-day-10-what-is-an-order-book-45ab</link>
      <guid>https://dev.to/godzilla_dev/godzilladev-ai-x-quant-trader-series-day-10-what-is-an-order-book-45ab</guid>
      <description>&lt;p&gt;source: &lt;a href="https://godzilla.dev/learning/ai_quant_traders_series_10/" rel="noopener noreferrer"&gt;https://godzilla.dev/learning/ai_quant_traders_series_10/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;See below for godzilla.dev materials about: AI x Quant Trader Series - Day 10&lt;/p&gt;

&lt;p&gt;What is an Order Book?¶&lt;br&gt;
Reading time: ~15 minutes&lt;br&gt;
Prerequisites: What is High Frequency Trading, What is Market Microstructure&lt;br&gt;
Focus: understanding the core data structure behind every electronic exchange&lt;/p&gt;

&lt;p&gt;Part 1: Introduction¶&lt;br&gt;
Every electronic exchange has one central component.&lt;/p&gt;

&lt;p&gt;The Order Book.&lt;/p&gt;

&lt;p&gt;Whether you are trading:&lt;/p&gt;

&lt;p&gt;Stocks&lt;br&gt;
Futures&lt;br&gt;
Options&lt;br&gt;
ETFs&lt;br&gt;
Cryptocurrencies&lt;br&gt;
every trade begins and ends with the order book.&lt;/p&gt;

&lt;p&gt;For quantitative developers, the order book is more than market data.&lt;/p&gt;

&lt;p&gt;It is the primary data structure that determines:&lt;/p&gt;

&lt;p&gt;Liquidity&lt;br&gt;
Price formation&lt;br&gt;
Execution priority&lt;br&gt;
Market depth&lt;br&gt;
Trading opportunities&lt;br&gt;
Without understanding the order book, it is impossible to understand modern electronic markets.&lt;/p&gt;

&lt;p&gt;Part 2: What is an Order Book?¶&lt;br&gt;
An order book is a real-time collection of all active buy and sell orders submitted to an exchange.&lt;/p&gt;

&lt;p&gt;It continuously records:&lt;/p&gt;

&lt;p&gt;Buy orders (Bids)&lt;br&gt;
Sell orders (Asks)&lt;br&gt;
Prices&lt;br&gt;
Quantities&lt;br&gt;
As orders arrive, are canceled, or are executed, the order book updates immediately.&lt;/p&gt;

&lt;p&gt;Unlike historical price charts, the order book represents the current state of market supply and demand.&lt;/p&gt;

&lt;p&gt;Part 3: A Simple Order Book¶&lt;br&gt;
A simplified order book might look like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        ASK
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Price      Size&lt;/p&gt;

&lt;p&gt;101.30      25&lt;/p&gt;

&lt;p&gt;101.20      40&lt;/p&gt;

&lt;p&gt;101.10      15&lt;/p&gt;




&lt;p&gt;101.00&lt;/p&gt;




&lt;p&gt;100.90      18&lt;/p&gt;

&lt;p&gt;100.80      35&lt;/p&gt;

&lt;p&gt;100.70      12&lt;/p&gt;

&lt;p&gt;Price      Size&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        BID
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The highest buying price is called the Best Bid.&lt;/p&gt;

&lt;p&gt;The lowest selling price is called the Best Ask.&lt;/p&gt;

&lt;p&gt;Together they define the current market.&lt;/p&gt;

&lt;p&gt;Part 4: Bid, Ask and Spread¶&lt;br&gt;
Suppose the market looks like:&lt;/p&gt;

&lt;p&gt;Best Ask = 101.10&lt;/p&gt;

&lt;p&gt;Best Bid = 100.90&lt;br&gt;
The difference is:&lt;/p&gt;

&lt;p&gt;Spread = 0.20&lt;br&gt;
The bid-ask spread represents the immediate cost of trading.&lt;/p&gt;

&lt;p&gt;Smaller spreads usually indicate:&lt;/p&gt;

&lt;p&gt;Higher liquidity&lt;br&gt;
Lower transaction costs&lt;br&gt;
More active markets&lt;br&gt;
Large spreads often signal uncertainty or low liquidity.&lt;/p&gt;

&lt;p&gt;Many quantitative strategies continuously monitor spread changes.&lt;/p&gt;

&lt;p&gt;Part 5: Order Book Updates¶&lt;br&gt;
The order book changes whenever one of three events occurs.&lt;/p&gt;

&lt;p&gt;New Order¶&lt;br&gt;
A participant submits a new buy or sell order.&lt;/p&gt;

&lt;p&gt;BUY&lt;/p&gt;

&lt;p&gt;100.95&lt;/p&gt;

&lt;p&gt;Size 30&lt;br&gt;
The order is inserted into the appropriate price level.&lt;/p&gt;

&lt;p&gt;Cancel Order¶&lt;br&gt;
An existing order is removed.&lt;/p&gt;

&lt;p&gt;Liquidity decreases.&lt;/p&gt;

&lt;p&gt;The market depth changes.&lt;/p&gt;

&lt;p&gt;Trade Execution¶&lt;br&gt;
A buy order matches a sell order.&lt;/p&gt;

&lt;p&gt;Both orders disappear (fully or partially).&lt;/p&gt;

&lt;p&gt;The traded price becomes the latest transaction price.&lt;/p&gt;

&lt;p&gt;These three event types generate almost every message published by an electronic exchange.&lt;/p&gt;

&lt;p&gt;Part 6: Market Orders vs Limit Orders¶&lt;br&gt;
The order book primarily stores limit orders.&lt;/p&gt;

&lt;p&gt;Limit Order¶&lt;br&gt;
A trader specifies:&lt;/p&gt;

&lt;p&gt;Price&lt;br&gt;
Quantity&lt;br&gt;
Example:&lt;/p&gt;

&lt;p&gt;Buy&lt;/p&gt;

&lt;p&gt;10 BTC&lt;/p&gt;

&lt;p&gt;at&lt;/p&gt;

&lt;p&gt;100,000 USD&lt;br&gt;
The order waits until a seller accepts that price.&lt;/p&gt;

&lt;p&gt;Market Order¶&lt;br&gt;
A market order specifies only quantity.&lt;/p&gt;

&lt;p&gt;The exchange immediately executes against the best available prices in the order book.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;Market Buy&lt;/p&gt;

&lt;p&gt;20 BTC&lt;br&gt;
The exchange consumes liquidity from multiple ask levels until the requested quantity is filled.&lt;/p&gt;

&lt;p&gt;Part 7: Market Depth¶&lt;br&gt;
An order book contains more than just the best bid and ask.&lt;/p&gt;

&lt;p&gt;It also reveals market depth.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;Ask&lt;/p&gt;

&lt;p&gt;101.10   10&lt;/p&gt;

&lt;p&gt;101.20   25&lt;/p&gt;

&lt;p&gt;101.30   80&lt;/p&gt;

&lt;p&gt;101.40   200&lt;br&gt;
Large resting orders often influence market behavior.&lt;/p&gt;

&lt;p&gt;Some quantitative strategies analyze:&lt;/p&gt;

&lt;p&gt;Depth imbalance&lt;br&gt;
Queue size&lt;br&gt;
Liquidity concentration&lt;br&gt;
to predict short-term price movement.&lt;/p&gt;

&lt;p&gt;Part 8: Price-Time Priority¶&lt;br&gt;
Most exchanges use Price-Time Priority.&lt;/p&gt;

&lt;p&gt;This means:&lt;/p&gt;

&lt;p&gt;Higher prices execute first.&lt;/p&gt;

&lt;p&gt;If multiple orders exist at the same price,&lt;/p&gt;

&lt;p&gt;the earliest order executes first.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;Trader A&lt;/p&gt;

&lt;p&gt;Buy&lt;/p&gt;

&lt;p&gt;100.00&lt;/p&gt;

&lt;p&gt;09:30:01&lt;/p&gt;

&lt;p&gt;Trader B&lt;/p&gt;

&lt;p&gt;Buy&lt;/p&gt;

&lt;p&gt;100.00&lt;/p&gt;

&lt;p&gt;09:30:05&lt;br&gt;
Trader A receives execution before Trader B.&lt;/p&gt;

&lt;p&gt;Queue position therefore becomes an important competitive advantage in High Frequency Trading.&lt;/p&gt;

&lt;p&gt;Part 9: Why the Order Book Matters¶&lt;br&gt;
Traditional investors mostly observe:&lt;/p&gt;

&lt;p&gt;Daily candles&lt;br&gt;
Moving averages&lt;br&gt;
Volume&lt;br&gt;
Quantitative traders often observe:&lt;/p&gt;

&lt;p&gt;Best Bid&lt;br&gt;
Best Ask&lt;br&gt;
Queue imbalance&lt;br&gt;
Order flow&lt;br&gt;
Market depth&lt;br&gt;
Trade aggressiveness&lt;br&gt;
These microstructure signals often contain far more information than historical prices alone.&lt;/p&gt;

&lt;p&gt;Many HFT strategies never use traditional technical indicators.&lt;/p&gt;

&lt;p&gt;Instead, they react directly to order book events.&lt;/p&gt;

&lt;p&gt;Part 10: Local Order Books¶&lt;br&gt;
Professional trading systems rarely query the exchange every time they need market information.&lt;/p&gt;

&lt;p&gt;Instead, they maintain a local order book.&lt;/p&gt;

&lt;p&gt;The process is straightforward:&lt;/p&gt;

&lt;p&gt;Exchange&lt;/p&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;p&gt;Market Data Feed&lt;/p&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;p&gt;Incremental Updates&lt;/p&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;p&gt;Local Order Book&lt;/p&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;p&gt;Trading Strategy&lt;br&gt;
Maintaining a synchronized local order book dramatically reduces latency and enables strategies to process market events without additional network requests.&lt;/p&gt;

&lt;p&gt;Almost every production HFT platform relies on this architecture.&lt;/p&gt;

&lt;p&gt;Part 11: Where godzilla.dev Fits¶&lt;br&gt;
Maintaining an accurate local order book is one of the most performance-critical components of a trading system.&lt;/p&gt;

&lt;p&gt;A production implementation must:&lt;/p&gt;

&lt;p&gt;Decode market data&lt;br&gt;
Process millions of updates&lt;br&gt;
Maintain price levels&lt;br&gt;
Handle incremental messages&lt;br&gt;
Synchronize state&lt;br&gt;
Minimize latency&lt;br&gt;
godzilla.dev provides the infrastructure required to build ultra-low latency trading systems capable of processing order book updates efficiently while exposing a clean interface for quantitative strategy development.&lt;/p&gt;

&lt;p&gt;Instead of rebuilding market data infrastructure, developers can focus on designing trading strategies.&lt;/p&gt;

&lt;p&gt;Part 12: Key Takeaways¶&lt;br&gt;
The order book is the central data structure of every electronic exchange.&lt;/p&gt;

&lt;p&gt;It continuously records:&lt;/p&gt;

&lt;p&gt;Buy orders&lt;br&gt;
Sell orders&lt;br&gt;
Available liquidity&lt;br&gt;
Market depth&lt;br&gt;
Execution priority&lt;br&gt;
Understanding the order book is essential for:&lt;/p&gt;

&lt;p&gt;High Frequency Trading&lt;br&gt;
Market Making&lt;br&gt;
Execution Algorithms&lt;br&gt;
Statistical Arbitrage&lt;br&gt;
Every market event ultimately becomes an order book update.&lt;/p&gt;

&lt;p&gt;What's Next?¶&lt;br&gt;
The next article explores the engine responsible for processing every order submitted to the market:&lt;/p&gt;

&lt;p&gt;What is a Matching Engine?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>web3</category>
    </item>
    <item>
      <title>godzilla.dev - AI Quant Trader Series - Day 9 - What is Market Microstructure?</title>
      <dc:creator>KX</dc:creator>
      <pubDate>Mon, 06 Jul 2026 07:31:39 +0000</pubDate>
      <link>https://dev.to/godzilla_dev/godzilladev-ai-x-quant-trader-series-day-9-what-is-market-microstructure-1i1l</link>
      <guid>https://dev.to/godzilla_dev/godzilladev-ai-x-quant-trader-series-day-9-what-is-market-microstructure-1i1l</guid>
      <description>&lt;p&gt;source: &lt;a href="https://godzilla.dev/learning/ai_quant_traders_series_9/" rel="noopener noreferrer"&gt;https://godzilla.dev/learning/ai_quant_traders_series_9/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;See below for godzilla.dev materials about: AI x Quant Trader Series - Day 9&lt;/p&gt;

&lt;p&gt;What is Market Microstructure?¶&lt;br&gt;
Reading time: ~15 minutes&lt;br&gt;
Prerequisites: basic financial markets, programming fundamentals&lt;br&gt;
Focus: understanding how electronic markets actually work&lt;/p&gt;

&lt;p&gt;Part 1: Introduction¶&lt;br&gt;
Most people think financial markets are simply places where buyers meet sellers.&lt;/p&gt;

&lt;p&gt;For quantitative traders, this description is far too simplistic.&lt;/p&gt;

&lt;p&gt;Every trade, every quote update, every order cancellation is generated by a highly optimized electronic matching system.&lt;/p&gt;

&lt;p&gt;Understanding Market Microstructure means understanding how these markets actually operate beneath the surface.&lt;/p&gt;

&lt;p&gt;If quantitative finance studies what prices should do, market microstructure studies how prices are formed.&lt;/p&gt;

&lt;p&gt;It is one of the most important subjects for:&lt;/p&gt;

&lt;p&gt;High Frequency Trading&lt;br&gt;
Market Making&lt;br&gt;
Statistical Arbitrage&lt;br&gt;
Execution Algorithms&lt;br&gt;
Transaction Cost Analysis&lt;br&gt;
Without understanding market microstructure, building a professional trading system becomes extremely difficult.&lt;/p&gt;

&lt;p&gt;Part 2: What is Market Microstructure?¶&lt;br&gt;
Market Microstructure studies the process through which financial assets are traded.&lt;/p&gt;

&lt;p&gt;Instead of analyzing long-term price movements, it focuses on:&lt;/p&gt;

&lt;p&gt;Order submission&lt;br&gt;
Order cancellation&lt;br&gt;
Trade execution&lt;br&gt;
Liquidity&lt;br&gt;
Bid-ask spreads&lt;br&gt;
Price discovery&lt;br&gt;
In other words,&lt;/p&gt;

&lt;p&gt;Market microstructure explains how individual market events produce market prices.&lt;br&gt;
Rather than asking:&lt;/p&gt;

&lt;p&gt;Why did Bitcoin increase 10%?&lt;br&gt;
Microstructure asks:&lt;/p&gt;

&lt;p&gt;Which orders entered the book?&lt;br&gt;
Who provided liquidity?&lt;br&gt;
Who removed liquidity?&lt;br&gt;
How did those interactions change the price?&lt;br&gt;
Part 3: The Continuous Double Auction¶&lt;br&gt;
Most modern electronic exchanges operate using a Continuous Double Auction (CDA).&lt;/p&gt;

&lt;p&gt;Buyers submit bids.&lt;/p&gt;

&lt;p&gt;Sellers submit asks.&lt;/p&gt;

&lt;p&gt;Whenever the best bid meets the best ask, a trade occurs automatically.&lt;/p&gt;

&lt;p&gt;For example,&lt;/p&gt;

&lt;p&gt;BUY&lt;br&gt;
100 @ 99&lt;/p&gt;

&lt;p&gt;SELL&lt;br&gt;
100 @ 99&lt;/p&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;p&gt;Trade Executed&lt;br&gt;
The matching engine continuously repeats this process millions of times every day.&lt;/p&gt;

&lt;p&gt;There is no human intervention.&lt;/p&gt;

&lt;p&gt;Everything is performed automatically.&lt;/p&gt;

&lt;p&gt;Part 4: The Order Book¶&lt;br&gt;
The order book is the central data structure of every electronic exchange.&lt;/p&gt;

&lt;p&gt;A simplified order book looks like:&lt;/p&gt;

&lt;p&gt;ASK&lt;/p&gt;

&lt;p&gt;101.3  25&lt;/p&gt;

&lt;p&gt;101.2  40&lt;/p&gt;

&lt;p&gt;101.1  15&lt;/p&gt;




&lt;p&gt;101.0&lt;/p&gt;




&lt;p&gt;100.9  18&lt;/p&gt;

&lt;p&gt;100.8  35&lt;/p&gt;

&lt;p&gt;100.7  12&lt;/p&gt;

&lt;p&gt;BID&lt;br&gt;
The highest bid is called the Best Bid.&lt;/p&gt;

&lt;p&gt;The lowest ask is called the Best Ask.&lt;/p&gt;

&lt;p&gt;The difference between them is known as the Bid-Ask Spread.&lt;/p&gt;

&lt;p&gt;Almost every HFT strategy continuously monitors these values.&lt;/p&gt;

&lt;p&gt;Part 5: Liquidity¶&lt;br&gt;
Liquidity measures how easily an asset can be traded.&lt;/p&gt;

&lt;p&gt;Highly liquid markets typically have:&lt;/p&gt;

&lt;p&gt;Small spreads&lt;br&gt;
Deep order books&lt;br&gt;
Fast execution&lt;br&gt;
Large trading volume&lt;br&gt;
Low liquidity usually results in:&lt;/p&gt;

&lt;p&gt;Large spreads&lt;br&gt;
Higher slippage&lt;br&gt;
Greater execution risk&lt;br&gt;
Many quantitative strategies are designed specifically to provide or consume liquidity efficiently.&lt;/p&gt;

&lt;p&gt;Part 6: Market Participants¶&lt;br&gt;
Not all market participants behave the same way.&lt;/p&gt;

&lt;p&gt;Typical participants include:&lt;/p&gt;

&lt;p&gt;Retail Traders¶&lt;br&gt;
Small individual investors.&lt;/p&gt;

&lt;p&gt;Usually submit market orders.&lt;/p&gt;

&lt;p&gt;Institutional Investors¶&lt;br&gt;
Mutual funds.&lt;/p&gt;

&lt;p&gt;Pension funds.&lt;/p&gt;

&lt;p&gt;Asset managers.&lt;/p&gt;

&lt;p&gt;Often execute very large orders.&lt;/p&gt;

&lt;p&gt;Market Makers¶&lt;br&gt;
Continuously provide both bids and asks.&lt;/p&gt;

&lt;p&gt;Profit from the bid-ask spread while managing inventory risk.&lt;/p&gt;

&lt;p&gt;High Frequency Traders¶&lt;br&gt;
React to market events within microseconds.&lt;/p&gt;

&lt;p&gt;Focus on execution quality and market efficiency.&lt;/p&gt;

&lt;p&gt;Part 7: Market Orders vs Limit Orders¶&lt;br&gt;
Two order types dominate modern markets.&lt;/p&gt;

&lt;p&gt;Market Orders¶&lt;br&gt;
Execute immediately.&lt;/p&gt;

&lt;p&gt;Price is determined by available liquidity.&lt;/p&gt;

&lt;p&gt;Advantages:&lt;/p&gt;

&lt;p&gt;Guaranteed execution&lt;br&gt;
Disadvantages:&lt;/p&gt;

&lt;p&gt;Slippage&lt;br&gt;
Higher transaction cost&lt;br&gt;
Limit Orders¶&lt;br&gt;
Specify a maximum buying price or minimum selling price.&lt;/p&gt;

&lt;p&gt;Advantages:&lt;/p&gt;

&lt;p&gt;Price control&lt;br&gt;
Disadvantages:&lt;/p&gt;

&lt;p&gt;No execution guarantee&lt;br&gt;
Many HFT firms primarily use limit orders because controlling execution cost is often more important than immediate execution.&lt;/p&gt;

&lt;p&gt;Part 8: Price Discovery¶&lt;br&gt;
Prices do not move randomly.&lt;/p&gt;

&lt;p&gt;They evolve through the interaction of buyers and sellers.&lt;/p&gt;

&lt;p&gt;For example,&lt;/p&gt;

&lt;p&gt;A large buy order consumes multiple ask levels.&lt;/p&gt;

&lt;p&gt;The best ask moves upward.&lt;/p&gt;

&lt;p&gt;The market price increases.&lt;/p&gt;

&lt;p&gt;This process is known as price discovery.&lt;/p&gt;

&lt;p&gt;The market is constantly discovering the fair value through order flow.&lt;/p&gt;

&lt;p&gt;Part 9: Why Microstructure Matters in Quant Trading¶&lt;br&gt;
Traditional investing often focuses on:&lt;/p&gt;

&lt;p&gt;Fundamentals&lt;br&gt;
Earnings&lt;br&gt;
Macroeconomics&lt;br&gt;
High-frequency trading focuses on something entirely different:&lt;/p&gt;

&lt;p&gt;Market events.&lt;/p&gt;

&lt;p&gt;Examples include:&lt;/p&gt;

&lt;p&gt;Order imbalance&lt;br&gt;
Queue position&lt;br&gt;
Spread changes&lt;br&gt;
Trade aggressiveness&lt;br&gt;
Order cancellations&lt;br&gt;
Market depth&lt;br&gt;
These signals often exist for only milliseconds.&lt;/p&gt;

&lt;p&gt;Understanding them creates opportunities unavailable on longer time horizons.&lt;/p&gt;

&lt;p&gt;Part 10: Where godzilla.dev Fits¶&lt;br&gt;
Modern trading systems must process enormous numbers of market events every second.&lt;/p&gt;

&lt;p&gt;A production trading platform needs to:&lt;/p&gt;

&lt;p&gt;Decode exchange messages&lt;br&gt;
Maintain a local order book&lt;br&gt;
Distribute market data&lt;br&gt;
Execute strategies&lt;br&gt;
Manage risk&lt;br&gt;
Send low-latency orders&lt;br&gt;
These responsibilities form the foundation of every professional trading infrastructure.&lt;/p&gt;

&lt;p&gt;godzilla.dev provides an open-source infrastructure designed specifically for these workloads.&lt;/p&gt;

&lt;p&gt;Instead of rebuilding market data pipelines and exchange connectivity from scratch, developers can focus on researching trading strategies while relying on a modular, ultra-low latency architecture.&lt;/p&gt;

&lt;p&gt;Part 11: Key Takeaways¶&lt;br&gt;
Market Microstructure explains how electronic markets actually function.&lt;/p&gt;

&lt;p&gt;It studies:&lt;/p&gt;

&lt;p&gt;Order books&lt;br&gt;
Liquidity&lt;br&gt;
Order flow&lt;br&gt;
Matching engines&lt;br&gt;
Price discovery&lt;br&gt;
Rather than predicting prices directly, microstructure explains how prices emerge from the interaction of market participants.&lt;/p&gt;

&lt;p&gt;For quantitative developers, this knowledge is often more valuable than traditional financial theory.&lt;/p&gt;

&lt;p&gt;What's Next?¶&lt;br&gt;
The following articles build upon these concepts:&lt;/p&gt;

&lt;p&gt;What is an Order Book?&lt;br&gt;
What is a Matching Engine?&lt;br&gt;
What is Market Data?&lt;br&gt;
What is an Exchange Gateway?&lt;br&gt;
What is Shared Memory IPC?&lt;br&gt;
Building Low-Latency Trading Systems&lt;/p&gt;

</description>
      <category>ai</category>
      <category>web3</category>
    </item>
    <item>
      <title>godzilla.dev - AI Quant Trader Series - Day 8 - What is High Frequency Trading?</title>
      <dc:creator>KX</dc:creator>
      <pubDate>Sat, 04 Jul 2026 04:38:27 +0000</pubDate>
      <link>https://dev.to/godzilla_dev/godzilladev-ai-x-quant-trader-series-day-8-what-is-high-frequency-trading-1240</link>
      <guid>https://dev.to/godzilla_dev/godzilladev-ai-x-quant-trader-series-day-8-what-is-high-frequency-trading-1240</guid>
      <description>&lt;p&gt;source: &lt;a href="https://godzilla.dev/learning/ai_quant_traders_series_8/" rel="noopener noreferrer"&gt;https://godzilla.dev/learning/ai_quant_traders_series_8/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;See below for godzilla.dev materials about: AI x Quant Trader Series - Day 8&lt;/p&gt;

&lt;p&gt;AI × Quant Trader Series — Day 8¶&lt;br&gt;
What is High Frequency Trading?¶&lt;br&gt;
Reading time: ~15 minutes&lt;br&gt;
Prerequisites: basic programming, financial markets&lt;br&gt;
Focus: engineering intuition, system architecture (not trading strategies)&lt;/p&gt;

&lt;p&gt;Part 1: Introduction¶&lt;br&gt;
When people hear High Frequency Trading (HFT), they often imagine computers buying and selling stocks in microseconds.&lt;/p&gt;

&lt;p&gt;While speed is certainly important, it is not the essence of HFT.&lt;/p&gt;

&lt;p&gt;High Frequency Trading is the engineering discipline of building trading systems capable of:&lt;/p&gt;

&lt;p&gt;Processing market data&lt;br&gt;
Making trading decisions&lt;br&gt;
Managing risk&lt;br&gt;
Executing orders&lt;br&gt;
all within extremely tight latency constraints.&lt;/p&gt;

&lt;p&gt;At its core, HFT combines:&lt;/p&gt;

&lt;p&gt;Computer Science&lt;br&gt;
Distributed Systems&lt;br&gt;
Networking&lt;br&gt;
Operating Systems&lt;br&gt;
Market Microstructure&lt;br&gt;
Quantitative Finance&lt;br&gt;
Modern exchanges are software systems.&lt;/p&gt;

&lt;p&gt;The competition is no longer between traders.&lt;/p&gt;

&lt;p&gt;It is between software architectures.&lt;/p&gt;

&lt;p&gt;Part 2: Why High Frequency Trading Exists¶&lt;br&gt;
Electronic markets continuously generate enormous amounts of information.&lt;/p&gt;

&lt;p&gt;Every second, exchanges publish:&lt;/p&gt;

&lt;p&gt;Order submissions&lt;br&gt;
Order cancellations&lt;br&gt;
Trade executions&lt;br&gt;
Quote updates&lt;br&gt;
Every market event may represent a trading opportunity.&lt;/p&gt;

&lt;p&gt;The challenge is simple:&lt;/p&gt;

&lt;p&gt;Who can react first?&lt;br&gt;
The first system to detect an opportunity and submit an order usually captures the available liquidity.&lt;/p&gt;

&lt;p&gt;Milliseconds matter.&lt;/p&gt;

&lt;p&gt;Sometimes even microseconds.&lt;/p&gt;

&lt;p&gt;Part 3: The HFT Pipeline¶&lt;br&gt;
A modern HFT system is usually organized as a processing pipeline.&lt;/p&gt;

&lt;p&gt;Exchange&lt;br&gt;
│&lt;br&gt;
Market Data Feed&lt;br&gt;
│&lt;br&gt;
Market Data Decoder&lt;br&gt;
│&lt;br&gt;
Shared Memory&lt;br&gt;
│&lt;br&gt;
Trading Strategy&lt;br&gt;
│&lt;br&gt;
Risk Engine&lt;br&gt;
│&lt;br&gt;
Order Manager&lt;br&gt;
│&lt;br&gt;
Exchange Gateway&lt;br&gt;
│&lt;br&gt;
Exchange&lt;br&gt;
Each component performs one specialized task.&lt;/p&gt;

&lt;p&gt;Together they create a deterministic low-latency trading system.&lt;/p&gt;

&lt;p&gt;Part 4: Core Components¶&lt;br&gt;
4.1 Market Data¶&lt;br&gt;
Everything begins with market data.&lt;/p&gt;

&lt;p&gt;Exchanges continuously publish information such as:&lt;/p&gt;

&lt;p&gt;Best bid&lt;br&gt;
Best ask&lt;br&gt;
Trades&lt;br&gt;
Order book updates&lt;br&gt;
The market data engine decodes these messages and distributes them to downstream components.&lt;/p&gt;

&lt;p&gt;The faster this happens, the sooner strategies can react.&lt;/p&gt;

&lt;p&gt;4.2 Trading Strategy¶&lt;br&gt;
The strategy consumes market events and determines whether to:&lt;/p&gt;

&lt;p&gt;Buy&lt;br&gt;
Sell&lt;br&gt;
Cancel&lt;br&gt;
Modify existing orders&lt;br&gt;
Strategies can include:&lt;/p&gt;

&lt;p&gt;Market Making&lt;br&gt;
Statistical Arbitrage&lt;br&gt;
Cross-Exchange Arbitrage&lt;br&gt;
ETF Arbitrage&lt;br&gt;
Trend Following&lt;br&gt;
The strategy itself is often surprisingly small.&lt;/p&gt;

&lt;p&gt;Most engineering effort lies in the surrounding infrastructure.&lt;/p&gt;

&lt;p&gt;4.3 Risk Management¶&lt;br&gt;
Every order passes through risk control before reaching the exchange.&lt;/p&gt;

&lt;p&gt;Typical checks include:&lt;/p&gt;

&lt;p&gt;Position limits&lt;br&gt;
Exposure limits&lt;br&gt;
Price validation&lt;br&gt;
Fat-finger protection&lt;br&gt;
Kill switches&lt;br&gt;
A fast trading system without risk management is simply a fast way to lose money.&lt;/p&gt;

&lt;p&gt;4.4 Order Management¶&lt;br&gt;
The Order Management System (OMS) tracks:&lt;/p&gt;

&lt;p&gt;Active orders&lt;br&gt;
Filled orders&lt;br&gt;
Cancelled orders&lt;br&gt;
Positions&lt;br&gt;
It provides a consistent view of the trading state across the entire system.&lt;/p&gt;

&lt;p&gt;4.5 Exchange Gateway¶&lt;br&gt;
Finally, orders are transmitted through exchange-specific gateways.&lt;/p&gt;

&lt;p&gt;Each exchange has its own:&lt;/p&gt;

&lt;p&gt;Protocol&lt;br&gt;
Message format&lt;br&gt;
Authentication&lt;br&gt;
Session management&lt;br&gt;
The gateway hides these implementation details from the strategy.&lt;/p&gt;

&lt;p&gt;Part 5: Why Latency Matters¶&lt;br&gt;
Suppose two firms observe the same arbitrage opportunity.&lt;/p&gt;

&lt;p&gt;Firm A reacts in:&lt;/p&gt;

&lt;p&gt;20 μs&lt;br&gt;
Firm B reacts in:&lt;/p&gt;

&lt;p&gt;150 μs&lt;br&gt;
Both systems discovered the same opportunity.&lt;/p&gt;

&lt;p&gt;Only one receives the execution.&lt;/p&gt;

&lt;p&gt;The opportunity disappears immediately after the first successful order.&lt;/p&gt;

&lt;p&gt;This is why HFT engineers spend enormous effort reducing latency across every component of the system.&lt;/p&gt;

&lt;p&gt;Part 6: Software Engineering Challenges¶&lt;br&gt;
Building an HFT platform is primarily a systems engineering problem.&lt;/p&gt;

&lt;p&gt;Common challenges include:&lt;/p&gt;

&lt;p&gt;Memory Management¶&lt;br&gt;
Avoid unnecessary allocations.&lt;/p&gt;

&lt;p&gt;Reuse objects whenever possible.&lt;/p&gt;

&lt;p&gt;Lock-Free Programming¶&lt;br&gt;
Traditional mutexes introduce unpredictable latency.&lt;/p&gt;

&lt;p&gt;Many production systems rely on:&lt;/p&gt;

&lt;p&gt;Atomic operations&lt;br&gt;
Ring buffers&lt;br&gt;
Lock-free queues&lt;br&gt;
Shared Memory¶&lt;br&gt;
Passing data between processes through sockets is expensive.&lt;/p&gt;

&lt;p&gt;Shared memory allows multiple processes to access market data with almost zero copying.&lt;/p&gt;

&lt;p&gt;CPU Cache Optimization¶&lt;br&gt;
Modern CPUs are significantly faster than main memory.&lt;/p&gt;

&lt;p&gt;Efficient cache usage often produces larger performance gains than algorithmic optimization.&lt;/p&gt;

&lt;p&gt;Deterministic Performance¶&lt;br&gt;
Average latency is not enough.&lt;/p&gt;

&lt;p&gt;Professional trading systems focus on:&lt;/p&gt;

&lt;p&gt;Predictable latency&lt;br&gt;
Stable execution&lt;br&gt;
Minimal jitter&lt;br&gt;
Consistency matters more than occasional speed.&lt;/p&gt;

&lt;p&gt;Part 7: HFT vs Algorithmic Trading¶&lt;br&gt;
These terms are often confused.&lt;/p&gt;

&lt;p&gt;Algorithmic Trading is a broad category covering any automated trading strategy.&lt;/p&gt;

&lt;p&gt;High Frequency Trading is a specialized subset emphasizing:&lt;/p&gt;

&lt;p&gt;Extremely low latency&lt;br&gt;
High message throughput&lt;br&gt;
Very short holding periods&lt;br&gt;
Continuous market interaction&lt;br&gt;
Every HFT system is algorithmic trading.&lt;/p&gt;

&lt;p&gt;Not every algorithmic trading system is HFT.&lt;/p&gt;

&lt;p&gt;Part 8: Common Misconceptions¶&lt;br&gt;
HFT is not Artificial Intelligence¶&lt;br&gt;
Most HFT systems rely on:&lt;/p&gt;

&lt;p&gt;Market microstructure&lt;br&gt;
Statistical models&lt;br&gt;
Rule-based execution&lt;br&gt;
Machine learning is only one possible component.&lt;/p&gt;

&lt;p&gt;HFT is not only about faster hardware¶&lt;br&gt;
Buying expensive servers does not automatically create a low-latency platform.&lt;/p&gt;

&lt;p&gt;Architecture matters more than hardware.&lt;/p&gt;

&lt;p&gt;Good software consistently outperforms poor software running on expensive machines.&lt;/p&gt;

&lt;p&gt;HFT is not only for large institutions¶&lt;br&gt;
Open-source infrastructure has dramatically reduced the barrier to entry.&lt;/p&gt;

&lt;p&gt;Independent quantitative researchers can now build professional-grade trading systems using commodity hardware.&lt;/p&gt;

&lt;p&gt;Part 9: Where godzilla.dev Fits¶&lt;br&gt;
Building an HFT platform from scratch requires implementing:&lt;/p&gt;

&lt;p&gt;Market data processing&lt;br&gt;
Shared memory communication&lt;br&gt;
Order management&lt;br&gt;
Risk management&lt;br&gt;
Exchange gateways&lt;br&gt;
Strategy framework&lt;br&gt;
Monitoring&lt;br&gt;
Performance optimization&lt;br&gt;
These components represent years of engineering effort.&lt;/p&gt;

&lt;p&gt;godzilla.dev provides an open-source ultra-low latency trading framework designed specifically for modern electronic markets.&lt;/p&gt;

&lt;p&gt;Instead of rebuilding infrastructure repeatedly, quantitative developers can focus on strategy research while relying on a modular, production-oriented architecture.&lt;/p&gt;

&lt;p&gt;Part 10: Key Takeaways¶&lt;br&gt;
High Frequency Trading is fundamentally a systems engineering discipline.&lt;/p&gt;

&lt;p&gt;Its objective is not simply "trading faster."&lt;/p&gt;

&lt;p&gt;Instead, it focuses on building reliable, deterministic, and ultra-low latency software capable of processing millions of market events while maintaining strict risk controls.&lt;/p&gt;

&lt;p&gt;Understanding HFT requires knowledge of:&lt;/p&gt;

&lt;p&gt;Market Microstructure&lt;br&gt;
Operating Systems&lt;br&gt;
Computer Networks&lt;br&gt;
Concurrent Programming&lt;br&gt;
Low-Latency Architecture&lt;br&gt;
Trading strategies may evolve.&lt;/p&gt;

&lt;p&gt;The underlying engineering principles remain remarkably consistent.&lt;/p&gt;

&lt;p&gt;What's Next?¶&lt;br&gt;
The following articles explore each component in greater depth:&lt;/p&gt;

&lt;p&gt;What is Market Microstructure?&lt;br&gt;
What is an Order Book?&lt;br&gt;
What is Shared Memory IPC?&lt;br&gt;
What is a Matching Engine?&lt;br&gt;
What is an Order Management System (OMS)?&lt;br&gt;
What is a Risk Engine?&lt;br&gt;
Lock-Free Programming&lt;br&gt;
Event-Driven Architecture&lt;br&gt;
Building Low-Latency Trading Systems&lt;/p&gt;

</description>
      <category>ai</category>
      <category>web3</category>
    </item>
    <item>
      <title>godzilla.dev — AI Quant Trader Series — Day 7</title>
      <dc:creator>KX</dc:creator>
      <pubDate>Sat, 04 Jul 2026 04:37:01 +0000</pubDate>
      <link>https://dev.to/godzilla_dev/ai-x-quant-trader-series-day-7-2jj5</link>
      <guid>https://dev.to/godzilla_dev/ai-x-quant-trader-series-day-7-2jj5</guid>
      <description>&lt;p&gt;source: &lt;a href="https://godzilla.dev/learning/ai_quant_traders_series_7/" rel="noopener noreferrer"&gt;https://godzilla.dev/learning/ai_quant_traders_series_7/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;See below for godzilla.dev materials about: AI x Quant Trader Series - Day 7&lt;/p&gt;

&lt;p&gt;The Swiss Army Knife of Linear Models: Lasso Regression¶&lt;br&gt;
Reading time: ~15 minutes&lt;br&gt;
Prerequisites: basic linear algebra, Python, NumPy&lt;br&gt;
Focus: engineering intuition, quant usage (not ML hype)&lt;/p&gt;

&lt;p&gt;Part 1: Introduction to Regularized Linear Models¶&lt;br&gt;
We now move from data processing to one of the most important modeling tools in quantitative trading and applied machine learning: regularized linear models.&lt;/p&gt;

&lt;p&gt;In real-world financial modeling, the main difficulty is rarely computation. Instead, it is almost always structure:&lt;/p&gt;

&lt;p&gt;Too many features&lt;br&gt;
Strong multicollinearity&lt;br&gt;
Limited samples&lt;br&gt;
High noise-to-signal ratio&lt;br&gt;
A plain linear regression model can fit the data extremely well in-sample, yet fail catastrophically out-of-sample.&lt;/p&gt;

&lt;p&gt;This is where Lasso regression becomes indispensable.&lt;/p&gt;

&lt;p&gt;Part 2: From Linear Regression to Lasso¶&lt;br&gt;
2.1 Ordinary Least Squares (OLS)¶&lt;br&gt;
The objective function of ordinary least squares is:&lt;/p&gt;

&lt;p&gt;OLS attempts to minimize prediction error only.&lt;br&gt;
It places no constraint on model complexity.&lt;/p&gt;

&lt;p&gt;As a result:&lt;/p&gt;

&lt;p&gt;Coefficients become unstable when features are correlated&lt;br&gt;
Noise features receive non-zero weights&lt;br&gt;
Overfitting is almost guaranteed in high-dimensional settings&lt;br&gt;
2.2 Why Regularization Is Necessary¶&lt;br&gt;
In quantitative finance, feature sets often include:&lt;/p&gt;

&lt;p&gt;Dozens of technical indicators&lt;br&gt;
Overlapping factors&lt;br&gt;
Lagged signals&lt;br&gt;
Many of these features carry redundant or spurious information.&lt;/p&gt;

&lt;p&gt;Regularization explicitly penalizes complexity, forcing the model to prefer simpler and more stable solutions.&lt;/p&gt;

&lt;p&gt;Part 3: Lasso Regression — Core Idea¶&lt;br&gt;
3.1 Objective Function¶&lt;br&gt;
Lasso (Least Absolute Shrinkage and Selection Operator) modifies OLS by adding an L1 penalty:&lt;/p&gt;

&lt;p&gt;Where:&lt;/p&gt;

&lt;p&gt;The first term measures fit quality&lt;br&gt;
The second term penalizes coefficient magnitude&lt;br&gt;
controls the strength of regularization&lt;br&gt;
3.2 What Makes Lasso Different¶&lt;br&gt;
Unlike Ridge regression (L2 regularization), Lasso drives some coefficients exactly to zero.&lt;/p&gt;

&lt;p&gt;This leads to:&lt;/p&gt;

&lt;p&gt;Automatic feature selection&lt;br&gt;
Sparse models&lt;br&gt;
Improved interpretability&lt;br&gt;
From an engineering perspective:&lt;/p&gt;

&lt;p&gt;Lasso is not just a regression model — it is a structured filter.&lt;br&gt;
Part 4: Intuition — Why Lasso Produces Sparsity¶&lt;br&gt;
The L1 penalty creates a sharp constraint geometry.&lt;br&gt;
When optimization occurs under this constraint, solutions naturally land on coordinate axes.&lt;/p&gt;

&lt;p&gt;The practical consequence is simple:&lt;/p&gt;

&lt;p&gt;Unimportant features are dropped entirely.&lt;br&gt;
This behavior is extremely valuable in quant trading, where fewer signals often outperform noisy combinations.&lt;/p&gt;

&lt;p&gt;Part 5: Implementing Lasso in Python¶&lt;br&gt;
We now implement Lasso using scikit-learn.&lt;/p&gt;

&lt;p&gt;Imports¶&lt;br&gt;
import numpy as np&lt;br&gt;
import pandas as pd&lt;br&gt;
from sklearn.linear_model import Lasso&lt;br&gt;
from sklearn.preprocessing import StandardScaler&lt;br&gt;
5.1 Generate Example Data¶&lt;br&gt;
import numpy as np&lt;/p&gt;

&lt;p&gt;np.random.seed(42)&lt;/p&gt;

&lt;p&gt;X = np.random.randn(100, 10)&lt;br&gt;
true_beta = np.array([3, 0, 0, 1.5, 0, 0, 0, 2, 0, 0])&lt;br&gt;
y = X @ true_beta + np.random.randn(100) * 0.5&lt;br&gt;
5.2 Standardize Features¶&lt;br&gt;
from sklearn.preprocessing import StandardScaler&lt;/p&gt;

&lt;p&gt;scaler = StandardScaler()&lt;br&gt;
X_scaled = scaler.fit_transform(X)&lt;br&gt;
5.3 Fit the Lasso Model¶&lt;/p&gt;

&lt;p&gt;from sklearn.linear_model import Lasso&lt;br&gt;
import pandas as pd&lt;/p&gt;

&lt;p&gt;lasso = Lasso(alpha=0.1)&lt;br&gt;
lasso.fit(X_scaled, y)&lt;br&gt;
pd.Series(lasso.coef_)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;0    2.85&lt;br&gt;
1    0.00&lt;br&gt;
2    0.00&lt;br&gt;
3    1.42&lt;br&gt;
4    0.00&lt;br&gt;
5    0.00&lt;br&gt;
6    0.00&lt;br&gt;
7    1.95&lt;br&gt;
8    0.00&lt;br&gt;
9    0.00&lt;br&gt;
dtype: float64&lt;br&gt;
Noise features are eliminated automatically, while true signals are retained.&lt;/p&gt;

&lt;p&gt;Part 6: The Role of Alpha (λ)¶&lt;br&gt;
6.1 Effect of Regularization Strength¶&lt;br&gt;
Small α → weak regularization → overfitting&lt;/p&gt;

&lt;p&gt;Large α → aggressive shrinkage → underfitting&lt;/p&gt;

&lt;p&gt;for a in [0.01, 0.1, 1.0]:&lt;br&gt;
    model = Lasso(alpha=a)&lt;br&gt;
    model.fit(X_scaled, y)&lt;br&gt;
    print(a, (model.coef_ != 0).sum())&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;0.01 7&lt;br&gt;
0.1  3&lt;br&gt;
1.0  0&lt;/p&gt;

&lt;p&gt;6.2 Cross-Validation (Recommended)¶&lt;/p&gt;

&lt;p&gt;from sklearn.linear_model import LassoCV&lt;/p&gt;

&lt;p&gt;lasso_cv = LassoCV(cv=5)&lt;br&gt;
lasso_cv.fit(X_scaled, y)&lt;/p&gt;

&lt;p&gt;lasso_cv.alpha_&lt;br&gt;
lasso_cv.coef_&lt;br&gt;
Cross-validation improves robustness across different market regimes.&lt;/p&gt;

&lt;p&gt;Part 7: Limitations of Lasso¶&lt;br&gt;
Lasso is not universally optimal:&lt;/p&gt;

&lt;p&gt;Performs poorly when features are highly correlated&lt;/p&gt;

&lt;p&gt;Cannot model non-linear interactions&lt;/p&gt;

&lt;p&gt;Sensitive to outliers&lt;/p&gt;

&lt;p&gt;Common remedies include:&lt;/p&gt;

&lt;p&gt;Elastic Net (L1 + L2)&lt;/p&gt;

&lt;p&gt;PCA + Lasso&lt;/p&gt;

&lt;p&gt;Lasso for feature selection followed by non-linear models&lt;/p&gt;

</description>
      <category>ai</category>
      <category>web3</category>
    </item>
    <item>
      <title>godzilla.dev — AI x Quant Trader Series — Day 6</title>
      <dc:creator>KX</dc:creator>
      <pubDate>Sat, 04 Jul 2026 04:26:22 +0000</pubDate>
      <link>https://dev.to/godzilla_dev/godzilladev-ai-x-quant-trader-series-day-6-41h3</link>
      <guid>https://dev.to/godzilla_dev/godzilladev-ai-x-quant-trader-series-day-6-41h3</guid>
      <description>&lt;p&gt;source: &lt;a href="https://godzilla.dev/learning/ai_quant_traders_series_6/" rel="noopener noreferrer"&gt;https://godzilla.dev/learning/ai_quant_traders_series_6/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;See below for godzilla.dev materials about: AI x Quant Trader Series - Day 6&lt;/p&gt;

&lt;p&gt;The Swiss Army Knife of Python Data Processing: pandas"¶&lt;br&gt;
Part 2: Rapid Advancement¶&lt;br&gt;
In the previous article, we introduced how to create and access data in pandas using the Series and DataFrame types. In this article, we will cover how to perform operations on pandas data. Once you’ve mastered these operations, you’ll be able to handle most data processing tasks.&lt;/p&gt;

&lt;p&gt;First, let’s import the modules we’ll be using in this article:&lt;/p&gt;

&lt;p&gt;import numpy as np&lt;br&gt;
import pandas as pd&lt;br&gt;
from pandas import Series, DataFrame&lt;br&gt;
To make the data easier to view, let’s adjust the output display width&lt;/p&gt;

&lt;p&gt;pd.set_option('display.width', 200)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Other Ways to Create Data¶
The creation of data structures is not limited to the standard forms introduced in the previous article.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In this article, we’ll look at a few more. For example, we can create a Series with dates as its elements:&lt;/p&gt;

&lt;p&gt;dates = pd.date_range('20250101', periods=5)&lt;br&gt;
print(dates)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;DatetimeIndex(['2025-01-01', '2025-01-02', '2025-01-03', '2025-01-04', '2025-01-05'], dtype='datetime64[ns]', freq='D')&lt;/p&gt;

&lt;p&gt;Assign this date Series as the index of a DataFrame:&lt;/p&gt;

&lt;p&gt;df = pd.DataFrame(np.random.randn(5, 4),index=dates,columns=list('ABCD'))&lt;br&gt;
print(df)&lt;br&gt;
the output:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;               A         B         C         D
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;2025-01-01 -1.119762 -0.088336  1.921095  1.158499&lt;br&gt;
2025-01-02 -0.250627  0.271175 -0.505430 -1.490358&lt;br&gt;
2025-01-03  0.710884 -1.478697  0.537757  1.448547&lt;br&gt;
2025-01-04 -1.658607 -0.364456  0.196627  0.881224&lt;br&gt;
2025-01-05  0.347936  0.312740 -0.199889  2.881074&lt;/p&gt;

&lt;p&gt;Any object that can be converted into a Series can be used to create a DataFrame:&lt;/p&gt;

&lt;p&gt;df2 = pd.DataFrame({ 'A' : 1., 'B': pd.Timestamp('20250214'), 'C': pd.Series(1.6,index=list(range(4)),dtype='float64'), 'D' : np.array([4] * 4, dtype='int64'), 'E' : 'hello pandas!' })&lt;br&gt;
print(df2)&lt;br&gt;
the output:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; A          B    C  D              E
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;0  1.0 2025-02-14  1.6  4  hello pandas!&lt;br&gt;
1  1.0 2025-02-14  1.6  4  hello pandas!&lt;br&gt;
2  1.0 2025-02-14  1.6  4  hello pandas!&lt;br&gt;
3  1.0 2025-02-14  1.6  4  hello pandas!&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Viewing Data¶
In most cases, data is not generated by the analysts themselves but obtained through data APIs, external files, or other sources.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here, we’ll use a dataset retrieved from binance rest api as an example:&lt;/p&gt;

&lt;h1&gt;
  
  
  pip install pandas requests python-dateutil
&lt;/h1&gt;

&lt;p&gt;import requests&lt;br&gt;
import pandas as pd&lt;br&gt;
from dateutil import parser&lt;/p&gt;

&lt;p&gt;symbol = "BTCUSDT"  # REST 接口不带斜杠&lt;br&gt;
interval = "1d"&lt;/p&gt;

&lt;p&gt;start = "2025-01-01 00:00:00"&lt;br&gt;
end   = "2025-02-01 00:00:00"&lt;/p&gt;

&lt;p&gt;start_ms = int(parser.isoparse(start).timestamp() * 1000)&lt;br&gt;
end_ms   = int(parser.isoparse(end).timestamp() * 1000)&lt;/p&gt;

&lt;p&gt;url = "&lt;a href="https://api.binance.com/api/v3/klines" rel="noopener noreferrer"&gt;https://api.binance.com/api/v3/klines&lt;/a&gt;"&lt;br&gt;
params = {&lt;br&gt;
    "symbol": symbol,&lt;br&gt;
    "interval": interval,&lt;br&gt;
    "startTime": start_ms,&lt;br&gt;
    "endTime": end_ms,&lt;br&gt;
    "limit": 1000&lt;br&gt;
}&lt;br&gt;
r = requests.get(url, params=params, timeout=15)&lt;br&gt;
r.raise_for_status()&lt;br&gt;
data = r.json()&lt;/p&gt;

&lt;h1&gt;
  
  
  返回每一行：
&lt;/h1&gt;

&lt;h1&gt;
  
  
  [
&lt;/h1&gt;

&lt;h1&gt;
  
  
  0 open time, 1 open, 2 high, 3 low, 4 close, 5 volume,
&lt;/h1&gt;

&lt;h1&gt;
  
  
  6 close time, 7 quote asset volume, 8 number of trades,
&lt;/h1&gt;

&lt;h1&gt;
  
  
  9 taker buy base volume, 10 taker buy quote volume, 11 ignore
&lt;/h1&gt;

&lt;h1&gt;
  
  
  ]
&lt;/h1&gt;

&lt;p&gt;df = pd.DataFrame(data, columns=[&lt;br&gt;
    "open_time","open","high","low","close","volume",&lt;br&gt;
    "close_time","quote_vol","trades","taker_base","taker_quote","ignore"&lt;br&gt;
])&lt;/p&gt;

&lt;h1&gt;
  
  
  转数值
&lt;/h1&gt;

&lt;p&gt;for col in ["open","high","low","close","volume","quote_vol","taker_base","taker_quote"]:&lt;br&gt;
    df[col] = pd.to_numeric(df[col], errors="coerce")&lt;/p&gt;

&lt;h1&gt;
  
  
  只保留核心列，并用UTC日期索引
&lt;/h1&gt;

&lt;p&gt;df["date_utc"] = pd.to_datetime(df["open_time"], unit="ms", utc=True).dt.date&lt;br&gt;
df = df[["open","high","low","close","volume","date_utc"]].set_index("date_utc").sort_index()&lt;/p&gt;

&lt;p&gt;print(df)&lt;br&gt;
the output:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;             open       high        low      close        volume
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;date_utc&lt;br&gt;&lt;br&gt;
2025-01-01   93576.00   95151.15   92888.00   94591.79  10373.326130&lt;br&gt;
2025-01-02   94591.78   97839.50   94392.00   96984.79  21970.489480&lt;br&gt;
2025-01-03   96984.79   98976.91   96100.01   98174.18  15253.829360&lt;br&gt;
2025-01-04   98174.17   98778.43   97514.79   98220.50   8990.056510&lt;br&gt;
2025-01-05   98220.51   98836.85   97276.79   98363.61   8095.637230&lt;br&gt;
2025-01-06   98363.61  102480.00   97920.00  102235.60  25263.433750&lt;br&gt;
2025-01-07  102235.60  102724.38   96181.81   96954.61  32059.875370&lt;br&gt;
2025-01-08   96954.60   97268.65   92500.90   95060.61  33704.678940&lt;br&gt;
2025-01-09   95060.61   95382.32   91203.67   92552.49  34544.836850&lt;br&gt;
2025-01-10   92552.49   95836.00   92206.02   94726.11  31482.864240&lt;br&gt;
2025-01-11   94726.10   95050.94   93831.73   94599.99   7047.904300&lt;br&gt;
2025-01-12   94599.99   95450.10   93711.19   94545.06   8606.866220&lt;br&gt;
2025-01-13   94545.07   95940.00   89256.69   94536.10  42619.564230&lt;br&gt;
2025-01-14   94536.11   97371.00   94346.22   96560.86  27846.617530&lt;br&gt;
2025-01-15   96560.85  100681.94   96500.00  100497.35  30509.991790&lt;br&gt;
2025-01-16  100497.35  100866.66   97335.13   99987.30  27832.853170&lt;br&gt;
2025-01-17   99987.30  105865.22   99950.77  104077.48  39171.852920&lt;br&gt;
2025-01-18  104077.47  104988.88  102277.55  104556.23  24307.829980&lt;br&gt;
2025-01-19  104556.23  106422.43   99651.60  101331.57  43397.282980&lt;br&gt;
2025-01-20  101331.57  109588.00   99550.00  102260.01  89529.231732&lt;br&gt;
2025-01-21  102260.00  107240.81  100119.04  106143.82  45941.020020&lt;br&gt;
2025-01-22  106143.82  106394.46  103339.12  103706.66  22248.692540&lt;br&gt;
2025-01-23  103706.66  106850.00  101262.28  103910.34  53953.120310&lt;br&gt;
2025-01-24  103910.35  107120.00  102750.00  104870.50  23609.240170&lt;br&gt;
2025-01-25  104870.51  105286.52  104106.09  104746.85   9068.323770&lt;br&gt;
2025-01-26  104746.86  105500.00  102520.44  102620.00   9812.512380&lt;br&gt;
2025-01-27  102620.01  103260.00   97777.77  102082.83  50758.134100&lt;br&gt;
2025-01-28  102082.83  103800.00  100272.68  101335.52  22022.057650&lt;br&gt;
2025-01-29  101335.52  104782.68  101328.01  103733.24  23155.358020&lt;br&gt;
2025-01-30  103733.25  106457.44  103278.54  104722.94  19374.074720&lt;br&gt;
2025-01-31  104722.94  106012.00  101560.00  102429.56  21983.181930&lt;/p&gt;

&lt;p&gt;Using the code above, we retrieved BTC’s daily market data for all trading days in January 2025. First, let’s check the size of the dataset:&lt;/p&gt;

&lt;p&gt;print(df.shape)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;(31, 5)&lt;/p&gt;

&lt;p&gt;We can see there are 31 rows, which means we fetched 31 records. Each record has 5 fields.&lt;/p&gt;

&lt;p&gt;Now let’s preview the data: DataFrame.head() and DataFrame.tail() show the first five and last five rows, respectively. To change the number of rows displayed, pass a number in the parentheses.&lt;/p&gt;

&lt;p&gt;print("Head of this DataFrame:")&lt;br&gt;
print(df.head())&lt;br&gt;
print("Tail of this DataFrame:")&lt;br&gt;
print(df.tail(3))&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;Head of this DataFrame:&lt;br&gt;
                open      high       low     close       volume&lt;br&gt;
date_utc&lt;br&gt;&lt;br&gt;
2025-01-01  93576.00  95151.15  92888.00  94591.79  10373.32613&lt;br&gt;
2025-01-02  94591.78  97839.50  94392.00  96984.79  21970.48948&lt;br&gt;
2025-01-03  96984.79  98976.91  96100.01  98174.18  15253.82936&lt;br&gt;
2025-01-04  98174.17  98778.43  97514.79  98220.50   8990.05651&lt;br&gt;
2025-01-05  98220.51  98836.85  97276.79  98363.61   8095.63723&lt;br&gt;
Tail of this DataFrame:&lt;br&gt;
                 open       high        low      close       volume&lt;br&gt;
date_utc&lt;br&gt;&lt;br&gt;
2025-01-29  101335.52  104782.68  101328.01  103733.24  23155.35802&lt;br&gt;
2025-01-30  103733.25  106457.44  103278.54  104722.94  19374.07472&lt;br&gt;
2025-01-31  104722.94  106012.00  101560.00  102429.56  21983.18193&lt;/p&gt;

&lt;p&gt;DataFrame.describe() provides statistical summaries for the purely numeric data in the DataFrame.&lt;/p&gt;

&lt;p&gt;print(df.describe())&lt;br&gt;
the output:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;            open           high            low          close        volume
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;count      31.000000      31.000000      31.000000      31.000000     31.000000&lt;br&gt;
mean    99750.482258  101877.524839   97835.769032  100036.080645  27888.217365&lt;br&gt;
std      4148.002200    4544.879400    4050.642975    4011.242254  17319.976611&lt;br&gt;
min     92552.490000   95050.940000   89256.690000   92552.490000   7047.904300&lt;br&gt;
25%     95810.730000   97605.250000   94369.110000   96757.735000  17313.952040&lt;br&gt;
50%    100497.350000  102724.380000   97777.770000  101331.570000  24307.829980&lt;br&gt;
75%    103719.955000  105938.610000  101295.145000  103719.950000  34124.757895&lt;br&gt;
max    106143.820000  109588.000000  104106.090000  106143.820000  89529.231732&lt;/p&gt;

&lt;p&gt;Sorting the data makes it easier to inspect. A DataFrame offers two kinds of sorting.&lt;/p&gt;

&lt;p&gt;One is label-based sorting—i.e., sorting by the index (row labels) or by column names.&lt;/p&gt;

&lt;p&gt;Use DataFrame.sort_index, with axis=0 to sort by the index (rows) and axis=1 to sort by column names. You can also specify ascending or descending order.&lt;/p&gt;

&lt;p&gt;print("Order by column names, descending:")&lt;br&gt;
print(df.sort_index(axis=1, ascending=False).head())&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;Order by column names, descending:&lt;br&gt;
                 volume      open       low      high     close&lt;br&gt;
date_utc&lt;br&gt;&lt;br&gt;
2025-01-01  10373.32613  93576.00  92888.00  95151.15  94591.79&lt;br&gt;
2025-01-02  21970.48948  94591.78  94392.00  97839.50  96984.79&lt;br&gt;
2025-01-03  15253.82936  96984.79  96100.01  98976.91  98174.18&lt;br&gt;
2025-01-04   8990.05651  98174.17  97514.79  98778.43  98220.50&lt;br&gt;
2025-01-05   8095.63723  98220.51  97276.79  98836.85  98363.61&lt;/p&gt;

&lt;p&gt;The second type is value-based sorting. You can specify the column name(s) and the sort order; by default, it sorts in ascending order.&lt;/p&gt;

&lt;p&gt;print("Order by column value, ascending:")&lt;br&gt;
print(df.sort_values(by="date_utc", ascending=True).head())&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;Order by column value, ascending:&lt;br&gt;
                open      high       low     close       volume&lt;br&gt;
date_utc&lt;br&gt;&lt;br&gt;
2025-01-01  93576.00  95151.15  92888.00  94591.79  10373.32613&lt;br&gt;
2025-01-02  94591.78  97839.50  94392.00  96984.79  21970.48948&lt;br&gt;
2025-01-03  96984.79  98976.91  96100.01  98174.18  15253.82936&lt;br&gt;
2025-01-04  98174.17  98778.43  97514.79  98220.50   8990.05651&lt;br&gt;
2025-01-05  98220.51  98836.85  97276.79  98363.61   8095.63723&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Data Access and Manipulation¶
3.1 Revisiting Data Access¶
In the previous section, we introduced several ways to access data in a DataFrame using loc, iloc, at, iat, ix, and [].&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here, we’ll introduce another method: using ":" to retrieve part of the rows or all of the columns.&lt;/p&gt;

&lt;p&gt;print(df.iloc[1:4][:])&lt;br&gt;
the output:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;            open      high       low     close       volume
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;date_utc&lt;br&gt;&lt;br&gt;
2025-01-02  94591.78  97839.50  94392.00  96984.79  21970.48948&lt;br&gt;
2025-01-03  96984.79  98976.91  96100.01  98174.18  15253.82936&lt;br&gt;
2025-01-04  98174.17  98778.43  97514.79  98220.50   8990.05651&lt;/p&gt;

&lt;p&gt;We can extend the method introduced in the previous section that uses Boolean vectors to access data.&lt;/p&gt;

&lt;p&gt;This makes it very convenient to filter data. For example, we can select the rows where the closing price is above the average.&lt;/p&gt;

&lt;p&gt;print(df[df.close&amp;gt; df.close.mean()].head())&lt;br&gt;
the output:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;             open       high        low      close       volume
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;date_utc&lt;br&gt;&lt;br&gt;
2025-01-06   98363.61  102480.00   97920.00  102235.60  25263.43375&lt;br&gt;
2025-01-15   96560.85  100681.94   96500.00  100497.35  30509.99179&lt;br&gt;
2025-01-17   99987.30  105865.22   99950.77  104077.48  39171.85292&lt;br&gt;
2025-01-18  104077.47  104988.88  102277.55  104556.23  24307.82998&lt;br&gt;
2025-01-19  104556.23  106422.43   99651.60  101331.57  43397.28298&lt;br&gt;
开启送礼物&lt;/p&gt;

</description>
      <category>ai</category>
      <category>web3</category>
    </item>
    <item>
      <title>godzilla.dev — AI x Quant Trader Series — Day 5</title>
      <dc:creator>KX</dc:creator>
      <pubDate>Sat, 04 Jul 2026 04:24:06 +0000</pubDate>
      <link>https://dev.to/godzilla_dev/godzilladev-ai-x-quant-trader-series-day-5-32mh</link>
      <guid>https://dev.to/godzilla_dev/godzilladev-ai-x-quant-trader-series-day-5-32mh</guid>
      <description>&lt;p&gt;source: &lt;a href="https://godzilla.dev/learning/ai_quant_traders_series_5/" rel="noopener noreferrer"&gt;https://godzilla.dev/learning/ai_quant_traders_series_5/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;See below for godzilla.dev materials about: AI x Quant Trader Series - Day 5&lt;/p&gt;

&lt;p&gt;The Swiss Army Knife of Python Data Processing: pandas"¶&lt;br&gt;
Part 1: Introduction to Basic Data Structures¶&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Introduction to Pandas¶
We've finally arrived at the module the author is most eager to introduce — and arguably the most powerful Python extension for data processing: pandas.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When working with real-world financial data, a single record often contains multiple types of data. For example, a stock ticker is a string, the closing price is a float, and the trading volume is an integer. In C++, this can be handled using a container like a vector of custom structs. In Python, pandas provides high-level data structures — Series and DataFrame — that make data manipulation extremely convenient, fast, and straightforward.&lt;/p&gt;

&lt;p&gt;Note that there are some incompatibilities between different versions of pandas. Therefore, it's important to know which version you are using. Let's first check the version of pandas in your local enviroment:&lt;/p&gt;

&lt;p&gt;import pandas as pd&lt;br&gt;
pd.&lt;strong&gt;version&lt;/strong&gt;&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;'2.2.3'&lt;/p&gt;

&lt;p&gt;The two main data structures in pandas are Series and DataFrame. In the next two sections, we’ll explore how to create these structures either from other data types or from scratch. But first, let’s import them along with the relevant modules:&lt;/p&gt;

&lt;p&gt;import numpy as np&lt;br&gt;
from pandas import Series, DataFrame&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Pandas Data Structure: Series¶
Generally speaking, a Series can be thought of as a one-dimensional array. The main difference between a Series and a regular 1D array is that a Series has an index, which makes it similar to a hash (dictionary-like structure) commonly seen in programming.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;2.1 Creating a Series¶&lt;br&gt;
The basic format for creating a Series is:&lt;/p&gt;

&lt;p&gt;s = Series(data, index=index, name=name)&lt;/p&gt;

&lt;p&gt;Below are a few examples of how to create a Series. Let's start by creating a Series from an array:&lt;/p&gt;

&lt;p&gt;a = np.random.randn(5)&lt;br&gt;
print("a is an array:")&lt;br&gt;
print(a)&lt;br&gt;
s = Series(a)&lt;br&gt;
print("s is a Series:")&lt;br&gt;
print(s)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;a is an array:&lt;br&gt;
[ 1.35729482 -1.45138391  0.91716941 -1.24918144 -0.68685959]&lt;br&gt;
s is a Series:&lt;br&gt;
0    1.357295&lt;br&gt;
1   -1.451384&lt;br&gt;
2    0.917169&lt;br&gt;
3   -1.249181&lt;br&gt;
4   -0.686860&lt;br&gt;
dtype: float64&lt;/p&gt;

&lt;p&gt;You can specify an index when creating a Series, and you can use Series.index to view the specific index values. One important thing to note is that when creating a Series from an array, the length of the specified index must match the length of the data.&lt;/p&gt;

&lt;p&gt;s = Series(np.random.randn(5), index=['a', 'b', 'c', 'd', 'e'])&lt;br&gt;
print(s)&lt;br&gt;
s.index&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;a   -1.898245&lt;br&gt;
b    0.172835&lt;br&gt;
c    0.779262&lt;br&gt;
d    0.289468&lt;br&gt;
e   -0.947995&lt;br&gt;
Name: my_series, dtype: float64&lt;br&gt;
my_series&lt;/p&gt;

&lt;p&gt;Another optional parameter when creating a Series is name, which allows you to assign a name to the Series. You can access it using Series.name. In a DataFrame, the name of each column becomes the name of the Series when that column is extracted individually.&lt;/p&gt;

&lt;p&gt;s = Series(np.random.randn(5), index=['a', 'b', 'c', 'd', 'e'], name='my_series')&lt;br&gt;
print(s)&lt;br&gt;
print(s.name)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;a   -1.898245&lt;br&gt;
b    0.172835&lt;br&gt;
c    0.779262&lt;br&gt;
d    0.289468&lt;br&gt;
e   -0.947995&lt;br&gt;
Name: my_series, dtype: float64&lt;br&gt;
my_series&lt;/p&gt;

&lt;p&gt;A Series can also be created from a dictionary (dict):&lt;/p&gt;

&lt;p&gt;d = {'a': 0., 'b': 1, 'c': 2}&lt;br&gt;
print("d is a dict:")&lt;br&gt;
print(d)&lt;br&gt;
s = Series(d)&lt;br&gt;
print("s is a Series:")&lt;br&gt;
print(s)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;d is a dict:&lt;br&gt;
{'a': 0.0, 'c': 2, 'b': 1}&lt;br&gt;
s is a Series:&lt;br&gt;
a    0&lt;br&gt;
b    1&lt;br&gt;
c    2&lt;br&gt;
dtype: float64&lt;/p&gt;

&lt;p&gt;Let’s take a look at the case where we specify an index when creating a Series from a dictionary (the index does not have to match the dictionary’s length):&lt;/p&gt;

&lt;p&gt;Series(d, index=['b', 'c', 'd', 'a'])&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;b     1&lt;br&gt;
c     2&lt;br&gt;
d   NaN&lt;br&gt;
a     0&lt;br&gt;
dtype: float64&lt;/p&gt;

&lt;p&gt;We can observe two things:&lt;/p&gt;

&lt;p&gt;When creating a Series from a dictionary, the data is reordered to match the specified index.&lt;/p&gt;

&lt;p&gt;The length of the index does not need to match the length of the dictionary. If there are extra index labels, pandas will automatically assign them a value of NaN (Not a Number — the standard marker for missing data in pandas). If the index is shorter, only the corresponding subset of the dictionary will be used.&lt;/p&gt;

&lt;p&gt;If the data is a single value, such as the number 4, then the Series will repeat this value across all index labels:&lt;/p&gt;

&lt;p&gt;Series(4., index=['a', 'b', 'c', 'd', 'e'])&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;a    4&lt;br&gt;
b    4&lt;br&gt;
c    4&lt;br&gt;
d    4&lt;br&gt;
e    4&lt;br&gt;
dtype: float64&lt;/p&gt;

&lt;p&gt;2.2 Accessing Data in a Series¶&lt;br&gt;
You can access data in a Series using index positions (like arrays), index labels (like dictionaries), and even through conditional filtering:&lt;/p&gt;

&lt;p&gt;s = Series(np.random.randn(10),index=['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'])&lt;br&gt;
s[0]&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;1.4328106520571824&lt;/p&gt;

&lt;p&gt;s[:2]&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;a    1.432811&lt;br&gt;
b    0.120681&lt;br&gt;
dtype: float64&lt;/p&gt;

&lt;p&gt;s[[2,0,4]]&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;c    0.578146&lt;br&gt;
a    1.432811&lt;br&gt;
e    1.327594&lt;br&gt;
dtype: float64&lt;/p&gt;

&lt;p&gt;s[['e', 'i']]&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;e    1.327594&lt;br&gt;
i   -0.634347&lt;br&gt;
dtype: float64&lt;/p&gt;

&lt;p&gt;s[s &amp;gt; 0.5]&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;a    1.432811&lt;br&gt;
c    0.578146&lt;br&gt;
e    1.327594&lt;br&gt;
g    1.850783&lt;br&gt;
dtype: float64&lt;/p&gt;

&lt;p&gt;'e' in s&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;True&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Pandas Data Structure: DataFrame¶
Before using a DataFrame, let’s briefly go over its characteristics. A DataFrame is a two-dimensional data structure formed by combining multiple Series (column-wise). Each column, when extracted individually, is a Series. This is very similar to how data is retrieved from a SQL database. Therefore, it’s often more convenient to process a DataFrame column by column, and it's helpful for users to develop a column-oriented mindset when working with data.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;One of the key advantages of a DataFrame is its ability to handle columns of different data types with ease. So there's no need to think about operations like matrix inversion on a DataFrame full of floats — for such numerical tasks, it’s usually better to store the data in a NumPy matrix.&lt;/p&gt;

&lt;p&gt;3.1 Creating a DataFrame¶&lt;br&gt;
Let’s first look at how to create a DataFrame from a dictionary. A DataFrame is a 2D data structure that serves as a collection of Series. We’ll start by creating a dictionary where the values are Series, and then convert it into a DataFrame:&lt;/p&gt;

&lt;p&gt;d = {'one': Series([1., 2., 3.], index=['a', 'b', 'c']), 'two': Series([1., 2., 3., 4.], index=['a', 'b', 'c', 'd'])}&lt;br&gt;
df = DataFrame(d)&lt;br&gt;
print(df)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;one  two&lt;br&gt;
a    1    1&lt;br&gt;
b    2    2&lt;br&gt;
c    3    3&lt;br&gt;
d  NaN    4&lt;/p&gt;

&lt;p&gt;You can specify the desired rows (index) and columns when creating the DataFrame. If the dictionary does not contain the corresponding elements, those entries will be filled with NaN (missing values):&lt;/p&gt;

&lt;p&gt;df = DataFrame(d, index=['r', 'd', 'a'], columns=['two', 'three'])&lt;br&gt;
print(df)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;two three&lt;br&gt;
r  NaN   NaN&lt;br&gt;
d    4   NaN&lt;br&gt;
a    1   NaN&lt;/p&gt;

&lt;p&gt;You can use dataframe.index and dataframe.columns to view the rows and columns of a DataFrame. The dataframe.values attribute returns the elements of the DataFrame as a NumPy array.&lt;/p&gt;

&lt;p&gt;print("DataFrame index:")&lt;br&gt;
print(df.index)&lt;br&gt;
print("DataFrame columns:")&lt;br&gt;
print(df.columns)&lt;br&gt;
print("DataFrame values:")&lt;br&gt;
print(df.values)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;DataFrame index:&lt;br&gt;
Index([u'alpha', u'beta', u'gamma', u'delta', u'eta'], dtype='object')&lt;br&gt;
DataFrame columns:&lt;br&gt;
Index([u'a', u'b', u'c', u'd', u'e'], dtype='object')&lt;br&gt;
DataFrame values:&lt;br&gt;
[[  0.   0.   0.   0.   0.]&lt;br&gt;
 [  1.   2.   3.   4.   5.]&lt;br&gt;
 [  2.   4.   6.   8.  10.]&lt;br&gt;
 [  3.   6.   9.  12.  15.]&lt;br&gt;
 [  4.   8.  12.  16.  20.]]&lt;/p&gt;

&lt;p&gt;A DataFrame can also be created from a dictionary whose values are arrays, but all arrays must be of the same length.&lt;/p&gt;

&lt;p&gt;d = {'one': [1., 2., 3., 4.], 'two': [4., 3., 2., 1.]}&lt;br&gt;
df = DataFrame(d, index=['a', 'b', 'c', 'd'])&lt;br&gt;
print(df)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;one  two&lt;br&gt;
a    1    4&lt;br&gt;
b    2    3&lt;br&gt;
c    3    2&lt;br&gt;
d    4    1&lt;/p&gt;

&lt;p&gt;When the values are not arrays, this length restriction does not apply, and any missing values will be automatically filled with NaN.&lt;/p&gt;

&lt;p&gt;d= [{'a': 1.6, 'b': 2}, {'a': 3, 'b': 6, 'c': 9}]&lt;br&gt;
df = DataFrame(d)&lt;br&gt;
print(df)&lt;br&gt;
the output:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; a  b   c
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;0  1.6  2 NaN&lt;br&gt;
1  3.0  6   9&lt;/p&gt;

&lt;p&gt;When working with real-world data, you may sometimes need to create an empty DataFrame. This can be done as follows:&lt;/p&gt;

&lt;p&gt;df = DataFrame()&lt;br&gt;
print(df)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;Empty DataFrame&lt;br&gt;
Columns: []&lt;br&gt;
Index: []&lt;/p&gt;

&lt;p&gt;Another very useful way to create a DataFrame is by using the concat function, which allows you to build a DataFrame from one or more Series or existing DataFrames.&lt;/p&gt;

&lt;p&gt;a = Series(range(5))&lt;br&gt;
b = Series(np.linspace(4, 20, 5))&lt;br&gt;
df = pd.concat([a, b], axis=1)&lt;br&gt;
print(df)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;0   1&lt;br&gt;
0  0   4&lt;br&gt;
1  1   8&lt;br&gt;
2  2  12&lt;br&gt;
3  3  16&lt;br&gt;
4  4  20&lt;/p&gt;

&lt;p&gt;Here, axis=1 means concatenation by columns, while axis=0 means concatenation by rows. Note that a Series is treated as a single column, so if you choose axis=0, you’ll get a 10×1 DataFrame.&lt;/p&gt;

&lt;p&gt;The following example shows how to concatenate DataFrames by rows to form a larger DataFrame:&lt;/p&gt;

&lt;p&gt;df = DataFrame()&lt;br&gt;
index = ['alpha', 'beta', 'gamma', 'delta', 'eta']&lt;br&gt;
for i in range(5):&lt;br&gt;
    a = DataFrame([np.linspace(i, 5*i, 5)], index=[index[i]])&lt;br&gt;
    df = pd.concat([df, a], axis=0)&lt;br&gt;
print(df)&lt;br&gt;
the output:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   0  1   2   3   4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;alpha  0  0   0   0   0&lt;br&gt;
beta   1  2   3   4   5&lt;br&gt;
gamma  2  4   6   8  10&lt;br&gt;
delta  3  6   9  12  15&lt;br&gt;
eta    4  8  12  16  20&lt;/p&gt;

&lt;p&gt;3.2 Accessing Data in a DataFrame¶&lt;br&gt;
First, it’s important to emphasize again that DataFrame operations are fundamentally column-based. You can think of every operation as first selecting a column (which is a Series), and then accessing elements from that Series.&lt;/p&gt;

&lt;p&gt;You can select a column using either dataframe.column_name or dataframe[]. You’ll quickly notice that:&lt;/p&gt;

&lt;p&gt;The dot notation (dataframe.column_name) can only select a single column.&lt;/p&gt;

&lt;p&gt;The bracket notation (dataframe[]) can be used to select one or multiple columns.&lt;/p&gt;

&lt;p&gt;If the DataFrame has no column names, you can use non-negative integers (i.e., indices) inside the brackets to select columns. However, if column names do exist, then you must use those names to select columns. Also, in the absence of column names, dataframe.column_name is not valid.&lt;/p&gt;

&lt;p&gt;print(df[1])&lt;br&gt;
print(type(df[1]))&lt;br&gt;
df.columns = ['a', 'b', 'c', 'd', 'e']&lt;br&gt;
print(df['b'])&lt;br&gt;
print(type(df['b']))&lt;br&gt;
print(df.b)&lt;br&gt;
print(type(df.b))&lt;br&gt;
print(df[['a', 'd']])&lt;br&gt;
print(type(df[['a', 'd']]))&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;alpha    0&lt;br&gt;
beta     2&lt;br&gt;
gamma    4&lt;br&gt;
delta    6&lt;br&gt;
eta      8&lt;br&gt;
Name: 1, dtype: float64&lt;br&gt;
&lt;br&gt;
alpha    0&lt;br&gt;
beta     2&lt;br&gt;
gamma    4&lt;br&gt;
delta    6&lt;br&gt;
eta      8&lt;br&gt;
Name: b, dtype: float64&lt;br&gt;
&lt;br&gt;
alpha    0&lt;br&gt;
beta     2&lt;br&gt;
gamma    4&lt;br&gt;
delta    6&lt;br&gt;
eta      8&lt;br&gt;
Name: b, dtype: float64&lt;br&gt;
&lt;br&gt;
       a   d&lt;br&gt;
alpha  0   0&lt;br&gt;
beta   1   4&lt;br&gt;
gamma  2   8&lt;br&gt;
delta  3  12&lt;br&gt;
eta    4  16&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;In the code above, we used dataframe.columns to assign column names to the DataFrame. As shown, when a single column is extracted, the resulting data structure is a Series. However, when two or more columns are selected, the result remains a DataFrame.&lt;/p&gt;

&lt;p&gt;To access specific elements, you can use indices or labels, just like with a Series.&lt;/p&gt;

&lt;p&gt;print df['b'][2]&lt;br&gt;
print df['b']['gamma']&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;4.0&lt;br&gt;
4.0&lt;/p&gt;

&lt;p&gt;To select rows, you can use dataframe.iloc to select by position (index number), or dataframe.loc to select by label (index name).&lt;/p&gt;

&lt;p&gt;print(df.iloc[1])&lt;br&gt;
print(df.loc['beta'])&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;a    1&lt;br&gt;
b    2&lt;br&gt;
c    3&lt;br&gt;
d    4&lt;br&gt;
e    5&lt;br&gt;
Name: beta, dtype: float64&lt;br&gt;
a    1&lt;br&gt;
b    2&lt;br&gt;
c    3&lt;br&gt;
d    4&lt;br&gt;
e    5&lt;br&gt;
Name: beta, dtype: float64&lt;/p&gt;

&lt;p&gt;Rows can also be selected using slicing or a Boolean array (Boolean mask).&lt;/p&gt;

&lt;p&gt;print("Selecting by slices:")&lt;br&gt;
print(df[1:3])&lt;br&gt;
bool_vec = [True, False, True, True, False]&lt;br&gt;
print("Selecting by boolean vector:")&lt;br&gt;
print(df[bool_vec])&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;Selecting by slices:&lt;br&gt;
       a  b  c  d   e&lt;br&gt;
beta   1  2  3  4   5&lt;br&gt;
gamma  2  4  6  8  10&lt;br&gt;
Selecting by boolean vector:&lt;br&gt;
       a  b  c   d   e&lt;br&gt;
alpha  0  0  0   0   0&lt;br&gt;
gamma  2  4  6   8  10&lt;br&gt;
delta  3  6  9  12  15&lt;/p&gt;

&lt;p&gt;Rows and columns can be combined to select specific data.&lt;/p&gt;

&lt;p&gt;print(df[['b', 'd']].iloc[[1, 3]])&lt;br&gt;
print(df.iloc[[1, 3]][['b', 'd']])&lt;br&gt;
print(df[['b', 'd']].loc[['beta', 'delta']])&lt;br&gt;
print(df.loc[['beta', 'delta']][['b', 'd']])&lt;br&gt;
the output:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   b   d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;beta   2   4&lt;br&gt;
delta  6  12&lt;br&gt;
       b   d&lt;br&gt;
beta   2   4&lt;br&gt;
delta  6  12&lt;br&gt;
       b   d&lt;br&gt;
beta   2   4&lt;br&gt;
delta  6  12&lt;br&gt;
       b   d&lt;br&gt;
beta   2   4&lt;br&gt;
delta  6  12&lt;/p&gt;

&lt;p&gt;If you want to access a specific element at a particular position (rather than an entire row or column), the fastest way is to use dataframe.at and dataframe.iat, which access data by label and integer position, respectively.&lt;/p&gt;

&lt;p&gt;print(df.iat[2, 3])&lt;br&gt;
print(df.at['gamma', 'd'])&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;8.0&lt;br&gt;
8.0&lt;/p&gt;

</description>
      <category>ai</category>
      <category>web3</category>
    </item>
    <item>
      <title>godzilla.dev — AI x Quant Trader Series — Day 4</title>
      <dc:creator>KX</dc:creator>
      <pubDate>Sat, 04 Jul 2026 04:18:19 +0000</pubDate>
      <link>https://dev.to/godzilla_dev/godzilladev-ai-x-quant-trader-series-day-4-25gc</link>
      <guid>https://dev.to/godzilla_dev/godzilladev-ai-x-quant-trader-series-day-4-25gc</guid>
      <description>&lt;p&gt;source: &lt;a href="https://godzilla.dev/learning/ai_quant_traders_series_4/" rel="noopener noreferrer"&gt;https://godzilla.dev/learning/ai_quant_traders_series_4/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;See below for godzilla.dev materials about: AI x Quant Trader Series - Day 4&lt;/p&gt;

&lt;p&gt;"Widely used Python Libraries"¶&lt;br&gt;
Last time we introduced NumPy. In this article, we'll focus on another commonly used library in quantitative finance: SciPy.&lt;/p&gt;

&lt;p&gt;SciPy¶&lt;br&gt;
Overview of SciPy¶&lt;br&gt;
In the previous article, we briefly introduced NumPy. Now let’s take a look at what SciPy can do. While NumPy handles vector and matrix operations—essentially functioning like an advanced scientific calculator—SciPy builds on top of NumPy and provides a more comprehensive and advanced set of functionalities. It offers a wide array of functions for statistics, optimization, interpolation, numerical integration, signal processing, and more, covering almost all fundamental scientific computing tasks.&lt;/p&gt;

&lt;p&gt;In quantitative analysis, the most commonly used areas are statistics and optimization. Therefore, this article will focus on SciPy’s statistics and optimization modules. Other modules will be introduced in future articles when relevant.&lt;/p&gt;

&lt;p&gt;This article will involve some matrix algebra. If you find it difficult, feel free to skip Part 3 or try to understand the concepts using one-dimensional scalars instead of higher-dimensional vectors.&lt;/p&gt;

&lt;p&gt;As always, let's start by importing the necessary modules. Here, we’ll be using the statistics and optimization parts of SciPy:&lt;/p&gt;

&lt;p&gt;import numpy as np&lt;br&gt;
import scipy.stats as stats&lt;br&gt;
import scipy.optimize as opt&lt;br&gt;
Statistics Module¶&lt;br&gt;
Generating Random Numbers¶&lt;br&gt;
Let’s begin with generating random numbers, as this will make it easier to demonstrate other concepts later. To generate n random numbers, you can use rv_continuous.rvs(size=n) or rv_discrete.rvs(size=n).&lt;/p&gt;

&lt;p&gt;rv_continuous refers to continuous probability distributions such as:&lt;/p&gt;

&lt;p&gt;Uniform distribution: uniform&lt;/p&gt;

&lt;p&gt;Normal distribution: norm&lt;/p&gt;

&lt;p&gt;Beta distribution: beta, etc.&lt;/p&gt;

&lt;p&gt;rv_discrete refers to discrete probability distributions such as:&lt;/p&gt;

&lt;p&gt;Bernoulli distribution: bernoulli&lt;/p&gt;

&lt;p&gt;Geometric distribution: geom&lt;/p&gt;

&lt;p&gt;Poisson distribution: poisson, etc.&lt;/p&gt;

&lt;p&gt;For example, to generate:&lt;/p&gt;

&lt;p&gt;10 random numbers in the interval 0,1 from a uniform distribution, and&lt;/p&gt;

&lt;p&gt;10 random numbers from a Beta distribution with parameters α and β (denoted as Beta(α,β)):&lt;/p&gt;

&lt;p&gt;rv_unif = stats.uniform.rvs(size=10)&lt;br&gt;
print rv_unif&lt;br&gt;
rv_beta = stats.beta.rvs(size=10, a=4, b=2)&lt;br&gt;
print rv_beta&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;[ 0.6419336   0.48403001  0.89548809  0.73837498  0.65744886  0.41845577&lt;br&gt;
  0.3823512   0.0985301   0.66785949  0.73163835]&lt;br&gt;
[ 0.82164685  0.69563836  0.74207073  0.94348192  0.82979411  0.87013796&lt;br&gt;
  0.78412952  0.47508183  0.29296073  0.52551156]&lt;/p&gt;

&lt;p&gt;Each random distribution function in SciPy comes with built-in default parameters—for example, the uniform distribution defaults to the range 0,1. However, when you need to modify these parameters, having to type out the full command each time can be a bit tedious.&lt;/p&gt;

&lt;p&gt;To simplify this, SciPy provides a "freezing" feature. This allows you to create a frozen distribution object with fixed parameters, so you don't need to repeatedly specify them. This is particularly useful in scenarios where you work with the same distribution settings multiple times.&lt;/p&gt;

&lt;p&gt;For example, in the case of the Beta distribution, instead of specifying the parameters α and β every time you call .rvs(), you can define a frozen distribution like this:&lt;/p&gt;

&lt;p&gt;np.random.seed(seed=2015)&lt;br&gt;
rv_beta = stats.beta.rvs(size=10, a=4, b=2)&lt;br&gt;
print "method 1:"&lt;br&gt;
print rv_beta&lt;/p&gt;

&lt;p&gt;np.random.seed(seed=2015)&lt;br&gt;
beta = stats.beta(a=4, b=2)&lt;br&gt;
print "method 2:"&lt;br&gt;
print beta.rvs(size=10)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;method 1:&lt;br&gt;
[ 0.43857338  0.9411551   0.75116671  0.92002864  0.62030521  0.56585548&lt;br&gt;
  0.41843548  0.5953096   0.88983036  0.94675351]&lt;br&gt;
method 2:&lt;br&gt;
[ 0.43857338  0.9411551   0.75116671  0.92002864  0.62030521  0.56585548&lt;br&gt;
  0.41843548  0.5953096   0.88983036  0.94675351]&lt;/p&gt;

&lt;p&gt;Hypothesis Testing¶&lt;br&gt;
Now, let’s generate a dataset and examine its related statistical properties. (You can find the parameters and documentation for the relevant distributions here: &lt;a href="http://docs.scipy.org/doc/scipy/reference/stats.html" rel="noopener noreferrer"&gt;http://docs.scipy.org/doc/scipy/reference/stats.html&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;norm_dist = stats.norm(loc=0.5, scale=2)&lt;br&gt;
n = 200&lt;br&gt;
dat = norm_dist.rvs(size=n)&lt;br&gt;
print "mean of data is: " + str(np.mean(dat))&lt;br&gt;
print "median of data is: " + str(np.median(dat))&lt;br&gt;
print "standard deviation of data is: " + str(np.std(dat))&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;mean of data is: 0.383309149888&lt;br&gt;
median of data is: 0.394980561217&lt;br&gt;
standard deviation of data is: 2.00589851641&lt;/p&gt;

&lt;p&gt;Suppose this dataset represents actual observed data—such as daily returns of a stock. We can perform a basic analysis on it. One of the simplest analyses is to test whether this dataset follows a given distribution, such as the normal distribution.&lt;/p&gt;

&lt;p&gt;This is a classic one-sample hypothesis testing problem. A commonly used method for this is the Kolmogorov–Smirnov test (K-S test).&lt;/p&gt;

&lt;p&gt;In a one-sample K-S test, the null hypothesis is that the sample comes from the specified theoretical distribution.&lt;/p&gt;

&lt;p&gt;In SciPy, this can be done using the kstest function, where the parameters are:&lt;/p&gt;

&lt;p&gt;the dataset,&lt;/p&gt;

&lt;p&gt;the name of the distribution to test against (as a string),&lt;/p&gt;

&lt;p&gt;and the parameters of that distribution.&lt;/p&gt;

&lt;p&gt;mu = np.mean(dat)&lt;br&gt;
sigma = np.std(dat)&lt;br&gt;
stat_val, p_val = stats.kstest(dat, 'norm', (mu, sigma))&lt;br&gt;
print 'KS-statistic D = %6.3f p-value = %6.4f' % (stat_val, p_val)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;KS-statistic D =  0.037 p-value = 0.9428&lt;/p&gt;

&lt;p&gt;If the p-value from the hypothesis test is large (note that under the null hypothesis, the p-value is a random variable uniformly distributed over the interval 0,1; see: &lt;a href="http://en.wikipedia.org/wiki/P-value" rel="noopener noreferrer"&gt;http://en.wikipedia.org/wiki/P-value&lt;/a&gt;), then we fail to reject the null hypothesis—in other words, we accept that the data passes the normality test.&lt;/p&gt;

&lt;p&gt;Given the assumption of normality, we can further test whether the mean of this dataset is significantly different from zero. A common method for this is the t-test, specifically the one-sample t-test.&lt;/p&gt;

&lt;p&gt;In SciPy, this is done using the ttest_1samp function:&lt;/p&gt;

&lt;p&gt;stat_val, p_val = stats.ttest_1samp(dat, 0)&lt;br&gt;
print 'One-sample t-statistic D = %6.3f, p-value = %6.4f' % (stat_val, p_val)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;One-sample t-statistic D =  2.696, p-value = 0.0076&lt;/p&gt;

&lt;p&gt;We observe that p-value &amp;lt; 0.05, which means that under a significance level of 0.05, we should reject the null hypothesis—that is, the data’s mean is not equal to 0.&lt;/p&gt;

&lt;p&gt;Next, let’s generate another dataset and try a two-sample t-test using ttest_ind. This test checks whether two independent samples have significantly different means.&lt;/p&gt;

&lt;p&gt;norm_dist2 = stats.norm(loc=-0.2, scale=1.2)&lt;br&gt;
dat2 = norm_dist2.rvs(size=n/2)&lt;br&gt;
stat_val, p_val = stats.ttest_ind(dat, dat2, equal_var=False)&lt;br&gt;
print 'Two-sample t-statistic D = %6.3f, p-value = %6.4f' % (stat_val, p_val)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;Two-sample t-statistic D =  3.572, p-value = 0.0004&lt;/p&gt;

&lt;p&gt;Note that in this case, the second dataset we generated differs from the first in terms of sample size and variance. Therefore, when performing the t-test, we need to use Welch’s t-test by setting equal_var=False in the ttest_ind function.&lt;/p&gt;

&lt;p&gt;We again obtain a relatively small p-value, which means that under the 0.05 significance level, we reject the null hypothesis and conclude that the two groups do not have equal means.&lt;/p&gt;

&lt;p&gt;The scipy.stats module also provides many other hypothesis testing functions, such as:&lt;/p&gt;

&lt;p&gt;bartlett and levene: for testing whether two or more samples have equal variances.&lt;/p&gt;

&lt;p&gt;anderson_ksamp: for performing the Anderson-Darling k-sample test, used to check whether multiple samples come from the same distribution.&lt;/p&gt;

&lt;p&gt;These tools are useful for more advanced statistical analysis depending on the properties of your data.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>web3</category>
    </item>
    <item>
      <title>godzilla.dev — AI x Quant Trader Series — Day 3</title>
      <dc:creator>KX</dc:creator>
      <pubDate>Sat, 04 Jul 2026 04:06:50 +0000</pubDate>
      <link>https://dev.to/godzilla_dev/godzilladev-ai-x-quant-trader-series-day-3-54hf</link>
      <guid>https://dev.to/godzilla_dev/godzilladev-ai-x-quant-trader-series-day-3-54hf</guid>
      <description>&lt;p&gt;source: &lt;a href="https://godzilla.dev/learning/ai_quant_traders_series_3/" rel="noopener noreferrer"&gt;https://godzilla.dev/learning/ai_quant_traders_series_3/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;See below for godzilla.dev materials about: AI x Quant Trader Series - Day 3&lt;/p&gt;

&lt;p&gt;"Widely used Python Libraries"¶&lt;br&gt;
The upcoming series will introduce some of the most widely used Python libraries in quantitative finance:&lt;/p&gt;

&lt;p&gt;numpy&lt;/p&gt;

&lt;p&gt;scipy&lt;/p&gt;

&lt;p&gt;pandas&lt;/p&gt;

&lt;p&gt;matplotlib&lt;/p&gt;

&lt;p&gt;Each will be explained one by one for beginners.&lt;/p&gt;

&lt;p&gt;NumPy¶&lt;br&gt;
What is NumPy¶&lt;br&gt;
Quantitative analysis involves a large amount of numerical computation, so having an efficient and convenient scientific computing tool is essential. Python was not originally designed as a language for scientific computing. However, as more people recognized its ease of use, a wide range of external extensions emerged—NumPy (Numeric Python) being one of them.&lt;/p&gt;

&lt;p&gt;NumPy provides a wealth of tools for numerical programming, making it easy to handle operations on vectors, matrices, and more, which significantly facilitates scientific computing tasks. On the other hand, Python is free, and compared to the high costs of using software like MATLAB, NumPy has made Python an increasingly popular choice.&lt;/p&gt;

&lt;p&gt;Let’s take a quick look at how to get started with NumPy:&lt;/p&gt;

&lt;p&gt;import numpy&lt;br&gt;
numpy.version.full_version&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;2.2.4&lt;/p&gt;

&lt;p&gt;We used the import command to load the NumPy library and checked the version with numpy.version.full_version, which turned out to be 2.2.4&lt;/p&gt;

&lt;p&gt;In the upcoming lessons, we’ll frequently use functions from NumPy. However, constantly writing numpy as a prefix before every function call can be tedious. As mentioned earlier, there’s a shortcut when importing external modules: using from numpy import * allows you to access all functions without the prefix.&lt;/p&gt;

&lt;p&gt;Problem solved? Not so fast!&lt;/p&gt;

&lt;p&gt;Python has thousands of external modules, and in practice, it’s common to import several of them at once. If two modules happen to include functions or properties with the same name, this can lead to conflicts. To avoid such name clashes—also known as namespace confusion—it’s generally better to keep the module prefix.&lt;/p&gt;

&lt;p&gt;So is there a simpler way? Yes—when importing a module, you can assign it an alias. This way, you don’t need to write the full module name every time. For example, we can import NumPy as np and call version.full_version like this:&lt;/p&gt;

&lt;p&gt;import numpy as np&lt;br&gt;
np.version.full_version&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;2.2.4&lt;/p&gt;

&lt;p&gt;A First Look at NumPy Objects: Arrays¶&lt;br&gt;
The fundamental object in NumPy is the homogeneous multidimensional array, meaning all elements in the array must be of the same type—just like arrays in C++. For example, character and numeric types cannot coexist in the same array.&lt;/p&gt;

&lt;p&gt;Let’s look at an example:&lt;/p&gt;

&lt;p&gt;a = np.arange(20)&lt;br&gt;
Here, we’ve created a one-dimensional array a starting from 0, with a step size of 1, and a total length of 20. In Python, indexing starts at 0, so users coming from R or MATLAB should be cautious about this difference. You can use print to view the array:&lt;/p&gt;

&lt;p&gt;print(a)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19]&lt;/p&gt;

&lt;p&gt;We can use the type function to check the type of a. Here, it shows that a is an array:&lt;/p&gt;

&lt;p&gt;type(a)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;numpy.ndarray&lt;/p&gt;

&lt;p&gt;Using the reshape function, we can restructure this array. For example, we can create a 4×5 two-dimensional array. The arguments passed to reshape specify the size of each dimension, and the data is arranged in order by dimension (for two dimensions, this means row-wise order). This is different from R, where arrays are filled column-wise by default.&lt;/p&gt;

&lt;p&gt;a = a.reshape(4, 5)&lt;br&gt;
print(a)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;[[ 0  1  2  3  4]&lt;br&gt;
 [ 5  6  7  8  9]&lt;br&gt;
 [10 11 12 13 14]&lt;br&gt;
 [15 16 17 18 19]]&lt;/p&gt;

&lt;p&gt;Creating higher-dimensional arrays is no problem either:&lt;/p&gt;

&lt;p&gt;a = a.reshape(2, 2, 5)&lt;br&gt;
print(a)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;[[[ 0  1  2  3  4]&lt;br&gt;
  [ 5  6  7  8  9]]&lt;/p&gt;

&lt;p&gt;[[10 11 12 13 14]&lt;br&gt;
  [15 16 17 18 19]]]&lt;/p&gt;

&lt;p&gt;Since a is an array, we can call its associated functions to further inspect its properties:&lt;/p&gt;

&lt;p&gt;ndim shows the number of dimensions&lt;/p&gt;

&lt;p&gt;shape returns the size of each dimension&lt;/p&gt;

&lt;p&gt;size gives the total number of elements (equal to the product of all dimension sizes)&lt;/p&gt;

&lt;p&gt;dtype displays the data type of the elements&lt;/p&gt;

&lt;p&gt;itemsize (not dsize) shows the number of bytes each element occupies&lt;/p&gt;

&lt;p&gt;a.ndim&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;3&lt;/p&gt;

&lt;p&gt;a.shape&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;(2, 2, 5)&lt;/p&gt;

&lt;p&gt;a.size&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;20&lt;/p&gt;

&lt;p&gt;a.dtype&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;dtype('int64')&lt;/p&gt;

&lt;p&gt;Creating Arrays¶&lt;br&gt;
Arrays can be created by converting lists, and higher-dimensional arrays can be created by converting nested lists.&lt;/p&gt;

&lt;p&gt;raw = [0,1,2,3,4]&lt;br&gt;
a = np.array(raw)&lt;br&gt;
a&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;array([0, 1, 2, 3, 4])&lt;/p&gt;

&lt;p&gt;raw = [[0,1,2,3,4], [5,6,7,8,9]]&lt;br&gt;
b = np.array(raw)&lt;br&gt;
b&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;array([[0, 1, 2, 3, 4],&lt;br&gt;
       [5, 6, 7, 8, 9]])&lt;/p&gt;

&lt;p&gt;Some special arrays have dedicated commands for creation—for example, a 4×5 matrix filled with zeros:&lt;/p&gt;

&lt;p&gt;d = (4, 5)&lt;br&gt;
np.zeros(d)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;array([[ 0.,  0.,  0.,  0.,  0.],&lt;br&gt;
       [ 0.,  0.,  0.,  0.,  0.],&lt;br&gt;
       [ 0.,  0.,  0.,  0.,  0.],&lt;br&gt;
       [ 0.,  0.,  0.,  0.,  0.]])&lt;/p&gt;

&lt;p&gt;By default, the generated array is of float type, but you can specify the data type to create an integer array instead:&lt;/p&gt;

&lt;p&gt;d = (4, 5)&lt;br&gt;
np.ones(d, dtype=int)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;array([[1, 1, 1, 1, 1],&lt;br&gt;
       [1, 1, 1, 1, 1],&lt;br&gt;
       [1, 1, 1, 1, 1],&lt;br&gt;
       [1, 1, 1, 1, 1]])&lt;/p&gt;

&lt;p&gt;An array of random numbers in the interval [0,1):&lt;/p&gt;

&lt;p&gt;np.random.rand(5)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;array([ 0.93807818,  0.45307847,  0.90732828,  0.36099623,  0.71981451])&lt;/p&gt;

&lt;p&gt;Array Operations¶&lt;br&gt;
Basic arithmetic operations have been overloaded—operators like +, -, *, and / are all applied element-wise to the entire array. For example, with addition:&lt;/p&gt;

&lt;p&gt;a = np.array([[1.0, 2], [2, 4]])&lt;br&gt;
print("a:")&lt;br&gt;
print(a)&lt;br&gt;
b = np.array([[3.2, 1.5], [2.5, 4]])&lt;br&gt;
print("b:")&lt;br&gt;
print(b)&lt;br&gt;
print("a+b:")&lt;br&gt;
print(a+b)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;a:&lt;br&gt;
[[ 1.  2.]&lt;br&gt;
 [ 2.  4.]]&lt;br&gt;
b:&lt;br&gt;
[[ 3.2  1.5]&lt;br&gt;
 [ 2.5  4. ]]&lt;br&gt;
a+b:&lt;br&gt;
[[ 4.2  3.5]&lt;br&gt;
 [ 4.5  8. ]]&lt;/p&gt;

&lt;p&gt;Here, you can see that even though only one element in array a is a float and the rest are integers, Python automatically converts all elements to float—because NumPy arrays are homogeneous. Also, when adding two 2D arrays, the size of each dimension must match.&lt;/p&gt;

&lt;p&gt;Of course, in NumPy, these operators can also be used between a scalar and an array. The result is that the operation is applied element-wise between the scalar and each element in the array, and the output is still an array.&lt;/p&gt;

&lt;p&gt;print("3 * a:")&lt;br&gt;
print(3 * a)&lt;br&gt;
print("b + 1.8:")&lt;br&gt;
print(b + 1.8)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;3 * a:&lt;br&gt;
[[  3.   6.]&lt;br&gt;
 [  6.  12.]]&lt;br&gt;
b + 1.8:&lt;br&gt;
[[ 5.   3.3]&lt;br&gt;
 [ 4.3  5.8]]&lt;/p&gt;

&lt;p&gt;Just like in C++, the +=, -=, *=, and /= operators are also supported in NumPy.&lt;/p&gt;

&lt;p&gt;a /= 2&lt;br&gt;
print(a)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;[[ 0.5  1. ]&lt;br&gt;
 [ 1.   2. ]]&lt;/p&gt;

&lt;p&gt;Taking square roots or computing exponentials is also very straightforward:&lt;/p&gt;

&lt;p&gt;print("a:")&lt;br&gt;
print(a)&lt;br&gt;
print("np.exp(a):")&lt;br&gt;
print(np.exp(a))&lt;br&gt;
print("np.sqrt(a):")&lt;br&gt;
print(np.sqrt(a))&lt;br&gt;
print("np.square(a):")&lt;br&gt;
print(np.square(a))&lt;br&gt;
print("np.power(a, 3):")&lt;br&gt;
print(np.power(a, 3))&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;a:&lt;br&gt;
[[ 0.5  1. ]&lt;br&gt;
 [ 1.   2. ]]&lt;br&gt;
np.exp(a):&lt;br&gt;
[[ 1.64872127  2.71828183]&lt;br&gt;
 [ 2.71828183  7.3890561 ]]&lt;br&gt;
np.sqrt(a):&lt;br&gt;
[[ 0.70710678  1.        ]&lt;br&gt;
 [ 1.          1.41421356]]&lt;br&gt;
np.square(a):&lt;br&gt;
[[ 0.25  1.  ]&lt;br&gt;
 [ 1.    4.  ]]&lt;br&gt;
np.power(a, 3):&lt;br&gt;
[[ 0.125  1.   ]&lt;br&gt;
 [ 1.     8.   ]]&lt;/p&gt;

&lt;p&gt;Need to find the maximum or minimum of a 2D array? Want to calculate the total sum of all elements, or sum by rows or columns? Use a for loop? No need—NumPy’s ndarray class already provides built-in functions for these operations:&lt;/p&gt;

&lt;p&gt;a = np.arange(20).reshape(4,5)&lt;br&gt;
print("a:")&lt;br&gt;
print(a)&lt;br&gt;
print("sum of all elements in a: " + str(a.sum()))&lt;br&gt;
print("maximum element in a: " + str(a.max()))&lt;br&gt;
print("minimum element in a: " + str(a.min()))&lt;br&gt;
print("maximum element in each row of a: " + str(a.max(axis=1)))&lt;br&gt;
print("minimum element in each column of a: " + str(a.min(axis=0)))&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;a:&lt;br&gt;
[[ 0  1  2  3  4]&lt;br&gt;
 [ 5  6  7  8  9]&lt;br&gt;
 [10 11 12 13 14]&lt;br&gt;
 [15 16 17 18 19]]&lt;br&gt;
sum of all elements in a: 190&lt;br&gt;
maximum element in a: 19&lt;br&gt;
minimum element in a: 0&lt;br&gt;
maximum element in each row of a: [ 4  9 14 19]&lt;br&gt;
minimum element in each column of a: [0 1 2 3 4]&lt;/p&gt;

&lt;p&gt;Matrix operations are heavily used in scientific computing. In addition to arrays, NumPy also provides a dedicated matrix object. There are two main differences between matrices and arrays:&lt;/p&gt;

&lt;p&gt;Matrices are strictly 2-dimensional, whereas arrays can have any number of dimensions (as long as they are positive integers).&lt;/p&gt;

&lt;p&gt;The * operator performs matrix multiplication for matrix objects, meaning the number of columns in the left matrix must equal the number of rows in the right matrix. In contrast, for arrays, the * operator performs element-wise multiplication, requiring that the arrays have the same shape.&lt;/p&gt;

&lt;p&gt;You can convert an array to a matrix using asmatrix or mat, or you can create a matrix directly. For example:&lt;/p&gt;

&lt;p&gt;a = np.arange(20).reshape(4, 5)&lt;br&gt;
a = np.asmatrix(a)&lt;br&gt;
print(type(a))&lt;/p&gt;

&lt;p&gt;b = np.matrix('1.0 2.0; 3.0 4.0')&lt;br&gt;
print(type(b))&lt;br&gt;
the output:&lt;/p&gt;



&lt;p&gt;Let’s take another look at matrix multiplication. Here, we use the arange function to generate another matrix b. The arange function can also be called with the form arange(start, stop, step) to create an arithmetic sequence. Note that the range includes the start value but excludes the stop value.&lt;/p&gt;

&lt;p&gt;b = np.arange(2, 45, 3).reshape(5, 3)&lt;br&gt;
b = np.mat(b)&lt;br&gt;
print(b)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;[[ 2  5  8]&lt;br&gt;
 [11 14 17]&lt;br&gt;
 [20 23 26]&lt;br&gt;
 [29 32 35]&lt;br&gt;
 [38 41 44]]&lt;/p&gt;

&lt;p&gt;Some might ask: arange specifies the step size, but what if you want to specify the length of the generated 1D array instead? No problem — linspace can do just that.&lt;/p&gt;

&lt;p&gt;np.linspace(0, 2, 9)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;array([ 0.  ,  0.25,  0.5 ,  0.75,  1.  ,  1.25,  1.5 ,  1.75,  2.  ])&lt;/p&gt;

&lt;p&gt;Back to our problem: perform matrix multiplication on matrices a and b.&lt;/p&gt;

&lt;p&gt;print("matrix a:")&lt;br&gt;
print(a)&lt;br&gt;
print("matrix b:")&lt;br&gt;
print(b)&lt;br&gt;
c = a * b&lt;br&gt;
print("matrix c:")&lt;br&gt;
print(c)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;matrix a:&lt;br&gt;
[[ 0  1  2  3  4]&lt;br&gt;
 [ 5  6  7  8  9]&lt;br&gt;
 [10 11 12 13 14]&lt;br&gt;
 [15 16 17 18 19]]&lt;br&gt;
matrix b:&lt;br&gt;
[[ 2  5  8]&lt;br&gt;
 [11 14 17]&lt;br&gt;
 [20 23 26]&lt;br&gt;
 [29 32 35]&lt;br&gt;
 [38 41 44]]&lt;br&gt;
matrix c:&lt;br&gt;
[[ 290  320  350]&lt;br&gt;
 [ 790  895 1000]&lt;br&gt;
 [1290 1470 1650]&lt;br&gt;
 [1790 2045 2300]]&lt;/p&gt;

&lt;p&gt;Array element access¶&lt;br&gt;
Elements of arrays and matrices can be accessed using indices. The following examples all use two-dimensional arrays (or matrices).&lt;/p&gt;

&lt;p&gt;a = np.array([[3.2, 1.5], [2.5, 4]])&lt;br&gt;
print(a[0][1])&lt;br&gt;
print(a[0, 1])&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;1.5&lt;br&gt;
1.5&lt;/p&gt;

&lt;p&gt;Array element values can be modified using index-based access.&lt;/p&gt;

&lt;p&gt;b = a&lt;br&gt;
a[0][1] = 2.0&lt;br&gt;
print("a:")&lt;br&gt;
print(a)&lt;br&gt;
print("b:")&lt;br&gt;
print(b)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;a:&lt;br&gt;
[[ 3.2  2. ]&lt;br&gt;
 [ 2.5  4. ]]&lt;br&gt;
b:&lt;br&gt;
[[ 3.2  2. ]&lt;br&gt;
 [ 2.5  4. ]]&lt;/p&gt;

&lt;p&gt;Now here comes the problem: you clearly modified a[0][1], so why did b[0][1] also change? This is a common pitfall in Python programming. The reason is that Python didn't actually make a true copy of a and assign it to b; instead, it made b point to the same memory address as a. To create a real copy of a for b, you can use copy.&lt;/p&gt;

&lt;p&gt;a = np.array([[3.2, 1.5], [2.5, 4]])&lt;br&gt;
b = a.copy()&lt;br&gt;
a[0][1] = 2.0&lt;br&gt;
print("a:")&lt;br&gt;
print(a)&lt;br&gt;
print("b:")&lt;br&gt;
print(b)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;a:&lt;br&gt;
[[ 3.2  2. ]&lt;br&gt;
 [ 2.5  4. ]]&lt;br&gt;
b:&lt;br&gt;
[[ 3.2  1.5]&lt;br&gt;
 [ 2.5  4. ]]&lt;/p&gt;

&lt;p&gt;If you reassign a, meaning you point it to a different address, b will still remain at the original address.&lt;/p&gt;

&lt;p&gt;a = np.array([[3.2, 1.5], [2.5, 4]])&lt;br&gt;
b = a&lt;br&gt;
a = np.array([[2, 1], [9, 3]])&lt;br&gt;
print("a:")&lt;br&gt;
print(a)&lt;br&gt;
print("b:")&lt;br&gt;
print(b)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;a:&lt;br&gt;
[[2 1]&lt;br&gt;
 [9 3]]&lt;br&gt;
b:&lt;br&gt;
[[ 3.2  1.5]&lt;br&gt;
 [ 2.5  4. ]]&lt;/p&gt;

&lt;p&gt;The colon : can be used to access all elements along a certain dimension — for example, to extract a specific column from a matrix.&lt;/p&gt;

&lt;p&gt;a = np.arange(20).reshape(4, 5)&lt;br&gt;
print("a:")&lt;br&gt;
print(a)&lt;br&gt;
print("the 2nd and 4th column of a:")&lt;br&gt;
print(a[:,[1,3]])&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;a:&lt;br&gt;
[[ 0  1  2  3  4]&lt;br&gt;
 [ 5  6  7  8  9]&lt;br&gt;
 [10 11 12 13 14]&lt;br&gt;
 [15 16 17 18 19]]&lt;br&gt;
the 2nd and 4th column of a:&lt;br&gt;
[[ 1  3]&lt;br&gt;
 [ 6  8]&lt;br&gt;
 [11 13]&lt;br&gt;
 [16 18]]&lt;/p&gt;

&lt;p&gt;Let’s try something a bit more complex: extracting elements that meet certain conditions — a common task in data processing, usually applied to a single row or column. In the example below, we extract the third column elements (12 and 17) that correspond to the rows where the first column values are greater than 5 (i.e., 10 and 15).&lt;/p&gt;

&lt;p&gt;a[:, 2][a[:, 0] &amp;gt; 5]&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;array([12, 17])&lt;/p&gt;

&lt;p&gt;The where function can be used to find the positions of specific values in an array.&lt;/p&gt;

&lt;p&gt;loc = numpy.where(a==11)&lt;br&gt;
print(loc)&lt;br&gt;
print(a[loc[0][0], loc[1][0]])&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;(array([2]), array([1]))&lt;br&gt;
11&lt;/p&gt;

&lt;p&gt;Matrix operations¶&lt;br&gt;
Let’s continue using a matrix (or 2D array) as an example. First, let’s look at matrix transposition.&lt;/p&gt;

&lt;p&gt;a = np.random.rand(2,4)&lt;br&gt;
print("a:")&lt;br&gt;
print(a)&lt;br&gt;
a = np.transpose(a)&lt;br&gt;
print("a is an array, by using transpose(a):")&lt;br&gt;
print(a)&lt;br&gt;
b = np.random.rand(2,4)&lt;br&gt;
b = np.mat(b)&lt;br&gt;
print("b:")&lt;br&gt;
print(b)&lt;br&gt;
print("b is a matrix, by using b.T:")&lt;br&gt;
print(b.T)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;a:&lt;br&gt;
[[ 0.17571282  0.98510461  0.94864387  0.50078988]&lt;br&gt;
 [ 0.09457965  0.70251658  0.07134875  0.43780173]]&lt;br&gt;
a is an array, by using transpose(a):&lt;br&gt;
[[ 0.17571282  0.09457965]&lt;br&gt;
 [ 0.98510461  0.70251658]&lt;br&gt;
 [ 0.94864387  0.07134875]&lt;br&gt;
 [ 0.50078988  0.43780173]]&lt;br&gt;
b:&lt;br&gt;
[[ 0.09653644  0.46123468  0.50117363  0.69752578]&lt;br&gt;
 [ 0.60756723  0.44492537  0.05946373  0.4858369 ]]&lt;br&gt;
b is a matrix, by using b.T:&lt;br&gt;
[[ 0.09653644  0.60756723]&lt;br&gt;
 [ 0.46123468  0.44492537]&lt;br&gt;
 [ 0.50117363  0.05946373]&lt;br&gt;
 [ 0.69752578  0.4858369 ]]&lt;/p&gt;

&lt;p&gt;Matrix inversion&lt;/p&gt;

&lt;p&gt;import numpy.linalg as nlg&lt;br&gt;
a = np.random.rand(2,2)&lt;br&gt;
a = np.mat(a)&lt;br&gt;
print("a:")&lt;br&gt;
print(a)&lt;br&gt;
ia = nlg.inv(a)&lt;br&gt;
print("inverse of a:")&lt;br&gt;
print(ia)&lt;br&gt;
print("a * inv(a)")&lt;br&gt;
print(a * ia)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;a:&lt;br&gt;
[[ 0.86211266  0.6885563 ]&lt;br&gt;
 [ 0.28798536  0.70810425]]&lt;br&gt;
inverse of a:&lt;br&gt;
[[ 1.71798445 -1.6705577 ]&lt;br&gt;
 [-0.69870271  2.09163573]]&lt;br&gt;
a * inv(a)&lt;br&gt;
[[ 1.  0.]&lt;br&gt;
 [ 0.  1.]]&lt;/p&gt;

&lt;p&gt;Computing eigenvalues and eigenvectors&lt;/p&gt;

&lt;p&gt;a = np.random.rand(3,3)&lt;br&gt;
eig_value, eig_vector = nlg.eig(a)&lt;br&gt;
print("eigen value:")&lt;br&gt;
print(eig_value)&lt;br&gt;
print("eigen vector:")&lt;br&gt;
print(eig_vector)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;eigen value:&lt;br&gt;
[ 1.35760609  0.43205379 -0.53470662]&lt;br&gt;
eigen vector:&lt;br&gt;
[[-0.76595379 -0.88231952 -0.07390831]&lt;br&gt;
 [-0.55170557  0.21659887 -0.74213622]&lt;br&gt;
 [-0.33005418  0.41784829  0.66616169]]&lt;/p&gt;

&lt;p&gt;Concatenate two vectors into a matrix by columns.&lt;/p&gt;

&lt;p&gt;a = np.array((1,2,3))&lt;br&gt;
b = np.array((2,3,4))&lt;br&gt;
print np.column_stack((a,b))&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;[[1 2]&lt;br&gt;
 [2 3]&lt;br&gt;
 [3 4]]&lt;/p&gt;

&lt;p&gt;After processing some data in a loop and obtaining results, it's often useful to combine those results into a matrix. This can be done using vstack and hstack.&lt;/p&gt;

&lt;p&gt;a = np.random.rand(2,2)&lt;br&gt;
b = np.random.rand(2,2)&lt;br&gt;
print("a:")&lt;br&gt;
print(a)&lt;br&gt;
print("b:")&lt;br&gt;
print(b)&lt;br&gt;
c = np.hstack([a,b])&lt;br&gt;
d = np.vstack([a,b])&lt;br&gt;
print("horizontal stacking a and b:")&lt;br&gt;
print(c)&lt;br&gt;
print("vertical stacking a and b:")&lt;br&gt;
print(d)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;a:&lt;br&gt;
[[ 0.6738195   0.4944045 ]&lt;br&gt;
 [ 0.25702675  0.15422012]]&lt;br&gt;
b:&lt;br&gt;
[[ 0.6738195   0.4944045 ]&lt;br&gt;
 [ 0.25702675  0.15422012]]&lt;br&gt;
horizontal stacking a and b:&lt;br&gt;
[[ 0.6738195   0.4944045   0.28058267  0.0967197 ]&lt;br&gt;
 [ 0.25702675  0.15422012  0.55191041  0.04694485]]&lt;br&gt;
vertical stacking a and b:&lt;br&gt;
[[ 0.6738195   0.4944045 ]&lt;br&gt;
 [ 0.25702675  0.15422012]&lt;br&gt;
 [ 0.28058267  0.0967197 ]&lt;br&gt;
 [ 0.55191041  0.04694485]]&lt;/p&gt;

&lt;p&gt;Missing Value¶&lt;br&gt;
Missing values are also a form of information in data analysis. NumPy provides nan to represent missing values, and isnan can be used to detect them.&lt;/p&gt;

&lt;p&gt;a = np.random.rand(2,2)&lt;br&gt;
a[0, 1] = np.nan&lt;br&gt;
print(np.isnan(a))&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;[[False  True]&lt;br&gt;
 [False False]]&lt;/p&gt;

&lt;p&gt;nan_to_num can be used to replace nan with 0. In the more advanced module pandas, which we’ll cover later, we’ll see that it provides functions that allow you to specify the replacement value for nan.&lt;/p&gt;

&lt;p&gt;print(np.nan_to_num(a))&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;[[ 0.58144238  0.        ]&lt;br&gt;
 [ 0.26789784  0.48664306]]&lt;/p&gt;

&lt;p&gt;NumPy offers many more functions. For a detailed understanding, you can refer to the following links: &lt;a href="http://wiki.scipy.org/Numpy_Example_List" rel="noopener noreferrer"&gt;http://wiki.scipy.org/Numpy_Example_List&lt;/a&gt; and &lt;a href="http://docs.scipy.org/doc/numpy" rel="noopener noreferrer"&gt;http://docs.scipy.org/doc/numpy&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>web3</category>
    </item>
    <item>
      <title>godzilla.dev — AI x Quant Trader Series — Day 2</title>
      <dc:creator>KX</dc:creator>
      <pubDate>Sat, 04 Jul 2026 04:04:53 +0000</pubDate>
      <link>https://dev.to/godzilla_dev/godzilladev-ai-x-quant-trader-series-day-2-57m4</link>
      <guid>https://dev.to/godzilla_dev/godzilladev-ai-x-quant-trader-series-day-2-57m4</guid>
      <description>&lt;p&gt;source: &lt;a href="https://godzilla.dev/learning/ai_quant_traders_series_2/" rel="noopener noreferrer"&gt;https://godzilla.dev/learning/ai_quant_traders_series_2/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;See below for godzilla.dev materials about: AI x Quant Trader Series - Day 2&lt;/p&gt;

&lt;p&gt;"Who will teach me about Python?"¶&lt;br&gt;
On the first day, We learned the basic operations of Python and several main container types.&lt;/p&gt;

&lt;p&gt;Today, We will learn Python's functions, loops and conditionals, and classes. With this, We will have a general understanding of Python. The learning outline for today is as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Functions¶&lt;br&gt;
a) Defining a function&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Loops and Conditionals¶&lt;br&gt;
a) if statements&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;b) while True / break statements&lt;/p&gt;

&lt;p&gt;c) for loops&lt;/p&gt;

&lt;p&gt;d) List comprehensions&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Classes¶
a) A casual talk about classes and objects&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;b) Defining a class&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Functions¶
a) Defining a function¶
(1) Definition Rules&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When introducing list methods, we already briefly mentioned functions. Anyone who has studied mathematics knows what a function is — it takes an input (a parameter) and returns a value. Functions can also be defined by yourself, using the following format:&lt;/p&gt;

&lt;p&gt;def function_name(parameter):&lt;br&gt;
    # function code&lt;br&gt;
In the function code, return indicates the value to be returned. For example, to define a square function square(x) that takes x as input and returns the square of x:&lt;/p&gt;

&lt;p&gt;def square(x):return x*x&lt;/p&gt;

&lt;p&gt;square(9)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;81&lt;/p&gt;

&lt;p&gt;(2) Defining Functions with Variable Parameters&lt;/p&gt;

&lt;p&gt;Sometimes you need to define a function with a variable number of parameters. There are several ways to do this:&lt;/p&gt;

&lt;p&gt;Assign default values to parameters For example, define a function like f(a, b=1, c='hehe'). In this case, the last two parameters are optional — if not specified during the function call, they will default to b=1 and c='hehe'. Therefore, the following calls are all valid:&lt;/p&gt;

&lt;p&gt;f('dsds')&lt;br&gt;
f('dsds', 2)&lt;br&gt;
f('dsds', 2, 'hdasda')&lt;br&gt;
Keyword arguments The method above fixes the order of parameters — the first value is assigned to the first parameter. With keyword arguments, however, you can specify which value goes to which parameter by name. For example, still using the function f(a, b=1, c='hehe'), you can call it like this:&lt;/p&gt;

&lt;p&gt;f(b=2, a=11)&lt;br&gt;
The order of parameters can be changed as long as you specify them using their keywords.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Loops and Conditionals¶
Note that Python uses indentation to indicate which block of code belongs to the loop.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;a) if statements¶&lt;br&gt;
Also note two things: first, indentation; and second, a colon (:) is required after the condition.&lt;/p&gt;

&lt;p&gt;j=2.67&lt;br&gt;
if j&amp;lt;3:&lt;br&gt;
    print('j&amp;lt;3')&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;j&amp;lt;3&lt;/p&gt;

&lt;p&gt;For multiple conditions, note that elseif should be written as elif. The standard format is:&lt;/p&gt;

&lt;p&gt;if condition1:&lt;br&gt;
    statement1&lt;br&gt;
elif condition2:&lt;br&gt;
    statement2&lt;br&gt;
else:&lt;br&gt;
    statement3&lt;br&gt;
Note that if, elif, and else are at the same indentation level — there should be no indentation before them.&lt;/p&gt;

&lt;p&gt;t=3&lt;br&gt;
if t&amp;lt;3:&lt;br&gt;
    print('t&amp;lt;3')&lt;br&gt;
elif t==3:&lt;br&gt;
    print('t=3')&lt;br&gt;
else:&lt;br&gt;
    print('t&amp;gt;3')&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;t=3&lt;/p&gt;

&lt;p&gt;b) while True / break statements¶&lt;br&gt;
The format of this statement is:&lt;/p&gt;

&lt;p&gt;while True:  # condition is true&lt;br&gt;
    statement&lt;br&gt;
    if break_condition:&lt;br&gt;
        break&lt;/p&gt;

&lt;p&gt;Here’s an example:&lt;/p&gt;

&lt;p&gt;a=3&lt;br&gt;
while a&amp;lt;10:&lt;br&gt;
    a=a+1&lt;br&gt;
    print(a)&lt;br&gt;
    if a==8: break&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;4&lt;br&gt;
5&lt;br&gt;
6&lt;br&gt;
7&lt;br&gt;
8&lt;/p&gt;

&lt;p&gt;Although the condition after while is a &amp;lt; 10, meaning the loop will continue as long as a is less than 10, the if condition specifies that the loop should break when a equals 8. Therefore, the output will only go up to 8.&lt;/p&gt;

&lt;p&gt;c) for loops¶&lt;br&gt;
No more explanation needed — you can iterate over a sequence, dictionary, etc.&lt;/p&gt;

&lt;p&gt;a=[1,2,3,4,5]&lt;br&gt;
for i in a:&lt;br&gt;
    print(i)&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;1&lt;br&gt;
2&lt;br&gt;
3&lt;br&gt;
4&lt;br&gt;
5&lt;/p&gt;

&lt;p&gt;d) List comprehensions¶&lt;br&gt;
List comprehensions are a way to create a new list from an existing one, working similarly to a for loop. The format is:&lt;/p&gt;

&lt;p&gt;[output_value for condition]&lt;br&gt;
When the condition is met, an output value is generated, and the final result is a list.&lt;/p&gt;

&lt;p&gt;[x*x for x in range(10)]&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]&lt;/p&gt;

&lt;p&gt;[x*x for x in range(10) if x%3==0]&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;[0, 9, 36, 81]&lt;/p&gt;

&lt;p&gt;The above example uses the sequence [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] to generate a new sequence.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Classes¶
a) A casual talk about classes and objects¶
A class is an abstract concept — it doesn't exist in the physical world in terms of time or space. A class simply defines the abstract attributes and behaviors for all its objects. For example, the class "Person" can represent many individuals, but the class itself doesn't exist as a tangible entity in the real world.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;An object, on the other hand, is a concrete instance of a class. It is something that actually exists. If "Person" is an abstract class, then you, yourself, are a specific object of that class.&lt;/p&gt;

&lt;p&gt;An object of a class is also called an instance of the class. To give another analogy, a class is like a mold, and objects are the concrete things produced using that mold — each with the same attributes and methods. As the saying goes, "They look just alike, as if made from the same mold" — that’s exactly the idea here.&lt;/p&gt;

&lt;p&gt;The process of using a mold to create a concrete thing is called instantiation of the class. Let’s take a look at a specific class example below:&lt;/p&gt;

&lt;p&gt;b) Defining a class¶&lt;br&gt;
class boy:&lt;br&gt;
    gender='male'&lt;br&gt;
    interest='girl'&lt;br&gt;
    def say(self):&lt;br&gt;
        return 'i am a boy'&lt;br&gt;
The statement above defines a class called boy. Now let’s use this class model to construct a specific object:&lt;/p&gt;

&lt;p&gt;peter=boy()&lt;br&gt;
Now let’s take a look at the attributes and methods of the specific instance peter.&lt;/p&gt;

&lt;p&gt;“What are attributes and methods?”&lt;/p&gt;

&lt;p&gt;They are two forms of a class:&lt;/p&gt;

&lt;p&gt;Attributes are the static aspects&lt;/p&gt;

&lt;p&gt;Methods are the dynamic aspects&lt;/p&gt;

&lt;p&gt;For example, the class “Person” may have attributes such as name, gender, height, age, and weight. It may also have methods such as walking, running, and jumping.&lt;/p&gt;

&lt;p&gt;peter.gender&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;'male'&lt;/p&gt;

&lt;p&gt;peter.interest&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;'girl'&lt;/p&gt;

&lt;p&gt;peter.say()&lt;br&gt;
the output:&lt;/p&gt;

&lt;p&gt;'i am a boy'&lt;/p&gt;

&lt;p&gt;Here, gender and interest are attributes of peter, while say is his method. If we instantiate another object, for example sam:&lt;/p&gt;

&lt;p&gt;sam=boy()&lt;br&gt;
Then sam and peter have the same attributes and methods — you could say, “They were truly made from the same mold!”&lt;/p&gt;

&lt;p&gt;Learning more fromhttps://godzilla.dev/&lt;/p&gt;

</description>
      <category>ai</category>
      <category>web3</category>
    </item>
  </channel>
</rss>
