AWS Lambda中lambda_handler缺少event和context参数报错求助
问题诊断与解决
核心错误原因
从错误日志的栈追踪可以明确定位问题:
File "/var/task/lambda_function.py", line 80, in <module> lambda_handler()
你的代码在模块顶层(所有函数定义之外)直接调用了lambda_handler(),但这个函数要求传入event和context两个必填参数,无参调用直接触发TypeError。而且这个调用会在Lambda加载代码模块的初始化阶段执行,直接导致函数初始化失败。
第一步:修复直接调用问题
删除代码中模块顶层的lambda_handler()调用语句(即报错指向的第80行)。Lambda会在触发时自动调用lambda_handler并传入event和context参数,完全不需要手动调用。
第二步:修复代码中的其他潜在问题
除了核心报错,你的代码还有几个会导致后续运行失败的问题,需要一并修正:
1. DynamoDB使用错误
当前代码中,dynamodb.Table()返回Table对象但未赋值,后续直接用dynamodb.get_item()是错误的,且get_item的返回数据嵌套在Item键下:
# 错误写法 dynamodb = boto3.resource("dynamodb") dynamodb.Table("woolyquant_cria_trading_bot") dynamodb_item = dynamodb.get_item(...) # 修正后 dynamodb = boto3.resource("dynamodb") table = dynamodb.Table("woolyquant_cria_trading_bot") dynamodb_response = table.get_item( Key = { 'Date': yesterday[0:10], 'TickerSymbol': ticker, } ) # 处理找不到数据的情况 if 'Item' not in dynamodb_response: return {"statusCode": 404, "body": "目标数据不存在"} prev_closing_price = fast_atof(dynamodb_response['Item']['ClosingPrice'])
2. requests响应处理错误
get_current_asset_position函数中,requests.get()返回的是Response对象而非字典,需要调用.json()解析,同时建议添加HTTP错误捕获:
def get_current_asset_position(ticker: str) -> dict: url = f'https://paper-api.alpaca.markets/v2/positions/{ticker}' headers = { "accept": "application/json", "content-type": "application/json", "APCA-API-KEY-ID": ALPACA_CONFIG['API_KEY'], "APCA-API-SECRET-KEY": ALPACA_CONFIG['API_SECRET'] } response = requests.get(url, headers=headers) response.raise_for_status() # 自动抛出HTTP错误 return response.json()
3. Alpaca订单Payload占位符未替换
alpaca_payload中的"string"占位符(如"notional": "string")是无效值,Alpaca API会拒绝此类请求。需要根据订单类型调整参数,比如止损单必须包含stop_price:
alpaca_payload = { "symbol": "AAPL", "type": "stop", "time_in_force": "day", "extended_hours": False, # 补充止损价示例,根据策略调整 "stop_price": str(curr_price * 0.98) }
修复后的完整代码示例
import os import boto3 import ctypes import logging from datetime import datetime from datetime import timedelta from config import ALPACA_CONFIG import requests # Handle fast str -> float conversion def fast_atof(s) -> float: return ctypes.c_float(float(s)).value def get_current_asset_position(ticker: str) -> dict: url = f'https://paper-api.alpaca.markets/v2/positions/{ticker}' headers = { "accept": "application/json", "content-type": "application/json", "APCA-API-KEY-ID": ALPACA_CONFIG['API_KEY'], "APCA-API-SECRET-KEY": ALPACA_CONFIG['API_SECRET'] } response = requests.get(url, headers=headers) response.raise_for_status() return response.json() def lambda_handler(event, context): url = "https://paper-api.alpaca.markets/v2/orders" ticker = "AAPL" yesterday = str(datetime.today() - timedelta(days = 1)) dynamodb = boto3.resource("dynamodb") table = dynamodb.Table("woolyquant_cria_trading_bot") dynamodb_response = table.get_item( Key = { 'Date': yesterday[0:10], 'TickerSymbol': ticker, } ) if 'Item' not in dynamodb_response: return {"statusCode": 404, "body": f"{ticker}在{yesterday[0:10]}无数据记录"} alpaca_headers = { "accept": "application/json", "content-type": "application/json", "APCA-API-KEY-ID": ALPACA_CONFIG['API_KEY'], "APCA-API-SECRET-KEY": ALPACA_CONFIG['API_SECRET'] } alpaca_payload = { "symbol": "AAPL", "type": "stop", "time_in_force": "day", "extended_hours": False, } asset = get_current_asset_position(ticker=ticker) prev_closing_price = fast_atof(dynamodb_response['Item']['ClosingPrice']) curr_price = fast_atof(asset['current_price']) if curr_price > prev_closing_price * 1.05: alpaca_payload['qty'] = asset['qty'] alpaca_payload['side'] = 'sell' alpaca_payload['stop_price'] = str(curr_price * 0.98) response = requests.post(url, json=alpaca_payload, headers=alpaca_headers) response.raise_for_status() return {"statusCode": 200, "body": response.json()} if curr_price < prev_closing_price * 0.8995: alpaca_payload['qty'] = '10' alpaca_payload['side'] = 'buy' alpaca_payload['stop_price'] = str(curr_price * 1.02) response = requests.post(url, json=alpaca_payload, headers=alpaca_headers) response.raise_for_status() return {"statusCode": 200, "body": response.json()} return {"statusCode": 200, "body": "未触发交易条件"}
总结
- 优先删除模块顶层的
lambda_handler()调用,这是当前报错的直接原因; - 修正DynamoDB和requests的使用逻辑,确保数据能正确读取与解析;
- 清理Alpaca订单参数中的无效占位符,符合API要求。
内容的提问来源于stack exchange,提问作者Jonathan Grady
相关产品推荐
相关产品推荐

