backtestengine
v1.0.2
Published
股票量化交易回测引擎
Downloads
17
Maintainers
Readme
BacktestEngine
一个功能强大的股票量化交易回测引擎,支持多时间周期回测、技术指标计算、风险管理等功能。
特性
- 支持多时间周期回测(分钟、小时、日、周、月、年)
- 内置多个技术指标(MA、MACD、KDJ、RSI等)
- 灵活的策略编写方式,支持自定义策略逻辑
- 完整的风险管理功能(止盈止损、仓位控制)
- 详细的回测统计指标(收益率、夏普比率、最大回撤等)
- 支持T+0/T+1交易限制
- 支持滑点和手续费设置
- 支持多品种回测
安装
npm install backtestengine
使用示例
基础用法
import { BacktestEngine, PrismaDataProvider, Timeframe, TradeRestriction } from 'backtestengine';
// 创建数据提供者实例
const dataProvider = new PrismaDataProvider();
// 策略代码
const strategyCode = `
// 获取当前K线数据
const { bar, indicators, signal, currentIndex, positions } = context;
// 打印当前K线信息
console.log(\`当前K线: 日期=\${bar.date.toISOString()}, 收盘价=\${bar.close}, 索引=\${currentIndex}\`);
// 获取技术指标值
const ma5 = indicators.getValue('MA', 'DAY', currentIndex, { period: 5 });
const ma10 = indicators.getValue('MA', 'DAY', currentIndex, { period: 10 });
const ma25 = indicators.getValue('MA', 'DAY', currentIndex, { period: 25 });
// 获取上一个周期的指标值
const prevMa5 = currentIndex > 0 ? indicators.getValue('MA', 'DAY', currentIndex - 1, { period: 5 }) : null;
const prevMa10 = currentIndex > 0 ? indicators.getValue('MA', 'DAY', currentIndex - 1, { period: 10 }) : null;
// 打印指标值
console.log(\`指标值: MA5=\${ma5?.toFixed(2)}, MA10=\${ma10?.toFixed(2)}, MA25=\${ma25?.toFixed(2)}\`);
if (currentIndex > 0) {
console.log(\`上一周期: prevMA5=\${prevMa5?.toFixed(2)}, prevMA10=\${prevMa10?.toFixed(2)}\`);
}
// 如果没有足够的数据,直接返回
if (!ma5 || !ma10 || !ma25 || !prevMa5 || !prevMa10) {
console.log('指标数据不足,跳过信号判断');
return;
}
// 买入条件:
// 1. 5日均线上穿10日均线(当前MA5 > MA10 且 前一日MA5 <= MA10)
// 2. 当天价格高于5周均线(25日均线)
if (
ma5 > ma10 &&
prevMa5 <= prevMa10 &&
bar.close > ma25
) {
console.log('触发买入信号');
console.log(\`当前持仓: \${Array.from(positions.values()).map(p => \`\${p.symbol}: \${p.quantity}股\`).join(', ') || '无'}\`);
// 买入信号,使用100%资金
signal('BUY', 1);
}
// 卖出条件:
// 1. 5日均线下穿10日均线(当前MA5 < MA10 且 前一日MA5 >= MA10)
if (
ma5 < ma10 &&
prevMa5 >= prevMa10
) {
console.log('触发卖出信号');
console.log(\`当前持仓: \${Array.from(positions.values()).map(p => \`\${p.symbol}: \${p.quantity}股\`).join(', ') || '无'}\`);
// 卖出信号,卖出全部持仓
signal('SELL', 1);
}
`;
// 配置回测参数
const config = {
// 初始资金100万
initialCapital: 1_000_000,
// 手续费率0.0003
commissionRate: 0.0003,
// 滑点率0.0001
slippage: 0.0001,
// 最大持仓比例100%
maxPositionRatio: 1,
// 止损比例100%(不设止损)
stopLossRatio: 1,
// 止盈比例100%(不设止盈)
takeProfitRatio: 1,
// 回测开始日期
startDate: new Date('2023-01-01'),
// 回测结束日期
endDate: new Date('2024-06-30'),
// 主要时间周期为日线
mainTimeframe: 'DAY' as Timeframe,
// 交易品种代码(贵州茅台,上交所)
symbol: '600519',
// T+1交易限制
tradeRestriction: TradeRestriction.T1,
// 数据提供者
dataProvider,
// 策略代码
strategyCode
};
// 创建回测引擎实例
const engine = new BacktestEngine(config);
// 运行回测
engine.runBacktest().then((result) => {
console.log("回测完成!");
console.log("总收益率:", result.stats.totalReturn);
console.log("年化收益率:", result.stats.annualizedReturn);
console.log("最大回撤:", result.stats.maxDrawdown);
console.log("夏普比率:", result.stats.sharpeRatio);
console.log("胜率:", result.stats.winRate);
console.log("盈亏比:", result.stats.profitLossRatio);
});
多时间周期回测示例
const config = {
// ... 其他配置同上
mainTimeframe: "DAY",
timeframes: ["5MIN", "15MIN", "60MIN", "DAY"],
indicators: [
{ name: "MA", params: { period: 20 }, timeframe: "DAY" },
{ name: "MA", params: { period: 60 }, timeframe: "60MIN" },
{ name: "RSI", params: { period: 14 }, timeframe: "15MIN" },
],
strategyCode: `
const { bar, indicators, signal, currentIndex, positions } = context;
// 获取不同时间周期的指标值
const dailyMA = indicators.getValue("MA", "DAY", currentIndex, { period: 20 });
const hourlyMA = indicators.getValue("MA", "60MIN", currentIndex, { period: 60 });
const rsi15min = indicators.getValue("RSI", "15MIN", currentIndex, { period: 14 });
// 多时间周期交易逻辑
if (bar.close > dailyMA && bar.close > hourlyMA && rsi15min < 30) {
signal("BUY", 0.1);
} else if (rsi15min > 70) {
signal("SELL", 1);
}
`
};
风险管理示例
const config = {
// ... 其他配置同上
// 最大持仓比例(单个品种最多使用20%的资金)
maxPositionRatio: 0.2,
// 止损比例(亏损5%自动止损)
stopLossRatio: 0.05,
// 止盈比例(盈利10%自动止盈)
takeProfitRatio: 0.1,
strategyCode: `
const { bar, indicators, signal, currentIndex, positions, cash } = context;
// 计算当前总资产
let totalAssets = cash;
positions.forEach((pos) => {
totalAssets += pos.quantity * bar.close;
});
// 仓位管理:确保单个品种持仓不超过总资产的20%
const maxPosition = totalAssets * 0.2;
const currentPosition = positions.get(bar.symbol)?.quantity * bar.close || 0;
if (currentPosition < maxPosition) {
// 交易信号逻辑
const rsi = indicators.getValue("RSI", "DAY", currentIndex, { period: 14 });
if (rsi < 30) {
// 计算可买入金额
const availableAmount = maxPosition - currentPosition;
const positionRatio = availableAmount / totalAssets;
signal("BUY", positionRatio);
}
}
// 系统会自动根据stopLossRatio和takeProfitRatio处理止盈止损
`
};
API文档
BacktestEngine
主要的回测引擎类,用于执行回测逻辑。
构造函数
constructor(config: BacktestConfig)
配置选项
initialCapital
: 初始资金commissionRate
: 手续费率slippage
: 滑点率maxPositionRatio
: 最大持仓比例stopLossRatio
: 止损比例takeProfitRatio
: 止盈比例startDate
: 回测开始日期endDate
: 回测结束日期mainTimeframe
: 主要时间周期timeframes
: 支持的时间周期数组tradeRestriction
: 交易限制(T+0/T+1)dataProvider
: 数据提供者symbol
: 交易品种代码indicators
: 技术指标配置strategyCode
: 策略代码
方法
runBacktest(overrideTimeframe?: Timeframe): Promise<BacktestResult>
运行回测,可选择覆盖配置中的时间周期
技术指标
内置多个技术指标类:
MAIndicator
: 移动平均线- 参数:period(周期)
MACDIndicator
: MACD指标- 参数:shortPeriod(短周期)、longPeriod(长周期)、signalPeriod(信号周期)
KDJIndicator
: KDJ指标- 参数:kPeriod(K周期)、dPeriod(D周期)、jPeriod(J周期)
RSIIndicator
: RSI指标- 参数:period(周期)
数据提供者
PrismaDataProvider
: 基于Prisma的数据提供者- 支持多时间周期数据加载
- 自动数据缓存
- 支持多品种数据
回测结果说明
回测完成后会返回包含以下信息的结果对象:
interface BacktestResult {
// 交易记录
trades: TradeRecord[];
// 权益曲线
equityCurve: number[];
// 统计指标
stats: {
// 总收益率
totalReturn: number;
// 年化收益率
annualizedReturn: number;
// 最大回撤
maxDrawdown: number;
// 夏普比率
sharpeRatio: number;
// 胜率
winRate: number;
// 盈亏比
profitLossRatio: number;
// 最大连续盈利次数
consecutiveWins: number;
// 最大连续亏损次数
consecutiveLosses: number;
// 平均持仓周期(天)
averageHoldingPeriod: number;
};
// 当前持仓
positions: Position[];
// 指标数据
indicators?: { [key: string]: any };
}
许可证
ISC