// 通用5分钟MA5-MA200交叉策略(含回本保护+反手)
Params
Numeric MA5_Period(5);
Numeric MA200_Period(200);
Numeric MinMove(2);
Numeric StopProfit_Pts(100);
Numeric Slippage_Pts(1);
Numeric Commission_Rate(0.00015);
Vars
Numeric MA5;
Numeric MA200;
Numeric MA5_Prev;
Numeric MA200_Prev;
Numeric Current_Price;
Bool Is_MA5_UpCross;
Bool Is_MA5_DownCross;
Numeric Last_Signal_Time(0);
Numeric Order_Index(0);
Numeric Hold_Lots(0);
Numeric Open_Price(0);
Numeric Cumulative_Cost(0);
Numeric Reverse_Flag(0);
Numeric Dirty_Data_Flag(0);
Numeric Daily_Loss_Pct(0.02);
Numeric Lot_Series[13];
Events
OnInit;
OnBar(Integer);
OnInit()
{
Lot_Series[0] = 1;
Lot_Series[1] = 2;
Lot_Series[2] = 2;
Lot_Series[3] = 3;
Lot_Series[4] = 3;
Lot_Series[5] = 4;
Lot_Series[6] = 4;
Lot_Series[7] = 5;
Lot_Series[8] = 5;
Lot_Series[9] = 6;
Lot_Series[10] = 6;
Lot_Series[11] = 7;
Lot_Series[12] = 7;
SetCommissionRate(Commission_Rate);
SetSlippage(Slippage_Pts * MinMove);
Print("【MA5_200_Universal】Initialized.");
}
OnBar(Integer index)
{
DateTime t = CurrentTime();
Numeric hour = GetHour(t);
Numeric minute = GetMinute(t);
Numeric second = GetSecond(t);
Numeric now_ms = second * 1000 + minute * 60000 + hour * 3600000;
if ((hour == 10 && minute >= 15 && minute < 30) ||
(hour >= 11 && hour < 13) ||
(hour == 14 && minute >= 55))
{
return;
}
Current_Price = Close;
if (Current_Price <= 0 || High <= Low || Volume <= 0 || IsNaN(Current_Price))
{
return;
}
MA5 = MA(Close, MA5_Period);
MA200 = MA(Close, MA200_Period);
MA5_Prev = Ref(MA5, 1);
MA200_Prev = Ref(MA200, 1);
if (MA5 <= 0 || MA200 <= 0 || MA5_Prev <= 0 || MA200_Prev <= 0)
{
return;
}
Is_MA5_UpCross = (MA5 > MA200) && (MA5_Prev <= MA200_Prev) && (MA5 - MA200 >= MinMove);
Is_MA5_DownCross = (MA5 < MA200) && (MA5_Prev >= MA200_Prev) && (MA200 - MA5 >= MinMove);
if ((Is_MA5_UpCross || Is_MA5_DownCross) && (now_ms - Last_Signal_Time < 5 * 60 * 1000))
{
Is_MA5_UpCross = False;
Is_MA5_DownCross = False;
return;
}
Numeric long_lots = CurrentContracts(Enum_Position_Long);
Numeric short_lots = CurrentContracts(Enum_Position_Short);
Numeric total_hold = long_lots + short_lots;
if (total_hold == 0 && Order_Index == 0)
{
if (Is_MA5_UpCross)
{
Numeric lot = Lot_Series[0];
Buy(lot, Open + Slippage_Pts * MinMove);
Open_Price = Open + Slippage_Pts * MinMove;
Hold_Lots = lot;
Order_Index = 1;
Last_Signal_Time = now_ms;
Print("[First Long]", lot, "@", NumToStr(Open_Price, 2));
}
else if (Is_MA5_DownCross)
{
Numeric lot = Lot_Series[0];
SellShort(lot, Open - Slippage_Pts * MinMove);
Open_Price = Open - Slippage_Pts * MinMove;
Hold_Lots = lot;
Order_Index = 1;
Last_Signal_Time = now_ms;
Print("[First Short]", lot, "@", NumToStr(Open_Price, 2));
}
}
if (long_lots > 0 && Is_MA5_DownCross && Reverse_Flag == 0)
{
Sell(long_lots, Open - Slippage_Pts * MinMove);
Numeric close_px = Open - Slippage_Pts * MinMove;
Cumulative_Cost += (Open_Price - close_px);
Numeric idx = Min(Order_Index, 12);
Numeric new_lot = Lot_Series[idx];
SellShort(new_lot, close_px);
Open_Price = close_px;
Hold_Lots = new_lot;
Order_Index = idx + 1;
Reverse_Flag = 1;
Last_Signal_Time = now_ms;
Print("[Reverse L->S]", long_lots, "->", new_lot, "Cost:", NumToStr(Cumulative_Cost, 1));
}
if (short_lots > 0 && Is_MA5_UpCross && Reverse_Flag == 0)
{
BuyToCover(short_lots, Open + Slippage_Pts * MinMove);
Numeric close_px = Open + Slippage_Pts * MinMove;
Cumulative_Cost += (close_px - Open_Price);
Numeric idx = Min(Order_Index, 12);
Numeric new_lot = Lot_Series[idx];
Buy(new_lot, close_px);
Open_Price = close_px;
Hold_Lots = new_lot;
Order_Index = idx + 1;
Reverse_Flag = 1;
Last_Signal_Time = now_ms;
Print("[Reverse S->L]", short_lots, "->", new_lot, "Cost:", NumToStr(Cumulative_Cost, 1));
}
if (Hold_Lots >= 2 && Cumulative_Cost > 0)
{
if (long_lots > 0)
{
Numeric profit_per = Current_Price - Open_Price;
Numeric remain = Hold_Lots - 1;
if (remain * profit_per >= Cumulative_Cost)
{
Sell(remain, Open - Slippage_Pts * MinMove);
Hold_Lots = 1;
Cumulative_Cost = 0;
Print("[BE Long] Close", remain);
}
}
if (short_lots > 0)
{
Numeric profit_per = Open_Price - Current_Price;
Numeric remain = Hold_Lots - 1;
if (remain * profit_per >= Cumulative_Cost)
{
BuyToCover(remain, Open + Slippage_Pts * MinMove);
Hold_Lots = 1;
Cumulative_Cost = 0;
Print("[BE Short] Close", remain);
}
}
}
if (Hold_Lots == 1 && Cumulative_Cost == 0)
{
if (long_lots == 1 && (Current_Price - Open_Price) >= StopProfit_Pts)
{
Sell(1, Open - Slippage_Pts * MinMove);
Print("[TP Long]", NumToStr(Current_Price - Open_Price, 1), "pts");
Reset_State();
}
if (short_lots == 1 && (Open_Price - Current_Price) >= StopProfit_Pts)
{
BuyToCover(1, Open + Slippage_Pts * MinMove);
Print("[TP Short]", NumToStr(Open_Price - Current_Price, 1), "pts");
Reset_State();
}
}
Numeric equity = PortfolioTotalValue();
Numeric init_eq = PortfolioInitialValue();
if (init_eq > 0)
{
Numeric loss_pct = (init_eq - equity) / init_eq;
if (loss_pct >= Daily_Loss_Pct)
{
if (long_lots > 0) Sell(long_lots, Open - Slippage_Pts * MinMove);
if (short_lots > 0) BuyToCover(short_lots, Open + Slippage_Pts * MinMove);
Print("[CIRCUIT BREAKER]", NumToStr(loss_pct * 100, 2), "%");
Reset_State();
}
}
}
Void Reset_State()
{
Order_Index = 0;
Hold_Lots = 0;
Open_Price = 0;
Cumulative_Cost = 0;
Reverse_Flag = 0;
Last_Signal_Time = 0;
}

没有这种用法