/* eslint-disable no-unused-vars */
/* eslint-disable max-len */

type Epoch = number;

type TransactionAction = 'deposit' | 'withdrawal' | 'buy' | 'sell';

type LandingCompany = 'japan' | 'costarica' | 'malta' | 'maltainvest' | 'iom';

type MarketType = 'forex' | 'indices' | 'stocks' | 'commodities' | 'volidx';

type DurationUnit = 'd' | 'm' | 's' | 'h' | 't';

type AccessScope = 'read' | 'trade' | 'payments' | 'admin';

declare class ApiRequest {
    req_id?: number,
}

declare class ApiResponse {
    msg_type: string,
    echo_req?: Object,
    req_id?: number,
}

type ApiErrorResponse = {
    msg_type: string,
    echo_req?: Object,
    error: {
        code: string,
        message: string,
    },
}


// active_symbols

declare class ActiveSymbolsRequest extends ApiRequest {
    active_symbols: 'brief' | 'full',
    landing_company?: LandingCompany,
}

declare class ActiveSymbol {
    symbol: string,
    intraday_interval_minutes: number,
    symbol_type: string,
    exchange_is_open: ?number,
    exchange_name: string,
    delay_amount: number,
    display_name: string,
    spot: ?number,
    spot_time: string,
    is_trading_suspended: number,
    quoted_currency_symbol: string,
    spot_age: string,
    market: string,
    market_display_name: string,
    submarket: string,
    submarket_display_name: string,
    pip: number,
}

declare class ActiveSymbolsResponse extends ApiResponse {
    active_symbolsarray: ActiveSymbol[],
}

// TODO: asset_index

declare class AssetIndexRequest extends ApiRequest {
    asset_index: 1,
    landing_company?: LandingCompany,
}

declare class AssetIndexResponse extends ApiResponse {
    asset_index: any[],
}

// authorize

declare class AuthorizeRequest extends ApiRequest {
    authorize: string,
}

declare class AuthorizeResponse extends ApiResponse {
    authorize: {
        email: string,
        currency: string,
        balance: number,
        loginid: string,
        is_virtual: 0 | 1,
        landing_company_name: string,
        fullname: string,
    },
}

// contracts_for

declare class ForwardStartingOption {
    close: Epoch,
    date: Epoch,
    open: Epoch,
}

declare class AvailableContractDetails {
    market: MarketType,
    contracts_display: string,
    max_contract_duration: string,
    barrier_category: string,
    payout_limit: number,
    submarket: string,
    exchange_name: string,
    contract_category_display: string,
    contract_type: string,
    min_contract_duration: string,
    sentiment: string,
    barriers: number,
    contract_category: string,
    start_type: string,
    expiry_type: string,
    underlying_symbol: string,
    forward_starting_options: ForwardStartingOption[],
    available_barriers?: number[],
    expired_barriers?: any[],
    trading_period?: {
        date_expiry: {
            date: string,
            epoch: Epoch,
        },
        date_start: {
            date: string,
            epoch: Epoch,
        },
        duration: string,
    }
}

declare class ContractsForRequest extends ApiRequest {
    contracts_for: string,
    currency?: string,
    region?: 'japan' | 'other',
}

declare class ContractsForResponse extends ApiResponse {
    contracts_for: {
        available: AvailableContractDetails,
        close: Epoch,
        open: Epoch,
        hit_count: number,
        spot: ?number,
        feed_license: string,
    },
}

// forget

declare class ForgetRequest extends ApiRequest {
    forget: string,
}

declare class ForgetResponse extends ApiResponse {
    forget: 0 | 1,
}

// forget_all

declare class ForgetAllRequest extends ApiRequest {
    forget_all: 'ticks' | 'candles' | 'proposal' | 'portfolio' | 'proposal_open_contract' | 'balance' | 'transaction' | 'pricing_table',
}

declare class ForgetAllResponse extends ApiResponse {
    forget_all: number[],
}

// get_corporate_actions

declare class CorporateAction {
    display_date: string,
    type: number,
    value: number,
    modifier: string,
}

declare class CorporateActionsRequest extends ApiRequest {
    get_corporate_actions: 1,
    symbol: string,
    start: string,
    end: string,
}

declare class CorporateActionsResponse extends ApiResponse {
    get_corporate_actions: {
        actions: CorporateAction[],
    }
}

// landing_company

declare class LandingCompanyDetails {
    id: string,
    name: string,
    gaming_company: {
        shortcode: string,
        name: string,
        address: string[],
        country: string,
        legal_default_currency: string,
        legal_allowed_currencies: string[],
        legal_allowed_markets: string[],
        has_reality_check: 0 | 1,
    },
}

declare class LandingCompanyRequest extends ApiRequest {
    landing_company: string,
}

declare class LandingCompanyResponse extends ApiResponse {
    landing_company: LandingCompanyDetails,
}

// landing_company_details

declare class LandingCompanyDetailsRequest extends ApiRequest {
    landing_company_details: string,
}

declare class LandingCompanyDetailsResponse extends ApiResponse {
    landing_company_details: LandingCompanyDetails,
}

// new_account_virtual

declare class NewAccountVirtualRequest extends ApiRequest {
    new_account_virtual: 1,
    verification_code: string,
    client_password: string,
    residence: string,
    affiliate_token?: string,
    utm_source?: string,
    utm_medium?: string,
    utm_campaign?: string,
}

declare class NewAccountVirtualResponse extends ApiResponse {
    new_account_virtual: {
        client_id: string,
        email: string,
        currency: string,
        balance: number,
        oauth_token: string,
    },
}

// ping

declare class PingRequest extends ApiRequest {
    ping: 1,
}

declare class PingResponse extends ApiResponse {
    ping: 'pong',
}

// paymentagent_list

declare class PaymentAgentDetails {
    currencies: string,
    deposit_commission: string,
    email: string,
    further_information: string,
    name: string,
    paymentagent_loginid: string,
    summary: string,
    supported_banks: string,
    telephone: string,
    url: string,
    withdrawal_commission: string,
}

declare class PaymentAgentListRequest extends ApiRequest {
    paymentagent_list: string,
}

declare class PaymentAgentListResponse extends ApiResponse {
    paymentagent_list: {
        available_countries: any[],
        list: PaymentAgentDetails[],
    }
}

// payout_currencies

declare class PayoutCurrenciesRequest extends ApiRequest {
    payout_currencies: 1,
}

declare class PayoutCurrenciesResponse extends ApiResponse {
    payout_currencies: string[],
}

// proposal

// TODO

// residence_list

declare class ResidenceListRequest extends ApiRequest {
    residence_list: 1,
}

declare class ResidenceListResponse extends ApiResponse {
    residence_list: string[],
}

// states_list

declare class StatesListRequest extends ApiRequest {
    states_list: 1,
}

declare class StatesListResponse extends ApiResponse {
    states_list: string[],
}

// ticks

declare class TickSpotData {
    epoch: Epoch,
    id: string,
    quote: number,
    symbol: string,
}

declare class TicksRequest extends ApiRequest {
    ticks: string | string[],
    subscribe?: 1,
}

declare class TicksResponse extends ApiResponse {
    tick: TickSpotData,
}

// ticks_history

declare class TickHistoryRequest extends ApiRequest {
    ticks_history: string | string[],
    end?: Epoch | 'latest',
    start: Epoch,
    count: number,
    style: 'candles' | 'ticks',
    granularity?: number,
    adjust_start_time?: 1,
    subscribe?: 1,
}

declare class TickHistoryResponse extends ApiResponse {
    history?: {
        times: Epoch[],
        prices: number,
    },
    candles?: Candle[],
}

// time

declare class TimeRequest extends ApiRequest {
    time: 1,
}

declare class TimeResponse extends ApiResponse {
    time: Epoch,
}

// trading_times

declare class TradingTimesRequest extends ApiRequest {
    trading_times: string,
}

declare class TradingTimesResponse extends ApiResponse {
    trading_times: {
        markets: any[],
    }
}

// verify_email

declare class VerifyEmailRequest extends ApiRequest {
    verify_email: string,
    type: 'account_opening' | 'reset_password' | 'paymentagent_withdraw' | 'payment_withdraw',
}

declare class VerifyEmailResponse extends ApiResponse {
    verify_email: 1,
}

// website_status

declare class WebsiteStatus {
    terms_conditions_version: string,
    api_call_limits: {
        max_proposal_subscription: {
            applies_to: string,
            max: number,
        },
        max_requestes_general: {
            applies_to: string,
            hourly: number,
            minutely: number,
        },
        max_requests_outcome: {
            applies_to: string,
            hourly: number,
            minutely: number,
        },
        max_requests_pricing: {
            applies_to: string,
            hourly: number,
            minutely: number,
        }
    },
    clients_country: string,
}

declare class WebsiteStatusRequest extends ApiRequest {
    website_status: 1,
}

declare class WebsiteStatusResponse extends ApiResponse {
    website_status: WebsiteStatus,
}

// get_limits

declare class AccountLimits {
    account_balance: number,
    daily_turnover: number,
    open_positions: number,
    payout: number,
    lifetime_limit: number,
    num_of_days: number,
    num_of_days_limit: number,
    remainder: number,
    withdrawal_for_x_days_monetary: number,
}

declare class AccountLimitsRequest extends ApiRequest {
    get_limits: 1,
}

declare class AccountLimitsResponse extends ApiResponse {
    get_limits: AccountLimits,
}

// get_settings

declare class AccountSettings {
    email: string,
    country: ?string,
    country_code: ?string,
    salutation: string,
    first_name: string,
    last_name: string,
    date_of_birth: ?number,
    address_line_1: string,
    address_line_2: string,
    address_city: string,
    address_state: string,
    address_postcode: string,
    phone: string,
    is_authenticated_payment_agent: number,
    jp_account_status: {
        status: 'activated' | 'jp_knowledge_test_pending' | 'jp_knowledge_test_fail' | 'jp_activation_pending' | 'disabled',
        last_test_epoch: number,
        next_test_epoch: number,
    },
    jp_settings: {
        gender: 'm' | 'f',
        occupation: 'Office worker' | 'Director' | 'Public worker' | 'Self-employed Housewife / Househusband' | 'Contract / Temporary / Part Time Student' | 'Unemployed' | 'Others',
        annual_income: 'Less than 1 million JPY' | '1-3 million JPY' | '3-5 million JPY' | '5-10 million JPY' | '10-30 million JPY' | '30-50 million JPY' | '50-100 million JPY' | 'Over 100 million JPY',
        financial_asset: 'Less than 1 million JPY' | '1-3 million JPY' | '3-5 million JPY' | '5-10 million JPY' | '10-30 million JPY' | '30-50 million JPY' | '50-100 million JPY' | 'Over 100 million JPY',
        daily_loss_limit: number,
        trading_experience_equities: 'No experience' |'Less than 6 months' | '6 months to 1 year' | '1-3 years' | '3-5 years' | 'Over 5 years',
        trading_experience_commodities: 'No experience' |'Less than 6 months' | '6 months to 1 year' | '1-3 years' | '3-5 years' | 'Over 5 years',
        trading_experience_foreign_currency_deposit: 'No experience' |'Less than 6 months' | '6 months to 1 year' | '1-3 years' | '3-5 years' | 'Over 5 years',
        trading_experience_margin_fx: 'No experience' |'Less than 6 months' | '6 months to 1 year' | '1-3 years' | '3-5 years' | 'Over 5 years',
        trading_experience_investment_trust: 'No experience' |'Less than 6 months' | '6 months to 1 year' | '1-3 years' | '3-5 years' | 'Over 5 years',
        trading_experience_public_bond: 'No experience' |'Less than 6 months' | '6 months to 1 year' | '1-3 years' | '3-5 years' | 'Over 5 years',
        trading_experience_option_trading: 'No experience' |'Less than 6 months' | '6 months to 1 year' | '1-3 years' | '3-5 years' | 'Over 5 years',
        trading_purpose: 'Targeting short-term profits' | 'Targeting medium-term / long-term profits' | 'Both the above Hedging',
        hedge_asset: 'Foreign currency deposit' | 'Margin FX' | 'Other',
        hedge_asset_amount: ?number,
    }
}

declare class AccountSettingsRequest extends ApiRequest {
    get_settings: 1,
}

declare class AccountSettingsResponse extends ApiResponse {
    get_settings: AccountSettings,
}

// get_account_status

declare class AccountStatus {
    status: string[],
    risk_classification: 'low' | 'standard' | 'high',
}

declare class AccountStatusRequest extends ApiRequest {
    get_account_status: 1,
}

declare class AccountStatusResponse extends ApiResponse {
    get_account_status: AccountStatus,
}

// balance

declare class Balance {
    balance: number,
    currency: string,
    loginid: string,
    id: string,
}

declare class BalanceRequest extends ApiRequest {
    balance: 1,
    subscribe?: 1,
}

declare class BalanceResponse extends ApiResponse {
    balance: Balance,
}

// get_self_exclusion

declare class SelfExclusionSettings {
    max_balance: number,
    max_turnover: number,
    max_losses: number,
    max_7day_turnover: number,
    max_7day_losses: number,
    max_30day_turnover: number,
    max_30day_losses: number,
    max_open_bets: number,
    session_duration_limit: number,
    exclude_until: string,
    timeout_until: number,
}

declare class SelfExclusionRequest extends ApiRequest {
    get_self_exclusion: 1,
}

declare class SelfExclusionResponse extends ApiResponse {
    get_self_exclusion: SelfExclusionSettings,
}

// login_history

declare class LoginHistoryEntry {
    time: Epoch,
    action: string,
    environment: string,
    status: 0 | 1,
}

declare class LoginHistoryRequest extends ApiRequest {
    login_history: 1,
    limit: number,
}

declare class LoginHistoryResponse extends ApiResponse {
    login_history: LoginHistoryEntry[],
}

// logout

declare class LogoutRequest extends ApiRequest {
    logout: 1,
}

declare class LogoutResponse extends ApiResponse {
    logout: number,
}

// statement

declare class StatementTransaction {
    balance_after: number,
    transaction_id: number,
    contract_id: ?number,
    transaction_time: Epoch,
    purchase_time: Epoch,
    action_type: TransactionAction,
    amount: number,
    longcode: string,
    shortcode: ?string,
    payout: ?number,
    app_id: ?number,
}

declare class StatementOptions {
    description?: 1,
    limit: number,
    offset: number,
    date_from: Epoch,
    date_to: Epoch,
    action_type: 'buy' | 'sell' | 'deposit' | 'withdrawal',
}

declare class StatementRequest extends ApiRequest mixins StatementOptions {
    statement: 1,
}

declare class StatementResponse extends ApiResponse {
    statement: {
        count: number,
        transactions: StatementTransaction[],
    }
}

// portfolio

declare class OpenContract {
    contract_id: number,
    transaction_id: number,
    purchase_time: Epoch,
    symbol: string,
    payout: number,
    buy_price: number,
    date_start: Epoch,
    expiry_time: Epoch,
    contract_type: ContractType,
    currency: string,
    longcode: string,
    app_id: ?number,
}

declare class PortfolioRequest extends ApiRequest {
    portfolio: 1,
}

declare class PortfolioResponse extends ApiResponse {
    portfolio: {
        contracts: OpenContract[],
    }
}

// profit_table

declare class ProfitTableTransaction {
    transaction_id: number,
    contract_id: ?number,
    purchase_time: Epoch,
    sell_time: Epoch,
    buy_price: number,
    sell_price: number,
    longcode: string,
    shortcode: string,
    payout: number,
    app_id: ?number,
}

declare class ProfitTableOptions {
    description?: 1,
    limit: number,
    offset: number,
    date_from: string,
    date_to: string,
    sort: 'ASC' | 'DESC',
}

declare class ProfitTableRequest extends ApiRequest mixins ProfitTableOptions {
    profit_table: 1,
}

declare class ProfitTableResponse extends ApiResponse {
    profit_table: {
        count: number,
        transactions: ProfitTableTransaction[],
    }
}

// proposal_open_contract

declare class PriceProposal {
    high_barrier?: number,
    low_barrier?: number,
    barrier?: number,
    original_high_barrier?: number,
    original_low_barrier?: number,
    original_barrier?: number,
    barrier_count: number,
    bid_price: number,
    contract_id: number,
    contract_type: string,
    currency: string,
    current_spot?: number,
    current_spot_time: Epoch,
    entry_spot?: number,
    date_expiry?: Epoch,
    date_settlement?: Epoch,
    date_start?: Epoch,
    id: string,
    has_corporate_actions: 0 | 1,
    is_expired: 0 | 1,
    is_forward_starting: 0 | 1,
    is_intraday: 0 | 1,
    is_path_dependent: number,
    is_valid_to_sell: 0 | 1,
    longcode: string,
    payout: number,
    shortcode: string,
    display_value: number,
    underlying: string,
    display_name: string,
    entry_tick: number,
    entry_tick_time: Epoch,
    exit_tick: number,
    exit_tick_time: Epoch,
    tick_count: number,
    validation_error?: string,
    sell_price?: number,
    buy_price: number,
    purchase_time?: Epoch,
    sell_time?: Epoch,
    sell_spot: number,
    sell_spot_time?: Epoch,
    entry_level?: number,
    amount_per_point?: string,
    stop_loss_level?: number,
    stop_profit_level?: number,
    current_level?: number,
    exit_level?: number,
    current_value_in_dollar?: number,
    current_value_in_point?: number,
    transaction_ids: string[],
}

declare class ProposalOpenContractRequest extends ApiRequest {
    proposal_open_contract: 1,
    contract_id: number,
    subscribe?: 1,
}

declare class ProposalOpenContractResponse extends ApiResponse {
    proposal_open_contract: LoginHistoryEntry[],
}

// reality_check

declare class RealityCheckSummary {
    start_time: Epoch,
    loginid: string,
    currency: string,
    buy_count: number,
    buy_amount: number,
    sell_count: number,
    sell_amount: number,
    potential_profit: number,
    open_contract_count: number,
}

declare class RealityCheckRequest extends ApiRequest {
    reality_check: 1,
}

declare class RealityCheckResponse extends ApiResponse {
    reality_check: RealityCheckSummary,
}

// transaction

declare class TrasnactionUpdate {
    balance: number,
    action: TransactionAction,
    contract_id: number,
    transaction_id: number,
    amount: number,
    id: string,
    transaction_time: Epoch,
    purchase_time: Epoch,
    currency: string,
    longcode: string,
    symbol: string,
    display_name: string,
    date_expiry: Epoch,
}

declare class TransactionRequest extends ApiRequest {
    transaction: 1,
    subscribe?: 1,
}

declare class TransactionResponse extends ApiResponse {
    transaction: TrasnactionUpdate,
}

// buy

declare class BuyContractParameters {
    amount: number,
    basis: 'payout' | 'stake',
    contract_type: string,
    currency: string,
    date_start: Epoch,
    date_expiry: Epoch,
    duration: number,
    duration_unit: DurationUnit,
    symbol: string,
    barrier: string,
    barrier2: string,
}

declare class BuySpreadContractParameters extends BuyContractParameters {
    amount_per_point: number,
    stop_typee: 'dollar' | 'point',
    stop_profit: number,
    stop_loss: number,
}

declare class ReceiptConfirmation {
    balance_after: number,
    longcode: string,
    shortcode: string,
    start_time: Epoch,
    contract_id: number,
    buy_price: number,
    purchase_time: Epoch,
    transaction_id: number,
}

declare class SpreadReceiptConfirmation extends ReceiptConfirmation {
    amount_per_point: number,
    stop_profit_level: number,
    stop_loss_level: number,
    payout: number,
}

declare class BuyContractRequest extends ApiRequest {
    buy: string,
    price: number,
    parameters: BuyContractParameters,
}

declare class BuyContractResponse extends ApiResponse {
    buy: ReceiptConfirmation,
}

// buy_contract_for_multiple_accounts

declare class BuyContractForMultipleAccountsRequest extends ApiRequest {
    buy_contract_for_multiple_accounts: 1,
    tokens: string[],
    price: number,
    parameters: BuyContractParameters,
}

declare class BuyContractForMultipleAccountsResponse extends ApiResponse {
    buy_contract_for_multiple_accounts: {
        result: ReceiptConfirmation[],
    },
}

// sell

declare class SellReceipt {
    balance_after: number,
    contract_id: number,
    sold_for: number,
    transaction_id: number,
}

declare class SellContractRequest extends ApiRequest {
    sell: number,
    price: number,
}

declare class SellContractResponse extends ApiResponse {
    sell: SellReceipt,
}

// sell_expired

declare class SellExpiredContractsRequest extends ApiRequest {
    sell_expired: 1,
}

declare class SellExpiredContractsResponse extends ApiResponse {
    sell_expired: {
        count: number,
    },
}

// topup_virtual

declare class TopUpVirtualRequest extends ApiRequest {
    topup_virtual: 1,
}

declare class TopUpVirtualResponse extends ApiResponse {
    topup_virtual: {
        currency: string,
        amount: number,
    },
}

// api_token

declare class ApiTokenManagementRequest extends ApiRequest {
    api_token: 1,
    new_token: string,
    new_token_scope: AccessScope[],
    delete_token: string,
    sub_account: string,
}

declare class ApiTokenManagementResponse extends ApiResponse {
    api_token: {
        tokens: string[],
        new_token?: 1,
        delete_token?: 1,
        sub_account: string,
    },
}

// app_register

declare class ApplicationDetails {
    name: string,
    scopes: AccessScope[],
    homepage?: string,
    github?: string,
    appstore?: string,
    googleplay: string,
    redirect_uri: string,
    app_markup_percentage?: number,
}

declare class ApplicationRegisterRequest extends ApiRequest mixins ApplicationDetails {
    app_register: 1,
}

declare class ApplicationRegisterResponse extends ApiResponse {
    app_register: ApplicationDetails,
}

// app_list

declare class ApplicationListRequest extends ApiRequest {
    app_list: 1,
}

declare class ApplicationListResponse extends ApiResponse {
    app_list: ApplicationDetails[],
}

// app_get

declare class ApplicationDetailsRequest extends ApiRequest {
    app_get: number,
}

declare class ApplicationDetailsResponse extends ApiResponse {
    app_get: ApplicationDetails,
}

// app_delete

declare class ApplicationDeleteRequest extends ApiRequest {
    app_delete: number,
}

declare class ApplicationDeleteResponse extends ApiResponse {
    app_delete: 1,
}

// app_update

declare class ApplcationUpdateRequest extends ApiRequest mixins ApplicationDetails {
    app_update: 1,
}

declare class ApplcationUpdateResponse extends ApiResponse {
    app_update: ApplicationDetails,
}

// oauth_apps

declare class OAuthApplication {
    name: string,
    app_id: number,
    last_used?: string,
    scopes: AccessScope[],
    app_markup_percentage: number,
}

declare class OAuthApplicationsRequest extends ApiRequest {
    oauth_apps: 1,
    revoke_app: number,
}

declare class OAuthApplicationsResponse extends ApiResponse {
    oauth_apps: OAuthApplication[],
}

// change_password

declare class ChangePasswordRequest extends ApiRequest {
    change_password: 1,
    old_password: string,
    new_password: string,
}

declare class ChangePasswordResponse extends ApiResponse {
    change_password: 1,
}

// jp_knowledge_test

declare class JapanKnowledgeTestRequest extends ApiRequest {
    jp_knowledge_test: 1,
    score: number,
    status: 'pass' | 'fail',
}

declare class JapanKnowledgeTestResponse extends ApiResponse {
    jp_knowledge_test: {
        test_taken_epoch: Epoch,
    },
}

// get_financial_assessment

declare class FinancialAssessmentDetails {
    score: number,
    forex_trading_frequency: string,
    forex_trading_experience: string,
    indices_trading_frequency: string,
    indices_trading_experience: string,
    commodities_trading_frequency: string,
    commodities_trading_experience: string,
    stocks_trading_experience: string,
    stocks_trading_frequency: string,
    other_derivatives_trading_frequency: string,
    other_derivatives_trading_experience: string,
    other_instruments_trading_frequency: string,
    other_instruments_trading_experience: string,
    employment_industry: string,
    education_level: string,
    income_source: string,
    net_income: string,
    estimated_worth: string,
}

declare class GetFinancialAssesmentRequest extends ApiRequest {
    get_financial_assessment: 1,
}

declare class GetFinancialAssesmentResponse extends ApiResponse {
    get_financial_assessment: FinancialAssessmentDetails,
}

// set_financial_assessment

declare class SetFinancialAssessmentRequest extends ApiRequest mixins FinancialAssessmentDetails {
    set_financial_assessment: 1,
}

declare class SetFinancialAssessmentResponse extends ApiResponse {
    set_financial_assessment: FinancialAssessmentDetails,
}

// new_account_maltainvest

declare class CreateMaltainvestAccountOptions {
    salutation: 'Mr' | 'Mrs' | 'Ms' | 'Miss',
    first_name: string,
    last_name: string,
    date_of_birth: string,
    residence: string,
    address_line_1: string,
    address_line_2?: string,
    address_city: string,
    address_state?: string,
    address_postcode?: string,
    phone: string,
    secret_question: string,
    secret_answer: string,
    affiliate_token?: string,
    forex_trading_experience: string,
    forex_trading_frequency: string,
    indices_trading_experience: string,
    indices_trading_frequency: string,
    commodities_trading_experience: string,
    commodities_trading_frequency: string,
    stocks_trading_experience: string,
    stocks_trading_frequency: string,
    other_derivatives_trading_experience: string,
    other_derivatives_trading_frequency: string,
    other_instruments_trading_experience: string,
    other_instruments_trading_frequency: string,
    employment_industry: string,
    education_level: string,
    income_source: string,
    net_income: string,
    estimated_worth: string,
    accept_risk: number,
}

declare class CreateMaltainvestAccountRequest extends ApiRequest mixins CreateMaltainvestAccountOptions {
    new_account_maltainvest: 1,
}

declare class CreateMaltainvestAccountResponse extends ApiResponse {
    new_account_maltainvest: {
        client_id: string,
        landing_company: string,
        landing_company_short: string,
        oauth_token: string,
    },
}

// new_account_real

declare class CreateRealAccountOptions {
    salutation: 'Mr' | 'Mrs' | 'Ms' | 'Miss',
    first_name: string,
    last_name: string,
    date_of_birth: string,
    residence: string,
    address_line_1: string,
    address_line_2?: string,
    address_city: string,
    address_state?: string,
    address_postcode?: string,
    phone: string,
    secret_question: string,
    secret_answer: string,
    affiliate_token?: string,
}

declare class CreateRealAccountRequest extends ApiRequest mixins CreateRealAccountOptions {
    new_account_real: 1,
}

declare class CreateRealAccountResponse extends ApiResponse {
    new_account_real: {
        client_id: string,
        landing_company: string,
        landing_company_short: string,
        oauth_token: string,
    },
}

// new_sub_account

declare class CreateRealSubAccountRequest extends ApiRequest {
    new_account_real: 1,
    salutation: 'Mr' | 'Mrs' | 'Ms' | 'Miss',
    first_name: string,
    last_name: string,
    date_of_birth: string,
    residence: string,
    address_line_1: string,
    address_line_2?: string,
    address_city: string,
    address_state?: string,
    address_postcode?: string,
    phone: string,
    secret_question: string,
    secret_answer: string,
    affiliate_token?: string,
}

declare class CreateRealSubAccountResponse extends ApiResponse {
    new_account_real: {
        client_id: string,
        landing_company: string,
        landing_company_short: string,
    },
}

// set_account_currency

declare class SetAccountCurrencyRequest extends ApiRequest {
    set_account_currency: string,
}

declare class SetAccountCurrencyResponse extends ApiResponse {
    set_account_currency: 0 | 1,
}

// set_self_exclusion

declare class SetSelfExclusionRequest extends ApiRequest mixins SelfExclusionSettings {
    set_self_exclusion: 1,
}

declare class SetSelfExclusionResponse extends ApiResponse {
    set_self_exclusion: 1,
}

// set_settings

declare class SetSettingsRequest extends ApiRequest mixins AccountSettings {
    set_settings: 1,
}

declare class SetSettingsResponse extends ApiResponse {
    set_settings: 1,
}

// tnc_approval

declare class TncApprovalRequest extends ApiRequest {
    tnc_approval: 1,
    ukgc_funds_protection: 1,
}

declare class TncApprovalResponse extends ApiResponse {
    tnc_approval: 1,
}

// cashier

declare class CashierRequest extends ApiRequest {
    cashier: 'deposit' | 'withdraw',
    verification_code: string,
}

declare class CashierResponse extends ApiResponse {
    cashier: string,
}

// cashier_password

declare class CashierPasswordRequest extends ApiRequest {
    cashier_password: 1,
    unlock_password: string,
    lock_password: string,
}

declare class CashierPasswordResponse extends ApiResponse {
    cashier_password: 0 | 1,
}

// paymentagent_withdraw

declare class PaymentAgentWithdrawRequest extends ApiRequest {
    paymentagent_withdraw: 1,
    paymentagent_loginid: string,
    currency: string,
    amount: number,
    verification_code: string,
    description: string,
    dry_run?: 1,
}

declare class PaymentAgentWithdrawResponse extends ApiResponse {
    paymentagent_withdraw: 1 | 2,
    paymentagent_name: string,
    transaction_id: number,
}

// paymentagent_transfer

declare class PaymentAgentTransferRequest extends ApiRequest {
    paymentagent_transfer: 1,
    transfer_to: string,
    currency: string,
    amount: number,
    dry_run?: 1,
}

declare class PaymentAgentTransferResponse extends ApiResponse {
    paymentagent_transfer: 1 | 2,
    client_to_full_name: string,
    client_to_loginid: string,
    transaction_id: number,
}

// transfer_between_accounts

declare class Account {
    loginid: string,
    balance: string,
    currency: string,
}

declare class TransferBetweenAccountsRequest extends ApiRequest {
    transfer_between_accounts: 1,
    account_from: string,
    account_to: string,
    currency: string,
    amount: number,
}

declare class TransferBetweenAccountsResponse extends ApiResponse {
    transfer_between_accounts: number,
    accounts: Account[],
    client_to_full_name: string,
    client_to_loginid: string,
    transaction_id: number,
}
