使用Oracle数据库进行技术市场分析

本文介绍有关Oracle数据库,PL / SQL,SQL,MATCH_RECOGNIZE,MODEL子句,聚合和管道化功能的信息。

市场的技术分析(TA)被用作功能区域。 首先,简要介绍一下市场交易,然后进行计算。

技术分析-一套基于过去价格变化模式预测可能的价格变化的工具。 从理论上讲,技术分析适用于任何市场。 但是,最广泛的技术分析是在高度自由流动的市场中进行的,例如,在交易所。

图片

已经开发了许多SQL语句,过程和图形。 部分-下面,完整代码-在GitHub上,位于文章底部的链接上。

技术市场指标(TIR)-价格图表的其他图表, 基于基本价格图表中包含的值的转换而形成 。 通常,这些是不同的平均类型(图表的下一个点被计算为一定数量的先前价格值的平均值,例如移动平均值),关系(下一点是比较一定数量的先前价格的结果-它们的差,一段时间内的变化导数)或滞后(延迟)。 这些指标清楚地显示了价格变化统计信息中包含的一些非显而易见的信息,并且可以形成有关贸易订单的建议-买/卖。 指标至少具有一个可变参数,根据该参数的值将改变结果。 为了开立真实交易,通常由交易商决定结合使用几种指标以及其他信息。

技术分析的宗旨之一是“历史重演”:相似情况下的市场参与者行为大致相同,形成相似的价格变化动态。 很自然地认为,未来的市场行为将主要重复过去出现的模式。 根据这一陈述,投资者可以从可能的TIR参数中选择在过去一段时间内表现最佳的那些参数。

当在TIR参数的值上使用每个指标时,本文以二维表示形式构建交易绩效图。 但是实际上,我将构建一个三维表示形式以便同时评估订单执行中延迟对结果的影响,因此参数将为X轴(横坐标),延迟将为Y轴(纵坐标),结果将为Z轴(重复)。 这是评估“滑点”效果的一种尝试,不幸的是,这种情况经常发生。 我没有沿Y轴实际“滑移”,而是将BUY / SELL订单的执行推迟了1到5个周期。

如果在此图上突出显示全局最大值,并且图本身看起来像帽子(通常称为“正态分布”,但假定垂直轴具有严格的对称性),则圆锥,金字塔也适用-这意味着您可以为此选择一个特定的参数值,它将显示最高的结果,并使用此指标您可以尝试交易。 如果性能图表(取决于参数)类似于“栅栏”,则不可能选择最佳参数值,并且在贸易中使用此TIR毫无意义。

可以说,在本文中,我仅计算指标的“命中百分比”。 问题是,要评估您可以“赚多少”,我不敢。

成功完成所述测试是有效交易的必要条件之一,但还不够。

供参考...与技术分析相反,基本面分析(FA)是一个术语,用于指定基于财务和生产绩效指标分析来预测工具的市场(交易)价值的方法。
在大多数情况下, FA的“内在价值”与公司的股价不一致,后者是由股票市场的供求比率决定的。 在公司活动中使用FA的投资者主要对公司股票的“内在价值”超过交易所中股票价格的情况感兴趣。 这些股票被认为价值被低估,这意味着它们的价格将会上涨,并且它们是潜在的投资目标。

沃伦·巴菲特(Warren Buffett)是使用基本面分析的最著名投资者之一。

查看预告片: https : //www.youtube.com/watch?v=SqE8fnvmV1Y

因此,我们有两种截然相反的方法-TAFA
FA通常使长期投资者感兴趣,TA-短期和中期,并且在交易对象的交易对象不感兴趣时​​,用于投机性交易。

本文的目标是两个...

除了上述有关TAFA的讨论之外,我还想探索并展示Oracle数据库执行技术市场指标计算的功能
我将这些机会提供给读者判断。

如果您决定重复我的计算,请从文章底部链接的GitHub下载代码。 在版本12.2.0.1上验证的代码

首先创建共享对象。 第一个是表格和视图。 下面的同一文件中是一个事务建模包。

第二步是创建执行TIR计算的功能。

第三步是计算。

用于计算所有TIR的所有函数将返回带有以下字段的游标:STOCK_NAME,ADATE,ACLOSE(日收盘价),AACTION(买卖订单)

该软件包包含三个表格建模函数,这些函数从上述TIR计算函数中获取输入光标,偏移量(订单执行中的延迟,滞后)和初始资本,默认情况下为1000美元。 包函数的调用方式如下:

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); 

其中XXXXXXXX是TIR的名称。

所有功能都将根据利润的全部再投资(不包括交易成本和税费,并且不包括通货膨胀和折扣)计算交易结果。

第一个函数TRADE_LOG形成简化的交易者的交易日志。 该功能使您可以跟踪整个交易链。 如果期末投资者是“有价证券”,则要计算货币余额(财务结果),该函数会模拟以最后收盘价出售所有有价证券,并在IN_STOCK字段中形成相应的标记。

第二个函数CALC_ACTIONS返回与调用的TIR计算游标相同的列,并添加以下列: AACTION_LAG (带偏移量的订单), BALANCE_CURRENCY (交易者的现金帐户余额), BALANCE_CURRENCY (未BALANCE_CURRENCY交易的工具数量)。 根据AACTION_LAG字段的值,模拟以收盘价进行的购买或出售,因此,货币余额和未平仓头寸的数量也会发生变化。

在每种工具的最后一行中,您可以看到每种工具的交易结果以及上一个功能,如果投资者是“证券”,则可以模拟出售以计算外币余额

第三个函数CALC_ACTIONS_TOTALS与第二个函数相同,但仅返回最后一行-每个工具的交易结果。 它将用于建模。

下载资料


给出了以下市场和指数的计算:S&P500,NYSE,布伦特,BTCUSD,EURUSD。
前四个是从Yahoo Finance下载的,最后一个是从另一个来源下载的。 来自其他来源的课程的计算结果可能会有所不同。

请注意,每种乐器的课程时间是不同的,即:

  • S&P500-03/01/1950 ... 29/01/2019,69岁;
  • 纽约-1965年12月31日至2019年3月22日,54岁;
  • Brent-17/05/1991 ... 06/02/2019,28岁;
  • BTCUSD-16/07/2010 ... 29/01/2019,9岁;
  • EURUSD-16/02/2001 ... 27/05/2019,18岁。

因此,不可能将工具的获利能力进行相互比较,但是可以使用不同的指标来比较每种工具的获利能力。

下载文件(SQL * Loader)也可以从GitHub底部的链接中获取。

移动平均线


至少有三种主要的移动平均线:

  • 线性(简单移动平均线,SMA),
  • 指数移动平均线(EMA)和
  • 线性加权(加权移动平均线,WMA)。

它们的组成部分重量不同。 对于线性移动平均值,权重是相等的;对于指数加权和线性加权的权重,随着组件远离窗口右边缘的距离呈指数或线性移动,权重减小。

线性移动平均值是最容易计算的。 在Oracle中,这是函数avg (VALUE) over (partition by STOCK_NAME order by ADATE rows between 9 preceding and current row) -移动平均值,其平均窗口为10个值。

线性移动平均值具有缺点。 首先,这些均值对市场逆转的反应缓慢。 由于对许多值进行了平均,每个值都赋予了相等的权重,因此平均响应通常在资产价格反转后的多个时间范围内发生。

同样,线性移动平均值也不是很有效,因为它对信号进行了两次响应:当指示器进入滑动窗口并离开滑动窗口时。 其余部分仅对指标的输入做出反应,并在您从窗口的右边缘向左移动时将其平滑地从计算中删除。

在计算TIR时 ,将使用所有三种类型的移动平均值。 对于本文中的指数加权和线性加权,开发了汇总函数EMAWMA ,它们以分析形式使用。 另外,可以通过递归或模型(短语MODEL )计算这些移动平均值。

在Oracle数据库中,仅通过分析来计算EMA和WMA,而无需递归或模型化,显然是不可能的。

但是对于移动平均线仍然有所保留:

  • 平均周期越短,该方法对转弯反应越敏感,则发出错误信号的可能性就越大;
  • 平均周期越短,产生的信号越多,交易开销就越大,这会变得非常重要。

技术市场指标


对于几乎所有指标,将给出几种计算方法:CALC-使用PL / SQL代码进行计算,SIMP-由一名操作员或RECU计算-通过递归计算,AGRF-使用聚合函数进行计算,MODE-通过模型进行计算。

有理由开发几种方法。 首先,通过使用几种方法计算TIR并比较指标,如果指标相同,则可以确保计算正确(考虑了舍入和处理NULL和“ 0”值的不同方法)。 在本文中,我将比较不同方法的样本的哈希值,从而确保所有算法都匹配位并进行相同的处理。

我相信Oracle需要开始使用SIMP方法开发TIR-由一位运营商进行计算。 完成此操作后,预言者的脑海中有了计划和计算算法,可以轻松地将其转移到PL / SQL或另一种过程语言。

我注意到这里的PL / SQL的CALC计算方法比SIMP方法(使用一个运算符)要快,如果整个计算可以沿着光标进行一次。 但是,如果要进行计算,则必须创建临时表或集合,或者在游标上传递1个以上的游标-我认为“单操作符”方法将变得更快且资源占用更少。

对于所有方法,包括SIMP(“一个运算符”)方法,我都将运算符置于函数中,以便可以使用参数调用计算以选择最佳值。

给出了七个TIR的计算:移动平均线的交点(EMASIMPLE),黄金和死亡十字架(CROSSES),余额交易量(OBV),凯尔特纳通道(KELTNER),价格和交易量趋势(PVT),军备动向指示器(EMV) ),商品渠道指数(CCI)。

对于这两篇文章的七个指标,将有一个参数“平均窗口大小”,第二个参数-移动(滞后)。 班次变化表明您需要推迟多少条执行买入/卖出定单-移动多少收盘价来平仓价(所有订单均以该条收盘价为准)。 这类似于“滑点”,但不完全是“滑点”。 延误通常不利于客户,而我们的滞后结果可能既不利于客户,也不利于客户。 但是,对于某些指标使用1到5 bar的滞后建模显示滑移对结果有重大影响。 对于某些指标,滞后和滑移并不那么重要。

SIMP(“单一操作员”)和RECU(“递归”) MATCH_RECOGNIZE根据所计算的TIR进入/退出指定范围或相对于其移动平均线的行为,主动使用短语MATCH_RECOGNIZE生成买/卖交易信号。

有关所有TIR的详细说明,请参见Wikipedia或Robert Colby的书《技术市场指标百科全书》。

指数移动平均线的交点


相交指数移动平均值的方法是最简单的TIR

该方法包括:如果价格值超过其自下而上的指数移动平均线(ESA),则买入(建仓); 如果价格从上至下穿越其ESS,则卖出(平仓)。

本文不考虑空头头寸以及一般的保证金交易。

将来,可以将此指标用作与其他指标进行比较的标准。 与该TIR进行比较优于与“买入并持有”策略进行比较,因为该策略在下跌的市场中无法盈利。

唯一的TIR参数是移动平均线的长度。

使用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; 


由一个递归运算符进行计算

 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; 


使用短语MODEL进行计算
函数文字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; 



使用聚合函数进行计算
EMA聚合函数和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; 



将计算结果与一个参数进行比较:

 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')); 

所有四种方法的所有哈希必须匹配。

如果哈希值不匹配,则可以使用此运算符准确找出差异的形成位置(用您要比较的函数的名称代替):

 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 --where sys_op_map_nonnull (a.ACLOSE) <> sys_op_map_nonnull (b.ACLOSE) -- or sys_op_map_nonnull (a.IND_VALUE) <> sys_op_map_nonnull (b.IND_VALUE) -- or sys_op_map_nonnull (a.AACTION) <> sys_op_map_nonnull (b.AACTION) order by 1, 2; ; 

参数选择

TIR本身使用一个参数,为此,对于所有其他TIR,我将其在1到200的范围内进行更改,但是为了计算三维图像的依赖性和滞后性,我们将引入第二个参数,其范围是1到5。

操作员打开200 * 5 = 1000个游标,因此可能需要更改Oracle OPEN_CURSORS

下面的查询执行数字从1到200的表与数字从1到5的表的笛卡尔积,并且笛卡尔通过调用表函数HABR_TRADEMODELLING_P.CALC_ACTIONS_TOTALS将所有乘积相乘。

在MATLAB中进行一些进一步的操作后,我们将进一步获得200 * 5矩阵,其中在矩阵单元格中,两个参数中每个参数的每个值都有一个总资本值。 接下来在MATLAB中,我们构建一个三维图片。

 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 --+ parallel(8) 'HABR_MARKETINDEXES_EMASIMPLE_F_CALC', 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 from TP1 cross join TP2 cross join table (HABR_TRADEMODELLING_P.CALC_ACTIONS_TOTALS (cursor (select STOCK_NAME, ADATE, ACLOSE, AACTION from table (HABR_MARKETINDEXES_EMASIMPLE_F_CALC (PARM1))), PARM2)) ; commit; 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 --+ parallel(8) 'HABR_MARKETINDEXES_EMASIMPLE_F_CALC', 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 from TP1 cross join TP2 cross join table (HABR_TRADEMODELLING_P.CALC_ACTIONS_TOTALS (cursor (select STOCK_NAME, ADATE, ACLOSE, AACTION from table (HABR_MARKETINDEXES_EMASIMPLE_F_CALC (PARM1))), PARM2)) ; commit; 

本文中的所有计算都是缓慢进行的,最多需要20分钟,这是由于打开了大量游标造成的。

我还开发了一种使用一个光标的快速仿真方法,而没有打开1000个光标,但是它是如此庞大,以至于需要花费本文的一半。 因此,我不会把他带到这里。

对移动平均线的相交进行建模的结果(所有图形均可单击):



图表的第二行与第一行相同,但是图表略微旋转,具有不同滞后的图表依次排列。 这使您可以评估滞后对结果的影响

通常,指标对滞后不是很敏感。 对于S&P500和NYSE市场, TIR参数需要选择的越多越好。 对于布伦特市场-大约25。在其他两个市场中,盈利能力与参数之间没有关联。

致命和金色十字架


在Oracle上的实现中,该指标与上一个指标非常相似,这里仅使用两个移动平均值,而没有一个。 因此,我将只给出一个计算选项。

Wiki描述了Ichimoku指标。 这是一个复杂的指标。 “十字”是组成部分之一。 但是该指标在Wiki上描述得很差,特别是请注意,Tenkan和Kijun行用完全不同的词来描述,尽管实际上它们是相同的,但是使用不同的时期。

在Robert Colby的书中,也没有描述该指标。

日本分析师称其为均线的交集,当短期均线从底部向上穿过长期线时称为金叉(Golden Cross),而相反的情况则是当短期均线从顶部至底部穿越长期线时为死线。

作者注意到,该指标在“美国石油的期货形成了一个“致命的十字架””一文中进行了描述,并开始使用Google对其进行描述和使用。

该指标在股市中被认为是严重的,部分原因是它很少发出信号。

最常用的是50和200周期移动平均值。

在对下面的性能进行建模时,我们将采用长均线的周期等于短均线的四倍周期,并模拟从1到200天的短线长度(对于长线则为4到800天)。

用于在GitHub上进行计算的代码。



该指标对滞后不是很敏感。 对于S&P500市场,最大交易日为48天(长SS期为192)和98天(长SS期为392)。 请注意,第一个最大值非常接近数字50x200。 可以假设,如果您选择的参数比其他市场参与者少1和2,则可以尝试在此指标上单独击败它们。

纽约证券交易所有4个高点。 在布伦特和BTCUSD市场中,该指标不起作用。
对于EURUSD市场,对于短SS,也应选择小于50的参数。 但是该指标并未在这个市场上产生利润。 它只能用作其他指标。

平衡量,平衡量,动量量(OBV)


OBV指标是在市场增长的情况下带加号的累积移动平均交易量,在市场下降的情况下带减号的累计移动平均交易量。

在这里,我们将使用这种方式来解释指标的价值:当OBV从下至上穿越其移动平均线时买入,当OBV从上至下穿越其移动平均线时卖出。

Wiki或Colby上的更多内容



在标准普尔500指数市场中,该指标对延迟(滞后)非常敏感,但是您可以尝试根据“越多越好”的原则选择参数,从而获得一定的收益。 在纽约证券交易所,无法实现盈利。 在布伦特市场中,可以从20到100中选择一个参数值。在BTCUSD市场中,没有明确的线性关系,但是选择小于40的参数值是不切实际的。 对于EURUSD市场,必须选择“越多越好”的参数值,但无法实现获利能力。

凯特纳频道


TIR由移动平均价格之上和之下的两个波段组成,其宽度确定为该时期平均价格变化的一部分。该价格是典型价格。

指标线的中线是典型价格的简单移动平均线。

指标的上下线与中线之间的距离等于日交易范围的简单移动平均线。

在我们的计算中,TIR信号将形成如下:如果价格越过上限,则买入;如果价格越过下部,则卖出。



标准普尔500指数和纽约证交所市场均处于高位。在布伦特市场上,结果不依赖参数,所有交易都处于亏损状态。BTCUSD市场存在高点,但窄幅,很难进入。在EURUSD市场中,结果取决于参数。

价格和数量趋势,价格和数量趋势,价格–数量趋势,PVT


PVT指标的值表示当前交易量乘以相对于上一时期的减少的价格增长的乘积的总和。

我们将在此处生成如下交易信号:当PVT从底部向上穿过其移动平均线时,买入;当PVT从顶部向下穿过其移动平均线时,卖出。Wiki上的

更多内容科尔比没有找到。对于S&P500,参数值“越大越好”,几乎不依赖于纽约证券交易所,对于布伦特而言,最大值在50附近,在BTCUSD上,该指标仅在最小滞后(1-2)和最小参数值(最大50)下有效。 ,对于EURUSD的依赖程度正在增加。





轻松移动,手臂轻松移动值,EMV


TIR EMV是市场价格变化的容易程度的数字表示。价格变化越强,营业额越低,市场上涨或下跌的可能性就越大。

在这里,我们将形成如下交易订单:当移动平均EMV上升到零以上时买入;当移动平均EMV下降到零以下时卖出。

有关Wiki或Colby的更多信息标普和纽约证交所市场高位;在布伦特市场,该指标在广泛的参数值中有效。在BTCUSD和EURUSD市场中,该指标无效。





商品渠道指数,CCI


TIR CCI是基于对一段时间内价格偏离其平均值的当前价格变化以及该参数的平均绝对值的指标。TIR适用于任何金融市场。

我们将形成如下交易订单:当CCI高于100时买入,当CCI低于100时卖出。

有关更多信息,请访问Wiki或Colby。在标普500,纽约证券交易所,布伦特市场,交易结果不依赖于参数值。依赖BTCUSD市场(两个明显的高点),您可以尝试在实际交易中抓住它。在欧元兑美元市场,结果的指标不会出现。github上的可用资源






创建通用对象,上传数据,或者是我的(如我之前所说,除最后一个市场以外的所有市场都来自Yahoo Finance),或者是您自己的,创建用于计算,计算交易绩效数据的函数(如我之前所说,最多计算20分钟的每个指标) 。

关于TIR的一般结论是仅使用一项利润指标是不可能的。不同的指标在不同的市场上具有不同的效力。不排除使用多个调整良好的指标以及其他外部信息获利的可能性。

可选的:

分析了本文未包括的另外三个指标。但是他们没有得到任何结果。也许他们的研究将继续。通常,在Oracle数据库上

执行TIR和财务活动的计算和复杂建模非常方便。

Source: https://habr.com/ru/post/zh-CN455050/


All Articles