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 ($): ")
|
min_price = get_float_input("Enter minimum stock price ($): ")
|
||||||
max_price = get_float_input("Enter maximum stock price ($): ")
|
max_price = get_float_input("Enter maximum stock price ($): ")
|
||||||
min_volume = int(input("Enter minimum volume: "))
|
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():
|
def main():
|
||||||
print("\nStock Analysis System")
|
print("\nStock Analysis System")
|
||||||
@ -82,9 +83,9 @@ def main():
|
|||||||
print("✅ Scores saved in data/metrics/stock_scores.csv\n")
|
print("✅ Scores saved in data/metrics/stock_scores.csv\n")
|
||||||
|
|
||||||
elif choice == "2":
|
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
|
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":
|
elif choice == "3":
|
||||||
from trading.main import main as trading_main
|
from trading.main import main as trading_main
|
||||||
|
|||||||
@ -2,6 +2,7 @@ from datetime import datetime, timedelta
|
|||||||
import pandas as pd
|
import pandas as pd
|
||||||
from db.db_connection import create_client
|
from db.db_connection import create_client
|
||||||
from indicators.sunny_bands import SunnyBands
|
from indicators.sunny_bands import SunnyBands
|
||||||
|
from trading.position_calculator import PositionCalculator
|
||||||
|
|
||||||
def get_interval_choice() -> str:
|
def get_interval_choice() -> str:
|
||||||
"""Get user's preferred time interval"""
|
"""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:
|
except Exception as e:
|
||||||
print(f"Error analyzing {ticker}: {str(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"""
|
"""Run the SunnyBand scanner and save results"""
|
||||||
print(f"\nInitializing scan for stocks between ${min_price:.2f} and ${max_price:.2f}")
|
print(f"\nInitializing scan for stocks between ${min_price:.2f} and ${max_price:.2f}")
|
||||||
print(f"Minimum volume: {min_volume:,}")
|
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 = []
|
bearish_signals = []
|
||||||
errors = []
|
errors = []
|
||||||
|
|
||||||
# Initialize SunnyBands indicator
|
# Initialize SunnyBands indicator and position calculator
|
||||||
sunny = SunnyBands()
|
sunny = SunnyBands()
|
||||||
|
calculator = None
|
||||||
|
if portfolio_size and portfolio_size > 0:
|
||||||
|
calculator = PositionCalculator(account_size=portfolio_size)
|
||||||
|
|
||||||
# Track progress
|
# Track progress
|
||||||
total = len(tickers)
|
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'],
|
'volume': last_day['volume'],
|
||||||
'date': last_day['date'],
|
'date': last_day['date'],
|
||||||
'dma': results['dma'].iloc[-1],
|
'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)
|
bullish_signals.append(signal_data)
|
||||||
print(f"🟢 Bullish Signal: {ticker} at ${last_day['close']:.2f}")
|
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"Volume: {signal['volume']:,}")
|
||||||
print(f"DMA: ${signal['dma']:.2f}")
|
print(f"DMA: ${signal['dma']:.2f}")
|
||||||
print(f"Lower Band: ${signal['lower_band']:.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:
|
if bearish_signals:
|
||||||
print(f"\n🔴 Found {len(bearish_signals)} Bearish Signals:")
|
print(f"\n🔴 Found {len(bearish_signals)} Bearish Signals:")
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user