一级标题
正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文。
二级标题
正文正文正百度官网文正文正文正文正文正文点此跳转正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文
public static List<int[]> 峰谷反做(string solName, bool history, int bLot, double minMove, int startI,
List<Bar> bars, bool arbi, string strgName, Dictionary<string, Prm> prms, ref SigData sigData, ref string error)
{
#region //读取参数
int barsN = bars.Count;
if (arbi) minMove = 1;
double X = doubleParam("X", strgName, prms, ref error); if (error == null) return null; //上下多少点截单(<=0时无效)
if (X <= 0)
{
error += "峰谷反做策略的X必须大于0";
return null;
}
double Q = doubleParam("Q", strgName, prms, ref error, 1.6); if (error == null) return null; //硬止损是X的多少倍(<=0时,没有硬止损)
int 盘口差跳数 = intParam("盘口差跳数", strgName, prms, ref error, 1); if (error == null) return null; //盘口差跳数
int 清仓时间 = intParam("清仓时间", strgName, prms, ref error, -1); if (error == null) return null;
//在测试中,当前K线起始时间小于此值,下一根K线起始时间达到此值或下一根K线起始日期大于当前K线起始日期时,当前K线清仓并不再下单,但下一根K线会恢复下单权限
//在实盘中,当前K线起始时间小于此值、当前tick时间达到此值时,清仓,当前K线清仓并不再下单,但下一根K线会恢复下单权限
//例如,中国大陆期货1分钟K线,如果打算隔夜清仓,可把清仓时间设为145950,否则设为-1
#endregion
#region //测试
List<int[]> newSigIJs = new List<int[]>();
bool isTick = false; //此策略不用于tick周期
int progressBarMax = 0;
if (history)
{
progressBarMax = callback.getProgressBarMax();
callback.setProgressBarMax(barsN);
callback.setProgress(0);
}
for (int i = startI; i < barsN; i++)
{
#region //每根K线的基本操作
if (history && i % 1000 == 0)
{
callback.setProgressBarText("方案【" + solName + "】生成信号,遍历第" + (i + 1).ToString() + "根K线(共" + barsN.ToString() + "根)");
callback.setProgress(i + 1);
}
string info = String.Empty; string Info = String.Empty;
bool barStart = false; //是否首次访问i号K线
if (i > StrgMng.getLastBarI(sigData))
{
barStart = true;
StrgMng.setLastBarI(ref sigData, i);
}
int date = bars[i].date; double time = bars[i].time;
double C = bars[i].C; double O = bars[i].O;
double H = bars[i].H; double L = bars[i].L;
double lastC = i - 1 >= 0 ? bars[i - 1].C : O; double lastO = i - 1 >= 0 ? bars[i - 1].O : O;
double lastH = i - 1 >= 0 ? bars[i - 1].H : O; double lastL = i - 1 >= 0 ? bars[i - 1].L : O;
//double lastLastC = i - 2 >= 0 ? bars[i - 2].C : lastO; double lastLastO = i - 2 >= 0 ? bars[i - 2].O : lastO;
//double lastLastH = i - 2 >= 0 ? bars[i - 2].H : lastO; double lastLastL = i - 2 >= 0 ? bars[i - 2].L : lastO;
//double lastLastLastC = i - 3 >= 0 ? bars[i - 3].C : lastLastO; double lastLastLastO = i - 3 >= 0 ? bars[i - 3].O : lastLastO;
//double lastLastLastLastC = i - 4 >= 0 ? bars[i - 4].C : lastLastLastO; double lastLastLastLastO = i - 4 >= 0 ? bars[i - 4].O : lastLastLastO;
if (barStart) updateSuperWave(i, C, O, lastC, lastH, lastL, isTick, minMove, ref sigData, ref info);
//在每根K线的开头更新波峰波谷(在此策略的sigData中,superH表示波峰,superL表示波谷)
#endregion
#region //判断转势
int lastTrend = sigData.superTrend;
double turnLine = Double.MinValue; //假如在当前K线转势,转势线的价格是多少
bool turnUp = false; //当前K线是否发生了向上转势
bool turnDown = false; //当前K线是否发生了向下转势
if (i > StrgMng.getSuperTurnI(sigData))
{
if (sigData.superTrend == 0) //尚无趋势时如何定趋势
{
sigData.backShortLine = sigData.superL.price + X;
sigData.backBuyLine = sigData.superH.price - X;
turnLine = sigData.backShortLine;
if (H > turnLine)
{
turnUp = true;
}
else
{
turnLine = sigData.backBuyLine;
if (L < turnLine) turnDown = true;
}
}
else if (sigData.superTrend < 0) //趋势向下时如何向上转势
{
turnLine = sigData.superL.price + X;
sigData.backShortLine = turnLine;
if (!turnUp && H > turnLine) turnUp = true;
}
else //if (sigData.superTrend > 0) //趋势向上时如何向下转势
{
turnLine = sigData.superH.price - X;
sigData.backBuyLine = turnLine;
if (!turnDown && L < turnLine) turnDown = true;
}
}
if (turnUp) //向上转势后更新相关变量
{
bool up = true; string signText = String.Empty;
superTurn(up, isTick, i, bars, i, turnLine, signText, minMove, ref sigData, ref Info);
}
else if (turnDown) //向下转势后更新相关变量
{
bool up = false; string signText = String.Empty;
superTurn(up, isTick, i, bars, i, turnLine, signText, minMove, ref sigData, ref Info);
}
#endregion
#region //交易
#region //隔夜清仓
if (清仓时间 >= 0)
{
if (barStart && StrgMng.getForbidden(sigData)) StrgMng.setForbidden(ref sigData, false);
if (history)
{
int nextBarDate = 0; double nextBarTime = -1;
if (i < barsN - 1)
{
Bar nextBar = bars[i + 1];
nextBarDate = nextBar.date; nextBarTime = nextBar.time;
}
bool needClear = false;
if (time < 清仓时间)
{
if (nextBarDate > 0 && nextBarTime >= 0)
{
if (nextBarDate > date) needClear = true;
else if (nextBarTime >= 清仓时间) needClear = true;
}
else
{
needClear = true;
}
}
if (needClear && !StrgMng.getForbidden(sigData))
{
StrgMng.setForbidden(ref sigData, true);
if (sigData.shortVol > 0)
{
double tradablePrice = Num.formatPrice(C + 盘口差跳数 * minMove, minMove, 1);
Cover(i, date, time, sigData.shortVol, tradablePrice, "隔夜平", false, ref sigData, ref newSigIJs);
}
if (sigData.longVol > 0)
{
double tradablePrice = Num.formatPrice(C - 盘口差跳数 * minMove, minMove, -1);
Sell(i, date, time, sigData.longVol, tradablePrice, "隔夜平", false, ref sigData, ref newSigIJs);
}
}
}
else
{
if (!StrgMng.getForbidden(sigData) && time < 清仓时间 && Num.getTime() >= 清仓时间)
{
StrgMng.setForbidden(ref sigData, true);
if (sigData.shortVol > 0)
{
double tradablePrice = Num.formatPrice(C + 盘口差跳数 * minMove, minMove, 1);
Cover(i, date, time, sigData.shortVol, tradablePrice, "隔夜平", false, ref sigData, ref newSigIJs);
}
else if (sigData.longVol > 0)
{
double tradablePrice = Num.formatPrice(C - 盘口差跳数 * minMove, minMove, -1);
Sell(i, date, time, sigData.longVol, tradablePrice, "隔夜平", false, ref sigData, ref newSigIJs);
}
}
}
}
#endregion
#region //其他
if (turnUp) //向上转势时
{
bool B = false;
峰谷反做下单(B, turnLine, i, O, date, time, 盘口差跳数, minMove, bLot, X, Q, ref sigData, ref newSigIJs);
}
else if (turnDown) //向下转势时
{
bool B = true;
峰谷反做下单(B, turnLine, i, O, date, time, 盘口差跳数, minMove, bLot, X, Q, ref sigData, ref newSigIJs);
}
bool 倒N形出场 = false; bool 继承开仓标记 = true; bool 改开仓标记 = false; bool 标平仓性质 = true;
double 保本比例 = 0; double ATR = StrgMng.errorIndValue;
List<int[]> closedOpenSigIJs = close(bars, i, 盘口差跳数, minMove, ATR, 保本比例, 0, 倒N形出场, 继承开仓标记, 改开仓标记, 标平仓性质, ref sigData, ref newSigIJs);
if (history) closeBeforeGap(i, minMove, bars, ref sigData, ref newSigIJs); //在回测中,在更换主力合约的大跳空之前清仓
#endregion
#endregion
setBarInfo(i, info, Info, ref sigData);
}
if (history)
{
callback.setProgressBarMax(progressBarMax);
callback.setProgress(0);
}
return newSigIJs;
#endregion
}