第二章 基础网格策略设计
约 1991 字大约 7 分钟
2025-10-07
一、核心思想回顾:从“波动获利”到“参数构建”
上一章我们提到,网格交易的核心在于:
利用价格波动反复低买高卖,赚取结构性差价收益。
这一章要回答的问题是: 我们应该如何量化设计这个“结构”?
换句话说:
- 网格应该覆盖多宽的价格区间?
- 网格之间的间距要多大?
- 总共划分几层?
- 每一层的仓位怎么安排?
这些看似简单的问题,其实决定了网格系统的收益率、风险敞口、资金效率。
二、价格区间、网格数量与间距的选择原则
一个标准网格系统可以抽象为:
| 参数 | 符号 | 含义 |
|---|---|---|
| 上限价格 | Pmax | 网格区间的最高价 |
| 下限价格 | Pmin | 网格区间的最低价 |
| 网格数量 | N | 网格层数(买卖层级数) |
| 网格间距 | ΔP | 相邻两网格的价格差 |
1. 间距计算公式
- 等差网格(Arithmetic Grid):
ΔP=NPmax−Pmin
- 等比网格(Geometric Grid):
r=(PminPmax)1/N,Pi=Pmin⋅ri
2. 区间选择建议
- 选择区间应覆盖预期波动范围的 95%。 例如最近 30 天价格的最高/最低价上下各扩展 5%。
- 若区间过窄 → 触发频繁但容易出区; 若区间过宽 → 资金分散、收益稀薄。
3. 网格数量的经验法则
| 市场波动性 | 建议网格数 | 特点 |
|---|---|---|
| 高波动品种(如加密货币) | 50–200 | 间距小、交易频繁 |
| 中等波动(外汇、ETF) | 20–100 | 平衡收益与风险 |
| 低波动(蓝筹股票) | 10–30 | 间距宽、节奏慢 |
三、等差 vs 等比网格:不同的“价格心理学”
1. 等差网格
每一层价格差固定,适合价格波动较平稳、趋势弱的市场。
- 优点:计算简单、易理解;
- 缺点:在高价区资金利用效率低。
示意图:
像在价格轴上等距铺设一排捕鱼网。
2. 等比网格
价格层间成比例递增(每格涨幅相同百分比), 适合波动率随价格上升而扩大的市场(如币圈)。
- 优点:相对平滑,能自适应价格尺度;
- 缺点:下区间间距过密,上区间过稀。
示意图:
像在对数坐标轴上等距布网,更接近人类“百分比思维”。
四、初始建仓策略:集中 vs 匀速
当你启动网格策略时,价格可能位于整个区间的任何位置。 这时需要决定——是否提前买入部分仓位?
策略一:集中建仓(Aggressive Start)
直接在中间价位附近一次性建好底仓。
- 优点:若行情立刻震荡,可快速获利;
- 缺点:若持续下跌,浮亏较大。
策略二:匀速建仓(Gradual Start)
从当前价格向下逐步挂买单,等待市场触发。
- 优点:安全稳健、平均成本低;
- 缺点:若价格上行,可能“踏空”。
📊 实际中,许多成熟系统采用“部分底仓 + 条件单补仓”的混合模式。
五、盈利与回撤的数学期望分析
1. 单次交易收益
假设网格间距为 ΔP,单次买入量为 q,则单次交易收益近似:
Profit1=q⋅ΔP
2. 理论年化收益估算
若单位时间平均触发频率为 f 次,则:
Annualized Return≈Total Capitalq⋅ΔP⋅f⋅365
3. 最大潜在回撤
当价格从上沿跌至下沿,触发所有买单,最大持仓成本:
Cmax=q⋅i=1∑NPi
浮亏约为:
Drawdown∗max=q⋅(P∗max−Pmin)
由此可粗略估计风险承受边界。
六、实例:可交互的收益与风险计算器
<script src="https://cdn.plot.ly/plotly-3.1.1.min.js" charset="utf-8"></script>
<div>
<label>标的名称: <input type="text" id="asset" value="某标的"></label><br>
<label>初始基准价: <input type="number" id="basePrice" value="100"></label><br>
<label>网格价差: <input type="number" id="gridGap" value="1"></label><br>
<label>每次交易金额: <input type="number" id="amount" value="100"></label><br>
<label>初始现金: <input type="number" id="initCash" value="10000"></label><br>
<label>初始持仓份数: <input type="number" id="initPosition" value="10"></label><br>
<label>波动幅度 (%): <input type="number" id="volatility" value="0.1"></label><br>
<label>时间步数: <input type="number" id="steps" value="50000"></label><br>
<button id="simulateBtn">模拟网格交易</button>
</div>
<div id="grid-simulator" style="width:100%; height:700px;"></div>
<div id="results">
<p id="profit"></p>
<p id="drawdown"></p>
<p id="annualReturn"></p>
</div>/* body {
background: white;
color: black;
}
@media (prefers-color-scheme: dark) {
body {
background: #222222;
color: white;
}
} */
body {
background: var(--bg-color);
color: var(--text-color);
border-radius: 8px;
padding: 1em;
}
input, textarea, select {
background-color: var(--input-bg);
color: var(--input-text);
border: 1px solid var(--input-border);
}
/* 亮色主题 */
:root[data-theme="light"] {
--bg-color: white;
--text-color: black;
--input-bg: #ffffff;
--input-text: #000000;
--input-border: #ccc;
}
/* 暗色主题 */
:root[data-theme="dark"] {
--bg-color: #1b1b1f;
--text-color: white;
--input-bg: #1e1e1e;
--input-text: #e0e0e0;
--input-border: #555;
}
/* 可选:让 placeholder 也变色 */
input::placeholder {
color: var(--input-border);
}
.plot-container {
filter: invert(90%) hue-rotate(180deg);
}function simulateGridDynamic(basePrice, gridGap, amount, initCash, initPosition, volatility, steps) {
let prices = [basePrice];
let cash = initCash;
let position = initPosition;
let equity = [cash + position * basePrice];
let currentBase = basePrice;
// 记录买入/卖出触发点
let buyPoints = {x: [], y: []};
let sellPoints = {x: [], y: []};
for (let t = 1; t <= steps; t++) {
let prevPrice = prices[prices.length-1];
let change = prevPrice * (Math.random()*2 - 1) * volatility/100;
let price = prevPrice + change;
let hand = 0;
prices.push(price);
if (price <= currentBase - gridGap) {
if (cash >= amount) {
// 买入并更新网格基准价
hand = Math.min( Math.trunc( (currentBase - price) / gridGap ), Math.trunc(cash / amount) );
cash -= amount * hand;
position += amount * hand / price;
currentBase -= gridGap * hand;
buyPoints.x.push(t);
buyPoints.y.push(price);
} else {
hand = Math.trunc( (currentBase - price) / gridGap );
currentBase -= gridGap * hand;
}
} else if (price >= currentBase + gridGap) {
if (position >= 1) {
// 卖出并更新网格基准价
hand = Math.min( Math.trunc( (price - currentBase) / gridGap ), Math.trunc(position) );
cash += amount * hand;
position -= amount * hand / price;
currentBase += gridGap * hand;
sellPoints.x.push(t);
sellPoints.y.push(price);
} else {
// 仅更新网格基准价
hand = Math.trunc( (price - currentBase) / gridGap );
currentBase += gridGap * hand;
}
}
equity.push(cash + position * price);
}
// 最大回撤
let maxEquity = equity[0];
let maxDrawdown = 0;
for (let val of equity) {
if (val > maxEquity) maxEquity = val;
const drawdown = maxEquity - val;
if (drawdown > maxDrawdown) maxDrawdown = drawdown;
}
let expectedAnnualReturn = (equity[equity.length-1] / (equity[0] || 1)) * 12 * 30;
let profit = equity.map(x => x - equity[0]);
return { prices, equity, profit, buyPoints, sellPoints, profitPerTrade: ((equity[equity.length-1]-equity[0])/steps).toFixed(2), maxDrawdown: maxDrawdown.toFixed(2), expectedAnnualReturn: (expectedAnnualReturn*100).toFixed(2) };
}
function getThemeTemplate() {
return document.body.dataset.theme === 'dark' ? 'plotly_dark' : 'plotly';
}
document.getElementById("simulateBtn").addEventListener("click", () => {
const asset = document.getElementById("asset").value;
const basePrice = parseFloat(document.getElementById("basePrice").value);
const gridGap = parseFloat(document.getElementById("gridGap").value);
const amount = parseFloat(document.getElementById("amount").value);
const initCash = parseFloat(document.getElementById("initCash").value);
const initPosition = parseFloat(document.getElementById("initPosition").value);
const volatility = parseFloat(document.getElementById("volatility").value);
const steps = parseInt(document.getElementById("steps").value);
const result = simulateGridDynamic(basePrice, gridGap, amount, initCash, initPosition, volatility, steps);
// document.getElementById("profit").innerText = `${asset} 平均单步收益: ${result.profitPerTrade}`;
// document.getElementById("drawdown").innerText = `${asset} 理论最大回撤: ${result.maxDrawdown}`;
// document.getElementById("annualReturn").innerText = `${asset} 理论年化收益率: ${result.expectedAnnualReturn}%`;
// 绘制上下两图
const fig = {
data: [
// 价格线
{
x: Array.from({length: result.prices.length}, (_, i)=>i),
y: result.prices,
// mode: "lines+markers",
mode: 'lines',
name: "价格",
xaxis: 'x',
yaxis: 'y1'
},
// 买入标记
{
x: result.buyPoints.x,
y: result.buyPoints.y,
mode: 'markers',
name: '买入',
marker: {color:'green', size:8, symbol:'triangle-up'},
xaxis: 'x',
yaxis: 'y1'
},
// 卖出标记
{
x: result.sellPoints.x,
y: result.sellPoints.y,
mode: 'markers',
name: '卖出',
marker: {color:'red', size:8, symbol:'triangle-down'},
xaxis: 'x',
yaxis: 'y1'
},
// 累计收益线
{
x: Array.from({length: result.profit.length}, (_, i)=>i),
y: result.profit,
mode: "lines",
name: "累计收益",
xaxis: 'x',
yaxis: 'y2'
}
],
layout: {
title: "网格交易动态模拟(标记买入/卖出)",
hovermode: 'x unified',
xaxis: {title:{text:'时间步'}},
yaxis: {title:{text:'价格'}, domain:[0.5,1]},
yaxis2: {title:{text:'累计收益'}, domain:[0,0.45]},
}
};
// 绘图
Plotly.newPlot("grid-simulator", fig.data, fig.layout);
});七、总结:策略设计的三要素
一个健壮的网格系统,往往平衡了以下三点:
- 结构合理:价格区间与间距反映市场特性;
- 资金安全:仓位与风险控制得当;
- 节奏匹配:触发频率与交易成本相协调。
网格交易不是“随意挂单”,而是有节奏的结构设计。 当你能理性地量化结构时,你离“稳定盈利”就只差一个执行系统。
📘 下一章预告: 我们将进入更智能的部分—— 如何利用“条件单”构建动态触发网格, 让系统根据市场行为自动调整, 实现条件单网格策略。
