Costruzione di un Trading System basato su pattern
Forums › ProRealTime forum Italiano › Supporto ProOrder › Costruzione di un Trading System basato su pattern
- This topic has 15 replies, 2 voices, and was last updated 3 years ago by othello.
-
-
01/02/2021 at 9:34 PM #156020
Vorrei aprire una discussione su come scrivere il codice di una strategia basata su pattern e che sia generalizzabile. Mi piacerebbe avere il contributo di molti, come Roberto e Nicolas (per esempio), a beneficio di tutti i neofiti e coloro che vogliono imparare la programmazione con il linguaggio ProRealTime.
Vorrei che si capisse come codificare il pattern vero e proprio (una volta stabilito), il trigger, ovvero la o le condizioni che devono essere rispettate per entrare a mercato, la codifica di uno o più filtri, la modalità con cui passare l’ordine di entrata (stop o limit) e la codifica dell’ordine di uscita (in stop loss o in profit). Il sistema, inoltre, deve sapere cosa fare se, nel corso di una trade, si verifica l’occorrenza di un altro pattern di segno opposto (ignorarlo oppure seguirlo).
Ho provato a cercare, sia in questo che nel forum in lingua inglese, ma non mi sembra che una discussione del genere sia mai stata aperta. Se mi fosse sfuggita vi pregherei di sottopormene il link.
Se c’è l’accordo potrei cominciare io stesso con un pattern al quale penso già da un po’ (che non mi sembra di aver visto in letteratura) che potrebbe costituire il primo esempio.
Ripeto, penso possa essere utile per molti, soprattutto per coloro che si avvicinano al linguaggio per la prima volta oppure che, pur conoscendolo, non hanno ancora ben capito determinati meccanismi.
Fatemi sapere.
Un buon 2021 a tutti.
01/02/2021 at 11:38 PM #156031Dimmi tu un pattern (ed il suo inverso) su cui basare la strategia.
01/03/2021 at 12:02 PM #156060Grazie, Roberto, per la tua disponibilità.
Allora, il pattern sul quale sto ragionando da un po’ di tempo è il seguente. E’ un pattern a due barre basato su una prima partenza in una direzione, che poi si rivela falsa in quanto il mercato va nella direzione inversa. Vediamolo nelle due versioni.
Versione Short
La versione short, che ho denominato IFU (Inside Fake Up), è così formata. La prima candela è una barra inside e la seconda è una barra il cui massimo è superiore al massimo della inside e la cui chiusura è inferiore al minimo della barra inside. Questo è il setup. Il trigger, ovvero il segnale di vendita, è dato dalla rottura del minimo della seconda barra.
Questo potrebbe essere il codice che individua il pattern.
12345// IFU:Inside Fake UpInsideBar=Low[1]>Low[2] and High[1]<High[2]SecondBarDown=High>High[1] and Close<Low[1]Versione Long
La versione long, che ho denominato IFD (Inside Fake Down), è così formata. La prima candela è una barra inside e la seconda è una barra il cui minimo è inferiore al minimo della barra inside e la cui chiusura è superiore al massimo della barra inside. Questo è il setup. Il trigger, ovvero il segnale di acquisto, è dato dalla rottura del massimo della seconda barra.
E questo potrebbe essere il codice che va a cercare questo pattern.
12345// IFD:Inside Fake DownInsideBar=Low[1]>Low[2] and High[1]<High[2]SecondBarUp=Low<Low[1] and Close>High[1]Un grafico, che si riferisce alla giornata del 21/12/2020 del Dax con time frame a 3 minuti, potrebbe aiutare.
In genere, quando studio un nuovo pattern, la prima cosa che faccio è quella di scrivermi l’indicatore che lo individua.
In questo caso ho scritto il seguente codice.
123456789101112131415161718192021// IFU:Inside Fake Up; IFD:Inside Fake DownInsideBar=Low[1]>Low[2] and High[1]<High[2]SecondBarDown=High>High[1] and Close<Low[1]SecondBarUp=Low<Low[1] and Close>High[1]atr=AverageTrueRange[14](close)//IFUif InsideBar and SecondBarDown thendrawarrowdown (barindex, High+0.5*atr) coloured(255,0,0) //rossoendif//IFDif InsideBar and SecondBarUp thendrawarrowup (barindex, Low-0.5*atr) coloured(0,255,0) //rossoendifreturnE qui pongo una prima domanda. E’, tale codice, corretto e coerente al pattern descritto? Oppure manca qualcosa o vi è qualcosa di errato? Inoltre, poteva essere scritto in modo più efficiente?
01/03/2021 at 6:58 PM #156116Le regole di entrata sono state definite. Il rischio, per ogni operazione, è pari al range della seconda candela più due punti. L’uscita in profit, invece, deve essere ottimizzata in backtest. Sarà una variabile, che indicheremo con perc, pari ad una percentuale del rischio. L’ottimizzazione di perc potrebbe andare da 0,3 a 3 con step di 0,1.
Sono sufficienti queste informazioni per scrivere il codice del sistema?
01/04/2021 at 3:55 PM #156276Allora provo io.
1234567891011121314151617181920212223242526Defparam CumulateOrders = False // Posizioni cumulate disattivatepercProfitto=0.6percRischio=7InsideBar=Low[1]>Low[2] and High[1]<High[2]SecondBarDown=High>High[1] and Close<Low[1]SecondBarUp=Low<Low[1] and Close>High[1]if STRATEGYPROFIT<> STRATEGYPROFIT[1] thenSetup=0Endifif InsideBar and SecondBarDown thenEntryShort=Low-1*pipsizeRischio=Range*percRischio+2*pipsizeProfitto=percProfitto*RischioSetup=1endifif Setup and not(OnMarket) thenSELLSHORT at EntryShort stopendifSET STOP PLOSS RischioSET TARGET PPROFIT ProfittoQuesto è il codice relativo alla sola versione short del pattern. Le righe di codice 10,11 e 12 si sono rese necessarie per evitare una seconda entrata non segnalata dalla presenza del pattern ma dal fatto che la variabile setup non viene portata a zero se l’entrata e l’uscita avvengono nella stessa barra.
Le variabili da ottimizzare sono percProfitto e percRischio. Con i valori indicati nel codice alle righe 3 e 4 si ottiene, applicato al Germany 30 su un grafico a 3 minuti, una percentuale di profitto del 72% circa con 10 punti circa di guadagno medio per trade. Naturalmente questo è solo un esempio di valore didattico.
01/04/2021 at 4:15 PM #156286Se inseriamo anche la parte di codice che genera le operazioni in acquisto, quando occorre il pattern nella sua versione rialzista,
12345678910111213141516171819202122232425262728293031323334353637Defparam CumulateOrders = False // Posizioni cumulate disattivatepercProfitto=0.6percRischio=7InsideBar=Low[1]>Low[2] and High[1]<High[2]SecondBarDown=High>High[1] and Close<Low[1]SecondBarUp=Low<Low[1] and Close>High[1]if STRATEGYPROFIT<> STRATEGYPROFIT[1] thenSetup=0Endifif InsideBar and SecondBarDown thenEntryShort=Low-1*pipsizeRischio=Range*percRischio+2*pipsizeProfitto=percProfitto*RischioSetup=-1endifif InsideBar and SecondBarUp thenEntryLong=High+1*pipsizeRischio=Range*percRischio+2*pipsizeProfitto=percProfitto*RischioSetup=1endifif Setup=-1 and not(OnMarket) thenSELLSHORT at EntryShort stopendifif Setup=1 and not(OnMarket) thenBuy at EntryLong stopendifSET STOP PLOSS RischioSET TARGET PPROFIT Profittoapplicato sullo stesso strumento, stesso time frame e stesso periodo di backtest, si ottiene il risultato mostrato in figura.
01/04/2021 at 5:01 PM #156304C’è poi la questione dei filtri, molto spesso basati sul tempo. Si potrebbe, in questo caso, accogliere solo quei pattern che si verificano nel corso della sessione di borsa aperta che, nel caso del Dax, significa dalle 9:00 alle 17:30. Vediamo il codice.
123456789101112131415161718192021222324252627282930313233343536373839Defparam CumulateOrders = False // Posizioni cumulate disattivatepercProfitto=0.6percRischio=7SetupTime=time>=090000 and time<=173000InsideBar=Low[1]>Low[2] and High[1]<High[2]SecondBarDown=High>High[1] and Close<Low[1]SecondBarUp=Low<Low[1] and Close>High[1]if STRATEGYPROFIT<> STRATEGYPROFIT[1] thenSetup=0Endifif InsideBar and SecondBarDown and SetupTime thenEntryShort=Low-1*pipsizeRischio=Range*percRischio+2*pipsizeProfitto=percProfitto*RischioSetup=-1endifif InsideBar and SecondBarUp and SetupTime thenEntryLong=High+1*pipsizeRischio=Range*percRischio+2*pipsizeProfitto=percProfitto*RischioSetup=1endifif Setup=-1 and not(OnMarket) thenSELLSHORT at EntryShort stopendifif Setup=1 and not(OnMarket) thenBuy at EntryLong stopendifSET STOP PLOSS RischioSET TARGET PPROFIT ProfittoSembra interessante: il guadagno medio per trade è cresciuto in modo percentualmente importante.
Naturalmente, come per tutti i filtri, si osserverà una più o meno importante riduzione del numero delle operazioni e, quindi, una riduzione dell’attendibilità dei risultati statistici del backtest. In questo caso, come si può notare dalla figura, il numero delle trades si è ridotto a circa un terzo di quello precedente all’inserzione del filtro.
01/04/2021 at 7:03 PM #156332Provalo su un periodo più ampio, 100K o 200K barre, un mese è poco!
01/04/2021 at 11:38 PM #156364Si, domani lo provo su un periodo più ampio. Nel frattempo ti volevo chiedere: come si può generalizzare il codice affinché vada bene per qualunque CFD (coppie valutarie, materie prime, obbligazioni, azioni, ecc.). Il problema che ho è il seguente: siccome sono abituato a scrivere codici che vanno applicati al Dax, quando provo ad applicarli, ad esempio, alla coppia valutaria euro-dollaro ho dei problemi in quanto l’unità di contrattazione minima è diversa: 1 punto per il dax ed un pip per l’euro-dollaro.
Potresti farmi vedere come generalizzare il codice?
Ti ringrazio.
01/05/2021 at 1:55 AM #156367Dal momento che usi una percentuale non ci sono problemi, che sia EurUsd, Dax 1€ o Dax 25€, la percentuale è la stessa.
La differenza la fai tu quando decidi, secondo i soldi che vuoi dedicargli, su quale strumento operare.
Per il resto il tuo codice utilizza un pattern, nessun indicatore, per cui dovrebbe andare bene su tutti gli strumenti, magari in modo un po’ diverso tra loro.
01/05/2021 at 1:05 PM #15643901/05/2021 at 5:09 PM #15647101/05/2021 at 8:38 PM #156514Due errori, trovati! In realtà era uno solo, l’altro era semplicemente legato al prezzo di entrata che essendo di tipo stop, lo faceva in apertura quale primo prezzo disponibile. E quel prezzo non mi tornava.
Comunque, sperando che ci sia qualcuno interessato, scrivo qui di cosa si trattava. Potrebbe tornare utile a chi, come me e tanti altri qui dentro, cerca di capire e sviscerare il linguaggio.
Allora, riferendomi al codice pubblicato al post #156304, le righe 8,9 e 10 individuano le barre che costituiscono il pattern long e quello short. Le righe da 16 a 21 verificano la sussistenza delle condizioni di presenza del pattern short e intervallo orario operativo e, in caso affermativo, calcolano il prezzo di entrata, il rischio dove posizionare lo stoploss ed il target price. Viene inoltre posta a -1 la variabile Setup.
Le righe da 23 a 28 verificano la sussistenza delle condizioni di presenza del pattern long e intervallo orario operativo e, in caso affermativo, calcolano il prezzo di entrata, il rischio dove posizionare lo stoploss ed il target price. Viene inoltre posta a +1 la variabile Setup.
Ora, nel caso non si sia a mercato e sia pari a -1 la variabile Setup, le righe 30,31 e 32 dispongono l’ordine di vendita al prezzo di entrata prima calcolato in modalità stop. In modo analogo, le righe 34, 35 e 36 nel caso di disposizione di ordine di acquisto.
Ora, vediamo cosa succede.
Il 3/12/2020 alle 12:48 c’è un ingresso short a 13255,6. Valore corretto in quanto il prezzo di entrata è calcolato un punto sotto al minimo della seconda barra del pattern che, in questo caso, vale 13.256,8. Il profitto, calcolato come da riga 19 del codice, vale 26,40. Quindi, l’uscita in gain dovrebbe avvenire a 13.230,4. In effetti, come mostra la seconda figura, avviene a 13.209. Perché?
Perché dopo l’ingresso, si sono presentati altri due pattern short, vedi terza figura, che hanno modificato il valore del profitto.
Allora il codice deve essere corretto. E come? Evitando che, quando il sistema è già a mercato, si rientri nella routine che ricalcola profitto, prezzo di entrata, ecc.
1234567891011if InsideBar and SecondBarDown and SetupTime and Setup=0 thenEntryShort=Low-1*pipsizeRischio=Range*percRischio+2*pipsizeProfitto=percProfitto*RischioSetup=-1EndifIn questo modo il sistema entra in questa parte di codice solo se Setup=0.
01/05/2021 at 11:40 PM #15653601/05/2021 at 11:50 PM #156539 -
AuthorPosts
Find exclusive trading pro-tools on