MOEX Market
MOEX Market displays prices for Moscow Exchange (MOEX) both stocks and futures.
| System | AWTRIX NG Scripts |
|---|---|
| Firmware | AWTRIX NG |
| Topic | Miscellaneous |
| Built by | Avemer |
| File | 6OxJadW935Wl.ax · 4.4 KB |
| Icons | — |
| Published | 10 Aug 2026 · updated 10 Aug 2026 |
The script is designed to be lightweight and uses the MOEX ISS API to periodically request the current price.
FEATURES
- Supports Moscow Exchange (MOEX) stocks and futures. You can specify it yourself.
- Displays the ticker together with the current price
- Automatic green/red price coloring based on the latest price movement
- Custom ticker and price colors
- Adjustable ticker length
- Adjustable update interval
- Adjustable spacing between ticker and price
- Lightweight and suitable for the limited resources of the ULANZI TC001
- Technically, you can have several such scripts that will rotate each other on the clock display and show data from different tickers.
!!! IMPORTANT NOTE - Data Source & Delay !!!
- This script uses the free MOEX market data feed to retrieve prices directly on the watch.
- The free data source has a 15-minute delay, so the displayed price is not real-time. This is a limitation of the free MOEX data access, not of the watch or the script itself.
- The advantage is that the script runs directly on the watch and does not require Home Assistant, a smart-home server, a PC, or any additional setup. It also would run for everyone and does not require an API token or anything like that.
- If real-time prices are required, the data source can be replaced with a suitable paid or real-time API, for example:
- A paid MOEX market data subscription;
- A broker's API;
- Another real-time market data provider.
- In other words, this script prioritizes simplicity and standalone operation over real-time market data.
- I like the very opportunity to occasionally check the current price of an asset without having to log into a phone or terminal. For more accurate values, I use price notifications in the broker's app.
SETTINGS
In code look for section ====== START OF USER SETTINGS ======
!!! IMPORTANT NOTE - Settings!!!
- You must specify the asset type. If you specify it incorrectly or do not specify it, the script will not work.
- TICKER_LETTERS must not exceed the actual length of TICKER.
For example, if Ticker = "T", set TICKER_LETTERS = 1. Setting it to 2 or higher will cause the script to fail.
For Ticker = "SBER", you can use any value from 0 to 4. Values 5+ display the full ticker.
1. Market Type
Select the type of instrument:
self.MARKET_TYPE = 0 — MOEX stock
self.MARKET_TYPE = 1 — MOEX futures
Stock examples:
0 → SBER
0 → BSPB
0 → PHOR
Futures examples:
1 → CRU6
1 → SiU6
1 → BRU6
2. Specifying the Ticker
self.TICKER = "CRU6"
Enter the MOEX security ticker.
For stocks:
SBER
T
PHOR
For futures:
CRU6
SiU6
BRU6
3. Adjust Ticker Length
self.TICKER_LETTERS = 2
Controls how many characters of the ticker are displayed:
0 — hide ticker
1 — C
2 — CR
3 — CRU
4 — CRU6
5+ — full ticker
For example:
CRU6 + 2 → CR 123.45
CRU6 + 4 → CRU6 123.45
4. Ticker Name Color
self.TICKER_COLOR = 0xFFFF00
Sets the ticker color using 0xRRGGBB format.
Examples:
0xFFFFFF — White
0xFF0000 — Red
0x00FF00 — Green
0x0000FF — Blue
0xFFFF00 — Yellow
0x00FFFF — Cyan
0xFF00FF — Magenta
5. Price Color Mode
self.PRICE_COLOR_MODE = 2
Controls the price color:
0 — always white
1 — use the custom PRICE_COLOR
2 — automatically use green/red
In automatic mode (Just like it shows in an any broker APP or Terminal):
Green — current price is higher than the previous received price
Red — current price is lower than the previous received price
White — price has not changed
The automatic mode compares the current price with the previous price received by the script, not with the previous day's closing price.
6. Custom Price Color
self.PRICE_COLOR = 0xFFFFFF
Used when:
PRICE_COLOR_MODE = 1
Uses the same 0xRRGGBB color format as the ticker. (See point 4 for examples)
7. Price Update Interval
self.UPDATE_TICKS = 10
Controls how frequently the script requests a new price.
Approximate values:
1 — every ~1 second (can be out of memory on ULANZI TC001)
5 — every ~5 seconds (can be out of memory on ULANZI TC001, but works for me)
10 or more — every ~10 seconds or more (recommended)
Lower values provide more frequent updates but increase CPU, memory and network usage.
For the ULANZI TC001, 10 seconds or more is recommended if you want to minimize resource usage.
8. Text Gap
self.GAP = 2
Controls the distance in pixels between the ticker and the price.
For example:
CR 123.45
The value determines the space between CR and 123.45.
TROUBLESHOOTING
If the script does not work, displays an error, fails to load values, or shows incorrect values (even after accounting for the 15-minute data delay mentioned at the beginning of the description):
- Make sure you have selected the correct asset type and saved changes (Ctrl+S) (see Setting 1).
- Make sure you have entered the correct ticker symbol and saved changes (Ctrl+S) (see Setting 2).
- Check your internet connection.
- The watch may be running out of available memory if you have installed many similar or other scripts at the same time. Consider adjusting
self.UPDATE_TICKS =to 10 or more so the script will update the data less frequently. Make sure that you saved changes (Ctrl+S) (see Setting 7). - Always consider rebooting the watch. Open the watch's web interface by entering its IP address in your browser, go to System → Maintenance → Reboot, and then press "Sure?". A reboot often resolves temporary glitches, memory-related issues, and other unexpected script behavior.
Vibecoded with ChatGPT, polished by Avemer.
P.S. I wrote this script for myself, and I bought the Ulanzi TC001 watch for this idea. Therefore, I tried to optimize the code as much as possible. My test runtime lasted for 10 hours, without any problems. I hope that it will work well, but if I find errors, I will try to fix them, create similar scripts with different functionality. The code contains explanations, that take some memory to store, if you run into troubles with that, you can always delete them and you can use it as a base for your development. If mistakes occur, do not judge strictly. And I'm a newbie. I hope this script will be useful to someone.
6OxJadW935Wl.ax
# @name MOEX Market
# @desc MOEX stocks and futures price display
# @author Avemer
# @version 1.0
class MOEXMarket
# USER VARIABLES
var MARKET_TYPE
var TICKER
var TICKER_LETTERS
var TICKER_COLOR
var PRICE_COLOR_MODE
var PRICE_COLOR
var UPDATE_TICKS
var GAP
# INTERNAL VARIABLES
var result
var oldPrice
var previousPrice
var ticks
var color
var displayTICKER
# ================ START OF USER SETTINGS ================
def init()
# MARKET TYPE
# 0 = stock
# 1 = futures
self.MARKET_TYPE = 1
# STOCK TIKER
# Stock examples: SBER, BSPB, PHOR
# Futures examples: CRU6, SiU6, BRU6
self.TICKER = "CRU6"
# NUMBER OF TICKER LETTERS DISPLAYED
# 0 = hide
# 1 = S
# 2 = SB
# 3 = SBE
# 4 = SBER
# 5+ = full ticker
self.TICKER_LETTERS = 2
# TICKER COLOR
# Format: 0xRRGGBB
# Examples:
# 0xFFFFFF White
# 0xFF0000 Red
# 0x00FF00 Green
# 0x0000FF Blue
# 0xFFFF00 Yellow
# 0x00FFFF Cyan
# 0xFF00FF Magenta
self.TICKER_COLOR = 0xFFFFFF
# PRICE COLOR MODE
# 0 = white
# 1 = custom PRICE_COLOR
# 2 = green/red automatically
self.PRICE_COLOR_MODE = 2
# CUSTOM PRICE COLOR
# Used when PRICE_COLOR_MODE = 1.
self.PRICE_COLOR = 0xFFFFFF
# UPDATE INTERVAL
# 1 = approximately every 1 second (can be out of memory on ULANZI TC001)
# 5 = approximately every 5 seconds (can be out of memory on ULANZI TC001)
# 10 = approximately every 10 seconds (recommended)
self.UPDATE_TICKS = 10
# DISTANCE BETWEEN TICKER AND PRICE
self.GAP = 2
# ================ END OF USER SETTINGS ================
# INITIAL VALUES
self.result = "..."
self.oldPrice = 0
self.previousPrice = 0
self.ticks = 0
self.color = 0xFFFFFF
self.displayTICKER = ""
# CREATE DISPLAYED TICKER
if self.TICKER_LETTERS <= 0
self.displayTICKER = ""
elif self.TICKER_LETTERS == 1
self.displayTICKER = self.TICKER[0]
elif self.TICKER_LETTERS == 2
self.displayTICKER = self.TICKER[0] + self.TICKER[1]
elif self.TICKER_LETTERS == 3
self.displayTICKER = self.TICKER[0] + self.TICKER[1] + self.TICKER[2]
elif self.TICKER_LETTERS == 4
self.displayTICKER = self.TICKER[0] + self.TICKER[1] + self.TICKER[2] + self.TICKER[3]
else
self.displayTICKER = self.TICKER
end
end
# APPLY PRICE COLOR
def update_color()
# Fixed white mode.
if self.PRICE_COLOR_MODE == 0
self.color = 0xFFFFFF
return
end
# Custom color mode.
if self.PRICE_COLOR_MODE == 1
self.color = self.PRICE_COLOR
return
end
# Automatic green/red mode.
# Compare the current price with
# the previous price received by the script.
if self.previousPrice > 0
if self.oldPrice > self.previousPrice
self.color = 0x00FF00
elif self.oldPrice < self.previousPrice
self.color = 0xFF0000
else
self.color = 0xFFFFFF
end
end
end
# CURRENT PRICE
def on_price(w, st)
if w == nil
return
end
var m
# STOCK
if self.MARKET_TYPE == 0
m = re.search(
"\"TQBR\"\\s*,\\s*([0-9.]+)",
w
)
# FUTURES
else
m = re.search(
"\"data\":\\s*\\[\\s*\\[\\s*\"[^\"]+\"\\s*,\\s*\"[^\"]+\"\\s*,\\s*([0-9.]+)",
w
)
end
if m == nil
return
end
var newPrice = num(m[1])
if newPrice == nil
return
end
# Save previous price before replacing it.
self.previousPrice = self.oldPrice
# Save current price.
self.oldPrice = newPrice
self.result = m[1]
# Recalculate color.
self.update_color()
end
# MAIN LOOP
def loop()
if self.ticks <= 0
self.ticks = self.UPDATE_TICKS
# CURRENT PRICE
if self.MARKET_TYPE == 0
http.get(
"https://iss.moex.com/iss/engines/stock/markets/shares/securities/" + self.TICKER + ".json?iss.meta=off&iss.only=marketdata&marketdata.columns=SECID,BOARDID,LAST",
/ b, st -> self.on_price(b, st)
)
else
http.get(
"https://iss.moex.com/iss/engines/futures/markets/forts/securities/" + self.TICKER + ".json?iss.meta=off&iss.only=marketdata&marketdata.columns=SECID,BOARDID,LAST",
/ b, st -> self.on_price(b, st)
)
end
end
self.ticks -= 1
end
# DRAW
def draw()
clear()
var tickerWidth = text_ink_width(self.displayTICKER)
var priceWidth = text_ink_width(self.result)
var totalWidth = tickerWidth + self.GAP + priceWidth
var x = int((width() - totalWidth) / 2)
if self.TICKER_LETTERS > 0
text(
x,
7,
self.displayTICKER,
self.TICKER_COLOR
)
end
text(
x + tickerWidth + self.GAP,
7,
self.result,
self.color
)
end
def on_button(btn)
end
end
return MOEXMarket()
Install it on your AWTRIX NG
Your browser writes the script straight to the device on your network. It joins the app rotation right away.
Some browsers refuse to talk to a device on your network from a public page. Download the flow and paste it into the Scripts tab of your device, or install it from a terminal:
More flows for AWTRIX NG Scripts or Miscellaneous
Something wrong with this flow? Report it.