Quant.Infra.Net is a .NET quantitative trading infrastructure library that lets you fetch data, run statistical analysis, execute trades, and send notifications with minimal code.
| Version | Date | Description |
|---|---|---|
| 1.0.0 | 2024-01-15 | Initial release with core features: data acquisition, statistical analysis, trade execution, and notifications |
| 1.1.0 | 2024-02-20 | Added support for Schwab broker integration and enhanced portfolio performance metrics |
| 1.2.0 | 2024-03-10 | Improved Python integration stability and added new statistical analysis methods |
| 1.3.0 | 2024-04-05 | Enhanced notification services with email templates and improved error handling |
| 1.4.0 | 2024-05-16 | Updated API integrations to handle recent broker changes, added comprehensive documentation |
| 1.5.0 | 2024-05-16 | Enforced comprehensive code standards: SOLID principles, bilingual XML documentation, parameter validation, English-only runtime messages, UTC time standardization, centralized enum management, sensitive data protection, and created complete code standards documentation |
This README follows a strict update policy to ensure consistency and accuracy:
- Synchronization: Every code change that affects public APIs must be reflected in this document simultaneously in both English and Chinese sections.
- Versioning: Version numbers follow Semantic Versioning (MAJOR.MINOR.PATCH) standards.
- Change Log: Each version entry must include: version number, release date, and concise description of changes.
- Bilingual Consistency: Both English and Chinese sections must maintain identical information and structure.
- Last Updated: 2024-05-16 (Version 1.5.0)
When developing quantitative trading systems, you likely face these recurring problems:
| Problem | What this library provides |
|---|---|
| Stock / crypto data APIs are scattered with inconsistent formats | Unified ITraditionalFinanceSourceDataService and ICryptoSourceDataService with standardized OHLCV models |
| Pair trading requires ADF test, OLS regression, Z-Score, correlation | IAnalysisService provides ready-to-use methods in one line |
| Integrating Binance, Alpaca, etc. means rewriting boilerplate | IBinanceUsdFutureService, IUSEquityBrokerService unified abstractions |
| No notification pipeline after strategy runs | DingTalk IDingtalkService, WeChat IWeChatService, Email EmailService |
| CAGR, Sharpe, Calmar, max drawdown must be coded from scratch | StrategyPerformanceAnalyzer with all metrics built in |
| Timers and rolling windows rewritten every project | IntervalTrigger, RollingWindow<T> ready to use |
In short: stop reinventing the wheel — focus on your strategy.
- Data Acquisition — Download stock daily bars from Yahoo Finance, batch-download crypto klines from Binance, read local data from CSV/MySQL/MongoDB.
- Statistical Analysis — Correlation, ADF stationarity test, OLS regression, Z-Score, Shapiro-Wilk normality test, pair-trading spread calculation.
- Trade Execution — Binance futures order/liquidate, Alpaca US equity order/liquidate, with Testnet/Paper/Live environment switching.
- Notifications — DingTalk bot, WeChat Work webhook, personal/commercial bulk email.
- Portfolio & Performance — Portfolio snapshots, equity curve charting, CAGR/Sharpe/Calmar/MaxDrawdown calculation.
- Utilities — Rolling window, interval trigger, resolution conversion, DataFrame I/O.
Note on Data Sources
The C# package
YahooFinanceApicannot keep up with Yahoo Finance's frequent API changes and often returns401 Unauthorized. The Pythonyfinancepackage is maintained more actively by a large community. This project usespythonnetto callyfinancefrom C# via a local Anaconda virtual environment.
dotnet new console -n MyQuantApp
cd MyQuantApp
dotnet add package Quant.Infra.Net
dotnet add package pythonnet
dotnet add package Microsoft.Extensions.DependencyInjectionOr use a ProjectReference when developing inside the repo:
<ProjectReference Include="..\Quant.Infra.Net\Quant.Infra.Net.csproj" />Why Python? The C# package
YahooFinanceApicannot keep up with Yahoo Finance's frequent API changes and often returns401 Unauthorized. The Pythonyfinancepackage is maintained more actively by a large community. This project usespythonnetto callyfinancefrom C# via a local Anaconda virtual environment.
conda create -n quant python=3.9 -y
conda activate quant
pip install yfinance- Note the environment path and Python DLL filename for the code:
# Windows example
Env path: D:\ProgramData\PythonVirtualEnvs\pair_trading
or C:\Users\<you>\miniconda3\envs\quant
Python DLL: python39.dll (for Python 3.9)
Set these two constants to match your environment:
private const string CondaEnvPath = @"D:\ProgramData\PythonVirtualEnvs\pair_trading";
private const string PythonDllName = "python39.dll";using Microsoft.Extensions.DependencyInjection;
using Python.Runtime;
using Quant.Infra.Net.Analysis.Service;
using Quant.Infra.Net.Shared.Model;
class Program
{
private const string CondaEnvPath = @"D:\ProgramData\PythonVirtualEnvs\pair_trading";
private const string PythonDllName = "python39.dll";
static async Task Main(string[] args)
{
// 1. Register services
var services = new ServiceCollection();
services.AddScoped<IAnalysisService, AnalysisService>();
var provider = services.BuildServiceProvider();
var analysis = provider.GetRequiredService<IAnalysisService>();
// 2. Download AAPL & MSFT via Python yfinance
var end = DateTime.UtcNow;
var start = end.AddYears(-1);
InitializePython();
Console.WriteLine("Downloading AAPL daily OHLCV via yfinance...");
var aaplClose = DownloadCloseViaYFinance("AAPL", start, end);
Console.WriteLine($"AAPL rows: {aaplClose.Count}");
Console.WriteLine("Downloading MSFT daily OHLCV via yfinance...");
var msftClose = DownloadCloseViaYFinance("MSFT", start, end);
Console.WriteLine($"MSFT rows: {msftClose.Count}");
// 3. Correlation
int minLen = Math.Min(aaplClose.Count, msftClose.Count);
aaplClose = aaplClose.Take(minLen).ToList();
msftClose = msftClose.Take(minLen).ToList();
double corr = analysis.CalculateCorrelation(aaplClose, msftClose);
Console.WriteLine($"AAPL vs MSFT correlation: {corr:F4}");
// 4. OLS regression
var (slope, intercept) = analysis.PerformOLSRegression(aaplClose, msftClose);
Console.WriteLine($"OLS regression: Slope={slope:F4}, Intercept={intercept:F4}");
// 5. ADF stationarity test
var spread = msftClose
.Zip(aaplClose, (m, a) => m - slope * a - intercept).ToList();
bool isStationary = analysis.AugmentedDickeyFullerTest(spread, adfTestStatisticThreshold: -2.86);
Console.WriteLine($"Spread ADF stationary: {isStationary}");
// 6. Z-Score
double zScore = analysis.CalculateZScores(spread, spread.Last());
Console.WriteLine($"Latest Z-Score: {zScore:F4}");
await Task.CompletedTask;
}
private static bool _pythonInitialized;
private static readonly object _initLock = new();
private static void InitializePython()
{
if (_pythonInitialized) return;
lock (_initLock)
{
if (_pythonInitialized) return;
var infra = PythonNetInfra.GetPythonInfra(CondaEnvPath, PythonDllName);
Runtime.PythonDLL = infra.PythonDLL;
PythonEngine.PythonHome = infra.PythonHome;
PythonEngine.PythonPath = infra.PythonPath;
PythonEngine.Initialize();
_pythonInitialized = true;
}
}
private static List<double> DownloadCloseViaYFinance(string symbol, DateTime start, DateTime end)
{
using (Py.GIL())
{
dynamic yf = Py.Import("yfinance");
string startStr = start.ToString("yyyy-MM-dd");
string endStr = end.ToString("yyyy-MM-dd");
dynamic df = yf.download(symbol, start: startStr, end: endStr, auto_adjust: true);
dynamic closeSeries = df.__getitem__("Close");
dynamic pyList = closeSeries.values.flatten().tolist();
var result = new List<double>();
foreach (dynamic item in pyList)
result.Add((double)item);
return result;
}
}
}Run:
dotnet runExpected output:
Downloading AAPL daily OHLCV via yfinance...
AAPL rows: 251
Downloading MSFT daily OHLCV via yfinance...
MSFT rows: 251
AAPL vs MSFT correlation: 0.9213
OLS regression: Slope=1.8472, Intercept=23.5610
Spread ADF stationary: True
Latest Z-Score: -0.3172
var dataService = provider.GetRequiredService<ITraditionalFinanceSourceDataService>();
var symbols = await dataService.GetSp500SymbolsAsync();
Console.WriteLine($"S&P 500 count: {symbols.Count()}");var futureService = provider.GetRequiredService<IBinanceUsdFutureService>();
futureService.ExchangeEnvironment = ExchangeEnvironment.Testnet;
decimal balance = await futureService.GetusdFutureAccountBalanceAsync();
Console.WriteLine($"Balance: {balance}");
await futureService.SetUsdFutureHoldingsAsync("BTCUSDT", 0.10, PositionSide.Long);
var positions = await futureService.GetHoldingPositionAsync();
Console.WriteLine($"Positions: {positions.Count()}");
await futureService.LiquidateUsdFutureAsync("BTCUSDT");var broker = provider.GetRequiredService<IUSEquityBrokerService>();
broker.ExchangeEnvironment = ExchangeEnvironment.Paper;
decimal equity = await broker.GetAccountEquityAsync();
Console.WriteLine($"Account equity: {equity}");
await broker.SetHoldingsAsync("AAPL", 0.05m);
await broker.LiquidateAsync("AAPL");var dingtalk = provider.GetRequiredService<IDingtalkService>();
await dingtalk.SendNotificationAsync("Signal: Buy AAPL", accessToken, secret);
var wechat = provider.GetRequiredService<IWeChatService>();
await wechat.SendTextNotificationAsync("Order filled", webHookUrl);var analysis = provider.GetRequiredService<IAnalysisService>();
double corr = analysis.CalculateCorrelation(seriesA, seriesB);
var (slope, intercept) = analysis.PerformOLSRegression(seriesA, seriesB);
bool isStationary = analysis.AugmentedDickeyFullerTest(spread);
AdfTestResult adfResult = analysis.AugmentedDickeyFullerTestPython(spread);
double z = analysis.CalculateZScores(spread, currentValue);
bool isNormal = analysis.PerformShapiroWilkTest(spread);var window = new RollingWindow<double>(20);
window.Add(100.5);
window.Add(101.2);
if (window.IsReady)
Console.WriteLine($"Window full, count={window.Count}");
var trigger = new IntervalTrigger(StartMode.NextHour, TimeSpan.FromMinutes(-1));
trigger.IntervalTriggered += (sender, e) =>
{
Console.WriteLine($"Triggered at {DateTime.UtcNow}");
};
trigger.Start();double cagr = StrategyPerformanceAnalyzer.CalculateCAGR(marketValueDict);
double sharpe = StrategyPerformanceAnalyzer.CalculateSharpeRatio(marketValueDict, riskFreeRate);
double calmar = StrategyPerformanceAnalyzer.CalculateCalmarRatio(marketValueDict);
double maxDD = StrategyPerformanceAnalyzer.CalculateMaximumDrawdown(values);
Console.WriteLine($"CAGR={cagr:P2}, Sharpe={sharpe:F2}, Calmar={calmar:F2}, MaxDD={maxDD:P2}");cd src
dotnet restore
dotnet build
dotnet testRun a specific test class:
dotnet test --filter "FullyQualifiedName~AnalysisServiceTests"Quant.Infra.Net/
├── Analysis/ # Statistical analysis: ADF, OLS, correlation, Z-Score, pair trading
├── Broker/ # Broker integration: Binance, Alpaca, InteractiveBrokers
├── Notification/ # Notifications: DingTalk, WeChat Work, Email
├── Order/ # Order models
├── Portfolio/ # Portfolio snapshots, performance analysis, equity curves
├── Shared/ # Common models, enums, RollingWindow, IntervalTrigger, UtilityService
└── SourceData/ # Data: Yahoo Finance, Binance, CSV, MySQL, MongoDB
- ADF Python mode:
AugmentedDickeyFullerTestPythonrequires a local Python environment withnumpy,pandas, andstatsmodels. If Python is not available, useAugmentedDickeyFullerTest(pure .NET implementation). - API Key configuration: Binance / Alpaca live trading requires API Key and Secret in
appsettings.jsonor User Secrets. - ExchangeEnvironment: Supports
Testnet,Paper, andLive. Use Testnet or Paper during development. - Binance IP Restrictions: The Binance API restricts access from certain countries/regions. If you encounter connection errors when running Binance-related unit tests, this is not a code issue. Please refer to the Binance official documentation for the list of restricted regions.
- Compliance Disclaimer: This project provides quantitative trading infrastructure tools only and does not constitute investment advice. Users are solely responsible for ensuring compliance with all applicable laws, regulations, and exchange rules in their jurisdiction. The authors assume no liability for any legal or financial consequences arising from the use of this library.
Quant.Infra.Net will continue to maintain this public repository as the Community Edition. Existing open-source features will remain available here. We are evaluating whether it is worth investing significant development effort into a separate Pro Edition for advanced broker integrations and production trading workflows, such as Charles Schwab, Interactive Brokers, multi-broker abstractions, risk controls, deployment templates, and priority support. This is not a pricing announcement. It is a roadmap validation request. If you need Schwab / IB integration, use this project in real trading workflows, or have concerns about the Community + Pro direction, please share your feedback in GitHub Discussions, join the community group below, or contact
rex.fan18@gmail.com. Your feedback will directly affect how much time we invest in this direction.
在量化交易开发中,你可能反复遇到这些问题:
| 你遇到的问题 | 本库提供的方案 |
|---|---|
| 股票 / 加密货币数据接口分散、格式不统一 | 统一的 ITraditionalFinanceSourceDataService 和 ICryptoSourceDataService,标准化 OHLCV 模型 |
| 配对交易需要 ADF 检验、OLS 回归、Z-Score、相关性分析 | IAnalysisService 提供现成方法,一行代码调用 |
| 对接 Binance、Alpaca 等券商时重复造轮子 | IBinanceUsdFutureService、IUSEquityBrokerService 等统一抽象 |
| 策略运行后缺少通知链路 | 钉钉 IDingtalkService、企业微信 IWeChatService、邮件 EmailService |
| 评估 CAGR、Sharpe、Calmar、最大回撤要自己写 | StrategyPerformanceAnalyzer 内置全部指标 |
| 定时器、滚动窗口每次都重写 | IntervalTrigger、RollingWindow<T> 开箱即用 |
简而言之:不重复造轮子,专注策略本身。
- 数据获取 — 从 Yahoo Finance 下载股票日线,从 Binance 批量下载加密货币 K 线,从 CSV/MySQL/MongoDB 读取本地历史数据。
- 统计分析 — 相关性、ADF 平稳性检验、OLS 线性回归、Z-Score、Shapiro-Wilk 正态性检验、配对交易价差计算。
- 交易执行 — Binance 合约下单 / 清仓、Alpaca 美股下单 / 清仓,支持 Testnet / Paper / Live 环境切换。
- 通知推送 — 钉钉群机器人、企业微信 Webhook、个人邮箱 / 商业邮件批量发送。
- 组合与绩效 — 投资组合快照、净值曲线绘图、CAGR / Sharpe / Calmar / 最大回撤计算。
- 工具类 — 滚动窗口、定时触发器、分辨率转换、DataFrame 读写。
关于数据源的说明
C# 包
YahooFinanceApi的更新速度跟不上 Yahoo Finance API 的频繁变动,经常出现401 Unauthorized等错误。 Python 社区的yfinance包更新更快、更稳定。因此本项目通过pythonnet在 C# 中调用本地 Anaconda 虚拟环境中的yfinance来获取行情数据。
dotnet new console -n MyQuantApp
cd MyQuantApp
dotnet add package Quant.Infra.Net
dotnet add package pythonnet
dotnet add package Microsoft.Extensions.DependencyInjection如果你在仓库内开发,也可以用 ProjectReference:
<ProjectReference Include="..\Quant.Infra.Net\Quant.Infra.Net.csproj" />conda create -n quant python=3.9 -y
conda activate quant
pip install yfinance- 记录虚拟环境路径和 Python DLL 文件名,后续代码中需要用到:
# Windows 示例
环境路径: D:\ProgramData\PythonVirtualEnvs\pair_trading
或 C:\Users\<你的用户名>\miniconda3\envs\quant
Python DLL:python39.dll (对应 Python 3.9)
将以下两个常量修改为你的实际路径:
private const string CondaEnvPath = @"D:\ProgramData\PythonVirtualEnvs\pair_trading";
private const string PythonDllName = "python39.dll";using Microsoft.Extensions.DependencyInjection;
using Python.Runtime;
using Quant.Infra.Net.Analysis.Service;
using Quant.Infra.Net.Shared.Model;
class Program
{
private const string CondaEnvPath = @"D:\ProgramData\PythonVirtualEnvs\pair_trading";
private const string PythonDllName = "python39.dll";
static async Task Main(string[] args)
{
// 1. Register services
var services = new ServiceCollection();
services.AddScoped<IAnalysisService, AnalysisService>();
var provider = services.BuildServiceProvider();
var analysis = provider.GetRequiredService<IAnalysisService>();
// 2. Download AAPL & MSFT via Python yfinance
var end = DateTime.UtcNow;
var start = end.AddYears(-1);
InitializePython();
Console.WriteLine("Downloading AAPL daily OHLCV via yfinance...");
var aaplClose = DownloadCloseViaYFinance("AAPL", start, end);
Console.WriteLine($"AAPL rows: {aaplClose.Count}");
Console.WriteLine("Downloading MSFT daily OHLCV via yfinance...");
var msftClose = DownloadCloseViaYFinance("MSFT", start, end);
Console.WriteLine($"MSFT rows: {msftClose.Count}");
// 3. Correlation
int minLen = Math.Min(aaplClose.Count, msftClose.Count);
aaplClose = aaplClose.Take(minLen).ToList();
msftClose = msftClose.Take(minLen).ToList();
double corr = analysis.CalculateCorrelation(aaplClose, msftClose);
Console.WriteLine($"AAPL vs MSFT correlation: {corr:F4}");
// 4. OLS regression
var (slope, intercept) = analysis.PerformOLSRegression(aaplClose, msftClose);
Console.WriteLine($"OLS regression: Slope={slope:F4}, Intercept={intercept:F4}");
// 5. ADF stationarity test
var spread = msftClose
.Zip(aaplClose, (m, a) => m - slope * a - intercept).ToList();
bool isStationary = analysis.AugmentedDickeyFullerTest(spread, adfTestStatisticThreshold: -2.86);
Console.WriteLine($"Spread ADF stationary: {isStationary}");
// 6. Z-Score
double zScore = analysis.CalculateZScores(spread, spread.Last());
Console.WriteLine($"Latest Z-Score: {zScore:F4}");
await Task.CompletedTask;
}
private static bool _pythonInitialized;
private static readonly object _initLock = new();
private static void InitializePython()
{
if (_pythonInitialized) return;
lock (_initLock)
{
if (_pythonInitialized) return;
var infra = PythonNetInfra.GetPythonInfra(CondaEnvPath, PythonDllName);
Runtime.PythonDLL = infra.PythonDLL;
PythonEngine.PythonHome = infra.PythonHome;
PythonEngine.PythonPath = infra.PythonPath;
PythonEngine.Initialize();
_pythonInitialized = true;
}
}
private static List<double> DownloadCloseViaYFinance(string symbol, DateTime start, DateTime end)
{
using (Py.GIL())
{
dynamic yf = Py.Import("yfinance");
string startStr = start.ToString("yyyy-MM-dd");
string endStr = end.ToString("yyyy-MM-dd");
dynamic df = yf.download(symbol, start: startStr, end: endStr, auto_adjust: true);
dynamic closeSeries = df.__getitem__("Close");
dynamic pyList = closeSeries.values.flatten().tolist();
var result = new List<double>();
foreach (dynamic item in pyList)
result.Add((double)item);
return result;
}
}
}运行:
dotnet run预期输出示例:
Downloading AAPL daily OHLCV via yfinance...
AAPL rows: 251
Downloading MSFT daily OHLCV via yfinance...
MSFT rows: 251
AAPL vs MSFT correlation: 0.9213
OLS regression: Slope=1.8472, Intercept=23.5610
Spread ADF stationary: True
Latest Z-Score: -0.3172
var dataService = provider.GetRequiredService<ITraditionalFinanceSourceDataService>();
var symbols = await dataService.GetSp500SymbolsAsync();
Console.WriteLine($"S&P 500 成分股数量: {symbols.Count()}");var futureService = provider.GetRequiredService<IBinanceUsdFutureService>();
futureService.ExchangeEnvironment = ExchangeEnvironment.Testnet; // 先用测试网
// 查询余额
decimal balance = await futureService.GetusdFutureAccountBalanceAsync();
Console.WriteLine($"账户余额: {balance}");
// 按比例建仓
await futureService.SetUsdFutureHoldingsAsync("BTCUSDT", 0.10, PositionSide.Long);
// 查看持仓
var positions = await futureService.GetHoldingPositionAsync();
Console.WriteLine($"持仓数量: {positions.Count()}");
// 清仓
await futureService.LiquidateUsdFutureAsync("BTCUSDT");var broker = provider.GetRequiredService<IUSEquityBrokerService>();
broker.ExchangeEnvironment = ExchangeEnvironment.Paper; // 模拟盘
decimal equity = await broker.GetAccountEquityAsync();
Console.WriteLine($"账户权益: {equity}");
await broker.SetHoldingsAsync("AAPL", 0.05m); // 5% 仓位
await broker.LiquidateAsync("AAPL"); // 清仓// 钉钉
var dingtalk = provider.GetRequiredService<IDingtalkService>();
await dingtalk.SendNotificationAsync("策略信号:买入 AAPL", accessToken, secret);
// 企业微信
var wechat = provider.GetRequiredService<IWeChatService>();
await wechat.SendTextNotificationAsync("订单已成交", webHookUrl);var analysis = provider.GetRequiredService<IAnalysisService>();
// 相关性
double corr = analysis.CalculateCorrelation(seriesA, seriesB);
// OLS 回归:diff = B - Slope * A - Intercept
var (slope, intercept) = analysis.PerformOLSRegression(seriesA, seriesB);
// ADF 平稳性检验(返回 bool)
bool isStationary = analysis.AugmentedDickeyFullerTest(spread);
// ADF 平稳性检验(返回详细结果,需要 Python 环境)
AdfTestResult adfResult = analysis.AugmentedDickeyFullerTestPython(spread);
// Z-Score
double z = analysis.CalculateZScores(spread, currentValue);
// Shapiro-Wilk 正态性检验
bool isNormal = analysis.PerformShapiroWilkTest(spread);// 滚动窗口:保持最近 20 根 K 线
var window = new RollingWindow<double>(20);
window.Add(100.5);
window.Add(101.2);
// ... 持续添加
if (window.IsReady)
{
Console.WriteLine($"窗口已满,共 {window.Count} 个元素");
}
// 定时触发器:每小时整点前 1 分钟触发
var trigger = new IntervalTrigger(StartMode.NextHour, TimeSpan.FromMinutes(-1));
trigger.IntervalTriggered += (sender, e) =>
{
Console.WriteLine($"触发! {DateTime.UtcNow}");
};
trigger.Start();// marketValueDict: Dictionary<DateTime, decimal> — 每日净值
double cagr = StrategyPerformanceAnalyzer.CalculateCAGR(marketValueDict);
double sharpe = StrategyPerformanceAnalyzer.CalculateSharpeRatio(marketValueDict, riskFreeRate);
double calmar = StrategyPerformanceAnalyzer.CalculateCalmarRatio(marketValueDict);
double maxDD = StrategyPerformanceAnalyzer.CalculateMaximumDrawdown(values);
Console.WriteLine($"CAGR={cagr:P2}, Sharpe={sharpe:F2}, Calmar={calmar:F2}, MaxDD={maxDD:P2}");cd src
dotnet restore
dotnet build
dotnet test运行指定测试类:
dotnet test --filter "FullyQualifiedName~AnalysisServiceTests"Quant.Infra.Net/
├── Analysis/ # 统计分析:ADF、OLS、相关性、Z-Score、配对交易
├── Broker/ # 券商接入:Binance、Alpaca、InteractiveBrokers
├── Notification/ # 通知:钉钉、企业微信、邮件
├── Order/ # 订单模型
├── Portfolio/ # 投资组合快照、绩效分析、净值曲线
├── Shared/ # 公共模型、枚举、RollingWindow、IntervalTrigger、UtilityService
└── SourceData/ # 数据采集:Yahoo Finance、Binance、CSV、MySQL、MongoDB
- ADF Python 模式:
AugmentedDickeyFullerTestPython方法依赖本机 Python 环境,需安装numpy、pandas、statsmodels。如果没有 Python 环境,请使用AugmentedDickeyFullerTest(纯 .NET 实现)。 - API Key 配置:Binance / Alpaca 等实盘接口需要在
appsettings.json或 User Secrets 中配置 API Key 和 Secret。 - ExchangeEnvironment:支持
Testnet(测试网)、Paper(模拟盘)、Live(实盘)三种环境,建议开发阶段使用 Testnet 或 Paper。 - Binance IP 限制:Binance API 对部分国家/地区的 IP 存在访问限制,如果你在运行 Binance 相关单元测试时遇到连接错误,这并非代码问题,请查阅 Binance 官方文档 了解受限地区列表。
- 合规免责声明:本项目仅提供量化交易基础设施工具,不构成任何投资建议。用户需自行确保使用本库时符合所在国家/地区的法律法规及交易所合规要求,因使用本库产生的任何法律或财务后果由用户自行承担。
Quant.Infra.Net 会继续维护当前公开仓库作为 Community Edition(免费版),现有开源功能会继续保留在这里。我们正在评估是否值得投入较多开发精力,建设一个独立的 Pro Edition,用于承载更高级的券商接入和生产级交易基础设施,例如 Charles Schwab、Interactive Brokers、多券商统一抽象、风控、部署模板和优先支持。这不是正式定价公告,而是一次路线图验证。如果你需要 Schwab / IB 接入,正在真实交易流程中使用本项目,或对 Community + Pro 双线路线有担忧和建议,欢迎在 GitHub Discussions 留言、加入下方技术交流群,或邮件联系
rex.fan18@gmail.com。 你的反馈会直接影响我们是否投入、以及投入多少精力做这件事。
由于券商API变动频繁,欢迎加入 Quant.Infra.Net 技术交流群。
- Telegram群组: https://t.me/+VPy-VLis8gVmYWM1
- 商业授权与定制开发咨询请联系: rex.fan18@gmail.com
扫码加入Telegram群组:
See LICENSE for details.
