feat: Add position sizing to Sunny Scanner with portfolio input
This commit is contained in:
parent
843f78851f
commit
88b944851a
@ -20,7 +20,8 @@ def get_scanner_parameters():
|
||||
min_price = get_float_input("Enter minimum stock price ($): ")
|
||||
max_price = get_float_input("Enter maximum stock price ($): ")
|
||||
min_volume = int(input("Enter minimum volume: "))
|
||||
return min_price, max_price, min_volume
|
||||
portfolio_size = get_float_input("Enter portfolio size ($) or 0 to skip position sizing: ")
|
||||
return min_price, max_price, min_volume, portfolio_size
|
||||
|
||||
def main():
|
||||
print("\nStock Analysis System")
|
||||
@ -82,9 +83,9 @@ def main():
|
||||
print("✅ Scores saved in data/metrics/stock_scores.csv\n")
|
||||
|
||||
elif choice == "2":
|
||||
min_price, max_price, min_volume = get_scanner_parameters()
|
||||
min_price, max_price, min_volume, portfolio_size = get_scanner_parameters()
|
||||
from screener.t_sunnyband import run_sunny_scanner
|
||||
run_sunny_scanner(min_price, max_price, min_volume)
|
||||
run_sunny_scanner(min_price, max_price, min_volume, portfolio_size)
|
||||
|
||||
elif choice == "3":
|
||||
from trading.main import main as trading_main
|
||||
|
||||
@ -2,6 +2,7 @@ from datetime import datetime, timedelta
|
||||
import pandas as pd
|
||||
from db.db_connection import create_client
|
||||
from indicators.sunny_bands import SunnyBands
|
||||
from trading.position_calculator import PositionCalculator
|
||||
|
||||
def get_interval_choice() -> str:
|
||||
"""Get user's preferred time interval"""
|
||||
@ -268,7 +269,7 @@ def view_stock_details(ticker: str, interval: str, start_date: datetime, end_dat
|
||||
except Exception as e:
|
||||
print(f"Error analyzing {ticker}: {str(e)}")
|
||||
|
||||
def run_sunny_scanner(min_price: float, max_price: float, min_volume: int) -> None:
|
||||
def run_sunny_scanner(min_price: float, max_price: float, min_volume: int, portfolio_size: float = None) -> None:
|
||||
"""Run the SunnyBand scanner and save results"""
|
||||
print(f"\nInitializing scan for stocks between ${min_price:.2f} and ${max_price:.2f}")
|
||||
print(f"Minimum volume: {min_volume:,}")
|
||||
@ -301,8 +302,11 @@ def run_sunny_scanner(min_price: float, max_price: float, min_volume: int) -> No
|
||||
bearish_signals = []
|
||||
errors = []
|
||||
|
||||
# Initialize SunnyBands indicator
|
||||
# Initialize SunnyBands indicator and position calculator
|
||||
sunny = SunnyBands()
|
||||
calculator = None
|
||||
if portfolio_size and portfolio_size > 0:
|
||||
calculator = PositionCalculator(account_size=portfolio_size)
|
||||
|
||||
# Track progress
|
||||
total = len(tickers)
|
||||
@ -337,8 +341,28 @@ def run_sunny_scanner(min_price: float, max_price: float, min_volume: int) -> No
|
||||
'volume': last_day['volume'],
|
||||
'date': last_day['date'],
|
||||
'dma': results['dma'].iloc[-1],
|
||||
'lower_band': results['lower_band'].iloc[-1]
|
||||
'lower_band': results['lower_band'].iloc[-1],
|
||||
'upper_band': results['upper_band'].iloc[-1]
|
||||
}
|
||||
|
||||
# Add position sizing if calculator exists
|
||||
if calculator:
|
||||
try:
|
||||
position = calculator.calculate_position_size(
|
||||
entry_price=last_day['close'],
|
||||
target_price=results['upper_band'].iloc[-1]
|
||||
)
|
||||
signal_data.update({
|
||||
'shares': position['shares'],
|
||||
'position_value': position['position_value'],
|
||||
'stop_loss': position['stop_loss'],
|
||||
'potential_profit': position['potential_profit'],
|
||||
'potential_loss': position['potential_loss'],
|
||||
'risk_reward_ratio': position['risk_reward_ratio']
|
||||
})
|
||||
except ValueError as e:
|
||||
print(f"Position sizing error for {ticker}: {str(e)}")
|
||||
|
||||
bullish_signals.append(signal_data)
|
||||
print(f"🟢 Bullish Signal: {ticker} at ${last_day['close']:.2f}")
|
||||
|
||||
@ -383,6 +407,16 @@ def run_sunny_scanner(min_price: float, max_price: float, min_volume: int) -> No
|
||||
print(f"Volume: {signal['volume']:,}")
|
||||
print(f"DMA: ${signal['dma']:.2f}")
|
||||
print(f"Lower Band: ${signal['lower_band']:.2f}")
|
||||
print(f"Upper Band: ${signal['upper_band']:.2f}")
|
||||
|
||||
if 'shares' in signal:
|
||||
print("\nPosition Details:")
|
||||
print(f"Shares: {signal['shares']}")
|
||||
print(f"Position Value: ${signal['position_value']:.2f}")
|
||||
print(f"Stop Loss: ${signal['stop_loss']:.2f}")
|
||||
print(f"Potential Profit: ${signal['potential_profit']:.2f}")
|
||||
print(f"Potential Loss: ${signal['potential_loss']:.2f}")
|
||||
print(f"Risk/Reward Ratio: {signal['risk_reward_ratio']:.2f}")
|
||||
|
||||
if bearish_signals:
|
||||
print(f"\n🔴 Found {len(bearish_signals)} Bearish Signals:")
|
||||
|
||||
Loading…
Reference in New Issue
Block a user