На главную > Блог > Категория > 🐹 Основы программирования на Go: полное руководство для начинающих
Go (или Golang) — язык программирования, разработанный в Google в 2007 году, когда инженеры устали от медленной компиляции C++ и сложности многопоточности в других языках. Главная идея Go — простота, производительность и лёгкость написания надёжного кода. Сегодня на Go написаны Docker, Kubernetes, Terraform, Prometheus, InfluxDB и множество других проектов, которые составляют основу современной облачной инфраструктуры.
Для трейдера Go интересен по нескольким причинам:
В этом руководстве я дам всё, что нужно для старта: установка, синтаксис, работа с массивами и словарями, функции, горутины и каналы, а также практический пример — программа для расчёта простой скользящей средней (SMA).
«Go — это как швейцарский нож для разработчика облачных сервисов. Простой, надёжный и очень острый, когда нужно».
go version.Создайте папку hello, внутри файл main.go со следующим содержимым:
package main
import "fmt"
func main() {
fmt.Println("Hello, трейдер!")
}
Запустите программу:
go run main.go
Вы увидите:
Hello, трейдер!
package main — объявление пакета (для исполняемой программы обязательно main).import "fmt" — импорт пакета для форматированного ввода-вывода.func main() — точка входа в программу.
package main
import "fmt"
func main() {
// Явное объявление
var price float64 = 67400.50
// Вывод типа (int)
var quantity int = 10
// Короткое объявление (только внутри функций)
symbol := "BTC/USDT"
// Несколько переменных
var open, high, low float64 = 67000, 68000, 66500
fmt.Println(price, quantity, symbol, open, high, low)
}
bool — true/false.string — строка.int, int8, int16, int32, int64 — целые числа.float32, float64 — числа с плавающей точкой.byte — псевдоним для uint8 (один байт).rune — псевдоним для int32 (Unicode).const (
pi = 3.14159
appVersion = "1.0.0"
)
price := 68000
sma := 67500
if price > sma {
fmt.Println("Сигнал на покупку")
} else if price < sma {
fmt.Println("Сигнал на продажу")
} else {
fmt.Println("Нет сигнала")
}
// Классический цикл
for i := 0; i < 5; i++ {
fmt.Println("Итерация", i)
}
// Цикл while (через for)
sum := 0
for sum < 100 {
sum += 10
}
// Бесконечный цикл
for {
// break когда нужно
}
var prices [5]float64 = [5]float64{67400, 67850, 68000, 67500, 68200}
prices[0] = 67500
fmt.Println(prices[2]) // 68000
prices := []float64{67400, 67850, 68000, 67500, 68200}
// Добавление элемента
prices = append(prices, 68500)
// Срез срезов
subset := prices[1:4] // [67850, 68000, 67500]
fmt.Println("Средняя цена:", sum(prices)/float64(len(prices)))
trade := map[string]interface{}{
"symbol": "BTC/USDT",
"entry": 67400,
"stop": 67000,
"tp": 68500,
}
fmt.Println(trade["symbol"]) // BTC/USDT
// Добавление элемента
trade["quantity"] = 0.1
// Удаление элемента
delete(trade, "stop")
Функции в Go могут возвращать несколько значений — это удобно для возврата результата и ошибки.
// Функция для расчёта SMA
func sma(prices []float64, period int) (float64, error) {
if len(prices) < period {
return 0, fmt.Errorf("недостаточно данных: нужно %d, получено %d", period, len(prices))
}
sum := 0.0
for i := len(prices) - period; i < len(prices); i++ {
sum += prices[i]
}
return sum / float64(period), nil
}
func main() {
prices := []float64{67400, 67850, 68000, 67500, 68200}
smaValue, err := sma(prices, 3)
if err != nil {
fmt.Println("Ошибка:", err)
return
}
fmt.Printf("SMA 3: %.2f\n", smaValue)
}
func sma(prices []float64, period int) (result float64, err error) {
// ...
result = sum / float64(period)
return // возврат result и err
}
В Go нет классов, но есть структуры с методами. Это основа объектно-ориентированного программирования в Go.
// Определение структуры "Сделка"
type Trade struct {
Symbol string
EntryPrice float64
StopLoss float64
TakeProfit float64
Quantity float64
IsOpen bool
}
// Метод, привязанный к структуре
func (t Trade) PnL(currentPrice float64) float64 {
if !t.IsOpen {
return 0
}
return (currentPrice - t.EntryPrice) * t.Quantity
}
func main() {
// Создание экземпляра
myTrade := Trade{
Symbol: "BTC/USDT",
EntryPrice: 67400,
StopLoss: 67000,
TakeProfit: 68500,
Quantity: 0.1,
IsOpen: true,
}
fmt.Printf("PnL при цене 68000: %.2f\n", myTrade.PnL(68000))
}
Интерфейсы в Go определяют набор методов. Любой тип, реализующий эти методы, автоматически удовлетворяет интерфейсу.
// Интерфейс для стратегии
type Strategy interface {
ShouldBuy(price float64) bool
ShouldSell(price float64) bool
}
// Реализация стратегии SMA Crossover
type SMACrossover struct {
FastPeriod int
SlowPeriod int
Prices []float64
}
func (s *SMACrossover) addPrice(price float64) {
s.Prices = append(s.Prices, price)
}
func (s *SMACrossover) ShouldBuy(price float64) bool {
s.addPrice(price)
if len(s.Prices) < s.SlowPeriod {
return false
}
smaFast := s.calcSMA(s.FastPeriod)
smaSlow := s.calcSMA(s.SlowPeriod)
return smaFast > smaSlow
}
func (s *SMACrossover) ShouldSell(price float64) bool {
// аналогично
return false
}
func (s *SMACrossover) calcSMA(period int) float64 {
sum := 0.0
for i := len(s.Prices) - period; i < len(s.Prices); i++ {
sum += s.Prices[i]
}
return sum / float64(period)
}
func main() {
var strat Strategy = &SMACrossover{FastPeriod: 10, SlowPeriod: 30}
prices := []float64{67400, 67850, 68000, 67500, 68200}
for _, p := range prices {
if strat.ShouldBuy(p) {
fmt.Println("Сигнал на покупку по цене", p)
}
}
}
Горутины — это лёгкие потоки. Каналы — способ общения между ними. Это делает Go идеальным для параллельной обработки данных (например, одновременный расчёт индикаторов для нескольких активов).
package main
import (
"fmt"
"time"
)
// Функция для расчёта SMA в отдельной горутине
func calculateSMA(prices []float64, period int, resultChan chan<- float64) {
sum := 0.0
for i := len(prices) - period; i < len(prices); i++ {
sum += prices[i]
}
sma := sum / float64(period)
resultChan <- sma // отправка результата в канал
}
func main() {
prices := []float64{67400, 67850, 68000, 67500, 68200, 68300, 68100}
// Канал для результатов
resultChan := make(chan float64)
// Запуск трёх параллельных расчётов SMA для разных периодов
go calculateSMA(prices, 3, resultChan)
go calculateSMA(prices, 5, resultChan)
go calculateSMA(prices, 10, resultChan)
// Сбор результатов (порядок не важен)
for i := 0; i < 3; i++ {
smaValue := <-resultChan
fmt.Printf("SMA: %.2f\n", smaValue)
}
time.Sleep(time.Second)
}
Напишем простую программу, которая запрашивает текущую цену BTC/USDT с Binance.
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"time"
)
type PriceResponse struct {
Symbol string `json:"symbol"`
Price string `json:"price"`
}
func getBTCPrice() (float64, error) {
url := "https://api.binance.com/api/v3/ticker/price?symbol=BTCUSDT"
client := &http.Client{Timeout: 10 * time.Second}
resp, err := client.Get(url)
if err != nil {
return 0, err
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return 0, err
}
var priceResp PriceResponse
if err := json.Unmarshal(body, &priceResp); err != nil {
return 0, err
}
var price float64
fmt.Sscanf(priceResp.Price, "%f", &price)
return price, nil
}
func main() {
price, err := getBTCPrice()
if err != nil {
fmt.Println("Ошибка:", err)
return
}
fmt.Printf("Текущая цена BTC/USDT: %.2f\n", price)
}
Go не заменит Python для прототипов и C++ для сверхнизкоуровневых задач. Но он идеален для создания надёжных, быстрых и легко поддерживаемых приложений, которые обрабатывают потоки данных, работают с API и параллельно анализируют несколько инструментов. Именно такие задачи стоят перед трейдером, который хочет автоматизировать свои стратегии.
Начните с малого: установите Go, пройдите интерактивный тур tour.golang.org, напишите функцию для расчёта SMA. Затем добавьте параллельный расчёт для нескольких активов через горутины. Потом подключитесь к WebSocket Binance и получайте котировки в реальном времени. За месяц вы сможете написать своего первого бота, который будет работать быстрее, чем его аналог на Python.
И помните: Go не прощает небрежности, но и не наказывает излишней сложностью. Простота — его главная сила. Пишите чистый код, и Go вознаградит вас скоростью и стабильностью.
«Go — это язык, который заставляет вас думать о простых решениях. И в трейдинге, где сложность убивает депозит, это бесценно».
Дата размещения статьи: 07-06-2026 в 07:23:23