Author Archives: toanalien

Đọc biến môi trường từ file

Theo Nguyên tắc số 3 của The Twelve-Factor App thì cấu hình cần phần tách biệt khỏi source code.

Thông thường cấu hình sẽ được lưu ở biến môi trường hoặc một dịch vụ bên ngoài như AWS Secrets Manager.

Trong Golang, để đọc biến môi trường ta có thể sử dụng code bên dưới

// set biến môi trường
os.Setenv(key, value)

// get biến môi trường
value := os.Getenv(key)

Để đọc biến môi trường được cấu hình từ file (ví dụ như .env) thì ta có thể sử dụng package godotenv

godotenv

go get github.com/joho/godotenv

godotenv cung cấp phương thức Load để đọc file env

// mặc định đọc file .env ở trong thư mục hiện tại
godotenv.Load()

// hoặc chỉ định file
godotenv.Load("/path/to/file/env")

File env hỗ trợ format yaml, tham khảo tài liệu ở đây

viper

Ngoài godotenv thì viper là package phổ biến nhất hỗ trợ các format như JSON, TOML, YAML, HCL, envfile và cả Java properties config file.

go get github.com/spf13/viper
// cấu hình đường dẫn file env
viper.SetConfigFile(".env")

// đọc cấu hình
viper.ReadInConfig()

// đọc giá trị
viper.Get(key)

// xác nhận kiểu dữ liệu
value, ok := viper.Get(key).(string)
// nếu kiểu dữ liệu của `key` là string thì ok trả về true

5 lời khuyên đầu tư với tài khoản nhỏ

silver and gold round coins in box
Photo by NeONBRAND on Unsplash

Khi bắt đầu giao dịch chúng ta muốn kiếm được nhiều tiền và trở thành tỉ phí vào cuối tháng. Động lực tuyệt vời này có thể bị cắt bỏ dễ dàng nếu không tuân thủ theo chiến lược và kế hoạch đơn giản.

Khi tôi bắt đầu giao dịch tôi vào 100$ và mất tất cả chỉ trong tháng. Tôi đã không chú ý đến kế hoạch và quy tắc tài chính cá nhân của mình, điều này khiến tôi thua lỗ rất nhiều trong những bước đầu tiên tham gia giao dịch.

Biết 5 mẹo này sẽ giúp ích cho bạn nếu bạn mới bắt đầu giao dịch và sử dụng tài khoản nhỏ.

1. Thực hiện theo kế hoạch tài chính, KHÔNG BAO GIỜ ALL-IN.

Vâng, để lập kế hoạch tài chính, bạn cần phải nghiên cứu nó trước, nếu bạn không có kiến thức về tài chính. ĐỪNG ALL-IN, đây không phải là trò đùa, hãy dừng lại ngay! NHỎ hay LỚN cũng như nhau trong giao dịch, và hãy xem các giao dịch của bạn một cách cẩn thận.

2. Dùng ít công cụ hơn, giảm số lượng giao dịch.

HÃY TẬP TRUNG. Một lần nữa, ÍT cũng như NHIỀU, NHỎ cũng như LỚN. Tìm hiểu một hoặc hai loại tài sản, tìm hiểu bản chất của chúng và hành vi biểu đồ thông thường. Điều này sẽ giúp bạn tập trung và bắt đầu mở các giao dịch có lãi.

3. Tránh các tài sản biến động mạnh; Giao dịch tài sản có khối lượng lớn.

Chọn một hoặc hai loại tài sản có khối lượng giao dịch lớn, chỉ nên giao dịch mỗi chúng. Đừng tiền vào cổ phiếu hoặc ngoại tệ chỉ vì chúng có giá thấp.

4. Sử dụng khung thời gian cao hơn, không scalping.

Hầu hết các nhà giao dịch mới đều mất tiền trong những tháng đầu tiên chỉ vì họ cố gắng mở rộng quy mô, cảm xúc của bạn trở nên điên cuồng và rủi ro tăng lên nhanh chóng. Bắt đầu thực hiện một-hai giao dịch mỗi tuần và xem nó sẽ diễn ra như thế nào, điều này sẽ giải phóng áp lực và thư giãn.

5. Chấp nhận thua lỗ, lên kế hoạch có thể mất bao nhiêu.

Vấn đề lớn nhất của tất cả các nhà giao dịch là suy nghĩ theo tỷ lệ phần trăm về tổn thất, cách này sẽ chỉ làm tăng tổn thất. Hãy suy nghĩ về tiền bạc và lập kế hoạch cho bạn số tiền thua lỗ có thể chấp nhận được.

Chú thích

Nguồn bài viết https://www.tradingview.com/chart/BTCUSD/cL1mUIVQ-5-TIPS-FOR-SMALL-ACCOUNTS/

Golang on M1

Lỗi

Failed to launch: could not launch process: can not run under Rosetta, check that the installed build of Go is right for your CPU architecture

Nguyên nhân

Do package dlvdlv-dap sai architecture trên M1.

Khắc phục

  • Kiểm tra phiên bản Golang đã cài đặt đúng chưa bằng cách
go env | grep GOARCH
# GOARCH="arm64"

Nếu phiên bản là arm64 trên M1 là đúng, nếu khác thì cần phải cài đặt lại. Download ở đây https://golang.org/dl/

Tiếp theo mở VSCode, gõ Shift + Command + P tìm "Go: Install/Update Tools", click vào dlvdlv-dap chọn ok để install/update.

Bây giờ mở lại debug (Shift + Command + D) sẽ chạy được như ý muốn.

Quản lý phiên bản Node.js

Mình dùng NVM để cài đặt Node.js và có thể chọn được version cần dùng.

Cài đặt

wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash

export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm

Show danh sách các phiên bản Node.js lts

nvm ls-remote --lts
...
       v12.21.0   (LTS: Erbium)
       v12.22.0   (LTS: Erbium)
       v12.22.1   (LTS: Erbium)
       v12.22.2   (LTS: Erbium)
       v12.22.3   (LTS: Erbium)
       v12.22.4   (LTS: Erbium)
       v12.22.5   (Latest LTS: Erbium)
       v14.15.0   (LTS: Fermium)
       v14.15.1   (LTS: Fermium)
       v14.15.2   (LTS: Fermium)
       v14.15.3   (LTS: Fermium)
       v14.15.4   (LTS: Fermium)
       v14.15.5   (LTS: Fermium)
       v14.16.0   (LTS: Fermium)
       v14.16.1   (LTS: Fermium)
       v14.17.0   (LTS: Fermium)
       v14.17.1   (LTS: Fermium)
       v14.17.2   (LTS: Fermium)
       v14.17.3   (LTS: Fermium)
       v14.17.4   (LTS: Fermium)
->     v14.17.5   (Latest LTS: Fermium)

Cài đặt Node.js. Npm sẽ đi kèm

nvm install v14.17.5

v14.17.5 is already installed.
Now using node v14.17.5 (npm v6.14.14)

Calculate MA, SMA indicators in Pandas

Tiếp theo bài viết https://toan.co/prepare-dataset-for-backtest-strategy/ mình sẽ tính các chỉ số SMA, EMA trên Pandas

df['SMA7'] = df.Close.rolling(5).mean()
df['SMA14'] = df.Close.rolling(14).mean()

df['EMA10'] = df.Close.ewm(span=10, adjust=False).mean()
df['EMA20'] = df.Close.ewm(span=20, adjust=False).mean()

# plot
df.head(500)[['SMA7', 'SMA14', 'EMA10', 'EMA20']].plot(figsize=(15, 10))

Confluent Docker in M1

TL;DR:

  • Vì bản docker build sẵn của Confluent cung cấp chỉ chạy được trên amd64 nên để chạy được mình cần build bản riêng cho arm64.
  • Nếu build lại từ đầu bằng cách lấy base image là arm64 rồi install thì tốn công hơn nên mình mod lại bản build của Confluent. Code trong repo bên dưới.
git clone https://github.com/toanalien/cp-docker-images.git
cd cp-docker-images
git checkout v6.2.0
make build-debian

Sample docker-compose.yaml file

---
version: '2'
services:
  zookeeper:
    image: confluentinc/cp-zookeeper:6.2.0
    hostname: zookeeper
    container_name: zookeeper
    ports:
      - "2181:2181"
    environment:
      ZOOKEEPER_CLIENT_PORT: 2181
      ZOOKEEPER_TICK_TIME: 2000

  broker:
    image: confluentinc/cp-server:6.2.0
    hostname: broker
    container_name: broker
    depends_on:
      - zookeeper
    ports:
      - "9092:9092"
      - "9101:9101"
    environment:
      KAFKA_BROKER_ID: 1
      KAFKA_ZOOKEEPER_CONNECT: 'zookeeper:2181'
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://broker:29092,PLAINTEXT_HOST://localhost:9092
      KAFKA_METRIC_REPORTERS: io.confluent.metrics.reporter.ConfluentMetricsReporter
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
      KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
      KAFKA_CONFLUENT_LICENSE_TOPIC_REPLICATION_FACTOR: 1
      KAFKA_CONFLUENT_BALANCER_TOPIC_REPLICATION_FACTOR: 1
      KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
      KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
      KAFKA_JMX_PORT: 9101
      KAFKA_JMX_HOSTNAME: localhost
      KAFKA_CONFLUENT_SCHEMA_REGISTRY_URL: http://schema-registry:8081
      CONFLUENT_METRICS_REPORTER_BOOTSTRAP_SERVERS: broker:29092
      CONFLUENT_METRICS_REPORTER_TOPIC_REPLICAS: 1
      CONFLUENT_METRICS_ENABLE: 'true'
      CONFLUENT_SUPPORT_CUSTOMER_ID: 'anonymous'

  schema-registry:
    image: confluentinc/cp-schema-registry:6.2.0
    hostname: schema-registry
    container_name: schema-registry
    depends_on:
      - broker
    ports:
      - "8081:8081"
    environment:
      SCHEMA_REGISTRY_HOST_NAME: schema-registry
      SCHEMA_REGISTRY_KAFKASTORE_BOOTSTRAP_SERVERS: 'broker:29092'
      SCHEMA_REGISTRY_LISTENERS: http://0.0.0.0:8081

  control-center:
    image: confluentinc/cp-enterprise-control-center:6.2.0
    hostname: control-center
    container_name: control-center
    depends_on:
      - broker
      - schema-registry
    ports:
      - "9021:9021"
    environment:
      CONTROL_CENTER_BOOTSTRAP_SERVERS: 'broker:29092'
      CONTROL_CENTER_CONNECT_CONNECT-DEFAULT_CLUSTER: 'connect:8083'
      CONTROL_CENTER_KSQL_KSQLDB1_URL: "http://ksqldb-server:8088"
      CONTROL_CENTER_KSQL_KSQLDB1_ADVERTISED_URL: "http://localhost:8088"
      CONTROL_CENTER_SCHEMA_REGISTRY_URL: "http://schema-registry:8081"
      CONTROL_CENTER_REPLICATION_FACTOR: 1
      CONTROL_CENTER_INTERNAL_TOPICS_PARTITIONS: 1
      CONTROL_CENTER_MONITORING_INTERCEPTOR_TOPIC_PARTITIONS: 1
      CONFLUENT_METRICS_TOPIC_REPLICATION: 1
      PORT: 9021

  rest-proxy:
    image: confluentinc/cp-kafka-rest:6.2.0
    depends_on:
      - broker
      - schema-registry
    ports:
      - 8082:8082
    hostname: rest-proxy
    container_name: rest-proxy
    environment:
      KAFKA_REST_HOST_NAME: rest-proxy
      KAFKA_REST_BOOTSTRAP_SERVERS: 'broker:29092'
      KAFKA_REST_LISTENERS: "http://0.0.0.0:8082"
      KAFKA_REST_SCHEMA_REGISTRY_URL: 'http://schema-registry:8081'