/*
THIS INFRAGISTICS ULTIMATE SOFTWARE LICENSE  AGREEMENT ("AGREEMENT") LOCATED HERE:
https://www.infragistics.com/legal/license/igultimate-la
https://www.infragistics.com/legal/license/igultimate-eula
GOVERNS THE LICENSING, INSTALLATION AND USE OF INFRAGISTICS SOFTWARE. BY DOWNLOADING AND/OR INSTALLING AND USING INFRAGISTICS SOFTWARE:  you are indicating that you have read and understand this Agreement, and agree to be legally bound by it on behalf of the yourself and your company.
*/
import { Base, fromEnum, markType } from "./type";
import { Random } from "./Random";
import { StockPosition } from "./StockPosition";
import { StockPricePoint } from "./StockPricePoint";
import { StockDataLookup } from "./StockDataLookup";
import { StockDetails } from "./StockDetails";
import { List$1 } from "./List$1";
import { StockPriceHistory } from "./StockPriceHistory";
import { intDivide, truncate } from "./number";
import { dateNow, dateFromValues, dateGetMonth, dateAddMonths, dateAddMinutes, dateGetTimeOfDay } from "./date";
import { timeSpanTotalMinutes, timeSpanInit1 } from "./timespan";
import { stringIsNullOrEmpty } from "./string";
import { round10N } from "./numberExtended";
/**
 * @hidden
 */
export class StockDataGenerator extends Base {
    constructor() {
        super();
        this._priceStart = 0;
        this._priceRange = 0;
        this._priceMinimum = 0;
        this._priceMaximum = 0;
        this._volumeStart = 0;
        this._volumeRange = 0;
        this._dateRange = 0;
        this._dateInterval = 0;
        this._stockInterval = 0;
        this._skipAfterHours = false;
        this.g = new Date();
        this.h = new Date();
        this.q = new Random(0);
        this.skipAfterHours = false;
        this.priceStart = 0;
        this.priceRange = NaN;
        this.priceMinimum = NaN;
        this.priceMaximum = NaN;
        this.volumeStart = 0;
        this.volumeRange = NaN;
        this.dateRange = 12;
        this.dateInterval = 24 * 60;
    }
    get priceStart() {
        return this._priceStart;
    }
    set priceStart(a) {
        this._priceStart = a;
    }
    get priceRange() {
        return this._priceRange;
    }
    set priceRange(a) {
        this._priceRange = a;
    }
    get priceMinimum() {
        return this._priceMinimum;
    }
    set priceMinimum(a) {
        this._priceMinimum = a;
    }
    get priceMaximum() {
        return this._priceMaximum;
    }
    set priceMaximum(a) {
        this._priceMaximum = a;
    }
    get volumeStart() {
        return this._volumeStart;
    }
    set volumeStart(a) {
        this._volumeStart = a;
    }
    get volumeRange() {
        return this._volumeRange;
    }
    set volumeRange(a) {
        this._volumeRange = a;
    }
    get dateRange() {
        return this._dateRange;
    }
    set dateRange(a) {
        this._dateRange = a;
    }
    get dateInterval() {
        return this._dateInterval;
    }
    set dateInterval(a) {
        this._dateInterval = a;
    }
    get stockInterval() {
        return this._stockInterval;
    }
    set stockInterval(a) {
        this._stockInterval = a;
    }
    get skipAfterHours() {
        return this._skipAfterHours;
    }
    set skipAfterHours(a) {
        this._skipAfterHours = a;
    }
    generatePosition(a, b = "") {
        let c = StockDataLookup.get(a);
        let d = (intDivide(this.q.next2(1, 10), 100));
        let e = new StockPosition();
        e.symbol = c.symbol;
        e.company = c.company;
        e.sector = c.sector;
        e.costPerShare = c.close - (c.open * d);
        e.marketPrice = c.close;
        e.tradeDate = dateNow();
        return e;
    }
    generateDetails() {
        let a = new List$1(StockDetails.$, 0);
        for (let b of fromEnum(StockDataLookup.b.values)) {
            let c = (intDivide(this.q.next2(10, 30), 100));
            let d = new StockDetails();
            d.company = b.company;
            d.symbol = b.symbol;
            d.sector = b.sector;
            d.marketPrice = b.close;
            d.marketShares = intDivide((b.volume * this.q.next2(15, 20)), 1000000);
            d.annualLow = b.close - (b.open * c);
            d.annualHigh = b.close + (b.open * c);
            a.add(d);
        }
        return a.toArray();
    }
    generateStockPrices(a, b = "") {
        let c = dateNow();
        this.g = dateFromValues(c.getFullYear(), dateGetMonth(c), c.getDate(), 16, 30, 0, 0);
        this.h = dateAddMonths(this.g, -this.dateRange);
        let d = Math.ceil(timeSpanTotalMinutes((+(this.g) - +(this.h))) / this.dateInterval);
        let e = d * this.dateInterval;
        this.s(d + " steps, " + e + " range");
        if (d > 100000) {
            d = 100000;
            e = d * this.dateInterval;
            this.s(d + "^steps, " + e + " range");
        }
        let f = dateAddMinutes(this.g, -e);
        if (this.h.getTime() > f.getTime()) {
            this.h = f;
        }
        let g = StockDataLookup.get(a);
        g.date = this.h;
        let h = g.sector;
        if (this.priceStart > 0) {
            g.open = this.priceStart;
        }
        if (this.volumeStart > 0) {
            g.volume = this.volumeStart;
        }
        this.volumeRange = g.volume * 0.05;
        this.priceRange = g.open * 0.025;
        this.priceMinimum = g.open - (g.open * 0.75);
        this.priceMaximum = g.open + (g.open * 0.75);
        g.high = g.open + (g.open * 0.02);
        g.low = g.open - (g.open * 0.02);
        g.close = g.open + ((this.q.nextDouble() - 0.5) * this.priceRange);
        let i = new StockPriceHistory();
        i.symbol = a;
        if (!stringIsNullOrEmpty(b)) {
            g.company = b;
            i.company = b;
        }
        else if (!stringIsNullOrEmpty(g.company)) {
            i.company = g.company;
        }
        do {
            if (this.skipAfterHours) {
                if (!this.e(g.date)) {
                    i.add(g);
                }
            }
            else {
                i.add(g);
            }
            g = this.generateStockPricePoint(g);
        } while (g.date.getTime() <= this.g.getTime());
        this.s(" " + i.count + " items");
        return i;
    }
    e(a) {
        if (a.getDay() == 6) {
            return true;
        }
        if (a.getDay() == 0) {
            return true;
        }
        let b = timeSpanInit1(9, 30, 0);
        let c = timeSpanInit1(16, 30, 0);
        let d = dateGetTimeOfDay(a);
        if (d < b || d > c) {
            return true;
        }
        return false;
    }
    generateStockPricePoint(a) {
        let b = (this.q.nextDouble() - 0.499) * this.priceRange;
        let c = a.close;
        let d = a.close + b;
        if (d < this.priceMinimum) {
            d = this.priceMinimum + b;
        }
        if (d > this.priceMaximum) {
            d = this.priceMaximum - b;
        }
        let e = (this.q.nextDouble() * 1.5 * Math.abs(b));
        let f = (this.q.nextDouble() * 1.5 * Math.abs(b));
        if (d > c) {
            e = d + e;
            f = c - f;
        }
        else {
            e = c + e;
            f = d - f;
        }
        let g = (this.q.nextDouble() - 0.49) * this.volumeRange;
        let h = truncate(Math.abs(a.volume + g));
        let i = dateAddMinutes(a.date, this.dateInterval);
        if (i.getTime() > this.g.getTime()) {
            i = this.g;
        }
        let j = ((() => {
            let $ret = new StockPricePoint();
            $ret.date = dateAddMinutes(a.date, this.dateInterval);
            $ret.symbol = a.symbol;
            $ret.company = a.company;
            $ret.sector = a.sector;
            $ret.close = round10N(d, 2);
            $ret.open = round10N(c, 2);
            $ret.high = round10N(e, 2);
            $ret.low = round10N(f, 2);
            $ret.volume = h;
            return $ret;
        })());
        return j;
    }
    s(message_) {
    }
}
StockDataGenerator.$t = markType(StockDataGenerator, 'StockDataGenerator');
