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

金融证券系统

开发平台:

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. // CCYO
  18. CCYO::CCYO( )
  19. {
  20. SetDefaultParameters( );
  21. }
  22. CCYO::CCYO( CKData * pKData )
  23. : CTechnique( pKData )
  24. {
  25. SetDefaultParameters( );
  26. }
  27. CCYO::~CCYO()
  28. {
  29. Clear( );
  30. }
  31. void CCYO::SetDefaultParameters( )
  32. {
  33. m_adwMTMDays.RemoveAll();
  34. m_adwMTMDays.Add( 9 );
  35. m_adwMTMDays.Add( 12 );
  36. m_adwMTMDays.Add( 18 );
  37. m_adwMTMDays.Add( 24 );
  38. m_nMADays = 6;
  39. m_itsGoldenFork = ITS_BUY;
  40. m_itsDeadFork = ITS_SELL;
  41. }
  42. void CCYO::AttachParameters( CCYO & src )
  43. {
  44. m_adwMTMDays.Copy( src.m_adwMTMDays );
  45. m_nMADays = src.m_nMADays;
  46. m_itsGoldenFork = src.m_itsGoldenFork;
  47. m_itsDeadFork = src.m_itsDeadFork;
  48. }
  49. BOOL CCYO::IsValidParameters( )
  50. {
  51. STT_VALID_DAYSARRAY( m_adwMTMDays );
  52. return ( VALID_DAYS(m_nMADays) && VALID_ITS(m_itsGoldenFork) && VALID_ITS(m_itsDeadFork) );
  53. }
  54. void CCYO::Clear( )
  55. {
  56. CTechnique::Clear( );
  57. }
  58. int CCYO::GetSignal( int nIndex, UINT * pnCode )
  59. {
  60. if( pnCode ) *pnCode = ITSC_NOTHING;
  61. int nMaxDays = AfxGetMaxDays( m_adwMTMDays )+m_nMADays;
  62. double dLiminalLow = 0, dLiminalHigh = 0;
  63. if( !IntensityPrepare( nIndex, pnCode, nMaxDays, ITS_GETMINMAXDAYRANGE, &dLiminalLow, &dLiminalHigh, 0.2, 0.6 ) )
  64. return ITS_NOTHING;
  65. if( nIndex <= 1 )
  66. return ITS_NOTHING;
  67. double dValue;
  68. if( !Calculate( &dValue, nIndex, FALSE ) )
  69. return ITS_NOTHING;
  70. int nSignal = GetForkSignal( nIndex, m_itsGoldenFork, m_itsDeadFork, pnCode );
  71. if( dValue < dLiminalLow && nSignal == m_itsGoldenFork )
  72. { // 低位金叉
  73. if( pnCode ) *pnCode = ITSC_GOLDENFORK;
  74. return m_itsGoldenFork;
  75. }
  76. if( dValue > dLiminalHigh && nSignal == m_itsDeadFork )
  77. { // 高位死叉
  78. if( pnCode ) *pnCode = ITSC_DEADFORK;
  79. return m_itsDeadFork;
  80. }
  81. return ITS_NOTHING;
  82. }
  83. BOOL CCYO::GetMinMaxInfo(int nStart, int nEnd,
  84.    double *pdMin, double *pdMax )
  85. {
  86. return AfxGetMinMaxInfo2( nStart, nEnd, pdMin, pdMax, this );
  87. }
  88. /***
  89.        9日MTM + 12日MTM×2 + 18日MTM×3 + 24日MTM×4
  90. CYO = ------------------------------------------------
  91.                            10
  92. */
  93. BOOL CCYO::Calculate( double * pValue, int nIndex, BOOL bUseLast )
  94. {
  95. STT_ASSERT_CALCULATE1( m_pKData, nIndex );
  96. if( LoadFromCache( nIndex, pValue ) )
  97. return TRUE;
  98. UINT nMaxDays = AfxGetMaxDays( m_adwMTMDays );
  99. if( (int)nMaxDays > nIndex )
  100. return FALSE;
  101. double dValue = 0;
  102. int nCount = 0;
  103. for( int m=0; m<m_adwMTMDays.GetSize(); m++ )
  104. {
  105. if( int(nIndex-m_adwMTMDays[m]) < 0 )
  106. return FALSE;
  107. double dMTM = 100;
  108. if( m_pKData->MaindataAt(nIndex-m_adwMTMDays[m]) > 0 )
  109. dMTM = 100. * m_pKData->MaindataAt(nIndex) / m_pKData->MaindataAt(nIndex-m_adwMTMDays[m]);
  110. dValue += dMTM*(m+1);
  111. nCount += (m+1);
  112. }
  113. if( nCount <= 0 )
  114. return FALSE;
  115. dValue = dValue / nCount;
  116. if( pValue )
  117. *pValue = dValue;
  118. StoreToCache( nIndex, pValue );
  119. return TRUE;
  120. }
  121. /***
  122. 计算CYO及其移动平均值
  123. */
  124. BOOL CCYO::Calculate( double * pValue, double * pMA, int nIndex, BOOL bUseLast )
  125. {
  126. return CalculateMA( pValue, pMA, nIndex, bUseLast, m_nMADays );
  127. }
  128. //////////////////////////////////////////////////////////////////////
  129. // CDCYO
  130. CDCYO::CDCYO( )
  131. {
  132. SetDefaultParameters( );
  133. }
  134. CDCYO::CDCYO( CKData * pKData )
  135. : CTechnique( pKData )
  136. {
  137. SetDefaultParameters( );
  138. }
  139. CDCYO::~CDCYO()
  140. {
  141. Clear( );
  142. }
  143. void CDCYO::SetDefaultParameters( )
  144. {
  145. m_adwMTMDays.RemoveAll();
  146. m_adwMTMDays.Add( 9 );
  147. m_adwMTMDays.Add( 12 );
  148. m_adwMTMDays.Add( 18 );
  149. m_adwMTMDays.Add( 24 );
  150. m_nMADays = 6;
  151. m_itsGoldenFork = ITS_BUY;
  152. m_itsDeadFork = ITS_SELL;
  153. }
  154. void CDCYO::AttachParameters( CDCYO & src )
  155. {
  156. m_adwMTMDays.Copy( src.m_adwMTMDays );
  157. m_nMADays = src.m_nMADays;
  158. m_itsGoldenFork = src.m_itsGoldenFork;
  159. m_itsDeadFork = src.m_itsDeadFork;
  160. }
  161. BOOL CDCYO::IsValidParameters( )
  162. {
  163. STT_VALID_DAYSARRAY( m_adwMTMDays );
  164. return ( VALID_DAYS(m_nMADays)
  165. && VALID_ITS(m_itsGoldenFork) && VALID_ITS(m_itsDeadFork) );
  166. }
  167. void CDCYO::Clear( )
  168. {
  169. CTechnique::Clear( );
  170. }
  171. int CDCYO::GetSignal( int nIndex, UINT * pnCode )
  172. {
  173. if( pnCode ) *pnCode = ITSC_NOTHING;
  174. int nMaxDays = AfxGetMaxDays( m_adwMTMDays )+m_nMADays;
  175. double dLiminalLow = 0, dLiminalHigh = 0;
  176. if( !IntensityPrepare( nIndex, pnCode, nMaxDays, ITS_GETMINMAXDAYRANGE, &dLiminalLow, &dLiminalHigh, 0.45, 0.55 ) )
  177. return ITS_NOTHING;
  178. if( nIndex <= 1 )
  179. return ITS_NOTHING;
  180. double dValue;
  181. if( !Calculate( &dValue, nIndex, FALSE ) )
  182. return ITS_NOTHING;
  183. int nSignal = GetForkSignal( nIndex, m_itsGoldenFork, m_itsDeadFork, pnCode );
  184. if( dValue < dLiminalLow && nSignal == m_itsGoldenFork )
  185. { // 低位金叉
  186. if( pnCode ) *pnCode = ITSC_GOLDENFORK;
  187. return m_itsGoldenFork;
  188. }
  189. if( dValue > dLiminalHigh && nSignal == m_itsDeadFork )
  190. { // 高位死叉
  191. if( pnCode ) *pnCode = ITSC_DEADFORK;
  192. return m_itsDeadFork;
  193. }
  194. return ITS_NOTHING;
  195. }
  196. BOOL CDCYO::GetMinMaxInfo(int nStart, int nEnd,
  197.    double *pdMin, double *pdMax )
  198. {
  199. return AfxGetMinMaxInfo2( nStart, nEnd, pdMin, pdMax, this );
  200. }
  201. /***
  202.        9日MTM + 12日MTM×2 + 18日MTM×3 + 24日MTM×4
  203. CYO = ------------------------------------------------
  204.                            10
  205. DCYO = CYO的m_nMADays日平均值
  206. */
  207. BOOL CDCYO::Calculate( double * pValue, int nIndex, BOOL bUseLast )
  208. {
  209. STT_ASSERT_CALCULATE1( m_pKData, nIndex );
  210. if( LoadFromCache( nIndex, pValue ) )
  211. return TRUE;
  212. UINT nMaxDays = AfxGetMaxDays( m_adwMTMDays );
  213. if( (int)nMaxDays > nIndex )
  214. return FALSE;
  215. int nMACount = 0;
  216. double dMA = 0;
  217. for( int k=nIndex; k>=0; k-- )
  218. {
  219. double dValue = 0;
  220. double nCount = 0;
  221. for( int m=0; m<m_adwMTMDays.GetSize(); m++ )
  222. {
  223. if( int(k-m_adwMTMDays[m]) < 0 )
  224. return FALSE;
  225. double dMTM = 100;
  226. if( m_pKData->MaindataAt(k-m_adwMTMDays[m]) > 0 )
  227. dMTM = 100. * m_pKData->MaindataAt(k) / m_pKData->MaindataAt(k-m_adwMTMDays[m]);
  228. dValue += dMTM*(m+1);
  229. nCount += (m+1);
  230. }
  231. if( nCount <= 0 )
  232. return FALSE;
  233. dValue = dValue / nCount;
  234. dMA += dValue;
  235. nMACount ++;
  236. if( nMACount >= m_nMADays )
  237. {
  238. dMA = dMA/m_nMADays;
  239. if( pValue )
  240. *pValue = dMA;
  241. StoreToCache( nIndex, pValue );
  242. return TRUE;
  243. }
  244. }
  245. return FALSE;
  246. }
  247. /***
  248. 计算DCYO及其移动平均值
  249. */
  250. BOOL CDCYO::Calculate( double * pValue, double * pMA, int nIndex, BOOL bUseLast )
  251. {
  252. return CalculateMA( pValue, pMA, nIndex, bUseLast, m_nMADays );
  253. }
  254. //////////////////////////////////////////////////////////////////////
  255. // CHSL
  256. CHSL::CHSL( )
  257. {
  258. SetDefaultParameters( );
  259. }
  260. CHSL::CHSL( CKData * pKData )
  261. : CTechnique( pKData )
  262. {
  263. SetDefaultParameters( );
  264. }
  265. CHSL::~CHSL()
  266. {
  267. Clear( );
  268. }
  269. double CHSL::GetMainChangeHand( DWORD dwMarket, CKData & kdata, int nIndexKD )
  270. {
  271. if( nIndexKD < 0 || nIndexKD >= kdata.GetSize() )
  272. return 0.0;
  273. KDATA kd = kdata.ElementAt(nIndexKD);
  274. // ignore dwMarket
  275. dwMarket = CStock::marketSHSE;
  276. CStock & stockMain = AfxGetStockMain( dwMarket );
  277. CStockInfo & infoMain = stockMain.GetStockInfo();
  278. CKData & kdataMain = stockMain.GetKData( kdata.GetKType() );
  279. int nIndexMain = kdataMain.GetIndexByDate( kd.m_date );
  280. if( nIndexMain < 0 || nIndexMain >= kdataMain.GetSize() )
  281. return 0.0;
  282. KDATA kdMain = kdataMain.ElementAt( nIndexMain );
  283. double dPriceAvg = 0.0;
  284. if( kdMain.m_fVolume > 1 )
  285. dPriceAvg = kdMain.m_fAmount / kdMain.m_fVolume;
  286. double dCapitalValue = 0.0;
  287. if( 0 == strcmp( STKLIB_CODE_MAIN, infoMain.GetStockCode() ) )
  288. {
  289. double dFactor = 5.85 * 1e8;
  290. CSPTime sptime;
  291. if( sptime.FromStockTime( kd.m_date, CKData::IsDayOrMin(kdata.GetKType()) ) )
  292. {
  293. CSPTime tm0(2004,5,19,0,0,0);
  294. CSPTimeSpan span = sptime - tm0;
  295. if( span.GetDays() < -3000 )
  296. {
  297. dFactor *= ( 1 - 0.08*3000.0/365.0);
  298. dFactor *= ( 1 - (-3000 - span.GetDays())/2000.0 );
  299. }
  300. else
  301. {
  302. dFactor *= ( 1 + 0.08*span.GetDays()/365.0 );
  303. }
  304. }
  305. dCapitalValue = dFactor * (kdMain.m_fClose+kdMain.m_fOpen+kdMain.m_fHigh+kdMain.m_fLow)/4;
  306. }
  307. else if( 0 == strcmp( STKLIB_CODE_MAINSZN, infoMain.GetStockCode() ) )
  308. {
  309. // 深证成指
  310. dCapitalValue = 0.41 * 1e8 * (kdMain.m_fClose+kdMain.m_fOpen+kdMain.m_fHigh+kdMain.m_fLow)/4;
  311. }
  312. double dChangeHand = 0.0;
  313. if( dCapitalValue > 1e-6 )
  314. dChangeHand = 100. * kdMain.m_fAmount / dCapitalValue;
  315. return dChangeHand;
  316. }
  317. void CHSL::SetDefaultParameters( )
  318. {
  319. m_nDays = 30;
  320. m_nMADays = 6;
  321. m_itsGoldenFork = ITS_BUY;
  322. m_itsDeadFork = ITS_SELL;
  323. }
  324. void CHSL::AttachParameters( CHSL & src )
  325. {
  326. m_nDays = src.m_nDays;
  327. m_nMADays = src.m_nMADays;
  328. m_itsGoldenFork = src.m_itsGoldenFork;
  329. m_itsDeadFork = src.m_itsDeadFork;
  330. }
  331. BOOL CHSL::IsValidParameters( )
  332. {
  333. return ( VALID_DAYS(m_nDays) && VALID_DAYS(m_nMADays) && VALID_ITS(m_itsGoldenFork) && VALID_ITS(m_itsDeadFork) );
  334. }
  335. void CHSL::Clear( )
  336. {
  337. CTechnique::Clear( );
  338. }
  339. int CHSL::GetSignal( int nIndex, UINT * pnCode )
  340. {
  341. if( pnCode ) *pnCode = ITSC_NOTHING;
  342. return ITS_NOTHING;
  343. }
  344. BOOL CHSL::GetMinMaxInfo(int nStart, int nEnd,
  345.    double *pdMin, double *pdMax )
  346. {
  347. return AfxGetMinMaxInfo1( nStart, nEnd, pdMin, pdMax, this );
  348. }
  349. /***
  350. 相对换手率
  351. */
  352. BOOL CHSL::Calculate( double * pValue, int nIndex, BOOL bUseLast )
  353. {
  354. STT_ASSERT_CALCULATE1( m_pKData, nIndex );
  355. if( LoadFromCache( nIndex, pValue ) )
  356. return TRUE;
  357. double dRatioChangeHand = 0;
  358. double dVolume = m_pKData->ElementAt(nIndex).m_fVolume;
  359. if( m_stockinfo.IsValidStock() && m_stockinfo.GetRatioChangeHand( &dRatioChangeHand, dVolume ) )
  360. {
  361. // 相对换手率
  362. double dMainChangeHand = GetMainChangeHand( m_stockinfo.GetMarket(), *m_pKData, nIndex );
  363. double dRelativeChangeHand = 1.0;
  364. if( dMainChangeHand > 1e-6 )
  365. {
  366. dRelativeChangeHand = dRatioChangeHand / dMainChangeHand;
  367. if( pValue )
  368. *pValue = dRelativeChangeHand;
  369. StoreToCache( nIndex, pValue );
  370. return TRUE;
  371. }
  372. }
  373. else
  374. {
  375. if( pValue )
  376. *pValue = 1.0;
  377. StoreToCache( nIndex, pValue );
  378. return TRUE;
  379. }
  380. return FALSE;
  381. }
  382. /***
  383. 计算HSL及其移动平均值
  384. */
  385. BOOL CHSL::Calculate( double * pValue, int nIndex, int nDays, BOOL bUseLast )
  386. {
  387. STT_ASSERT_CALCULATE1( m_pKData, nIndex );
  388. if( nDays > nIndex+1 )
  389. return FALSE;
  390. double dValue = 0, dMA = 0;
  391. int nCount = 0;
  392. for( int k=nIndex; k>=0; k-- )
  393. {
  394. double dTemp = 0;
  395. if( Calculate( &dTemp, k, FALSE ) )
  396. {
  397. if( nIndex == k )
  398. dValue = dTemp;
  399. dMA += dTemp;
  400. nCount ++;
  401. if( nCount == nDays )
  402. {
  403. dMA = dMA / nDays;
  404. if( pValue ) *pValue = dMA;
  405. return TRUE;
  406. }
  407. }
  408. }
  409. return FALSE;
  410. }
  411. //////////////////////////////////////////////////////////////////////
  412. // CDPER
  413. CDPER::CDPER( )
  414. {
  415. SetDefaultParameters( );
  416. }
  417. CDPER::CDPER( CKData * pKData )
  418. : CTechnique( pKData )
  419. {
  420. SetDefaultParameters( );
  421. }
  422. CDPER::~CDPER()
  423. {
  424. Clear( );
  425. }
  426. void CDPER::SetDefaultParameters( )
  427. {
  428. m_nDays = 30;
  429. m_nMADays = 6;
  430. m_nDetrendDays = 12;
  431. m_itsGoldenFork = ITS_BUY;
  432. m_itsDeadFork = ITS_SELL;
  433. }
  434. void CDPER::AttachParameters( CDPER & src )
  435. {
  436. m_nDays = src.m_nDays;
  437. m_nMADays = src.m_nMADays;
  438. m_nDetrendDays = src.m_nDetrendDays;
  439. m_itsGoldenFork = src.m_itsGoldenFork;
  440. m_itsDeadFork = src.m_itsDeadFork;
  441. }
  442. BOOL CDPER::IsValidParameters( )
  443. {
  444. return ( VALID_DAYS(m_nDays) && VALID_DAYS(m_nMADays) && VALID_DAYS(m_nDetrendDays)
  445. && VALID_ITS(m_itsGoldenFork) && VALID_ITS(m_itsDeadFork) );
  446. }
  447. void CDPER::Clear( )
  448. {
  449. CTechnique::Clear( );
  450. }
  451. int CDPER::GetSignal( int nIndex, UINT * pnCode )
  452. {
  453. if( pnCode ) *pnCode = ITSC_NOTHING;
  454. int nMaxDays = m_nDays+m_nMADays+m_nDetrendDays;
  455. double dLiminalLow = 0, dLiminalHigh = 0;
  456. if( !IntensityPrepare( nIndex, pnCode, nMaxDays, ITS_GETMINMAXDAYRANGE, &dLiminalLow, &dLiminalHigh, 0.15, 0.7 ) )
  457. return ITS_NOTHING;
  458. if( nIndex <= 1 )
  459. return ITS_NOTHING;
  460. double dValue;
  461. if( !Calculate( &dValue, nIndex, FALSE ) )
  462. return ITS_NOTHING;
  463. int nSignal = GetForkSignal( nIndex, m_itsGoldenFork, m_itsDeadFork, pnCode );
  464. if( dValue < dLiminalLow && nSignal == m_itsGoldenFork )
  465. { // 低位金叉
  466. if( pnCode ) *pnCode = ITSC_GOLDENFORK;
  467. return m_itsGoldenFork;
  468. }
  469. if( dValue > dLiminalHigh && nSignal == m_itsDeadFork )
  470. { // 高位死叉
  471. if( pnCode ) *pnCode = ITSC_DEADFORK;
  472. return m_itsDeadFork;
  473. }
  474. return ITS_NOTHING;
  475. }
  476. BOOL CDPER::GetMinMaxInfo(int nStart, int nEnd,
  477.    double *pdMin, double *pdMax )
  478. {
  479. if( pdMin ) *pdMin = 0;
  480. if( pdMax ) *pdMax = 100;
  481. return TRUE;
  482. }
  483. /***
  484. A = 今日收盘价 - (m_nDetrendDays+m_nDetrendDays)日的平均收盘价
  485.        N日内A小于今日A的天数
  486. DPER = ----------------------
  487.                 N
  488. */
  489. BOOL CDPER::Calculate( double * pValue, int nIndex, BOOL bUseLast )
  490. {
  491. STT_ASSERT_CALCULATE1( m_pKData, nIndex );
  492. if( m_nDays+m_nDetrendDays > nIndex+1 )
  493. return FALSE;
  494. if( LoadFromCache( nIndex, pValue ) )
  495. return TRUE;
  496. double dNow = 0;
  497. int nCount = 0;
  498. double dCountLow = 0;
  499. for( int k=nIndex; k>=0; k-- )
  500. {
  501. double dCur = 0;
  502. double dCt = 0, dMA = 0;
  503. double nDetrendCount = 0;
  504. for( int l=k-1; l>=0; l-- )
  505. {
  506. dMA += m_pKData->MaindataAt(l);
  507. nDetrendCount ++;
  508. if( nDetrendCount == m_nDetrendDays+m_nDetrendDays )
  509. {
  510. dCt = m_pKData->MaindataAt(k);
  511. dMA = dMA / (m_nDetrendDays+m_nDetrendDays);
  512. dCur = dCt - dMA;
  513. break;
  514. }
  515. }
  516. if( nIndex == k )
  517. {
  518. dNow = dCur;
  519. continue;
  520. }
  521. if( dCur < dNow )
  522. dCountLow += 1;
  523. nCount ++;
  524. if( nCount >= m_nDays )
  525. {
  526. if( pValue )
  527. *pValue = 100. * dCountLow / m_nDays;
  528. StoreToCache( nIndex, pValue );
  529. return TRUE;
  530. }
  531. }
  532. return FALSE;
  533. }
  534. /***
  535. 计算CYO及其移动平均值
  536. */
  537. BOOL CDPER::Calculate( double * pValue, double * pMA, int nIndex, BOOL bUseLast )
  538. {
  539. return CalculateMA( pValue, pMA, nIndex, bUseLast, m_nMADays );
  540. }