Ciao Roberto, ho provato ad aggiungere un codice martingala trovato a pag. 68 del manuale Probacktest im un Ts di prova, ma non mi funziona. Puoi controllare, oppure hai qualche codice migliore dato che questo è abbastanza vecchio?
Questo nel manuale:
//***********Codice da inserire all'inizio del sistema di trading**********//
ONCE OrderSize = 1
ONCE ExitIndex = -2
REM Initial position size of 1.
//*********************//
//***********Codice da inserire subito dopo la chiusura della posizione**********//
ExitIndex = BarIndex
//***********Codice da inserire alla fine del sistema di trading**********//
IF Barindex = ExitIndex + 1 THEN
ExitIndex = 0
IF PositionPerf(1) < 0 THEN
OrderSize = OrderSize * 2
REM Se l'ultimo trade é perdente, allora raddoppiamo la grandezza della posizione
ELSIF PositionPerf(1) > 0 THEN
OrderSize = 1
REM Se l'ultimo trade é vincente, allora ritorniamo ad una posizione di grandezza 1
ENDIF
ENDIF
Lo ho provato ad inserire in questo TS di prova funzionante (provato sul Dax 15 minuti):
defParam cumulateOrders = false //(test DAX 15m)
once orderSize = 1
//--------------
avg50 = average[50,0](close)
if close crosses over avg50 then
buy orderSize contract at market
endif
if longOnMarket and close < (avg50 - 50*pointSize) then
sell orderSize contract at market
endif
//-------------------------------------
set target pProfit 100
Ma unendo i due codici non funzionano (forse lo ho uniti male?)
defParam cumulateOrders = false //(test DAX 15m)
once orderSize = 1
once exitIndex = -2
//--------------
avg50 = average[50,0](close)
if close crosses over avg50 then
buy orderSize contract at market
endif
if longOnMarket and close < (avg50 - 50*pointSize) then
sell orderSize contract at market
exitIndex = barIndex
endif
//-------------------------------------
set target pProfit 100
//--------------------------------------------
if barIndex = exitIndex + 1 then
exitIndex = 0
if positionPerf(1) < 0 then
orderSize = orderSize * 2
elsIf positionPerf(1) > 0 then
orderSize = 1
endif
endif
Nel codice del libro devi usare:
IF StrategyProfit < StrategyProfit[1] THEN
OrderSize = OrderSize * 2
ELSE
OrderSize = 1
ENDIF
altrimenti raddoppia ad ogni barra in cui la strategia è in perdita!
Ho provato, ma non funziona ugualmente. Il ts entra con tanti contratti lo stesso.
Si, c’era qualche aggiustamento da fare, STRATEGYPROFIT invece di POSITIONPERF, poi ho tolto EXITINDEX ed ho spostato il codice all’inizio subordinandolo a Not OnMarket.
Ho anche aggiunto TP e SL per fare le prove, altrimenti non riuscivo a capire bene.
defParam cumulateOrders = false //(test DAX 15m)
once orderSize = 1
if not OnMarket then
if StrategyProfit < StrategyProfit[1] then
orderSize = orderSize * 2
else
orderSize = 1
endif
endif
//--------------
avg50 = average[50,0](close)
if close crosses over avg50 then
buy orderSize contract at market
endif
if longOnMarket and close < (avg50 - 50*pointSize) then
sell orderSize contract at market
endif
//-------------------------------------
set target pProfit 500
set stop pLoss 200
//--------------------------------------------
graph ordersize
Ciao Roberto, ho provato il tuo codice, ma c’è ancora qualcosa che non va. Non si raddoppia la posizione in caso di perdita (come dovrebbe fare il Martingala), ma il TS usa sempre un contratto. (test Dax 15m)
Fammi un esempio dicosa dovrebbe fare.
- Dovrebbe raddoppiare la posizione in caso di perdita soltanto una volta.
Esempio: se si entra con 1 contratto e si guadagna si continua con 1 contratto. Se capita un operazione in perdita, soltanto l’operazione successiva viene fatta con 2 contratti (per provare a recuperare la perdita). Se ci dovesse essere una seconda perdita consecutiva si entra comunque sempre con 1 contratto. In pratica si raddoppia la posizione soltanto una volta dopo che ad una operazione positiva ne segue una negativa (per evitare di bruciare tutto il capitale in caso di una serie di operazioni perdenti consecutive!)
- In ogni caso il codice che, nel manuale, mi piacerebbe utilizzare (dato che NON sono un sostenitore della Martingala) è il codice a pag. 72 chiamato: l’inverso d’Alembert (se riesci a scrivere il primo questo è una variazione soltanto). In questo caso bisogna fissare l’unità minima di incremento-decremento (diciamo 1), l’unità minima per non bloccare il TS (diciamo sempre 1) e l’ammontare massimo dei contratti (diciamo X) per non aumentare comunque troppo l’esposizione monetaria in caso di una sequenza positiva di trades (sebbene sia un caso favorevole questa volta). Ecco cosa riporta il manuale:
L’inverso d’Alembert
Diminuiamo la grandezza della posizione
in caso di perdita o aumentiamo la grandezza della posizione in caso di guadagno.
Questa tecnica é dunque pertinente quando si ritiene che una perdita passata aumenti la probabilità di una
perdita futura e un guadagno passato aumenti la probabilità di un futuro guadagno.
Questo codice puo’ essere integrato con le vostre condizioni di entrata e di uscita.
//***********Codice da inserire all’inizio di un sistema di trading**********//
ONCE OrderSize = 1
ONCE ExitIndex = -2
// Cominciamo con una posizione di 1
//*********************//
//***********Codice da inserire subito dopo la chiusura di una posizione**********//
ExitIndex = BarIndex
//***********Codice da inserire alla fine del sistema di trading**********//
IF Barindex = ExitIndex + 1 THEN
ExitIndex = 0
IF PositionPerf(1) < 0 THEN
OrderSize = MAX(OrderSize -1, 1)
ELSIF PositionPerf(1) >= 0 THEN
OrderSize = OrderSize + 1
ENDIF
ENDIF
//*********************//
REM La grandezza della posizione deve essere determinata dalla variabile OrderSize
nell’intero codice.
Ho provato anche questo codice (cambiando solo alcuni nomi), funziona ma non fa nulla. Il risultato è identico allo stesso TS SENZA codice “Inverso d’Alembert”. Strano che nel manuale ci siano codici non funzionanti. Penso che debbano essere completamente riscritti.
//TEST TS codice "Inverso d'Alembert" (manuale proBackTest pag. 72)
defParam cumulateOrders = false //(test DAX 15m)
once positionSize = 1
once closeTradeIndex = -2
//--------------
avg50 = average[50,0](close)
if close crosses over avg50 then
buy positionSize contract at market
endif
if longOnMarket and close < (avg50 - 50*pointSize) then
sell positionSize contract at market
closeTradeIndex = barIndex
endif
//-------------------------------------
set target pProfit 100
//-----------------------------------------
if barIndex = closeTradeIndex +1 then
closeTradeIndex = 0
if positionPerf(1) < 0 then
positionSize = max(positionSize-1,1)
elsIf positionPerf(1) > 0 then
positionSize = positionSize +1
endif
endif
//------------------------------------------
Io guardai pag. 68, ho visto che anche a pag. 71 c’è il problema di POSITIONPERF invece di STRATEGYPROFIT.
Qusto è il mio precedente codice aggiornato con la regola di raddoppiare alla sola PRIMA perdita DOPO un profitto:
defParam cumulateOrders = false //(test DAX 15m)
once orderSize = 1
once raddoppio = 0
if not OnMarket then
if StrategyProfit < StrategyProfit[1] then
IF Raddoppio = 1 THEN
orderSize = orderSize * 2
Raddoppio = 0
ENDIF
else
orderSize = 1
IF StrategyProfit > StrategyProfit[1] then
Raddoppio = 1
ENDIF
endif
endif
//--------------
avg50 = average[50,0](close)
if close crosses over avg50 then
buy orderSize contract at market
endif
if longOnMarket and close < (avg50 - 50*pointSize) then
sell orderSize contract at market
endif
//-------------------------------------
set target pProfit 500
set stop pLoss 200
//--------------------------------------------
graph ordersize coloured(255,0,0,255)
graph Raddoppio coloured(0,0,255,255)
graph StrategyProfit < StrategyProfit[1] coloured(0,0,0,150)
Anche questo codice entra sempre con 1 contratto, anche dopo solo la prima perdita dopo un profitto. Se guardi la lista ordini (test sul dax 15m) vedi sempre QTA 1.
Il codice sopra, sul DAX, 15 minuti, 200K barre, entra anche con 2 (seppure raramente).
Puoi vedere la foto allegata.
Non so cosa dirti, a questo punto devi chiedere a IG o PRT.
Ricontrollo, ma anche il tuo grafico non è corretto (almeno secondo quello che vorrei che il codice facesse).
Mi spiego meglio: indico con + un operazione in guadagno (long o short) e con – un operazione in perdita (long o short).
Vorrei che dopo OGNI sequenza + – il TS entri con 2 contratti soltanto l’operazione seguente.
Quindi se abbiamo + (1 contratto ) e poi – (1 contratto), la terza operazione deve essere fatta con 2 contratti.
Se poi ne segue una con +, si attende un altra op con – prima di utilizzare nuovamente 2 contratti
Se invece segue una o più op con – si deve attendere una op con + , poi una con – e poi la seguente nuovamente deve essere fatta con 2 contratti.
Siccome è molto frequente la sequenza + – , le operazioni non possono essere rare.
Non sono un grande programmatore, ma questo codice potrebbe avvicinarsi a quello che stai cercando?
ONCE LotSize = 1 //starting number of lots/contracts
ONCE MinLots = 1 //minimum lot size required by the broker
ONCE MaxLots = 2 //999 max lots allowed (to be also set in AutoTradung)
ONCE Rise = 1 //numebe of lots to increment
ONCE Fall = 1 //number of lots to decrement
IF StrategyProfit > StrategyProfit[1] THEN
LotSize = LotSize + Rise
ELSIF StrategyProfit < StrategyProfit[1] THEN
LotSize = LotSize //– Fall
ENDIF
LotSize = min(MaxLots,max(MinLots,LotSize))) //check both Maximum and Minimum
IF MyLongConditions THEN
BUY LotSize CONTRACTS AT MARKET
ENDIF
IF MyShortConditions THEN
SELLSHORT LotSize CONTRACTS AT MARKET
ENDIF
Dimmi sul 15 minuti DAX quale operazione è errata, così posso controllare meglio (con l’ultimo codice che ho postato).
Aspetta, ho visto un possibile errore, ti farò sapere.