atsuga commited on
Commit
50628ed
·
verified ·
1 Parent(s): 9a9970f

Upload 6 files

Browse files
Files changed (6) hide show
  1. Procfile +1 -0
  2. app.py +112 -0
  3. model.pkl +3 -0
  4. requirements.txt +8 -0
  5. scaler.pkl +3 -0
  6. templates/index.html +177 -0
Procfile ADDED
@@ -0,0 +1 @@
 
 
1
+ web: gunicorn app:app
app.py ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, render_template, request, jsonify
2
+ import pickle
3
+ import numpy as np
4
+ import requests
5
+ import pandas as pd
6
+
7
+ app = Flask(__name__)
8
+
9
+ # Load model dan scaler yang sudah disimpan
10
+ with open('model.pkl', 'rb') as model_file:
11
+ model = pickle.load(model_file)
12
+
13
+ with open('scaler.pkl', 'rb') as scaler_file:
14
+ scaler = pickle.load(scaler_file)
15
+
16
+ # Halaman utama
17
+ @app.route('/')
18
+ def home():
19
+ return render_template('index.html')
20
+
21
+ # Endpoint untuk prediksi berdasarkan input pengguna
22
+ @app.route('/predict', methods=['POST'])
23
+ def predict():
24
+ try:
25
+ # Mendapatkan data dari form input
26
+ input_data = request.get_json()
27
+
28
+ # Ambil nilai input (pastikan semuanya adalah angka)
29
+ sell_1 = float(input_data['features'][2])
30
+ sell_2 = float(input_data['features'][1])
31
+ sell_3 = float(input_data['features'][0])
32
+
33
+ # Normalisasi data menggunakan scaler
34
+ last_row = np.array([
35
+ scaler.transform([[sell_1]]).flatten()[0],
36
+ scaler.transform([[sell_2]]).flatten()[0],
37
+ scaler.transform([[sell_3]]).flatten()[0]
38
+ ]).reshape(1, -1)
39
+
40
+ # Buat DataFrame dari nilai yang telah dinormalisasi
41
+ last_row_df = pd.DataFrame(last_row, columns=['sell-1', 'sell-2', 'sell-3'])
42
+
43
+ # Prediksi harga berdasarkan model
44
+ predicted_value_normalized = model.predict(last_row_df)
45
+ predicted_value = scaler.inverse_transform(predicted_value_normalized.reshape(-1, 1))
46
+
47
+ # Ambil harga emas terakhir untuk perhitungan persentase
48
+ last_price_inversed = sell_1 # Menggunakan harga hari ketiga (sell_3) sebagai harga terakhir
49
+
50
+ # Hitung perubahan persentase
51
+ percentage_change = ((predicted_value[0][0] - last_price_inversed) / last_price_inversed) * 100
52
+
53
+ # Tentukan tanda perubahan (positif atau negatif)
54
+ change_sign = '+' if percentage_change > 0 else ''
55
+
56
+ # Kembalikan hasil prediksi dalam bentuk JSON
57
+ return jsonify({
58
+ 'last_price': last_price_inversed,
59
+ 'predicted_value': predicted_value[0][0],
60
+ 'percentage_change': f"{change_sign}{percentage_change:.2f}%",
61
+ 'raw_data': input_data
62
+ })
63
+
64
+
65
+ except Exception as e:
66
+ return jsonify({'error': str(e)}), 400
67
+
68
+ # Endpoint untuk prediksi otomatis berdasarkan data API
69
+ @app.route('/auto-predict', methods=['POST'])
70
+ def auto_predict():
71
+ try:
72
+ # Mendapatkan data yang dikirimkan dari frontend
73
+ input_data = request.get_json()
74
+ print(input_data)
75
+ # Ambil nilai input (pastikan semuanya adalah angka)
76
+ price_day_1 = float(input_data['features'][0])
77
+ price_day_2 = float(input_data['features'][1])
78
+ price_day_3 = float(input_data['features'][2])
79
+ last_row = np.array([
80
+ scaler.transform([[price_day_1]]).flatten()[0],
81
+ scaler.transform([[price_day_2]]).flatten()[0],
82
+ scaler.transform([[price_day_3]]).flatten()[0]
83
+ ]).reshape(1, -1)
84
+ last_row_df = pd.DataFrame(last_row, columns=['sell-1', 'sell-2', 'sell-3'])
85
+ # Prediksi harga
86
+ predicted_value_normalized = model.predict(last_row_df)
87
+ predicted_value = scaler.inverse_transform(predicted_value_normalized.reshape(-1, 1))
88
+
89
+ # Ambil harga emas terakhir untuk perhitungan persentase
90
+ last_price_inversed = price_day_3
91
+
92
+ # Hitung perubahan persentase
93
+ percentage_change = ((predicted_value[0][0] - last_price_inversed) / last_price_inversed) * 100
94
+
95
+ # Tentukan tanda perubahan (positif atau negatif)
96
+ if percentage_change > 0:
97
+ change_sign = '+'
98
+ else:
99
+ change_sign = ''
100
+
101
+ return jsonify({
102
+ 'last_price': last_price_inversed,
103
+ 'predicted_value': predicted_value[0][0],
104
+ 'percentage_change': f"{change_sign}{percentage_change:.2f}%",
105
+ 'raw_data': input_data
106
+ })
107
+
108
+ except Exception as e:
109
+ return jsonify({'error': str(e)}), 400
110
+
111
+ if __name__ == '__main__':
112
+ app.run(debug=True)
model.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:710965e9766cad3405f843241d572faab2d26835024e8555443eacb6d0514761
3
+ size 575
requirements.txt CHANGED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ Flask
2
+ pandas
3
+ numpy
4
+ joblib
5
+ scikit-learn
6
+ requests
7
+ fastapi
8
+ uvicorn[standard]
scaler.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c3d15e2ae968980d835817bca262d44edd0e89f08cbe2b517a50e9e65bd9159a
3
+ size 521
templates/index.html ADDED
@@ -0,0 +1,177 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Prediksi Harga Emas</title>
7
+ <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
8
+ <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
9
+ <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.bundle.min.js"></script>
10
+ <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
11
+ </head>
12
+ <body>
13
+ <div class="container mt-5">
14
+ <h1>Grafik Harga Jual Emas 30 Hari Terakhir</h1>
15
+
16
+ <!-- Grafik Harga Emas -->
17
+ <canvas id="sell-chart" width="400" height="200"></canvas>
18
+
19
+ <!-- Tab navigation -->
20
+ <ul class="nav nav-tabs" id="myTab" role="tablist">
21
+ <li class="nav-item" role="presentation">
22
+ <a class="nav-link active" id="auto-tab" data-toggle="tab" href="#auto-predict" role="tab" aria-controls="auto-predict" aria-selected="true">Auto Predict</a>
23
+ </li>
24
+ <li class="nav-item" role="presentation">
25
+ <a class="nav-link" id="input-tab" data-toggle="tab" href="#input-predict" role="tab" aria-controls="input-predict" aria-selected="false">Input Predict</a>
26
+ </li>
27
+ </ul>
28
+
29
+ <div class="tab-content" id="myTabContent">
30
+ <!-- Auto Predict Tab -->
31
+ <div class="tab-pane fade show active" id="auto-predict" role="tabpanel" aria-labelledby="auto-tab">
32
+ <h2>Prediksi Otomatis (Dari API):</h2>
33
+ <button id="auto-predict-btn" class="btn btn-secondary">Dapatkan Prediksi Otomatis</button>
34
+ <div id="auto-prediction-result" class="mt-3">
35
+ <p id="auto-last-price"></p>
36
+ <p id="auto-predicted-price"></p>
37
+ <p id="auto-percentage-change"></p>
38
+ </div>
39
+ </div>
40
+
41
+ <!-- Input Predict Tab -->
42
+ <div class="tab-pane fade" id="input-predict" role="tabpanel" aria-labelledby="input-tab">
43
+ <h2>Prediksi Berdasarkan Input:</h2>
44
+ <form id="input-form">
45
+ <div class="form-group">
46
+ <label for="sell-1">Harga Sell H-1:</label>
47
+ <input type="number" class="form-control" id="sell-1" required>
48
+ </div>
49
+ <div class="form-group">
50
+ <label for="sell-2">Harga Sell H-2:</label>
51
+ <input type="number" class="form-control" id="sell-2" required>
52
+ </div>
53
+ <div class="form-group">
54
+ <label for="sell-3">Harga Sell H-3:</label>
55
+ <input type="number" class="form-control" id="sell-3" required>
56
+ </div>
57
+ <button type="submit" class="btn btn-primary">Prediksi</button>
58
+ </form>
59
+ <div id="input-prediction-result" class="mt-3">
60
+ <p id="input-predicted-price"></p>
61
+ <p id="input-percentage-change"></p>
62
+ </div>
63
+ </div>
64
+ </div>
65
+ </div>
66
+
67
+ <script>
68
+
69
+ var sellPrices = [];
70
+ // Grafik Harga Emas: Ambil data untuk grafik dari URL API berbeda
71
+ $(document).ready(function() {
72
+ $.ajax({
73
+ url: 'https://api-pluang.pluang.com/api/v3/asset/gold/pricing?daysLimit=30', // Ganti dengan URL API yang sesuai
74
+ type: 'GET',
75
+ success: function(data) {
76
+ var dates = data.data.history.map(function(item) {
77
+ return item.updated_at.split('T')[0]; // Ambil hanya tanggal
78
+ });
79
+ sellPrices = data.data.history.map(function(item) {
80
+ return item.sell;
81
+ });
82
+
83
+ // Balikkan urutan data (dari data pertama ke terakhir)
84
+ dates.reverse();
85
+ sellPrices.reverse();
86
+
87
+ // Tampilkan grafik harga sell
88
+ var ctx = document.getElementById('sell-chart').getContext('2d');
89
+ var sellChart = new Chart(ctx, {
90
+ type: 'line',
91
+ data: {
92
+ labels: dates, // Tanggal
93
+ datasets: [{
94
+ label: 'Harga Sell Emas',
95
+ data: sellPrices, // Harga sell
96
+ borderColor: 'rgba(75, 192, 192, 1)',
97
+ borderWidth: 2,
98
+ fill: false
99
+ }]
100
+ },
101
+ options: {
102
+ responsive: true,
103
+ scales: {
104
+ y: {
105
+ beginAtZero: false
106
+ }
107
+ }
108
+ }
109
+ });
110
+ },
111
+ error: function(error) {
112
+ alert('Terjadi kesalahan saat memanggil API untuk grafik: ' + error.responseJSON.error);
113
+ }
114
+ });
115
+ });
116
+
117
+ // Fungsi untuk mengambil data dari grafik dan mengirimkan ke Flask
118
+ function getDataFromChart() {
119
+ // Ambil 3 harga terakhir dari data grafik
120
+ var lastThreeDays = sellPrices.slice(-3);
121
+
122
+ return {
123
+ features: lastThreeDays
124
+ };
125
+ }
126
+
127
+ // Fungsi untuk memanggil endpoint Flask dengan data dari grafik
128
+ $('#auto-predict-btn').click(function() {
129
+ var inputData = getDataFromChart();
130
+ console.log(inputData);
131
+
132
+ $.ajax({
133
+ url: '/auto-predict',
134
+ type: 'POST',
135
+ contentType: 'application/json',
136
+ data: JSON.stringify(inputData),
137
+ success: function(data) {
138
+ $('#auto-last-price').text(`Harga Emas Terakhir: ${data.last_price}`);
139
+ $('#auto-predicted-price').text(`Prediksi Harga Emas: ${data.predicted_value}`);
140
+ $('#auto-percentage-change').text(`Perubahan: ${data.percentage_change}`);
141
+ },
142
+ error: function(error) {
143
+ alert('Terjadi kesalahan: ' + error.responseJSON.error);
144
+ }
145
+ });
146
+ });
147
+
148
+ // Fungsi untuk menangani prediksi berdasarkan input pengguna
149
+ $('#input-form').submit(function(event) {
150
+ event.preventDefault();
151
+
152
+ var sell_1 = parseFloat($('#sell-1').val()); // Mengonversi input menjadi angka
153
+ var sell_2 = parseFloat($('#sell-2').val()); // Mengonversi input menjadi angka
154
+ var sell_3 = parseFloat($('#sell-3').val()); // Mengonversi input menjadi angka
155
+ var last_price = sell_1; // Anda bisa sesuaikan jika ingin mengambil nilai lainnya
156
+
157
+ $.ajax({
158
+ url: '/predict',
159
+ type: 'POST',
160
+ contentType: 'application/json',
161
+ data: JSON.stringify({
162
+ features: [sell_1, sell_2, sell_3],
163
+ last_price: [last_price]
164
+ }),
165
+ success: function(data) {
166
+ $('#input-predicted-price').text(`Prediksi Harga Emas: ${data.predicted_value}`);
167
+ $('#input-percentage-change').text(`Perubahan: ${data.percentage_change}`);
168
+ },
169
+ error: function(error) {
170
+ alert('Terjadi kesalahan: ' + error.responseJSON.error);
171
+ }
172
+ });
173
+ });
174
+
175
+ </script>
176
+ </body>
177
+ </html>