Market Data Form Finder Toolkit (MDFFT)
The project goal is to make working with a raw market data easier. Provide a tool that allow to identify recurrent market patterns.
Any types of market can processed by this.
The library allow to carry out following tasks:
- Load a list of quotes for any instrument.
- Create a chart using the Japanese candlestick format.
- Draw lines and markers on the chart.
- Search for candles using various criteria.
- Navigate through the entire candles collection.
- Change the timeframe to different one.
Table of content
Install
pip install mdfft
Import classes
The namespace mdfft contains of whole list of lib's classes. The example of import is below:
from mdfft import Candles, SimpleParser, Styler, painter as p, RawCandle, Trader
Classes:
- Candle - The class represents a Japanese candle
- Candles - The class represents a Japanese candle list
- RawCandle - The simple class that based to create Candle. May used in quote parsers.
- painter - The object to draw a chart.
- Style - The class to appearance a chart.
- SimpleParser - The class to parse candles for my samples.
Candle collection examples
Load candles
The collection of candles is created by parsing quotes or making an array of RawCandle objects. The array of RawCandles is created by the programmer himself.
raw_candles = [
RawCandle(
dt=datetime(2020, 1, 1),
o=2,
h=4,
l=1,
c=3
),
RawCandle(
dt=datetime(2020, 1, 2),
o=12,
h=14,
l=11,
c=13
)
]
candles = Candles.from_raw_candles(raw_candles, timeframe="1D")
print(candles)
Next I will use my SimpleParser and my rather large data set of OHLC quotes.
parser = SimpleParser(file="./data/EURUSD_H1.txt")
candles = Candles.from_raw_candles(parser.parse(), timeframe="1H")
Count of candles in the dataset
print(candles.candles_count())
print(len(candles))
A first and a last candle in the dataset
start_candle = candles.head()
print("Start candle: " + str(start_candle))
end_candle = candles.tail()
print("End candle: " + str(end_candle))
Get a candle by an index
my_candle = candles.candle_at(1985)
same_candle = candles[1985]
Navigation through a dataset
Navigation is performed by calling next()
and prev()
methods of a candle object.
next_candle = my_candle.next()
prev_candle = my_candle.prev()
next20_candle = my_candle.next(20)
prev30_candle = my_candle.prev(30)
Search by a date
found_candle = candles.find_candle(datetime(1999, 1, 4, 5))
if not found_candle:
print("Candle not found at 1999-01-04 05:00")
return print("Found candle: " + str(found_candle))
Get a subcollection from the main collection by indices
print(candles.take(10, skip=5))
print(candles.skip(5))
Get a subcollection from the main collection by dates
from datetime import datetime
candles_range = candles.range_dt( datetime(2000, 1, 3, 1 ), datetime(2000, 1, 10, 1))
if not candles_range:
print("No candles in range")
return 0
print("Count candles: " + str(candles_range.candles_count()))
print(candles_range)
Iterate over a collection
for candle in candles:
print("Candle: " + str(candle))
A highest and a lowest candle in the collection
candle_h, candle_l = candles.high_and_low_candles()
print("High candle: " + str(candle_h))
print("Low candle: " + str(candle_l))
Timeframes
A candle collection may be converted from a current timeframe to another timeframe. A new timeframe must be bigger than the source timeframe.
Example: the timeframe of 1 hour may be converted to 2 hours, 8 hours, 2 days, or another one, but bigger than source one.
The 1 hour timeframe must not convert to 45 minutes, 30 minutes, or another one less.
A timeframe label consists of two parts: a number of time units and a time unit label.
Example of timeframes: 24M - 24 minutes timeframe, 1H - 1 hour timeframe, 11H - 11 hours timeframe, 1D - 1 day timeframe, 11D - 11 days timeframe
Possible time unit labels:
- M - minute
- H - hour
- D - day
- W - week
- MONTH - month
Get a timeframe of a candles collection
print(candles.timeframe)
Change a candles collection timeframe
candles_2h = candles.to_tf("2H")
candles_3h = candles_2h.to_tf("3H")
candles_4h = candles_3h.to_tf("4H")
candles_13h = candles_4h.to_tf("13H")
candles_1d = candles_4h.to_tf("1D")
Pandas
Convert a candles collection to a pandas dataframe
from mdfft import PandasCandles
df = PandasCandles.candles_to_pandas_df(candles)
print(df)
You may create a dataset in which a row contains several candles prices.
from mdfft import PandasCandles
df_windows = PandasCandles.candles_windows_to_pandas_df(candles, 3)
print(df_windows)
Candle
Next and prev candle
candle = candles.candle_at(1985)
next_candle = candle.next()
next30_candle = candle.next(30)
prve_candle = candle.prev()
prev100_candle = candle.prev(100)
Candle type
direct = candle.direct
Prices
price_open = candle.open
price_high = candle.high
price_low = candle.low
price_close = candle.close
price_mid = candle.mid
Dates and times
candle_dt = candle.datetime
candle_date = candle.date
candle_time = candle.time
candle_year = candle.year
candle_month = candle.month
candle_day = candle.day
candle_hour = candle.hour
candle_minute = candle.minute
dt_str = candle.dt_as_str()
print(dt_str)
dt_str_fmt = candle.dt_as_str('%d, %b %Y')
print(dt_str_fmt)
ts = candle.timestamp()
print(ts)
ts_utc = candle.timestamp_utc()
print(ts_utc)
Candle index
ci = candle.index
cib = candle.index_back
Candle chart
To start painting you must import bellow classes
from mdfft import painter as p, Styler
Matplotlib is used for drawing. That means you may use colors, marker, visual elements, etc. from Matplotlib.
Simple chart
p.start_paint()
p.title="Candles"
p.paint(candles_collection)
p.paint_done()
Save chart to file
p.start_paint()
p.title = "Save paint"
p.paint(candles_to_paint)
p.save_paint('candles.jpg')
Appearance
The appearance is performed through the object of class Styler that included in object painter. Possible settings is an enum in class Styler.
s = Styler()
p.title="Rainbow candles"
s.color_bear_body = [plt.cm.get_cmap('Pastel1', candles_cnt)(c) for c in range(candles_cnt)]
s.color_bear_border = [plt.cm.get_cmap('Set1_r', candles_cnt)(c) for c in range(candles_cnt)]
s.color_bear_shadow = "blue"
s.color_bull_body = [plt.cm.get_cmap('turbo', candles_cnt)(c) for c in range(candles_cnt)]
s.color_bull_border = [plt.cm.get_cmap('tab20b', candles_cnt)(c) for c in range(candles_cnt)]
s.color_bull_shadow = "green"
p.styler = s
p.start_paint()
p.paint(candles)
p.paint_done()
Drawing on the chart
Possible markers and lines
p.start_paint()
p.paint(candles_to_paint)
for c in candles_to_paint:
if (c.index % 5) == 0:
p.paint_marker(c, "l", marker_size=4, marker_color='red', marker='v')
p.paint_marker(c, "h", marker_size=3, marker_color='black', marker='^')
p.paint_marker(c, c.mid, marker='_')
hc, lc = candles_to_paint.high_and_low_candles()
p.paint_line( hc, hc.high, lc, lc.low, line_style="dotted", line_color="green")
p.paint_done()
Trading
For the success or failure of a position, the Trader class is used. The class contains a single method that returns the result of a position at a certain point.
pip = 1 / 10000
start_candle = candles.candle_at(12345)
trader = Trader()
profit, distance, action_price = trader.place_order(
candle=start_candle,
order_price='o',
place_type=Trader.PLACE_TYPE_BUY,
sl=start_candle.low - pip,
tp=start_candle.high + pip * 100,
tl=1000
)
print(f"Profit pips: {profit / pip}")
print(f"Candles to close order: {distance}")
print(f"Price that close order: {action_price}")