最新使用Ollama进行股票技术指标权威评测与排名对比结果分析
摘要
利用Streamlit可视化股票数据,计算滚动平均值、指数移动平均、相对强弱指数及布林带等指
这是关于股票技术指标评价的绝佳指南,没有之一。
核心内容:
- 使用 streamlit 可视化股票数据
- 计算多种指标了解市场趋势
- 利用 Llama 3 对数据做解释

本篇文章有几个有意思的点:
- 1.使用streamlit可视化。
- 2.计算滚动平均值和动量等指标来了解市场趋势。
- 3.使用Llama 3对数据做解释。
准备工作
提前安装并导入如下包:
import yfinance as yf import pandas as pd import schedule import time import ollama from datetime import datetime, timedelta
# Fetching historical data for Apple (AAPL) and Dow Jones (DJI) for yesterday (1-minute intervals)
stock = yf.Ticker("AAPL")
dow_jones = yf.Ticker("^DJI")
data = stock.history(period="1d", interval="1m")
dow_data = dow_jones.history(period="1d", interval="1m")
data.head()
全局变量与每日跟踪
Global variables to store rolling data for analysis
rolling_window = pd.DataFrame()
dow_rolling_window = pd.DataFrame()
# Variables to track daily context
daily_high = float('-inf')
daily_low = float('inf')
buying_momentum = 0
selling_momentum = 0
这段代码定义了一些全局变量,用于存储滚动数据和跟踪每日的市场情况。
- rolling_window和dow_rolling_window用于存储苹果公司和道琼斯指数的滚动数据。然后定义了几个变量来跟踪每日的市场情况。
- daily_high和 daily_low分别初始化为负无穷大和正无穷大,用于记录当天的最高价和最低价。通过将它们初始化为极端值,可以确保在实际数据更新时,这些变量会被正确地设置为当天的实际最高价和最低价。
- buying_momentum和selling_momentum变量初始化为0,用于跟踪当天的买入和卖出动量。这些变量可以帮助分析市场情绪和趋势,判断市场是处于买入还是卖出状态。
市场开市时长计算
get_market_open_duration:Extract current time from the last element of the window
def get_market_open_duration(window):
# Extract current time from the last element of the window
current_time = window.index[-1].time() # Returns a datetime.time object
# Get the previous trading day's date
previous_trading_day = datetime.today() - timedelta(days=1)
# Combine the previous trading day with the current time
current_datetime = datetime.combine(previous_trading_day, current_time)
# Define the market opening time as 09:30:00 on the previous trading day
market_start_time = datetime.combine(previous_trading_day, datetime.strptime("09:30:00", "%H:%M:%S").time())
# Calculate the duration the market has been open in minutes
market_open_duration = (current_datetime - market_start_time).total_seconds() / 60 # in minutes
return market_open_duration
LLM 文本洞察生成(重点:可替换为其他模型)
get_natural_language_insights:generate natural language insights using Ollama
def get_natural_language_insights(
rolling_a vg, ema, rsi, bollinger_upper, bollinger_lower,
price_change, volume_change, dow_rolling_a vg, market_open_duration, dow_price_change, dow_volume_change, daily_high, daily_low, buying_momentum, selling_momentum
):
prompt = f"""
You are a professional stock broker. Apple's stock has a 5-minute rolling a verage of {rolling_a vg:.2f}.
The Exponential Moving A verage (EMA) is {ema:.2f}, and the Relative Strength Index (RSI) is {rsi:.2f}.
The Bollinger Bands are set with an upper band of {bollinger_upper:.2f} and a lower band of {bollinger_lower:.2f}.
The price has changed by {price_change:.2f}, and the volume has shifted by {volume_change}.
The DOW price has changed by {dow_price_change:.2f}, and the volume has shifted by {dow_volume_change}.
Meanwhile, the Dow Jones index has a 5-minute rolling a verage of {dow_rolling_a vg:.2f}.
The market has been open for {market_open_duration:.2f} minutes.
Today's high was {daily_high:.2f} and low was {daily_low:.2f}.
The buying momentum is {buying_momentum:.2f} and selling momentum is {selling_momentum:.2f}.
Based on this data, provide insights into the current stock trend and the general market sentiment.
The insights should not be longer than 100 words and should not ha ve an introduction.
"""
response = ollama.chat(
model="llama3",
messages=[{"role": "user", "content": prompt}]
)
response_text = response['message']['content'].strip()
# Print the natural language insight
print("Natural Language Insight:", response_text)
核心指标计算与LLM触发
calculate_insights:moving a verages and trends
def calculate_insights(window, dow_window):
if len(window) >= 5:
# Calculate 5-minute rolling a verage of the 'Close' prices
rolling_a vg = window['Close'].rolling(window=5).mean().iloc[-1]
# Calculate price change and volume change
price_change = window['Close'].iloc[-1] - window['Close'].iloc[-2] if len(window) >= 2 else 0
volume_change = window['Volume'].iloc[-1] - window['Volume'].iloc[-2] if len(window) >= 2 else 0
# Calculate DOW price change and volume change
dow_price_change = dow_window['Close'].iloc[-1] - dow_window['Close'].iloc[-2] if len(dow_window) >= 2 else 0
dow_volume_change = dow_window['Volume'].iloc[-1] - dow_window['Volume'].iloc[-2] if len(dow_window) >= 2 else 0
# Calculate Exponential Moving A verage (EMA) and Bollinger Bands (with a 5-period window)
ema = window['Close'].ewm(span=5, adjust=False).mean().iloc[-1]
std = window['Close'].rolling(window=5).std().iloc[-1]
bollinger_upper = rolling_a vg + (2 * std)
bollinger_lower = rolling_a vg - (2 * std)
# Calculate Relative Strength Index (RSI) if there are enough periods (14 is typical)
delta = window['Close'].diff()
gain = delta.where(delta > 0, 0)
loss = -delta.where(delta < 0, 0)
a vg_gain = gain.rolling(window=14, min_periods=1).mean().iloc[-1]
a vg_loss = loss.rolling(window=14, min_periods=1).mean().iloc[-1]
rs = a vg_gain / a vg_loss if a vg_loss != 0 else float('nan')
rsi = 100 - (100 / (1 + rs))
# Calculate Dow Jones index rolling a verage
dow_rolling_a vg = dow_window['Close'].rolling(window=5).mean().iloc[-1]
market_open_duration = get_market_open_duration(window)
# Print the calculated insights
print(f"5-minute Rolling A verage: {rolling_a vg:.2f}")
print(f"EMA: {ema:.2f}")
print(f"RSI: {rsi:.2f}")
print(f"Bollinger Upper Band: {bollinger_upper:.2f}, Lower Band: {bollinger_lower:.2f}")
print(f"Price Change: {price_change:.2f}")
print(f"Volume Change: {volume_change}")
print(f"DOW Price Change: {dow_price_change:.2f}")
print(f"DOW Volume Change: {dow_volume_change}")
print(f"Dow Jones 5-minute Rolling A verage: {dow_rolling_a vg:.2f}")
print(f"Daily High: {daily_high:.2f}, Daily Low: {daily_low:.2f}")
print(f"Buying Momentum: {buying_momentum:.2f}, Selling Momentum: {selling_momentum:.2f}")
print(f"Market has been open for {market_open_duration:.2f} minutes")
if int(market_open_duration) % 5 == 0: # Trigger LLM every 5 minutes
get_natural_language_insights(
rolling_a vg, ema, rsi, bollinger_upper, bollinger_lower,
price_change, volume_change, dow_rolling_a vg, market_open_duration, dow_price_change, dow_volume_change, daily_high, daily_low, buying_momentum, selling_momentum
)
实时数据更新处理
process_stock_update:process a new stock update every minute
def process_stock_update():
global rolling_window, data, dow_rolling_window, dow_data
global daily_high, daily_low, buying_momentum, selling_momentum
if not data.empty and not dow_data.empty:
# Simulate receiving a new data point for AAPL and Dow Jones
update = data.iloc[0].to_frame().T
time_str = update.index[0].time()
print(time_str) # Output: ['09:30:00']
dow_update = dow_data.iloc[0].to_frame().T
data = data.iloc[1:] # Safely remove the first row without causing index issues
dow_data = dow_data.iloc[1:]
# Append the new data points to the rolling windows
rolling_window = pd.concat([rolling_window, update], ignore_index=False)
dow_rolling_window = pd.concat([dow_rolling_window, dow_update], ignore_index=False)
# Update daily high and low
daily_high = max(daily_high, update['Close'].values[0])
daily_low = min(daily_low, update['Close'].values[0])
# Calculate momentum based on price changes
if len(rolling_window) >= 2:
price_change = update['Close'].values[0] - rolling_window['Close'].iloc[-2]
if price_change > 0:
buying_momentum += price_change
else:
selling_momentum += abs(price_change)
# Limit the rolling window to 5 minutes for moving a verage
if len(rolling_window) > 5:
rolling_window = rolling_window.iloc[1:]
if len(dow_rolling_window) > 5:
dow_rolling_window = dow_rolling_window.iloc[1:]
# Calculate insights (moving a verages, Bollinger Bands, RSI, etc.)
calculate_insights(rolling_window, dow_rolling_window)
定时调度与运行
Schedule job to simulate receiving updates every minute:
schedule.every(10).seconds.do(process_stock_update)
# Run the scheduled jobs
print("Starting real-time simulation for AAPL stock updates...")
while True:
schedule.run_pending()
time.sleep(1)
运行日志与LLM分析结果
通过Llama 3给出的数据分析:
Natural Language Insight: Apple's price is consolidating within the Bollinger Bands, with a slight dip to 226.39. The EMA and rolling a verage are slightly higher, indicating a short-term uptrend. The RSI of 37.54 suggests the stock may be oversold, potentially leading to a bounce. The buying momentum is higher than selling momentum, implying investors are still cautiously optimistic. With the Dow Jones index also experiencing a slight decline, it's possible Apple's strength could lead it outperforming the broader market in the short term.
可视化界面
使用Streamlit设计一个界面:
# Streamlit UI
st.title("AI Stock Advisor")
logtxtbox = st.empty()
logtxt = '09:30:00'
logtxtbox.caption(logtxt)
message = st.chat_message("assistant")
message.write("Starting real-time simulation for AAPL stock updates. First update will be processed in 5 minutes...")
来源:互联网
本网站新闻资讯均来自公开渠道,力求准确但不保证绝对无误,内容观点仅代表作者本人,与本站无关。若涉及侵权,请联系我们处理。本站保留对声明的修改权,最终解释权归本站所有。