=encoding utf8

=for comment POD_DERIVED_INDEX_GENERATED
The following documentation is automatically generated.  Please do not edit
this file, but rather the original, inline with Finance::Calendar
at lib/Finance/Calendar.pm
(on the system that originally ran this).
If you do edit this file, and don't want your changes to be removed, make
sure you change the first line.

=cut

=head1 NAME

Finance::Calendar - represents the trading calendar.

=head1 SYNOPSIS

    use Finance::Calendar;
    use Date::Utility;

    my $calendar = {
        holidays => {
            "25-Dec-2013" => {
                "Christmas Day" => [qw(FOREX METAL)],
            },
            "1-Jan-2014" => {
                "New Year's Day" => [qw( FOREX METAL)],
            },
            "1-Apr-2013" => {
                "Easter Monday" => [qw( USD)],
            },
        },
        early_closes => {
            '24-Dec-2009' => {
                '16:30' => ['HKSE'],
            },
            '22-Dec-2016' => {
                '18:00' => ['FOREX', 'METAL'],
            },
        },
        late_opens => {
            '24-Dec-2010' => {
                '14:30' => ['HKSE'],
            },
        },
    };
    my $calendar = Finance::Calendar->new(calendar => $calendar);
    my $now = Date::Utility->new;

    # Does London Stocks Exchange trade on $now
    $calendar->trades_on(Finance::Exchange->create_exchange('LSE'), $now);

    # Is it a country holiday for the United States on $now
    $calendar->is_holiday_for('USD', $now);

    # Returns the opening time of Australian Stocks Exchange on $now
    $calendar->opening_on(Finance::Exchange->create_exchange('ASX'), $now);

    # Returns the closing time of Forex on $now
    $calendar->closing_on(Finance::Exchange->create_exchange('FOREX'), $now);
    ...

=head1 DESCRIPTION

This class is responsible for providing trading times or holidays related information of a given financial stock exchange on a specific date.

=head1 ATTRIBUTES - Object Construction

=head2 calendar

A hash reference that has information on:
- exchange and country holidays
- late opens
- early closes

=head1 METHODS - TRADING DAYS RELATED

=head2 trades_on

->trades_on($exchange_object, $date_object);

Returns true if trading is done on the day of a given Date::Utility.

=head2 trade_date_before

->trade_date_before($exchange_object, $date_object);

Returns a Date::Utility object for the previous trading day of an exchange for the given date.

=head2 trade_date_after

->trade_date_after($exchange_object, $date_object);

Returns a Date::Utility object of the next trading day of an exchange for a given date.

=head2 trading_date_for

->trading_date_for($exchange_object, $date_object);

The date on which trading is considered to be taking place even if it is not the same as the GMT date.
Note that this does not handle trading dates are offset forward beyond the next day (24h). It will need additional work if these are found to exist.

Returns a Date object representing midnight GMT of the trading date.

=head2 calendar_days_to_trade_date_after

->calendar_days_to_trade_date_after($exchange_object, $date_object);

Returns the number of calendar days between a given Date::Utility
and the next day on which trading is open.

=head2 trading_days_between

->trading_days_between($exchange_object, Date::Utility->new('4-May-10'),Date::Utility->new('5-May-10'));

Returns the number of trading days _between_ two given dates.

=head2 holiday_days_between

->holiday_days_between($exchange_object, Date::Utility->new('4-May-10'),Date::Utility->new('5-May-10'));

Returns the number of holidays _between_ two given dates.

=head1 METHODS - TRADING TIMES RELATED.

=head2 is_open

->is_open($exchange_object);

Returns true is exchange is open now, false otherwise.

=head2 is_open_at

->is_open_at($exchange_object, $epoch);

Return true is exchange is open at the given epoch, false otherwise.

=head2 seconds_since_open_at

->seconds_since_open_at($exchange_object, $epoch);

Returns the number of seconds since the exchange opened from the given epoch.

=head2 seconds_since_close_at

->seconds_since_close_at($exchange_object, $epoch);

Returns the number of seconds since the exchange closed from the given epoch.

=head2 opening_on

->opening_on($exchange_object, Date::Utility->new('25-Dec-10')); # returns undef (given Xmas is a holiday)

Returns the opening time (Date::Utility) of the exchange for a given Date::Utility, undefined otherwise.

=head2 closing_on

->closing_on($exchange_object, Date::Utility->new('25-Dec-10')); # returns undef (given Xmas is a holiday)

Returns the closing time (Date::Utility) of the exchange for a given Date::Utility, undefined otherwise.

=head2 trading_breaks

->trading_breaks($exchange_object, $date_object);

Defines the breaktime for this exchange.

=head2 regularly_adjusts_trading_hours_on

Returns a hashref of special-case changes that may apply on specific
trading days. Currently, this applies on Fridays only:

=over 4

=item * for forex or metals

=back

Example:

 $calendar->regularly_adjusts_trading_hours_on('FOREX', time);

=head2 closes_early_on

->closes_early_on($exchange_object, $date_object);

Returns the closing time as a L<Date::Utility> instance if the exchange closes early on the given date,
or C<undef>.

=head2 opens_late_on

->opens_late_on($exchange_object, $date_object);

Returns true if the exchange opens late on the given date.

=head2 seconds_of_trading_between_epochs

->seconds_of_trading_between_epochs($exchange_object, $epoch1, $epoch2);

Get total number of seconds of trading time between two epochs accounting for breaks.

=head2 regular_trading_day_after

->regular_trading_day_after($exchange_object, $date_object);

Returns a Date::Utility object on a trading day where the exchange does not close early or open late after the given date.

=head2 trading_period

->trading_period('HKSE', Date::Utility->new);

Returns an array reference of hash references of open and close time of the given exchange and epoch

=head2 is_holiday_for

Check if it is a holiday for a specific exchange or a country on a specific day

->is_holiday_for('ASX', '2013-01-01'); # Australian exchange holiday
->is_holiday_for('USD', Date::Utility->new); # United States country holiday

Returns the description of the holiday if it is a holiday.

=head2 is_in_dst_at

->is_in_dst_at($exchange_object, $date_object);

Is this exchange trading on daylight savings times for the given epoch?

=head2 get_exchange_open_times

Query an exchange for valid opening times. Expects 3 parameters:

=over 4

=item * C<$exchange> - a L<Finance::Exchange> instance

=item * C<$date> - a L<Date::Utility>

=item * C<$which> - which market information to request, see below

=back

The possible values for C<$which> include:

=over 4

=item * C<daily_open>

=item * C<daily_close>

=item * C<trading_breaks>

=back

Returns either C<undef>, a single L<Date::Utility>, or an arrayref of L<Date::Utility> instances.

=head2 next_open_at

->next_open_at($exchange_object, Date::Utility->new('2023-02-16 15:30:00'));

Returns Date::Utility object of the next opening date and time.

Returns undef if exchange is open for the requested date.

=head1 INHERITED METHODS

=over 4

=item L<Moose::Object>

L<BUILDALL|Moose::Object/BUILDALL>, L<BUILDARGS|Moose::Object/BUILDARGS>, L<DEMOLISHALL|Moose::Object/DEMOLISHALL>, L<DOES|Moose::Object/DOES>, L<does|Moose::Object/does>, L<dump|Moose::Object/dump>

=back

