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.