「拉回買入」,專為趨勢交易者在商品上漲趨勢中,尋找追買/加碼點而設計。當商品價格進入新一輪的上漲階段時,交易者需掌握如何在價格的短期回調中抓住低點進場。這不僅可以避免追高,也能充分利用資金分批加碼,進一步提升獲利潛力。
本篇多單進場的方式,即是利用 MACD仍在零軸上的多方趨勢中的拉回進場。空單的進場方式以 收盤價小於 NL 值搭配 KD 低檔鈍化做限價掛單進場
#include <Trade\Trade.mqh>
#include <MagicMT5_函數庫V1.mqh>
ENUM_TIMEFRAMES 時間週期 = PERIOD_M20;
int OnInit()
{
LoadEA = TimeCurrent();
return(INIT_SUCCEEDED);
}
void OnTick()
{
if(AccountInfoDouble(ACCOUNT_BALANCE) <= 資金風控)
{
Alert("********** 資金不足 *************");
return;
}
BarNumber = iBarShift(Symbol(),時間週期,LoadEA);
BarSinceExit = BarNumber-CloseOrderNo ;
if((BarNumber == 1 && BarNumber != JudgeNo))
{
多單進場單號 = Buy_at_MARKET(Symbol(),Lots,0,0,"1st_K",MagicNumber) ;
LX_CloseByTicket(多單進場單號,Lots) ;
CloseOrderNo = iBarShift(Symbol(),時間週期,LoadEA);
FastSma = MathMin(LenA1, LenB1);
SlowSma = MathMax(LenA1, LenB1);
}
if(BarNumber != JudgeNo)
{
換K棒();
允許交易時段 = (getTM_Weekday(TimeCurrent()) != 5); //時間濾網
}
Ask=SymbolInfoDouble(Symbol(),SYMBOL_ASK);
Bid=SymbolInfoDouble(Symbol(),SYMBOL_BID);
AccountBalance=AccountInfoDouble(ACCOUNT_BALANCE);
Tickvalue=SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_VALUE);
SP = NormalizeDouble(MathAbs(Ask-Bid),Digits()) ;
//+------------------------------------------------------------------+
//|計算交易手數
//+------------------------------------------------------------------+
if(Lots_AutoCal == true)
{
Lots = get_dynamic_lot_size(Lots_Even,Symbol(),RiskPercent,AccountBalance,SL) ;
Lots = MathMin(0.3,MathMax(0.01,Lots)) ;
}
if(允許交易時段 == true)
{
//+------------------------------------------------------------------+
//|多單進場 連三黑K且收盤最低 且 MACD 零軸上
//+------------------------------------------------------------------+
LE_Cond = (Black3Bar_LClose() && a_MACD[1] > 0) ;
if(LE_Cond == true)
{
//做多前 有空單先平倉
if(空單部位() > 0 && BarNumber != OrderBarNo)
{
sell_order_close_all(Symbol(), MagicNumber, ORDER_TYPE_SELL);
CloseOrderNo = iBarShift(Symbol(),時間週期,LoadEA);
}
if(多單部位() == 0 && BarNumber != OrderBarNo)
{
//距離上筆出場經過一根K棒 且當日未進場
if(BarSinceExit > 1 && EntriesToday(MagicNumber,Symbol()) < 1)
{
// 空手+市價單買入
多單進場單號 = Buy_at_MARKET(Symbol(),Lots,TP,SL,"BUY MARKET",MagicNumber) ;
OrderBarNo = iBarShift(Symbol(),時間週期,LoadEA);
} // end of BarSinceExit > 1
} // end of 空手且不同根K棒() == true
} // end of LE_Cond == true
//+------------------------------------------------------------------+
//|空單進場 前一根收盤價小於 NL 且KD 低檔鈍化
//+------------------------------------------------------------------+
SE_Cond = (Close[1] < NL && KD低檔鈍化()) ;
if(SE_Cond == true)
{
//做空前 有多單先平倉
if(多單部位() > 0 && BarNumber != OrderBarNo)
{
buy_order_close_all(Symbol(), MagicNumber, ORDER_TYPE_BUY);
CloseOrderNo = iBarShift(Symbol(),時間週期,LoadEA);
}
if(空單部位() == 0 && BarNumber != OrderBarNo)
{
賣出價格 = NormalizeDouble((Lowest_OHLC(Symbol(),PERIOD_D1,MODE_LOW,LBar,2) - Range[2]*0.5),Digits());
//距離上筆出場經過一根K棒 且當日未進場
if(BarSinceExit > 1 && EntriesToday(MagicNumber,Symbol()) < 1)
{
if(Close[1] < 賣出價格)
{
// 空手+掛單限價賣出
空單進場單號 = Short_at_LIMIT(Symbol(),MagicNumber,賣出價格,Lots,TP,SL,"Short STOP",3600) ;
OrderBarNo = iBarShift(Symbol(),時間週期,LoadEA);
}
} //end of BarSinceExit > 1
} // end of 空手且不同根K棒() == true
} // end of SE_Cond == true
} //end of 允許交易時段 == true
if(多單部位() > 0)
{
//+------------------------------------------------------------------+
//| Buy Exit Method 多單 固定停利停損點數出場
//+------------------------------------------------------------------+
多單進場價格 = LE_EntryPrice(MagicNumber,多單進場單號);
多單停利價格 = NormalizeDouble(多單進場價格 + TP * Point(),Digits()) ;
多單停損價格 = NormalizeDouble(多單進場價格 - SL * Point(),Digits()) ;
LX_Cond = ((Close[1] <= 多單停利價格 && Bid > 多單停利價格) || (Close[1] >= 多單停損價格 && Bid < 多單停損價格)) ;
//---------------------------------------------------------多單出場
if(LX_Cond == true && BarNumber != CloseOrderNo && BarNumber != OrderBarNo && LE_BarsSinceEntry(MagicNumber,多單進場單號,時間週期) > 0)
{
LX_CloseByTicket(多單進場單號,Lots) ;
if(多單部位() == 0)
{
CloseOrderNo = iBarShift(Symbol(),時間週期,LoadEA) ;
}
}
} // end of 多單部位() > 0
if(空單部位() > 0)
{
//+------------------------------------------------------------------+
//| Short Exit Method 空單 一目均衡表雲層界外出場
//+------------------------------------------------------------------+
bool SXcond51,SXcond52 ;
空單停利價格 = NormalizeDouble(MathMin(a_ICHI_SA[1], a_ICHI_SB[1]) - Range[1] * 2,Digits());
空單停損價格 = NormalizeDouble(MathMin((空單進場價格 + SL * Point()),MathMax(a_ICHI_SA[1], a_ICHI_SB[1]) + Range[1] * 2),Digits());
SXcond51 = (空單進場價格 > 空單停利價格 && Close[1] >= 空單停利價格 && Ask < 空單停利價格) ;
SXcond52 = (空單進場價格 < 空單停損價格 && Close[1] <= 空單停損價格 && Ask > 空單停損價格) ;
SX_Cond = (SXcond51 == true || SXcond52 == true) ;
//---------------------------------------------------------空單出場
if(SX_Cond == true && BarNumber != CloseOrderNo && SE_BarsSinceEntry(MagicNumber,空單進場單號,時間週期) > 0)
{
SX_CloseByTicket(空單進場單號,Lots) ;
if(空單部位() == 0)
{
CloseOrderNo = iBarShift(Symbol(),時間週期,LoadEA) ;
}
}
} // end of 空單部位() > 0
JudgeNo = iBarShift(Symbol(),時間週期,LoadEA);
} //end of onTick
//+------------------------------------------------------------------+
//| 自訂函數庫 |
//+------------------------------------------------------------------+
int 多單部位()
{
int count;
count = get_TradeCounts(Symbol(), MagicNumber,POSITION_TYPE_BUY) ;
return count ;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int 空單部位()
{
int count;
count = get_TradeCounts(Symbol(), MagicNumber,POSITION_TYPE_SELL) ;
return count ;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void 換K棒()
{
// 新K棒刪除所有掛單
if(total_pending_order_count(Symbol(), MagicNumber,-1) != 0)
{
delete_pending_orders_all(Symbol(), MagicNumber, -1, 0x0000ff);
}
Set_OHLC_Bar_Series();
Get_OHLC_Bar(10) ;
Set_OHLC_Day_Series();
Get_OHLC_Day(10) ;
set_BarInfo();
set_MACD();
set_KD() ;
set_CDP();
set_ICHIMOKU();
Day5Range = ((HighD[1] - LowD[1])+(HighD[2] - LowD[2])+(HighD[3] - LowD[3])+(HighD[4] - LowD[4])+(HighD[5] - LowD[5]))/5;
}
//+--------------------------------------------------------+
//| 設定 開高低收 陣列序列
//+--------------------------------------------------------+
//********BarPrice Array variables
double Open[], High[], Low[], Close[],Range[],Body[],UPshadow[],DNshadow[] ;
double OpenD[], HighD[], LowD[], CloseD[] ;
//+------------------------------------------------------------------+
//|
//+------------------------------------------------------------------+
void Set_OHLC_Bar_Series()
{
ArraySetAsSeries(Open,true);
ArraySetAsSeries(High,true);
ArraySetAsSeries(Low,true);
ArraySetAsSeries(Close,true);
}
//+------------------------------------------------------------------+
//|
//+------------------------------------------------------------------+
void Get_OHLC_Bar(int argCount)
{
get_OpenData(Symbol(),時間週期,argCount,Open) ;
get_HighData(Symbol(),時間週期,argCount,High) ;
get_LowData(Symbol(),時間週期,argCount,Low) ;
get_CloseData(Symbol(),時間週期,argCount,Close) ;
}
//+------------------------------------------------------------------+
//|
//+------------------------------------------------------------------+
void set_BarInfo()
{
ArrayResize(Range,ArraySize(Open)) ;
ArraySetAsSeries(Range,true) ;
ArrayResize(Body,ArraySize(Open)) ;
ArraySetAsSeries(Body,true) ;
ArrayResize(UPshadow,ArraySize(Open)) ;
ArraySetAsSeries(UPshadow,true) ;
ArrayResize(DNshadow,ArraySize(Open)) ;
ArraySetAsSeries(DNshadow,true) ;
for(int i = 0; i < ArraySize(Open)-1; i=i+1)
{
Range[i] = High[i]-Low[i];
Body[i] = MathAbs(Close[i]-Open[i]);
UPshadow[i] = High[i]-MathMax(Close[i],Open[i]);
DNshadow[i] = MathMin(Close[i],Open[i])-Low[i];
}
}
//+------------------------------------------------------------------+
//|
//+------------------------------------------------------------------+
void Set_OHLC_Day_Series()
{
ArraySetAsSeries(OpenD,true);
ArraySetAsSeries(HighD,true);
ArraySetAsSeries(LowD,true);
ArraySetAsSeries(CloseD,true);
}
//+------------------------------------------------------------------+
//|
//+------------------------------------------------------------------+
void Get_OHLC_Day(int argCount)
{
get_OpenData(Symbol(),PERIOD_D1,argCount,OpenD) ;
get_HighData(Symbol(),PERIOD_D1,argCount,HighD) ;
get_LowData(Symbol(),PERIOD_D1,argCount,LowD) ;
get_CloseData(Symbol(),PERIOD_D1,argCount,CloseD) ;
}
//+------------------------------------------------------------------+
//| 指標及通道計算
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| 計算 MACD 值
//+------------------------------------------------------------------+
double a_DIF[], a_MACD[], a_OSC[] ;
void set_MACD()
{
int MacdLen, FastLen, SlowLen ;
int h_DIF,h_MACD ;
MacdLen = MathMax(LenA1,LenB1) ;
if(MacdLen > 15)
MacdLen = 15 ;
FastLen = (int)MathRound(MacdLen*1.33) ;
SlowLen = (int)MathRound(MacdLen*2.66) ;
h_DIF = iMACD(Symbol(),時間週期,FastLen,SlowLen,MacdLen,PRICE_WEIGHTED);
ArraySetAsSeries(a_DIF, true);
h_MACD = iMACD(Symbol(),時間週期,FastLen,SlowLen,MacdLen,PRICE_WEIGHTED);
ArraySetAsSeries(a_MACD, true);
get_IndexData(h_DIF,0,0,10,a_DIF) ;
get_IndexData(h_MACD,1,0,10,a_MACD) ;
ArraySetAsSeries(a_OSC, true);
ArrayResize(a_OSC,ArraySize(a_DIF)) ;
for(int i = 0;i < ArraySize(a_OSC); i++)
{
a_OSC[i] = a_DIF[i]-a_MACD[i] ;
}
}
//+------------------------------------------------------------------+
//| 計算 KD值
//+------------------------------------------------------------------+
int h_KA2,h_DA2 ;
double a_KA2[], a_DA2[] ;
void set_KD()
{
h_KA2 = iStochastic(Symbol(),時間週期,LenA2,3,3,MODE_EMA,STO_LOWHIGH) ;
ArraySetAsSeries(a_KA2,true);
h_DA2 = iStochastic(Symbol(),時間週期,LenA2,3,3,MODE_EMA,STO_LOWHIGH) ;
ArraySetAsSeries(a_DA2,true);
get_IndexData(h_KA2,0,0,5,a_KA2) ;
get_IndexData(h_DA2,1,0,5,a_DA2) ;
}
//+------------------------------------------------------------------+
//| 計算 CDO值
//+------------------------------------------------------------------+
double CDP,AH,NH,NL,AL,CDPrange ;
bool CrossAH,CrossAL;
void set_CDP()
{
double Highest2,Lowest2 ;
CDP = (HighD[1]+LowD[1]+2*CloseD[1])/4;
AH = CDP + (HighD[1] - LowD[1]);
NH = CDP*2 - LowD[1];
NL = CDP*2 - HighD[1];
AL = CDP - (HighD[1] - LowD[1]);
CDPrange = HighD[1] - LowD[1] ;
}
//+------------------------------------------------------------------+
//| 計算一目均衡表通道
//+------------------------------------------------------------------+
double a_ICHI_B[],a_ICHI_C[],a_ICHI_SA[],a_ICHI_SB[],a_ICHI_LC[] ;
void set_ICHIMOKU()
{
int h_ICHI_C,h_ICHI_B,h_ICHI_SA,h_ICHI_SB,h_ICHI_LC ;
h_ICHI_C = iIchimoku(Symbol(),時間週期,9,26,52);
ArraySetAsSeries(a_ICHI_C, true);
h_ICHI_B = iIchimoku(Symbol(),時間週期,9,26,52);
ArraySetAsSeries(a_ICHI_B, true);
h_ICHI_SA = iIchimoku(Symbol(),時間週期,9,26,52);
ArraySetAsSeries(a_ICHI_SA, true);
h_ICHI_SB = iIchimoku(Symbol(),時間週期,9,26,52);
ArraySetAsSeries(a_ICHI_SB, true);
h_ICHI_LC = iIchimoku(Symbol(),時間週期,9,26,52);
ArraySetAsSeries(a_ICHI_LC, true);
get_IndexData(h_ICHI_C,0,0,5,a_ICHI_C) ;
get_IndexData(h_ICHI_B,1,0,5,a_ICHI_B) ;
get_IndexData(h_ICHI_SA,2,0,5,a_ICHI_SA) ;
get_IndexData(h_ICHI_SB,3,0,5,a_ICHI_SB) ;
get_IndexData(h_ICHI_LC,4,0,5,a_ICHI_LC) ;
}
//+------------------------------------------------------------------+
//|
//+------------------------------------------------------------------+
bool KD低檔鈍化()
{
int Counter = 0;
for(int i = 1; i < ArraySize(a_KA2); i=i+1)
{
if(a_KA2[i] < 30)
{
Counter = Counter + 1;
}
}
if(a_KA2[1] < 30 && Counter >= 4)
{
return true;
}
return false;
}
//+------------------------------------------------------------------+
//| 連三黑K 且收盤價最低
//+------------------------------------------------------------------+
bool Black3Bar_LClose()
{
int j = 0;
for(int i = 1; i <= 3; i=i+1)
{
if(Close[i] < Open[i])
{
j = j + 1;
}
}
if((j == 3 && Close[1] <= MathMin(Close[2], Close[3])))
{
return true;
}
return false;
}
//+------------------------------------------------------------------+
交易商品 NDAQ100 樣本內區間 2019/1/1 ~2022/12/31 交易手數 固定 0.1手
沒有留言:
張貼留言