-
Notifications
You must be signed in to change notification settings - Fork 10
/
psar.py
109 lines (91 loc) · 3.18 KB
/
psar.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# -*- coding: utf-8 -*-
"""
http://virtualizedfrog.wordpress.com/ 2014
Translated from http://www.amibroker.com/library/detail.php?id=268
Requires pandas to load csv files, and matplotlib to chart the data
The main expects table.csv file. Valid files can be downloaded on Yahoo Finance
eg: http://real-chart.finance.yahoo.com/table.csv?s=%5EGSPC&ignore=.csv
"""
import pandas as pd
from datetime import datetime
import matplotlib.pyplot as plt
def psar(barsdata, iaf = 0.02, maxaf = 0.2):
length = len(barsdata)
dates = list(barsdata['Date'])
high = list(barsdata['High'])
low = list(barsdata['Low'])
close = list(barsdata['Close'])
psar = close[0:len(close)]
psarbull = [None] * length
psarbear = [None] * length
bull = True
af = iaf
ep = low[0]
hp = high[0]
lp = low[0]
for i in range(2,length):
if bull:
psar[i] = psar[i - 1] + af * (hp - psar[i - 1])
else:
psar[i] = psar[i - 1] + af * (lp - psar[i - 1])
reverse = False
if bull:
if low[i] < psar[i]:
bull = False
reverse = True
psar[i] = hp
lp = low[i]
af = iaf
else:
if high[i] > psar[i]:
bull = True
reverse = True
psar[i] = lp
hp = high[i]
af = iaf
if not reverse:
if bull:
if high[i] > hp:
hp = high[i]
af = min(af + iaf, maxaf)
if low[i - 1] < psar[i]:
psar[i] = low[i - 1]
if low[i - 2] < psar[i]:
psar[i] = low[i - 2]
else:
if low[i] < lp:
lp = low[i]
af = min(af + iaf, maxaf)
if high[i - 1] > psar[i]:
psar[i] = high[i - 1]
if high[i - 2] > psar[i]:
psar[i] = high[i - 2]
if bull:
psarbull[i] = psar[i]
else:
psarbear[i] = psar[i]
return {"dates":dates, "high":high, "low":low, "close":close, "psar":psar, "psarbear":psarbear, "psarbull":psarbull}
if __name__ == "__main__":
import sys
import os
if len(sys.argv) < 2:
sys.exit("Usage: %s datafile.csv" % sys.argv[0])
if not os.path.exists(sys.argv[1]):
sys.exit("Error: can't open file '%s': No such file" % sys.argv[1])
barsdata = pd.read_csv(sys.argv[1])
#Reindex the data: ascending dates are expected in the function
barsdata = barsdata.reindex(index=barsdata.index[::-1])
#Convert strings to actual timestamps
barsdata['Date'] = [datetime.strptime(x, '%Y-%m-%d') for x in barsdata['Date']]
startidx = 0
endidx = len(barsdata)
result = psar(barsdata)
dates = result['dates'][startidx:endidx]
close = result['close'][startidx:endidx]
psarbear = result['psarbear'][startidx:endidx]
psarbull = result['psarbull'][startidx:endidx]
plt.plot(dates, close)
plt.plot(dates, psarbull)
plt.plot(dates, psarbear)
plt.grid()
plt.show()