TechTrend.cpp
上传用户:zhanglf88
上传日期:2013-11-19
资源大小:6036k
文件大小:10k
源码类别:

金融证券系统

开发平台:

Visual C++

  1. /*
  2. Cross Platform Core Code.
  3. Copyright(R) 2001-2002 Balang Software.
  4. All rights reserved.
  5. */
  6. #include "StdAfx.h"
  7. #include "../Include/Stock.h"
  8. #include "../Include/Technique.h"
  9. #ifdef _DEBUG
  10. #undef THIS_FILE
  11. static char THIS_FILE[] = __FILE__;
  12. #endif
  13. #ifdef _DEBUG
  14. #define new DEBUG_NEW
  15. #endif
  16. //////////////////////////////////////////////////////////////////////
  17. // CMACD
  18. CMACD::CMACD( )
  19. {
  20. SetDefaultParameters( );
  21. }
  22. CMACD::CMACD( CKData * pKData )
  23. : CTechnique( pKData )
  24. {
  25. SetDefaultParameters( );
  26. }
  27. CMACD::~CMACD()
  28. {
  29. Clear( );
  30. }
  31. void CMACD::SetDefaultParameters( )
  32. {
  33. m_nEMA1Days = 12;
  34. m_nEMA2Days = 26;
  35. m_nDIFDays = 9;
  36. m_itsDeviateOnBottom = ITS_BUYINTENSE;
  37. m_itsDeviateOnTop = ITS_SELLINTENSE;
  38. m_itsGoldenFork = ITS_BUY;
  39. m_itsDeadFork = ITS_SELL;
  40. }
  41. void CMACD::AttachParameters( CMACD & src )
  42. {
  43. m_nEMA1Days = src.m_nEMA1Days;
  44. m_nEMA2Days = src.m_nEMA2Days;
  45. m_nDIFDays = src.m_nDIFDays;
  46. m_itsDeviateOnBottom = src.m_itsDeviateOnBottom;
  47. m_itsDeviateOnTop = src.m_itsDeviateOnTop;
  48. m_itsGoldenFork = src.m_itsGoldenFork;
  49. m_itsDeadFork = src.m_itsDeadFork;
  50. }
  51. BOOL CMACD::IsValidParameters( )
  52. {
  53. return ( VALID_DAYS(m_nEMA1Days) && VALID_DAYS(m_nEMA2Days) && VALID_DAYS(m_nDIFDays)
  54. && VALID_ITS(m_itsDeviateOnBottom) && VALID_ITS(m_itsDeviateOnTop)
  55. && VALID_ITS(m_itsGoldenFork) && VALID_ITS(m_itsDeadFork) );
  56. }
  57. void CMACD::Clear( )
  58. {
  59. CTechnique::Clear( );
  60. }
  61. int CMACD::GetSignal( int nIndex, UINT * pnCode )
  62. {
  63. if( pnCode ) *pnCode = ITSC_NOTHING;
  64. PrepareCache( 0, -1, FALSE );
  65. int nMaxDays = max( max(m_nEMA1Days,m_nEMA2Days) , m_nDIFDays );
  66. double dLiminalLow = 0, dLiminalHigh = 0;
  67. if( !IntensityPrepare( nIndex, pnCode, nMaxDays, ITS_GETMINMAXDAYRANGE, &dLiminalLow, &dLiminalHigh, 0.309, 0.682 ) )
  68. return ITS_NOTHING;
  69. double dEMA1, dEMA2, dDIF, dDEA;
  70. if( !Calculate( &dEMA1, &dEMA2, &dDIF, &dDEA, nIndex, FALSE ) )
  71. return ITS_NOTHING;
  72. if( IsDeviateOnBottom( nIndex, m_pdCache3, m_pdCache4 ) )
  73. { // 底背离
  74. if( pnCode ) *pnCode = ITSC_DEVIATEONBOTTOM;
  75. return m_itsDeviateOnBottom;
  76. }
  77. if( IsDeviateOnTop( nIndex, m_pdCache3, m_pdCache4 ) )
  78. { // 顶背离
  79. if( pnCode ) *pnCode = ITSC_DEVIATEONTOP;
  80. return m_itsDeviateOnTop;
  81. }
  82. if( dDIF < dLiminalLow && dDEA < dLiminalLow && IsGoldenFork( nIndex, m_pdCache3, m_pdCache4 ) )
  83. { // 低位金叉
  84. if( pnCode ) *pnCode = ITSC_GOLDENFORK;
  85. return m_itsGoldenFork;
  86. }
  87. if( dDIF > dLiminalHigh && dDEA > dLiminalHigh && IsDeadFork( nIndex, m_pdCache3, m_pdCache4 ) )
  88. { // 高位死叉
  89. if( pnCode ) *pnCode = ITSC_DEADFORK;
  90. return m_itsDeadFork;
  91. }
  92. if( dDIF < dLiminalLow && dDEA < dLiminalLow )
  93. { // 低位
  94. if( pnCode ) *pnCode = ITSC_GOLDENFORK;
  95. return m_itsGoldenFork;
  96. }
  97. if( dDIF > dLiminalHigh && dDEA > dLiminalHigh )
  98. { // 高位
  99. if( pnCode ) *pnCode = ITSC_DEADFORK;
  100. return m_itsDeadFork;
  101. }
  102. return ITS_NOTHING;
  103. }
  104. /***
  105. EMA  = 短期移动均值
  106. EMA2 = 长期移动均值
  107. DIF  = 短期移动均值 - 长期移动均值
  108. DEA  = DIF的移动平滑值
  109. 柱状线值 = DIF - DEA
  110. */
  111. BOOL CMACD::GetMinMaxInfo(int nStart, int nEnd, double *pdMin, double *pdMax )
  112. {
  113. STT_ASSERT_GETMINMAXINFO( m_pKData, nStart, nEnd );
  114. double dMin = 0, dMax = 0;
  115. double dEMA1 = 0, dEMA2 = 0, dDIF = 0, dDEA = 0;
  116. BOOL bFirst = TRUE;
  117. for( int k=nStart; k<=nEnd; k++ )
  118. {
  119. if( Calculate( &dEMA1, &dEMA2, &dDIF, &dDEA, k, !bFirst ) )
  120. {
  121. if( bFirst ) { dMin = dDIF; dMax = dDIF; }
  122. if( dDIF < dMin ) dMin = dDIF;
  123. if( dDEA < dMin ) dMin = dDEA;
  124. if( 2*(dDIF-dDEA) < dMin ) dMin = 2*(dDIF-dDEA); // WARNING: different
  125. if( dDIF > dMax ) dMax = dDIF;
  126. if( dDEA > dMax ) dMax = dDEA;
  127. if( 2*(dDIF-dDEA) > dMax ) dMax = 2*(dDIF-dDEA); // WARNING: different
  128. bFirst = FALSE;
  129. }
  130. }
  131. dMin -= fabs(dMin)*0.02;
  132. dMax += fabs(dMax)*0.02;
  133. if( fabs(dMin) < 1e-4 )
  134. dMin = -0.01;
  135. if( fabs(dMax) < 1e-4 )
  136. dMax = 0.01;
  137. if( dMax - dMin < 0.03 )
  138. dMax = dMin + 0.05;
  139. if( pdMin ) *pdMin = dMin;
  140. if( pdMax ) *pdMax = dMax;
  141. return TRUE;
  142. }
  143. BOOL CMACD::Calculate( double *pdEMA1, double *pdEMA2, double *pdDIF, double *pdDEA,
  144. int nIndex, BOOL bUseLast )
  145. {
  146. STT_ASSERT_CALCULATE1( m_pKData, nIndex );
  147. if( m_nEMA1Days > nIndex+1 || m_nEMA2Days > nIndex+1 || m_nDIFDays > nIndex+1 )
  148. return FALSE;
  149. if( LoadFromCache( nIndex, pdEMA1, pdEMA2, pdDIF, pdDEA ) )
  150. return TRUE;
  151. // Calculate EMA1, EMA2, DIF, DEA
  152. double dEMA1New = 0, dEMA2New = 0, dDIFNew = 0, dDEANew = 0;
  153. if( bUseLast && pdEMA1 && pdEMA2 && pdDEA )
  154. {
  155. dEMA1New = (*pdEMA1)*(m_nEMA1Days-1)/(m_nEMA1Days+1) + 2 * m_pKData->MaindataAt(nIndex) /(m_nEMA1Days+1);
  156. dEMA2New = (*pdEMA2)*(m_nEMA2Days-1)/(m_nEMA2Days+1) + 2 * m_pKData->MaindataAt(nIndex) /(m_nEMA2Days+1);
  157. dDIFNew = dEMA1New-dEMA2New;
  158. dDEANew = (*pdDEA)*(m_nDIFDays-1)/(m_nDIFDays+1) + 2 * dDIFNew/(m_nDIFDays+1);
  159. }
  160. else
  161. {
  162. double factor1 = 1, factor2 = 1;
  163. for( int k=nIndex; k > 0; k-- )
  164. {
  165. factor1 *= ((double)(m_nEMA1Days-1))/(m_nEMA1Days+1);
  166. factor2 *= ((double)(m_nEMA2Days-1))/(m_nEMA2Days+1);
  167. if( factor1 < 0.001 && factor2 < 0.001 )
  168. break;
  169. }
  170. dEMA1New = m_pKData->MaindataAt(k);
  171. dEMA2New = m_pKData->MaindataAt(k);
  172. dDIFNew = dEMA1New - dEMA2New;
  173. dDEANew = dDIFNew;
  174. for( ; k<=nIndex; k++ )
  175. {
  176. dEMA1New = dEMA1New * (m_nEMA1Days-1)/(m_nEMA1Days+1) + 2 * m_pKData->MaindataAt(k) /(m_nEMA1Days+1);
  177. dEMA2New = dEMA2New * (m_nEMA2Days-1)/(m_nEMA2Days+1) + 2 * m_pKData->MaindataAt(k) /(m_nEMA2Days+1);
  178. dDIFNew = dEMA1New - dEMA2New;
  179. dDEANew = dDEANew * (m_nDIFDays-1)/(m_nDIFDays+1) + 2 * dDIFNew / (m_nDIFDays+1);
  180. }
  181. }
  182. if( pdEMA1 ) *pdEMA1 = dEMA1New;
  183. if( pdEMA2 ) *pdEMA2 = dEMA2New;
  184. if( pdDIF ) *pdDIF = dDIFNew;
  185. if( pdDEA ) *pdDEA = dDEANew;
  186. StoreToCache( nIndex, pdEMA1, pdEMA2, pdDIF, pdDEA );
  187. return TRUE;
  188. }
  189. //////////////////////////////////////////////////////////////////////
  190. // CMIKE
  191. CMIKE::CMIKE( )
  192. {
  193. SetDefaultParameters( );
  194. }
  195. CMIKE::CMIKE( CKData * pKData )
  196. : CTechnique( pKData )
  197. {
  198. SetDefaultParameters( );
  199. }
  200. CMIKE::~CMIKE()
  201. {
  202. Clear( );
  203. }
  204. void CMIKE::SetDefaultParameters( )
  205. {
  206. m_nDays = 12;
  207. }
  208. void CMIKE::AttachParameters( CMIKE & src )
  209. {
  210. m_nDays = src.m_nDays;
  211. }
  212. BOOL CMIKE::IsValidParameters( )
  213. {
  214. return VALID_DAYS( m_nDays );
  215. }
  216. void CMIKE::Clear( )
  217. {
  218. CTechnique::Clear( );
  219. }
  220. /***
  221. H:最高价 L:最低价 C:收盘价
  222. TP = (H+L+C)÷3
  223. 第一条窄通道的上下限计算如下:
  224. 弱阻力WR=TP+(TP-L) 弱支撑WS=TP-(H-TP)
  225. 第二条通道的上下限计算如下:
  226. 中阻力MR=TP+(H-L) 中支撑MS=TP-(H-L)
  227. 第三条阔通道的上下限计算如下:
  228. 强阻力SR=H+(H-L) 强支撑SS=L-(H-L)
  229. */
  230. BOOL CMIKE::CalculateMIKE( double *pWR, double *pMR, double *pSR,
  231. double *pWS, double *pMS, double *pSS, int nIndex )
  232. {
  233. STT_ASSERT_CALCULATE1( m_pKData, nIndex );
  234. if( m_nDays * 2 > nIndex + 1 )
  235. return FALSE;
  236. double TP = (m_pKData->ElementAt(nIndex).m_fHigh + m_pKData->ElementAt(nIndex).m_fLow + m_pKData->ElementAt(nIndex).m_fClose)/3.0;
  237. double minN = 0, min2N = 0, maxN = 0, max2N = 0;
  238. for( int k=nIndex; k>=0; k -- )
  239. {
  240. KDATA kd = m_pKData->ElementAt(k);
  241. if( nIndex-k < m_nDays )
  242. {
  243. if( nIndex == k ) { minN = kd.m_fLow; maxN = kd.m_fHigh; }
  244. if( kd.m_fLow < minN ) minN = kd.m_fLow;
  245. if( kd.m_fHigh > maxN ) maxN = kd.m_fHigh;
  246. }
  247. if( nIndex-k < m_nDays*2 )
  248. {
  249. if( nIndex == k ) { min2N = kd.m_fLow; max2N = kd.m_fHigh; }
  250. if( kd.m_fLow < min2N ) min2N = kd.m_fLow;
  251. if( kd.m_fHigh > max2N ) max2N = kd.m_fHigh;
  252. }
  253. else
  254. {
  255. break;
  256. }
  257. }
  258. if( pWR ) *pWR = ( TP + (TP - minN) ) ;
  259. if( pMR ) *pMR = ( TP + (maxN - minN) ) ;
  260. if( pSR ) *pSR = ( TP + (max2N - minN) ) ;
  261. if( pWS ) *pWS = ( TP - (maxN - TP) ) ;
  262. if( pMS ) *pMS = ( TP - (maxN - minN) ) ;
  263. if( pSS ) *pSS = ( TP - (maxN - min2N) ) ;
  264. return TRUE;
  265. }
  266. //////////////////////////////////////////////////////////////////////
  267. // CPSY
  268. CPSY::CPSY( )
  269. {
  270. SetDefaultParameters( );
  271. }
  272. CPSY::CPSY( CKData * pKData )
  273. : CTechnique( pKData )
  274. {
  275. SetDefaultParameters( );
  276. }
  277. CPSY::~CPSY()
  278. {
  279. Clear( );
  280. }
  281. void CPSY::SetDefaultParameters( )
  282. {
  283. m_nDays = 12;
  284. m_itsSold = ITS_BUY;
  285. m_itsBought = ITS_SELL;
  286. }
  287. void CPSY::AttachParameters( CPSY & src )
  288. {
  289. m_nDays = src.m_nDays;
  290. m_itsSold = src.m_itsSold;
  291. m_itsBought = src.m_itsBought;
  292. }
  293. BOOL CPSY::IsValidParameters( )
  294. {
  295. return ( VALID_DAYS(m_nDays) && VALID_ITS(m_itsSold) && VALID_ITS(m_itsBought) );
  296. }
  297. void CPSY::Clear( )
  298. {
  299. CTechnique::Clear( );
  300. }
  301. int CPSY::GetSignal( int nIndex, UINT * pnCode )
  302. {
  303. if( pnCode ) *pnCode = ITSC_NOTHING;
  304. if( nIndex <= 0 )
  305. return ITS_NOTHING;
  306. double dPSY = 0, dPSYLast;
  307. if( !Calculate( &dPSYLast, nIndex-1, FALSE )
  308. || !Calculate( &dPSY, nIndex, FALSE ) )
  309. return ITS_NOTHING;
  310. if( dPSY < 30 && dPSY >= dPSYLast )
  311. { // 超卖
  312. if( pnCode ) *pnCode = ITSC_OVERSOLD;
  313. return m_itsSold;
  314. }
  315. if( dPSY > 70 && dPSY <= dPSYLast )
  316. { // 超买
  317. if( pnCode ) *pnCode = ITSC_OVERBOUGHT;
  318. return m_itsBought;
  319. }
  320. return ITS_NOTHING;
  321. }
  322. BOOL CPSY::GetMinMaxInfo(int nStart, int nEnd,
  323.    double *pdMin, double *pdMax )
  324. {
  325. if( pdMin ) *pdMin = 0;
  326. if( pdMax ) *pdMax = 100;
  327. return TRUE;
  328. }
  329. /***
  330.         N日内上涨的天数
  331. PSY = —————————— × 100
  332.               N
  333. */
  334. BOOL CPSY::Calculate( double * pValue, int nIndex, BOOL bUseLast )
  335. {
  336. STT_ASSERT_CALCULATE1( m_pKData, nIndex );
  337. if( m_nDays > nIndex )
  338. return FALSE;
  339. if( LoadFromCache( nIndex, pValue ) )
  340. return TRUE;
  341. double UD = 0;
  342. int nCount = 0;
  343. for( int k=nIndex; k>=1; k-- )
  344. {
  345. if( m_pKData->MaindataAt(k) > m_pKData->MaindataAt(k-1) )
  346. UD += 1;
  347. nCount ++;
  348. if( nCount == m_nDays )
  349. {
  350. if( pValue ) *pValue = UD * 100 / m_nDays;
  351. StoreToCache( nIndex, pValue );
  352. return TRUE;
  353. }
  354. }
  355. return FALSE;
  356. }