Este artículo trata sobre Oracle Database, PL / SQL, SQL, MATCH_RECOGNIZE, cláusula MODEL, agregado y funciones canalizadas.
El análisis técnico (AT) de los mercados se utilizó como área funcional. Primero, una pequeña nota introductoria superficial sobre el comercio en los mercados, luego los cálculos.
Análisis técnico: un conjunto de herramientas para pronosticar probables cambios de precios basados en patrones de cambios de precios pasados. Teóricamente, el análisis técnico es aplicable en cualquier mercado. Pero el análisis técnico más extendido fue en mercados libres altamente líquidos, por ejemplo, en bolsas.
Se han desarrollado muchas declaraciones, procedimientos y gráficos de SQL. Parte - abajo, código completo - en GitHub en el enlace al final del artículo.
Indicadores técnicos del mercado (TIR): gráficos adicionales para gráficos de precios,
formados sobre la base de la conversión de valores contenidos en el gráfico de precios base . Por lo general, estos son diferentes tipos de promedios (el siguiente punto del gráfico se calcula como el valor promedio de un cierto número de valores de precios anteriores, por ejemplo, un promedio móvil), relaciones (el siguiente punto es el resultado de comparar un cierto número de precios anteriores: su diferencia, derivada de un cambio durante un período) o retrasos ( retrasos). Los indicadores muestran claramente cierta información no obvia contenida en las estadísticas de cambios de precios, y pueden formular recomendaciones sobre órdenes comerciales - COMPRAR / VENDER. Los indicadores tienen al menos un parámetro variable, cuyo valor cambiará el resultado.
Para abrir transacciones reales, generalmente se utilizan varios indicadores en combinación, más información adicional, a discreción del operador.Uno de los principios del Análisis Técnico es "la historia se repite": los participantes del mercado en circunstancias similares se comportan aproximadamente de la misma manera, formando dinámicas similares de cambios de precios. Y es natural suponer que el comportamiento del mercado en el futuro repetirá principalmente los patrones que han surgido en el pasado. Después de esta declaración, el inversor puede elegir entre los posibles parámetros TIR aquellos que han demostrado ser mejores en períodos pasados.
Este artículo crea un gráfico del rendimiento comercial cuando se usa cada indicador en el valor del parámetro TIR, esto es en una representación bidimensional. Pero, de hecho, construiré una representación tridimensional para evaluar también el efecto del retraso en la ejecución del pedido sobre el resultado, por lo que el parámetro será el eje X (abscisa), el retraso será el eje Y (ordenada), el resultado será el eje Z (aplicar). Este es un intento de evaluar el efecto del "deslizamiento", que, desafortunadamente, siempre sucede. En lugar de un "deslizamiento" real a lo largo del eje Y, pospongo la ejecución de la orden BUY / SELL por un período de 1 a 5 períodos.
Si se resalta un máximo global en este gráfico y el gráfico en sí se verá como un sombrero (en general, se llama la "distribución normal", pero supone una simetría estricta sobre el eje vertical), el cono, la pirámide también son adecuados, lo que significa que puede elegir un cierto valor de parámetro para esto , que mostrará el resultado más alto, y con este indicador puede intentar comerciar. Si el gráfico de rendimiento, según el parámetro, se asemeja a una "empalizada", es imposible elegir el valor óptimo del parámetro y no tiene sentido utilizar este
TIR en el comercio.
Podemos decir que en este artículo solo calculo el "porcentaje de aciertos" de los indicadores. El problema, para evaluar cuánto puede "ganar", no me atreví.La finalización exitosa de la prueba descrita es uno de los factores necesarios, pero no suficientes para un comercio efectivo.Para información ... En contraste con el Análisis Técnico, Análisis Fundamental (FA) es un término para designar métodos para predecir el valor de mercado (intercambio) de instrumentos basados en el análisis de indicadores de desempeño financiero y de producción.
El "valor intrínseco" de la
FA en la mayoría de los casos no coincide con el precio de las acciones de la compañía, que está determinado por la relación de oferta y demanda en el mercado de valores. Los inversores que usan el
FA en sus actividades están interesados principalmente en situaciones en las que el "valor intrínseco" de las acciones de la compañía excede el precio de las acciones en el intercambio. Dichas acciones se consideran infravaloradas, lo que significa que su precio aumentará y son posibles objetivos de inversión.
Uno de los inversores más conocidos que utiliza el Análisis Fundamental es Warren Buffett.
Mira el avance:
https://www.youtube.com/watch?v=SqE8fnvmV1YPor lo tanto, tenemos dos enfoques diametralmente opuestos:
TA y
FA .
FA generalmente interesa a los inversores a largo plazo, TA: a corto y mediano plazo, y se utiliza para transacciones de naturaleza especulativa, cuando el tema del comercio del comerciante no está interesado.
Y los objetivos de este artículo son dos ...
Además de las discusiones sobre
TA y
FA descritas anteriormente,
quería explorar y mostrar las capacidades de Oracle Database para realizar cálculos de indicadores técnicos del mercado .
Presento estas oportunidades al juicio de los lectores.
Si decide repetir mis cálculos, descargue el código de GitHub en el enlace al final del artículo. Código verificado en la versión 12.2.0.1.
Primero crea objetos compartidos. Los primeros son las tablas y la vista. En el mismo archivo a continuación hay un paquete de modelado de transacciones.
El segundo paso es la creación de funciones que realizan el cálculo de
TIR .
El tercer paso son los cálculos.
Todas las funciones para calcular todas las
TIR devolverán un cursor con los siguientes campos: STOCK_NAME, ADATE, ACLOSE (precio de cierre del día), AACTION (orden de venta / compra)
El paquete contiene tres funciones de modelado tabular que toman un cursor de entrada de las funciones de cálculo
TIR descritas anteriormente, compensación (retraso en la ejecución de la orden, retraso) y capital inicial, por defecto es 1000 USD. Las funciones del paquete se llaman así:
select * from HABR_TRADEMODELLING_P.TRADE_LOG (cursor (select STOCK_NAME, ADATE, ACLOSE, AACTION from table (HABR_MARKETINDEXES_XXXXXXXX_F_CALC (10))), p_lag => 1) order by 1, 2; select * from HABR_TRADEMODELLING_P.CALC_ACTIONS (cursor (select STOCK_NAME, ADATE, ACLOSE, AACTION from table (HABR_MARKETINDEXES_XXXXXXXX_F_CALC (10))), p_lag => 1); select * from HABR_TRADEMODELLING_P.CALC_ACTIONS_TOTALS (cursor (select STOCK_NAME, ADATE, ACLOSE, AACTION from table (HABR_MARKETINDEXES_XXXXXXXX_F_CALC (10))), p_lag => 1);
donde XXXXXXXX es el nombre de la
TIR .
Todas las funciones calculan el resultado del comercio sujeto a la reinversión total de las ganancias, excluyendo los costos de transacción y los impuestos, y excluyendo la inflación y el descuento.La primera función
TRADE_LOG
forma un registro de transacciones del comerciante simplificado. La función le permite rastrear toda la cadena de transacciones. Si al final del período el inversor está "en valores", para calcular el saldo en moneda (resultado financiero), la función simula la venta de todos los valores al último precio de cierre y forma la marca correspondiente en el campo IN_STOCK.
La segunda función
CALC_ACTIONS
devuelve las mismas columnas que el cursor de cálculo
TIR llamado, y agrega las siguientes columnas:
AACTION_LAG
(orden con compensación),
BALANCE_CURRENCY
(saldo de la cuenta del operador en efectivo),
BALANCE_STOCK
(número de instrumentos en posiciones abiertas). Dependiendo del valor del campo
AACTION_LAG
, se simula una compra o venta a un precio de cierre y, en consecuencia, se cambia el saldo en la moneda y la cantidad de posiciones abiertas.
En la última línea de cada instrumento, puede ver el resultado de la negociación de cada instrumento, así como en la función anterior, si el inversor está "en valores", se simula una venta para calcular el saldo en moneda extranjera
La tercera función
CALC_ACTIONS_TOTALS
hace lo mismo que la segunda, pero solo devuelve la última fila, el resultado de la negociación de cada instrumento. Se usará en el modelado.
Descargar datos
Los cálculos se dan para dichos mercados e índices: S & P500, NYSE, Brent, BTCUSD, EURUSD.
Los primeros 4 fueron descargados de Yahoo Finance, el último de otra fuente. Los resultados del cálculo para cursos de otras fuentes pueden variar.
Tenga en cuenta que los períodos de los cursos de cada instrumento son diferentes, a saber:
- S & P500 - 01/03/1950 ... 29/01/2019, 69 años;
- NYSE - 31/12/1965 ... 22/03/2019, 54 años;
- Brent - 17/05/1991 ... 02/06/2019, 28 años;
- BTCUSD - 16/07/2010 ... 29/01/2019, 9 años de edad;
- EURUSD - 16/02/2001 ... 27/05/2019, 18 años.
Por lo tanto, es imposible comparar la rentabilidad lograda de los instrumentos entre sí, pero puede comparar la rentabilidad de cada uno de los instrumentos utilizando diferentes indicadores.
El archivo de descarga (SQL * Loader) también se puede tomar de GitHub en el enlace al final del artículo.
Medias móviles
Existen al menos tres tipos principales de promedios móviles:
- lineal (media móvil simple, SMA),
- Promedio móvil exponencial (EMA) y
- ponderado linealmente (Promedio móvil ponderado, WMA).
Se diferencian en los pesos de sus partes constituyentes. Para un promedio móvil lineal, los pesos son iguales, para pesos ponderados exponenciales y lineales, disminuyen a medida que el componente se mueve más lejos del borde derecho de la ventana, exponencial o linealmente.
El promedio móvil lineal es el más fácil de calcular. En Oracle, esta es la función
avg (VALUE) over (partition by STOCK_NAME order by ADATE rows between 9 preceding and current row)
: un promedio móvil con una ventana de promedio de 10 valores.
El promedio móvil lineal tiene inconvenientes. En primer lugar, dichos promedios responden lentamente a las reversiones del mercado. Dado que se promedian muchos valores, cada uno de los cuales tiene el mismo peso, la respuesta promedio a menudo ocurre varios marcos de tiempo después de una reversión del precio de los activos.
Además, el promedio móvil lineal no es muy efectivo, porque responde a la señal dos veces: cuando el indicador ingresó a la ventana deslizante y la dejó. El resto reacciona solo a la entrada del indicador y lo elimina suavemente del cálculo a medida que se mueve desde el borde derecho de la ventana hacia la izquierda.
Al calcular la
TIR , se utilizan los tres tipos de promedios móviles. Para exponencial y ponderado linealmente en este artículo, se desarrollan las funciones agregadas
EMA
y
WMA
, que se utilizan en forma analítica. Además, estos promedios móviles se pueden calcular por recursividad o modelo (frase
MODEL
).
El cálculo de EMA y WMA, sin recursividad o modelka, solo por análisis, en Oracle Database, aparentemente, es imposible.
Pero aún reservas sobre promedios móviles:
- cuanto más corto es el período promedio y cuanto más sensible es el método a los giros, más se emiten señales falsas;
- cuanto más corto es el período promedio, más señales se generan, mayor es la sobrecarga de la transacción, lo que puede llegar a ser muy significativo.
Indicadores técnicos del mercado
Para casi todos los indicadores, se darán varios métodos de cálculo: CALC - cálculo usando código PL / SQL, SIMP - cálculo por un operador o RECU - cálculo por recursión, AGRF - cálculo usando la función de agregado, MODE - cálculo por modelo.
Hay razones para desarrollar varios métodos. En primer lugar, calculando el
TIR por varios métodos y comparando los indicadores, si los indicadores son los mismos, puede estar seguro de que los cálculos se realizaron correctamente (teniendo en cuenta diferentes métodos de redondeo y procesamiento de valores NULL y "0"). En este artículo compararé los hash de muestras de diferentes métodos, por lo que se garantiza la coincidencia de bits y el mismo procesamiento por todos los algoritmos.
Creo que Oracle necesita comenzar a desarrollar
TIR con el método SIMP: cálculo realizado por un operador. Cuando se hace esto, el oracleoide tiene un plan y un algoritmo de cálculo en su cabeza, y puede transferirse fácilmente a PL / SQL u otro lenguaje de procedimiento.
Observo que el método de cálculo CALC para PL / SQL aquí es más rápido que el método SIMP (con un operador) si todo el cálculo puede realizarse en una pasada a lo largo del cursor. Pero si para el cálculo tiene que crear tablas o colecciones temporales, o más de 1 pasada en el cursor, creo que el método de "un operador" resultará más rápido y menos intensivo en recursos.
Para todos los métodos, incluido el método SIMP ("un operador"), pondré a los operadores en funciones para que se pueda llamar al cálculo con un parámetro para seleccionar el valor óptimo.
Los cálculos se dan para siete
TIR : intersección de la media móvil (EMASIMPLE), cruces de oro y muerte (CRUCES), volumen de equilibrio (OBV), canal Keltner (KELTNER), tendencia de precio y volumen (PVT), indicador de facilidad de movimiento de armas (EMV) ), Índice de canal de productos básicos (CCI).
Para los siete indicadores de estos dos artículos, habrá un parámetro "tamaño de ventana promedio" y el segundo parámetro - shift (lag). El turno dice cuántas barras necesita para posponer la ejecución de la orden COMPRAR / VENDER, cuántas barras mover el precio de cierre (todas las órdenes se hacen al precio de cierre de la barra). Esto es similar a "deslizamiento", pero no es exactamente "deslizamiento". El deslizamiento generalmente no está a favor del cliente, y nuestro retraso puede resultar tanto a favor del cliente como a favor. Sin embargo, el uso de modelos con un retraso de 1 a 5 barras para algunos indicadores muestra que el deslizamiento tiene un efecto significativo en el resultado. Y para algunos indicadores, el retraso y el deslizamiento no son tan importantes.
Los métodos SIMP ("operador único") y RECU ("recursión")
MATCH_RECOGNIZE
activamente la frase
MATCH_RECOGNIZE
para generar la señal comercial COMPRAR / VENDER en función de la entrada / salida del
TIR calculado en el rango especificado o su comportamiento en relación con su promedio móvil.
Se pueden encontrar descripciones detalladas de todos los TIR en Wikipedia o en el libro de Robert Colby, Enciclopedia de indicadores técnicos del mercado.La intersección de la media móvil exponencial
El método de intersección de promedios móviles exponenciales es el
TIR más simple.
El método implica: comprar (abrir una posición larga) si el valor del precio cruza su promedio móvil exponencial ascendente (ESA); vender (cerrar una posición larga) si el precio cruza su ESS de arriba a abajo.
Las posiciones cortas, así como el comercio de margen en general, no se consideran en este artículo.
En el futuro, es este indicador el que se puede usar como estándar para compararlo con otros. Una comparación con este
TIR es mejor que una comparación con la estrategia Buy and Hold, porque esta estrategia no es rentable en la caída de los mercados.
El único parámetro
TIR es la longitud de la media móvil.
Cálculo usando PL / SQL
create or replace function HABR_MARKETINDEXES_EMASIMPLE_F_CALC (p_averaging_window_width integer) return HABR_MARKETINDEXES_RESULT_LIST_T pipelined is l_result HABR_MARKETINDEXES_RESULT_LIST_T; EMA number; prev_EMA number; prev_TYPICAL_PRICE number; retval HABR_MARKETINDEXES_RESULT_T := HABR_MARKETINDEXES_RESULT_T (null, null, null, null, null, null, null, null, null); prev_STOCK_NAME varchar2(256); l_alpha number; begin l_alpha := 2 / (p_averaging_window_width + 1); for c1 in (select STOCK_NAME, ADATE, TYPICAL_PRICE, ACLOSE from LOAD_YAHOO_V order by 1, 2) loop retval.ADATE := c1.ADATE; retval.ACLOSE := c1.ACLOSE; if prev_STOCK_NAME is null or prev_STOCK_NAME <> c1.STOCK_NAME then retval.STOCK_NAME := c1.STOCK_NAME; EMA := c1.TYPICAL_PRICE; prev_EMA := null; else EMA := round (c1.TYPICAL_PRICE * l_alpha + EMA * (1 - l_alpha), 20); end if; if prev_TYPICAL_PRICE < prev_EMA and c1.TYPICAL_PRICE > EMA then retval.AACTION := 'BUY'; elsif prev_TYPICAL_PRICE > prev_EMA and c1.TYPICAL_PRICE < EMA then retval.AACTION := 'SELL'; else retval.AACTION := null; end if; retval.IND_VALUE := EMA; pipe row (retval); prev_STOCK_NAME := c1.STOCK_NAME; prev_EMA := EMA; prev_TYPICAL_PRICE := c1.TYPICAL_PRICE; end loop; end;
Cálculo por un operador recursivo
create or replace function HABR_MARKETINDEXES_EMASIMPLE_F_RECU (p_averaging_window_width integer) return HABR_MARKETINDEXES_RESULT_LIST_T is l_result HABR_MARKETINDEXES_RESULT_LIST_T; begin with T1 (STOCK_NAME, ADATE, TYPICAL_PRICE, EMA, ACLOSE, RN) as (select STOCK_NAME, ADATE, TYPICAL_PRICE, round (TYPICAL_PRICE, 20), ACLOSE, RN from LOAD_YAHOO_V where RN = 1 union all select b.STOCK_NAME , b.ADATE , b.TYPICAL_PRICE , round (b.TYPICAL_PRICE * 2 / (p_averaging_window_width + 1) + a.EMA * (1 - 2 / (p_averaging_window_width + 1)), 20) , b.ACLOSE , b.RN from T1 a, LOAD_YAHOO_V b where b.RN = a.RN + 1 and b.STOCK_NAME = a.STOCK_NAME) select HABR_MARKETINDEXES_RESULT_T (STOCK_NAME, ADATE, ACLOSE, EMA, null, null, null, null, AACTION) bulk collect into l_result from T1 match_recognize (partition by STOCK_NAME order by ADATE measures classifier() as AACTION all rows per match with unmatched rows pattern (BUY+ | SELL+) define BUY as (prev (TYPICAL_PRICE) < prev (EMA) and TYPICAL_PRICE > EMA) , SELL as (prev (TYPICAL_PRICE) > prev (EMA) and TYPICAL_PRICE < EMA) ) MR; return l_result; end;
Cálculo utilizando la frase MODELO
Texto de función HABR_MARKETINDEXES_EMASIMPLE_F_MODE create or replace function HABR_MARKETINDEXES_EMASIMPLE_F_MODE (p_averaging_window_width integer) return HABR_MARKETINDEXES_RESULT_LIST_T is l_result HABR_MARKETINDEXES_RESULT_LIST_T; begin with T1 as (select * from LOAD_YAHOO_V model dimension by (STOCK_NAME, RN) measures (ADATE, TYPICAL_PRICE, ACLOSE, to_number(null) as EMA) rules (EMA[any, any] = round (TYPICAL_PRICE [cv(), cv()] * 2 / (p_averaging_window_width + 1) + nvl(EMA [cv(), cv() - 1], TYPICAL_PRICE [cv(), cv()]) * (1 - 2 / (p_averaging_window_width + 1)), 20))) , T2 as (select STOCK_NAME, ADATE, ACLOSE , TYPICAL_PRICE, LAG (TYPICAL_PRICE) over (partition by STOCK_NAME order by ADATE) as PREV_TYPICAL_PRICE , EMA, lag (EMA) over (partition by STOCK_NAME order by ADATE) as PREV_EMA from T1) select HABR_MARKETINDEXES_RESULT_T (STOCK_NAME, ADATE, ACLOSE, EMA, null, null, null, null , case when prev_TYPICAL_PRICE < prev_EMA and TYPICAL_PRICE > EMA then 'BUY' when prev_TYPICAL_PRICE > prev_EMA and TYPICAL_PRICE < EMA then 'SELL' end) bulk collect into l_result from T2 order by STOCK_NAME, ADATE; return l_result; end;
Cálculo utilizando la función agregada
El texto de la función agregada EMA y la función HABR_MARKETINDEXES_EMASIMPLE_F_AGRF create or replace type EMA_DATA_T as object (AVALUE number, AVERAGING_WINDOW integer); create or replace type EMA_IMPL_T as object ( l_window_width integer, l_ema number, static function ODCIAggregateInitialize (sctx in out EMA_IMPL_T) return number, member function ODCIAggregateIterate (self in out EMA_IMPL_T, value in EMA_DATA_T) return number, member function ODCIAggregateMerge (self in out EMA_IMPL_T, ctx2 in EMA_IMPL_T) return number, member function ODCIAggregateTerminate (self in EMA_IMPL_T, returnValue out number, flags in number) return number ); create or replace type body EMA_IMPL_T is static function ODCIAggregateInitialize (sctx in out EMA_IMPL_T) return number is begin sctx := EMA_IMPL_T (null, null); return ODCIConst.Success; end; member function ODCIAggregateIterate (self in out EMA_IMPL_T, value in EMA_DATA_T) return number is begin if value.AVALUE is not null then if l_window_width is null then l_window_width := value.AVERAGING_WINDOW; self.l_ema := value.AVALUE; else self.l_ema := round (value.AVALUE * 2 / (l_window_width + 1) + self.l_ema * (1 - 2 / (l_window_width + 1)), 20); end if; end if; return ODCIConst.Success; end; member function ODCIAggregateMerge(self in out EMA_IMPL_T, ctx2 in EMA_IMPL_T) return number is begin return ODCIConst.Error; end; member function ODCIAggregateTerminate(self in EMA_IMPL_T, returnValue out number, flags in number) return number is begin returnValue := self.l_ema; return ODCIConst.Success; end; end; create or replace function EMA (input EMA_DATA_T) return number aggregate using EMA_IMPL_T; create or replace function HABR_MARKETINDEXES_EMASIMPLE_F_AGRF (p_averaging_window_width integer) return HABR_MARKETINDEXES_RESULT_LIST_T is l_result HABR_MARKETINDEXES_RESULT_LIST_T; begin with T1 as (select STOCK_NAME, ADATE, TYPICAL_PRICE, ACLOSE , round (EMA (EMA_DATA_T (TYPICAL_PRICE, p_averaging_window_width)) over (partition by STOCK_NAME order by ADATE), 20) as EMA from LOAD_YAHOO_V) select HABR_MARKETINDEXES_RESULT_T (STOCK_NAME, ADATE, ACLOSE, EMA, null, null, null, null, AACTION) bulk collect into l_result from T1 match_recognize (partition by STOCK_NAME order by ADATE measures classifier() as AACTION all rows per match with unmatched rows pattern (BUY+ | SELL+) define BUY as (prev (TYPICAL_PRICE) < prev (EMA) and TYPICAL_PRICE > EMA) , SELL as (prev (TYPICAL_PRICE) > prev (EMA) and TYPICAL_PRICE < EMA) ) MR; return l_result; end;
Compare los resultados del cálculo con un parámetro:
select COLUMN_VALUE as ALG, dbms_sqlhash.gethash (COLUMN_VALUE, 2) as RECORDSET_HASH from table (sys.odcivarchar2list ('select * from table (HABR_MARKETINDEXES_EMASIMPLE_F_CALC (15)) order by 1, 2' , 'select * from table (HABR_MARKETINDEXES_EMASIMPLE_F_RECU (15)) order by 1, 2' , 'select * from table (HABR_MARKETINDEXES_EMASIMPLE_F_MODE (15)) order by 1, 2' , 'select * from table (HABR_MARKETINDEXES_EMASIMPLE_F_AGRF (15)) order by 1, 2'));
Todos los hashes deben coincidir para los cuatro métodos.
Si los hash no coinciden, puede averiguar exactamente dónde se formó la discrepancia, utilizando este operador (sustituya los nombres de las funciones que desea comparar):
select coalesce (a.STOCK_NAME, b.STOCK_NAME) as STOCK_NAME, coalesce (a.ADATE, b.ADATE) as ADATE , a.ACLOSE as CALC_ACLOSE, b.ACLOSE as AGRF_CLOSE , a.IND_VALUE as CALC_EMA, b.IND_VALUE as AGRF_EMA , a.AACTION as CALC_AACTION, b.AACTION as AGRF_AACTION from table (HABR_MARKETINDEXES_EMASIMPLE_F_CALC (15)) a full outer join table (HABR_MARKETINDEXES_EMASIMPLE_F_AGRF (15)) b on a.STOCK_NAME = b.STOCK_NAME and a.ADATE = b.ADATE
Selección de parámetros.El
TIR en sí usa un parámetro, para este y para todos los demás
TIR lo cambio en el rango de 1 a 200, pero para calcular una imagen tridimensional de dependencia y también en el retraso, introduciremos un segundo parámetro que variará de 1 a 5.
El operador abre 200 * 5 = 1000 cursores, por lo que
es posible que deba cambiar Oracle
OPEN_CURSORSLa siguiente consulta realiza el producto cartesiano de una tabla con números del 1 al 200, con una tabla con números del 1 al 5, y el cartesiano multiplica todo esto llamando a la función de tabla
HABR_TRADEMODELLING_P.CALC_ACTIONS_TOTALS
.
Después de algunas manipulaciones adicionales en MATLAB, obtendremos una matriz de 200 * 5, donde en las celdas de la matriz habrá un valor de capital total para cada valor de cada uno de los dos parámetros. Luego en MATLAB construimos una imagen tridimensional.
rollback; delete HABR_MARKETINDEXES_PARMSEL_RESULTS where INDICATOR_NAME = 'HABR_MARKETINDEXES_EMASIMPLE_F_CALC'; commit; insert into HABR_MARKETINDEXES_PARMSEL_RESULTS (INDICATOR_NAME, PARM1, PARM2, STOCK_NAME, ADATE_MIN, ADATE_MAX, DEALS_COUNT, BALANCE_RESULT, DEALS_PROFIT_AMOUNT, DEALS_LOSS_AMOUNT, DEALS_PROFIT_COUNT, DEALS_LOSS_COUNT, IN_STOCK) with TP1 as (select rownum as PARM1 from dual connect by level <= &&AVERAGING_INTERVAL) , TP2 as (select rownum as PARM2 from dual connect by level <= &&LAG_MODELLING_DEPTH) select
PARM2, STOCK_NAME, ADATE_MIN, ADATE_MAX, DEALS_COUNT, BALANCE_RESULT, DEALS_PROFIT_AMOUNT, DEALS_LOSS_AMOUNT, DEALS_PROFIT_COUNT, DEALS_LOSS_COUNT, IN_STOCK) rollback; delete HABR_MARKETINDEXES_PARMSEL_RESULTS where INDICATOR_NAME = 'HABR_MARKETINDEXES_EMASIMPLE_F_CALC'; commit; insert into HABR_MARKETINDEXES_PARMSEL_RESULTS (INDICATOR_NAME, PARM1, PARM2, STOCK_NAME, ADATE_MIN, ADATE_MAX, DEALS_COUNT, BALANCE_RESULT, DEALS_PROFIT_AMOUNT, DEALS_LOSS_AMOUNT, DEALS_PROFIT_COUNT, DEALS_LOSS_COUNT, IN_STOCK) with TP1 as (select rownum as PARM1 from dual connect by level <= &&AVERAGING_INTERVAL) , TP2 as (select rownum as PARM2 from dual connect by level <= &&LAG_MODELLING_DEPTH) select
Todos los cálculos en este artículo se realizan lentamente, hasta 20 minutos, esto se debe a la apertura de una gran cantidad de cursores.
También desarrollé un método de simulación más rápido con un cursor, sin abrir 1000 cursores, pero es tan voluminoso que tomaría la mitad del artículo. Por lo tanto, no lo traeré aquí.
El resultado de modelar la intersección de la media móvil (se puede hacer clic en todos los gráficos):

La segunda línea de gráficos es la misma que la primera línea, pero los gráficos están ligeramente rotados, los gráficos con diferentes retrasos se organizan uno tras otro. Esto le permite evaluar el efecto del retraso en el resultado.
En general, el indicador no es muy sensible a los retrasos. Para los mercados S & P500 y NYSE, el parámetro
TIR debe seleccionarse cuanto más, mejor. Para el mercado Brent: alrededor de 25. En los otros dos mercados, no hay correlación entre rentabilidad y parámetro.
Cruces mortales y doradas
En la implementación en Oracle, este indicador es muy similar al anterior, solo que aquí se usan dos promedios móviles, y no uno. Por lo tanto, daré solo una opción de cálculo.
El Wiki describe el indicador Ichimoku. Este es un indicador complejo. Las "cruces" son una de las partes constituyentes. Pero el indicador está mal descrito en la Wiki, en particular, tenga en cuenta que las líneas de Tenkan y Kijun se describen en palabras completamente diferentes, aunque en realidad es lo mismo, pero con diferentes períodos.
En el libro de Robert Colby, este indicador tampoco se describe.
Los analistas japoneses llaman a la intersección de los promedios, cuando el promedio a corto plazo cruza el largo plazo de abajo hacia arriba, la Cruz de Oro (Golden Cross), y la situación opuesta, cuando el promedio móvil a corto plazo cruza el largo plazo de arriba hacia abajo, Dead Cross.
El autor notó que este indicador se describe en el artículo
"Los futuros del petróleo estadounidense formaron una" cruz mortal "" y comenzó a buscar en Google su descripción y uso.
Este indicador se considera serio en el mercado de valores, en parte porque rara vez da señales.
Los más utilizados son los promedios móviles de 50 y 200 períodos.
Al modelar el rendimiento a continuación, tomaremos el período del promedio móvil largo igual al período cuádruple del promedio móvil corto y simularemos la duración del corto de 1 a 200 días (resultará de 4 a 800 días para el largo).
Código para calcular en GitHub.

El indicador no es muy sensible a los retrasos. Para el mercado S & P500, hay máximos en 48 (192 para un SS largo) y 98 días (392 para un SS largo). Tenga en cuenta que el primer máximo está muy cerca de los números 50x200. Se puede suponer que si elige este parámetro 1 y 2 menos que otros participantes del mercado, puede intentar superarlos solo en este indicador.
Hay 4 máximos en la NYSE. En los mercados Brent y BTCUSD, el indicador no funciona.
También para el mercado EURUSD, el parámetro debe elegirse un poco menos de 50 para un SS corto. Pero el indicador no da ganancias en este mercado. Solo se puede usar como un indicador adicional.
Volumen de equilibrio, volumen de equilibrio, volumen en equilibrio (OBV)
El indicador OBV es un volumen de negociación promedio móvil acumulativo tomado con un signo más en el caso de un mercado en crecimiento y con un signo menos en el caso de una caída.
Aquí usaremos esta forma de interpretar el valor de los indicadores: comprar cuando el OBV cruza su promedio móvil de abajo hacia arriba, vender cuando el OBV cruza su promedio móvil de arriba hacia abajo.
Más sobre
Wiki o Colby

En el mercado S & P500, el indicador es muy sensible a los retrasos (retrasos), pero puede intentar elegir un parámetro según el principio de "cuanto más mejor", se logra cierta rentabilidad. En la Bolsa de Nueva York, la rentabilidad no se puede lograr. En el mercado Brent, puede seleccionar un valor de parámetro de 20 a 100. En el mercado BTCUSD, no existe una relación lineal clara, pero elegir un valor de parámetro menor que 40 no es práctico. Para el mercado EURUSD, el valor del parámetro debe elegirse "cuanto más mejor", pero no se puede lograr la rentabilidad.
Canal Keltner
TIR consta de dos bandas por encima y por debajo del precio promedio móvil, cuyo ancho se determina como una fracción del cambio de precio promedio para el período. El precio es un precio típico.La línea media de la línea indicadora es un promedio móvil simple del precio típico.Las líneas superior e inferior del indicador están separadas de la línea media por una cantidad igual al promedio móvil simple del rango de negociación diario.En nuestros cálculos, la señal TIR se formará de la siguiente manera: Comprar si el precio cruza la línea superior, Vender si el precio cruza la línea inferior.
Hay máximos para los mercados S & P500 y NYSE. En el mercado Brent, no hay dependencia del resultado en el parámetro, y todas las operaciones están perdidas. Hay altos en el mercado de BTCUSD, pero estrechos, y es difícil entrar en ellos. En el mercado EURUSD, el resultado depende del parámetro.Tendencia de precio y volumen, Tendencia de precio y volumen, Precio - Tendencia de volumen, PVT
El valor del indicador PVT representa la suma acumulativa del producto del volumen de negociación actual por el aumento de precio reducido en relación con el período anterior.Generaremos señales de negociación aquí de la siguiente manera: Compre cuando el PVT cruza su promedio móvil de abajo hacia arriba, Venda cuando el PVT cruza su promedio móvil de arriba hacia abajo.Más en Wiki . Colby no lo encontró. Para el S & P500, el valor del parámetro "cuanto más grande, mejor", en NYSE casi no hay dependencia, para Brent hay un máximo en la región de 50, en BTCUSD el indicador es efectivo solo con retrasos mínimos, 1-2, y con valores mínimos de parámetro, hasta 50 , para EURUSD la dependencia está aumentando.
Facilidad de movimiento, Valor de facilidad de movimiento de armas, EMV
TIR EMV es una expresión numérica de cuán fácilmente cambia un precio en un mercado. Cuanto más fuerte es el cambio en el precio y menor es el volumen de negocios, más fácil sube o baja el mercado.Las órdenes de negociación aquí se formarán de la siguiente manera: Comprar cuando el EMV promedio móvil sube por encima de cero, Vender cuando el EMV promedio móvil cae por debajo de cero.Más sobre Wiki o Colby. Hay máximos en los mercados S&P y NYSE; en el mercado Brent, el indicador es efectivo en una amplia gama de valores de parámetros. En los mercados BTCUSD y EURUSD, el indicador es ineficaz.
Índice de canal de productos básicos, CCI
TIR CCI es un indicador basado en el análisis del cambio actual en la desviación del precio de su valor promedio durante un cierto período y el valor absoluto promedio de este parámetro. TIR es aplicable a cualquier mercado financiero.Formaremos las órdenes de negociación de la siguiente manera: Compre cuando el CCI supere los 100, Venda cuando el CCI caiga por debajo de 100.Más sobre Wiki o Colby. En los mercados S & P500, NYSE, Brent, no hay dependencia del resultado comercial en el valor del parámetro. Existe una dependencia en el mercado BTCUSD (dos máximos claros), y puede intentar atraparlo en el comercio real. En el mercado EURUSD, el indicador del resultado no traerá. Fuentes disponibles en github
, , ( , Yahoo Finance), , , ( , 20 ).
: . . .
Opcional:
Se analizaron otros tres indicadores que no están incluidos en el artículo. Pero no pudieron obtener ningún resultado. Quizás su estudio continuará.Es muy conveniente realizar cálculos y modelos complejos de TIR y actividades financieras en general en Oracle Database.