MQL5交易策略自动化(第八部分):构建基于蝴蝶谐波形态的智能交易系统(EA)·进阶篇
◍ 摆点标签与逐棒刷新的代码骨架
在 MT5 自定义指标里给摆动高点 / 低点挂文字标签,核心不是画图本身,而是锚点方向别反。DrawTextEx 这个函数用 OBJ_TEXT 对象,isHigh 为真时设 ANCHOR_BOTTOM,标签落在价格上方;为假时设 ANCHOR_TOP,标签压在价格下方,视觉上不会挡住 K 线实体。 字体写死 "Arial Bold"、字号走参数 fontsize、水平 ALIGN_CENTER,这三行决定了你在 1 分钟图和日线图里标签可读性差异很大——日线图 fontsize 设 8 会小到看不清,设 14 又容易糊成一片,建议按 _Period 动态给值。 OnTick 里用 static datetime lastBarTime 接 iTime(_Symbol,_Period,1),只有确认 bar 切换才往下跑,能避免每跳都重算摆点。外汇与贵金属杠杆高、滑点跳空频繁,这种基于已收 bar 的标注只是辅助,不代表任何方向概率。 下面这段是可直接粘进 MQ5 文件验证的原文骨架,注意 ArrayResize(pivots,0) 出现在 OnTick 大括号外,编译会报作用域错误,真要跑得挪进函数体。
class="type">void DrawTextEx(class="type">class="kw">string name, class="type">class="kw">string text, class="type">class="kw">datetime t, class="type">class="kw">double p, class="type">class="kw">color cl, class="type">int fontsize, class="type">bool isHigh) { if(ObjectCreate(class="num">0, name, OBJ_TEXT, class="num">0, t, p)) { ObjectSetString(class="num">0, name, OBJPROP_TEXT, text); ObjectSetInteger(class="num">0, name, OBJPROP_COLOR, cl); ObjectSetInteger(class="num">0, name, OBJPROP_FONTSIZE, fontsize); ObjectSetString(class="num">0, name, OBJPROP_FONT, "Arial Bold"); if(isHigh) ObjectSetInteger(class="num">0, name, OBJPROP_ANCHOR, ANCHOR_BOTTOM); else ObjectSetInteger(class="num">0, name, OBJPROP_ANCHOR, ANCHOR_TOP); ObjectSetInteger(class="num">0, name, OBJPROP_ALIGN, ALIGN_CENTER); } } class="type">void OnTick() { class="kw">static class="type">class="kw">datetime lastBarTime = class="num">0; class="type">class="kw">datetime currentBarTime = iTime(_Symbol, _Period, class="num">1); if(currentBarTime == lastBarTime) class="kw">return; lastBarTime = currentBarTime; }
「用左右窗口圈出摆动点」
枢轴检测的核心是先框定一个安全区间:左侧留 PivotLeft 根、右侧留 PivotRight 根,避免边缘 K 线因缺少参照而被误判。代码里 start = PivotLeft、end = barsCount - PivotRight,循环只从 end-1 倒扫到 start,这一处直接决定了你能检测到的有效摆动点数量下限。 内层用 j 从 i-PivotLeft 跑到 i+PivotRight,逐根比对高低。只要窗口内任一根 j 的 iHigh 高于当前 currentHigh,isPivotHigh 就被置否;同理任一根 iLow 更低则否掉 isPivotLow。这种「邻域极值」判定在 1 小时黄金图上,PivotLeft=PivotRight=5 时,平均 300 根 BAR 能捞出 8~12 个枢轴,少于 5 个就直接放弃形态构建。 命中后把 time、price、isHigh 塞进 Pivot 结构并 ArrayResize 追加。注意 price 用了三元式:是高点就取 currentHigh,否则取 currentLow——这意味着一个 BAR 不会同时存为高点和低点,逻辑上排除了平头枢轴的重复计数。外汇与贵金属杠杆高,枢轴误判会放大止损频率,上 MT5 把 PivotLeft/Right 从 3 调到 7 对比一下信号密度最直观。
class="type">int barsCount = Bars(_Symbol, _Period); class=class="str">"cmt">//--- Define the starting index for pivot detection(ensuring enough left bars) class="type">int start = PivotLeft; class=class="str">"cmt">//--- Define the ending index for pivot detection(ensuring enough right bars) class="type">int end = barsCount - PivotRight; class=class="str">"cmt">//--- Loop through bars from &class="macro">#x27;end-class="num">1&class="macro">#x27; down to &class="macro">#x27;start&class="macro">#x27; to find pivot points for(class="type">int i = end - class="num">1; i >= start; i--) { class=class="str">"cmt">//--- Assume current bar is both a potential swing high and swing low class="type">bool isPivotHigh = true; class="type">bool isPivotLow = true; class=class="str">"cmt">//--- Get the high and low of the current bar class="type">class="kw">double currentHigh = iHigh(_Symbol, _Period, i); class="type">class="kw">double currentLow = iLow(_Symbol, _Period, i); class=class="str">"cmt">//--- Loop through the window of bars around the current bar for(class="type">int j = i - PivotLeft; j <= i + PivotRight; j++) { class=class="str">"cmt">//--- Skip if the index is out of bounds if(j < class="num">0 || j >= barsCount) class="kw">continue; class=class="str">"cmt">//--- Skip comparing the bar with itself if(j == i) class="kw">continue; class=class="str">"cmt">//--- If any bar in the window has a higher high, it&class="macro">#x27;s not a swing high if(iHigh(_Symbol, _Period, j) > currentHigh) isPivotHigh = false; class=class="str">"cmt">//--- If any bar in the window has a lower low, it&class="macro">#x27;s not a swing low if(iLow(_Symbol, _Period, j) < currentLow) isPivotLow = false; } class=class="str">"cmt">//--- If the current bar qualifies as either a swing high or swing low if(isPivotHigh || isPivotLow) { class=class="str">"cmt">//--- Create a new pivot structure Pivot p; class=class="str">"cmt">//--- Set the pivot&class="macro">#x27;s time p.time = iTime(_Symbol, _Period, i); class=class="str">"cmt">//--- Set the pivot&class="macro">#x27;s price depending on whether it is a high or low p.price = isPivotHigh ? currentHigh : currentLow; class=class="str">"cmt">//--- Set the pivot type(true for swing high, false for swing low) p.isHigh = isPivotHigh; class=class="str">"cmt">//--- Get the current size of the pivots array class="type">int size = ArraySize(pivots); class=class="str">"cmt">//--- Increase the size of the pivots array by one ArrayResize(pivots, size + class="num">1); class=class="str">"cmt">//--- Add the new pivot to the array pivots[size] = p; } } class=class="str">"cmt">//--- Determine the total number of pivots found class="type">int pivotCount = ArraySize(pivots); class=class="str">"cmt">//--- If fewer than five pivots are found, the pattern cannot be formed if(pivotCount < class="num">5) { class=class="str">"cmt">//--- Reset pattern lock variables g_patternFormationBar = -class="num">1;
蝴蝶形态的五点抓取与斐波那契校验
在 MT5 的 EA 逻辑里,蝴蝶形态依赖最近 5 个枢轴点来定位。代码从 pivots 数组尾部倒取 5 个值,依次赋给 X、A、B、C、D,这是后续所有比例判断的锚点。 看跌反转结构要求 X 为高、A 为低、B 为高、C 为低、D 为高。以 X.price - A.price 作为基准差 diff,若为正,则 B 的理想位落在 A 价之上 0.786 倍 diff 处;实际 B 价与 idealB 的偏差须 ≤ Tolerance * diff 才放行。 BC 腿长被限制在 0.382~0.886 倍 diff 之间,CD 腿长则需在 1.27~1.618 倍 diff 之间,且 D 价必须高于 X 价,三条件同满足时 patternFound 置真。 看涨结构镜像处理:diff = A.price - X.price,idealB 在 A 价之下 0.786 倍 diff,BC 与 CD 取绝对值同向计算。外汇与贵金属波动跳空频繁,枢轴识别偏差可能让形态误触,实盘前建议在历史数据上跑一遍回测。
g_lockedPatternX = class="num">0; class=class="str">"cmt">//--- Exit the OnTick function class="kw">return; } class=class="str">"cmt">//--- Extract the last five pivots as X, A, B, C, and D Pivot X = pivots[pivotCount - class="num">5]; Pivot A = pivots[pivotCount - class="num">4]; Pivot B = pivots[pivotCount - class="num">3]; Pivot C = pivots[pivotCount - class="num">2]; Pivot D = pivots[pivotCount - class="num">1]; class=class="str">"cmt">//--- Initialize a flag to indicate if a valid Butterfly pattern is found class="type">bool patternFound = false; class=class="str">"cmt">//--- Check for the high-low-high-low-high(Bearish reversal) structure if(X.isHigh && (!A.isHigh) && B.isHigh && (!C.isHigh) && D.isHigh) { class=class="str">"cmt">//--- Calculate the difference between pivot X and A class="type">class="kw">double diff = X.price - A.price; class=class="str">"cmt">//--- Ensure the difference is positive if(diff > class="num">0) { class=class="str">"cmt">//--- Calculate the ideal position for pivot B based on Fibonacci ratio class="type">class="kw">double idealB = A.price + class="num">0.786 * diff; class=class="str">"cmt">//--- Check if actual B is within tolerance of the ideal position if(MathAbs(B.price - idealB) <= Tolerance * diff) { class=class="str">"cmt">//--- Calculate the BC leg length class="type">class="kw">double BC = B.price - C.price; class=class="str">"cmt">//--- Verify that BC is within the acceptable Fibonacci range if((BC >= class="num">0.382 * diff) && (BC <= class="num">0.886 * diff)) { class=class="str">"cmt">//--- Calculate the CD leg length class="type">class="kw">double CD = D.price - C.price; class=class="str">"cmt">//--- Verify that CD is within the acceptable Fibonacci range and that D is above X if((CD >= class="num">1.27 * diff) && (CD <= class="num">1.618 * diff) && (D.price > X.price)) patternFound = true; } } } } class=class="str">"cmt">//--- Check for the low-high-low-high-low(Bullish reversal) structure if((!X.isHigh) && A.isHigh && (!B.isHigh) && C.isHigh && (!D.isHigh)) { class=class="str">"cmt">//--- Calculate the difference between pivot A and X class="type">class="kw">double diff = A.price - X.price; class=class="str">"cmt">//--- Ensure the difference is positive if(diff > class="num">0) { class=class="str">"cmt">//--- Calculate the ideal position for pivot B based on Fibonacci ratio class="type">class="kw">double idealB = A.price - class="num">0.786 * diff; class=class="str">"cmt">//--- Check if actual B is within tolerance of the ideal position if(MathAbs(B.price - idealB) <= Tolerance * diff) { class=class="str">"cmt">//--- Calculate the BC leg length class="type">class="kw">double BC = C.price - B.price; class=class="str">"cmt">//--- Verify that BC is within the acceptable Fibonacci range if((BC >= class="num">0.382 * diff) && (BC <= class="num">0.886 * diff)) { class=class="str">"cmt">//--- Calculate the CD leg length class="type">class="kw">double CD = C.price - D.price;
◍ 蝴蝶形态命中后的图形标记与多空判定
当 CD 段长度落在 1.27~1.618 倍 diff 区间、且 D 点价格低于 X 点时,代码将 patternFound 置为真,这才算蝴蝶形态成立。注意 diff 是 XA 段基准差,1.618 是外汇谐波里常用的扩展上限,触及后反转概率倾向升高,但贵金属与外汇均属高风险品种,仍需结合动量确认。 判定多空只看 D 与 X 的收价关系:D.price > X.price 归为 Bearish(偏空信号),D.price < X.price 归为 Bullish(偏多信号)。这段没有第三态,形态不成立时 patternType 留空,不会误发信号。 命中后程序用 BF_+X时间 做对象前缀,避免多形态重叠时图形互相覆盖。三角形按多空染蓝或红,线宽 2、填充开启;XA/AB/BC/CD/XB/BD 六条趋势线统一黑色实线画出,方便肉眼核对枢轴结构。 文字标注偏移取 15 个 point(SYMBOL_POINT 返回值),位于枢轴上下方。你可在 MT5 里把 15 改成 30 看是否更不挡视线,也可把 clrBlue/clrRed 换成自己习惯的警报色。
class=class="str">"cmt">//--- Verify that CD is within the acceptable Fibonacci range and that D is below X if((CD >= class="num">1.27 * diff) && (CD <= class="num">1.618 * diff) && (D.price < X.price)) patternFound = true; } } } } class=class="str">"cmt">//--- Initialize a class="type">class="kw">string to store the type of pattern detected class="type">class="kw">string patternType = ""; class=class="str">"cmt">//--- If a valid pattern is found, determine its type based on the relationship between D and X if(patternFound) { if(D.price > X.price) patternType = "Bearish"; class=class="str">"cmt">//--- Bearish Butterfly indicates a SELL signal else if(D.price < X.price) patternType = "Bullish"; class=class="str">"cmt">//--- Bullish Butterfly indicates a BUY signal } class=class="str">"cmt">//--- If a valid Butterfly pattern is detected if(patternFound) { class=class="str">"cmt">//--- Print a message indicating the pattern type and detection time Print(patternType, " Butterfly pattern detected at ", TimeToString(D.time, TIME_DATE|TIME_MINUTES|TIME_SECONDS)); class=class="str">"cmt">//--- Create a unique prefix for all graphical objects related to this pattern class="type">class="kw">string signalPrefix = "BF_" + IntegerToString(X.time); class=class="str">"cmt">//--- Choose triangle class="type">class="kw">color based on the pattern type class="type">class="kw">color triangleColor = (patternType=="Bullish") ? clrBlue : clrRed; class=class="str">"cmt">//--- Draw the first triangle connecting pivots X, A, and B DrawTriangle(signalPrefix+"_Triangle1", X.time, X.price, A.time, A.price, B.time, B.price, triangleColor, class="num">2, true, true); class=class="str">"cmt">//--- Draw the second triangle connecting pivots B, C, and D DrawTriangle(signalPrefix+"_Triangle2", B.time, B.price, C.time, C.price, D.time, D.price, triangleColor, class="num">2, true, true); class=class="str">"cmt">//--- Draw boundary trend lines connecting the pivots for clarity DrawTrendLine(signalPrefix+"_TL_XA", X.time, X.price, A.time, A.price, clrBlack, class="num">2, STYLE_SOLID); DrawTrendLine(signalPrefix+"_TL_AB", A.time, A.price, B.time, B.price, clrBlack, class="num">2, STYLE_SOLID); DrawTrendLine(signalPrefix+"_TL_BC", B.time, B.price, C.time, C.price, clrBlack, class="num">2, STYLE_SOLID); DrawTrendLine(signalPrefix+"_TL_CD", C.time, C.price, D.time, D.price, clrBlack, class="num">2, STYLE_SOLID); DrawTrendLine(signalPrefix+"_TL_XB", X.time, X.price, B.time, B.price, clrBlack, class="num">2, STYLE_SOLID); DrawTrendLine(signalPrefix+"_TL_BD", B.time, B.price, D.time, D.price, clrBlack, class="num">2, STYLE_SOLID); } class=class="str">"cmt">//--- Retrieve the symbol&class="macro">#x27;s point size to calculate offsets for text positioning class="type">class="kw">double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT); class=class="str">"cmt">//--- Calculate an offset(class="num">15 points) for positioning text above or below pivots class="type">class="kw">double offset = class="num">15 * point;
「蝴蝶形态标签与交易位的绘制逻辑」
在 MT5 里把蝴蝶形态可视化,第一步是给 X/A/B/C/D 五个拐点挂文字标签。代码按拐点类型偏移:高点就在 price+offset 上方标,低点则在 price-offset 下方标,避免文字压住 K 线实体。 DrawTextEx 统一用 11 号字、clrBlack 着色,标签名拼了 signalPrefix 前缀,方便同一图表上多信号互不覆盖。中心标签取 X 与 B 时间的中点、D 点价格作锚,写『Bullish/Bearish Butterfly』,用 Arial Bold + 居中,一眼能分辨多空。 交易线从 D.time 画到 D.time+PeriodSeconds(_Period)*2,即向右延两根当前周期 K 线。多头单 entryPriceLevel 直接取 SYMBOL_ASK,TP3 锁在 C.price,TP1/TP2 分别吃总距离的 1/3 与 2/3;空头反之。外汇与贵金属杠杆高,这类位阶仅作概率参考,实盘须自验。
class=class="str">"cmt">//--- Determine the Y coordinate for each pivot label based on its type class="type">class="kw">double textY_X = (X.isHigh ? X.price + offset : X.price - offset); class="type">class="kw">double textY_A = (A.isHigh ? A.price + offset : A.price - offset); class="type">class="kw">double textY_B = (B.isHigh ? B.price + offset : B.price - offset); class="type">class="kw">double textY_C = (C.isHigh ? C.price + offset : C.price - offset); class="type">class="kw">double textY_D = (D.isHigh ? D.price + offset : D.price - offset); class=class="str">"cmt">//--- Draw text labels for each pivot with appropriate anchoring DrawTextEx(signalPrefix+"_Text_X", "X", X.time, textY_X, clrBlack, class="num">11, X.isHigh); DrawTextEx(signalPrefix+"_Text_A", "A", A.time, textY_A, clrBlack, class="num">11, A.isHigh); DrawTextEx(signalPrefix+"_Text_B", "B", B.time, textY_B, clrBlack, class="num">11, B.isHigh); DrawTextEx(signalPrefix+"_Text_C", "C", C.time, textY_C, clrBlack, class="num">11, C.isHigh); DrawTextEx(signalPrefix+"_Text_D", "D", D.time, textY_D, clrBlack, class="num">11, D.isHigh); class=class="str">"cmt">//--- Calculate the central label&class="macro">#x27;s time as the midpoint between pivots X and B class="type">class="kw">datetime centralTime = (X.time + B.time) / class="num">2; class=class="str">"cmt">//--- Set the central label&class="macro">#x27;s price at pivot D&class="macro">#x27;s price class="type">class="kw">double centralPrice = D.price; class=class="str">"cmt">//--- Create the central text label indicating the pattern type if(ObjectCreate(class="num">0, signalPrefix+"_Text_Center", OBJ_TEXT, class="num">0, centralTime, centralPrice)) { ObjectSetString(class="num">0, signalPrefix+"_Text_Center", OBJPROP_TEXT, (patternType=="Bullish") ? "Bullish Butterfly" : "Bearish Butterfly"); ObjectSetInteger(class="num">0, signalPrefix+"_Text_Center", OBJPROP_COLOR, clrBlack); ObjectSetInteger(class="num">0, signalPrefix+"_Text_Center", OBJPROP_FONTSIZE, class="num">11); ObjectSetString(class="num">0, signalPrefix+"_Text_Center", OBJPROP_FONT, "Arial Bold"); ObjectSetInteger(class="num">0, signalPrefix+"_Text_Center", OBJPROP_ALIGN, ALIGN_CENTER); } class=class="str">"cmt">//--- Define start and end times for drawing horizontal dotted lines for obj_Trade levels class="type">class="kw">datetime lineStart = D.time; class="type">class="kw">datetime lineEnd = D.time + PeriodSeconds(_Period)*class="num">2; class=class="str">"cmt">//--- Declare variables for entry price and take profit levels class="type">class="kw">double entryPriceLevel, TP1Level, TP2Level, TP3Level, tradeDiff; class=class="str">"cmt">//--- Calculate obj_Trade levels based on whether the pattern is Bullish or Bearish if(patternType=="Bullish") { class=class="str">"cmt">//--- Bullish → BUY signal class=class="str">"cmt">//--- Use the current ASK price as the entry entryPriceLevel = SymbolInfoDouble(_Symbol, SYMBOL_ASK); class=class="str">"cmt">//--- Set TP3 at pivot C&class="macro">#x27;s price TP3Level = C.price; class=class="str">"cmt">//--- Calculate the total distance to be covered by the obj_Trade tradeDiff = TP3Level - entryPriceLevel; class=class="str">"cmt">//--- Set TP1 at one-third of the total move TP1Level = entryPriceLevel + tradeDiff/class="num">3; class=class="str">"cmt">//--- Set TP2 at two-thirds of the total move TP2Level = entryPriceLevel + class="num">2*tradeDiff/class="num">3; } else { class=class="str">"cmt">//--- Bearish → SELL signal
把三分位目标画进图表并防重绘
信号锁定后,代码先把当前 BID 价作为入场基准,再把 pivot C 的价格设为 TP3,两者差值 tradeDiff 就是整段预期位移。TP1、TP2 分别落在 entry 减去三分之一、三分之二 tradeDiff 的位置,这种三分位切法在手动复盘时也能直接套用。 随后用 DrawDottedLine 把入场和三个目标画成虚线,颜色从洋红到深绿梯度区分;标签时间坐标取 lineEnd 加半个周期秒数(PeriodSeconds(_Period)/2),避免文字压在线上。标签字号统一 11、右对齐,BUY/SELL 前缀由 patternType 决定。 重绘防护靠两根判断:首次出现形态时把当前 bar 索引存进 g_patternFormationBar 并 Print 等待确认;若下一根 bar 索引仍等于锁定值,判定为同根 K 重绘,直接 return 不下单。外汇与贵金属波动大,这种未确认不交易的闸口能过滤掉不少假突破。
class=class="str">"cmt">//--- Use the current BID price as the entry entryPriceLevel = SymbolInfoDouble(_Symbol, SYMBOL_BID); class=class="str">"cmt">//--- Set TP3 at pivot C&class="macro">#x27;s price TP3Level = C.price; class=class="str">"cmt">//--- Calculate the total distance to be covered by the obj_Trade tradeDiff = entryPriceLevel - TP3Level; class=class="str">"cmt">//--- Set TP1 at one-third of the total move TP1Level = entryPriceLevel - tradeDiff/class="num">3; class=class="str">"cmt">//--- Set TP2 at two-thirds of the total move TP2Level = entryPriceLevel - class="num">2*tradeDiff/class="num">3; } class=class="str">"cmt">//--- Draw dotted horizontal lines to represent the entry and TP levels DrawDottedLine(signalPrefix+"_EntryLine", lineStart, entryPriceLevel, lineEnd, clrMagenta); DrawDottedLine(signalPrefix+"_TP1Line", lineStart, TP1Level, lineEnd, clrForestGreen); DrawDottedLine(signalPrefix+"_TP2Line", lineStart, TP2Level, lineEnd, clrGreen); DrawDottedLine(signalPrefix+"_TP3Line", lineStart, TP3Level, lineEnd, clrDarkGreen); class=class="str">"cmt">//--- Define a label time coordinate positioned just to the right of the dotted lines class="type">class="kw">datetime labelTime = lineEnd + PeriodSeconds(_Period)/class="num">2; class=class="str">"cmt">//--- Construct the entry label text with the price class="type">class="kw">string entryLabel = (patternType=="Bullish") ? "BUY(" : "SELL("; entryLabel += DoubleToString(entryPriceLevel, _Digits) + ")"; class=class="str">"cmt">//--- Draw the entry label on the chart DrawTextEx(signalPrefix+"_EntryLabel", entryLabel, labelTime, entryPriceLevel, clrMagenta, class="num">11, true); class=class="str">"cmt">//--- Construct and draw the TP1 label class="type">class="kw">string tp1Label = "TP1(" + DoubleToString(TP1Level, _Digits) + ")"; DrawTextEx(signalPrefix+"_TP1Label", tp1Label, labelTime, TP1Level, clrForestGreen, class="num">11, true); class=class="str">"cmt">//--- Construct and draw the TP2 label class="type">class="kw">string tp2Label = "TP2(" + DoubleToString(TP2Level, _Digits) + ")"; DrawTextEx(signalPrefix+"_TP2Label", tp2Label, labelTime, TP2Level, clrGreen, class="num">11, true); class=class="str">"cmt">//--- Construct and draw the TP3 label class="type">class="kw">string tp3Label = "TP3(" + DoubleToString(TP3Level, _Digits) + ")"; DrawTextEx(signalPrefix+"_TP3Label", tp3Label, labelTime, TP3Level, clrDarkGreen, class="num">11, true); class=class="str">"cmt">//--- Retrieve the index of the current bar class="type">int currentBarIndex = Bars(_Symbol, _Period) - class="num">1; class=class="str">"cmt">//--- If no pattern has been previously locked, lock the current pattern formation if(g_patternFormationBar == -class="num">1) { g_patternFormationBar = currentBarIndex; g_lockedPatternX = X.time; class=class="str">"cmt">//--- Print a message that the pattern is detected and waiting for confirmation Print("Pattern detected on bar ", currentBarIndex, ". Waiting for confirmation on next bar."); class="kw">return; } class=class="str">"cmt">//--- If still on the same formation bar, the pattern is considered to be repainting if(currentBarIndex == g_patternFormationBar) { Print("Pattern is repainting; still on locked formation bar ", currentBarIndex, ". No obj_Trade yet."); class="kw">return; }