coinquant

package module
v1.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 21, 2026 License: MIT Imports: 12 Imported by: 0

README

coinquant-go

CoinQuant Golang SDK

A Go client for the CoinQuant Public API

This is an unofficial community package. It is not maintained or endorsed by CoinQuant.

Build, backtest, and ship algorithmic trading strategies from your Go code, with AI in the loop.

Go Reference Go Version License API Docs

Installation · Quick start · Streaming · Backtesting · API reference · FAQ


Why this package?

I built this because I wanted to talk to the CoinQuant API from Go without writing the same HTTP and SSE plumbing every time. CoinQuant lets you describe a trading idea in plain English and turns it into a backtestable strategy; this client wraps the public API so you can do that from your Go program.

It is intentionally thin: you talk to the AI, get a strategy, backtest it, and read the metrics, all in idiomatic Go, with context.Context first and strongly typed requests and responses.

What you get

  • Idiomatic Go — every call takes context.Context first, requests and responses are concrete structs with json tags, no map[string]any guesswork.
  • Full endpoint coverage — all 37 public endpoints: health, chats, strategies, versions, backtests, reports, templates, credits, and community.
  • SSE streaming that actually works — callback-driven streaming for POST /v1/prompts/stream and POST /v1/chats/{chat_id}/messages:stream, with events classified into error, strategy, report, chat, or unknown using CoinQuant's own precedence rules.
  • Backtests without busyworkCreateBacktestAndWait submits a run, polls until it reaches a terminal state, and returns the results plus CSV exports in one call.
  • Schema-only materialization — when the AI returns a strategy schema but no version ID yet, FinalizeChat turns it into a real versioned strategy you can backtest.
  • Actionable errors — a typed APIError carries HTTP status, request_id, machine-readable code, and a human message, so you know what went wrong and can quote a request ID to support.

Installation

go get github.com/tigusigalpa/coinquant-go

Requires Go 1.22 or newer.

Quick start

Grab a token, create a client, and check your balance in a dozen lines:

package main

import (
    "context"
    "fmt"
    "log"
    "os"

    coinquant "github.com/tigusigalpa/coinquant-go"
)

func main() {
    client := coinquant.NewClient(os.Getenv("COINQUANT_TOKEN"))
    ctx := context.Background()

    credits, err := client.GetCredits(ctx)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("available:", credits.AvailableCreditsTotal)
}

Authentication

CoinQuant uses a JWT bearer token. To get one:

  1. Open the CoinQuant web app.
  2. Go to Settings → Service Accounts → New key.
  3. Copy the one-time access_token (you will not see it again).

Service-account tokens are valid for 30 days and work on every endpoint except the human-profile surfaces (/v1/me, /v1/billing/*). When a token expires, generate a new one in the frontend.

client := coinquant.NewClient("YOUR_SECRET_TOKEN")

Keep secrets out of source control. Read the token from an environment variable or your secret manager, never hard-code it.

Configuring the client

The client works out of the box, but you can tweak it with functional options:

client := coinquant.NewClient(
    os.Getenv("COINQUANT_TOKEN"),
    coinquant.WithTimeout(60*time.Second),          // default is 30s
    coinquant.WithBaseURL("https://api.coinquant.ai"), // override for staging/mocks
    coinquant.WithHTTPClient(myInstrumentedClient),  // bring your own *http.Client
)

WithHTTPClient is the escape hatch for retries, tracing, proxies, or custom TLS — pass any *http.Client and the client will use it.

Streaming — the heart of CoinQuant

The AI engine replies over Server-Sent Events. Instead of making you parse raw event frames, the client reads the stream, hands each event to your callback as it arrives, and returns a classified StreamResult when the stream closes.

result, err := client.StreamPrompt(ctx, coinquant.StreamingPromptRequest{
    Message: "Generate a BTCUSDT 1h EMA crossover strategy.",
}, func(ev coinquant.StreamEvent) error {
    // Called for every event as it streams in — useful for live UIs or logs.
    fmt.Print(ev.Text)
    return nil
})
if err != nil {
    log.Fatal(err)
}

fmt.Println("\nclassified as:", result.Type)

Pass nil as the callback if you only care about the final aggregated result.

How responses are classified

CoinQuant can answer a prompt with a chat reply, a research report, or a full strategy. Even a "simple" question can come back as a report, so the client does not guess from your intent. It classifies from the actual events using this precedence:

Priority Condition result.Type
1 Any error event, or HTTP status ≥ 400 StreamTypeError
2 A result event carrying strategy_id, strategy_version_id, or schema StreamTypeStrategy
3 Any report_block or report event StreamTypeReport
4 Only chunk text events StreamTypeChat
5 None of the above StreamTypeUnknown
Continuing a conversation

Attach to an existing chat to keep context, or stream a message into a specific chat:

// Continue a prompt thread
result, _ := client.StreamPrompt(ctx, coinquant.StreamingPromptRequest{
    Message: "Now make the exit tighter.",
    ChatID:  result.ChatID,
}, nil)

// Or stream directly into a chat
result, _ = client.StreamChatMessage(ctx, chatID, coinquant.StreamingChatRequest{
    Content: "Add a 2% stop loss.",
}, nil)
Schema-only strategies

Sometimes the AI returns a strategy schema but no strategy_version_id yet — it is a blueprint, not something you can backtest. Materialize it into a real versioned strategy with one call:

if result.Type == coinquant.StreamTypeStrategy && result.StrategyVersionID == nil && result.ChatID != nil {
    strategy, err := client.FinalizeChat(ctx, *result.ChatID, "EMA Crossover", "My first strategy")
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("ready to backtest:", strategy.LatestVersion.ID)
}

Backtesting without the boilerplate

Backtests are asynchronous: you submit a strategy version, then poll until it finishes. CreateBacktestAndWait wraps the whole loop — submit, poll every N seconds, stop on any terminal status (completed, failed, cancelled, error, timeout), and, on success, fetch the results plus both CSV exports.

result, err := client.CreateBacktestAndWait(ctx, "STRATEGY_VERSION_ID", 900 /* timeout s */, 5 /* poll s */)
if err != nil {
    log.Fatal(err)
}

fmt.Println("status:", result.Detail.Status)
if result.Results != nil {
    fmt.Printf("Total Return: %v%%\n", result.Results.Metrics["Total Return"])
    fmt.Printf("Sharpe:       %v\n", result.Results.Metrics["Sharpe Ratio"])
    // result.SummaryCSV and result.TradesCSV hold the raw CSV exports.
}

Prefer to drive the loop yourself? The building blocks are all public: CreateBacktest, GetBacktest, GetBacktestResults, GetBacktestSummaryCSV, and GetBacktestTradesCSV.

Handling errors

Every non-2xx response becomes a typed *APIError. Use errors.As to inspect it:

credits, err := client.GetCredits(ctx)
if err != nil {
    var apiErr *coinquant.APIError
    if errors.As(err, &apiErr) {
        log.Printf("status=%d code=%s request_id=%s: %s",
            apiErr.Status, apiErr.Code, apiErr.RequestID, apiErr.Message)
        if apiErr.Status == 402 {
            log.Println("out of credits — top up and retry")
        }
    }
    return err
}

The request_id is the thing to include when you reach out to CoinQuant support; they can trace your exact call with it.

A complete workflow

From idea to metrics, end to end:

// 1. Describe the idea and let the AI draft a strategy.
res, _ := client.StreamPrompt(ctx, coinquant.StreamingPromptRequest{
    Message: "Long BTCUSDT when price crosses above the 200 EMA on 1h, exit on cross below.",
}, nil)

// 2. Materialize it if it came back schema-only.
versionID := ""
if res.StrategyVersionID != nil {
    versionID = *res.StrategyVersionID
} else if res.ChatID != nil {
    s, _ := client.FinalizeChat(ctx, *res.ChatID, "EMA 200 Crossover", "")
    versionID = s.LatestVersion.ID
}

// 3. Backtest and wait for the verdict.
bt, _ := client.CreateBacktestAndWait(ctx, versionID, 900, 5)
fmt.Println("done:", bt.Detail.Status, bt.Results.Metrics)

Full API reference

Endpoint Method
GET /health client.Health
GET /v1/chats client.ListChats
POST /v1/chats client.CreateChat
GET /v1/chats/{id} client.GetChat
PATCH /v1/chats/{id} client.UpdateChat
DELETE /v1/chats/{id} client.DeleteChat
GET /v1/chats/{id}/messages client.ListMessages
POST /v1/chats/{id}/messages client.AppendMessage
POST /v1/chats/{id}/messages:stream client.StreamChatMessage
POST /v1/prompts/stream client.StreamPrompt
GET /v1/strategies client.ListStrategies
POST /v1/strategies client.CreateStrategy / client.FinalizeChat
GET /v1/strategies/{id} client.GetStrategy
PATCH /v1/strategies/{id} client.UpdateStrategy
GET /v1/strategies/{id}/versions client.ListStrategyVersions
GET /v1/strategies/{id}/versions/{vid} client.GetStrategyVersion
PATCH /v1/strategies/{id}/versions/{vid} client.UpdateStrategyVersion
GET /v1/backtests client.ListBacktests
POST /v1/backtests client.CreateBacktest
GET /v1/backtests/{id} client.GetBacktest
GET /v1/backtests/{id}/results client.GetBacktestResults
GET /v1/backtests/{id}/exports/summary.csv client.GetBacktestSummaryCSV
GET /v1/backtests/{id}/exports/trades.csv client.GetBacktestTradesCSV
POST /v1/backtests/compare client.CompareBacktests
POST /v1/backtests/{id}/duplicate client.DuplicateBacktest
GET /v1/reports client.ListReports
GET /v1/reports/{id} client.GetReport
GET /v1/templates client.ListTemplates
GET /v1/templates/{id} client.GetTemplate
GET /v1/credits client.GetCredits
GET /v1/credits/usage client.GetCreditUsage
GET /v1/credits/transactions client.ListCreditTransactions
GET /v1/credits/estimates/tick client.EstimateTickCredits
GET /v1/community/leaderboards client.ListLeaderboards
GET /v1/community/backtests client.ListCommunityBacktests
GET /v1/community/backtests/{id} client.GetCommunityBacktest
GET /v1/community/me client.GetCommunityMe
GET /v1/community/me/activities client.ListCommunityActivities

Runnable examples

Each file in examples/ is a self-contained program you can run with go run:

File What it shows
auth_check.go Verify connectivity and read your credit balance
send_prompt.go Stream a prompt and materialize a schema-only strategy
backtest_poll.go Kick off a backtest and wait for the results
community_leaderboard.go Browse the public leaderboard (no token required)
export COINQUANT_TOKEN=your_token_here
go run examples/auth_check.go

FAQ

Do I need a token for everything? No. The health check and the community endpoints (leaderboards, backtests) work anonymously. Everything else needs a service-account token.

Why did my "simple" prompt come back as a report? That is expected — CoinQuant decides the response shape, not the caller. Always branch on result.Type rather than on what you asked for.

How long do tokens last? 30 days. When one expires you will get a 401; mint a fresh key in Settings → Service Accounts.

A backtest keeps returning 409 on results. The run is not finished yet. Use CreateBacktestAndWait, which polls for you, or keep calling GetBacktest until the status is terminal before fetching results.

Can I plug in retries or tracing? Yes — pass your own *http.Client via WithHTTPClient and wrap it however you like.

Contributing

Issues and pull requests are welcome. Please keep the code idiomatic, run go build ./... and go vet ./... before submitting, and describe the change clearly.

License

Released under the MIT License.

Author

Igor Sazonov


Built for quants who ship. If this package saves you time, consider giving the repo a star.

CoinQuant · API Reference · Go package

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type APIError

type APIError struct {
	Status    int    `json:"-"`
	RequestID string `json:"request_id"`
	Code      string `json:"code"`
	Message   string `json:"message"`
}

APIError is a typed error returned by the CoinQuant API.

func IsAPIError

func IsAPIError(err error) (*APIError, bool)

IsAPIError reports whether err is or wraps a *APIError.

func (*APIError) Error

func (e *APIError) Error() string

Error implements the error interface.

type APIResponse

type APIResponse[T any] struct {
	Data  T       `json:"data"`
	Meta  *Meta   `json:"meta,omitempty"`
	Error *string `json:"error,omitempty"`
}

APIResponse is the wrapper shape returned by every JSON endpoint.

type AppendMessageRequest

type AppendMessageRequest struct {
	Content  string         `json:"content"`
	Metadata map[string]any `json:"metadata,omitempty"`
}

AppendMessageRequest is the request body for POST /v1/chats/{chat_id}/messages.

type Artifact

type Artifact struct {
	Type              string  `json:"type"`
	StrategyID        *string `json:"strategy_id,omitempty"`
	StrategyVersionID *string `json:"strategy_version_id,omitempty"`
}

Artifact appears on messages.

type ArtifactCounts

type ArtifactCounts struct {
	Reports          int `json:"reports"`
	StrategyVersions int `json:"strategy_versions"`
}

ArtifactCounts holds report/version counts on chats.

type Backtest

type Backtest struct {
	BacktestID            string           `json:"backtest_id"`
	StrategyID            string           `json:"strategy_id"`
	StrategyVersionID     string           `json:"strategy_version_id"`
	Status                string           `json:"status"`
	CreatedAt             time.Time        `json:"created_at"`
	CompletedAt           *time.Time       `json:"completed_at,omitempty"`
	SourceBacktestID      *string          `json:"source_backtest_id,omitempty"`
	LatestBacktestSummary *BacktestSummary `json:"latest_backtest_summary,omitempty"`
}

Backtest is a backtest resource.

type BacktestListOptions

type BacktestListOptions struct {
	Limit             int    `url:"limit,omitempty"`
	Cursor            string `url:"cursor,omitempty"`
	Sort              string `url:"sort,omitempty"`
	StrategyID        string `url:"strategy_id,omitempty"`
	StrategyVersionID string `url:"strategy_version_id,omitempty"`
	Status            string `url:"status,omitempty"`
}

BacktestListOptions are query parameters for GET /v1/backtests.

type BacktestPollResult

type BacktestPollResult struct {
	Detail     *Backtest
	Results    *BacktestResults
	SummaryCSV string
	TradesCSV  string
}

BacktestPollResult is the aggregate output of CreateBacktestAndWait.

type BacktestResults

type BacktestResults struct {
	BacktestID  string             `json:"backtest_id"`
	Status      string             `json:"status"`
	Metrics     map[string]float64 `json:"metrics"`
	EquityCurve []map[string]any   `json:"equity_curve,omitempty"`
	Trades      []map[string]any   `json:"trades,omitempty"`
	Drawdown    []map[string]any   `json:"drawdown,omitempty"`
}

BacktestResults contains the full results of a completed backtest.

type BacktestSummary

type BacktestSummary struct {
	TotalReturn float64 `json:"total_return"`
	SharpeRatio float64 `json:"sharpe_ratio"`
	MaxDrawdown float64 `json:"max_drawdown"`
	TotalTrades int     `json:"total_trades"`
}

BacktestSummary contains lightweight backtest metrics.

type BacktestsList

type BacktestsList struct {
	Backtests []Backtest `json:"backtests"`
}

BacktestsList is the data container for GET /v1/backtests.

type Chat

type Chat struct {
	ID                   string                `json:"id"`
	Title                string                `json:"title"`
	CreatedAt            time.Time             `json:"created_at"`
	UpdatedAt            time.Time             `json:"updated_at"`
	Archived             bool                  `json:"archived"`
	Starred              bool                  `json:"starred"`
	Tags                 []string              `json:"tags"`
	LatestMessagePreview *LatestMessagePreview `json:"latest_message_preview,omitempty"`
	ArtifactCounts       *ArtifactCounts       `json:"artifact_counts,omitempty"`
	MessageCount         int                   `json:"message_count,omitempty"`
	StrategyID           *string               `json:"strategy_id,omitempty"`
	StrategyVersionID    *string               `json:"strategy_version_id,omitempty"`
	Metadata             map[string]any        `json:"metadata,omitempty"`
}

Chat is a chat session.

type ChatDeleteResponse

type ChatDeleteResponse struct {
	Deleted bool   `json:"deleted"`
	ID      string `json:"id"`
}

ChatDeleteResponse is returned by DELETE /v1/chats/{chat_id}.

type ChatsList

type ChatsList struct {
	Chats []Chat `json:"chats"`
}

ChatsList is the data container for GET /v1/chats.

type ChatsListOptions

type ChatsListOptions struct {
	Limit       int    `url:"limit,omitempty"`
	Cursor      string `url:"cursor,omitempty"`
	Sort        string `url:"sort,omitempty"`
	Archived    *bool  `url:"archived,omitempty"`
	HasStrategy *bool  `url:"has_strategy,omitempty"`
	HasReport   *bool  `url:"has_report,omitempty"`
	Tags        string `url:"tags,omitempty"`
}

ChatsListOptions are query parameters for GET /v1/chats.

type Client

type Client struct {
	BaseURL    string
	HTTPClient *http.Client
	Token      string
}

Client is the CoinQuant Public API HTTP client.

func NewClient

func NewClient(token string, opts ...ClientOption) *Client

NewClient creates a new CoinQuant API client. Use WithHTTPClient and WithBaseURL options as needed.

func (*Client) AppendMessage

func (c *Client) AppendMessage(ctx context.Context, chatID string, req AppendMessageRequest) (*Message, error)

AppendMessage appends a user message without invoking the AI.

func (*Client) CompareBacktests

func (c *Client) CompareBacktests(ctx context.Context, req CompareBacktestsRequest) (*CompareBacktestsResponse, error)

CompareBacktests runs a comparison across completed backtests.

func (*Client) CreateBacktest

func (c *Client) CreateBacktest(ctx context.Context, strategyVersionID string) (*Backtest, error)

CreateBacktest creates an async backtest for a strategy version.

func (*Client) CreateBacktestAndWait

func (c *Client) CreateBacktestAndWait(ctx context.Context, strategyVersionID string, timeoutSeconds, pollIntervalSeconds int) (*BacktestPollResult, error)

CreateBacktestAndWait creates a backtest and polls until terminal status.

func (*Client) CreateChat

func (c *Client) CreateChat(ctx context.Context, req CreateChatRequest) (*Chat, error)

CreateChat creates a new chat session.

func (*Client) CreateStrategy

func (c *Client) CreateStrategy(ctx context.Context, req CreateStrategyRequest) (*Strategy, error)

CreateStrategy materialises a strategy from a chat.

func (*Client) DeleteChat

func (c *Client) DeleteChat(ctx context.Context, chatID string) (*ChatDeleteResponse, error)

DeleteChat permanently deletes a chat session.

func (*Client) DuplicateBacktest

func (c *Client) DuplicateBacktest(ctx context.Context, backtestID string) (*DuplicateBacktestResponse, error)

DuplicateBacktest clones a completed backtest.

func (*Client) EstimateTickCredits

func (c *Client) EstimateTickCredits(ctx context.Context, dataDays, timeframeMinutes int) (*TickEstimate, error)

EstimateTickCredits returns a deterministic credit cost estimate.

func (*Client) FinalizeChat

func (c *Client) FinalizeChat(ctx context.Context, chatID, name, description string) (*Strategy, error)

FinalizeChat is a helper that materialises a schema-only stream result into a backtestable strategy.

func (*Client) GetBacktest

func (c *Client) GetBacktest(ctx context.Context, backtestID string) (*Backtest, error)

GetBacktest retrieves a backtest detail.

func (*Client) GetBacktestResults

func (c *Client) GetBacktestResults(ctx context.Context, backtestID string) (*BacktestResults, error)

GetBacktestResults retrieves full results for a completed backtest.

func (*Client) GetBacktestSummaryCSV

func (c *Client) GetBacktestSummaryCSV(ctx context.Context, backtestID string) (string, error)

GetBacktestSummaryCSV downloads the summary CSV for a completed backtest.

func (*Client) GetBacktestTradesCSV

func (c *Client) GetBacktestTradesCSV(ctx context.Context, backtestID string) (string, error)

GetBacktestTradesCSV downloads the trades CSV for a completed backtest.

func (*Client) GetChat

func (c *Client) GetChat(ctx context.Context, chatID string) (*Chat, error)

GetChat retrieves a single chat session.

func (*Client) GetCommunityBacktest

func (c *Client) GetCommunityBacktest(ctx context.Context, backtestID string, include string) (*CommunityBacktest, error)

GetCommunityBacktest returns the public-facing view of a shared backtest.

func (*Client) GetCommunityMe

func (c *Client) GetCommunityMe(ctx context.Context, include string) (*CommunityProfile, error)

GetCommunityMe returns the current user's community-facing stats.

func (*Client) GetCreditUsage

func (c *Client) GetCreditUsage(ctx context.Context, opts CreditUsageOptions) (*CreditUsage, error)

GetCreditUsage returns aggregated credit usage over time.

func (*Client) GetCredits

func (c *Client) GetCredits(ctx context.Context) (*CreditBalance, error)

GetCredits returns the current credit balance.

func (*Client) GetReport

func (c *Client) GetReport(ctx context.Context, reportID string) (*Report, error)

GetReport retrieves a single report.

func (*Client) GetStrategy

func (c *Client) GetStrategy(ctx context.Context, strategyID string) (*Strategy, error)

GetStrategy retrieves a single strategy container.

func (*Client) GetStrategyVersion

func (c *Client) GetStrategyVersion(ctx context.Context, strategyID, versionID string) (*StrategyVersion, error)

GetStrategyVersion retrieves a full strategy version snapshot.

func (*Client) GetTemplate

func (c *Client) GetTemplate(ctx context.Context, templateID string) (*TemplateDetail, error)

GetTemplate retrieves a full template definition.

func (*Client) Health

func (c *Client) Health(ctx context.Context) (*HealthResponse, error)

Health checks the API status without authentication.

func (*Client) ListBacktests

func (c *Client) ListBacktests(ctx context.Context, opts BacktestListOptions) (*BacktestsList, error)

ListBacktests returns paginated backtests.

func (*Client) ListChats

func (c *Client) ListChats(ctx context.Context, opts ChatsListOptions) (*ChatsList, error)

ListChats returns paginated chat sessions.

func (*Client) ListCommunityActivities

func (c *Client) ListCommunityActivities(ctx context.Context, opts CommunityActivityOptions) (*CommunityActivitiesData, error)

ListCommunityActivities returns community activity for the current user.

func (*Client) ListCommunityBacktests

func (c *Client) ListCommunityBacktests(ctx context.Context, opts CommunityBacktestListOptions) (*CommunityBacktestsList, error)

ListCommunityBacktests returns public/shared backtests.

func (*Client) ListCreditTransactions

func (c *Client) ListCreditTransactions(ctx context.Context, opts CreditTransactionOptions) (*CreditTransactionsList, error)

ListCreditTransactions returns the credit ledger.

func (*Client) ListLeaderboards

func (c *Client) ListLeaderboards(ctx context.Context, opts LeaderboardOptions) (*LeaderboardsData, error)

ListLeaderboards returns community leaderboard entries.

func (*Client) ListMessages

func (c *Client) ListMessages(ctx context.Context, chatID string, opts PaginatedOptions) (*MessagesList, error)

ListMessages returns paginated messages for a chat.

func (*Client) ListReports

func (c *Client) ListReports(ctx context.Context, opts ReportListOptions) (*ReportsList, error)

ListReports returns paginated report artifacts.

func (*Client) ListStrategies

func (c *Client) ListStrategies(ctx context.Context, opts StrategyListOptions) (*StrategiesList, error)

ListStrategies returns paginated strategy containers.

func (*Client) ListStrategyVersions

func (c *Client) ListStrategyVersions(ctx context.Context, strategyID string, opts PaginatedOptions) (*StrategyVersionsList, error)

ListStrategyVersions returns paginated version summaries.

func (*Client) ListTemplates

func (c *Client) ListTemplates(ctx context.Context, opts TemplateListOptions) (*TemplatesList, error)

ListTemplates returns reusable strategy templates.

func (*Client) StreamChatMessage

func (c *Client) StreamChatMessage(ctx context.Context, chatID string, req StreamingChatRequest, callback StreamCallback) (*StreamResult, error)

StreamChatMessage sends a message to a chat and streams the result. Pass callback to receive individual events.

func (*Client) StreamPrompt

func (c *Client) StreamPrompt(ctx context.Context, req StreamingPromptRequest, callback StreamCallback) (*StreamResult, error)

StreamPrompt sends a prompt and streams the result. Pass callback to receive individual events.

func (*Client) UpdateChat

func (c *Client) UpdateChat(ctx context.Context, chatID string, req UpdateChatRequest) (*Chat, error)

UpdateChat updates mutable chat metadata.

func (*Client) UpdateStrategy

func (c *Client) UpdateStrategy(ctx context.Context, strategyID string, req UpdateStrategyRequest) (*Strategy, error)

UpdateStrategy updates a strategy container.

func (*Client) UpdateStrategyVersion

func (c *Client) UpdateStrategyVersion(ctx context.Context, strategyID, versionID string, req UpdateStrategyVersionRequest) (*StrategyVersion, error)

UpdateStrategyVersion updates version-level metadata.

type ClientOption

type ClientOption func(*Client)

ClientOption configures a Client.

func WithBaseURL

func WithBaseURL(u string) ClientOption

WithBaseURL overrides the default production base URL.

func WithHTTPClient

func WithHTTPClient(hc *http.Client) ClientOption

WithHTTPClient replaces the default HTTP client.

func WithTimeout

func WithTimeout(d time.Duration) ClientOption

WithTimeout sets the HTTP client timeout.

type CommunityActivitiesData

type CommunityActivitiesData struct {
	Activities []CommunityActivity `json:"activities"`
	Totals     map[string]any      `json:"totals,omitempty"`
}

CommunityActivitiesData is the data container for GET /v1/community/me/activities.

type CommunityActivity

type CommunityActivity struct {
	ID        string    `json:"id"`
	Task      string    `json:"task"`
	Status    string    `json:"status"`
	Title     string    `json:"title"`
	CreatedAt time.Time `json:"created_at"`
}

CommunityActivity is a community activity record.

type CommunityActivityOptions

type CommunityActivityOptions struct {
	Limit   int    `url:"limit,omitempty"`
	Cursor  string `url:"cursor,omitempty"`
	Task    string `url:"task,omitempty"`
	Status  string `url:"status,omitempty"`
	Include string `url:"include,omitempty"`
}

CommunityActivityOptions are query parameters for GET /v1/community/me/activities.

type CommunityBacktest

type CommunityBacktest struct {
	BacktestID        string           `json:"backtest_id"`
	StrategyName      string           `json:"strategy_name"`
	CreatedByUsername string           `json:"created_by_username"`
	PublishedAt       time.Time        `json:"published_at"`
	Metrics           map[string]any   `json:"metrics,omitempty"`
	FavouritesCount   int              `json:"favourites_count"`
	IsFavouritedByMe  bool             `json:"is_favourited_by_me"`
	Orders            []map[string]any `json:"orders,omitempty"`
	AssetClass        string           `json:"asset_class,omitempty"`
	SqsScore          int              `json:"sqs_score,omitempty"`
	Timeframe         string           `json:"timeframe,omitempty"`
	StartDate         *time.Time       `json:"start_date,omitempty"`
	EndDate           *time.Time       `json:"end_date,omitempty"`
}

CommunityBacktest is a public/shared backtest.

type CommunityBacktestDetailOptions

type CommunityBacktestDetailOptions struct {
	Include string `url:"include,omitempty"`
}

CommunityBacktestDetailOptions are query parameters for GET /v1/community/backtests/{backtest_id}.

type CommunityBacktestListOptions

type CommunityBacktestListOptions struct {
	Season     int    `url:"season,omitempty"`
	StrategyID string `url:"strategy_id,omitempty"`
	Q          string `url:"q,omitempty"`
	Sort       string `url:"sort,omitempty"`
	Limit      int    `url:"limit,omitempty"`
	Cursor     string `url:"cursor,omitempty"`
	Include    string `url:"include,omitempty"`
}

CommunityBacktestListOptions are query parameters for GET /v1/community/backtests.

type CommunityBacktestsList

type CommunityBacktestsList struct {
	Backtests []CommunityBacktest `json:"backtests"`
}

CommunityBacktestsList is the data container for GET /v1/community/backtests.

type CommunityMeOptions

type CommunityMeOptions struct {
	Include string `url:"include,omitempty"`
}

CommunityMeOptions are query parameters for GET /v1/community/me.

type CommunityProfile

type CommunityProfile struct {
	UserID             string `json:"user_id"`
	Username           string `json:"username"`
	TotalPoints        int    `json:"total_points"`
	Rank               int    `json:"rank"`
	PublishedBacktests int    `json:"published_backtests"`
	Followers          int    `json:"followers"`
}

CommunityProfile is returned by GET /v1/community/me.

type CompareBacktestsRequest

type CompareBacktestsRequest struct {
	BacktestIDs []string `json:"backtest_ids"`
}

CompareBacktestsRequest is the request body for POST /v1/backtests/compare.

type CompareBacktestsResponse

type CompareBacktestsResponse struct {
	Backtests           []map[string]any `json:"backtests"`
	WinnerByTotalReturn string           `json:"winner_by_total_return,omitempty"`
}

CompareBacktestsResponse is returned by POST /v1/backtests/compare.

type CreateBacktestRequest

type CreateBacktestRequest struct {
	StrategyVersionID string `json:"strategy_version_id"`
}

CreateBacktestRequest is the request body for POST /v1/backtests.

type CreateChatRequest

type CreateChatRequest struct {
	Title          string         `json:"title,omitempty"`
	Tags           []string       `json:"tags,omitempty"`
	Metadata       map[string]any `json:"metadata,omitempty"`
	InitialMessage string         `json:"initial_message,omitempty"`
}

CreateChatRequest is the request body for POST /v1/chats.

type CreateStrategyRequest

type CreateStrategyRequest struct {
	ChatID      string `json:"chat_id"`
	Name        string `json:"name,omitempty"`
	Description string `json:"description,omitempty"`
}

CreateStrategyRequest is the request body for POST /v1/strategies.

type CreditBalance

type CreditBalance struct {
	AvailableCreditsTotal        int         `json:"available_credits_total"`
	AvailableCreditsSubscription int         `json:"available_credits_subscription"`
	AvailableCreditsTopup        int         `json:"available_credits_topup"`
	PendingCreditsSubscription   int         `json:"pending_credits_subscription"`
	Lots                         []CreditLot `json:"lots"`
	TickMaxDays                  int         `json:"tick_max_days"`
	ServerTime                   time.Time   `json:"server_time"`
}

CreditBalance is returned by GET /v1/credits.

type CreditLot

type CreditLot struct {
	LotID            string    `json:"lot_id"`
	Bucket           string    `json:"bucket"`
	RemainingCredits int       `json:"remaining_credits"`
	TotalCredits     int       `json:"total_credits"`
	ExpiresAt        time.Time `json:"expires_at"`
}

CreditLot describes a credit lot.

type CreditTransaction

type CreditTransaction struct {
	ID           string    `json:"id"`
	Direction    string    `json:"direction"`
	Amount       int       `json:"amount"`
	EventType    string    `json:"event_type"`
	ReferenceID  *string   `json:"reference_id,omitempty"`
	CreatedAt    time.Time `json:"created_at"`
	BalanceAfter int       `json:"balance_after"`
}

CreditTransaction is a single ledger entry.

type CreditTransactionOptions

type CreditTransactionOptions struct {
	Limit       int    `url:"limit,omitempty"`
	Cursor      string `url:"cursor,omitempty"`
	From        string `url:"from,omitempty"`
	To          string `url:"to,omitempty"`
	Direction   string `url:"direction,omitempty"`
	EventType   string `url:"event_type,omitempty"`
	ReferenceID string `url:"reference_id,omitempty"`
}

CreditTransactionOptions are query parameters for GET /v1/credits/transactions.

type CreditTransactionsList

type CreditTransactionsList struct {
	Transactions []CreditTransaction `json:"transactions"`
}

CreditTransactionsList is the data container for GET /v1/credits/transactions.

type CreditUsage

type CreditUsage struct {
	FromDate string            `json:"from_date"`
	ToDate   string            `json:"to_date"`
	Totals   CreditUsageTotals `json:"totals"`
	Series   []map[string]any  `json:"series"`
}

CreditUsage is returned by GET /v1/credits/usage.

type CreditUsageOptions

type CreditUsageOptions struct {
	From    string `url:"from,omitempty"`
	To      string `url:"to,omitempty"`
	GroupBy string `url:"group_by,omitempty"`
}

CreditUsageOptions are query parameters for GET /v1/credits/usage.

type CreditUsageTotals

type CreditUsageTotals struct {
	PromptsCredits int `json:"prompts_credits"`
	PromptsCount   int `json:"prompts_count"`
	CandleCredits  int `json:"candle_credits"`
	CandleCount    int `json:"candle_count"`
	TickCredits    int `json:"tick_credits"`
	TickMinutes    int `json:"tick_minutes"`
}

CreditUsageTotals holds aggregated credit usage.

type DuplicateBacktestResponse

type DuplicateBacktestResponse struct {
	BacktestID       string    `json:"backtest_id"`
	SourceBacktestID string    `json:"source_backtest_id"`
	Status           string    `json:"status"`
	CreatedAt        time.Time `json:"created_at"`
}

DuplicateBacktestResponse is returned by POST /v1/backtests/{backtest_id}/duplicate.

type HTTPResponse

type HTTPResponse struct {
	*http.Response
	RequestID string
}

HTTPResponse wraps the raw *http.Response for consumers who need it.

type HealthResponse

type HealthResponse struct {
	Status  string `json:"status"`
	Service string `json:"service"`
}

HealthResponse is returned by GET /health.

type LatestMessagePreview

type LatestMessagePreview struct {
	ID        string    `json:"id"`
	Role      string    `json:"role"`
	Content   string    `json:"content"`
	CreatedAt time.Time `json:"created_at"`
}

LatestMessagePreview is the preview object on chats.

type LeaderboardEntry

type LeaderboardEntry struct {
	Rank        int    `json:"rank"`
	Username    string `json:"username"`
	TotalPoints int    `json:"total_points"`
}

LeaderboardEntry is a single leaderboard row.

type LeaderboardOptions

type LeaderboardOptions struct {
	Season  int    `url:"season,omitempty"`
	Limit   int    `url:"limit,omitempty"`
	Cursor  string `url:"cursor,omitempty"`
	Include string `url:"include,omitempty"`
}

LeaderboardOptions are query parameters for GET /v1/community/leaderboards.

type LeaderboardsData

type LeaderboardsData struct {
	Entries     []LeaderboardEntry `json:"entries"`
	CurrentUser *LeaderboardEntry  `json:"current_user,omitempty"`
	Season      int                `json:"season"`
}

LeaderboardsData is the data container for GET /v1/community/leaderboards.

type Message

type Message struct {
	ID                string         `json:"id"`
	ChatID            string         `json:"chat_id"`
	Role              string         `json:"role"`
	Content           string         `json:"content"`
	CreatedAt         time.Time      `json:"created_at"`
	StrategyID        *string        `json:"strategy_id,omitempty"`
	StrategyVersionID *string        `json:"strategy_version_id,omitempty"`
	Artifacts         []Artifact     `json:"artifacts"`
	Metadata          map[string]any `json:"metadata,omitempty"`
}

Message is a chat message.

type MessagesList

type MessagesList struct {
	Messages []Message `json:"messages"`
}

MessagesList is the data container for GET /v1/chats/{chat_id}/messages.

type Meta

type Meta struct {
	RequestID string  `json:"request_id"`
	Cursor    *string `json:"cursor,omitempty"`
	HasMore   bool    `json:"has_more,omitempty"`
}

Meta is the standard API response envelope metadata.

type PaginatedOptions

type PaginatedOptions struct {
	Limit  int    `json:"limit,omitempty"`
	Cursor string `json:"cursor,omitempty"`
	Sort   string `json:"sort,omitempty"`
}

PaginatedOptions contains shared pagination parameters.

type Report

type Report struct {
	ID        string         `json:"id"`
	ChatID    *string        `json:"chat_id,omitempty"`
	MessageID *string        `json:"message_id,omitempty"`
	Title     string         `json:"title"`
	Content   string         `json:"content,omitempty"`
	CreatedAt time.Time      `json:"created_at"`
	Metadata  map[string]any `json:"metadata,omitempty"`
}

Report is a read-only report artifact.

type ReportListOptions

type ReportListOptions struct {
	Limit  int    `url:"limit,omitempty"`
	Cursor string `url:"cursor,omitempty"`
	ChatID string `url:"chat_id,omitempty"`
	Sort   string `url:"sort,omitempty"`
}

ReportListOptions are query parameters for GET /v1/reports.

type ReportsList

type ReportsList struct {
	Reports []Report `json:"reports"`
}

ReportsList is the data container for GET /v1/reports.

type StrategiesList

type StrategiesList struct {
	Strategies []Strategy `json:"strategies"`
}

StrategiesList is the data container for GET /v1/strategies.

type Strategy

type Strategy struct {
	ID            string                  `json:"id"`
	ChatID        *string                 `json:"chat_id,omitempty"`
	Name          string                  `json:"name"`
	Description   string                  `json:"description,omitempty"`
	CreatedAt     time.Time               `json:"created_at"`
	UpdatedAt     time.Time               `json:"updated_at"`
	State         string                  `json:"state"`
	VersionCount  int                     `json:"version_count"`
	LatestVersion *StrategyVersionSummary `json:"latest_version,omitempty"`
}

Strategy is a strategy container.

type StrategyCondition

type StrategyCondition struct {
	ID               string         `json:"id"`
	Type             string         `json:"type"`
	Action           string         `json:"action"`
	Operator         string         `json:"operator"`
	Series1          string         `json:"series_1"`
	Series2          string         `json:"series_2,omitempty"`
	Series1Params    map[string]any `json:"series_1_params,omitempty"`
	Series2Params    map[string]any `json:"series_2_params,omitempty"`
	Series1Timeframe string         `json:"series_1_timeframe,omitempty"`
	Series2Timeframe string         `json:"series_2_timeframe,omitempty"`
}

StrategyCondition is a single entry/exit condition within a strategy schema.

type StrategyLatestBacktest

type StrategyLatestBacktest struct {
	BacktestID  string    `json:"backtest_id,omitempty"`
	CreatedAt   time.Time `json:"created_at,omitempty"`
	TotalReturn float64   `json:"total_return,omitempty"`
	SharpeRatio float64   `json:"sharpe_ratio,omitempty"`
	Status      string    `json:"status,omitempty"`
}

StrategyLatestBacktest is the lightweight backtest summary on strategy/version objects.

type StrategyListOptions

type StrategyListOptions struct {
	Limit       int    `url:"limit,omitempty"`
	Cursor      string `url:"cursor,omitempty"`
	State       string `url:"state,omitempty"`
	IsPublished *bool  `url:"is_published,omitempty"`
	Q           string `url:"q,omitempty"`
	Sort        string `url:"sort,omitempty"`
}

StrategyListOptions are query parameters for GET /v1/strategies.

type StrategySchema

type StrategySchema struct {
	Instrument        string              `json:"instrument"`
	Timeframe         string              `json:"timeframe"`
	StrategyName      string              `json:"strategy_name,omitempty"`
	InitialCapital    float64             `json:"initial_capital,omitempty"`
	PositionSizeType  string              `json:"position_size_type,omitempty"`
	PositionSizeValue float64             `json:"position_size_value,omitempty"`
	Conditions        []StrategyCondition `json:"conditions"`
}

StrategySchema is the executable strategy payload.

type StrategyVersion

type StrategyVersion struct {
	ID             string                  `json:"id"`
	StrategyID     string                  `json:"strategy_id"`
	VersionNumber  int                     `json:"version_number"`
	State          string                  `json:"state"`
	IsPublished    bool                    `json:"is_published"`
	PublishedAt    *time.Time              `json:"published_at,omitempty"`
	Title          string                  `json:"title,omitempty"`
	Description    string                  `json:"description,omitempty"`
	Schema         *StrategySchema         `json:"schema,omitempty"`
	LatestBacktest *StrategyLatestBacktest `json:"latest_backtest,omitempty"`
	CreatedAt      time.Time               `json:"created_at"`
}

StrategyVersion is a full strategy version snapshot.

type StrategyVersionSummary

type StrategyVersionSummary struct {
	ID             string                  `json:"id"`
	VersionNumber  int                     `json:"version_number"`
	State          string                  `json:"state"`
	IsPublished    bool                    `json:"is_published"`
	PublishedAt    *time.Time              `json:"published_at,omitempty"`
	LatestBacktest *StrategyLatestBacktest `json:"latest_backtest,omitempty"`
	Schema         *StrategySchema         `json:"schema,omitempty"`
}

StrategyVersionSummary is a short version descriptor.

type StrategyVersionsList

type StrategyVersionsList struct {
	Versions []StrategyVersion `json:"versions"`
}

StrategyVersionsList is the data container for GET /v1/strategies/{strategy_id}/versions.

type StreamCallback

type StreamCallback func(event StreamEvent) error

StreamCallback is called for every SSE event.

type StreamEvent

type StreamEvent struct {
	Type      StreamEventType `json:"type"`
	Event     string          `json:"event"`
	Data      json.RawMessage `json:"data"`
	RequestID string          `json:"request_id,omitempty"`
	ChatID    *string         `json:"chat_id,omitempty"`
	// Pointers populated depending on event content.
	StrategyID        *string         `json:"strategy_id,omitempty"`
	StrategyVersionID *string         `json:"strategy_version_id,omitempty"`
	ReportID          *string         `json:"report_id,omitempty"`
	Schema            json.RawMessage `json:"schema,omitempty"`
	Text              string          `json:"text,omitempty"`
	ErrorCode         string          `json:"error_code,omitempty"`
	ErrorMessage      string          `json:"error_message,omitempty"`
}

StreamEvent is a parsed SSE event from CoinQuant.

type StreamEventType

type StreamEventType string

StreamEventType describes the high-level classification of an SSE stream.

const (
	StreamTypeError    StreamEventType = "error"
	StreamTypeStrategy StreamEventType = "strategy"
	StreamTypeReport   StreamEventType = "report"
	StreamTypeChat     StreamEventType = "chat"
	StreamTypeUnknown  StreamEventType = "unknown"
)

type StreamResult

type StreamResult struct {
	Type              StreamEventType `json:"type"`
	RequestID         string          `json:"request_id,omitempty"`
	ChatID            *string         `json:"chat_id,omitempty"`
	StrategyID        *string         `json:"strategy_id,omitempty"`
	StrategyVersionID *string         `json:"strategy_version_id,omitempty"`
	ReportID          *string         `json:"report_id,omitempty"`
	Schema            json.RawMessage `json:"schema,omitempty"`
	Text              string          `json:"text"`
	Events            []StreamEvent   `json:"events"`
	Err               error           `json:"-"`
}

StreamResult aggregates a complete stream once finished.

type StreamingChatRequest

type StreamingChatRequest struct {
	Content string         `json:"content"`
	Options map[string]any `json:"options,omitempty"`
}

StreamingChatRequest is the request body for POST /v1/chats/{chat_id}/messages:stream.

type StreamingPromptRequest

type StreamingPromptRequest struct {
	Message string         `json:"message"`
	ChatID  *string        `json:"chat_id,omitempty"`
	Options map[string]any `json:"options,omitempty"`
}

StreamingPromptRequest is the request body for POST /v1/prompts/stream.

type Template

type Template struct {
	ID          string            `json:"id"`
	Name        string            `json:"name"`
	Description string            `json:"description,omitempty"`
	Category    *TemplateCategory `json:"category,omitempty"`
	CreatedAt   time.Time         `json:"created_at"`
}

Template is a reusable strategy template.

type TemplateCategory

type TemplateCategory struct {
	Slug string `json:"slug"`
	Name string `json:"name"`
}

TemplateCategory describes a template category.

type TemplateDetail

type TemplateDetail struct {
	ID              string            `json:"id"`
	Title           string            `json:"title"`
	Slug            string            `json:"slug"`
	Prompt          string            `json:"prompt"`
	Description     string            `json:"description,omitempty"`
	LongDescription string            `json:"long_description,omitempty"`
	IsFeatured      bool              `json:"is_featured"`
	IsPro           bool              `json:"is_pro"`
	IsPopular       bool              `json:"is_popular"`
	StrategyType    string            `json:"strategy_type,omitempty"`
	Category        *TemplateCategory `json:"category,omitempty"`
}

TemplateDetail is the full template definition.

type TemplateListOptions

type TemplateListOptions struct {
	Limit    int    `url:"limit,omitempty"`
	Cursor   string `url:"cursor,omitempty"`
	Category string `url:"category,omitempty"`
	Q        string `url:"q,omitempty"`
	GroupBy  string `url:"group_by,omitempty"`
}

TemplateListOptions are query parameters for GET /v1/templates.

type TemplatesList

type TemplatesList struct {
	Templates []Template `json:"templates"`
}

TemplatesList is the data container for GET /v1/templates.

type TickEstimate

type TickEstimate struct {
	DataDays         int `json:"data_days"`
	TimeframeMinutes int `json:"timeframe_minutes"`
	EstimatedCredits int `json:"estimated_credits"`
	TickMaxDays      int `json:"tick_max_days"`
}

TickEstimate is returned by GET /v1/credits/estimates/tick.

type TickEstimateOptions

type TickEstimateOptions struct {
	DataDays         int `url:"data_days"`
	TimeframeMinutes int `url:"timeframe_minutes"`
}

TickEstimateOptions are query parameters for GET /v1/credits/estimates/tick.

type UpdateChatRequest

type UpdateChatRequest struct {
	Title    string   `json:"title,omitempty"`
	Archived *bool    `json:"archived,omitempty"`
	Starred  *bool    `json:"starred,omitempty"`
	Tags     []string `json:"tags,omitempty"`
}

UpdateChatRequest is the request body for PATCH /v1/chats/{chat_id}.

type UpdateStrategyRequest

type UpdateStrategyRequest struct {
	Name        string `json:"name,omitempty"`
	Description string `json:"description,omitempty"`
}

UpdateStrategyRequest is the request body for PATCH /v1/strategies/{strategy_id}.

type UpdateStrategyVersionRequest

type UpdateStrategyVersionRequest struct {
	Title       string `json:"title,omitempty"`
	Description string `json:"description,omitempty"`
	IsPublished *bool  `json:"is_published,omitempty"`
}

UpdateStrategyVersionRequest is the request body for PATCH /v1/strategies/{strategy_id}/versions/{version_id}.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL