PageSourceSearch

https://technology-p.com/wp-content/plugins/losscut-calculator/js/losscut-calculator.js?ver=7.1.3

js technology-p.com collected 2026-10-07 12:05:51 UTC 6,291 bytes, 143 lines download raw bytes

1class LossCutCalculator {
2    constructor(losscut_calculator) {
3        this.account_balanace = losscut_calculator.querySelector('#losscutcal-account-balance');
4        this.currency_pair = losscut_calculator.querySelector('#losscutcal-currency-pair');
5        this.entry_rate = losscut_calculator.querySelector('#losscutcal-entry-rate');
6        this.amount_position = losscut_calculator.querySelector('#losscutcal-amount-position');
7        this.unit_currency = losscut_calculator.querySelector('#losscutcal-unit-currency');
8        this.buy_or_sell = losscut_calculator.querySelector('#losscutcal-buy-or-sell');
9        this.trade_course = losscut_calculator.querySelector('#losscutcal-trade-course');
10
11        this.result_losscut_rate = losscut_calculator.querySelector('#losscutcal-result-losscut-rate');
12
13        var input_listener = (event) => {
14            this.controlValueRangeWarning(event.currentTarget);
15            this.controlMarginWarning();
16            this.displayCalculation();
17        }
18        var currency_input_listener = () => {
19            this.selectCurrencyPair();
20            this.controlMarginWarning();
21            this.displayCalculation();
22        }
23
24        this.account_balanace.addEventListener('input', input_listener);
25        this.currency_pair.addEventListener('input', currency_input_listener);
26        this.entry_rate.addEventListener('input', input_listener);
27        this.amount_position.addEventListener('input', input_listener);
28        this.unit_currency.addEventListener('input', input_listener);
29        this.buy_or_sell.addEventListener('input', this.displayCalculation.bind(this));
30        this.trade_course.addEventListener('input', this.displayCalculation.bind(this));
31
32        this.selectCurrencyPair();
33        this.displayCalculation();
34    }
35
36    selectCurrencyPair() {
37        this.entry_rate.value = this.currency_pair.value;
38        this.controlValueRangeWarning(this.entry_rate);
39    }
40
41    controlValueRangeWarning(target_input) {
42        if (this.isValidNumberInput(target_input) || target_input.value === '') {
43            this.hideWarning(target_input);
44        } else {
45            var min = target_input.getAttribute('min');
46            var max = target_input.getAttribute('max');
47            this.displayWarning(target_input, '有効な値を入力してください(' + min + '~' + max + ')');
48        }
49    }
50
51    controlMarginWarning() {
52        var required_margin = this.calculateRequiredMargin();
53        if (!this.isValidNumberInput(this.account_balanace) && this.account_balanace.value !== '') {
54            this.controlValueRangeWarning(this.account_balanace);
55        } else if (required_margin > this.account_balanace.value) {
56            var warn_message = this.formatNumber(required_margin - this.account_balanace.value, 5) + '円不足しています';
57            this.displayWarning(this.account_balanace, warn_message);
58        } else {
59            this.hideWarning(this.account_balanace);
60        }
61    }
62
63    displayCalculation() {
64        if (!this.isFilledInput()) {
65            this.result_losscut_rate.textContent = '-';
66            return;
67        }
68        var required_margin = this.calculateRequiredMargin();
69        if (required_margin > this.account_balanace.value) {
70            this.result_losscut_rate.textContent = '-';
71            return;
72        }
73        var surplus = this.calculateSurplus(required_margin);
74        var price_range = this.calculatePriceRange(surplus);
75        var losscut_line = this.calculateLosCutLine(price_range);
76
77        this.result_losscut_rate.textContent = this.formatNumber(losscut_line, 3);
78    }
79
80    calculateRequiredMargin() {
81        if (!this.isValidNumberInput(this.entry_rate)) return 0;
82        return this.entry_rate.value * this.amount_position.value * this.unit_currency.value * 0.04;
83    }
84
85    calculateSurplus(required_margin) {
86        return this.account_balanace.value - (required_margin * this.trade_course.value / 100);
87    }
88
89    calculatePriceRange(surplus) {
90        if (this.amount_position.value == 0) return 0;
91        return surplus / (this.unit_currency.value * this.amount_position.value);
92    }
93
94    calculateLosCutLine(price_range) {
95        if (this.buy_or_sell.value == 'buy') {
96            price_range = -price_range;
97        }
98        return Math.max(Number(this.entry_rate.value) + price_range, 0);
99    }
100
101    isFilledInput() {
102        if (!this.isValidNumberInput(this.account_balanace)) return false;
103        if (!this.isValidNumberInput(this.amount_position)) return false;
104        if (!this.isValidNumberInput(this.entry_rate)) return false;
105        return true;
106    }
107
108    isValidNumberInput(target_input) {
109        if (target_input.tagName != 'INPUT') return false;
110        if (target_input.getAttribute('type') != 'number') return false;
111        var min = target_input.hasAttribute('min') ? Number(target_input.getAttribute('min')) : Number.MIN_VALUE;
112        var max = target_input.hasAttribute('max') ? Number(target_input.getAttribute('max')) : Number.MAX_VALUE;
113        return target_input.value >= min && target_input.value <= max;
114    }
115
116    formatNumber(original_value, valid_decimal_place) {
117        var digit_fixer = Math.pow(10, valid_decimal_place);
118        var round_downed = Math.trunc(original_value * digit_fixer) / digit_fixer;
119        return new Intl.NumberFormat('ja-JP',{maximumFractionDigits:valid_decimal_place}).format(round_downed);
120    }
121
122    displayWarning(target_input, message) {
123        target_input.classList.add('input-warning');
124        var calculate_warning = target_input.parentNode.querySelector('.input-error-warn');
125        if (calculate_warning) {
126            calculate_warning.textContent = message;
127            calculate_warning.classList.remove('not-visible');
128        }
129    }
130
131    hideWarning(target_input) {
132        target_input.classList.remove('input-warning');
133        var calculate_warning = target_input.parentNode.querySelector('.input-error-warn');
134        if (calculate_warning) {
135            calculate_warning.textContent = '';
136            calculate_warning.classList.add('not-visible');
137        }
138    }
139}
140
141if (document.querySelector('#losscut-calculator')) {
142    var losscut_calc_controller = new LossCutCalculator(document.querySelector('#losscut-calculator'));
143}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.