Files
aitrade/pkg/app/strategy/aggressive.go
T
kaedwen ea141eb012
Build and Push Docker Image / build-and-push (push) Failing after 1m41s
initial
2026-07-02 20:09:44 +02:00

115 lines
2.9 KiB
Go

package strategy
import (
"context"
"fmt"
"strings"
"github.com/pheinrich/aitrade/pkg/model"
)
type AggressiveStrategy struct {
stopLossEnabled bool
stopLossPercent float64
}
func NewAggressiveStrategy(stopLossEnabled bool, stopLossPercent float64) *AggressiveStrategy {
return &AggressiveStrategy{
stopLossEnabled: stopLossEnabled,
stopLossPercent: stopLossPercent,
}
}
func (s *AggressiveStrategy) Name() string {
return "aggressive"
}
func (s *AggressiveStrategy) GetRiskParams() RiskParameters {
return RiskParameters{
MaxParallelTrades: 10,
MaxTradesPerHour: 12,
PositionSizePercent: 7.5, // 5-10% of capital
StopLossPercent: 5.0,
}
}
func (s *AggressiveStrategy) Analyze(ctx context.Context, market *MarketData, news []*model.NewsArticle) (*TradeSignal, error) {
// Aggressive strategy: Trade on any positive sentiment
// Higher risk, higher frequency
positiveCount := 0
negativeCount := 0
totalSentiment := 0.0
relevantArticles := 0
for _, article := range news {
if article.SentimentScore == nil {
continue
}
// Check if article mentions this symbol
if !strings.Contains(strings.ToUpper(article.Symbols), market.Symbol) {
continue
}
relevantArticles++
sentiment := *article.SentimentScore
totalSentiment += sentiment
if article.SentimentLabel == "positive" {
positiveCount++
} else if article.SentimentLabel == "negative" {
negativeCount++
}
}
// Aggressive: Need at least 1 relevant article
if relevantArticles < 1 {
return nil, nil
}
avgSentiment := totalSentiment / float64(relevantArticles)
// Aggressive: Any net positive sentiment
if avgSentiment <= 0 {
return nil, nil
}
// Also consider sell signals on strong negative sentiment
if avgSentiment < -0.5 && negativeCount > positiveCount {
return &TradeSignal{
Symbol: market.Symbol,
Action: model.ActionSell,
Quantity: 0, // Will be filled from position
Confidence: (-avgSentiment) * 0.95,
Reasoning: fmt.Sprintf("Aggressive SELL: %d negative articles, avg sentiment %.2f", negativeCount, avgSentiment),
}, nil
}
return &TradeSignal{
Symbol: market.Symbol,
Action: model.ActionBuy,
Quantity: 0, // Will be calculated by trader
Confidence: avgSentiment * 0.95,
Reasoning: fmt.Sprintf("Aggressive BUY: %d positive articles, avg sentiment %.2f", positiveCount, avgSentiment),
}, nil
}
// CalculatePositionSize - Aggressive strategy uses larger sizing with confidence scaling
func (s *AggressiveStrategy) CalculatePositionSize(price float64, confidence float64, availableCapital float64) int {
basePositionPercent := s.GetRiskParams().PositionSizePercent
// Aggressive: More aggressive confidence scaling (0.7 - 1.2x)
confidenceMultiplier := 0.7 + (confidence * 0.5)
adjustedPercent := basePositionPercent * confidenceMultiplier
positionValue := availableCapital * (adjustedPercent / 100.0)
quantity := int(positionValue / price)
if quantity < 1 {
return 1
}
return quantity
}