From: 紅財神財務工程學院

http://ganapati.pixnet.net/blog/post/32094356-%E5%BE%97%E5%AF%B8%E9%80%B2%E5%B0%BA-(2)---%E6%B7%BA%E8%AB%87%E5%81%9C%E6%90%8Dstop-loss-%E4%BB%A5%E5%8F%8A-%E7%A7%BB%E5%8B%95%E5%81%9C%E6%90%8D


院長/York

各位讀者大家好。延續上一篇文章的介紹,我們接著來談「移動停損」的概念以及做法。絕大部分的投資者都有停損的觀念,但大部分懂停損的投資者,對於「停損」概念都是固定定點的停損。例如,以「資產停損」(Equity Stop Loss)模式就是在下了單之後,當市場反向時在虧損幾點之後就停損出場。舉錢一篇文章的假設,若我們的帳戶有1000元美金,而資產損失之最大風險設為5%。所以,在任何市場情況下,只要其帳戶損失達到1000 x 5% =50 美金時,停損命令就會被下達。這類的停損其實是一種非常機械性的「觸發然後執行」的動作。本篇文章所要談停損是一種「動態性」的停損,就如本文章的標題「得寸進尺」,它可以讓你在保護利潤之餘同時讓停損點一步一步移到有利於自己的下單部位。



首先,我們先來解釋何謂「移動停損」Trailing Stop ? 我們很簡單的到 Investopedia 來查詢一個簡單的解釋: "A stop-loss order set at a percentage level below the market price - for a long position. The trailing stop price is adjusted as the price fluctuates. The trailing stop order can be placed as a trailing stop limit order, or a trailing stop market order. " 【中譯】: 在一個多單的倉位,設定一個低於目前市場價位某個百分比階層的停損單。而這個移動停損單的價格將會因為市場的波動而調整。此移動停損單可以被設定成「移動停損限價單」或「移動停損市價單」。



整句話的重點在於「調整」兩個字,也就是說,「Trailing Stop」 是一個會隨著市場波動而調整停損點的一個停損機制。而細部的解釋就是「Trailing Stop」可以設定一個「停損參數」,而這個「停損參數」可以產生「移動現象」,而此「移動現象」是依照價格的波動所產生的。所以才被稱之為「移動停損」Trailing Stop。這個「停損參數」可以是被設定為價格波動的百分比,例如10%、15%等,或者一個固定的數值,例如20 Pips、30 Pips等。比如說,我們假設預估EURUSD的價格會往上,我們對EURUSD下買單,假設當EURUSD真的價格往上移的時候,一個設定適當的「移動停損」Trailing Stop 可以用來利潤最大化或保護利潤,同時「墊高」並限制當價格下滑後的停損點。相反的,我們假設預估EURUSD的價格會往下,我們對EURUSD下賣單,假設當EURUSD真的價格往下移的時候,一個設定適當的「移動停損」Trailing Stop 一樣可以用來利潤最大化或保護利潤,同時「下移」並限制當價格上漲後的停損點。以一個實際的案例來說,假設我們買了EURUSD在1.4410,同時我們設了Trailing Stop 為10 Pips。那就是說停損點是設在 1.4410 - 0.0010 (10 Pips) = 1.4400。假設我們下了這個1.4410的買單,但如果市場並沒有往上漲,反而往下掉了9點到1.4401,這時,我們所設定的Trailing Stop並不會被觸發,因為我們設的移動停損點是在1.4400。很幸運的,當市場掉到1.4401之後開始往上漲,漲到1.4460,這時的停損點因為設定Trailing Stop 為10Pips 的關係,所以不是在1.4400而是在1.4450。而接下來市場又開始走跌,市場價格真的跌到1.4450,甚至被貫壓到1.4350,這時Trailing Stop 會在1.4450就以市場單來執行此買單出場。所以,若依照上面的劇本,如果沒有設定Trailing Stop,不僅利潤不見了,還被市場碰到原始的停損單1.4400,本來可以賺錢的卻變成虧損。所以,「移動停損」Trailing Stop 不僅是保護利潤的方式,也是逐步墊高(或下壓)停損價格點的一個方法。



在外匯市場裏,「移動停損」Trailing Stop是常被使用的停損工具,在我的舊文章中的「商業用 「外匯自動交易程式」的基本架構 (程式設計者或專業人士必讀)」有提到,一般專業的自動交易程式都會包含「 移動停利/移動停損區塊」。以下我舉兩個片段的程式給各位讀者參考,第一個程式就是典型的Trailing Stop程式,原作者為網路知名的程式教育者Coder's Guru,如下所示。

extern int Tral_Stop=10; // Trailing distance

int start()
{
string Symb=Symbol(); // Symbol
//------------------------------------------------------------------------------- 2 --
for(int i=1; i<=OrdersTotal(); i++) // Cycle searching in orders
{
if (OrderSelect(i-1,SELECT_BY_POS)==true) // If the next is available
{ // Analysis of orders:
int Tip=OrderType(); // Order type
if(OrderSymbol()!=Symb||Tip>1)continue; // The order is not "ours"
double SL=OrderStopLoss(); // SL of the selected order
//---------------------------------------------------------------------- 3 --
while(true) // Modification cycle
{
double TS=Tral_Stop; // Initial value
int Min_Dist=MarketInfo(Symb,MODE_STOPLEVEL); //Min. distance
if (TS < Min_Dist) // If less than allowed
TS=Min_Dist; // New value of TS
//------------------------------------------------------------------- 4 --
bool Modify=false; // Not to be modified
switch(Tip) // By order type
{
case 0 : // Order Buy
if (NormalizeDouble(SL,Digits)< // If it is lower than we want
NormalizeDouble(Bid-TS*Point,Digits))
{
SL=Bid-TS*Point; // then modify it
string Text="Buy "; // Text for Buy
Modify=true; // To be modified
}
break; // Exit 'switch'
case 1 : // Order Sell
if (NormalizeDouble(SL,Digits)> // If it is higher than we want
NormalizeDouble(Ask+TS*Point,Digits)
|| NormalizeDouble(SL,Digits)==0) //or equal to zero
{
SL=Ask+TS*Point; // then modify it
Text="Sell "; // Text for Sell
Modify=true; // To be modified
}
} // End of 'switch'

if (Modify==false) // If it is not modified
break; // Exit 'while'
//------------------------------------------------------------------- 5 --
double TP=OrderTakeProfit(); // TP of the selected order
double Price =OrderOpenPrice(); // Price of the selected order
int Ticket=OrderTicket(); // Ticket of the selected order
Alert ("Modification ",Text,Ticket,". Awaiting response..");
bool Ans=OrderModify(Ticket,Price,SL,TP,0);//Modify it!
//------------------------------------------------------------------- 6 --
if (Ans==true) // Got ticket
{
Alert ("Order ",Text,Ticket," is modified:)");
break; // From modification cycle.
}
//------------------------------------------------------------------- 7 --
int Error=GetLastError(); // Failed
switch(Error) // Overcomable errors
{
case 130:
Alert("Wrong stops. Retrying.");
RefreshRates(); // Update data
continue; // At the next iteration
case 136:
Alert("No prices. Waiting for a new tick..");
while(RefreshRates()==false) // To the new tick
Sleep(1); // Cycle delay
continue; // At the next iteration
case 146:
Alert("Trading subsystem is busy. Retrying ");
Sleep(500); // Simple solution
RefreshRates(); // Update data
continue; // At the next iteration
// Critical errors
case 2 :
Alert("Common error.");
break; // Exit 'switch'
case 5 :
Alert("Old version of the client terminal.");
break; // Exit 'switch'
case 64:
Alert("Account is blocked.");
break; // Exit 'switch'
case 133:
Alert("Trading is prohibited");
break; // Exit 'switch'
default:
Alert("Occurred error ",Error); //Other errors
}
break; // From modification cycle
} // End of modification cycle
//---------------------------------------------------------------------- 8 --
} // End of order analysis
} // End of order search
//------------------------------------------------------------------------------- 9 --
return; // Exit start()
}



而以下的第二部分的程式是用來保護利潤的一個建議程式碼。

extern double ProfitToProtect = 200;
extern double ProtectStarter = 150;
extern double LossToProtect = 100;
extern bool ProtectProfit= true;
extern double Slippage = 3;
extern int MagicNumber=20110621;

bool ProtectLoss= false;

int start()
{
//----
if(ProtectProfit)
ProfitProtect(ProfitToProtect);

if(ProtectLoss)
LossProtect(LossToProtect);
//----
return(0);
}

//+------------------------------------------------------------------+
void ProfitProtect(double profit)
{
int total = OrdersTotal();
double MyCurrentProfit=0;
for (int cnt = 0 ; cnt < total ; cnt++)
{
OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES);
if (OrderMagicNumber() == MagicNumber)
MyCurrentProfit += OrderProfit();
}

if(MyCurrentProfit>=ProtectStarter) //start protection at this level!
ProtectLoss=true;

if(MyCurrentProfit>=profit)
CloseAll();
}

void LossProtect(double profit)
{
int total = OrdersTotal();
double MyCurrentProfit=0;
for (int cnt = 0 ; cnt < total ; cnt++)
{
OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES);
if (OrderMagicNumber() == MagicNumber)
MyCurrentProfit += OrderProfit();
}

if(MyCurrentProfit<=profit)
CloseAll();
}

void CloseAll()
{
int total = OrdersTotal();
for (int cnt = 0 ; cnt < total ; cnt++)
{
OrderSelect(0,SELECT_BY_POS,MODE_TRADES);
if (OrderMagicNumber() == MagicNumber)
if(OrderType()==OP_BUY)
OrderClose(OrderTicket(),OrderLots(),Bid,Slippage, Violet);

if(OrderType()==OP_SELL)
OrderClose(OrderTicket(),OrderLots(),Ask,Slippage, Violet);
}
}

以上的程式碼是只是參考用的程式碼,程式設計者可以利用相關的觀念再加以變更或設計自己所喜好的模式,一般有使用「移動停損/移動停利 Trailing Stops」區塊的程式大底上都是大同小異。

arrow
arrow
    全站熱搜

    David 發表在 痞客邦 留言(0) 人氣()