RayMelius Claude Sonnet 4.6 commited on
Commit
9136daa
·
1 Parent(s): 0b7d7ac

Add new securities and use real prices in FIX UI order entry

Browse files

- securities.txt: add EUROB, AEG, INTKA, AAAK, ATTIK to existing symbols
- fix-ui-client: load securities as {symbol: price} dict so prices flow through
- index.html: auto-populate price field from current security price on symbol change
- oeg_simulator: read symbols and prices from securities.txt instead of hardcoded FOO/AAA/BBB at ~100

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

fix-ui-client/fix-ui-client.py CHANGED
@@ -145,16 +145,20 @@ def stop_fix():
145
  fix_initiator = None
146
 
147
  def load_securities():
148
- symbols = []
149
  try:
150
  with open(Config.SECURITIES_FILE) as f:
151
  for line in f:
152
  line = line.strip()
153
  if line and not line.startswith('#'):
154
- symbols.append(line.split('\t')[0])
 
 
 
 
155
  except Exception:
156
  pass
157
- return symbols or ["ALPHA", "PEIR", "EXAE", "QUEST", "NBG"]
158
 
159
  # --- Flask routes ---
160
  @app.route("/")
 
145
  fix_initiator = None
146
 
147
  def load_securities():
148
+ securities = {}
149
  try:
150
  with open(Config.SECURITIES_FILE) as f:
151
  for line in f:
152
  line = line.strip()
153
  if line and not line.startswith('#'):
154
+ parts = line.split()
155
+ if len(parts) >= 3:
156
+ securities[parts[0]] = float(parts[2])
157
+ elif len(parts) >= 1:
158
+ securities[parts[0]] = 10.0
159
  except Exception:
160
  pass
161
+ return securities or {"ALPHA": 5.65, "PEIR": 8.35, "EXAE": 6.90, "QUEST": 13.35, "NBG": 8.00}
162
 
163
  # --- Flask routes ---
164
  @app.route("/")
fix-ui-client/templates/index.html CHANGED
@@ -158,7 +158,7 @@
158
  </div>
159
  <div class="form-group">
160
  <label>Symbol</label>
161
- <select id="f-symbol">
162
  {% for s in securities %}
163
  <option value="{{ s }}">{{ s }}</option>
164
  {% endfor %}
@@ -170,7 +170,7 @@
170
  </div>
171
  <div class="form-group">
172
  <label>Price</label>
173
- <input id="f-price" type="number" step="0.01" value="150.00">
174
  </div>
175
  <button type="submit" class="btn-send">Send Order</button>
176
  </form>
@@ -186,6 +186,16 @@
186
  </div>
187
 
188
  <script>
 
 
 
 
 
 
 
 
 
 
189
  // Works whether served at / or under /fix/
190
  const BASE = window.location.pathname === '/' ? ''
191
  : window.location.pathname.replace(/\/$/, '');
@@ -264,6 +274,7 @@
264
  pollMessages();
265
  setInterval(pollStatus, 2000);
266
  setInterval(pollMessages, 2000);
 
267
  </script>
268
 
269
  </body>
 
158
  </div>
159
  <div class="form-group">
160
  <label>Symbol</label>
161
+ <select id="f-symbol" onchange="updatePrice()">
162
  {% for s in securities %}
163
  <option value="{{ s }}">{{ s }}</option>
164
  {% endfor %}
 
170
  </div>
171
  <div class="form-group">
172
  <label>Price</label>
173
+ <input id="f-price" type="number" step="0.01" value="">
174
  </div>
175
  <button type="submit" class="btn-send">Send Order</button>
176
  </form>
 
186
  </div>
187
 
188
  <script>
189
+ const SECURITIES_PRICES = {{ securities | tojson }};
190
+
191
+ function updatePrice() {
192
+ const sym = document.getElementById('f-symbol').value;
193
+ const price = SECURITIES_PRICES[sym];
194
+ if (price !== undefined) {
195
+ document.getElementById('f-price').value = price.toFixed(2);
196
+ }
197
+ }
198
+
199
  // Works whether served at / or under /fix/
200
  const BASE = window.location.pathname === '/' ? ''
201
  : window.location.pathname.replace(/\/$/, '');
 
274
  pollMessages();
275
  setInterval(pollStatus, 2000);
276
  setInterval(pollMessages, 2000);
277
+ updatePrice();
278
  </script>
279
 
280
  </body>
oeg/oeg_simulator.py CHANGED
@@ -1,25 +1,48 @@
1
  #!/usr/bin/env python3
2
  import time, json, random, requests, os
 
3
  FRONTEND = os.environ.get("FRONTEND_URL", "http://frontend:5000")
4
- SYMBOLS = ["FOO","AAA","BBB"]
5
- SIDES = ["buy","sell"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
 
7
  def post_order(order):
8
  try:
9
  r = requests.post(FRONTEND + "/submit", json=order, timeout=5)
10
- print(json.dumps({"component":"oeg","event":"post_order","payload":{"order":order,"status":r.status_code}}))
11
  except Exception as e:
12
- print(json.dumps({"component":"oeg","event":"post_failed","payload":{"order":order,"error":str(e)}}))
 
13
 
14
  if __name__ == "__main__":
 
 
 
15
  try:
16
  while True:
 
 
17
  order = {
18
- "order_id": str(int(time.time()*1000)),
19
- "symbol": random.choice(SYMBOLS),
20
  "type": random.choice(SIDES),
21
- "quantity": random.choice([5,10,20]),
22
- "price": round(100 + random.uniform(-1,1),2),
23
  "timestamp": time.time(),
24
  "source": "oeg-sim"
25
  }
 
1
  #!/usr/bin/env python3
2
  import time, json, random, requests, os
3
+
4
  FRONTEND = os.environ.get("FRONTEND_URL", "http://frontend:5000")
5
+ SECURITIES_FILE = os.environ.get("SECURITIES_FILE", "/app/data/securities.txt")
6
+ SIDES = ["buy", "sell"]
7
+
8
+
9
+ def load_securities():
10
+ securities = {}
11
+ try:
12
+ with open(SECURITIES_FILE) as f:
13
+ for line in f:
14
+ line = line.strip()
15
+ if line and not line.startswith('#'):
16
+ parts = line.split()
17
+ if len(parts) >= 3:
18
+ securities[parts[0]] = float(parts[2])
19
+ except Exception:
20
+ pass
21
+ return securities or {"ALPHA": 5.65, "PEIR": 8.35, "EXAE": 6.90}
22
+
23
 
24
  def post_order(order):
25
  try:
26
  r = requests.post(FRONTEND + "/submit", json=order, timeout=5)
27
+ print(json.dumps({"component": "oeg", "event": "post_order", "payload": {"order": order, "status": r.status_code}}))
28
  except Exception as e:
29
+ print(json.dumps({"component": "oeg", "event": "post_failed", "payload": {"order": order, "error": str(e)}}))
30
+
31
 
32
  if __name__ == "__main__":
33
+ securities = load_securities()
34
+ symbols = list(securities.keys())
35
+ print(json.dumps({"component": "oeg", "event": "loaded_securities", "payload": {"symbols": symbols}}))
36
  try:
37
  while True:
38
+ symbol = random.choice(symbols)
39
+ base_price = securities[symbol]
40
  order = {
41
+ "order_id": str(int(time.time() * 1000)),
42
+ "symbol": symbol,
43
  "type": random.choice(SIDES),
44
+ "quantity": random.choice([5, 10, 20]),
45
+ "price": round(base_price + random.uniform(-0.5, 0.5), 2),
46
  "timestamp": time.time(),
47
  "source": "oeg-sim"
48
  }
shared_data/securities.txt CHANGED
@@ -1,6 +1,11 @@
1
  #SYMBOL <start_price> <current_price>
2
- ALPHA 24.95 25.65
3
- PEIR 18.05 18.35
4
- EXAE 42.05 41.90
5
  QUEST 12.60 13.35
6
- NBG 18.05 18.00
 
 
 
 
 
 
1
  #SYMBOL <start_price> <current_price>
2
+ ALPHA 5.95 5.65
3
+ PEIR 8.05 8.35
4
+ EXAE 6.05 6.90
5
  QUEST 12.60 13.35
6
+ NBG 8.05 8.00
7
+ EUROB 3.20 3.45
8
+ AEG 4.25 4.75
9
+ INTKA 7.15 7.35
10
+ AAAK 2.25 2.75
11
+ ATTIK 4.15 4.9