### Go Documentation Comment Example Source: https://github.com/rodrigo-brito/ninjabot/blob/main/CONTRIBUTING.md Illustrates how to document exported types and interfaces in Go. Comments should be complete sentences starting with the name of the thing being described. ```go // Strategy defines the interface that all trading strategies must implement. // A strategy receives candle data and makes trading decisions through the broker. type Strategy interface { // Timeframe returns the time interval for strategy execution (e.g., "1h", "1d"). Timeframe() string } ``` -------------------------------- ### Install Ninjabot Source: https://github.com/rodrigo-brito/ninjabot/blob/main/readme.md Use the Go toolchain to install the Ninjabot framework or the CLI tool. ```bash go get -u github.com/rodrigo-brito/ninjabot/... ``` ```bash go install github.com/rodrigo-brito/ninjabot/cmd/ninjabot@latest ``` -------------------------------- ### Verify Development Setup with Tests Source: https://github.com/rodrigo-brito/ninjabot/blob/main/CONTRIBUTING.md Run tests to verify your development environment setup. The `make test` command is a convenient shortcut. ```bash make test ``` ```bash go test -race -cover ./... ``` -------------------------------- ### Install Development Tools Source: https://github.com/rodrigo-brito/ninjabot/blob/main/CONTRIBUTING.md Install essential development tools like golangci-lint for code linting and mockery for generating mocks. ```bash # Install golangci-lint for linting go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest # Install mockery for generating mocks go install github.com/vektra/mockery/v2@latest ``` -------------------------------- ### View Documentation Locally Source: https://github.com/rodrigo-brito/ninjabot/blob/main/CONTRIBUTING.md Command to start a local godoc server for viewing project documentation. ```bash godoc -http=:6060 # Then visit http://localhost:6060/pkg/github.com/rodrigo-brito/ninjabot/ ``` -------------------------------- ### Go Error Handling Example Source: https://github.com/rodrigo-brito/ninjabot/blob/main/CONTRIBUTING.md Demonstrates correct error wrapping with context using fmt.Errorf. Avoid using log.Fatal in library code. ```go // Good func (b *Bot) Start(ctx context.Context) error { if err := b.validate(); err != nil { return fmt.Errorf("validation failed: %w", err) } return nil } // Bad func (b *Bot) Start(ctx context.Context) { if err := b.validate(); err != nil { log.Fatal(err) // Don't panic/fatal in library code } } ``` -------------------------------- ### Turtle Trading Strategy Example Source: https://github.com/rodrigo-brito/ninjabot/blob/main/coverage_report.txt Implements the Turtle trading strategy. Requires Timeframe, WarmupPeriod, and Indicators. ```go strategy.NewTurtle( Timeframe: time.Minute, WarmupPeriod: 100, Indicators: []string{"donchian"}, ) ``` -------------------------------- ### Conventional Commit Message Example (docs) Source: https://github.com/rodrigo-brito/ninjabot/blob/main/CONTRIBUTING.md Example of a conventional commit message for documentation changes only. ```text docs(readme): update installation instructions Add prerequisites section and clarify Go version requirements. ``` -------------------------------- ### OCO Sell Strategy Example Source: https://github.com/rodrigo-brito/ninjabot/blob/main/coverage_report.txt Implements an OCO (One-Cancels-the-Other) sell strategy. Requires Timeframe, WarmupPeriod, and Indicators. ```go strategy.NewOCosellStrategy( Timeframe: time.Minute, WarmupPeriod: 100, Indicators: []string{"ema", "rsi"}, ) ``` -------------------------------- ### Go Table-Driven Test Example Source: https://github.com/rodrigo-brito/ninjabot/blob/main/CONTRIBUTING.md Shows the structure for table-driven tests in Go using t.Run for subtests. Use meaningful test names. ```go func TestBot_Start_WithValidConfig_Succeeds(t *testing.T) { tests := []struct { name string config Config wantErr bool }{ { name: "valid config", config: validConfig(), wantErr: false, }, // more test cases... } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // test implementation }) } } ``` -------------------------------- ### Pull Request Title Format Example Source: https://github.com/rodrigo-brito/ninjabot/blob/main/CONTRIBUTING.md Examples of pull request titles following the conventional commit format. ```text feat(exchange): add support for Coinbase fix(bot): prevent race condition in order processing docs(contributing): add commit message guidelines ``` -------------------------------- ### High-Frequency Strategy with Trailing Stop (Go) Source: https://context7.com/rodrigo-brito/ninjabot/llms.txt Implement the HighFrequencyStrategy interface for strategies requiring intra-candle logic, such as trailing stops. This example shows how to manage trailing stops using OnCandle and OnPartialCandle callbacks. ```go package strategies import ( "github.com/rodrigo-brito/ninjabot" "github.com/rodrigo-brito/ninjabot/indicator" "github.com/rodrigo-brito/ninjabot/model" "github.com/rodrigo-brito/ninjabot/service" "github.com/rodrigo-brito/ninjabot/strategy" "github.com/rodrigo-brito/ninjabot/tools" "github.com/rodrigo-brito/ninjabot/tools/log" ) type TrailingStrategy struct { trailingStop map[string]*tools.TrailingStop } func NewTrailingStrategy(pairs []string) strategy.HighFrequencyStrategy { s := &TrailingStrategy{ trailingStop: make(map[string]*tools.TrailingStop), } for _, pair := range pairs { s.trailingStop[pair] = tools.NewTrailingStop() } return s } func (t TrailingStrategy) Timeframe() string { return "4h" } func (t TrailingStrategy) WarmupPeriod() int { return 21 } func (t TrailingStrategy) Indicators(df *model.Dataframe) []strategy.ChartIndicator { df.Metadata["ema"] = indicator.EMA(df.Close, 8) df.Metadata["sma"] = indicator.SMA(df.Close, 21) return nil } // OnCandle - called on complete candles for entry signals func (t TrailingStrategy) OnCandle(df *model.Dataframe, broker service.Broker) { asset, quote, err := broker.Position(df.Pair) if err != nil { log.Error(err) return } // Entry condition if quote > 10.0 && asset*df.Close.Last(0) < 10 && df.Metadata["ema"].Crossover(df.Metadata["sma"]) { _, err = broker.CreateOrderMarketQuote(ninjabot.SideTypeBuy, df.Pair, quote) if err != nil { log.Error(err) return } // Start trailing stop from entry price with initial stop at candle low t.trailingStop[df.Pair].Start(df.Close.Last(0), df.Low.Last(0)) } } // OnPartialCandle - called on every tick for real-time trailing stop updates func (t TrailingStrategy) OnPartialCandle(df *model.Dataframe, broker service.Broker) { trailing := t.trailingStop[df.Pair] if trailing == nil { return } // Update trailing stop and check if triggered if trailing.Update(df.Close.Last(0)) { asset, _, err := broker.Position(df.Pair) if err != nil { log.Error(err) return } if asset > 0 { _, err = broker.CreateOrderMarket(ninjabot.SideTypeSell, df.Pair, asset) if err != nil { log.Error(err) return } trailing.Stop() } } } ``` -------------------------------- ### EMA Cross Strategy Example Source: https://github.com/rodrigo-brito/ninjabot/blob/main/coverage_report.txt Implements an EMA Cross trading strategy. Requires Timeframe, WarmupPeriod, and Indicators to be defined. ```go strategy.NewEMACrossStrategy( Timeframe: time.Minute, WarmupPeriod: 100, Indicators: []string{"ema", "ema"}, ) ``` -------------------------------- ### Conventional Commit Message Example (feat) Source: https://github.com/rodrigo-brito/ninjabot/blob/main/CONTRIBUTING.md Example of a conventional commit message for a new feature. Follows the format (): with an optional body and footer. ```text feat(strategy): add support for custom indicators Add ability to register custom indicators in strategies. This allows users to implement their own technical indicators beyond the built-in ones. Closes #123 ``` -------------------------------- ### Get Binance Account Information Source: https://github.com/rodrigo-brito/ninjabot/blob/main/coverage_report.txt Fetches account information, including balances and trading status. ```go exchange.Account() ``` -------------------------------- ### Conventional Commit Message Example (fix) Source: https://github.com/rodrigo-brito/ninjabot/blob/main/CONTRIBUTING.md Example of a conventional commit message for a bug fix. Includes a subject, body explaining the fix, and references the issue closed. ```text fix(exchange): handle rate limiting correctly Previously, rate limit errors were not properly handled, causing the bot to crash. Now we retry with exponential backoff. Fixes #456 ``` -------------------------------- ### Trailing Stop Strategy Example Source: https://github.com/rodrigo-brito/ninjabot/blob/main/coverage_report.txt Implements a trailing stop loss strategy. Requires Timeframe, WarmupPeriod, and Indicators. OnPartialCandle can be used for partial updates. ```go strategy.NewTrailingStop( Timeframe: time.Minute, WarmupPeriod: 100, Indicators: []string{"sma", "atr"}, ) ``` -------------------------------- ### Get Binance Position Source: https://github.com/rodrigo-brito/ninjabot/blob/main/coverage_report.txt Retrieves current position information for a given symbol. ```go exchange.Position("BTC/USDT") ``` -------------------------------- ### Get Account Balances Source: https://context7.com/rodrigo-brito/ninjabot/llms.txt Retrieve all account balances, including free and locked amounts for each asset, using the `Account` method. Iterate through the balances to display them. ```go // Get account balances account, err := broker.Account() for _, balance := range account.Balances { fmt.Printf("%s: Free=%.4f, Locked=%.4f\n", balance.Asset, balance.Free, balance.Lock) } ``` -------------------------------- ### Get Binance Orders Source: https://github.com/rodrigo-brito/ninjabot/blob/main/coverage_report.txt Retrieves a list of orders for a given symbol. Use Order to fetch a single order by ID. ```go exchange.Orders("BTC/USDT") ``` -------------------------------- ### Implement Trading Strategy with CrossEMA Source: https://context7.com/rodrigo-brito/ninjabot/llms.txt Define a trading strategy by implementing the `Strategy` interface. This example, `CrossEMA`, uses Exponential Moving Average (EMA) and Simple Moving Average (SMA) crossovers for trading signals. It specifies the timeframe, warmup period, calculates indicators, and defines trade execution logic for buying and selling assets. ```go package strategies import ( "github.com/rodrigo-brito/ninjabot" "github.com/rodrigo-brito/ninjabot/indicator" "github.com/rodrigo-brito/ninjabot/model" "github.com/rodrigo-brito/ninjabot/service" "github.com/rodrigo-brito/ninjabot/strategy" "github.com/rodrigo-brito/ninjabot/tools/log" ) type CrossEMA struct{} // Timeframe returns the candle interval for strategy execution func (e CrossEMA) Timeframe() string { return "4h" // Options: 1m, 5m, 15m, 30m, 1h, 2h, 4h, 12h, 1d, 1w } // WarmupPeriod is the number of candles needed before strategy starts func (e CrossEMA) WarmupPeriod() int { return 22 // Must be >= longest indicator period } // Indicators calculates technical indicators and stores them in Dataframe.Metadata func (e CrossEMA) Indicators(df *model.Dataframe) []strategy.ChartIndicator { df.Metadata["ema8"] = indicator.EMA(df.Close, 8) df.Metadata["sma21"] = indicator.SMA(df.Close, 21) // Return chart indicators for visualization return []strategy.ChartIndicator{ { Overlay: true, GroupName: "Moving Averages", Time: df.Time, Metrics: []strategy.IndicatorMetric{ {Values: df.Metadata["ema8"], Name: "EMA 8", Color: "red", Style: strategy.StyleLine}, {Values: df.Metadata["sma21"], Name: "SMA 21", Color: "blue", Style: strategy.StyleLine}, }, }, } } // OnCandle is called after each candle close - implement your trading logic here func (e *CrossEMA) OnCandle(df *model.Dataframe, broker service.Broker) { closePrice := df.Close.Last(0) // Get current position assetPosition, quotePosition, err := broker.Position(df.Pair) if err != nil { log.Error(err) return } // Buy signal: EMA crosses above SMA and we have quote currency if quotePosition >= 10 && df.Metadata["ema8"].Crossover(df.Metadata["sma21"]) { amount := quotePosition / closePrice _, err := broker.CreateOrderMarket(ninjabot.SideTypeBuy, df.Pair, amount) if err != nil { log.Error(err) } return } // Sell signal: EMA crosses below SMA and we have asset if assetPosition > 0 && df.Metadata["ema8"].Crossunder(df.Metadata["sma21"]) { _, err := broker.CreateOrderMarket(ninjabot.SideTypeSell, df.Pair, assetPosition) if err != nil { log.Error(err) } } } ``` -------------------------------- ### Ninjabot Technical Indicators with TA-Lib Source: https://context7.com/rodrigo-brito/ninjabot/llms.txt Demonstrates the usage of various technical indicators provided by Ninjabot, which are wrappers around TA-Lib. All indicators accept a Series and return a Series. Ensure TA-Lib is correctly installed. ```go import "github.com/rodrigo-brito/ninjabot/indicator" // Moving Averages ema := indicator.EMA(df.Close, 12) // Exponential Moving Average sma := indicator.SMA(df.Close, 20) // Simple Moving Average wma := indicator.WMA(df.Close, 14) // Weighted Moving Average dema := indicator.DEMA(df.Close, 14) // Double EMA tema := indicator.TEMA(df.Close, 14) // Triple EMA kama := indicator.KAMA(df.Close, 30) // Kaufman Adaptive MA // Bollinger Bands - returns upper, middle, lower bands upper, middle, lower := indicator.BB(df.Close, 20, 2.0, indicator.TypeSMA) // MACD - returns macd line, signal line, histogram macd, signal, hist := indicator.MACD(df.Close, 12, 26, 9) // Momentum Indicators rsi := indicator.RSI(df.Close, 14) // Relative Strength Index stochK, stochD := indicator.Stoch(df.High, df.Low, df.Close, // Stochastic 14, 3, indicator.TypeSMA, 3, indicator.TypeSMA) cci := indicator.CCI(df.High, df.Low, df.Close, 20) // Commodity Channel Index mfi := indicator.MFI(df.High, df.Low, df.Close, df.Volume, 14) // Money Flow Index willr := indicator.WilliamsR(df.High, df.Low, df.Close, 14) // Williams %R adx := indicator.ADX(df.High, df.Low, df.Close, 14) // Average Directional Index // Volatility Indicators atr := indicator.ATR(df.High, df.Low, df.Close, 14) // Average True Range natr := indicator.NATR(df.High, df.Low, df.Close, 14) // Normalized ATR trange := indicator.TRANGE(df.High, df.Low, df.Close) // True Range // Volume Indicators obv := indicator.OBV(df.Close, df.Volume) // On Balance Volume ad := indicator.Ad(df.High, df.Low, df.Close, df.Volume) // Accumulation/Distribution // Trend Indicators sar := indicator.SAR(df.High, df.Low, 0.02, 0.2) // Parabolic SAR ``` ```go import "github.com/rodrigo-brito/ninjabot/indicator" import "github.com/rodrigo-brito/ninjabot/strategy" import "github.com/rodrigo-brito/ninjabot/model" // Use in strategy func (s *MyStrategy) Indicators(df *model.Dataframe) []strategy.ChartIndicator { df.Metadata["rsi"] = indicator.RSI(df.Close, 14) df.Metadata["ema"] = indicator.EMA(df.Close, 20) // Check for oversold condition if df.Metadata["rsi"].Last(0) < 30 { // RSI oversold signal } return nil } ``` -------------------------------- ### Fetch Binance Candles by Period Source: https://github.com/rodrigo-brito/ninjabot/blob/main/coverage_report.txt Fetches historical candles within a specified start and end time. CandlesByLimit fetches a fixed number of candles. ```go exchange.CandlesByPeriod("BTC/USDT", time.Minute*15, time.Now().Add(-time.Hour*24), time.Now()) ``` -------------------------------- ### NewDownloader with Interval and Days Source: https://github.com/rodrigo-brito/ninjabot/blob/main/coverage_report.txt Initializes a new downloader with specified interval and days. Use this to configure data fetching parameters. ```go downloader.NewDownloader( WithInterval(time.Minute*15), WithDays(100), ) ``` -------------------------------- ### Run Paper Trading Simulation with Binance Data Source: https://context7.com/rodrigo-brito/ninjabot/llms.txt This Go code sets up a paper trading environment using Binance for live market data. It configures a simulated wallet with specific fees and an initial balance, then runs a trading strategy with charting capabilities. Ensure all necessary packages are imported. ```go package main import ( "context" "github.com/rodrigo-brito/ninjabot" "github.com/rodrigo-brito/ninjabot/exchange" "github.com/rodrigo-brito/ninjabot/plot" "github.com/rodrigo-brito/ninjabot/plot/indicator" "github.com/rodrigo-brito/ninjabot/storage" "github.com/rodrigo-brito/ninjabot/tools/log" ) func main() { ctx := context.Background() settings := ninjabot.Settings{ Pairs: []string{"BTCUSDT", "ETHUSDT", "BNBUSDT"}, } // Connect to Binance for real-time data (no credentials needed for public data) binance, err := exchange.NewBinance(ctx) if err != nil { log.Fatal(err) } storage, err := storage.FromMemory() if err != nil { log.Fatal(err) } // Create paper wallet with simulated fees and initial balance paperWallet := exchange.NewPaperWallet( ctx, "USDT", exchange.WithPaperFee(0.001, 0.001), // 0.1% maker/taker fees exchange.WithPaperAsset("USDT", 10000), exchange.WithDataFeed(binance), ) strategy := &CrossEMA{} chart, err := plot.NewChart( plot.WithCustomIndicators( indicator.EMA(8, "red"), indicator.SMA(21, "blue"), ), ) if err != nil { log.Fatal(err) } bot, err := ninjabot.NewBot( ctx, settings, paperWallet, strategy, ninjabot.WithStorage(storage), ninjabot.WithPaperWallet(paperWallet), ninjabot.WithCandleSubscription(chart), ninjabot.WithOrderSubscription(chart), ) if err != nil { log.Fatal(err) } // Start chart server in background go func() { if err := chart.Start(); err != nil { log.Fatal(err) } }() // Run paper trading - blocks until context cancelled if err := bot.Run(ctx); err != nil { log.Fatal(err) } } ``` -------------------------------- ### Configure Binance Exchange Source: https://github.com/rodrigo-brito/ninjabot/blob/main/coverage_report.txt Sets up a Binance exchange client with various options. Use WithBinanceCredentials for API keys and WithTestNet for the test environment. ```go exchange.NewBinance( WithBinanceCredentials("key", "secret"), WithBinanceHeikinAshiCandle(), WithMetadataFetcher(), WithTestNet(), WithCustomMainAPIEndpoint("https://api.binance.com"), WithCustomTestnetAPIEndpoint("https://testnet.binance.vision"), ) ``` -------------------------------- ### Paper Trading Configuration Source: https://context7.com/rodrigo-brito/ninjabot/llms.txt How to initialize a paper wallet for simulated trading using live market data. ```APIDOC ## Paper Trading (Live Simulation) ### Description Paper trading connects to live market data but executes trades on a simulated wallet, allowing real-time strategy testing without financial risk. ### Configuration - **exchange.NewPaperWallet(ctx, baseAsset, options...)**: Initializes a new paper wallet. - **exchange.WithPaperFee(maker, taker)**: Sets simulated trading fees. - **exchange.WithPaperAsset(asset, amount)**: Sets the initial balance for a specific asset. - **exchange.WithDataFeed(exchange)**: Connects the paper wallet to a live data feed (e.g., Binance). ``` -------------------------------- ### Run Backtest with Historical Data in Go Source: https://context7.com/rodrigo-brito/ninjabot/llms.txt This Go code demonstrates how to set up and run a backtest using historical CSV data. It configures the bot with specific settings, loads data from CSV files for multiple trading pairs, initializes a paper wallet, and sets up a chart for visualization. The backtest is executed using the bot's Run method, and performance summaries are printed. ```go package main import ( "context" "github.com/rodrigo-brito/ninjabot" "github.com/rodrigo-brito/ninjabot/exchange" "github.com/rodrigo-brito/ninjabot/plot" "github.com/rodrigo-brito/ninjabot/plot/indicator" "github.com/rodrigo-brito/ninjabot/storage" "github.com/rodrigo-brito/ninjabot/tools/log" ) func main() { ctx := context.Background() settings := ninjabot.Settings{ Pairs: []string{"BTCUSDT", "ETHUSDT"}, } strategy := &CrossEMA{} // Load historical data from CSV files csvFeed, err := exchange.NewCSVFeed( strategy.Timeframe(), exchange.PairFeed{ Pair: "BTCUSDT", File: "testdata/btc-1h.csv", Timeframe: "1h", }, exchange.PairFeed{ Pair: "ETHUSDT", File: "testdata/eth-1h.csv", Timeframe: "1h", }, ) if err != nil { log.Fatal(err) } // Use in-memory storage for backtest storage, err := storage.FromMemory() if err != nil { log.Fatal(err) } // Create paper wallet with initial balance wallet := exchange.NewPaperWallet( ctx, "USDT", exchange.WithPaperAsset("USDT", 10000), exchange.WithDataFeed(csvFeed), ) // Create chart for visualization chart, err := plot.NewChart( plot.WithStrategyIndicators(strategy), plot.WithCustomIndicators(indicator.RSI(14, "purple")), plot.WithPaperWallet(wallet), ) if err != nil { log.Fatal(err) } // Create bot with backtest mode enabled bot, err := ninjabot.NewBot( ctx, settings, wallet, strategy, ninjabot.WithBacktest(wallet), ninjabot.WithStorage(storage), ninjabot.WithCandleSubscription(chart), ninjabot.WithOrderSubscription(chart), ninjabot.WithLogLevel(log.WarnLevel), ) if err != nil { log.Fatal(err) } // Run backtest if err := bot.Run(ctx); err != nil { log.Fatal(err) } // Print performance summary bot.Summary() // Display interactive chart at http://localhost:8080 if err := chart.Start(); err != nil { log.Fatal(err) } } /* Expected output: +---------+--------+-----+------+--------+--------+-----+----------+-----------+ | PAIR | TRADES | WIN | LOSS | % WIN | PAYOFF | SQN | PROFIT | VOLUME | +---------+--------+-----+------+--------+--------+-----+----------+-----------+ | ETHUSDT | 9 | 6 | 3 | 66.7 % | 3.407 | 1.3 | 21748.41 | 407769.64 | | BTCUSDT | 14 | 6 | 8 | 42.9 % | 5.929 | 1.5 | 13511.66 | 448030.05 | +---------+--------+-----+------+--------+--------+-----+----------+-----------+ | TOTAL | 23 | 12 | 11 | 52.2 % | 4.942 | 1.4 | 35260.07 | 855799.68 | +---------+--------+-----+------+--------+--------+-----+----------+-----------+ */ ``` -------------------------------- ### Download Go Dependencies Source: https://github.com/rodrigo-brito/ninjabot/blob/main/CONTRIBUTING.md Download all necessary Go module dependencies for the project. ```bash go mod download ``` -------------------------------- ### Configure Storage Backends Source: https://context7.com/rodrigo-brito/ninjabot/llms.txt Persist orders using in-memory, file-based, or SQL database storage backends. ```go import "github.com/rodrigo-brito/ninjabot/storage" // In-memory storage (lost on restart) store, err := storage.FromMemory() // File-based storage using BuntDB store, err := storage.FromFile("ninjabot.db") // SQL database (SQLite, PostgreSQL, MySQL via GORM) import "gorm.io/driver/sqlite" import "gorm.io/gorm" db, _ := gorm.Open(sqlite.Open("trades.db"), &gorm.Config{}) store := storage.FromSQL(db) // Use in bot bot, err := ninjabot.NewBot( ctx, settings, exchange, strategy, ninjabot.WithStorage(store), ) ``` -------------------------------- ### Run Backtesting Strategy Source: https://github.com/rodrigo-brito/ninjabot/blob/main/readme.md Execute a custom strategy for backtesting using the Go runtime. ```bash go run examples/backtesting/main.go ``` -------------------------------- ### Configure Chart Visualization Source: https://context7.com/rodrigo-brito/ninjabot/llms.txt Create interactive candlestick charts with strategy indicators or custom indicators, and subscribe to bot events. ```go import ( "github.com/rodrigo-brito/ninjabot/plot" "github.com/rodrigo-brito/ninjabot/plot/indicator" ) // Create chart with strategy indicators automatically included chart, err := plot.NewChart( plot.WithPort(8080), // Default port plot.WithStrategyIndicators(strategy), // Include strategy indicators plot.WithPaperWallet(wallet), // Show equity curve plot.WithDebug(), // Disable JS minification ) // Or with custom indicators chart, err := plot.NewChart( plot.WithCustomIndicators( indicator.RSI(14, "purple"), indicator.EMA(8, "red"), indicator.SMA(21, "blue"), indicator.BollingerBands(20, 2.0, "blue", "gray", "gray"), indicator.MACD(12, 26, 9, "blue", "orange", "gray"), indicator.OBV("green"), ), ) // Subscribe chart to bot events bot, err := ninjabot.NewBot( ctx, settings, exchange, strategy, ninjabot.WithCandleSubscription(chart), ninjabot.WithOrderSubscription(chart), ) // Start chart server (blocking) // Access at http://localhost:8080 // Enhanced view at http://localhost:8080/enhanced err := chart.Start() ``` -------------------------------- ### Create Market Orders Source: https://context7.com/rodrigo-brito/ninjabot/llms.txt Use `CreateOrderMarket` for immediate execution at the current price. Specify the side, pair, and quantity. `CreateOrderMarketQuote` allows specifying the order amount in the quote currency. ```go // Market order - executes immediately at current market price order, err := broker.CreateOrderMarket(model.SideTypeBuy, "BTCUSDT", 0.001) // Buy 0.001 BTC order, err := broker.CreateOrderMarket(model.SideTypeSell, "BTCUSDT", 0.001) // Sell 0.001 BTC // Market order by quote amount - specify amount in quote currency order, err := broker.CreateOrderMarketQuote(model.SideTypeBuy, "BTCUSDT", 100.0) // Buy $100 worth of BTC ``` -------------------------------- ### Bot Configuration Options Source: https://context7.com/rodrigo-brito/ninjabot/llms.txt Customize bot behavior using various Option functions during initialization. ```go bot, err := ninjabot.NewBot( ctx, settings, exchange, strategy, // Enable backtest mode (required for CSV backtesting) ninjabot.WithBacktest(paperWallet), // Use paper wallet for simulation ninjabot.WithPaperWallet(paperWallet), // Custom storage backend ninjabot.WithStorage(storage), // Set log level (DebugLevel, InfoLevel, WarnLevel, ErrorLevel) ninjabot.WithLogLevel(log.InfoLevel), // Subscribe to candle events (for charts, logging, etc.) ninjabot.WithCandleSubscription(candleSubscriber), // Subscribe to order events ninjabot.WithOrderSubscription(orderSubscriber), // Custom notifier (email, Slack, etc.) ninjabot.WithNotifier(customNotifier), ) ``` -------------------------------- ### Get Specific Order by ID Source: https://context7.com/rodrigo-brito/ninjabot/llms.txt Fetch details of a specific order using its ID with the `Order` method. This requires the trading pair and the order ID. ```go // Get specific order by ID order, err := broker.Order("BTCUSDT", orderID) ``` -------------------------------- ### Run Go Tests Source: https://github.com/rodrigo-brito/ninjabot/blob/main/CONTRIBUTING.md Commands for executing tests with various configurations including race detection, coverage, and specific package targeting. ```bash go test -race -cover ./... ``` ```bash go test ./exchange/... ``` ```bash go test -run TestBotStart ./... ``` ```bash go test -coverprofile=coverage.out ./... go tool cover -html=coverage.out ``` -------------------------------- ### Get Current Position Source: https://context7.com/rodrigo-brito/ninjabot/llms.txt Retrieve the current holdings for a given trading pair using the `Position` method. It returns the amount of the base asset and the quote asset currently held. ```go // Get current position assetAmount, quoteAmount, err := broker.Position("BTCUSDT") ``` -------------------------------- ### Initialize Ninjabot Instance Source: https://context7.com/rodrigo-brito/ninjabot/llms.txt Use `NewBot` to initialize a Ninjabot instance. Configure trading pairs, optional Telegram notifications, and connect to an exchange like Binance using API credentials. This function sets up order controllers, data feeds, and other essential components. ```go package main import ( "context" "log" "github.com/rodrigo-brito/ninjabot" "github.com/rodrigo-brito/ninjabot/exchange" ) func main() { ctx := context.Background() // Configure trading pairs and optional Telegram notifications settings := ninjabot.Settings{ Pairs: []string{"BTCUSDT", "ETHUSDT"}, Telegram: ninjabot.TelegramSettings{ Enabled: true, Token: "YOUR_TELEGRAM_BOT_TOKEN", Users: []int{123456789}, }, } // Connect to Binance with API credentials binance, err := exchange.NewBinance(ctx, exchange.WithBinanceCredentials("API_KEY", "API_SECRET"), ) if err != nil { log.Fatal(err) } // Initialize strategy and create bot strategy := &MyStrategy{} bot, err := ninjabot.NewBot(ctx, settings, binance, strategy) if err != nil { log.Fatal(err) } // Start the bot - this blocks until context is cancelled if err := bot.Run(ctx); err != nil { log.Fatal(err) } } ``` -------------------------------- ### Create Stop-Loss Orders Source: https://context7.com/rodrigo-brito/ninjabot/llms.txt Utilize `CreateOrderStop` to automatically sell a position when the price drops to a predetermined stop-loss level, helping to limit potential losses. ```go // Stop-loss order - triggers sell when price drops to limit order, err := broker.CreateOrderStop("BTCUSDT", 0.001, 38000.0) // Stop-loss at $38,000 ``` -------------------------------- ### Configure Binance Exchange Connection (Go) Source: https://context7.com/rodrigo-brito/ninjabot/llms.txt Connect to the Binance exchange with various options including API credentials, testnet, Heikin-Ashi candles, custom endpoints, and metadata fetchers. ```go import "github.com/rodrigo-brito/ninjabot/exchange" ctx := context.Background() // Basic connection (public data only) binance, err := exchange.NewBinance(ctx) // With API credentials for trading binance, err := exchange.NewBinance(ctx, exchange.WithBinanceCredentials("API_KEY", "API_SECRET"), ) // Use Binance testnet binance, err := exchange.NewBinance(ctx, exchange.WithBinanceCredentials("TESTNET_API_KEY", "TESTNET_SECRET"), exchange.WithTestNet(), ) // Enable Heikin-Ashi candle conversion binance, err := exchange.NewBinance(ctx, exchange.WithBinanceHeikinAshiCandle(), ) // Custom metadata fetcher (add extra data to each candle) binance, err := exchange.NewBinance(ctx, exchange.WithMetadataFetcher(func(pair string, t time.Time) (string, float64) { // Fetch funding rate, open interest, etc. return "funding_rate", 0.0001 }), ) // Custom API endpoints binance, err := exchange.NewBinance(ctx, exchange.WithCustomMainAPIEndpoint( "https://api.binance.com", "wss://stream.binance.com:9443/ws", "wss://stream.binance.com:9443/stream", ), ) ``` -------------------------------- ### Run Tests and Linting Source: https://github.com/rodrigo-brito/ninjabot/blob/main/CONTRIBUTING.md Execute tests and run linters to ensure code quality and correctness before committing. `make` commands provide convenient shortcuts. ```bash make test make lint # or go test -race -cover ./... golangci-lint run --fix ``` -------------------------------- ### Configure Binance Futures Exchange Source: https://github.com/rodrigo-brito/ninjabot/blob/main/coverage_report.txt Sets up a Binance Futures exchange client. Use WithBinanceFuturesHeikinAshiCandle for Heikin Ashi candles. ```go exchange.NewBinanceFuture( WithBinanceCredentials("key", "secret"), WithBinanceFuturesHeikinAshiCandle(), ) ``` -------------------------------- ### Running All Tests Command Source: https://github.com/rodrigo-brito/ninjabot/blob/main/CONTRIBUTING.md Command to execute all tests within the project using the make utility. ```bash # Run all tests make test ``` -------------------------------- ### Create Binance Market Order Source: https://github.com/rodrigo-brito/ninjabot/blob/main/coverage_report.txt Creates a market order on Binance. Use CreateOrderMarketQuote for orders specified in quote currency. ```go exchange.CreateOrderMarket("BTC/USDT", "buy", "10000", "0.0001") ``` -------------------------------- ### Download Historical Data with Ninjabot CLI (Bash) Source: https://context7.com/rodrigo-brito/ninjabot/llms.txt Use the Ninjabot CLI to download historical candle data from exchanges. Specify pair, timeframe, number of days, and output file. ```bash # Install CLI go install github.com/rodrigo-brito/ninjabot/cmd/ninjabot@latest # Download 30 days of BTCUSDT daily candles ninjabot download --pair BTCUSDT --timeframe 1d --days 30 --output ./btc-1d.csv # Download hourly data ninjabot download --pair ETHUSDT --timeframe 1h --days 90 --output ./eth-1h.csv ``` -------------------------------- ### Configure Telegram Integration Source: https://context7.com/rodrigo-brito/ninjabot/llms.txt Enable Telegram notifications and remote command execution by providing bot settings. ```go settings := ninjabot.Settings{ Pairs: []string{"BTCUSDT"}, Telegram: ninjabot.TelegramSettings{ Enabled: true, Token: "BOT_TOKEN_FROM_BOTFATHER", Users: []int{123456789}, // Authorized user IDs }, } // Telegram commands available: // /status - Check bot status (running/stopped) // /balance - Show wallet balances // /profit - Show trading performance summary // /start - Start the bot // /stop - Stop the bot // /buy BTCUSDT 100 - Buy $100 worth of BTC // /buy BTCUSDT 50% - Buy with 50% of available quote // /sell BTCUSDT 0.001 - Sell 0.001 BTC // /sell BTCUSDT 100% - Sell entire position ``` -------------------------------- ### Create Limit Orders Source: https://context7.com/rodrigo-brito/ninjabot/llms.txt Place `CreateOrderLimit` orders to execute trades only when the market price reaches a specified limit. This is useful for buying at a lower price or selling at a higher price than the current market. ```go // Limit order - executes when price reaches specified limit order, err := broker.CreateOrderLimit(model.SideTypeBuy, "BTCUSDT", 0.001, 40000.0) // Buy at $40,000 order, err := broker.CreateOrderLimit(model.SideTypeSell, "BTCUSDT", 0.001, 50000.0) // Sell at $50,000 ``` -------------------------------- ### Download Historical Data Programmatically (Go) Source: https://context7.com/rodrigo-brito/ninjabot/llms.txt Download historical candle data programmatically using the Ninjabot downloader package. Specify the exchange, pair, timeframe, output file, and date range. ```go // Programmatic download import "github.com/rodrigo-brito/ninjabot/download" ctx := context.Background() binance, _ := exchange.NewBinance(ctx) downloader := download.NewDownloader(binance) er := downloader.Download( ctx, "BTCUSDT", "1h", "./btc-1h.csv", download.WithDays(30), // Last 30 days // Or: download.WithInterval(startTime, endTime) ) ``` -------------------------------- ### Clone and Navigate Ninjabot Repository Source: https://github.com/rodrigo-brito/ninjabot/blob/main/CONTRIBUTING.md Clone the Ninjabot repository and navigate into the project directory. Replace YOUR-USERNAME with your GitHub username. ```bash git clone https://github.com/YOUR-USERNAME/ninjabot.git cd ninjabot ``` -------------------------------- ### Create Binance Limit Order Source: https://github.com/rodrigo-brito/ninjabot/blob/main/coverage_report.txt Creates a limit order on Binance. Ensure price and quantity are formatted correctly using formatPrice and formatQuantity. ```go exchange.CreateOrderLimit("BTC/USDT", "buy", "10000", "0.0001", "10000") ``` -------------------------------- ### Download Historical Data via CLI Source: https://github.com/rodrigo-brito/ninjabot/blob/main/readme.md Download historical candle data for a specific pair and timeframe to a CSV file. ```bash # Download candles of BTCUSDT to btc.csv file (Last 30 days, timeframe 1D) ninjabot download --pair BTCUSDT --timeframe 1d --days 30 --output ./btc.csv ``` -------------------------------- ### Generate Mocks Source: https://github.com/rodrigo-brito/ninjabot/blob/main/CONTRIBUTING.md Commands to generate mocks using mockery, which are stored in the testdata/mocks/ directory. ```bash make generate # or go generate ./... ``` -------------------------------- ### Fetch Binance Candles by Limit Source: https://github.com/rodrigo-brito/ninjabot/blob/main/coverage_report.txt Fetches a limited number of historical candles for a symbol and timeframe. Use CandlesByPeriod for a date range. ```go exchange.CandlesByLimit("BTC/USDT", time.Minute*15, 100) ``` -------------------------------- ### Create OCO (One-Cancels-Other) Orders Source: https://context7.com/rodrigo-brito/ninjabot/llms.txt The `CreateOrderOCO` method allows setting both a take-profit price and a stop-loss trigger simultaneously. Once one order is filled, the other is automatically canceled. ```go // OCO (One-Cancels-Other) order - take-profit with stop-loss // Parameters: side, pair, size, price (take-profit), stop (trigger), stopLimit (execution) orders, err := broker.CreateOrderOCO( model.SideTypeSell, "BTCUSDT", 0.001, // quantity 50000.0, // take-profit price 38000.0, // stop trigger price 37900.0, // stop limit price ) ``` -------------------------------- ### Broker Order Execution Methods Source: https://context7.com/rodrigo-brito/ninjabot/llms.txt Methods available within the OnCandle callback to manage market, limit, stop-loss, and OCO orders. ```APIDOC ## Broker Order Methods ### Description The Broker interface provides methods for creating and managing different order types, including market, limit, stop-loss, and OCO orders, as well as retrieving account and position data. ### Methods - **CreateOrderMarket(side, pair, quantity)**: Executes a market order immediately. - **CreateOrderMarketQuote(side, pair, quoteAmount)**: Executes a market order based on a specific quote currency amount. - **CreateOrderLimit(side, pair, quantity, price)**: Places a limit order at a specified price. - **CreateOrderStop(pair, quantity, stopPrice)**: Places a stop-loss order. - **CreateOrderOCO(side, pair, quantity, price, stopTrigger, stopLimit)**: Places an OCO order (One-Cancels-Other). - **Cancel(order)**: Cancels an existing order. - **Position(pair)**: Returns the current asset and quote amount for a pair. - **Order(pair, orderID)**: Retrieves a specific order by ID. - **Account()**: Returns the account balances. ``` -------------------------------- ### Define Order Type Constants in Go Source: https://context7.com/rodrigo-brito/ninjabot/llms.txt Defines constants for various order types, including side (BUY/SELL), order type (LIMIT, MARKET, STOP_LOSS, etc.), and status (NEW, FILLED, CANCELED, etc.). ```go // Order types const ( SideTypeBuy SideType = "BUY" SideTypeSell SideType = "SELL" OrderTypeLimit OrderType = "LIMIT" OrderTypeMarket OrderType = "MARKET" OrderTypeStopLoss OrderType = "STOP_LOSS" OrderTypeStopLossLimit OrderType = "STOP_LOSS_LIMIT" OrderTypeTakeProfit OrderType = "TAKE_PROFIT" OrderTypeTakeProfitLimit OrderType = "TAKE_PROFIT_LIMIT" OrderStatusTypeNew OrderStatusType = "NEW" OrderStatusTypeFilled OrderStatusType = "FILLED" OrderStatusTypeCanceled OrderStatusType = "CANCELED" OrderStatusTypePartiallyFilled OrderStatusType = "PARTIALLY_FILLED" ) ``` -------------------------------- ### Convert WebSocket Kline to Candle Source: https://github.com/rodrigo-brito/ninjabot/blob/main/coverage_report.txt Helper function to convert raw WebSocket Kline data from Binance into the Candle struct. ```go exchange.CandleFromWsKline([]interface{}{ "BTCUSDT", // Symbol []interface{}{"1641033600000", "47000.00", "47500.00", "46500.00", "47200.00", "1000.00", "1641037199999", "1000.00", "100", "500.00", "500.00", "1234567890"}, }) ``` -------------------------------- ### Create Feature or Fix Branch Source: https://github.com/rodrigo-brito/ninjabot/blob/main/CONTRIBUTING.md Create a new branch for your changes, either for a new feature or to fix an existing issue. Use descriptive branch names. ```bash git checkout -b feature/my-new-feature # or git checkout -b fix/issue-123 ``` -------------------------------- ### Download Functionality Source: https://github.com/rodrigo-brito/ninjabot/blob/main/coverage_report.txt Provides functionalities for downloading data, with options to configure intervals and days. ```APIDOC ## Download Functionality ### NewDownloader ### Description Creates a new downloader instance. ### Method Constructor ### Endpoint N/A ### Parameters #### Request Body (No specific request body parameters mentioned for constructor, typically options are passed via With functions) ### Request Example ```go downloader := ninjabot.NewDownloader() ``` ## Downloader Options ### WithInterval ### Description Sets the interval for the downloader. ### Method Option ### Endpoint N/A ### Parameters #### Request Body - **interval** (string) - Required - The interval to set (e.g., "1m", "1h", "1d"). ### Request Example ```go downloader := ninjabot.NewDownloader(ninjabot.WithInterval("1h")) ``` ## Downloader Options ### WithDays ### Description Sets the number of days for the downloader. ### Method Option ### Endpoint N/A ### Parameters #### Request Body - **days** (int) - Required - The number of days to download data for. ### Request Example ```go downloader := ninjabot.NewDownloader(ninjabot.WithDays(30)) ``` ## Downloader Functionality ### Download ### Description Initiates the data download process. ### Method Method ### Endpoint N/A ### Parameters #### Request Body - **symbol** (string) - Required - The trading pair symbol (e.g., "BTCUSDT"). - **interval** (string) - Required - The candle interval (e.g., "1h"). - **fromTime** (time.Time) - Required - The start time for the download. ### Request Example ```go err := downloader.Download("BTCUSDT", "1h", startTime) ``` ## Downloader Functionality ### CandlesCount ### Description Sets the number of candles to download. ### Method Method ### Endpoint N/A ### Parameters #### Request Body - **count** (int) - Required - The number of candles to download. ### Request Example ```go data, err := downloader.CandlesCount(1000).Download("BTCUSDT", "1h", startTime) ``` ``` -------------------------------- ### Add Upstream Repository Source: https://github.com/rodrigo-brito/ninjabot/blob/main/CONTRIBUTING.md Add the official Ninjabot repository as an upstream remote to keep your fork updated. ```bash git remote add upstream https://github.com/rodrigo-brito/ninjabot.git ``` -------------------------------- ### Convert Kline to Candle Source: https://github.com/rodrigo-brito/ninjabot/blob/main/coverage_report.txt Helper function to convert raw Kline data from Binance API into the Candle struct. ```go exchange.CandleFromKline([][]string{ "1641033600000", // Open time "47000.00", // Open "47500.00", // High "46500.00", // Low "47200.00", // Close "1000.00", // Volume "1641037199999", // Close time "1000.00", // Quote asset volume "100", // Number of trades "500.00", // Taker buy base asset volume "500.00", // Taker buy quote asset volume "1234567890", // Ignore } ) ``` -------------------------------- ### Subscribe to Binance Candles Source: https://github.com/rodrigo-brito/ninjabot/blob/main/coverage_report.txt Subscribes to real-time candle updates for a given symbol and timeframe. CandlesByLimit and CandlesByPeriod fetch historical data. ```go exchange.CandlesSubscription("BTC/USDT", time.Minute*15) ```