您现在的位置是: 首页 > 介绍 介绍
火币API自动化交易:新手也能轻松掌握?速看!
时间:2025-03-06 53人已围观
如何通过火币API进行自动化交易
火币API(应用程序编程接口)允许开发者通过编程的方式访问火币交易所的各种功能,例如查询市场数据、下单交易、管理账户等。利用火币API,可以实现自动化交易策略,提高交易效率,抓住市场机会。本文将详细介绍如何通过火币API进行自动化交易。
1. 准备工作
1.1 注册火币账户并进行身份验证
您需要在火币全球站(Huobi Global)注册一个账户。这是进行API交易的先决条件。请访问官方注册地址: https://www.huobi.com/ 进行注册。注册过程中,请务必使用安全可靠的邮箱地址和设置高强度的密码,并开启二次验证(例如Google Authenticator或短信验证),以保障您的账户安全。
注册成功后,至关重要的是完成身份验证(KYC,Know Your Customer)。火币交易所采用分级KYC认证系统,不同级别的KYC认证对应不同的API交易权限和提现限额。通常,至少需要完成基础KYC认证才能启用API功能。KYC认证需要您提供真实的身份信息,包括姓名、国籍、身份证件照片等。请确保您提供的信息准确无误,以便顺利通过审核。
完成KYC认证后,请仔细查阅火币官方文档,了解不同KYC级别对应的API交易权限限制,例如交易频率限制、订单大小限制等,以便根据您的交易需求选择合适的KYC级别。未进行KYC认证或者KYC级别较低,可能会影响您的API交易体验,甚至无法进行交易。
请注意,火币可能会根据监管政策的变化调整KYC认证的要求。请您定期关注火币官方公告,及时更新您的KYC信息,以确保您的API交易账户始终处于正常状态。
1.2 开通API交易权限
要开始使用API进行交易,您需要在您的交易所账户上开通API交易权限。以火币为例,您需要登录您的火币账户,然后导航至“API管理”或类似的页面。在这个页面上,您将能够申请开通API交易权限。开通流程可能需要您完成一些身份验证步骤,以确保账户的安全性。
为了增强安全性,通常需要将您的API密钥绑定到特定的IP地址。这意味着只有来自这些指定IP地址的请求才能使用您的API密钥进行交易。通过限制API密钥的使用范围,您可以降低密钥泄露带来的风险。您可以根据您的服务器或应用程序的IP地址进行配置,例如填写服务器的公网IP地址。
请务必设置一个高强度的密码,并采取一切必要的措施来妥善保管您的API密钥(API Key)和密钥(Secret Key)。API密钥是访问您账户的凭证,一旦泄露,可能导致您的资产被未经授权的访问和操作。不要将API密钥存储在不安全的地方,例如公共代码仓库或明文配置文件中。强烈建议使用加密的方式存储API密钥,并定期更换密钥以进一步提高安全性。
如果您怀疑您的API密钥已经泄露,请立即采取行动。您可以立即禁用或删除当前的API密钥,并生成新的密钥。同时,检查您的交易记录,以确认是否有未经授权的交易活动。如有任何可疑情况,请立即联系交易所的客服部门寻求帮助。
1.3 选择编程语言和开发环境
火币API提供了广泛的语言支持,开发者可以根据自身的技术栈和偏好选择合适的编程语言。常见的选择包括但不限于:
-
Python:
由于其简洁的语法和丰富的第三方库(如
requests
、pandas
),Python成为量化交易和自动化脚本的首选语言。 它拥有活跃的社区和大量的开源资源,极大地简化了API交互和数据分析过程。 - Java: Java拥有强大的跨平台能力和高性能,适合构建大型交易系统和高频交易应用。 它的稳定性和可靠性使其在金融领域备受青睐。
- C++: C++以其卓越的性能和底层控制能力而闻名,是高频交易系统和对延迟极其敏感的应用的理想选择。 使用C++可以最大程度地优化程序的执行效率。
- JavaScript (Node.js): JavaScript凭借其在Web开发领域的普及和Node.js平台的出现,也逐渐被用于API交互和数据处理。它尤其适用于构建实时监控仪表盘和Web交易界面。
- 其他语言: 火币API原则上支持任何能够发送HTTP请求和解析JSON响应的编程语言。
选择编程语言时,请考虑以下因素:
- 你的编程经验: 选择你最熟悉的语言可以缩短开发周期并减少错误。
- 项目需求: 高频交易需要高性能的语言,而简单的脚本可以使用更易于编写的语言。
- 可用资源: 某些语言可能有更丰富的火币API相关的库和社区支持。
选择开发环境时,需要考虑集成开发环境(IDE)、代码编辑器和必要的库。 例如,对于Python,常用的开发环境包括:
- IDE: PyCharm、Visual Studio Code (带Python插件)。
-
必要库:
-
requests
:用于发送HTTP请求与火币API交互。 -
-
pandas
:用于数据分析和处理(可选)。 -
numpy
:用于数值计算(可选)。 -
websocket-client
:用于订阅火币的WebSocket数据流(可选)。
-
本文将以Python为例,详细讲解如何使用火币API进行自动化交易。我们将介绍如何设置开发环境、安装必要的库、进行API认证以及发送各种类型的请求。
1.4 安装火币API SDK
火币全球(Huobi Global)为了方便开发者高效、便捷地接入其平台,提供了多种编程语言的软件开发工具包(SDK),开发者可以通过这些SDK轻松调用API接口,进行诸如交易、账户管理、市场数据获取等操作。针对Python开发者,推荐使用官方维护的
huobi-client
库。该库封装了所有必要的API调用,简化了认证、请求构建和响应处理过程。安装
huobi-client
非常简单,只需使用Python的包管理工具pip即可:
bash
pip install huobi-client
安装完成后,即可在Python脚本中导入
huobi-client
,开始构建基于火币API的应用程序。建议同时查阅火币官方的API文档,以便更深入地理解各个接口的功能和使用方法,更好地利用SDK进行开发。务必注意API Key的安全保管,避免泄露造成资产损失。
2. 火币API接口概览
火币API提供了全面的数据访问和交易功能,主要可以划分为以下几个核心类别:
-
市场数据API:
用于获取实时的市场行情信息,是量化交易和数据分析的基础。 细分功能包括:
- K线数据: 提供不同时间周期的K线图数据,例如分钟级、小时级、日级等,用于技术分析。 通过指定时间范围和K线类型,可以获取历史K线数据。
- 最新成交价: 获取最新的交易成交价格。
- 深度数据: 提供买单和卖单的挂单深度信息,反映市场的买卖力量对比。 深度数据可以分为不同档位,例如买一价、卖一价、买五价、卖五价等。
- 实时行情汇总数据: 获取交易对的实时行情汇总信息,包括最高价、最低价、成交量、成交额等。
-
交易API:
允许用户进行交易操作,是实现自动化交易的关键。 细分功能包括:
- 下单: 创建新的交易订单,包括限价单、市价单等。 下单时需要指定交易对、交易方向(买入或卖出)、数量和价格(限价单)。
- 撤单: 取消尚未成交的订单。 可以根据订单ID取消单个订单,也可以批量取消订单。
- 查询订单状态: 查询订单的当前状态,例如待成交、部分成交、完全成交、已撤销等。 通过订单ID可以查询订单的详细信息。
- 批量下单/撤单: 允许一次性提交多个订单或撤销多个订单,提高交易效率。
-
账户API:
提供账户信息的查询和管理功能,便于用户监控资金状况。 细分功能包括:
- 查询账户余额: 获取账户中各种币种的可用余额和冻结余额。
- 交易历史: 查询账户的交易历史记录,包括成交时间、成交价格、成交数量等。 可以根据时间范围和交易对筛选交易历史。
- 充提币记录: 查询账户的充币和提币记录。
-
通用API:
提供一些通用的辅助功能。 细分功能包括:
- 获取服务器时间: 获取火币服务器的当前时间,用于同步客户端时间。
- 获取所有交易对信息: 获取火币平台支持的所有交易对的信息,包括交易对名称、交易精度等。
- API调用频率限制: 获取API调用频率限制信息,避免触发限流。
3. 使用火币API进行自动化交易的步骤
3.1 身份验证
在使用火币API进行任何交易或数据访问之前,身份验证是至关重要的步骤。它确保只有授权用户才能访问其账户信息并执行交易。身份验证的核心在于使用您的API密钥(Access Key)和密钥(Secret Key)。Access Key用于标识您的身份,而Secret Key则用于生成签名,以验证请求的真实性和完整性。务必妥善保管您的Secret Key,切勿泄露给他人,因为它相当于您的账户密码。
下面展示了如何使用
huobi-client
Python库进行身份验证,这是与火币API交互的常用方法:
使用火币API,需要创建三个client对象,MarketClient用于行情数据获取,TradeClient用于交易,AccountClient用于账户信息的查询。创建时需要提供Access Key和Secret Key。
以下代码展示了如何初始化这三个client对象,并进行了简单的配置:
from huobi.client.market import MarketClient
from huobi.client.trade import TradeClient
from huobi.client.account import AccountClient
# 替换为您的实际API密钥和密钥
access_key = "YOUR_ACCESS_KEY"
secret_key = "YOUR_SECRET_KEY"
# 初始化MarketClient (用于行情数据)
market_client = MarketClient()
# 初始化TradeClient (用于交易)
trade_client = TradeClient(api_key=access_key, secret_key=secret_key)
# 初始化AccountClient (用于账户管理)
account_client = AccountClient(api_key=access_key, secret_key=secret_key)
在使用 TradeClient 和 AccountClient 时,需要提供 api_key 和 secret_key,MarketClient 则不需要。在实际使用中,请将 "YOUR_ACCESS_KEY" 和 "YOUR_SECRET_KEY" 替换为您的真实密钥,并且注意保管。
替换为你的API密钥和密钥
在使用任何加密货币交易平台提供的API服务之前,必须将占位符替换为你自己的API密钥和密钥。API密钥和密钥是用于验证你的身份并授权你访问特定API端点的凭证。这些密钥通常可以在你平台的账户设置或API管理部分生成。
ACCESS_KEY = "YOUR_ACCESS_KEY"
ACCESS_KEY
(也称为公钥)是你的API密钥的公开部分,用于标识你的账户。它类似于用户名,允许平台识别正在请求访问的用户。在某些情况下,它可以安全地与他人共享,但这取决于平台的安全策略和API的使用方式。
SECRET_KEY = "YOUR_SECRET_KEY"
SECRET_KEY
(也称为私钥)是你的API密钥的私密部分,必须妥善保管。它类似于密码,用于验证请求的真实性。切勿与任何人共享你的私钥,也不要将其存储在不安全的位置,例如未加密的文本文件或公共代码仓库中。如果你的私钥泄露,他人可以使用它来冒充你并访问你的账户。
为了安全起见,强烈建议使用环境变量来存储你的API密钥和密钥,而不是直接将它们硬编码到你的代码中。这样可以防止你的密钥被意外地提交到版本控制系统或泄露给未经授权的人员。许多平台提供API密钥的权限控制功能,允许你限制特定密钥可以访问的API端点,从而降低安全风险。定期轮换你的API密钥也是一种良好的安全实践。
创建客户端
为了与交易所进行交互,您需要实例化相应的客户端对象。以下代码展示了如何创建用于市场数据查询、交易操作和账户管理的客户端实例。
市场数据客户端 (MarketClient):
用于获取实时的市场行情数据,例如交易对的价格、成交量、深度数据等。
market_client = MarketClient()
通过创建一个
MarketClient
的实例,您可以访问交易所提供的各种市场数据接口,无需提供API密钥和私钥,因为市场数据通常是公开的。
交易客户端 (TradeClient):
用于执行交易操作,例如下单、撤单、查询订单状态等。
trade_client = TradeClient(api_key=ACCESS_KEY, secret_key=SECRET_KEY)
创建
TradeClient
实例时,需要提供有效的API密钥 (
api_key
) 和私钥 (
secret_key
)。这些密钥用于验证您的身份,并授权您执行交易操作。请务必妥善保管您的API密钥和私钥,防止泄露,因为它们可以被用来控制您的账户。
账户客户端 (AccountClient):
用于查询账户信息,例如余额、持仓情况、交易历史等。
account_client = AccountClient(api_key=ACCESS_KEY, secret_key=SECRET_KEY)
类似于
TradeClient
,
AccountClient
也需要API密钥和私钥来进行身份验证。通过
AccountClient
,您可以获取您的账户相关的各种信息,以便进行风险管理和交易决策。同样,请妥善保管您的API密钥和私钥。
3.2 获取市场行情数据
自动化交易策略的核心在于对市场行情的敏锐感知与快速响应。 因此,获取准确、及时的市场行情数据是制定和执行自动化交易策略的基础。您可以通过
MarketClient
这一强大的工具来获取所需的各种市场数据。
例如,以下代码展示了如何利用
MarketClient
获取BTC/USDT交易对的K线数据,该数据是分析价格走势的重要依据:
kline = market_client.get_kline(symbol="btcusdt", period="1min", size=10)
print(kline)
这段代码的功能是获取BTC/USDT交易对最近10分钟的K线数据。
symbol
参数指定了交易对(这里是"btcusdt"),
period
参数定义了K线的时间周期(这里是"1min",表示1分钟K线),而
size
参数则指定了要获取的K线数量(这里是10)。返回的
kline
变量将包含一个包含10个K线数据的列表或数组,每个K线数据通常包含开盘价、收盘价、最高价、最低价以及成交量等信息。
基于这些K线数据,您可以进行各种技术分析,计算例如移动平均线(MA)、相对强弱指数(RSI)、布林带(Bollinger Bands)等关键技术指标。 这些技术指标能够帮助您更深入地了解市场趋势、识别潜在的买入或卖出信号,从而优化您的自动化交易策略。
3.3 查询账户余额
在进行加密货币交易前,务必先查询账户余额,以确保账户内有足够的资金来完成交易。余额不足会导致交易失败。你可以使用
AccountClient
对象提供的
get_accounts()
方法获取账户信息,再使用
get_account_balance()
方法查询指定账户的余额。
以下代码演示了如何使用
AccountClient
查询账户余额,并提取特定币种(如USDT和BTC)的余额信息:
accounts = account_client.get_accounts()
if accounts:
account_id = accounts[0].id # 取第一个账户的ID
balances = account_client.get_account_balance(account_id=account_id)
if balances:
for balance in balances:
if balance.currency == "usdt":
print(f"USDT余额:{balance.balance}")
if balance.currency == "btc":
print(f"BTC余额:{balance.balance}")
上述代码首先获取所有账户列表,然后选择第一个账户的ID。接着,使用该ID查询该账户的余额信息。返回的余额信息是一个列表,包含了该账户下所有币种的余额。代码遍历这个列表,筛选出USDT和BTC的余额,并将其打印出来。请注意,实际环境中可能需要根据交易所或API的具体实现调整代码,例如处理多个账户或使用不同的币种代码。务必处理API调用可能出现的异常情况。
3.4 下单交易
当行情走势符合您预设的交易策略,认为出现入场或离场机会时,便可以使用
TradeClient
对象来进行下单交易操作。 例如,以下代码演示了如何使用市价单买入0.01个比特币(BTC):
order_id = trade_client.create_order(
symbol="btcusdt",
account_id=account_id,
order_type="buy-market",
amount="0.01"
)
print(f"订单ID:{order_id}")
上述代码片段的功能是创建一个市价买单,该买单会以当前市场最优价格立即成交,买入数量为0.01个BTC。 其中,
order_type
参数是至关重要的一个参数,它精确地指定了订单的类型。 在本例中,
buy-market
值明确指示该订单为市价买入订单。
除了市价买入之外, 还可以选择其他类型的订单,以满足不同的交易需求和策略。 以下列出了一些常用的订单类型及其含义:
-
buy-limit
:限价买入, 只有当市场价格达到或低于您设定的指定价格时,订单才会被执行。 -
sell-market
:市价卖出, 会以当前市场最优价格立即卖出指定数量的资产。 -
sell-limit
:限价卖出, 只有当市场价格达到或高于您设定的指定价格时,订单才会被执行。
在使用限价单时,需要额外指定一个
price
参数,用于设定期望的成交价格。 合理选择订单类型, 可以更有效地执行您的交易策略,并控制交易成本。
3.5 查询订单状态
下单后,为了及时掌握交易进展,你需要查询订单状态,确认订单是否已经成功成交。
TradeClient
提供了查询订单状态的功能,允许你追踪订单的执行情况。
你可以使用以下代码查询订单状态:
order = trade_client.get_order(order_id=order_id)
print(f"订单状态:{order.state}")
这段代码会根据提供的
order_id
从交易平台获取订单的详细信息,并打印出订单的当前状态。 其中,
order_id
是你在下单时获得的唯一订单标识符。订单状态可能包含以下几种常见类型:
-
submitted
(已提交):订单已成功提交到交易平台,等待撮合。 -
filled
(已成交):订单已完全成交,所有买入或卖出的需求都已满足。 -
canceled
(已撤销):订单已被用户主动撤销或因其他原因被系统取消。 -
partial-filled
(部分成交):订单已部分成交,但仍有剩余的买入或卖出需求未被满足。 -
pending-cancel
(待撤销): 订单已提交撤销请求,正在等待处理。 -
rejected
(已拒绝): 订单因某种原因被交易平台拒绝。常见的拒绝原因包括余额不足、价格超出范围等。
通过定期查询订单状态,你可以及时了解交易的进展情况,并根据需要采取进一步的操作,例如撤销订单或调整交易策略。
3.6 撤销订单
在加密货币交易中,订单未成交时,通常允许用户撤销订单。这对于避免不必要的资金占用或调整交易策略至关重要。
TradeClient
提供了一个便捷的方法来执行此操作。
使用
TradeClient
撤销订单的示例代码如下:
result = trade_client.cancel_order(order_id=order_id)
print(f"撤单结果:{result}")
上述代码段展示了如何调用
cancel_order
方法。该方法接收一个必需参数
order_id
,它指定了要撤销的订单的唯一标识符。
order_id
的值应替换为实际要撤销的订单的 ID。
cancel_order
方法的返回值
result
包含了撤单操作的结果信息,例如撤单是否成功,以及可能的错误信息。为了便于调试和验证,建议打印
result
的内容。
需要注意的是,即使调用
cancel_order
方法成功,也不意味着订单立即被撤销。订单撤销可能需要一些时间,具体取决于交易所的处理速度和当前的市场状况。因此,建议在撤销订单后,通过查询订单状态来确认订单是否已被成功撤销。
4. 注意事项
- 风险控制: 自动化交易虽然能提升效率,但也伴随着潜在风险。务必在交易策略中设置明确的止损和止盈点,严格控制单次交易的最大亏损额度,避免因市场波动造成重大损失。根据自身风险承受能力调整仓位大小,切勿孤注一掷。同时,定期审查和优化风险控制参数,适应市场变化。
- API频率限制: 火币API为了保障系统稳定运行,对API调用频率设置了严格限制。超出频率限制可能导致API调用失败,影响交易策略的执行。务必仔细阅读火币API官方文档,了解不同API接口的频率限制要求。在代码实现中,合理规划API调用逻辑,避免短时间内进行大量API请求。可以使用缓存机制或优化算法,减少不必要的API调用。如果需要高频交易,可以考虑使用WebSocket接口或调整API调用策略。
- 异常处理: 自动化交易程序需要具备完善的异常处理机制,以应对各种突发情况。例如,网络连接中断、API调用超时、交易所服务器维护等。在代码中加入try-except语句,捕获并处理这些异常。当API调用失败时,记录错误信息,并采取相应的措施,例如重试API调用、暂停交易、发送告警通知等。避免因程序异常导致交易中断或出现意外损失。
- 数据安全: API密钥是访问火币账户的凭证,务必妥善保管,切勿泄露给他人。不要将API密钥存储在公开的代码仓库中,避免被恶意用户获取。建议使用环境变量或配置文件管理API密钥,并设置适当的访问权限。定期更换API密钥,提高安全性。同时,注意防范钓鱼网站和恶意软件,避免因安全漏洞导致API密钥泄露。
- 模拟交易: 在真实资金投入交易之前,务必先使用火币提供的模拟交易环境进行充分测试。模拟交易可以帮助你验证交易策略的有效性,评估风险控制参数的合理性,熟悉API的使用方法。在模拟交易中,可以模拟各种市场情况,测试程序的稳定性和容错能力。只有在模拟交易中取得满意的结果后,才能考虑使用真实资金进行交易。需要注意的是,模拟交易环境与真实交易环境可能存在差异,最终结果可能略有不同。
5. 示例代码:简单的移动平均线策略
以下是一个基于火币交易所API实现的简单移动平均线策略的示例代码。该策略使用BTC/USDT交易对,并通过比较当前价格与移动平均线来决定买入或卖出。请注意,此代码仅为示例,实际应用中需要进行更全面的风险评估和参数优化。
import time from huobi.client.market import MarketClient from huobi.client.trade import TradeClient from huobi.client.account import AccountClient
ACCESS KEY = "YOUR ACCESS KEY" # 替换为您的API访问密钥 SECRET KEY = "YOUR SECRET KEY" # 替换为您的API密钥 SYMBOL = "btcusdt" # 交易对,例如比特币/USDT PERIOD = "1min" # K线周期,例如1分钟 MOVING AVERAGE PERIOD = 20 # 移动平均线周期,例如20 AMOUNT = "0.01" #每次下单数量, 根据您的账户资金进行调整
market client = MarketClient() # 初始化市场数据客户端 trade client = TradeClient(api key=ACCESS KEY, secret key=SECRET KEY) # 初始化交易客户端 account client = AccountClient(api key=ACCESS KEY, secret key=SECRET_KEY) # 初始化账户客户端
accounts = account client.get accounts() # 获取账户信息 if accounts: account_id = accounts[0].id # 获取第一个账户ID
def calculate moving average(data): """计算移动平均线 Args: data: 包含价格数据的列表. Returns: 计算出的移动平均线值. """ return sum(data) / len(data)
def run strategy(): """运行策略 该函数循环运行,定期获取K线数据,计算移动平均线,并根据策略发出买入或卖出信号. 在实际部署前,请务必进行充分的回测和风险管理. """ while True: try: # 获取K线数据 kline = market client.get kline(symbol=SYMBOL, period=PERIOD, size=MOVING AVERAGE PERIOD) if not kline or len(kline) < MOVING AVERAGE PERIOD: print("K线数据不足,等待...") time.sleep(60) continue
# 提取收盘价
close_prices = [float(k.close) for k in kline]
# 计算移动平均线
moving_average = calculate_moving_average(close_prices)
# 获取最新成交价
ticker = market_client.get_ticker(symbol=SYMBOL)
if not ticker:
print("获取最新成交价失败,等待...")
time.sleep(10)
continue
current_price = float(ticker.close)
# 查询账户USDT余额
balances = account_client.get_account_balance(account_id=account_id)
usdt_balance = 0
if balances:
for balance in balances:
if balance.currency == "usdt":
usdt_balance = float(balance.balance)
break
# 策略逻辑:如果当前价格高于移动平均线,且USDT余额充足,则买入
if current_price > moving_average and usdt_balance > 10: # 至少保证有10USDT才交易
order_id = trade_client.create_order(
symbol=SYMBOL,
account_id=account_id,
order_type="buy-market",
amount=AMOUNT
)
print(f"买入信号:当前价格 {current_price}, 移动平均线 {moving_average}, 订单ID {order_id}")
# 策略逻辑:如果当前价格低于移动平均线,且持有BTC,则卖出
elif current_price < moving_average:
# 查询账户BTC余额
btc_balance = 0
if balances:
for balance in balances:
if balance.currency == "btc":
btc_balance = float(balance.balance)
break
if btc_balance > 0.001: #至少保证有0.001BTC才交易
order_id = trade_client.create_order(
symbol=SYMBOL,
account_id=account_id,
order_type="sell-market",
amount=AMOUNT
)
print(f"卖出信号:当前价格 {current_price}, 移动平均线 {moving_average}, 订单ID {order_id}")
else:
print(f"无交易信号:当前价格 {current_price}, 移动平均线 {moving_average}")
time.sleep(60) # 每隔60秒执行一次
except Exception as e:
print(f"发生错误:{e}")
time.sleep(60)
if name == " main ": run_strategy()
这个示例代码会定期从火币交易所获取BTC/USDT的K线数据,利用这些数据计算移动平均线。如果当前价格高于移动平均线,并且账户中有足够的USDT余额,则会执行市价买入操作。相反,如果当前价格低于移动平均线,并且账户持有一定数量的BTC,则会执行市价卖出操作。请务必理解,这只是一个非常基础的示例,缺乏完善的风险控制机制和参数优化。在实际应用中,您需要根据市场情况和您的个人风险承受能力,对策略参数进行精细调整,并实施严格的风险管理措施,例如设置止损点和止盈点。建议您在真实交易前,先使用模拟账户进行充分的测试,以评估策略的有效性和稳定性。切记,加密货币交易存在高风险,请谨慎投资。