GetFills - Get Fill Data
Retrieve fills at a specific position from Hyperliquid L1 Gateway via gRPC. Get order execution data for analysis and reconciliation.
Retrieve fills at a specific position from the Hyperliquid L1 Gateway.
GetFills is essential for:
- Trade Reconciliation - Verify fills at a specific point in time
- Historical Analysis - Retrieve fill data for backtesting or reporting
- Auditing - Verify trade executions at specific blocks
- Debugging - Investigate specific fills during development
rpc GetFills(Position) returns (BlockFills) {}
Request Parameters
Requesttimestamp_msint64
One of `position`. ms since Unix epoch, inclusive
block_heightint64
One of `position`. block height, inclusive
local_time*string
ISO-8601 timestamp when node processed the fill
block_time*string
ISO-8601 timestamp from block consensus
block_number*number
Block height containing these fills
events*array
Array of [address, fill_data] pairs
def reconcile_pnl(client, metadata, start_block, end_block):
"""Calculate total PnL between two blocks"""
pnl_by_address = {}
for block_height in range(start_block, end_block + 1):
request = hyperliquid_pb2.Position(block_height=block_height)
response = client.GetFills(request, metadata=metadata)
fills = json.loads(response.data)
for event in fills.get('events', []):
if len(event) >= 2:
address = event[0]
fill = event[1]
pnl = float(fill.get('closedPnl', 0))
if address not in pnl_by_address:
pnl_by_address[address] = 0
pnl_by_address[address] += pnl
return pnl_by_address
func verifyFill(client pb.HyperliquidL1GatewayClient, ctx context.Context, blockHeight int64, traderId string) []map[string]interface{} {
request := &pb.Position{Position: &pb.Position_BlockHeight{BlockHeight: blockHeight}}
response, _ := client.GetFills(ctx, request)
var fills map[string]interface{}
json.Unmarshal(response.Data, &fills)
var traderFills []map[string]interface{}
events := fills["events"].([]interface{})
for _, event := range events {
eventArr := event.([]interface{})
if len(eventArr) >= 2 {
address := eventArr[0].(string)
if address == traderId {
fillData := eventArr[1].(map[string]interface{})
traderFills = append(traderFills, fillData)
}
}
}
return traderFills
}
function analyzeVolume(fills) {
const volumeByCoin = {};
const events = fills.events || [];
for (const event of events) {
if (event.length >= 2) {
const fill = event[1];
const coin = fill.coin;
const volume = parseFloat(fill.sz) * parseFloat(fill.px);
if (!volumeByCoin[coin]) {
volumeByCoin[coin] = {
totalVolume: 0,
buyVolume: 0,
sellVolume: 0,
fillCount: 0
};
}
volumeByCoin[coin].totalVolume += volume;
volumeByCoin[coin].fillCount++;
if (fill.side === 'B') {
volumeByCoin[coin].buyVolume += volume;
} else {
volumeByCoin[coin].sellVolume += volume;
}
}
}
return volumeByCoin;
}
- Position Selection: Use block height for precise queries; timestamps may return different fills across requests
- Data Validation: Always validate JSON structure and handle optional fields
- Deduplication: Use
tid (trade ID) as the unique identifier for deduplication
- Error Recovery: Implement retry logic with exponential backoff
- Resource Management: Close gRPC connections properly to avoid resource leaks
- Data Retention: Historical fill data is limited to a 24-hour rolling window
- Rate Limits: Be mindful of request frequency to avoid overwhelming the service
Need help? Contact our support team or check the Hyperliquid gRPC documentation.