text_html_output_1.png
from plotly.subplots import make_subplots

import math

import pandas as pd

import plotly.graph_objects as go

df = pd.read_csv('../input/samsung-electronics-stock-historical-price/005930.KS.csv')
df

fig = make_subplots(specs=[[{'secondary_y':True}]])
fig.add_trace(
    go.Scatter(x=df.Date,y=df.Close,name='Close')
)
fig.add_trace(
    go.Scatter(x=df.Date,y=df['Adj Close'],name='Adj Close')
)
fig.update_layout(xaxis_title='Date',
                  yaxis_title='Price'
                 )
fig.show()

def bolinger(data):
    data['MA20'] = data.Close.rolling(window=20).mean()
    data['std'] = data.Close.rolling(window=20).std()
    data['upper_20'] = data.MA20 + 2 * data['std']
    data['lower_20'] = data.MA20 - 2 * data['std']
    data.drop('std', axis=1, inplace=True)
    data.dropna(inplace=True)
    return data

df = bolinger(df)
df.ffill(inplace=True)
df.reset_index(drop=True, inplace=True)
df

fig = make_subplots(specs=[[{'secondary_y':True}]])
fig.add_trace(
    go.Scatter(x=df.Date,y=df.Close,name='Close')
)
fig.add_trace(
    go.Scatter(x=df.Date,y=df.upper_20,name='Upper 20')
)
fig.add_trace(
    go.Scatter(x=df.Date,y=df.lower_20,name='Lower 20')
)
fig.update_layout(title='ploting bolinger band',
                  xaxis_title='Date',
                  yaxis_title='Price'
                 )
fig.show()

total_balance = 1000000
def backtesting(df, total_balance):
    buy_price = []
    buy_date = []
    sell_price = []
    sell_date = []
    long_earn = []
    num_bought = 0
    df_balance = []
    df_date = []
    balance_date = []
    trade_num = 0
    buy_num = -1
    sell_num = -1
    trade_num = -1
    position = 'none'
    for i in range(len(df.Close)):
        if total_balance <= 0:
            break
        elif position == 'none':
            if df.Close[i] <= df['lower_20'][i] and abs(df.Close[i] - df['lower_20'][i]) <= 1000:
                position = 'long'
                buy_price.append(df.Close[i])
                buy_date.append(df.Date[i])
                if trade_num >= 0:
                    total_balance = df_balance[trade_num]
                num_bought = 0
                num_count = math.floor(total_balance / df.Close[i])
                num_bought += num_count
                remain = total_balance - df.Close[i] * num_count
                df_balance.append(total_balance)
                df_date.append(df.Date[i])
                trade_num += 1
                buy_num += 1
        elif position == 'long':
            if df.Close[i] >= df['upper_20'][i] and abs(df.Close[i] - df['upper_20'][i]) <= 1000:
                position = 'none'
                sell_price.append(df.Close[i])
                sell_date.append(df.Date[i])
                total_balance = remain
                earn = df.Close[i] - buy_price[buy_num]
                total_earn = earn * num_bought + buy_price[buy_num] * num_bought
                total_balance += total_earn
                df_balance.append(total_balance)
                df_date.append(df.Date[i])
                sell_num += 1
                trade_num += 1
        if i % (len(df) - 1) == 0:
            if position == 'long':
                sell_price.append(df.Close[i])
                sell_date.append(df.Date[i])
                total_balance = remain
                earn = df.Close[i] - buy_price[buy_num]
                total_earn = earn * num_bought + buy_price[buy_num] * num_bought
                total_balance += total_earn
                df_balance.append(total_balance)
                df_date.append(df.Date[i])
    balance = pd.DataFrame({'Date': df_date, 'balance': df_balance})
    final_return_ratio = (balance.iloc[-1][1] / 1000000 - 1) * 100
    return balance

df_balance = backtesting(df, total_balance)