/**** Local functions definitions. ****/ static ErrorNumber test_emptytradelog( void ) { TA_TradeLog *tradeLog; TA_RetCode retCode; /* Allocate an empty TA_TradeLog. */ retCode = TA_TradeLogAlloc( &tradeLog ); if( (retCode != TA_SUCCESS) || (tradeLog == NULL) ) { printRetCode( retCode ); printf( "Failed: TA_TradeLogAlloc bad retCode! [%d]\n", retCode ); return TA_PM_EMPTY_TA_TRADE_LOG_TESTS_0; } /* Verify invalid parameters. */ retCode = TA_TradeLogAlloc( NULL ); if( retCode != TA_BAD_PARAM ) { printRetCode( retCode ); printf( "Failed: TA_TradeLogAlloc bad retCode! [%d]\n", retCode ); return TA_PM_EMPTY_TA_TRADE_LOG_TESTS_2; } /* Free the empty TA_TradeLog */ retCode = TA_TradeLogFree( tradeLog ); if( retCode != TA_SUCCESS ) { printRetCode( retCode ); printf( "Failed: TA_TradeLogAlloc bad retCode! [%d]\n", retCode ); return TA_PM_EMPTY_TA_TRADELOGFREE_FAILED; } return TA_TEST_PASS; }
TA_RetCode TA_TradeLogAlloc( TA_TradeLog **allocatedTradeLog ) { TA_TradeLog *tradeLog; TA_TradeLogPriv *tradeLogPriv; TA_RetCode retCode; if( allocatedTradeLog ) *allocatedTradeLog = NULL; else return TA_BAD_PARAM; /* Allocate the public and private structure. */ tradeLog = TA_Malloc( sizeof( TA_TradeLog ) + sizeof( TA_TradeLogPriv ) ); if( !tradeLog ) return TA_ALLOC_ERR; memset( tradeLog, 0, sizeof( TA_TradeLog ) + sizeof( TA_TradeLogPriv ) ); tradeLogPriv = (TA_TradeLogPriv *)(((char *)tradeLog)+sizeof(TA_TradeLog)); tradeLogPriv->magicNb = TA_TRADELOGPRIV_MAGIC_NB; tradeLog->hiddenData = tradeLogPriv; TA_ListInit( &tradeLogPriv->defaultDictEntry.shortEntryPrivList ); TA_ListInit( &tradeLogPriv->defaultDictEntry.longEntryPrivList ); /* TA_TradeLogFree can be safely called from this point. */ tradeLogPriv->tradeDictCAT = TA_DictAlloc( TA_DICT_KEY_ONE_STRING, freeTradeDictEntry ); if( !tradeLogPriv->tradeDictCAT ) { TA_TradeLogFree( tradeLog ); return TA_ALLOC_ERR; } tradeLogPriv->tradeDictSYM = TA_DictAlloc( TA_DICT_KEY_ONE_STRING, freeTradeDictEntry ); if( !tradeLogPriv->tradeDictSYM ) { TA_TradeLogFree( tradeLog ); return TA_ALLOC_ERR; } tradeLogPriv->tradeDictCATSYM = TA_DictAlloc( TA_DICT_KEY_TWO_STRING, freeTradeDictEntry ); if( !tradeLogPriv->tradeDictCATSYM ) { TA_TradeLogFree( tradeLog ); return TA_ALLOC_ERR; } tradeLogPriv->tradeDictUserKey = TA_DictAlloc( TA_DICT_KEY_INTEGER, freeTradeDictEntry ); if( !tradeLogPriv->tradeDictUserKey ) { TA_TradeLogFree( tradeLog ); return TA_ALLOC_ERR; } retCode = TA_AllocatorForDataLog_Init( &tradeLogPriv->allocator ); if( retCode != TA_SUCCESS ) { TA_TradeLogFree( tradeLog ); return retCode; } /* Initialize the caller pointer on the allocated TA_TradeLog */ *allocatedTradeLog = tradeLog; return TA_SUCCESS; }
static ErrorNumber test_onetrade_only( TA_KEY_TYPE keyTypeTest, TA_TransactionType transactionType, unsigned int winningTrade ) { TA_RetCode retCode; TA_Instrument instrument; TA_Transaction transaction; TA_TradeLog *tradeLog; TA_PM *allocatedPM; ErrorNumber errorNumber; /* Allocate a TA_TradeLog. */ retCode = TA_TradeLogAlloc( &tradeLog ); if( (retCode != TA_SUCCESS) || (tradeLog == NULL) ) { printRetCode( retCode ); printf( "Failed: TA_TradeLogAlloc bad retCode! [%d]\n", retCode ); return TA_PM_EMPTY_TA_TRADE_LOG_TESTS_0; } /* Add the entry TA_Transaction */ switch( keyTypeTest ) { case TA_KEY_TYPE_INTEGER: TA_InstrumentInitWithUserKey( &instrument, 0 ); break; case TA_KEY_TYPE_CAT: TA_InstrumentInit( &instrument, "CATONLY", "" ); break; case TA_KEY_TYPE_SYM: TA_InstrumentInit( &instrument, "", "SYMONLY" ); break; case TA_KEY_TYPE_CATSYM: TA_InstrumentInit( &instrument, "C", "S" ); break; default: return TA_PM_ERR_INVALID_KEY_TYPE; } transaction.id = &instrument; transaction.price = 10.00; transaction.quantity = 1234; TA_TimestampCopy( &transaction.timestamp, ×tampNowPlusOneYear ); transaction.type = transactionType; retCode = TA_TradeLogAdd( tradeLog, &transaction ); if( retCode != TA_SUCCESS ) { printf( "Failed: TA_TradeLogAdd bad retCode %d\n", retCode ); return TA_PM_2TRADETST_TRADELOGADD_1; } /* Set the corresponsing exit transaction type. * Also make the exit price either winning * or loosing. */ if( transactionType == TA_LONG_ENTRY ) { transaction.type = TA_LONG_EXIT; if( winningTrade ) transaction.price = 12.00; else transaction.price = 9.50; } else if( transactionType == TA_SHORT_ENTRY ) { transaction.type = TA_SHORT_EXIT; if( winningTrade ) transaction.price = 9.25; else transaction.price = 11.00; } else return TA_PM_2TRADETST_BAD_TRADE_TYPE; /* Add the exit transaction. */ retCode = TA_TradeLogAdd( tradeLog, &transaction ); if( retCode != TA_SUCCESS ) { TA_TradeLogFree( tradeLog ); printRetCode( retCode ); printf( "Failed: TA_TradeLogAdd bad retCode %d\n", retCode ); return TA_PM_2TRADETST_TRADELOGADD_2; } /* Create a TA_PM */ retCode = TA_PMAlloc( ×tampNow, ×tampNowPlusOneYear, 1000, &allocatedPM ); if( retCode != TA_SUCCESS ) { TA_TradeLogFree( tradeLog ); printRetCode( retCode ); printf( "Failed: TA_PMAlloc bad retCode %d\n", retCode ); return TA_PM_2TRADETST_PMALLOC_FAILED; } retCode = TA_PMAddTradeLog( allocatedPM, tradeLog ); if( retCode != TA_SUCCESS ) { TA_PMFree( allocatedPM ); TA_TradeLogFree( tradeLog ); printRetCode( retCode ); printf( "Failed: TA_PMAddTradeLog bad retCode %d\n", retCode ); return TA_PM_2TRADETST_PMADDTRADELOG_FAILED; } /* Verify the NB of TRADE and the net profit */ if( transactionType == TA_LONG_ENTRY ) { if( winningTrade ) errorNumber = checkPMvalues( allocatedPM, 1, 0, 2468, 0 ); else errorNumber = checkPMvalues( allocatedPM, 1, 0, -617, 0 ); } else if( transactionType == TA_SHORT_ENTRY ) { if( winningTrade ) errorNumber = checkPMvalues( allocatedPM, 0, 1, 0, 925.5 ); else errorNumber = checkPMvalues( allocatedPM, 0, 1, 0, -1234); } else errorNumber = TA_PM_UNKNOWN_TRANSACTION_TYPE; if( errorNumber != TA_TEST_PASS ) return errorNumber; errorNumber = checkNoHang( allocatedPM ); if( errorNumber != TA_TEST_PASS ) return errorNumber; /* Building a report should work */ errorNumber = test_report( allocatedPM, 0 ); if( errorNumber != TA_TEST_PASS ) return errorNumber; /* Clean-up and exit */ retCode = TA_PMFree( allocatedPM ); if( retCode != TA_SUCCESS ) { TA_PMFree( allocatedPM ); TA_TradeLogFree( tradeLog ); printRetCode( retCode ); printf( "Failed: TA_PMFree bad retCode %d\n", retCode ); return TA_PM_2TRADETST_PMFREE_FAILED; } retCode = TA_TradeLogFree( tradeLog ); if( retCode != TA_SUCCESS ) { printRetCode( retCode ); printf( "Failed: TA_TradeLogFree bad retCode %d\n", retCode ); return TA_PM_TRADELOGFREE_ONE_TRADE_FAILED; } return TA_TEST_PASS; }
static ErrorNumber test_onetransaction_only( TA_KEY_TYPE keyTypeTest ) { TA_RetCode retCode; TA_Instrument instrument; TA_Transaction transaction; TA_TradeLog *tradeLog; ErrorNumber errorNumber; TA_PM *allocatedPM; /* Allocate an empty TA_TradeLog. */ retCode = TA_TradeLogAlloc( &tradeLog ); if( (retCode != TA_SUCCESS) || (tradeLog == NULL) ) { printRetCode( retCode ); printf( "Failed: TA_TradeLogAlloc bad retCode! [%d]\n", retCode ); return TA_PM_EMPTY_TA_TRADE_LOG_TESTS_0; } /* Add one TA_Transaction */ switch( keyTypeTest ) { case TA_KEY_TYPE_INTEGER: TA_InstrumentInitWithUserKey( &instrument, 0x12345432 ); break; case TA_KEY_TYPE_CAT: TA_InstrumentInit( &instrument, "CATONLY", NULL ); break; case TA_KEY_TYPE_SYM: TA_InstrumentInit( &instrument, NULL, "S" ); break; case TA_KEY_TYPE_CATSYM: TA_InstrumentInit( &instrument, "CATABCDEFGHIJKLMNOPQRSTUVWXYZ", "SYM012345678901234567890" ); break; default: return TA_PM_ERR_INVALID_KEY_TYPE; } transaction.id = &instrument; transaction.price = 34.45; transaction.quantity = 8765; TA_TimestampCopy( &transaction.timestamp, ×tampNow ); transaction.type = TA_LONG_ENTRY; retCode = TA_TradeLogAdd( tradeLog, &transaction ); if( retCode != TA_SUCCESS ) { printRetCode( retCode ); printf( "Failed: TA_TradeLogAdd bad retCode %d\n", retCode ); return TA_PM_TRADELOGADD_ONE_TRADE_FAILED; } /* Create a TA_PM */ retCode = TA_PMAlloc( ×tampNow, ×tampNow, 1000, &allocatedPM ); if( retCode != TA_SUCCESS ) { TA_TradeLogFree( tradeLog ); printRetCode( retCode ); printf( "Failed: TA_PMAlloc bad retCode %d\n", retCode ); return TA_PM_TRADELOGADD_ONE_TRADE_FAILED_1; } retCode = TA_PMAddTradeLog( allocatedPM, tradeLog ); if( retCode != TA_SUCCESS ) { TA_PMFree( allocatedPM ); TA_TradeLogFree( tradeLog ); printRetCode( retCode ); printf( "Failed: TA_PMAddTradeLog bad retCode %d\n", retCode ); return TA_PM_TRADELOGADD_ONE_TRADE_FAILED_2; } /* Verify the NB of TRADE */ errorNumber = checkPMvalues( allocatedPM, 0, 0, 0, 0 ); if( errorNumber != TA_TEST_PASS ) return errorNumber; errorNumber = checkNoHang( allocatedPM ); if( errorNumber != TA_TEST_PASS ) return errorNumber; /* Building a report should work */ errorNumber = test_report( allocatedPM, 0 ); if( errorNumber != TA_TEST_PASS ) return errorNumber; /* Clean-up and exit */ retCode = TA_PMFree( allocatedPM ); if( retCode != TA_SUCCESS ) { TA_PMFree( allocatedPM ); TA_TradeLogFree( tradeLog ); printRetCode( retCode ); printf( "Failed: TA_PMFree bad retCode %d\n", retCode ); return TA_PM_TRADELOGADD_ONE_TRADE_FAILED_3; } retCode = TA_TradeLogFree( tradeLog ); if( retCode != TA_SUCCESS ) { printRetCode( retCode ); printf( "Failed: TA_TradeLogFree bad retCode %d\n", retCode ); return TA_PM_TRADELOGFREE_ONE_TRADE_FAILED; } return TA_TEST_PASS; }
static ErrorNumber test_arrayId( TA_PMArrayIdTest *test ) { int i, j; TA_TradeLog *tradeLog; TA_PM *pm; TA_RetCode retCode; TA_Real theValue; TA_PMArray *pmArray; const char *tempStr; /* Allocate and build the TA_TradeLog */ retCode = TA_TradeLogAlloc( &tradeLog ); if( retCode != TA_SUCCESS ) return TA_PM_TEST_ARRAY_ID_FAILED_0; /* Add all the transaction. For simplicity, make these * all the same instrument. */ #define TA_SAFETY_NET_LIMIT 100 i = 0; while( (((void *)test->inputs[i].type) != ((void *)-1)) && (i<TA_SAFETY_NET_LIMIT) ) { retCode = TA_TradeLogAdd( tradeLog, &test->inputs[i] ); if( retCode != TA_SUCCESS ) { printRetCode( retCode ); TA_TradeLogFree( tradeLog ); return TA_PM_TEST_ARRAY_ID_FAILED_1; } i++; } if( i >= TA_SAFETY_NET_LIMIT ) { printf( "Failed: Number of transaction exceed %d limit\n", TA_SAFETY_NET_LIMIT ); return TA_PM_TEST_ARRAY_ID_FAILED_2; } #undef TA_SAFETY_NET_LIMIT /* Build the TA_PM */ retCode = TA_PMAlloc( &test->startDate, &test->endDate, test->initialCapital, &pm ); if( retCode != TA_SUCCESS ) { printRetCode( retCode ); TA_TradeLogFree( tradeLog ); return TA_PM_TEST_ARRAY_ID_FAILED_3; } /* Add the trade log to that PM */ retCode = TA_PMAddTradeLog( pm, tradeLog ); if( retCode != TA_SUCCESS ) { printRetCode( retCode ); return TA_PM_TEST_ARRAY_ID_FAILED_4; } /* Check the requested TA_PMArrayId */ #define TA_SAFETY_NET_LIMIT 30 i=0; while( (((int)test->toCheck[i].id) != -1) && (i<TA_SAFETY_NET_LIMIT) ) { switch( test->toCheck[i].grp ) { case TA_PM_ALL_TRADES: tempStr = "TA_PM_ALL_TRADES"; break; case TA_PM_SHORT_TRADES: tempStr = "TA_PM_SHORT_TRADES"; break; case TA_PM_LONG_TRADES: tempStr = "TA_PM_LONG_TRADES"; break; default: tempStr = "Invalid Group Id"; } retCode = TA_PMArrayAlloc( pm, test->toCheck[i].id, test->toCheck[i].grp, test->toCheck[i].period, &pmArray ); if( (retCode != test->toCheck[i].expectedRetCode) || (pmArray == NULL) ) { printRetCode( test->toCheck[i].expectedRetCode ); printRetCode( retCode ); printf( "Failed: TA_PMArrayAlloc expectedRetCode != retCode (%d != %d)\n", test->toCheck[i].expectedRetCode, retCode ); printf( "Failed: For %d:%s %d:%s Date[%d]\n", test->toCheck[i].id, "", test->toCheck[i].grp, tempStr, (int)test->toCheck[i].date.date ); return TA_PM_TEST_ARRAY_ID_FAILED_5; } if( retCode == TA_SUCCESS ) { /* Find the value to be verified */ for( j=0; j < pmArray->nbData; j++ ) { if( TA_TimestampEqual( &pmArray->timestamp[j], &test->toCheck[i].date ) ) { theValue = pmArray->data[j]; if( !TA_REAL_EQ(theValue,test->toCheck[i].expectedValue,0.01) ) { printf( "Failed: TA_PMArray expectedValue != theValue (%f != %f)\n", test->toCheck[i].expectedValue, theValue ); printf( "Failed: For %d:%s %d:%s, Date[%d]\n", test->toCheck[i].id, "", test->toCheck[i].grp, tempStr, (int)test->toCheck[i].date.date ); return TA_PM_TEST_ARRAY_ID_FAILED_6; } break; } } if( j >= pmArray->nbData ) { printf( "Failed: The expected date [%d] has not been found\n", (int)test->toCheck[i].date.date ); return TA_PM_TEST_ARRAY_WITH_INVALID_DATE; } TA_PMArrayFree( pmArray ); } i++; } if( i >= TA_SAFETY_NET_LIMIT ) { printf( "Failed: Number of checks exceed %d limit\n", TA_SAFETY_NET_LIMIT ); return TA_PM_TEST_ARRAY_ID_FAILED_7; } #undef TA_SAFETY_NET_LIMIT /* Free up everything */ retCode = TA_TradeLogFree( tradeLog ); if( retCode != TA_SUCCESS ) { printRetCode( retCode ); return TA_PM_TEST_ARRAY_ID_FAILED_8; } retCode = TA_PMFree( pm ); if( retCode != TA_SUCCESS ) { printRetCode( retCode ); return TA_PM_TEST_ARRAY_ID_FAILED_9; } return TA_TEST_PASS; }
static ErrorNumber test_valueId( TA_PMValueIdTest *test ) { unsigned int i; TA_TradeLog *tradeLog; TA_PM *pm; ErrorNumber errorNumber; TA_RetCode retCode; TA_Real theValue; const char *tempStr; /* Allocate and build the TA_TradeLog */ retCode = TA_TradeLogAlloc( &tradeLog ); if( retCode != TA_SUCCESS ) return TA_PM_TEST_VALUE_ID_FAILED_0; /* Add all the transaction. For simplicity, make these * all the same instrument. */ #define TA_SAFETY_NET_LIMIT 100 i = 0; while( (((void *)test->inputs[i].type) != ((void *)-1)) && (i<TA_SAFETY_NET_LIMIT) ) { retCode = TA_TradeLogAdd( tradeLog, &test->inputs[i] ); if( retCode != TA_SUCCESS ) { printRetCode( retCode ); TA_TradeLogFree( tradeLog ); return TA_PM_TEST_VALUE_ID_FAILED_1; } i++; } if( i >= TA_SAFETY_NET_LIMIT ) { printf( "Failed: Number of transaction exceed %d limit\n", TA_SAFETY_NET_LIMIT ); return TA_PM_TEST_VALUE_ID_FAILED_2; } #undef TA_SAFETY_NET_LIMIT /* Build the TA_PM */ retCode = TA_PMAlloc( &test->startDate, &test->endDate, test->initialCapital, &pm ); if( retCode != TA_SUCCESS ) { printRetCode( retCode ); TA_TradeLogFree( tradeLog ); return TA_PM_TEST_VALUE_ID_FAILED_3; } /* Add the trade log to that PM */ retCode = TA_PMAddTradeLog( pm, tradeLog ); if( retCode != TA_SUCCESS ) { printRetCode( retCode ); return TA_PM_TEST_VALUE_ID_FAILED_4; } /* Test the report feature. Again just to detect * software hanging/bad pointer. */ errorNumber = test_report( pm, 0 ); if( errorNumber != TA_TEST_PASS ) return errorNumber; /* Check the requested TA_PMArrayId */ #define TA_SAFETY_NET_LIMIT 30 i=0; while( (((int)test->toCheck[i].id) != -1) && (i<TA_SAFETY_NET_LIMIT) ) { switch( test->toCheck[i].grp ) { case TA_PM_ALL_TRADES: tempStr = "TA_PM_ALL_TRADES"; break; case TA_PM_SHORT_TRADES: tempStr = "TA_PM_SHORT_TRADES"; break; case TA_PM_LONG_TRADES: tempStr = "TA_PM_LONG_TRADES"; break; default: tempStr = "Invalid Group Id"; } retCode = TA_PMValue( pm, test->toCheck[i].id, test->toCheck[i].grp, &theValue ); if( retCode != test->toCheck[i].expectedRetCode ) { printRetCode( test->toCheck[i].expectedRetCode ); printRetCode( retCode ); printf( "Failed: TA_PMValue expectedRetCode != retCode (%d != %d)\n", test->toCheck[i].expectedRetCode, retCode ); printf( "Failed: For %d:%s %d:%s\n", test->toCheck[i].id, TA_PMValueIdString(test->toCheck[i].id), test->toCheck[i].grp, tempStr ); return TA_PM_TEST_VALUE_ID_FAILED_5; } if( !TA_REAL_EQ(theValue,test->toCheck[i].expectedValue,0.01) ) { printf( "Failed: TA_PMValue expectedValue != theValue (%f != %f)\n", test->toCheck[i].expectedValue, theValue ); printf( "Failed: For %d:%s %d:%s\n", test->toCheck[i].id, TA_PMValueIdString(test->toCheck[i].id), test->toCheck[i].grp, tempStr ); return TA_PM_TEST_VALUE_ID_FAILED_6; } i++; } if( i >= TA_SAFETY_NET_LIMIT ) { printf( "Failed: Number of checks exceed %d limit\n", TA_SAFETY_NET_LIMIT ); return TA_PM_TEST_VALUE_ID_FAILED_7; } #undef TA_SAFETY_NET_LIMIT /* Check for any potential software hanging/bad pointer. */ errorNumber = checkNoHang( pm ); if( errorNumber != TA_TEST_PASS ) return errorNumber; /* Free up everything */ retCode = TA_TradeLogFree( tradeLog ); if( retCode != TA_SUCCESS ) { printRetCode( retCode ); return TA_PM_TEST_VALUE_ID_FAILED_8; } retCode = TA_PMFree( pm ); if( retCode != TA_SUCCESS ) { printRetCode( retCode ); return TA_PM_TEST_VALUE_ID_FAILED_9; } return TA_TEST_PASS; }