Ho un grafico intra-day e sto cercando di capire come calcolare i livelli di supporto e resistenza , qualcuno conosce un algoritmo per farlo o un buon punto di partenza?Support Resistance Algorithm - Analisi tecnica
risposta
Sì, un algoritmo molto semplice è quello di scegliere un intervallo di tempo, ad esempio 100 bar, quindi cercare punti di svolta locali o Maxima e Minima. I massimi e i minimi possono essere calcolati da un prezzo di chiusura arrotondato utilizzando la derivata 1a e 2a (dy/dx e d^2y/dx). Dove dy/dx = zero e d^y/dx è positivo, hai un minimo, quando dy/dx = zero e d^2y/dx è negativo, hai un massimo.
In termini pratici, questo potrebbe essere calcolato iterando sulle serie di prezzi di chiusura uniformi e osservando tre punti adiacenti. Se i punti sono inferiori/superiori/inferiori in termini relativi, allora hai un massimo, altrimenti più alto/basso/più alto hai un minimo. Potresti voler mettere a punto questo metodo di rilevamento per guardare più punti (ad esempio 5, 7) e attivare solo se i punti di bordo sono a una certa percentuale di distanza dal punto centrale. questo è simile all'algoritmo usato dall'indicatore ZigZag.
Una volta raggiunti i massimi e i minimi locali, è necessario cercare gruppi di punti di svolta a una certa distanza l'uno dall'altro nella direzione Y. questo è semplice Prendi la lista dei N punti di svolta e calcola la distanza Y tra essa e ciascuno degli altri punti di svolta scoperti. Se la distanza è inferiore a una costante fissa, hai trovato due punti di svolta "vicini", indicando un possibile supporto/resistenza.
Puoi quindi classificare le tue linee S/R, quindi due punti di svolta a $ 20 sono meno importanti di tre punti di svolta a $ 20 per esempio.
Un'estensione a questo sarebbe il calcolo delle linee di tendenza. Con l'elenco dei punti di svolta scoperti ora prendi ogni punto a turno e seleziona altri due punti, cercando di adattare un'equazione a linea retta. Se l'equazione è risolvibile entro un certo margine di errore, si ha una linea di tendenza in pendenza. In caso contrario, scartare e passare alla successiva tripletta di punti.
Il motivo per cui è necessario tre alla volta per calcolare le linee di tendenza è che è possibile utilizzare due punti nell'equazione della linea retta. Un altro modo per calcolare le linee di tendenza sarebbe calcolare l'equazione in linea retta di tutte le coppie di punti di svolta, quindi vedere se un terzo punto (o più di uno) si trova sulla stessa linea retta all'interno di un margine di errore. Se 1 o più punti si trovano su questa linea, bingo hai calcolato una linea di tendenza di supporto/resistenza.
Spero che questo aiuti. Nessun esempio di codice mi dispiace, ti sto solo dando alcune idee su come potrebbe essere fatto.In sintesi:
ingressi al sistema
- periodo Lookback L (numero di barre)
- prezzi di chiusura di L bar
- Smoothing fattore (per lisciare prezzo di chiusura)
- margine di errore o Delta (distanza minima tra i punti di svolta per costituire una corrispondenza)
Uscite
- Elenco dei punti di svolta, chiamarli TPoints [] (x, y)
- Elenco di potenziali linee di tendenza, ciascuno con l'equazione linea (y = mx + c)
saluti,
Grazie Andrea per la vostra risposta dettagliata, vado a verificare che – Yaron
Ciao Andrew, ho verificato la tua idea, non riesco ancora a capire come calcolare i minimi e i massimi, perché non ho la formula di y (x = valore temporale, y = prezzo), e ne ho bisogno per ottenere 1a e 2a derivata es, puoi spiegare? Grazie mille. Yaron – Yaron
Quello che devi fare è eseguire la differenziazione numerica dei prezzi di chiusura livellati per determinare dy/dx: en.m.wikipedia.org/wiki/Numerical_differentiation. Quindi eseguire nuovamente la differenziazione per trovare d^2y/dx. Nota che ci sono altri modi più semplici per trovare i punti di svolta, controlla l'indicatore a zigzag: onlinetradingconcepts.com/TechnicalAnalysis/ZigZag.html –
Metto insieme un pacchetto che implementa linee di tendenza di supporto e resistenza come quello che stai chiedendo. Ecco alcuni esempi di alcuni esempi:
import numpy as np
import pandas.io.data as pd
from matplotlib.pyplot import *
gentrends('fb', window = 1.0/3.0)
Questo esempio solo tira i prezzi di chiusura corretti, ma se si dispone di dati intraday già caricati in voi può anche alimentare è dati grezzi come un array numpy e implementerà lo stesso algoritmo su quei dati come se lo si alimentasse con un simbolo ticker.
Non so se questo è esattamente quello che stavi cercando, ma spero che questo ti aiuti a iniziare. Il codice e qualche altra spiegazione possono essere trovati nella pagina GitHub dove l'ho ospitato: https://github.com/dysonance/Trendy
Grazie! Lo proverò – Yaron
Trova semplicemente i due valori più grandi e più piccoli e calcola le linee che passano da quei punti? – nurettin
Per questa funzione specifica, trova il massimo e il minimo globali dei dati, quindi trova il 2 ° massimo e il massimo __esterno__ del periodo di finestra in cui lo si alimenta. Quindi se gli dai una finestra di 30 periodi, troverà il massimo/minimo più alto che è di almeno 30 periodi lontano dal massimo/minimo globale. Per prima cosa guarda avanti, ma se non ci sono ancora 30 periodi rimasti nella serie, allora guarderà indietro. Qui gli fornisco una finestra di 1.0/3.0, che interpreta come un terzo della lunghezza dei dati. Ci sono altri metodi che offrono approcci più flessibili se sei interessato :) –
Sto usando un algoritmo molto meno complesso nel mio sistema di trading algoritmico.
I passaggi seguenti sono un lato dell'algoritmo e vengono utilizzati per il calcolo dei livelli di supporto. Si prega di leggere le note sotto l'algoritmo per capire come calcolare i livelli di resistenza.
Algoritmo timeseries
- rompere in segmenti di dimensione N (diciamo, N = 5)
- Identificare valori minimi di ogni segmento, si avrà una matrice di valori minimi di tutti i segmenti =: arrayOfMin
- Find minimo (: arrayOfMin) =: minValue
- Vedere se uno dei valori rimanenti rientrano nella gamma (X% di: minValue) (Say, X = 1.3%)
- Fai un array separato (: supportArr)
- aggiungere valori nel range & rimuovere questi valori da: arrayOfMin
- anche aggiungere: minValue dal passaggio 3
Calcolo supporto (o resistenza)
- Prendere una media di questa matrice = support_level
- Se il supporto viene testato molte volte, viene considerato valido.
- strength_of_support = supportArr.length
- level_type (SUPPORTO | RESISTENZA) = Ora, se il prezzo corrente è sotto il supporto quindi sostenere il ruolo cambia e diventa resistenza
Ripetere i passaggi 3-7 fino a quando : arrayOfMin è vuoto
- Avrete tutti i valori di supporto/resistenza con una forza. Ora attenua questi valori, se i livelli di supporto sono troppo vicini, quindi elimina uno di essi.
- Questi supporti/resistenza sono stati calcolati considerando la ricerca dei livelli di supporto. È necessario eseguire i passaggi da 2 a 9 considerando la ricerca dei livelli di resistenza. Si prega di consultare le note e l'implementazione.
Note:
- regolare i valori di N & X per ottenere risultati più accurati.
- Esempio, per titoli meno volatili o indici azionari usa (N = 10, X = 1,2%)
- Per stock volatile alti usare (N = 22, X = 1,5%)
- Per la resistenza, la procedura è esattamente opposta (utilizzare la funzione massima invece del minimo)
- Questo algoritmo è stato volutamente mantenuto semplice per evitare la complessità, può essere migliorato per ottenere risultati migliori.
Ecco la mia realizzazione:
public interface ISupportResistanceCalculator {
/**
* Identifies support/resistance levels.
*
* @param timeseries
* timeseries
* @param beginIndex
* starting point (inclusive)
* @param endIndex
* ending point (exclusive)
* @param segmentSize
* number of elements per internal segment
* @param rangePct
* range % (Example: 1.5%)
* @return A tuple with the list of support levels and a list of resistance
* levels
*/
Tuple<List<Level>, List<Level>> identify(List<Float> timeseries,
int beginIndex, int endIndex, int segmentSize, float rangePct);
}
principale classe calcolatrice
/**
*
*/
package com.perseus.analysis.calculator.technical.trend;
import static com.perseus.analysis.constant.LevelType.RESISTANCE;
import static com.perseus.analysis.constant.LevelType.SUPPORT;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import com.google.common.collect.Lists;
import com.perseus.analysis.calculator.mean.IMeanCalculator;
import com.perseus.analysis.calculator.timeseries.ITimeSeriesCalculator;
import com.perseus.analysis.constant.LevelType;
import com.perseus.analysis.model.Tuple;
import com.perseus.analysis.model.technical.Level;
import com.perseus.analysis.model.timeseries.ITimeseries;
import com.perseus.analysis.util.CollectionUtils;
/**
* A support and resistance calculator.
*
* @author PRITESH
*
*/
public class SupportResistanceCalculator implements
ISupportResistanceCalculator {
static interface LevelHelper {
Float aggregate(List<Float> data);
LevelType type(float level, float priceAsOfDate, final float rangePct);
boolean withinRange(Float node, float rangePct, Float val);
}
static class Support implements LevelHelper {
@Override
public Float aggregate(final List<Float> data) {
return Collections.min(data);
}
@Override
public LevelType type(final float level, final float priceAsOfDate,
final float rangePct) {
final float threshold = level * (1 - (rangePct/100));
return (priceAsOfDate < threshold) ? RESISTANCE : SUPPORT;
}
@Override
public boolean withinRange(final Float node, final float rangePct,
final Float val) {
final float threshold = node * (1 + (rangePct/100f));
if (val < threshold)
return true;
return false;
}
}
static class Resistance implements LevelHelper {
@Override
public Float aggregate(final List<Float> data) {
return Collections.max(data);
}
@Override
public LevelType type(final float level, final float priceAsOfDate,
final float rangePct) {
final float threshold = level * (1 + (rangePct/100));
return (priceAsOfDate > threshold) ? SUPPORT : RESISTANCE;
}
@Override
public boolean withinRange(final Float node, final float rangePct,
final Float val) {
final float threshold = node * (1 - (rangePct/100f));
if (val > threshold)
return true;
return false;
}
}
private static final int SMOOTHEN_COUNT = 2;
private static final LevelHelper SUPPORT_HELPER = new Support();
private static final LevelHelper RESISTANCE_HELPER = new Resistance();
private final ITimeSeriesCalculator tsCalc;
private final IMeanCalculator meanCalc;
public SupportResistanceCalculator(final ITimeSeriesCalculator tsCalc,
final IMeanCalculator meanCalc) {
super();
this.tsCalc = tsCalc;
this.meanCalc = meanCalc;
}
@Override
public Tuple<List<Level>, List<Level>> identify(
final List<Float> timeseries, final int beginIndex,
final int endIndex, final int segmentSize, final float rangePct) {
final List<Float> series = this.seriesToWorkWith(timeseries,
beginIndex, endIndex);
// Split the timeseries into chunks
final List<List<Float>> segments = this.splitList(series, segmentSize);
final Float priceAsOfDate = series.get(series.size() - 1);
final List<Level> levels = Lists.newArrayList();
this.identifyLevel(levels, segments, rangePct, priceAsOfDate,
SUPPORT_HELPER);
this.identifyLevel(levels, segments, rangePct, priceAsOfDate,
RESISTANCE_HELPER);
final List<Level> support = Lists.newArrayList();
final List<Level> resistance = Lists.newArrayList();
this.separateLevels(support, resistance, levels);
// Smoothen the levels
this.smoothen(support, resistance, rangePct);
return new Tuple<>(support, resistance);
}
private void identifyLevel(final List<Level> levels,
final List<List<Float>> segments, final float rangePct,
final float priceAsOfDate, final LevelHelper helper) {
final List<Float> aggregateVals = Lists.newArrayList();
// Find min/max of each segment
for (final List<Float> segment : segments) {
aggregateVals.add(helper.aggregate(segment));
}
while (!aggregateVals.isEmpty()) {
final List<Float> withinRange = new ArrayList<>();
final Set<Integer> withinRangeIdx = new TreeSet<>();
// Support/resistance level node
final Float node = helper.aggregate(aggregateVals);
// Find elements within range
for (int i = 0; i < aggregateVals.size(); ++i) {
final Float f = aggregateVals.get(i);
if (helper.withinRange(node, rangePct, f)) {
withinRangeIdx.add(i);
withinRange.add(f);
}
}
// Remove elements within range
CollectionUtils.remove(aggregateVals, withinRangeIdx);
// Take an average
final float level = this.meanCalc.mean(
withinRange.toArray(new Float[] {}), 0, withinRange.size());
final float strength = withinRange.size();
levels.add(new Level(helper.type(level, priceAsOfDate, rangePct),
level, strength));
}
}
private List<List<Float>> splitList(final List<Float> series,
final int segmentSize) {
final List<List<Float>> splitList = CollectionUtils
.convertToNewLists(CollectionUtils.splitList(series,
segmentSize));
if (splitList.size() > 1) {
// If last segment it too small
final int lastIdx = splitList.size() - 1;
final List<Float> last = splitList.get(lastIdx);
if (last.size() <= (segmentSize/1.5f)) {
// Remove last segment
splitList.remove(lastIdx);
// Move all elements from removed last segment to new last
// segment
splitList.get(lastIdx - 1).addAll(last);
}
}
return splitList;
}
private void separateLevels(final List<Level> support,
final List<Level> resistance, final List<Level> levels) {
for (final Level level : levels) {
if (level.getType() == SUPPORT) {
support.add(level);
} else {
resistance.add(level);
}
}
}
private void smoothen(final List<Level> support,
final List<Level> resistance, final float rangePct) {
for (int i = 0; i < SMOOTHEN_COUNT; ++i) {
this.smoothen(support, rangePct);
this.smoothen(resistance, rangePct);
}
}
/**
* Removes one of the adjacent levels which are close to each other.
*/
private void smoothen(final List<Level> levels, final float rangePct) {
if (levels.size() < 2)
return;
final List<Integer> removeIdx = Lists.newArrayList();
Collections.sort(levels);
for (int i = 0; i < (levels.size() - 1); i++) {
final Level currentLevel = levels.get(i);
final Level nextLevel = levels.get(i + 1);
final Float current = currentLevel.getLevel();
final Float next = nextLevel.getLevel();
final float difference = Math.abs(next - current);
final float threshold = (current * rangePct)/100;
if (difference < threshold) {
final int remove = currentLevel.getStrength() >= nextLevel
.getStrength() ? i : i + 1;
removeIdx.add(remove);
i++; // start with next pair
}
}
CollectionUtils.remove(levels, removeIdx);
}
private List<Float> seriesToWorkWith(final List<Float> timeseries,
final int beginIndex, final int endIndex) {
if ((beginIndex == 0) && (endIndex == timeseries.size()))
return timeseries;
return timeseries.subList(beginIndex, endIndex);
}
}
Ecco alcune classi di supporto:
public enum LevelType {
SUPPORT, RESISTANCE
}
public class Tuple<A, B> {
private final A a;
private final B b;
public Tuple(final A a, final B b) {
super();
this.a = a;
this.b = b;
}
public final A getA() {
return this.a;
}
public final B getB() {
return this.b;
}
@Override
public String toString() {
return "Tuple [a=" + this.a + ", b=" + this.b + "]";
};
}
public abstract class CollectionUtils {
/**
* Removes items from the list based on their indexes.
*
* @param list
* list
* @param indexes
* indexes this collection must be sorted in ascending order
*/
public static <T> void remove(final List<T> list,
final Collection<Integer> indexes) {
int i = 0;
for (final int idx : indexes) {
list.remove(idx - i++);
}
}
/**
* Splits the given list in segments of the specified size.
*
* @param list
* list
* @param segmentSize
* segment size
* @return segments
*/
public static <T> List<List<T>> splitList(final List<T> list,
final int segmentSize) {
int from = 0, to = 0;
final List<List<T>> result = new ArrayList<>();
while (from < list.size()) {
to = from + segmentSize;
if (to > list.size()) {
to = list.size();
}
result.add(list.subList(from, to));
from = to;
}
return result;
}
}
/**
* This class represents a support/resistance level.
*
* @author PRITESH
*
*/
public class Level implements Serializable {
private static final long serialVersionUID = -7561265699198045328L;
private final LevelType type;
private final float level, strength;
public Level(final LevelType type, final float level) {
this(type, level, 0f);
}
public Level(final LevelType type, final float level, final float strength) {
super();
this.type = type;
this.level = level;
this.strength = strength;
}
public final LevelType getType() {
return this.type;
}
public final float getLevel() {
return this.level;
}
public final float getStrength() {
return this.strength;
}
@Override
public String toString() {
return "Level [type=" + this.type + ", level=" + this.level
+ ", strength=" + this.strength + "]";
}
}
funziona bene? – experquisite
Sì, funziona sicuramente. Ma non è perfetto, una volta compreso l'algoritmo, devi modificarlo per ottenere risultati sempre più accurati. Ti dà quella flessibilità. Prima prova a capire i passaggi, quindi ti consiglio di provarlo con i dati di borsa. Si prega di controllare la sezione "Note" della risposta. –
ho letto brevemente il contributo di Jacob.Penso che potrebbe avere alcuni problemi con il codice qui sotto: # Ora il min se min1 - Finestra < 0: min2 = min (x [(min1 + finestra):]) altro: min2 = min (x [ 0: (min1 - finestra)])
# Now find the indices of the secondary extrema
max2 = np.where(x == max2)[0][0] # find the index of the 2nd max
min2 = np.where(x == min2)[0][0] # find the index of the 2nd min
l'algoritmo fa cercare di trovare valore min secondario finestra esterna proposta, ma poi la posizione corrispondente alla np.where (x == min2) [0] [0] potrebbe trovarsi all'interno della finestra a causa di possibili valori duplicati all'interno della finestra.
Ecco una funzione pitone per trovare support
/resistance
livelli
Questa funzione prende un allineamento NumPy di ultimo prezzo negoziato e restituisce una lista di livelli di supporto e resistenza rispettivamente. n è il numero delle voci da scansionare.
def supres(ltp, n):
"""
This function takes a numpy array of last traded price
and returns a list of support and resistance levels
respectively. n is the number of entries to be scanned.
"""
from scipy.signal import savgol_filter as smooth
# converting n to a nearest even number
if n % 2 != 0:
n += 1
n_ltp = ltp.shape[0]
# smoothening the curve
ltp_s = smooth(ltp, (n + 1), 3)
# taking a simple derivative
ltp_d = np.zeros(n_ltp)
ltp_d[1:] = np.subtract(ltp_s[1:], ltp_s[:-1])
resistance = []
support = []
for i in xrange(n_ltp - n):
arr_sl = ltp_d[i:(i + n)]
first = arr_sl[:(n/2)] # first half
last = arr_sl[(n/2):] # second half
r_1 = np.sum(first > 0)
r_2 = np.sum(last < 0)
s_1 = np.sum(first < 0)
s_2 = np.sum(last > 0)
# local maxima detection
if (r_1 == (n/2)) and (r_2 == (n/2)):
resistance.append(ltp[i + ((n/2) - 1)])
# local minima detection
if (s_1 == (n/2)) and (s_2 == (n/2)):
support.append(ltp[i + ((n/2) - 1)])
return support, resistance
E se volessi tracciare queste righe? Come troveresti le date corrispondenti? – cJc
Immagino che puoi provare ad abbinare i prezzi supporto/resistenza ai dati originali, che dovrebbero includere un campo data. Ho tracciato questo prima, ma non riesco a ricordare il progetto! –
- 1. Analisi tecnica - Arresto parabolico e indicatore inverso
- 2. Tecnica di analisi XML di Android
- 3. Solving String reduction Algorithm
- 4. Algorithm smbPitchShift (Pascal)
- 5. Tricky Encryption Algorithm Design
- 6. Word Jumble Algorithm
- 7. Map Clustering Algorithm
- 8. Prime Number Algorithm
- 9. Algorithm Problem Classification
- 10. Dijkstra's Algorithm Issue
- 11. QuickSelect Algorithm Understanding
- 12. Algorithm/Recursion tree challenge
- 13. oggetto Positioning Algorithm
- 14. Algorithm: unione segmenti sovrapposti
- 15. Color Logic Algorithm
- 16. Exposé Layout Algorithm
- 17. Genetic Algorithm Tournament Selection
- 18. g ++ standard support
- 19. Android - Hindi Conjuncts Support?
- 20. LinearLayout overlapping Support CoordinatorLayout
- 21. Design Support TabLayout
- 22. "$ .support is undefined"
- 23. CREATE ALGORITHM = DEFINER NON DEFINITO
- 24. Padding in MD5 Hash Algorithm
- 25. Greedy Algorithm Java/metodo firstFit
- 26. Hashing Algorithm, i suoi usi?
- 27. Alcune modifiche su Soundex Algorithm
- 28. Tecnica di codifica Jpeg
- 29. Come rendere javascript support shebang (#!)?
- 30. jQuery assertion support/programmazione difensiva?
Si consiglia inoltre di controllare questa domanda: http://stackoverflow.com/questions/14861023/resampling-minute-data – ticktock