Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -9,13 +9,16 @@ from numpy import average as npAverage, nan as npNaN, log as npLog, power as npP
|
|
| 9 |
from pandas_ta.utils import get_offset, verify_series
|
| 10 |
from datetime import datetime
|
| 11 |
from matplotlib.dates import date2num
|
|
|
|
| 12 |
|
| 13 |
st.set_page_config(layout="wide")
|
| 14 |
|
| 15 |
st.title("Moving Averages Techniques for Price Analysis")
|
| 16 |
|
| 17 |
st.markdown("""
|
| 18 |
-
This
|
|
|
|
|
|
|
| 19 |
|
| 20 |
- **Fundamental Techniques**: Includes **SMA**, **EMA**, **WMA**, **DEMA**, **TEMA**, **VAMA**, **KAMA**, **TMA**, and **HMA**.
|
| 21 |
|
|
@@ -28,15 +31,14 @@ This tool implements various moving averages methods:
|
|
| 28 |
For technical details on these methods, refer to [this article](https://entreprenerdly.com/top-36-moving-averages-methods-for-stock-prices-in-python/).
|
| 29 |
""")
|
| 30 |
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
""")
|
| 40 |
|
| 41 |
# Function to fetch data
|
| 42 |
@st.cache_data
|
|
@@ -458,309 +460,10 @@ start_date = st.sidebar.date_input(
|
|
| 458 |
)
|
| 459 |
end_date = st.sidebar.date_input(
|
| 460 |
"End Date",
|
| 461 |
-
value=st.session_state.get('end_date', pd.to_datetime(
|
| 462 |
help="Select the end date for fetching the stock data."
|
| 463 |
)
|
| 464 |
|
| 465 |
-
# Run button to apply moving averages
|
| 466 |
-
if st.sidebar.button('Run Analysis'):
|
| 467 |
-
# Save the moving average settings to session state
|
| 468 |
-
st.session_state['use_sma'] = use_sma
|
| 469 |
-
st.session_state['sma_period'] = sma_period
|
| 470 |
-
st.session_state['use_ema'] = use_ema
|
| 471 |
-
st.session_state['ema_period'] = ema_period
|
| 472 |
-
st.session_state['use_wma'] = use_wma
|
| 473 |
-
st.session_state['wma_period'] = wma_period
|
| 474 |
-
st.session_state['use_dema'] = use_dema
|
| 475 |
-
st.session_state['dema_period'] = dema_period
|
| 476 |
-
st.session_state['use_tema'] = use_tema
|
| 477 |
-
st.session_state['tema_period'] = tema_period
|
| 478 |
-
st.session_state['use_vama'] = use_vama
|
| 479 |
-
st.session_state['vama_period'] = vama_period
|
| 480 |
-
st.session_state['use_kama'] = use_kama
|
| 481 |
-
st.session_state['kama_period'] = kama_period
|
| 482 |
-
st.session_state['fastest_period'] = fastest_period
|
| 483 |
-
st.session_state['slowest_period'] = slowest_period
|
| 484 |
-
st.session_state['use_tma'] = use_tma
|
| 485 |
-
st.session_state['tma_period'] = tma_period
|
| 486 |
-
st.session_state['use_hull_ma'] = use_hull_ma
|
| 487 |
-
st.session_state['hull_ma_period'] = hull_ma_period
|
| 488 |
-
st.session_state['use_harmonic_ma'] = use_harmonic_ma
|
| 489 |
-
st.session_state['harmonic_ma_period'] = harmonic_ma_period
|
| 490 |
-
st.session_state['use_frama'] = use_frama
|
| 491 |
-
st.session_state['frama_batch'] = frama_batch
|
| 492 |
-
st.session_state['use_zlema'] = use_zlema
|
| 493 |
-
st.session_state['zlema_period'] = zlema_period
|
| 494 |
-
st.session_state['use_vidya'] = use_vidya
|
| 495 |
-
st.session_state['vidya_period'] = vidya_period
|
| 496 |
-
st.session_state['use_alma'] = use_alma
|
| 497 |
-
st.session_state['alma_period'] = alma_period
|
| 498 |
-
st.session_state['alma_offset'] = alma_offset
|
| 499 |
-
st.session_state['alma_sigma'] = alma_sigma
|
| 500 |
-
st.session_state['use_mama_fama'] = use_mama_fama
|
| 501 |
-
st.session_state['mama_fast_limit'] = mama_fast_limit
|
| 502 |
-
st.session_state['mama_slow_limit'] = mama_slow_limit
|
| 503 |
-
st.session_state['use_apma'] = use_apma
|
| 504 |
-
st.session_state['apma_min_period'] = apma_min_period
|
| 505 |
-
st.session_state['apma_max_period'] = apma_max_period
|
| 506 |
-
st.session_state['use_rainbow_ema'] = use_rainbow_ema
|
| 507 |
-
st.session_state['rainbow_lookback_periods'] = rainbow_lookback_periods
|
| 508 |
-
st.session_state['use_wilders_ma'] = use_wilders_ma
|
| 509 |
-
st.session_state['wilders_ma_period'] = wilders_ma_period
|
| 510 |
-
st.session_state['use_smma'] = use_smma
|
| 511 |
-
st.session_state['smma_period'] = smma_period
|
| 512 |
-
st.session_state['use_gmma'] = use_gmma
|
| 513 |
-
st.session_state['gmma_short_periods'] = gmma_short_periods
|
| 514 |
-
st.session_state['gmma_long_periods'] = gmma_long_periods
|
| 515 |
-
st.session_state['use_lsma'] = use_lsma
|
| 516 |
-
st.session_state['lsma_period'] = lsma_period
|
| 517 |
-
st.session_state['use_mma'] = use_mma
|
| 518 |
-
st.session_state['mma_period'] = mma_period
|
| 519 |
-
st.session_state['use_sinwma'] = use_sinwma
|
| 520 |
-
st.session_state['sinwma_period'] = sinwma_period
|
| 521 |
-
st.session_state['use_medma'] = use_medma
|
| 522 |
-
st.session_state['medma_period'] = medma_period
|
| 523 |
-
st.session_state['use_gma'] = use_gma
|
| 524 |
-
st.session_state['gma_period'] = gma_period
|
| 525 |
-
st.session_state['use_evwma'] = use_evwma
|
| 526 |
-
st.session_state['evwma_period'] = evwma_period
|
| 527 |
-
st.session_state['use_rema'] = use_rema
|
| 528 |
-
st.session_state['rema_alpha'] = rema_alpha
|
| 529 |
-
st.session_state['rema_lambda'] = rema_lambda
|
| 530 |
-
st.session_state['use_pwma'] = use_pwma
|
| 531 |
-
st.session_state['pwma_period'] = pwma_period
|
| 532 |
-
st.session_state['use_jma'] = use_jma
|
| 533 |
-
st.session_state['jma_period'] = jma_period
|
| 534 |
-
st.session_state['jma_phase'] = jma_phase
|
| 535 |
-
st.session_state['use_epma'] = use_epma
|
| 536 |
-
st.session_state['epma_period'] = epma_period
|
| 537 |
-
st.session_state['use_cma'] = use_cma
|
| 538 |
-
st.session_state['use_mcginley_dynamic'] = use_mcginley_dynamic
|
| 539 |
-
st.session_state['mcginley_dynamic_period'] = mcginley_dynamic_period
|
| 540 |
-
#st.session_state['use_ama'] = use_ama
|
| 541 |
-
#st.session_state['ama_anchor_date'] = ama_anchor_date
|
| 542 |
-
st.session_state['use_fma'] = use_fma
|
| 543 |
-
st.session_state['fma_period'] = fma_period
|
| 544 |
-
# (Save all previous moving average settings here)
|
| 545 |
-
|
| 546 |
-
# Start with the base price plot
|
| 547 |
-
fig = go.Figure(data=st.session_state['price_plot'].data)
|
| 548 |
-
|
| 549 |
-
# Add JMA if selected
|
| 550 |
-
if use_jma:
|
| 551 |
-
st.session_state['JMA'] = jma(data['Close'], length=jma_period, phase=jma_phase)
|
| 552 |
-
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['JMA'], mode='lines', name=f'JMA (n={jma_period}, phase={jma_phase})', line=dict(dash='dash', color='green')))
|
| 553 |
-
|
| 554 |
-
# Add EPMA if selected
|
| 555 |
-
if use_epma:
|
| 556 |
-
st.session_state['EPMA'] = calculate_EPMA(data['Close'].tolist(), epma_period)
|
| 557 |
-
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['EPMA'], mode='lines', name=f'EPMA (n={epma_period})', line=dict(dash='dash', color='blue')))
|
| 558 |
-
|
| 559 |
-
# Add CMA if selected
|
| 560 |
-
if use_cma:
|
| 561 |
-
st.session_state['CMA'] = calculate_CMA(data['Close'])
|
| 562 |
-
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['CMA'], mode='lines', name=f'CMA', line=dict(dash='dash', color='blue')))
|
| 563 |
-
|
| 564 |
-
# Add McGinley Dynamic if selected
|
| 565 |
-
if use_mcginley_dynamic:
|
| 566 |
-
st.session_state['McGinley_Dynamic'] = calculate_mcginley_dynamic(data['Close'].tolist(), mcginley_dynamic_period)
|
| 567 |
-
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['McGinley_Dynamic'], mode='lines', name=f'McGinley Dynamic (n={mcginley_dynamic_period})', line=dict(dash='dash', color='orange')))
|
| 568 |
-
|
| 569 |
-
# Add AMA if selected
|
| 570 |
-
#if use_ama:
|
| 571 |
-
# st.session_state['AMA'] = calculate_AMA(data['Close'].tolist(), ama_anchor_date, data)
|
| 572 |
-
# fig.add_trace(go.Scatter(x=data.index, y=st.session_state['AMA'], mode='lines', name=f'Anchored MA (Anchor Date={ama_anchor_date})', line=dict(dash='dash', color='red')))
|
| 573 |
-
# fig.add_shape(type="line", x0=ama_anchor_date, y0=data['Close'].min(), x1=ama_anchor_date, y1=data['Close'].max(), line=dict(color="blue", width=2, dash="dash"))
|
| 574 |
-
|
| 575 |
-
# Add FMA if selected
|
| 576 |
-
if use_fma:
|
| 577 |
-
st.session_state['FMA'] = filtered_moving_average(data['Close'].values, fma_period)
|
| 578 |
-
fig.add_trace(go.Scatter(x=data.index, y=np.concatenate([np.array([np.nan]*(fma_period-1)), st.session_state['FMA']]), mode='lines', name=f'Filtered MA (n={fma_period})', line=dict(dash='dash', color='green')))
|
| 579 |
-
|
| 580 |
-
# Add SMA if selected
|
| 581 |
-
if use_sma:
|
| 582 |
-
st.session_state['SMA'] = data['Close'].rolling(window=sma_period).mean()
|
| 583 |
-
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['SMA'], mode='lines', name=f'{sma_period}-Day SMA', line=dict(dash='dash')))
|
| 584 |
-
|
| 585 |
-
# Add EMA if selected
|
| 586 |
-
if use_ema:
|
| 587 |
-
st.session_state['EMA'] = data['Close'].ewm(span=ema_period, adjust=False).mean()
|
| 588 |
-
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['EMA'], mode='lines', name=f'{ema_period}-Day EMA', line=dict(dash='dash', color='green')))
|
| 589 |
-
|
| 590 |
-
# Add WMA if selected
|
| 591 |
-
if use_wma:
|
| 592 |
-
weights = np.arange(1, wma_period + 1)
|
| 593 |
-
st.session_state['WMA'] = data['Close'].rolling(window=wma_period).apply(lambda prices: np.dot(prices, weights)/weights.sum(), raw=True)
|
| 594 |
-
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['WMA'], mode='lines', name=f'{wma_period}-Day WMA', line=dict(dash='dash', color='orange')))
|
| 595 |
-
|
| 596 |
-
# Add DEMA if selected
|
| 597 |
-
if use_dema:
|
| 598 |
-
data['EMA'] = data['Close'].ewm(span=dema_period, adjust=False).mean()
|
| 599 |
-
data['EMA2'] = data['EMA'].ewm(span=dema_period, adjust=False).mean()
|
| 600 |
-
st.session_state['DEMA'] = 2 * data['EMA'] - data['EMA2']
|
| 601 |
-
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['DEMA'], mode='lines', name=f'{dema_period}-Day DEMA', line=dict(dash='dash', color='red')))
|
| 602 |
-
|
| 603 |
-
# Add TEMA if selected
|
| 604 |
-
if use_tema:
|
| 605 |
-
data['EMA'] = data['Close'].ewm(span=tema_period, adjust=False).mean()
|
| 606 |
-
data['EMA2'] = data['EMA'].ewm(span=tema_period, adjust=False).mean()
|
| 607 |
-
data['EMA3'] = data['EMA2'].ewm(span=tema_period, adjust=False).mean()
|
| 608 |
-
st.session_state['TEMA'] = 3 * data['EMA'] - 3 * data['EMA2'] + data['EMA3']
|
| 609 |
-
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['TEMA'], mode='lines', name=f'{tema_period}-Day TEMA', line=dict(dash='dash', color='purple')))
|
| 610 |
-
|
| 611 |
-
# Add VAMA if selected
|
| 612 |
-
if use_vama:
|
| 613 |
-
data['Volume_Price'] = data['Close'] * data['Volume']
|
| 614 |
-
st.session_state['VAMA'] = data['Volume_Price'].rolling(window=vama_period).sum() / data['Volume'].rolling(window=vama_period).sum()
|
| 615 |
-
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['VAMA'], mode='lines', name=f'{vama_period}-Day VAMA', line=dict(dash='dash', color='orange')))
|
| 616 |
-
|
| 617 |
-
# Add KAMA if selected
|
| 618 |
-
if use_kama:
|
| 619 |
-
fastest_SC = 2 / (fastest_period + 1)
|
| 620 |
-
slowest_SC = 2 / (slowest_period + 1)
|
| 621 |
-
data['Change'] = abs(data['Close'] - data['Close'].shift(kama_period))
|
| 622 |
-
data['Volatility'] = data['Close'].diff().abs().rolling(window=kama_period).sum()
|
| 623 |
-
data['ER'] = data['Change'] / data['Volatility']
|
| 624 |
-
data['SC'] = (data['ER'] * (fastest_SC - slowest_SC) + slowest_SC)**2
|
| 625 |
-
data['KAMA'] = data['Close'].copy()
|
| 626 |
-
for i in range(kama_period, len(data)):
|
| 627 |
-
data['KAMA'].iloc[i] = data['KAMA'].iloc[i-1] + data['SC'].iloc[i] * (data['Close'].iloc[i] - data['KAMA'].iloc[i-1])
|
| 628 |
-
st.session_state['KAMA'] = data['KAMA']
|
| 629 |
-
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['KAMA'], mode='lines', name=f'KAMA (n={kama_period})', line=dict(dash='dash', color='green')))
|
| 630 |
-
|
| 631 |
-
# Add TMA if selected
|
| 632 |
-
if use_tma:
|
| 633 |
-
half_n = (tma_period + 1) // 2
|
| 634 |
-
data['Half_SMA'] = data['Close'].rolling(window=half_n).mean()
|
| 635 |
-
st.session_state['TMA'] = data['Half_SMA'].rolling(window=half_n).mean()
|
| 636 |
-
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['TMA'], mode='lines', name=f'TMA (n={tma_period})', line=dict(dash='dash', color='red')))
|
| 637 |
-
|
| 638 |
-
# Add Hull MA if selected
|
| 639 |
-
if use_hull_ma:
|
| 640 |
-
st.session_state['Hull_MA'] = hull_moving_average(data['Close'], hull_ma_period)
|
| 641 |
-
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['Hull_MA'], mode='lines', name=f'Hull MA (n={hull_ma_period})', line=dict(dash='dash', color='green')))
|
| 642 |
-
|
| 643 |
-
# Add Harmonic MA if selected
|
| 644 |
-
if use_harmonic_ma:
|
| 645 |
-
st.session_state['Harmonic_MA'] = calculate_harmonic_moving_average(data['Close'].values, harmonic_ma_period)
|
| 646 |
-
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['Harmonic_MA'], mode='lines', name=f'Harmonic MA (n={harmonic_ma_period})', line=dict(dash='dash', color='purple')))
|
| 647 |
-
|
| 648 |
-
# Add FRAMA if selected
|
| 649 |
-
if use_frama:
|
| 650 |
-
st.session_state['FRAMA'] = calculate_FRAMA(data, batch=frama_batch)['FRAMA']
|
| 651 |
-
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['FRAMA'], mode='lines', name=f'FRAMA (batch={frama_batch})', line=dict(dash='dash', color='green')))
|
| 652 |
-
|
| 653 |
-
# Add ZLEMA if selected
|
| 654 |
-
if use_zlema:
|
| 655 |
-
st.session_state['ZLEMA'] = calculate_ZLEMA(data['Close'].tolist(), zlema_period)
|
| 656 |
-
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['ZLEMA'], mode='lines', name=f'ZLEMA (n={zlema_period})', line=dict(dash='dash', color='red')))
|
| 657 |
-
|
| 658 |
-
# Add VIDYA if selected
|
| 659 |
-
if use_vidya:
|
| 660 |
-
st.session_state['VIDYA'] = calculate_VIDYA(data['Close'].tolist(), vidya_period)
|
| 661 |
-
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['VIDYA'], mode='lines', name=f'VIDYA (n={vidya_period})', line=dict(dash='dash', color='blue')))
|
| 662 |
-
|
| 663 |
-
# Add ALMA if selected
|
| 664 |
-
if use_alma:
|
| 665 |
-
st.session_state['ALMA'] = calculate_ALMA(data['Close'].tolist(), alma_period, offset=alma_offset, sigma=alma_sigma)
|
| 666 |
-
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['ALMA'], mode='lines', name=f'ALMA (n={alma_period})', line=dict(dash='dash', color='purple')))
|
| 667 |
-
|
| 668 |
-
# Add MAMA and FAMA if selected
|
| 669 |
-
if use_mama_fama:
|
| 670 |
-
data['MAMA'], data['FAMA'] = talib.MAMA(data['Close'].values, fastlimit=mama_fast_limit, slowlimit=mama_slow_limit)
|
| 671 |
-
st.session_state['MAMA'] = data['MAMA']
|
| 672 |
-
st.session_state['FAMA'] = data['FAMA']
|
| 673 |
-
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['MAMA'], mode='lines', name=f'MAMA', line=dict(dash='dash', color='blue')))
|
| 674 |
-
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['FAMA'], mode='lines', name=f'FAMA', line=dict(dash='dash', color='red')))
|
| 675 |
-
|
| 676 |
-
# Add APMA if selected
|
| 677 |
-
if use_apma:
|
| 678 |
-
st.session_state['APMA'] = adaptive_period_moving_average(data['Close'].values, min_period=apma_min_period, max_period=apma_max_period)
|
| 679 |
-
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['APMA'], mode='lines', name=f'APMA (min={apma_min_period}, max={apma_max_period})', line=dict(dash='dash', color='red')))
|
| 680 |
-
|
| 681 |
-
# Add Rainbow EMA if selected
|
| 682 |
-
if use_rainbow_ema:
|
| 683 |
-
data = calculate_rainbow_ema(data, rainbow_lookback_periods)
|
| 684 |
-
colors = ['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet', 'black','gray','brown']
|
| 685 |
-
for i, lookback in enumerate(rainbow_lookback_periods):
|
| 686 |
-
fig.add_trace(go.Scatter(x=data.index, y=data[f'EMA{lookback}'], mode='lines', name=f'EMA {lookback}', line=dict(dash='solid', color=colors[i % len(colors)])))
|
| 687 |
-
|
| 688 |
-
# Add Wilders MA if selected
|
| 689 |
-
if use_wilders_ma:
|
| 690 |
-
st.session_state['Wilders_MA'] = wilders_moving_average(data['Close'].tolist(), wilders_ma_period)
|
| 691 |
-
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['Wilders_MA'], mode='lines', name=f'Wilders MA (n={wilders_ma_period})', line=dict(dash='dash', color='red')))
|
| 692 |
-
|
| 693 |
-
# Add SMMA if selected
|
| 694 |
-
if use_smma:
|
| 695 |
-
st.session_state['SMMA'] = calculate_SMMA(data['Close'].tolist(), smma_period)
|
| 696 |
-
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['SMMA'], mode='lines', name=f'SMMA (n={smma_period})', line=dict(dash='dash', color='red')))
|
| 697 |
-
|
| 698 |
-
# Add GMMA if selected
|
| 699 |
-
if use_gmma:
|
| 700 |
-
close_prices = data['Close'].tolist()
|
| 701 |
-
for period in gmma_short_periods:
|
| 702 |
-
data[f'EMA_{period}'] = calculate_EMA(close_prices, period)
|
| 703 |
-
fig.add_trace(go.Scatter(x=data.index, y=data[f'EMA_{period}'], mode='lines', name=f'GMMA Short EMA {period}', line=dict(dash='solid')))
|
| 704 |
-
for period in gmma_long_periods:
|
| 705 |
-
data[f'EMA_{period}'] = calculate_EMA(close_prices, period)
|
| 706 |
-
fig.add_trace(go.Scatter(x=data.index, y=data[f'EMA_{period}'], mode='lines', name=f'GMMA Long EMA {period}', line=dict(dash='dash')))
|
| 707 |
-
|
| 708 |
-
# Add LSMA if selected
|
| 709 |
-
if use_lsma:
|
| 710 |
-
st.session_state['LSMA'] = calculate_LSMA(data['Close'].tolist(), lsma_period)
|
| 711 |
-
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['LSMA'], mode='lines', name=f'LSMA (n={lsma_period})', line=dict(dash='dash', color='blue')))
|
| 712 |
-
|
| 713 |
-
# Add MMA (Welch's MMA) if selected
|
| 714 |
-
if use_mma:
|
| 715 |
-
st.session_state['MMA'] = calculate_MMA(data['Close'].tolist(), mma_period)
|
| 716 |
-
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['MMA'], mode='lines', name=f'MMA (n={mma_period})', line=dict(dash='dash', color='blue')))
|
| 717 |
-
|
| 718 |
-
# Add SinWMA if selected
|
| 719 |
-
if use_sinwma:
|
| 720 |
-
st.session_state['SinWMA'] = calculate_SinWMA(data['Close'].tolist(), sinwma_period)
|
| 721 |
-
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['SinWMA'], mode='lines', name=f'SinWMA (n={sinwma_period})', line=dict(dash='dash', color='green')))
|
| 722 |
-
|
| 723 |
-
# Add MedMA if selected
|
| 724 |
-
if use_medma:
|
| 725 |
-
st.session_state['MedMA'] = calculate_MedMA(data['Close'].tolist(), medma_period)
|
| 726 |
-
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['MedMA'], mode='lines', name=f'MedMA (n={medma_period})', line=dict(dash='dash', color='blue')))
|
| 727 |
-
|
| 728 |
-
# Add GMA if selected
|
| 729 |
-
if use_gma:
|
| 730 |
-
st.session_state['GMA'] = calculate_GMA(data['Close'].tolist(), gma_period)
|
| 731 |
-
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['GMA'], mode='lines', name=f'GMA (n={gma_period})', line=dict(dash='dash', color='green')))
|
| 732 |
-
|
| 733 |
-
# Add eVWMA if selected
|
| 734 |
-
if use_evwma:
|
| 735 |
-
st.session_state['eVWMA'] = calculate_eVWMA(data['Close'], data['Volume'], evwma_period)
|
| 736 |
-
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['eVWMA'], mode='lines', name=f'eVWMA (n={evwma_period})', line=dict(dash='dash', color='blue')))
|
| 737 |
-
|
| 738 |
-
# Add REMA if selected
|
| 739 |
-
if use_rema:
|
| 740 |
-
st.session_state['REMA'] = REMA(data['Close'], alpha=rema_alpha, lambda_=rema_lambda)
|
| 741 |
-
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['REMA'], mode='lines', name=f'REMA (alpha={rema_alpha}, lambda={rema_lambda})', line=dict(dash='dash', color='red')))
|
| 742 |
-
|
| 743 |
-
# Add PWMA if selected
|
| 744 |
-
if use_pwma:
|
| 745 |
-
pwma_values = parabolic_weighted_moving_average(data['Close'].values, pwma_period)
|
| 746 |
-
st.session_state['PWMA'] = np.concatenate([np.array([np.nan]*(pwma_period-1)), pwma_values])
|
| 747 |
-
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['PWMA'], mode='lines', name=f'PWMA (n={pwma_period})', line=dict(dash='dash', color='red')))
|
| 748 |
-
|
| 749 |
-
|
| 750 |
-
# Update layout with grid toggle
|
| 751 |
-
fig.update_layout(
|
| 752 |
-
title=f'{ticker_symbol} Stock Price with Moving Averages',
|
| 753 |
-
xaxis_title='Date',
|
| 754 |
-
yaxis_title='Stock Price',
|
| 755 |
-
legend_title='Indicators',
|
| 756 |
-
template='plotly_white',
|
| 757 |
-
xaxis=dict(showgrid=show_grid),
|
| 758 |
-
yaxis=dict(showgrid=show_grid)
|
| 759 |
-
)
|
| 760 |
-
|
| 761 |
-
# Store the updated figure in session state
|
| 762 |
-
st.session_state['current_fig'] = fig
|
| 763 |
-
|
| 764 |
# Fetch Data button
|
| 765 |
if st.sidebar.button('Fetch Data'):
|
| 766 |
# Only fetch if the ticker or date range has changed
|
|
@@ -1036,9 +739,7 @@ if 'data' in st.session_state:
|
|
| 1036 |
mama_fast_limit = st.sidebar.number_input(
|
| 1037 |
'MAMA Fast Limit',
|
| 1038 |
min_value=0.0,
|
| 1039 |
-
max_value=1.0,
|
| 1040 |
-
|
| 1041 |
-
|
| 1042 |
value=st.session_state.get('mama_fast_limit', 0.5),
|
| 1043 |
step=0.01,
|
| 1044 |
disabled=not use_mama_fama,
|
|
@@ -1369,11 +1070,312 @@ if 'data' in st.session_state:
|
|
| 1369 |
help="Toggle to show or hide the grid on the plot."
|
| 1370 |
)
|
| 1371 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1372 |
|
| 1373 |
# Display the current figure, which remains unchanged until "Run" is clicked
|
| 1374 |
if 'current_fig' in st.session_state:
|
| 1375 |
st.plotly_chart(st.session_state['current_fig'], use_container_width=True)
|
| 1376 |
|
|
|
|
|
|
|
|
|
|
| 1377 |
st.markdown(
|
| 1378 |
"""
|
| 1379 |
<style>
|
|
@@ -1394,4 +1396,4 @@ hide_streamlit_style = """
|
|
| 1394 |
footer {visibility: hidden;}
|
| 1395 |
</style>
|
| 1396 |
"""
|
| 1397 |
-
st.markdown(hide_streamlit_style, unsafe_allow_html=True)
|
|
|
|
| 9 |
from pandas_ta.utils import get_offset, verify_series
|
| 10 |
from datetime import datetime
|
| 11 |
from matplotlib.dates import date2num
|
| 12 |
+
from datetime import datetime
|
| 13 |
|
| 14 |
st.set_page_config(layout="wide")
|
| 15 |
|
| 16 |
st.title("Moving Averages Techniques for Price Analysis")
|
| 17 |
|
| 18 |
st.markdown("""
|
| 19 |
+
This app provides a detailed analysis of various moving averages. You can select from a wide range of techniques to better understand asset price movement trends.
|
| 20 |
+
|
| 21 |
+
### Moving Averages Categories:
|
| 22 |
|
| 23 |
- **Fundamental Techniques**: Includes **SMA**, **EMA**, **WMA**, **DEMA**, **TEMA**, **VAMA**, **KAMA**, **TMA**, and **HMA**.
|
| 24 |
|
|
|
|
| 31 |
For technical details on these methods, refer to [this article](https://entreprenerdly.com/top-36-moving-averages-methods-for-stock-prices-in-python/).
|
| 32 |
""")
|
| 33 |
|
| 34 |
+
st.sidebar.markdown("""
|
| 35 |
+
### How to Use:
|
| 36 |
+
- **Asset Symbol**: Enter the stock symbol (e.g., `AAPL`) or Crypto Currency Pair (e.g., `BTC-USD`).
|
| 37 |
+
- **Date Range**: Select the start and end dates.
|
| 38 |
+
- **Fetch Data**: Click 'Fetch Data' to load the stock data.
|
| 39 |
+
- **Moving Averages**: Choose and customize your moving averages.
|
| 40 |
+
- **Run Analysis**: Click 'Run' to apply and visualize.
|
| 41 |
+
""")
|
|
|
|
| 42 |
|
| 43 |
# Function to fetch data
|
| 44 |
@st.cache_data
|
|
|
|
| 460 |
)
|
| 461 |
end_date = st.sidebar.date_input(
|
| 462 |
"End Date",
|
| 463 |
+
value=st.session_state.get('end_date', pd.to_datetime(pd.Timestamp.now().date() + pd.Timedelta(days=1))),
|
| 464 |
help="Select the end date for fetching the stock data."
|
| 465 |
)
|
| 466 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 467 |
# Fetch Data button
|
| 468 |
if st.sidebar.button('Fetch Data'):
|
| 469 |
# Only fetch if the ticker or date range has changed
|
|
|
|
| 739 |
mama_fast_limit = st.sidebar.number_input(
|
| 740 |
'MAMA Fast Limit',
|
| 741 |
min_value=0.0,
|
| 742 |
+
max_value=1.0,
|
|
|
|
|
|
|
| 743 |
value=st.session_state.get('mama_fast_limit', 0.5),
|
| 744 |
step=0.01,
|
| 745 |
disabled=not use_mama_fama,
|
|
|
|
| 1070 |
help="Toggle to show or hide the grid on the plot."
|
| 1071 |
)
|
| 1072 |
|
| 1073 |
+
# Run button to apply moving averages
|
| 1074 |
+
if st.sidebar.button('Run Analysis'):
|
| 1075 |
+
# Save the moving average settings to session state
|
| 1076 |
+
st.session_state['use_sma'] = use_sma
|
| 1077 |
+
st.session_state['sma_period'] = sma_period
|
| 1078 |
+
st.session_state['use_ema'] = use_ema
|
| 1079 |
+
st.session_state['ema_period'] = ema_period
|
| 1080 |
+
st.session_state['use_wma'] = use_wma
|
| 1081 |
+
st.session_state['wma_period'] = wma_period
|
| 1082 |
+
st.session_state['use_dema'] = use_dema
|
| 1083 |
+
st.session_state['dema_period'] = dema_period
|
| 1084 |
+
st.session_state['use_tema'] = use_tema
|
| 1085 |
+
st.session_state['tema_period'] = tema_period
|
| 1086 |
+
st.session_state['use_vama'] = use_vama
|
| 1087 |
+
st.session_state['vama_period'] = vama_period
|
| 1088 |
+
st.session_state['use_kama'] = use_kama
|
| 1089 |
+
st.session_state['kama_period'] = kama_period
|
| 1090 |
+
st.session_state['fastest_period'] = fastest_period
|
| 1091 |
+
st.session_state['slowest_period'] = slowest_period
|
| 1092 |
+
st.session_state['use_tma'] = use_tma
|
| 1093 |
+
st.session_state['tma_period'] = tma_period
|
| 1094 |
+
st.session_state['use_hull_ma'] = use_hull_ma
|
| 1095 |
+
st.session_state['hull_ma_period'] = hull_ma_period
|
| 1096 |
+
st.session_state['use_harmonic_ma'] = use_harmonic_ma
|
| 1097 |
+
st.session_state['harmonic_ma_period'] = harmonic_ma_period
|
| 1098 |
+
st.session_state['use_frama'] = use_frama
|
| 1099 |
+
st.session_state['frama_batch'] = frama_batch
|
| 1100 |
+
st.session_state['use_zlema'] = use_zlema
|
| 1101 |
+
st.session_state['zlema_period'] = zlema_period
|
| 1102 |
+
st.session_state['use_vidya'] = use_vidya
|
| 1103 |
+
st.session_state['vidya_period'] = vidya_period
|
| 1104 |
+
st.session_state['use_alma'] = use_alma
|
| 1105 |
+
st.session_state['alma_period'] = alma_period
|
| 1106 |
+
st.session_state['alma_offset'] = alma_offset
|
| 1107 |
+
st.session_state['alma_sigma'] = alma_sigma
|
| 1108 |
+
st.session_state['use_mama_fama'] = use_mama_fama
|
| 1109 |
+
st.session_state['mama_fast_limit'] = mama_fast_limit
|
| 1110 |
+
st.session_state['mama_slow_limit'] = mama_slow_limit
|
| 1111 |
+
st.session_state['use_apma'] = use_apma
|
| 1112 |
+
st.session_state['apma_min_period'] = apma_min_period
|
| 1113 |
+
st.session_state['apma_max_period'] = apma_max_period
|
| 1114 |
+
st.session_state['use_rainbow_ema'] = use_rainbow_ema
|
| 1115 |
+
st.session_state['rainbow_lookback_periods'] = rainbow_lookback_periods
|
| 1116 |
+
st.session_state['use_wilders_ma'] = use_wilders_ma
|
| 1117 |
+
st.session_state['wilders_ma_period'] = wilders_ma_period
|
| 1118 |
+
st.session_state['use_smma'] = use_smma
|
| 1119 |
+
st.session_state['smma_period'] = smma_period
|
| 1120 |
+
st.session_state['use_gmma'] = use_gmma
|
| 1121 |
+
st.session_state['gmma_short_periods'] = gmma_short_periods
|
| 1122 |
+
st.session_state['gmma_long_periods'] = gmma_long_periods
|
| 1123 |
+
st.session_state['use_lsma'] = use_lsma
|
| 1124 |
+
st.session_state['lsma_period'] = lsma_period
|
| 1125 |
+
st.session_state['use_mma'] = use_mma
|
| 1126 |
+
st.session_state['mma_period'] = mma_period
|
| 1127 |
+
st.session_state['use_sinwma'] = use_sinwma
|
| 1128 |
+
st.session_state['sinwma_period'] = sinwma_period
|
| 1129 |
+
st.session_state['use_medma'] = use_medma
|
| 1130 |
+
st.session_state['medma_period'] = medma_period
|
| 1131 |
+
st.session_state['use_gma'] = use_gma
|
| 1132 |
+
st.session_state['gma_period'] = gma_period
|
| 1133 |
+
st.session_state['use_evwma'] = use_evwma
|
| 1134 |
+
st.session_state['evwma_period'] = evwma_period
|
| 1135 |
+
st.session_state['use_rema'] = use_rema
|
| 1136 |
+
st.session_state['rema_alpha'] = rema_alpha
|
| 1137 |
+
st.session_state['rema_lambda'] = rema_lambda
|
| 1138 |
+
st.session_state['use_pwma'] = use_pwma
|
| 1139 |
+
st.session_state['pwma_period'] = pwma_period
|
| 1140 |
+
st.session_state['use_jma'] = use_jma
|
| 1141 |
+
st.session_state['jma_period'] = jma_period
|
| 1142 |
+
st.session_state['jma_phase'] = jma_phase
|
| 1143 |
+
st.session_state['use_epma'] = use_epma
|
| 1144 |
+
st.session_state['epma_period'] = epma_period
|
| 1145 |
+
st.session_state['use_cma'] = use_cma
|
| 1146 |
+
st.session_state['use_mcginley_dynamic'] = use_mcginley_dynamic
|
| 1147 |
+
st.session_state['mcginley_dynamic_period'] = mcginley_dynamic_period
|
| 1148 |
+
#st.session_state['use_ama'] = use_ama
|
| 1149 |
+
#st.session_state['ama_anchor_date'] = ama_anchor_date
|
| 1150 |
+
st.session_state['use_fma'] = use_fma
|
| 1151 |
+
st.session_state['fma_period'] = fma_period
|
| 1152 |
+
# (Save all previous moving average settings here)
|
| 1153 |
+
|
| 1154 |
+
# Start with the base price plot
|
| 1155 |
+
fig = go.Figure(data=st.session_state['price_plot'].data)
|
| 1156 |
+
|
| 1157 |
+
# Add JMA if selected
|
| 1158 |
+
if use_jma:
|
| 1159 |
+
st.session_state['JMA'] = jma(data['Close'], length=jma_period, phase=jma_phase)
|
| 1160 |
+
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['JMA'], mode='lines', name=f'JMA (n={jma_period}, phase={jma_phase})', line=dict(dash='dash', color='green')))
|
| 1161 |
+
|
| 1162 |
+
# Add EPMA if selected
|
| 1163 |
+
if use_epma:
|
| 1164 |
+
st.session_state['EPMA'] = calculate_EPMA(data['Close'].tolist(), epma_period)
|
| 1165 |
+
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['EPMA'], mode='lines', name=f'EPMA (n={epma_period})', line=dict(dash='dash', color='blue')))
|
| 1166 |
+
|
| 1167 |
+
# Add CMA if selected
|
| 1168 |
+
if use_cma:
|
| 1169 |
+
st.session_state['CMA'] = calculate_CMA(data['Close'])
|
| 1170 |
+
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['CMA'], mode='lines', name=f'CMA', line=dict(dash='dash', color='blue')))
|
| 1171 |
+
|
| 1172 |
+
# Add McGinley Dynamic if selected
|
| 1173 |
+
if use_mcginley_dynamic:
|
| 1174 |
+
st.session_state['McGinley_Dynamic'] = calculate_mcginley_dynamic(data['Close'].tolist(), mcginley_dynamic_period)
|
| 1175 |
+
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['McGinley_Dynamic'], mode='lines', name=f'McGinley Dynamic (n={mcginley_dynamic_period})', line=dict(dash='dash', color='orange')))
|
| 1176 |
+
|
| 1177 |
+
# Add AMA if selected
|
| 1178 |
+
#if use_ama:
|
| 1179 |
+
# st.session_state['AMA'] = calculate_AMA(data['Close'].tolist(), ama_anchor_date, data)
|
| 1180 |
+
# fig.add_trace(go.Scatter(x=data.index, y=st.session_state['AMA'], mode='lines', name=f'Anchored MA (Anchor Date={ama_anchor_date})', line=dict(dash='dash', color='red')))
|
| 1181 |
+
# fig.add_shape(type="line", x0=ama_anchor_date, y0=data['Close'].min(), x1=ama_anchor_date, y1=data['Close'].max(), line=dict(color="blue", width=2, dash="dash"))
|
| 1182 |
+
|
| 1183 |
+
# Add FMA if selected
|
| 1184 |
+
if use_fma:
|
| 1185 |
+
st.session_state['FMA'] = filtered_moving_average(data['Close'].values, fma_period)
|
| 1186 |
+
fig.add_trace(go.Scatter(x=data.index, y=np.concatenate([np.array([np.nan]*(fma_period-1)), st.session_state['FMA']]), mode='lines', name=f'Filtered MA (n={fma_period})', line=dict(dash='dash', color='green')))
|
| 1187 |
+
|
| 1188 |
+
# Add SMA if selected
|
| 1189 |
+
if use_sma:
|
| 1190 |
+
st.session_state['SMA'] = data['Close'].rolling(window=sma_period).mean()
|
| 1191 |
+
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['SMA'], mode='lines', name=f'{sma_period}-Day SMA', line=dict(dash='dash')))
|
| 1192 |
+
|
| 1193 |
+
# Add EMA if selected
|
| 1194 |
+
if use_ema:
|
| 1195 |
+
st.session_state['EMA'] = data['Close'].ewm(span=ema_period, adjust=False).mean()
|
| 1196 |
+
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['EMA'], mode='lines', name=f'{ema_period}-Day EMA', line=dict(dash='dash', color='green')))
|
| 1197 |
+
|
| 1198 |
+
# Add WMA if selected
|
| 1199 |
+
if use_wma:
|
| 1200 |
+
weights = np.arange(1, wma_period + 1)
|
| 1201 |
+
st.session_state['WMA'] = data['Close'].rolling(window=wma_period).apply(lambda prices: np.dot(prices, weights)/weights.sum(), raw=True)
|
| 1202 |
+
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['WMA'], mode='lines', name=f'{wma_period}-Day WMA', line=dict(dash='dash', color='orange')))
|
| 1203 |
+
|
| 1204 |
+
# Add DEMA if selected
|
| 1205 |
+
if use_dema:
|
| 1206 |
+
data['EMA'] = data['Close'].ewm(span=dema_period, adjust=False).mean()
|
| 1207 |
+
data['EMA2'] = data['EMA'].ewm(span=dema_period, adjust=False).mean()
|
| 1208 |
+
st.session_state['DEMA'] = 2 * data['EMA'] - data['EMA2']
|
| 1209 |
+
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['DEMA'], mode='lines', name=f'{dema_period}-Day DEMA', line=dict(dash='dash', color='red')))
|
| 1210 |
+
|
| 1211 |
+
# Add TEMA if selected
|
| 1212 |
+
if use_tema:
|
| 1213 |
+
data['EMA'] = data['Close'].ewm(span=tema_period, adjust=False).mean()
|
| 1214 |
+
data['EMA2'] = data['EMA'].ewm(span=tema_period, adjust=False).mean()
|
| 1215 |
+
data['EMA3'] = data['EMA2'].ewm(span=tema_period, adjust=False).mean()
|
| 1216 |
+
st.session_state['TEMA'] = 3 * data['EMA'] - 3 * data['EMA2'] + data['EMA3']
|
| 1217 |
+
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['TEMA'], mode='lines', name=f'{tema_period}-Day TEMA', line=dict(dash='dash', color='purple')))
|
| 1218 |
+
|
| 1219 |
+
# Add VAMA if selected
|
| 1220 |
+
if use_vama:
|
| 1221 |
+
data['Volume_Price'] = data['Close'] * data['Volume']
|
| 1222 |
+
st.session_state['VAMA'] = data['Volume_Price'].rolling(window=vama_period).sum() / data['Volume'].rolling(window=vama_period).sum()
|
| 1223 |
+
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['VAMA'], mode='lines', name=f'{vama_period}-Day VAMA', line=dict(dash='dash', color='orange')))
|
| 1224 |
+
|
| 1225 |
+
# Add KAMA if selected
|
| 1226 |
+
if use_kama:
|
| 1227 |
+
fastest_SC = 2 / (fastest_period + 1)
|
| 1228 |
+
slowest_SC = 2 / (slowest_period + 1)
|
| 1229 |
+
data['Change'] = abs(data['Close'] - data['Close'].shift(kama_period))
|
| 1230 |
+
data['Volatility'] = data['Close'].diff().abs().rolling(window=kama_period).sum()
|
| 1231 |
+
data['ER'] = data['Change'] / data['Volatility']
|
| 1232 |
+
data['SC'] = (data['ER'] * (fastest_SC - slowest_SC) + slowest_SC)**2
|
| 1233 |
+
data['KAMA'] = data['Close'].copy()
|
| 1234 |
+
for i in range(kama_period, len(data)):
|
| 1235 |
+
data['KAMA'].iloc[i] = data['KAMA'].iloc[i-1] + data['SC'].iloc[i] * (data['Close'].iloc[i] - data['KAMA'].iloc[i-1])
|
| 1236 |
+
st.session_state['KAMA'] = data['KAMA']
|
| 1237 |
+
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['KAMA'], mode='lines', name=f'KAMA (n={kama_period})', line=dict(dash='dash', color='green')))
|
| 1238 |
+
|
| 1239 |
+
# Add TMA if selected
|
| 1240 |
+
if use_tma:
|
| 1241 |
+
half_n = (tma_period + 1) // 2
|
| 1242 |
+
data['Half_SMA'] = data['Close'].rolling(window=half_n).mean()
|
| 1243 |
+
st.session_state['TMA'] = data['Half_SMA'].rolling(window=half_n).mean()
|
| 1244 |
+
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['TMA'], mode='lines', name=f'TMA (n={tma_period})', line=dict(dash='dash', color='red')))
|
| 1245 |
+
|
| 1246 |
+
# Add Hull MA if selected
|
| 1247 |
+
if use_hull_ma:
|
| 1248 |
+
st.session_state['Hull_MA'] = hull_moving_average(data['Close'], hull_ma_period)
|
| 1249 |
+
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['Hull_MA'], mode='lines', name=f'Hull MA (n={hull_ma_period})', line=dict(dash='dash', color='green')))
|
| 1250 |
+
|
| 1251 |
+
# Add Harmonic MA if selected
|
| 1252 |
+
if use_harmonic_ma:
|
| 1253 |
+
st.session_state['Harmonic_MA'] = calculate_harmonic_moving_average(data['Close'].values, harmonic_ma_period)
|
| 1254 |
+
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['Harmonic_MA'], mode='lines', name=f'Harmonic MA (n={harmonic_ma_period})', line=dict(dash='dash', color='purple')))
|
| 1255 |
+
|
| 1256 |
+
# Add FRAMA if selected
|
| 1257 |
+
if use_frama:
|
| 1258 |
+
st.session_state['FRAMA'] = calculate_FRAMA(data, batch=frama_batch)['FRAMA']
|
| 1259 |
+
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['FRAMA'], mode='lines', name=f'FRAMA (batch={frama_batch})', line=dict(dash='dash', color='green')))
|
| 1260 |
+
|
| 1261 |
+
# Add ZLEMA if selected
|
| 1262 |
+
if use_zlema:
|
| 1263 |
+
st.session_state['ZLEMA'] = calculate_ZLEMA(data['Close'].tolist(), zlema_period)
|
| 1264 |
+
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['ZLEMA'], mode='lines', name=f'ZLEMA (n={zlema_period})', line=dict(dash='dash', color='red')))
|
| 1265 |
+
|
| 1266 |
+
# Add VIDYA if selected
|
| 1267 |
+
if use_vidya:
|
| 1268 |
+
st.session_state['VIDYA'] = calculate_VIDYA(data['Close'].tolist(), vidya_period)
|
| 1269 |
+
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['VIDYA'], mode='lines', name=f'VIDYA (n={vidya_period})', line=dict(dash='dash', color='blue')))
|
| 1270 |
+
|
| 1271 |
+
# Add ALMA if selected
|
| 1272 |
+
if use_alma:
|
| 1273 |
+
st.session_state['ALMA'] = calculate_ALMA(data['Close'].tolist(), alma_period, offset=alma_offset, sigma=alma_sigma)
|
| 1274 |
+
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['ALMA'], mode='lines', name=f'ALMA (n={alma_period})', line=dict(dash='dash', color='purple')))
|
| 1275 |
+
|
| 1276 |
+
# Add MAMA and FAMA if selected
|
| 1277 |
+
if use_mama_fama:
|
| 1278 |
+
data['MAMA'], data['FAMA'] = talib.MAMA(data['Close'].values, fastlimit=mama_fast_limit, slowlimit=mama_slow_limit)
|
| 1279 |
+
st.session_state['MAMA'] = data['MAMA']
|
| 1280 |
+
st.session_state['FAMA'] = data['FAMA']
|
| 1281 |
+
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['MAMA'], mode='lines', name=f'MAMA', line=dict(dash='dash', color='blue')))
|
| 1282 |
+
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['FAMA'], mode='lines', name=f'FAMA', line=dict(dash='dash', color='red')))
|
| 1283 |
+
|
| 1284 |
+
# Add APMA if selected
|
| 1285 |
+
if use_apma:
|
| 1286 |
+
st.session_state['APMA'] = adaptive_period_moving_average(data['Close'].values, min_period=apma_min_period, max_period=apma_max_period)
|
| 1287 |
+
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['APMA'], mode='lines', name=f'APMA (min={apma_min_period}, max={apma_max_period})', line=dict(dash='dash', color='red')))
|
| 1288 |
+
|
| 1289 |
+
# Add Rainbow EMA if selected
|
| 1290 |
+
if use_rainbow_ema:
|
| 1291 |
+
data = calculate_rainbow_ema(data, rainbow_lookback_periods)
|
| 1292 |
+
colors = ['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet', 'black','gray','brown']
|
| 1293 |
+
for i, lookback in enumerate(rainbow_lookback_periods):
|
| 1294 |
+
fig.add_trace(go.Scatter(x=data.index, y=data[f'EMA{lookback}'], mode='lines', name=f'EMA {lookback}', line=dict(dash='solid', color=colors[i % len(colors)])))
|
| 1295 |
+
|
| 1296 |
+
# Add Wilders MA if selected
|
| 1297 |
+
if use_wilders_ma:
|
| 1298 |
+
st.session_state['Wilders_MA'] = wilders_moving_average(data['Close'].tolist(), wilders_ma_period)
|
| 1299 |
+
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['Wilders_MA'], mode='lines', name=f'Wilders MA (n={wilders_ma_period})', line=dict(dash='dash', color='red')))
|
| 1300 |
+
|
| 1301 |
+
# Add SMMA if selected
|
| 1302 |
+
if use_smma:
|
| 1303 |
+
st.session_state['SMMA'] = calculate_SMMA(data['Close'].tolist(), smma_period)
|
| 1304 |
+
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['SMMA'], mode='lines', name=f'SMMA (n={smma_period})', line=dict(dash='dash', color='red')))
|
| 1305 |
+
|
| 1306 |
+
# Add GMMA if selected
|
| 1307 |
+
if use_gmma:
|
| 1308 |
+
close_prices = data['Close'].tolist()
|
| 1309 |
+
for period in gmma_short_periods:
|
| 1310 |
+
data[f'EMA_{period}'] = calculate_EMA(close_prices, period)
|
| 1311 |
+
fig.add_trace(go.Scatter(x=data.index, y=data[f'EMA_{period}'], mode='lines', name=f'GMMA Short EMA {period}', line=dict(dash='solid')))
|
| 1312 |
+
for period in gmma_long_periods:
|
| 1313 |
+
data[f'EMA_{period}'] = calculate_EMA(close_prices, period)
|
| 1314 |
+
fig.add_trace(go.Scatter(x=data.index, y=data[f'EMA_{period}'], mode='lines', name=f'GMMA Long EMA {period}', line=dict(dash='dash')))
|
| 1315 |
+
|
| 1316 |
+
# Add LSMA if selected
|
| 1317 |
+
if use_lsma:
|
| 1318 |
+
st.session_state['LSMA'] = calculate_LSMA(data['Close'].tolist(), lsma_period)
|
| 1319 |
+
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['LSMA'], mode='lines', name=f'LSMA (n={lsma_period})', line=dict(dash='dash', color='blue')))
|
| 1320 |
+
|
| 1321 |
+
# Add MMA (Welch's MMA) if selected
|
| 1322 |
+
if use_mma:
|
| 1323 |
+
st.session_state['MMA'] = calculate_MMA(data['Close'].tolist(), mma_period)
|
| 1324 |
+
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['MMA'], mode='lines', name=f'MMA (n={mma_period})', line=dict(dash='dash', color='blue')))
|
| 1325 |
+
|
| 1326 |
+
# Add SinWMA if selected
|
| 1327 |
+
if use_sinwma:
|
| 1328 |
+
st.session_state['SinWMA'] = calculate_SinWMA(data['Close'].tolist(), sinwma_period)
|
| 1329 |
+
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['SinWMA'], mode='lines', name=f'SinWMA (n={sinwma_period})', line=dict(dash='dash', color='green')))
|
| 1330 |
+
|
| 1331 |
+
# Add MedMA if selected
|
| 1332 |
+
if use_medma:
|
| 1333 |
+
st.session_state['MedMA'] = calculate_MedMA(data['Close'].tolist(), medma_period)
|
| 1334 |
+
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['MedMA'], mode='lines', name=f'MedMA (n={medma_period})', line=dict(dash='dash', color='blue')))
|
| 1335 |
+
|
| 1336 |
+
# Add GMA if selected
|
| 1337 |
+
if use_gma:
|
| 1338 |
+
st.session_state['GMA'] = calculate_GMA(data['Close'].tolist(), gma_period)
|
| 1339 |
+
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['GMA'], mode='lines', name=f'GMA (n={gma_period})', line=dict(dash='dash', color='green')))
|
| 1340 |
+
|
| 1341 |
+
# Add eVWMA if selected
|
| 1342 |
+
if use_evwma:
|
| 1343 |
+
st.session_state['eVWMA'] = calculate_eVWMA(data['Close'], data['Volume'], evwma_period)
|
| 1344 |
+
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['eVWMA'], mode='lines', name=f'eVWMA (n={evwma_period})', line=dict(dash='dash', color='blue')))
|
| 1345 |
+
|
| 1346 |
+
# Add REMA if selected
|
| 1347 |
+
if use_rema:
|
| 1348 |
+
st.session_state['REMA'] = REMA(data['Close'], alpha=rema_alpha, lambda_=rema_lambda)
|
| 1349 |
+
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['REMA'], mode='lines', name=f'REMA (alpha={rema_alpha}, lambda={rema_lambda})', line=dict(dash='dash', color='red')))
|
| 1350 |
+
|
| 1351 |
+
# Add PWMA if selected
|
| 1352 |
+
if use_pwma:
|
| 1353 |
+
pwma_values = parabolic_weighted_moving_average(data['Close'].values, pwma_period)
|
| 1354 |
+
st.session_state['PWMA'] = np.concatenate([np.array([np.nan]*(pwma_period-1)), pwma_values])
|
| 1355 |
+
fig.add_trace(go.Scatter(x=data.index, y=st.session_state['PWMA'], mode='lines', name=f'PWMA (n={pwma_period})', line=dict(dash='dash', color='red')))
|
| 1356 |
+
|
| 1357 |
+
|
| 1358 |
+
# Update layout with grid toggle
|
| 1359 |
+
fig.update_layout(
|
| 1360 |
+
title=f'{ticker_symbol} Stock Price with Moving Averages',
|
| 1361 |
+
xaxis_title='Date',
|
| 1362 |
+
yaxis_title='Stock Price',
|
| 1363 |
+
legend_title='Indicators',
|
| 1364 |
+
template='plotly_white',
|
| 1365 |
+
xaxis=dict(showgrid=show_grid),
|
| 1366 |
+
yaxis=dict(showgrid=show_grid)
|
| 1367 |
+
)
|
| 1368 |
+
|
| 1369 |
+
# Store the updated figure in session state
|
| 1370 |
+
st.session_state['current_fig'] = fig
|
| 1371 |
|
| 1372 |
# Display the current figure, which remains unchanged until "Run" is clicked
|
| 1373 |
if 'current_fig' in st.session_state:
|
| 1374 |
st.plotly_chart(st.session_state['current_fig'], use_container_width=True)
|
| 1375 |
|
| 1376 |
+
|
| 1377 |
+
|
| 1378 |
+
|
| 1379 |
st.markdown(
|
| 1380 |
"""
|
| 1381 |
<style>
|
|
|
|
| 1396 |
footer {visibility: hidden;}
|
| 1397 |
</style>
|
| 1398 |
"""
|
| 1399 |
+
st.markdown(hide_streamlit_style, unsafe_allow_html=True)
|