Costruzione di un Trading System basato su pattern

Viewing 15 posts - 1 through 15 (of 16 total)
  • Author
    Posts
  • #156020 quote
    othello
    Participant
    Senior

    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.

    #156031 quote
    robertogozzi
    Moderator
    Master

    Dimmi tu un pattern (ed il suo inverso) su cui basare la strategia.

    #156060 quote
    othello
    Participant
    Senior

    Grazie, 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.

    // IFU:Inside Fake Up
    
    InsideBar=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.

    // IFD:Inside Fake Down
    
    InsideBar=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.

    // IFU:Inside Fake Up; IFD:Inside Fake Down
    
    InsideBar=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)
    
    //IFU
    if InsideBar and SecondBarDown then
    drawarrowdown (barindex, High+0.5*atr) coloured(255,0,0) //rosso
    endif
    
    //IFD
    if InsideBar and SecondBarUp then
    drawarrowup (barindex, Low-0.5*atr) coloured(0,255,0) //rosso
    endif
    
    return

    E 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?

    IFU_IFD.png IFU_IFD.png
    #156116 quote
    othello
    Participant
    Senior

    Le 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?

    #156276 quote
    othello
    Participant
    Senior

    Allora provo io.

    Defparam CumulateOrders = False // Posizioni cumulate disattivate
    
    percProfitto=0.6
    percRischio=7
    
    InsideBar=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] then
    Setup=0
    Endif
    
    if InsideBar and SecondBarDown then
    EntryShort=Low-1*pipsize
    Rischio=Range*percRischio+2*pipsize
    Profitto=percProfitto*Rischio
    Setup=1
    endif
    
    if Setup and not(OnMarket) then
    SELLSHORT at EntryShort stop
    endif
    
    SET STOP PLOSS Rischio
    SET TARGET PPROFIT Profitto
    
    

    Questo è 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.

    fig1.png fig1.png
    #156286 quote
    othello
    Participant
    Senior

    Se inseriamo anche la parte di codice che genera le operazioni in acquisto, quando occorre il pattern nella sua versione rialzista,

    Defparam CumulateOrders = False // Posizioni cumulate disattivate
    
    percProfitto=0.6
    percRischio=7
    
    InsideBar=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] then
    Setup=0
    Endif
    
    if InsideBar and SecondBarDown then
    EntryShort=Low-1*pipsize
    Rischio=Range*percRischio+2*pipsize
    Profitto=percProfitto*Rischio
    Setup=-1
    endif
    
    if InsideBar and SecondBarUp then
    EntryLong=High+1*pipsize
    Rischio=Range*percRischio+2*pipsize
    Profitto=percProfitto*Rischio
    Setup=1
    endif
    
    if Setup=-1 and not(OnMarket) then
    SELLSHORT at EntryShort stop
    endif
    
    if Setup=1 and not(OnMarket) then
    Buy at EntryLong stop
    endif
    
    SET STOP PLOSS Rischio
    SET TARGET PPROFIT Profitto

    applicato sullo stesso strumento, stesso time frame e stesso periodo di backtest, si ottiene il risultato mostrato in figura.

    fig2.png fig2.png
    #156304 quote
    othello
    Participant
    Senior

    C’è 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.

    Defparam CumulateOrders = False // Posizioni cumulate disattivate
    
    percProfitto=0.6
    percRischio=7
    
    SetupTime=time>=090000 and time<=173000
    
    InsideBar=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] then
    Setup=0
    Endif
    
    if InsideBar and SecondBarDown and SetupTime then
    EntryShort=Low-1*pipsize
    Rischio=Range*percRischio+2*pipsize
    Profitto=percProfitto*Rischio
    Setup=-1
    endif
    
    if InsideBar and SecondBarUp and SetupTime then
    EntryLong=High+1*pipsize
    Rischio=Range*percRischio+2*pipsize
    Profitto=percProfitto*Rischio
    Setup=1
    endif
    
    if Setup=-1 and not(OnMarket) then
    SELLSHORT at EntryShort stop
    endif
    
    if Setup=1 and not(OnMarket) then
    Buy at EntryLong stop
    endif
    
    SET STOP PLOSS Rischio
    SET TARGET PPROFIT Profitto

    Sembra 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.

    fig3.png fig3.png
    #156332 quote
    robertogozzi
    Moderator
    Master

    Provalo su un periodo più ampio, 100K o 200K barre, un mese è poco!

    #156364 quote
    othello
    Participant
    Senior

    Si, 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.

    #156367 quote
    robertogozzi
    Moderator
    Master

    Dal 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.

    #156439 quote
    othello
    Participant
    Senior

    Ok. Allora, oltre alla prova che mi hai suggerito di fare su una base storica più ampia (100 k o 200 k), lo provo anche su Eur-Usd, vediamo se funziona e come va.

    Grazie.

    #156471 quote
    othello
    Participant
    Senior

    Non ho ancora pubblicato i risultati perché ho trovato un errore che non riesco ad individuare e che mi sta facendo perdere tempo. Se non lo trovo chiederò aiuto, sperando nella pazienza e nella disponibilità di qualcuno.

    #156514 quote
    othello
    Participant
    Senior

    Due 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.

     

    if InsideBar and SecondBarDown and SetupTime and Setup=0 then
    
    EntryShort=Low-1*pipsize
    
    Rischio=Range*percRischio+2*pipsize
    
    Profitto=percProfitto*Rischio
    
    Setup=-1
    
    Endif

     

    In questo modo il sistema entra in questa parte di codice solo se Setup=0.

    IFU_IFD_1.png IFU_IFD_1.png IFU_IFD_2.png IFU_IFD_2.png IFU_IFD_3.png IFU_IFD_3.png
    #156536 quote
    othello
    Participant
    Senior

    L’ottimizzazione, su 200 k, con time frame a 7 minuti, produce i risultati mostrati in figura.

    IFU_IFD_4.png IFU_IFD_4.png IFU_IFD_5.png IFU_IFD_5.png
    #156539 quote
    othello
    Participant
    Senior

    L’ottimizzazione, su 50 k, sempre con time frame a 7 minuti, produce i risultati mostrati in figura. Sembrano abbastanza stabili.

    IFU_IFD_6.png IFU_IFD_6.png
Viewing 15 posts - 1 through 15 (of 16 total)
  • You must be logged in to reply to this topic.

Costruzione di un Trading System basato su pattern


ProOrder: Trading Automatico & Backtesting

New Reply
Author
author-avatar
othello @othello Participant
Summary

This topic contains 15 replies,
has 2 voices, and was last updated by othello
5 years, 1 month ago.

Topic Details
Forum: ProOrder: Trading Automatico & Backtesting
Language: Italian
Started: 01/02/2021
Status: Active
Attachments: 12 files
Logo Logo
Loading...