    #ifndef INTRADAY_RECORD_H
    #define INTRADAY_RECORD_H

    /********************************************************************/
    // s_IntradayRecord

    //Special values used for s_IntradayRecord::Open
    const float SINGLE_TRADE_WITH_BID_ASK = 0.0F;
    const float FIRST_SUB_TRADE_OF_UNBUNDLED_TRADE_VALUE = -1.99900095e+37F;
    const float LAST_SUB_TRADE_OF_UNBUNDLED_TRADE_VALUE = -1.99900197e+37F;

    struct s_IntradayRecord
    {
        //--- Static Members ---------------------------------------------

        //--- Members ----------------------------------------------------

        SCDateTimeMS DateTime;

        float Open;
        float High;
        float Low;
        float Close;

        uint32_t NumTrades;
        uint32_t TotalVolume;
        uint32_t BidVolume;
        uint32_t AskVolume;

        //--- Methods ----------------------------------------------------

        s_IntradayRecord();
        s_IntradayRecord(int Value);

        bool operator == (const s_IntradayRecord& Record) const;

        s_IntradayRecord& operator = (const s_IntradayRecord& Record);

        s_IntradayRecord& operator += (const float Amount);
        s_IntradayRecord& operator *= (const float Multiplier);
        s_IntradayRecord& operator /= (const float Divisor);

        void AddAdjustment
            ( const float Amount
            , const bool AdjustZeroValues
            );

        bool IsEmpty() const;

        void Clear();
        void ClearOpenFlags();

        void Fix();

        bool IsSingleTradeWithBidAsk() const;
        bool IsFirstSubTradeOfUnbundledTrade() const;
        bool IsLastSubTradeOfUnbundledTrade() const;
        bool IsFirstOrLastSubTradeOfUnbundledTrade() const;
        bool IsBidAskUpdateOnly() const;

        float GetOpen() const;
        float GetHigh() const;
        float GetLow() const;
        float GetClose() const;
        float GetBidPrice() const;
        float GetAskPrice() const;
    };

    /********************************************************************/
    // s_Header

    struct s_IntradayFileHeader
    {
        static const uint32_t UNIQUE_HEADER_ID = 0x44494353;  // "SCID"

        uint32_t FileTypeUniqueHeaderID;  // "SCID"
        uint32_t HeaderSize;

        uint32_t RecordSize;
        uint16_t Version;

        uint16_t Unused1;

        uint32_t Unused2;

        char Reserve[36];

        s_IntradayFileHeader()
            : FileTypeUniqueHeaderID(UNIQUE_HEADER_ID)
            , HeaderSize(sizeof(s_IntradayFileHeader))
            , RecordSize(sizeof(s_IntradayRecord))
            , Version(1)
            , Unused1(0)
            , Unused2(0)
        {
            memset(Reserve, 0, sizeof(Reserve));
        }
    };

    /****************************************************************************/
    // s_IntradayRecord

    /*==========================================================================*/
    inline s_IntradayRecord::s_IntradayRecord()
    {
        Clear();
    }

    /*============================================================================
    This constructor is to support using this structure as an c_SCArray
    element.
    ----------------------------------------------------------------------------*/
    inline s_IntradayRecord::s_IntradayRecord(int Value)
    {
        Clear();
    }

    /*==========================================================================*/
    inline bool s_IntradayRecord::operator ==
    (const s_IntradayRecord& Record
        ) const
    {
        return memcmp(this, &Record, sizeof(s_IntradayRecord)) == 0;
    }

    /*==========================================================================*/
    inline s_IntradayRecord&
    s_IntradayRecord::operator =
    (const s_IntradayRecord& Record
        )
    {
        if (&Record == this)
            return *this;

        memcpy(this, &Record, sizeof(s_IntradayRecord));

        return *this;
    }

    /*==========================================================================*/
    inline s_IntradayRecord&
    s_IntradayRecord::operator += (const float Amount)
    {
        if (!IsSingleTradeWithBidAsk())
            Open += Amount;

        High += Amount;
        Low += Amount;
        Close += Amount;

        return *this;
    }

    /*==========================================================================*/
    inline s_IntradayRecord&
    s_IntradayRecord::operator *= (const float Multiplier)
    {
        if (!IsSingleTradeWithBidAsk())
            Open *= Multiplier;

        High *= Multiplier;
        Low *= Multiplier;
        Close *= Multiplier;

        return *this;
    }

    /*==========================================================================*/
    inline s_IntradayRecord&
    s_IntradayRecord::operator /= (const float Divisor)
    {
        if (!IsSingleTradeWithBidAsk())
            Open /= Divisor;

        High /= Divisor;
        Low /= Divisor;
        Close /= Divisor;

        return *this;
    }
    /*============================================================================
    Adds the given Amount to the prices, so long as the prices are non-zero,
    or AdjustZeroValues is true.
    ----------------------------------------------------------------------------*/
    inline void s_IntradayRecord::AddAdjustment
    (const float Amount
        , const bool AdjustZeroValues
    )
    {
        if (!IsSingleTradeWithBidAsk())
        {
            if (Open != 0.0f || AdjustZeroValues)
                Open += Amount;
        }

        if (High != 0.0f || AdjustZeroValues)
            High += Amount;

        if (Low != 0.0f || AdjustZeroValues)
            Low += Amount;

        if (Close != 0.0f || AdjustZeroValues)
            Close += Amount;
    }

    /*==========================================================================*/
    inline bool s_IntradayRecord::IsEmpty() const
    {
        return DateTime.IsUnset()
            && Open == 0.0f
            && High == 0.0f
            && Low == 0.0f
            && Close == 0.0f
            && NumTrades == 0
            && TotalVolume == 0;
    }

    /*==========================================================================*/
    inline void s_IntradayRecord::Clear()
    {
        DateTime.Clear();
        Open = 0.0f;
        High = 0.0f;
        Low = 0.0f;
        Close = 0.0f;
        NumTrades = 0;
        TotalVolume = 0;
        BidVolume = 0;
        AskVolume = 0;
    }

    /*==========================================================================*/
    inline void s_IntradayRecord::ClearOpenFlags()
    {
        Open = 0.0f;
    }

    /*============================================================================
    This function fixes any data that looks erroneous.
    ----------------------------------------------------------------------------*/
    inline void s_IntradayRecord::Fix()
    {
        if (NumTrades > INT_MAX)
            NumTrades = 0;

        if (TotalVolume > INT_MAX)
            TotalVolume = 0;

        if (BidVolume > INT_MAX)
            BidVolume = 0;

        if (AskVolume > INT_MAX)
            AskVolume = 0;
    }

    /*==========================================================================*/
    inline bool s_IntradayRecord::IsSingleTradeWithBidAsk() const
    {
        return NumTrades == 1
            && (Open == 0.0
                || Open == FIRST_SUB_TRADE_OF_UNBUNDLED_TRADE_VALUE
                || Open == LAST_SUB_TRADE_OF_UNBUNDLED_TRADE_VALUE
                );
    }

    /*==========================================================================*/
    inline bool s_IntradayRecord::IsFirstSubTradeOfUnbundledTrade() const
    {
        return (Open == FIRST_SUB_TRADE_OF_UNBUNDLED_TRADE_VALUE);
    }

    /*==========================================================================*/
    inline bool s_IntradayRecord::IsLastSubTradeOfUnbundledTrade() const
    {
        return (Open == LAST_SUB_TRADE_OF_UNBUNDLED_TRADE_VALUE);
    }

    /*==========================================================================*/
    inline bool s_IntradayRecord::IsFirstOrLastSubTradeOfUnbundledTrade() const
    {
        return Open == FIRST_SUB_TRADE_OF_UNBUNDLED_TRADE_VALUE
            || Open == LAST_SUB_TRADE_OF_UNBUNDLED_TRADE_VALUE;
    }

    /*==========================================================================*/
    inline bool s_IntradayRecord::IsBidAskUpdateOnly() const
    {
        return NumTrades == 1
            && TotalVolume == 0
            && Open == 0.0
            && High != 0.0
            && Low != 0.0;
    }

    /*==========================================================================*/
    inline float s_IntradayRecord::GetOpen() const
    {
        if (IsSingleTradeWithBidAsk())
            return Close;

        return Open;
    }

    /*==========================================================================*/
    inline float s_IntradayRecord::GetHigh() const
    {
        if (IsSingleTradeWithBidAsk())
            return Close;

        return High;
    }

    /*==========================================================================*/
    inline float s_IntradayRecord::GetLow() const
    {
        if (IsSingleTradeWithBidAsk())
            return Close;

        return Low;
    }

    /*==========================================================================*/
    inline float s_IntradayRecord::GetClose() const
    {
        return Close;
    }

    /*==========================================================================*/
    inline float s_IntradayRecord::GetBidPrice() const
    {
        if (!IsSingleTradeWithBidAsk())
            return 0.0f;

        return Low;
    }

    /*==========================================================================*/
    inline float s_IntradayRecord::GetAskPrice() const
    {
        if (!IsSingleTradeWithBidAsk())
            return 0.0f;

        return High;
    }
    #endif