DataFrame aus einer Funktion außerhalb dieser Funktion nutzen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
tommythegun
User
Beiträge: 4
Registriert: Freitag 24. November 2017, 10:09

Hey Leute,

ich bin Python-Anfänger und habe mir eine Funktion geschrieben. Innerhalb dieser Funktion habe ich einen DataFrame names "Portfolio kreiert und würde diesen nun gerne außerhalb der Funktion nutzen (bspw. für Plots).

Mit return portfolio funktioniert das ganze nicht. Habt ihr eine andere Lösung?

Code: Alles auswählen

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

# Import a data source - FSE-Data with Index 'Date'
all_close_prices = pd.read_csv('FSE_daily_close.csv')
all_close_prices = all_close_prices.set_index('Date')
# Fill NaN Values with the last available stock price - except for Zalando
all_close_prices = all_close_prices.fillna(method='ffill')
# Import ticker symbols
ticker_list = list(all_close_prices)
# Zalando 'FSE/ZO1_X' (position row 99) - doesn't begin in 2004
# Drop Zalando
all_close_prices.drop('FSE/ZO1_X', axis=1)
# Also from the ticker list
ticker_list.remove('FSE/ZO1_X')
# Create an empty signal dataframe with datetime index equivalent to the stocks
signals = pd.DataFrame(index=all_close_prices.index)

def ma_strategy(ticker, long_window, short_window):
    # Calculate the moving avergaes
    moving_avg_long = all_close_prices.rolling(window=long_window, min_periods=1).mean()
    moving_avg_short = all_close_prices.rolling(window=short_window, min_periods=1).mean()
    moving_avg_short = moving_avg_short
    moving_avg_long = moving_avg_long
    # Add the two MAs for the stocks in the ticker_list to the signals dataframe
    for i in ticker_list:
        signals['moving_avg_short_' + i] = moving_avg_short[i]
        signals['moving_avg_long_' + i] = moving_avg_long[i]

    # Set up the signals
    for i in ticker_list:
        signals['signal_' + i] = np.where(signals['moving_avg_short_' + i] > signals['moving_avg_long_' + i], 1, 0)
        signals['positions_' + i] = signals['signal_' + i].diff(periods=1)
    #Backtest
    initial_capital = float(100000)
    # Create a DataFrame `positions` with index of signals
    positions = pd.DataFrame(index=all_close_prices)
    # Create a new column in the positions DataFrame
    # On the days that the signal is 1 (short moving average crosses the long moving average, you’ll buy a 100 shares.
    # The days on which the signal is 0, the final result will be 0 as a result of the operation 100*signals['signal']
    positions = 100 * signals[['signal_' + ticker]]
    # Store the portfolio value owned with the stock
    # DataFrame.multiply(other, axis='columns', fill_value=None) - Multiplication of dataframe and other, element-wise
    # Store the difference in shares owned - same like position column in signals
    pos_diff = positions.diff()
    # Add `holdings` to portfolio
    portfolio = pd.DataFrame(index=all_close_prices.index)
    portfolio['holdings'] = (positions.multiply(all_close_prices[ticker], axis=0)).sum(axis=1)
    # Add `cash` to portfolio
    portfolio['cash'] = initial_capital - (pos_diff.multiply(all_close_prices[ticker], axis=0)).sum(
        axis=1).cumsum()
    # Add `total` to portfolio
    portfolio['total'] = portfolio['cash'] + portfolio['holdings']
    # Add `returns` to portfolio
    portfolio['return'] = portfolio['total'].pct_change()
    portfolio['return_cum'] = portfolio['total'].pct_change().cumsum()
    return portfolio



# Visualize the total value of the portfolio
portfolio_value = plt.figure(figsize=(12, 8))
ax1 = portfolio_value.add_subplot(1, 1, 1, ylabel='Portfolio value in $')
# Plot the equity curve in dollars
portfolio['total'].plot(ax=ax1, lw=2.)
__deets__
User
Beiträge: 14540
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du rufst die Funktion ja nicht auf :K
tommythegun
User
Beiträge: 4
Registriert: Freitag 24. November 2017, 10:09

Sorry, hatte das beim Posten rausgelöscht. Natürlich rufe ich die Funktion vor dem Plot auf.

Code: Alles auswählen

ma_strategy('FSE/VOW3_X',20,5)
tommythegun
User
Beiträge: 4
Registriert: Freitag 24. November 2017, 10:09

__deets__ hat geschrieben:Du rufst die Funktion ja nicht auf :K

Sorry, hatte das beim Posten rausgelöscht. Natürlich rufe ich die Funktion vor dem Plot auf.

Code: Alles auswählen

ma_strategy('FSE/VOW3_X',20,5)
__deets__
User
Beiträge: 14540
Registriert: Mittwoch 14. Oktober 2015, 14:29

na, und dann musst du den rueckgabewert natuerlich zuweisen. Magisch passiert das nicht, stell dir mal vor in einer Funktion definierst du einen Namen, und dann aenderst du den - und ploetzlich ist aller Code ueberall davon betroffen. Was uebrigens der Grund ist, nicht mit globalen Variablen zu arbeiten.

Code: Alles auswählen

ergebnis = funktionsaufruf()
Du darfst den Namen natuerlich auch gleich waehlen. Aber implizit passiert da - gottlob - nix.
tommythegun
User
Beiträge: 4
Registriert: Freitag 24. November 2017, 10:09

__deets__ hat geschrieben:na, und dann musst du den rueckgabewert natuerlich zuweisen. Magisch passiert das nicht, stell dir mal vor in einer Funktion definierst du einen Namen, und dann aenderst du den - und ploetzlich ist aller Code ueberall davon betroffen. Was uebrigens der Grund ist, nicht mit globalen Variablen zu arbeiten.

Code: Alles auswählen

ergebnis = funktionsaufruf()
Du darfst den Namen natuerlich auch gleich waehlen. Aber implizit passiert da - gottlob - nix.

Ah perfekt! Jetzt hab ich es selbst gemerkt. Danke für den Tipp :)
Antworten