// $Revision: 1.12 $ // ViewerConstructors.C // Copyright (C) 1994, 1995 Taligent, Inc. All rights reserved. #ifndef TaligentSamples_VIEWERCONSTRUCTORS #include "ViewerConstructors.h" #endif #ifndef TaligentSamples_VIEWERDRAWERS #include "ViewerDrawers.h" #endif #ifndef TaligentSamples_GRAPHRANGE #include #endif #ifndef TaligentSamples_MARKDRAWER #include #endif #ifndef TaligentSamples_STANDARDGRAPH #include #endif #ifndef Taligent_DATETIME #include #endif #ifndef Taligent_ASSERTIONS #include #endif #ifndef _H_LIMITS #include #endif //============================================================================== // TPriceGraphConstructor TaligentTypeExtensionMacro_Abstract(TPriceGraphConstructor); TPriceGraphConstructor::TPriceGraphConstructor() : TStockGraphConstructor() { } TPriceGraphConstructor::TPriceGraphConstructor( const TPriceGraphConstructor& source) : TStockGraphConstructor(source) { } TPriceGraphConstructor::TPriceGraphConstructor( const TStandardText& description, const TStandardText& xAxisLabel, const TStandardText& yAxisLabel) : TStockGraphConstructor(description, xAxisLabel, yAxisLabel) { } TPriceGraphConstructor::~TPriceGraphConstructor() { } TStream& TPriceGraphConstructor::operator>>=(TStream& toStream) const { ::WriteVersion(toStream, kOriginalVersion); TStockGraphConstructor::operator>>=(toStream); return toStream; } TStream& TPriceGraphConstructor::operator<<=(TStream& fromStream) { ::ReadVersion(fromStream, kOriginalVersion, kOriginalVersion); TStockGraphConstructor::operator<<=(fromStream); return fromStream; } void TPriceGraphConstructor::CalcGraphRanges( TGraphRange& xRange, TGraphRange& yRange, const TCollectionOf& data) { const GraphValue kDefaultLow = 100; const GraphValue kDefaultCount = 100; GraphValue high = 0; GraphValue low = kDefaultLow; long count = kDefaultCount; if (!data.IsEmpty()) { low = ULONG_MAX; GraphValue dayHigh = 0; GraphValue dayLow = 0; TDeleterFor > iterator = data.CreateIterator(); for (TStockDay* day = iterator->First(); day != NIL; day = iterator->Next()) { // Get the whole year's high and low prices. dayHigh = day->GetHigh(); dayLow = day->GetLow(); if (dayHigh == 0) { continue; } if (dayHigh > high) { high = dayHigh; } if (dayLow < low) { low = dayLow; } } count = data.Count(); } xRange.SetMinAndMax(0, count); yRange.SetMinAndMax(low, high); } void TPriceGraphConstructor::HandleAddExtendedDrawers( TStandardGraph& theGraph, const TCollectionOf& data, const TGraphRange& xRange, const TGraphRange& yRange) { TCollectionOf* copyOfData = ::Copy(data); copyOfData->RemoveAll(); TDeleterFor > iter = data.CreateIterator(); for (TStockDay* item = iter->First(); item; item = iter->Next()) { copyOfData->Add(new TStockDay(*item)); } const GraphValue kDataPointInterval = 1; TPriceDrawer* priceDrawer = new TPriceDrawer(GetDrawerWidth(), kDataPointInterval, copyOfData); theGraph.AdoptDrawer(priceDrawer); } void TPriceGraphConstructor::HandleDoEnd( TStandardGraph& theGraph, const TCollectionOf& data, const TGraphRange& xRange, const TGraphRange& yRange) { const bool kPrepareDrawers = true; const GCoordinate kGraphHeight = 200; theGraph.SetAxisLengths(TGPoint(xRange.GetMax() * GetMarkLength(), kGraphHeight), kPrepareDrawers); } //============================================================================== // TAllDaysPriceGraphConstructor TaligentTypeExtensionMacro(TAllDaysPriceGraphConstructor); TAllDaysPriceGraphConstructor::TAllDaysPriceGraphConstructor() : TPriceGraphConstructor() { } TAllDaysPriceGraphConstructor::TAllDaysPriceGraphConstructor( const TAllDaysPriceGraphConstructor& source) : TPriceGraphConstructor(source) { } TAllDaysPriceGraphConstructor::TAllDaysPriceGraphConstructor( const TStandardText& description, const TStandardText& xAxisLabel, const TStandardText& yAxisLabel) : TPriceGraphConstructor(description, xAxisLabel, yAxisLabel) { } TAllDaysPriceGraphConstructor::~TAllDaysPriceGraphConstructor() { } TStream& TAllDaysPriceGraphConstructor::operator>>=(TStream& toStream) const { ::WriteVersion(toStream, kOriginalVersion); TPriceGraphConstructor::operator>>=(toStream); return toStream; } TStream& TAllDaysPriceGraphConstructor::operator<<=(TStream& fromStream) { ::ReadVersion(fromStream, kOriginalVersion, kOriginalVersion); TPriceGraphConstructor::operator<<=(fromStream); return fromStream; } void TAllDaysPriceGraphConstructor::HandleDoBegin(TStandardGraph& theGraph, TCollectionOf& data) { theGraph.DeleteAllDrawers(); } //============================================================================== // TMonthlySummaryPriceGraphConstructor TaligentTypeExtensionMacro(TMonthlySummaryPriceGraphConstructor); TMonthlySummaryPriceGraphConstructor::TMonthlySummaryPriceGraphConstructor( const TMonthlySummaryPriceGraphConstructor& source) : TPriceGraphConstructor(source) { } TMonthlySummaryPriceGraphConstructor::TMonthlySummaryPriceGraphConstructor( const TStandardText& description, const TStandardText& xAxisLabel, const TStandardText& yAxisLabel) : TPriceGraphConstructor(description, xAxisLabel, yAxisLabel) { } TMonthlySummaryPriceGraphConstructor::~TMonthlySummaryPriceGraphConstructor() { } TStream& TMonthlySummaryPriceGraphConstructor::operator>>=(TStream& toStream) const { ::WriteVersion(toStream, kOriginalVersion); TPriceGraphConstructor::operator>>=(toStream); return toStream; } TStream& TMonthlySummaryPriceGraphConstructor::operator<<=(TStream& fromStream) { ::ReadVersion(fromStream, kOriginalVersion, kOriginalVersion); TPriceGraphConstructor::operator<<=(fromStream); return fromStream; } TMonthlySummaryPriceGraphConstructor::TMonthlySummaryPriceGraphConstructor () : TPriceGraphConstructor() { } void TMonthlySummaryPriceGraphConstructor::HandleDoBegin( TStandardGraph& theGraph, TCollectionOf& data) { theGraph.DeleteAllDrawers(); GraphValue high(0); GraphValue low(0); TDays date; TGregorianCalendar calendar; // Start with the month of January. long month = 1; long nextMonthValue; // Get the first day of the first month in the stock data collection. TDeleterFor > iterator = data.CreateIterator(); if (iterator != NIL) { TStockDay* first = iterator->First(); if (first != NIL) { date = first->GetDate(); GraphValue highest = 0; GraphValue lowest = ULONG_MAX; // Create a collection of the same type as data. TDeleterFor > newData = ::Copy(data); newData->RemoveAll(); TStockDay* nextDay = NIL; TStockDay* previousDay = NIL; for (TStockDay* stockDay = iterator->First(); stockDay != NIL; ) { bool isHoliday = stockDay->IsHoliday(); if (!isHoliday) { high = stockDay->GetHigh(); low = stockDay->GetLow(); if (high > highest) { highest = high; } if (low < lowest) { lowest = low; } } // Note: volume doesn't matter for this updater, so each new TStockDay // object is given a volume of zero. nextDay = iterator->Next(); if (nextDay != NIL) { calendar.SetTime(nextDay->GetDate()); nextMonthValue = calendar.GetField(TCalendar::kMonthInYear); if (nextMonthValue > month) { if (isHoliday) { ::Assertion(previousDay != NIL, "previous day can't be NIL! (1)"); newData->Add(new TStockDay(date, highest, lowest, previousDay->GetClose(), 0)); } else { newData->Add(new TStockDay(date, highest, lowest, stockDay->GetClose(), 0)); } highest = 0; lowest = ULONG_MAX; calendar.GetTime(date); month = nextMonthValue; } } else { if (isHoliday) { ::Assertion(previousDay != NIL, "previous day can't be NIL! (2)"); newData->Add(new TStockDay(date, highest, lowest, previousDay->GetClose(), 0)); } else { newData->Add(new TStockDay(date, highest, lowest, stockDay->GetClose(), 0)); } } previousDay = stockDay; stockDay = nextDay; } data.DeleteAll(); data.AddCollection(newData); } } } //============================================================================== // TWeeklySummaryPriceGraphConstructor TaligentTypeExtensionMacro(TWeeklySummaryPriceGraphConstructor); TWeeklySummaryPriceGraphConstructor::TWeeklySummaryPriceGraphConstructor(const TWeeklySummaryPriceGraphConstructor& source) : TPriceGraphConstructor(source) { } TWeeklySummaryPriceGraphConstructor::TWeeklySummaryPriceGraphConstructor( const TStandardText& description, const TStandardText& xAxisLabel, const TStandardText& yAxisLabel) : TPriceGraphConstructor(description, xAxisLabel, yAxisLabel) { } TWeeklySummaryPriceGraphConstructor::~TWeeklySummaryPriceGraphConstructor () { } TStream& TWeeklySummaryPriceGraphConstructor::operator>>=(TStream& toStream) const { ::WriteVersion(toStream, kOriginalVersion); TPriceGraphConstructor::operator>>=(toStream); return toStream; } TStream& TWeeklySummaryPriceGraphConstructor::operator<<=(TStream& fromStream) { ::ReadVersion(fromStream, kOriginalVersion, kOriginalVersion); TPriceGraphConstructor::operator<<=(fromStream); return fromStream; } TWeeklySummaryPriceGraphConstructor::TWeeklySummaryPriceGraphConstructor () : TPriceGraphConstructor() { } void TWeeklySummaryPriceGraphConstructor::HandleDoBegin(TStandardGraph& theGraph, TCollectionOf& data) { theGraph.DeleteAllDrawers(); unsigned long counter(0); GraphValue high(0); GraphValue low(0); GraphValue highest(0); GraphValue lowest(ULONG_MAX); TDays date; const unsigned long kDaysPerWeek = 5; // Make a new collection of the same type as data. TDeleterFor > newData = ::Copy(data); newData->RemoveAll(); // Volume is not important to this updater so each new TStockDay object // is given a volume of zero. TStockDay* nextStockDay = NIL; TStockDay* previousStockDay = NIL; TDeleterFor > iterator = data.CreateIterator(); for (TStockDay* stockDay = iterator->First(); stockDay != NIL; ) { if ((counter + 1) % kDaysPerWeek == kDaysPerWeek - 1) { date = stockDay->GetDate(); } bool isHoliday = stockDay->IsHoliday(); if (!isHoliday) { high = stockDay->GetHigh(); low = stockDay->GetLow(); if (high > highest) { highest = high; } if (low < lowest) { lowest = low; } } nextStockDay = iterator->Next(); if ((counter + 1) % kDaysPerWeek == 0 || nextStockDay == NIL) { if (isHoliday) { ::Assertion(previousStockDay != NIL, "previous day can't be NIL!"); newData->Add(new TStockDay(date, highest, lowest, previousStockDay->GetClose(), 0)); } else { newData->Add(new TStockDay(date, highest, lowest, stockDay->GetClose(), 0)); } highest = 0; lowest = ULONG_MAX; } previousStockDay = stockDay; stockDay = nextStockDay; ++counter; } data.DeleteAll(); data.AddCollection(newData); } //============================================================================== // TVolumeGraphConstructor TaligentTypeExtensionMacro_Abstract(TVolumeGraphConstructor); TVolumeGraphConstructor::TVolumeGraphConstructor() : TStockGraphConstructor() { } TVolumeGraphConstructor::TVolumeGraphConstructor( const TVolumeGraphConstructor& source) : TStockGraphConstructor(source) { } TVolumeGraphConstructor::TVolumeGraphConstructor( const TStandardText& description, const TStandardText& xAxisLabel, const TStandardText& yAxisLabel) : TStockGraphConstructor(description, xAxisLabel, yAxisLabel) { } TVolumeGraphConstructor::~TVolumeGraphConstructor() { } TStream& TVolumeGraphConstructor::operator>>=(TStream& toStream) const { ::WriteVersion(toStream, kOriginalVersion); TStockGraphConstructor::operator>>=(toStream); return toStream; } TStream& TVolumeGraphConstructor::operator<<=(TStream& fromStream) { ::ReadVersion(fromStream, kOriginalVersion, kOriginalVersion); TStockGraphConstructor::operator<<=(fromStream); return fromStream; } void TVolumeGraphConstructor::CalcGraphRanges( TGraphRange& xRange, TGraphRange& yRange, const TCollectionOf& data) { const GraphValue kDefaultHighestVolume = 100; const GraphValue kDefaultCount = 100; GraphValue highestVolume = kDefaultHighestVolume; long count = kDefaultCount; if (!data.IsEmpty()) { highestVolume = 0; TDeleterFor > iterator = data.CreateIterator(); for (TStockDay* day = iterator->First(); day != NIL; day = iterator->Next()) { // Get the year's highest volume. GraphValue dayVolume = day->GetVolume(); if (dayVolume > highestVolume) { highestVolume = dayVolume; } } count = data.Count(); } xRange.SetMinAndMax(0, count); yRange.SetMinAndMax(0, highestVolume); } void TVolumeGraphConstructor::HandleAddExtendedDrawers( TStandardGraph& theGraph, const TCollectionOf& data, const TGraphRange& xRange, const TGraphRange& yRange) { const GraphValue kDataPointInterval = 1; TVolumeDrawer* volumeDrawer = new TVolumeDrawer(0, GetDrawerWidth(), kDataPointInterval, data); theGraph.AdoptDrawer(volumeDrawer); } void TVolumeGraphConstructor::HandleDoEnd( TStandardGraph& theGraph, const TCollectionOf& data, const TGraphRange& xRange, const TGraphRange& yRange) { const bool kPrepareDrawers = true; const GCoordinate kGraphHeight = 200; theGraph.SetAxisLengths(TGPoint(xRange.GetMax() * GetMarkLength(), kGraphHeight), kPrepareDrawers); } //============================================================================== // TAllDaysVolumeGraphConstructor TaligentTypeExtensionMacro(TAllDaysVolumeGraphConstructor); TAllDaysVolumeGraphConstructor::TAllDaysVolumeGraphConstructor() : TVolumeGraphConstructor() { } TAllDaysVolumeGraphConstructor::TAllDaysVolumeGraphConstructor( const TAllDaysVolumeGraphConstructor& source) : TVolumeGraphConstructor(source) { } TAllDaysVolumeGraphConstructor::TAllDaysVolumeGraphConstructor( const TStandardText& description, const TStandardText& xAxisLabel, const TStandardText& yAxisLabel) : TVolumeGraphConstructor(description, xAxisLabel, yAxisLabel) { } TAllDaysVolumeGraphConstructor::~TAllDaysVolumeGraphConstructor() { } TStream& TAllDaysVolumeGraphConstructor::operator>>=(TStream& toStream) const { ::WriteVersion(toStream, kOriginalVersion); TVolumeGraphConstructor::operator>>=(toStream); return toStream; } TStream& TAllDaysVolumeGraphConstructor::operator<<=(TStream& fromStream) { ::ReadVersion(fromStream, kOriginalVersion, kOriginalVersion); TVolumeGraphConstructor::operator<<=(fromStream); return fromStream; } void TAllDaysVolumeGraphConstructor::HandleDoBegin(TStandardGraph& theGraph, TCollectionOf& data) { theGraph.DeleteAllDrawers(); } //============================================================================== // TMonthlySummaryVolumeGraphConstructor TaligentTypeExtensionMacro(TMonthlySummaryVolumeGraphConstructor); TMonthlySummaryVolumeGraphConstructor::TMonthlySummaryVolumeGraphConstructor( const TMonthlySummaryVolumeGraphConstructor& source) : TVolumeGraphConstructor(source) { } TMonthlySummaryVolumeGraphConstructor::TMonthlySummaryVolumeGraphConstructor( const TStandardText& description, const TStandardText& xAxisLabel, const TStandardText& yAxisLabel) : TVolumeGraphConstructor(description, xAxisLabel, yAxisLabel) { } TMonthlySummaryVolumeGraphConstructor::~TMonthlySummaryVolumeGraphConstructor() { } TStream& TMonthlySummaryVolumeGraphConstructor::operator>>=(TStream& toStream) const { ::WriteVersion(toStream, kOriginalVersion); TVolumeGraphConstructor::operator>>=(toStream); return toStream; } TStream& TMonthlySummaryVolumeGraphConstructor::operator<<=(TStream& fromStream) { ::ReadVersion(fromStream, kOriginalVersion, kOriginalVersion); TVolumeGraphConstructor::operator<<=(fromStream); return fromStream; } TMonthlySummaryVolumeGraphConstructor::TMonthlySummaryVolumeGraphConstructor () : TVolumeGraphConstructor() { } void TMonthlySummaryVolumeGraphConstructor::HandleDoBegin(TStandardGraph& theGraph, TCollectionOf& data) { theGraph.DeleteAllDrawers(); GraphValue volume(0); TDays date; TGregorianCalendar calendar; // Start with the month of January. long month = 1; long nextMonthValue; // Get the first day of the first month in the stock data collection. TDeleterFor > iterator = data.CreateIterator(); if (iterator != NIL) { TStockDay* first = iterator->First(); if (first != NIL) { date = first->GetDate(); // Make a new collection of the same type as data. TDeleterFor > newData = ::Copy(data); newData->RemoveAll(); // High, low and closing prices are unimportant in this routine so // each new TStockDay object is initialized with zeros for those values. TStockDay* nextDay = NIL; TStockDay* previousDay = NIL; for (TStockDay* stockDay = iterator->First(); stockDay != NIL; ) { volume += stockDay->GetVolume(); nextDay = iterator->Next(); if (nextDay != NIL) { calendar.SetTime(nextDay->GetDate()); nextMonthValue = calendar.GetField(TCalendar::kMonthInYear); if (nextMonthValue > month) { if (stockDay->IsHoliday()) { ::Assertion(previousDay != NIL, "previous day can't be NIL! (1)"); newData->Add(new TStockDay(date, 0, 0, 0, volume)); } else { newData->Add(new TStockDay(date, 0, 0, 0, volume)); } volume = 0; calendar.GetTime(date); month = nextMonthValue; } } else { if (stockDay->IsHoliday()) { ::Assertion(previousDay != NIL, "previous day can't be NIL! (2)"); newData->Add(new TStockDay(date, 0, 0, 0, volume)); } else { newData->Add(new TStockDay(date, 0, 0, 0, volume)); } } previousDay = stockDay; stockDay = nextDay; } data.DeleteAll(); data.AddCollection(newData); } } } //============================================================================== // TWeeklySummaryVolumeGraphConstructor TaligentTypeExtensionMacro(TWeeklySummaryVolumeGraphConstructor); TWeeklySummaryVolumeGraphConstructor::TWeeklySummaryVolumeGraphConstructor(const TWeeklySummaryVolumeGraphConstructor& source) : TVolumeGraphConstructor(source) { } TWeeklySummaryVolumeGraphConstructor::TWeeklySummaryVolumeGraphConstructor( const TStandardText& description, const TStandardText& xAxisLabel, const TStandardText& yAxisLabel) : TVolumeGraphConstructor(description, xAxisLabel, yAxisLabel) { } TWeeklySummaryVolumeGraphConstructor::~TWeeklySummaryVolumeGraphConstructor () { } TStream& TWeeklySummaryVolumeGraphConstructor::operator>>=(TStream& toStream) const { ::WriteVersion(toStream, kOriginalVersion); TVolumeGraphConstructor::operator>>=(toStream); return toStream; } TStream& TWeeklySummaryVolumeGraphConstructor::operator<<=(TStream& fromStream) { ::ReadVersion(fromStream, kOriginalVersion, kOriginalVersion); TVolumeGraphConstructor::operator<<=(fromStream); return fromStream; } TWeeklySummaryVolumeGraphConstructor::TWeeklySummaryVolumeGraphConstructor () : TVolumeGraphConstructor() { } void TWeeklySummaryVolumeGraphConstructor::HandleDoBegin(TStandardGraph& theGraph, TCollectionOf& data) { theGraph.DeleteAllDrawers(); unsigned long counter(0); GraphValue volume(0); TDays date; const unsigned long kDaysPerWeek = 5; // Make a new collection of the same type as data. TDeleterFor > newData = ::Copy(data); newData->RemoveAll(); // High, low and closing prices are unimportant to this routine so // each new TStockDay object is initialized with zeros for those values. TStockDay* nextStockDay = NIL; TStockDay* previousStockDay = NIL; TDeleterFor > iterator = data.CreateIterator(); for (TStockDay* stockDay = iterator->First(); stockDay != NIL; ) { if ((counter + 1) % kDaysPerWeek == kDaysPerWeek - 1) { date = stockDay->GetDate(); } volume += stockDay->GetVolume(); nextStockDay = iterator->Next(); if ((counter + 1) % kDaysPerWeek == 0 || nextStockDay == NIL) { if (stockDay->IsHoliday()) { ::Assertion(previousStockDay != NIL, "previous day can't be NIL!"); newData->Add(new TStockDay(date, 0, 0, 0, volume)); } else { newData->Add(new TStockDay(date, 0, 0, 0, volume)); } volume = 0; } previousStockDay = stockDay; stockDay = nextStockDay; ++counter; } data.DeleteAll(); data.AddCollection(newData); }