Earlier than implementing any buying and selling technique, making ready clear, structured knowledge is essential. Under is the Python script for managing this very important step:
import pandas as pdimport pandas_ta as tafrom tqdm import tqdmimport osimport numpy as npimport plotly.graph_objects as go
tqdm.pandas()def read_csv_to_dataframe(file_path):df = pd.read_csv(file_path)df[“Gmt time”] = df[“Gmt time”].str.change(“.000”, “”)df[‘Gmt time’] = pd.to_datetime(df[‘Gmt time’], format=’%d.%m.%Y %H:%M:%S’)df = df[df.High != df.Low] # Take away invalid rowsdf.set_index(“Gmt time”, inplace=True)return dfdef read_data_folder(folder_path=”./knowledge”):dataframes = []file_names = []for file_name in tqdm(os.listdir(folder_path)):if file_name.endswith(‘.csv’):file_path = os.path.be a part of(folder_path, file_name)df = read_csv_to_dataframe(file_path)dataframes.append(df)file_names.append(file_name)return dataframes, file_names
Step Breakdown:
Library Importation: Libraries similar to pandas streamline knowledge manipulation, pandas_ta calculates technical indicators, tqdm screens progress, and plotly is used for visualization.File Preprocessing: Recordsdata are learn individually, and irrelevant rows are filtered out (e.g., rows the place Excessive equals Low are thought-about anomalies).Timestamp Conversion: The datetime format is standardized to make sure constant time-series indexing.Effectivity for Bulk Information: The read_data_folder perform allows processing a number of datasets, accommodating situations like multi-asset evaluation.
The technique depends on particular situations met by sequential candlestick formations. Right here is the perform that evaluates the sample:
def total_signal(df, current_candle):current_pos = df.index.get_loc(current_candle)c1 = df[‘High’].iloc[current_pos] > df[‘Close’].iloc[current_pos]c2 = df[‘Close’].iloc[current_pos] > df[‘High’].iloc[current_pos-2]c3 = df[‘High’].iloc[current_pos-2] > df[‘High’].iloc[current_pos-1]c4 = df[‘High’].iloc[current_pos-1] > df[‘Low’].iloc[current_pos]c5 = df[‘Low’].iloc[current_pos] > df[‘Low’].iloc[current_pos-2]c6 = df[‘Low’].iloc[current_pos-2] > df[‘Low’].iloc[current_pos-1]if c1 and c2 and c3 and c4 and c5 and c6:return 2 # Sign to purchase (lengthy)# Symmetrical situations for brief signalsc1 = df[‘Low’].iloc[current_pos] < df[‘Open’].iloc[current_pos]c2 = df[‘Open’].iloc[current_pos] < df[‘Low’].iloc[current_pos-2]c3 = df[‘Low’].iloc[current_pos-2] < df[‘Low’].iloc[current_pos-1]c4 = df[‘Low’].iloc[current_pos-1] < df[‘High’].iloc[current_pos]c5 = df[‘High’].iloc[current_pos] < df[‘High’].iloc[current_pos-2]c6 = df[‘High’].iloc[current_pos-2] < df[‘High’].iloc[current_pos-1]if c1 and c2 and c3 and c4 and c5 and c6:return 1 # Sign to promote (quick)return 0
Step Breakdown:
Logic Clarification: Six situations guarantee exact detection of a selected candlestick sequence, defining entry factors for each purchase and promote alerts.Sign Output: The perform returns a numerical sign (2 for lengthy, 1 for brief, 0 for no sign), which can be later interpreted throughout backtesting.Error Minimization: By utilizing strict logical situations, false alerts are minimized, making certain the technique operates on high-probability setups.
Visualizing entry and exit factors is crucial for verifying a technique. Under are the features for marking patterns and plotting them on candlestick charts:
def add_total_signal(df):df[‘TotalSignal’] = df.progress_apply(lambda row: total_signal(df, row.identify), axis=1)return df
def add_pointpos_column(df, signal_column):def pointpos(row):if row[signal_column] == 2:return row[‘Low’] – 1e-4elif row[signal_column] == 1:return row[‘High’] + 1e-4return np.nandf[‘pointpos’] = df.apply(lambda row: pointpos(row), axis=1)return df
def plot_candlestick_with_signals(df, start_index, num_rows):df_subset = df[start_index:start_index + num_rows]fig = make_subplots(rows=1, cols=1)fig.add_trace(go.Candlestick(x=df_subset.index,open=df_subset[‘Open’],excessive=df_subset[‘High’],low=df_subset[‘Low’],shut=df_subset[‘Close’],identify=’Candlesticks’), row=1, col=1)fig.add_trace(go.Scatter(x=df_subset.index, y=df_subset[‘pointpos’], mode=”markers”,marker=dict(dimension=10, shade=”MediumPurple”, image=’circle’),identify=”Entry Factors”), row=1, col=1)fig.present()
Step Breakdown:
Integration with Alerts: The add_total_signal perform augments the dataset with generated commerce alerts.Chart Enhancements: Entry factors are marked as purple circles under or above candles, aligning visible suggestions with technique logic.Customizability: The script accommodates customizations similar to time ranges, making it adaptable for various datasets.
With the logic in place, it’s time to backtest. Right here’s methods to consider efficiency throughout numerous belongings:
from backtesting import Technique, Backtest
def SIGNAL():return df.TotalSignal
class MyStrat(Technique):mysize = 0.1 # Commerce sizeslperc = 0.04 # Cease loss percentagetpperc = 0.02 # Take revenue proportion
def init(self):self.signal1 = self.I(SIGNAL)
def subsequent(self):if self.signal1 == 2 and never self.place:self.purchase(dimension=self.mysize, sl=self.knowledge.Shut[-1] * (1 – self.slperc), tp=self.knowledge.Shut[-1] * (1 + self.tpperc))elif self.signal1 == 1 and never self.place:self.promote(dimension=self.mysize, sl=self.knowledge.Shut[-1] * (1 + self.slperc), tp=self.knowledge.Shut[-1] * (1 – self.tpperc))
Step Breakdown:
Cease Loss & Take Revenue Ranges: Adjustable percentages guarantee strong threat administration.Sign Integration: The backtest dynamically interprets generated alerts and executes trades accordingly.Flexibility for Optimization: Parameters like mysize, slperc, and tpperc will be fine-tuned to maximise profitability.
Backtesting outcomes on the S&P 500 index provided the next takeaways:
65% Win Price: Demonstrates constant success underneath numerous market situations.Aggregated Return: Yielded a notable 71% return throughout the testing interval.Commerce-Particular Insights: The very best commerce delivered a revenue of 10.3%, whereas the worst drawdown was restricted to 4.8%.
Whereas this technique excelled with equities, its efficiency on foreign exchange was much less constant, indicating potential for asset-specific refinement.
This candlestick sample technique demonstrates the ability of mixing conventional buying and selling knowledge with cutting-edge automation. Whereas its simplicity is a bonus, combining it with further patterns or refining it for particular asset courses might unlock better potential.
For step-by-step tutorials and Python code, go to our publication, the place we dive even deeper into algorithmic methods and buying and selling applied sciences. Subscribe to remain up to date with the newest developments in automated buying and selling!