Estoy en el proceso de crear un algoritmo de negociación de divisas y quería probar mi oportunidad de calcular la EMA (medias móviles exponenciales) Mis resultados parecen ser correctos (en comparación con los cálculos que hice a mano), así que creo que el siguiente método funciona, pero solo quería tener un par de ojos extra para asegurarme de que no me falta nada.
Tenga en cuenta que esto solo devuelve la EMA por el precio más reciente, no devuelve una matriz de EMA, ya que no es lo que necesito para mi aplicación.
I Estoy usando este enlace como referencia: Media móvil exponencial
class Indicators: def sma(self, data, window): """ Calculates Simple Moving Average http://fxtrade.oanda.com/learn/forex-indicators/simple-moving-average """ if len(data) < window: return None return sum(data[-window:]) / float(window) def ema(self, data, window, position=None, previous_ema=None): """ Calculates Exponential Moving Average http://fxtrade.oanda.com/learn/forex-indicators/exponential-moving-average """ if len(data) < window + 2: return None c = 2 / float(window + 1) if not previous_ema: return self.ema(data, window, window, self.sma(data[-window*2 + 1:-window + 1], window)) else: current_ema = (c * data[-position]) + ((1 - c) * previous_ema) if position > 0: return self.ema(data, window, position - 1, current_ema) return previous_ema # Sample close prices for GBP_USD currency pair on the 2 hour timeframe close_prices = [1.682555, 1.682545, 1.682535, 1.682655, 1.682455, 1.682685, 1.68205, 1.683245, 1.68405, 1.68401, 1.68506, 1.685825, 1.685955, 1.686595, 1.686325, 1.686375, 1.68701, 1.684995, 1.687245, 1.686135, 1.686205, 1.68724, 1.68753, 1.687775, 1.688245, 1.687745, 1.68699, 1.687285, 1.686325, 1.686295, 1.683945, 1.683035, 1.68401, 1.68327, 1.685185, 1.684755, 1.685265, 1.685325, 1.68625, 1.685645, 1.684355, 1.68387, 1.68413, 1.68416, 1.683425, 1.68481, 1.683245, 1.683645, 1.68325, 1.682745, 1.680385, 1.680655, 1.680875, 1.679995, 1.680445, 1.68064, 1.67937, 1.677735, 1.67769, 1.67777, 1.677525, 1.677435, 1.67766, 1.677835, 1.678005, 1.67823, 1.67902, 1.678605, 1.678425, 1.67876, 1.678555, 1.678505, 1.679085, 1.678755, 1.678125, 1.677495, 1.67677, 1.676205, 1.67716, 1.67741, 1.677135, 1.679295, 1.68054, 1.68143, 1.68115, 1.68111, 1.68055, 1.680495, 1.680565, 1.681375, 1.68244, 1.673395, 1.670885, 1.67156, 1.669525, 1.66906, 1.66903, 1.668935, 1.668805, 1.667895, 1.667905, 1.668485, 1.666345, 1.66832, 1.668005, 1.668615, 1.669305, 1.668415, 1.66891, 1.66843, 1.66855, 1.66834, 1.668725, 1.66952, 1.668075, 1.66859, 1.669, 1.669685, 1.668575, 1.66909, 1.66957, 1.669375, 1.671655, 1.67186, 1.67244, 1.6729, 1.672965, 1.673405, 1.67284, 1.67256, 1.67216, 1.67193, 1.673265, 1.67295, 1.672705, 1.67224, 1.67221, 1.67222, 1.67254, 1.670105, 1.66501, 1.663845, 1.66201, 1.661935, 1.661725, 1.66189, 1.661605, 1.661925, 1.66215, 1.66049, 1.660185, 1.66233, 1.66374, 1.66491, 1.665195, 1.663225, 1.66267, 1.65927, 1.659415, 1.65998, 1.6583, 1.656825, 1.65741, 1.659025, 1.658355, 1.659355, 1.65871, 1.65887, 1.658595, 1.65768, 1.657965, 1.657855, 1.657415, 1.658125, 1.65816, 1.659125, 1.658245, 1.65773, 1.658585, 1.65732, 1.657825, 1.65731, 1.65725, 1.65433, 1.654875, 1.65508, 1.656205, 1.656185, 1.6567, 1.658865, 1.658805, 1.65879, 1.6584, 1.65806, 1.658145, 1.65706, 1.656925, 1.65885, 1.65917, 1.659, 1.65794, 1.65797, 1.65711, 1.658675, 1.656915, 1.65474, 1.65455, 1.654135, 1.65467, 1.65473, 1.65543, 1.65465, 1.65721, 1.65717, 1.65927, 1.65895, 1.65724, 1.65812, 1.657435, 1.657395, 1.65755, 1.65975, 1.65983, 1.658975, 1.658855, 1.65814, 1.65838, 1.65797, 1.65785, 1.657795, 1.658915, 1.65888, 1.65888, 1.65869, 1.65851, 1.658195, 1.659985, 1.65933, 1.65842, 1.65836, 1.658435, 1.657605, 1.660225, 1.65991, 1.65908, 1.659065, 1.659605, 1.659555, 1.660535, 1.663025, 1.662295, 1.661525, 1.662735, 1.661335, 1.660895, 1.660905, 1.66093, 1.661425, 1.65934, 1.658235, 1.658305, 1.657035, 1.652785, 1.653185, 1.65176, 1.650105, 1.648505, 1.64713, 1.646975, 1.646815, 1.646575, 1.645355, 1.646425, 1.646365, 1.648295, 1.646245, 1.646305, 1.645075, 1.644875, 1.646035, 1.64602, 1.646025, 1.645615, 1.646135, 1.645585, 1.645695, 1.646195, 1.642865, 1.64237, 1.634805, 1.634575, 1.634475, 1.631665, 1.629265, 1.631115, 1.63094, 1.631775, 1.632175, 1.631775, 1.629345, 1.632785, 1.631155, 1.631765, 1.632865, 1.6327, 1.618735, 1.621365, 1.622655, 1.620755, 1.617995, 1.616985, 1.611595, 1.61411, 1.615785, 1.613975, 1.611155, 1.610865, 1.60935, 1.609255, 1.610085, 1.607585, 1.608405, 1.610095, 1.611495, 1.610465, 1.609775, 1.608715, 1.608615, 1.612435, 1.610495, 1.612275, 1.612555, 1.611785, 1.612515, 1.612945, 1.609495, 1.612515, 1.616155, 1.613295, 1.618215, 1.621225, 1.62018, 1.619885, 1.619565, 1.620435, 1.619375, 1.624325, 1.625165, 1.625185, 1.621845, 1.622345, 1.623795, 1.621875, 1.627455, 1.624845, 1.623875, 1.623625, 1.623295, 1.625575, 1.626125, 1.622445, 1.622145, 1.624155, 1.626055, 1.625755, 1.62671, 1.627055, 1.625875, 1.625055, 1.623925, 1.624645, 1.625215, 1.624725, 1.624025, 1.624515, 1.624205, 1.623755, 1.623325, 1.62273, 1.622535, 1.6242, 1.623045, 1.62169, 1.618415, 1.618185, 1.619605, 1.621425, 1.627035, 1.628145, 1.62778, 1.6271, 1.626485, 1.626335, 1.627615, 1.627965, 1.63094, 1.630125, 1.632065, 1.633775, 1.632895, 1.63064, 1.627885, 1.625845, 1.62667, 1.626805, 1.626695, 1.631185, 1.629635, 1.63067, 1.63367, 1.63908, 1.63709, 1.637255, 1.63738, 1.64403, 1.642545, 1.650745, 1.65183, 1.64764, 1.646825, 1.639945, 1.634085, 1.633615, 1.631255, 1.63123, 1.62993, 1.628745, 1.629105, 1.63096, 1.63417, 1.635245, 1.634745, 1.633755, 1.63316, 1.633325, 1.63464, 1.63394, 1.635555, 1.636435, 1.636235, 1.63692, 1.638125, 1.63869, 1.637795, 1.6323, 1.638925, 1.640955, 1.63767, 1.63686, 1.636575, 1.63977, 1.63909, 1.63945, 1.64001, 1.641005, 1.63986, 1.63838, 1.64039, 1.64047, 1.636, 1.63434, 1.634115, 1.633895, 1.633725, 1.63255, 1.633225, 1.63228, 1.632915, 1.63046, 1.630275, 1.628565, 1.63377, 1.631165, 1.630405, 1.63149, 1.63178, 1.63308, 1.63234, 1.630675, 1.630235, 1.63027, 1.632255, 1.630505, 1.626665, 1.625325, 1.624565, 1.624355, 1.62497, 1.62389, 1.62394, 1.62399, 1.622855, 1.621865, 1.62358, 1.62292, 1.623685, 1.624135, 1.62672, 1.624515, 1.624305, 1.624215, 1.62416, 1.623665, 1.6259, 1.625805, 1.626625, 1.62005, 1.618425, 1.62162, 1.62192, 1.620865, 1.62121, 1.621525, 1.621475, 1.619475, 1.619145, 1.619835, 1.620235, 1.6204, 1.618875, 1.622535, 1.62144, 1.617695, 1.61798, 1.61831, 1.618825, 1.61982, 1.62336, 1.621535, 1.61987, 1.616985, 1.6134, 1.61441, 1.6139, 1.61428, 1.61376, 1.61498, 1.615715, 1.612955, 1.61323, 1.61406, 1.6102, 1.606695, 1.60757, 1.59774, 1.59611, 1.597425, 1.597505, 1.59687, 1.59683, 1.596235, 1.59762, 1.59792, 1.59878, 1.596685, 1.598745, 1.59928, 1.60067, 1.602755, 1.603465, 1.607645, 1.608225, 1.60736, 1.60442, 1.604255, 1.60657, 1.60907, 1.604735, 1.607615, 1.61128, 1.607135, 1.60798, 1.60935, 1.60968, 1.60865, 1.607105, 1.60607, 1.606545, 1.60638, 1.607575, 1.60701, 1.60822, 1.606605, 1.604175, 1.617025, 1.615945, 1.616205, 1.61726, 1.61868, 1.618035, 1.62082, 1.620575, 1.62089, 1.61883, 1.61219, 1.61243, 1.61167, 1.61194, 1.61212, 1.61281, 1.61193, 1.61268, 1.606455, 1.60555, 1.60459, 1.60322, 1.604705, 1.60562, 1.606145, 1.6077, 1.60683, 1.60916, 1.611945, 1.61187, 1.611335, 1.60832, 1.609145, 1.60955, 1.608575, 1.60676, 1.606755, 1.60695, 1.607395, 1.606405, 1.6076, 1.606815, 1.60695, 1.604905, 1.59545, 1.59164, 1.59162, 1.592925, 1.59173, 1.590465, 1.590475, 1.588995, 1.58925, 1.590845, 1.590575, 1.589605, 1.59287, 1.59246, 1.597345, 1.596035, 1.591425, 1.59756, 1.60024, 1.59879, 1.600055, 1.598305, 1.597, 1.59925, 1.596045, 1.598845, 1.600635, 1.606405, 1.60702, 1.609275, 1.607365, 1.609575, 1.60851, 1.60739, 1.607985, 1.60689, 1.60864, 1.61119, 1.606205, 1.60851, 1.61039, 1.6088, 1.609185, 1.609595, 1.609035, 1.609775, 1.61074, 1.61063, 1.61041, 1.612855, 1.612635, 1.61363, 1.613635, 1.61695, 1.61705, 1.615905, 1.615515, 1.61577, 1.617205, 1.618045, 1.616225, 1.61466, 1.61568, 1.61528, 1.613335, 1.613045, 1.611435, 1.61178, 1.611265, 1.612395, 1.612615, 1.61215, 1.607975, 1.604285, 1.60507, 1.60358, 1.606845, 1.606225, 1.605045, 1.60427, 1.60436, 1.604135, 1.60491, 1.60554, 1.603425, 1.60145, 1.602715, 1.602035, 1.603575, 1.60334, 1.602125, 1.602895, 1.602555, 1.60353, 1.603785, 1.60398, 1.603185, 1.60395, 1.605205, 1.608145, 1.6097, 1.608285, 1.60858, 1.609015, 1.608575, 1.609035, 1.61034, 1.61067, 1.61045, 1.610075, 1.609925, 1.609565, 1.61126, 1.61328, 1.612295, 1.61265, 1.611675, 1.61242, 1.61272, 1.61275, 1.61212, 1.612105, 1.610675, 1.611365, 1.617255, 1.61567, 1.613815, 1.61384, 1.613175, 1.61411, 1.6132, 1.613675, 1.61394, 1.613675, 1.612405, 1.61159, 1.61244, 1.6149, 1.609405, 1.600625, 1.60129, 1.600285, 1.597765, 1.59804, 1.597085, 1.59792, 1.598775, 1.598545, 1.60051, 1.602205, 1.599575, 1.599565, 1.600345, 1.59987, 1.599305, 1.599525, 1.597605, 1.599295, 1.59902, 1.600385, 1.59634, 1.59984, 1.599365, 1.599665, 1.59966, 1.597265, 1.593855, 1.59653, 1.59713, 1.59792, 1.59974, 1.60036, 1.599825, 1.598095, 1.598495, 1.59798, 1.597485, 1.59773, 1.597355, 1.5986, 1.599495, 1.599755, 1.60003, 1.600025, 1.600375, 1.60105, 1.598955, 1.600155, 1.599765, 1.600475, 1.60022, 1.6006, 1.60181, 1.596045, 1.5943, 1.588815, 1.59068, 1.596245, 1.59832, 1.59755, 1.59771, 1.59605, 1.595625, 1.59563, 1.597925, 1.599085, 1.59813, 1.594745, 1.593165, 1.592695, 1.586095, 1.58439, 1.583355, 1.583495, 1.58396, 1.58395, 1.58188, 1.58351, 1.58259, 1.583445, 1.582, 1.58423, 1.584275, 1.58594, 1.58744, 1.58719, 1.588185, 1.58738, 1.589525, 1.590055, 1.59015, 1.588425, 1.590905, 1.589435, 1.587295, 1.585705, 1.585945, 1.584915, 1.584655, 1.585055, 1.585295, 1.58395, 1.58466, 1.584475, 1.58468, 1.585585, 1.586555, 1.588415, 1.59241, 1.591835, 1.591695, 1.590885, 1.591405, 1.590985, 1.591665, 1.592275, 1.5882, 1.581655, 1.580375, 1.58148, 1.57864, 1.578555, 1.57667, 1.577125, 1.577305, 1.57743, 1.577365, 1.577185, 1.57641, 1.574255, 1.57483, 1.57164, 1.570785, 1.57102, 1.5706, 1.568675, 1.567595, 1.56684, 1.56692, 1.56813, 1.567345, 1.565315, 1.560175, 1.565545, 1.568455, 1.567155, 1.566805, 1.566615, 1.567495, 1.57258, 1.572635, 1.571035, 1.56638, 1.56362, 1.564205, 1.56323, 1.564425, 1.56413, 1.564065, 1.56356, 1.56443, 1.565565, 1.565335, 1.565155, 1.56566, 1.565865, 1.564555, 1.564785, 1.564695, 1.56344, 1.5631, 1.56226, 1.561195, 1.56147, 1.560665, 1.562395, 1.56057, 1.56928, 1.566655, 1.56624, 1.566875, 1.56932, 1.56767, 1.56817, 1.567015, 1.567355, 1.56741, 1.56635, 1.565175, 1.566865, 1.570025, 1.57282, 1.56816, 1.570325, 1.56959, 1.56924, 1.56901, 1.570075, 1.569705, 1.56823, 1.56393, 1.56667, 1.56727, 1.56499, 1.56707, 1.564855, 1.566205, 1.56555, 1.564845, 1.565205, 1.56587, 1.56643, 1.56677, 1.564145, 1.56529, 1.56839, 1.568565, 1.569955, 1.569735, 1.570485, 1.57035, 1.569595, 1.568, 1.567995, 1.568395, 1.56889, 1.567615, 1.56646, 1.57027, 1.57135, 1.57154]
Comentarios
- ¡Bienvenido a CodeReview.SE! ¿Podría proporcionar datos ficticios para que uno pueda probar su código antes de revisarlo?
- Hola Josay, yo ' le agregamos una lista de muestra de datos si ' desea probar.
Respuesta
- La recursividad es una buena herramienta para el trabajo correcto, pero aquí se usa para lograr un bucle simple. Como tal, el código … .
- es más difícil de leer y razonar.
- es más lento porque gran parte del código en
ema
solo necesita ejecutarse una vez. - fallará con un valor suficientemente grande de
window
debido a o Verflowing Python «s call stack.
- Por favor documente al menos los parámetros de cada función, ej. que
window
es la longitud de la ventana, y queposition
cuenta hacia atrás desde el final dedata
. (De hecho, las cosas estarían más claras siposition
fuera un índice de avance normal endata
). - Genere una excepción cuando encuentra que un parámetro tiene un valor no válido. Devolver
None
en su lugar solo causará una excepción más confusa más adelante. De hecho, si prueboIndicators().ema(close_prices, 600)
obtengo una recursividad infinita porquesma
devuelveNone
, que hace queema
llame asma
una y otra vez. - El punto anterior también revela que
if len(data) < window + 2
no es la verificación de validez correcta. - El
+ 1
endata[-window*2 + 1:-window + 1]
no parece correcto para mí. Supongo que quieresdata[-window*2:-window]
- La declaración
return previous_ema
está en un lugar extraño porque en ese punto ha calculado un nuevocurrent_ema
. Este es el caso base de la recursividad, y se acostumbra manejar primero el caso base.
Mi propuesta para ema
:
def ema(self, data, window): if len(data) < 2 * window: raise ValueError("data is too short") c = 2.0 / (window + 1) current_ema = self.sma(data[-window*2:-window], window) for value in data[-window:]: current_ema = (c * value) + ((1 - c) * current_ema) return current_ema
Respuesta
Revisión bastante superficial:
No es necesario que escribas una clase sobre lo que estás haciendo (y te sugiero que eches un vistazo a este video ). Su clase no encapsula ningún dato y solo lo usa para tener sus funciones en la misma entidad. Supongo que las cosas serían más fáciles de entender si definiera classmethod
para que sea obvio que no dependerá realmente de ninguna instancia. Sin embargo, una opción aún mejor sería simplemente definir funciones en un módulo indicator
.
Comentarios
- ¡Gracias por las sugerencias! ellos como métodos de clase y debatí ir y venir entre incluso usar una clase o simplemente definir funciones en un módulo indicador (lo que ahora haré).
- Acabo de ver el video también, excelentes cosas.