Added Python 2.7.x and 3.4.x compatibility to the code. Disabled HTTPS security warning in urllib3 package of 'requests' package.

This commit is contained in:
Michael Halls-Moore
2015-05-11 17:30:28 +01:00
parent 8e74edb4f7
commit a03bc7a1fb
9 changed files with 67 additions and 39 deletions
+1
View File
@@ -1,5 +1,6 @@
*~
*.py[co]
__pycache__
# Packages
*.egg
+9 -4
View File
@@ -1,5 +1,10 @@
from __future__ import print_function
import copy
import Queue
try:
import Queue as queue
except ImportError:
import queue
import threading
import time
from decimal import Decimal, getcontext
@@ -28,7 +33,7 @@ def backtest(
ticker.stream_next_tick()
try:
event = events.get(False)
except Queue.Empty:
except queue.Empty:
pass
else:
if event is not None:
@@ -45,14 +50,14 @@ def backtest(
if __name__ == "__main__":
heartbeat = 0.0
events = Queue.Queue()
events = queue.Queue()
equity = settings.EQUITY
# Load the historic CSV tick data files
pairs = ["GBPUSD"]
csv_dir = settings.CSV_DATA_DIR
if csv_dir is None:
print "No historic data directory provided - backtest terminating."
print("No historic data directory provided - backtest terminating.")
sys.exit()
# Create the historic tick data streaming class
+8 -6
View File
@@ -1,5 +1,5 @@
import datetime
from decimal import Decimal, ROUND_HALF_DOWN
from decimal import Decimal, getcontext, ROUND_HALF_DOWN
import os
import os.path
import time
@@ -59,12 +59,13 @@ class PriceHandler(object):
This will turn the bid/ask of "GBPUSD" into bid/ask for
"USDGBP" and place them in the prices dictionary.
"""
getcontext().rounding = ROUND_HALF_DOWN
inv_pair = "%s%s" % (pair[3:], pair[:3])
inv_bid = (Decimal("1.0")/bid).quantize(
Decimal("0.00001", ROUND_HALF_DOWN)
Decimal("0.00001")
)
inv_ask = (Decimal("1.0")/ask).quantize(
Decimal("0.00001", ROUND_HALF_DOWN)
Decimal("0.00001")
)
return inv_pair, inv_bid, inv_ask
@@ -129,16 +130,17 @@ class HistoricCSVPriceHandler(PriceHandler):
well as updating the current bid/ask and inverse bid/ask.
"""
try:
index, row = self.all_pairs.next()
index, row = next(self.all_pairs)
except StopIteration:
return
else:
getcontext().rounding = ROUND_HALF_DOWN
pair = row["Pair"]
bid = Decimal(str(row["Bid"])).quantize(
Decimal("0.00001", ROUND_HALF_DOWN)
Decimal("0.00001")
)
ask = Decimal(str(row["Ask"])).quantize(
Decimal("0.00001", ROUND_HALF_DOWN)
Decimal("0.00001")
)
# Create decimalised prices for traded pair
+16 -10
View File
@@ -1,4 +1,6 @@
from decimal import Decimal, ROUND_HALF_DOWN
from __future__ import print_function
from decimal import Decimal, getcontext, ROUND_HALF_DOWN
import requests
import json
@@ -24,18 +26,20 @@ class StreamingForexPrices(PriceHandler):
This will turn the bid/ask of "GBPUSD" into bid/ask for
"USDGBP" and place them in the prices dictionary.
"""
getcontext().rounding = ROUND_HALF_DOWN
inv_pair = "%s%s" % (pair[3:], pair[:3])
inv_bid = (Decimal("1.0")/bid).quantize(
Decimal("0.00001", ROUND_HALF_DOWN)
Decimal("0.00001")
)
inv_ask = (Decimal("1.0")/ask).quantize(
Decimal("0.00001", ROUND_HALF_DOWN)
Decimal("0.00001")
)
return inv_pair, inv_bid, inv_ask
def connect_to_stream(self):
pairs_oanda = ["%s_%s" % (p[:3], p[3:]) for p in self.pairs]
try:
requests.packages.urllib3.disable_warnings()
s = requests.Session()
url = "https://" + self.domain + "/v1/prices"
headers = {'Authorization' : 'Bearer ' + self.access_token}
@@ -46,7 +50,7 @@ class StreamingForexPrices(PriceHandler):
return resp
except Exception as e:
s.close()
print "Caught exception when connecting to stream\n" + str(e)
print("Caught exception when connecting to stream\n" + str(e))
def stream_to_queue(self):
response = self.connect_to_stream()
@@ -55,19 +59,21 @@ class StreamingForexPrices(PriceHandler):
for line in response.iter_lines(1):
if line:
try:
msg = json.loads(line)
dline = line.decode('utf-8')
msg = json.loads(dline)
except Exception as e:
print "Caught exception when converting message into json\n" + str(e)
print("Caught exception when converting message into json\n" + str(e))
return
if msg.has_key("instrument") or msg.has_key("tick"):
print msg
if "instrument" in msg or "tick" in msg:
print(msg)
getcontext().rounding = ROUND_HALF_DOWN
instrument = msg["tick"]["instrument"].replace("_", "")
time = msg["tick"]["time"]
bid = Decimal(str(msg["tick"]["bid"])).quantize(
Decimal("0.00001", ROUND_HALF_DOWN)
Decimal("0.00001")
)
ask = Decimal(str(msg["tick"]["ask"])).quantize(
Decimal("0.00001", ROUND_HALF_DOWN)
Decimal("0.00001")
)
self.prices[instrument]["bid"] = bid
self.prices[instrument]["ask"] = ask
+14 -4
View File
@@ -1,6 +1,16 @@
from __future__ import print_function
from abc import ABCMeta, abstractmethod
import httplib
import urllib
try:
import httplib
except ImportError:
import http.client as httplib
try:
from urllib import urlencode
except ImportError:
from urllib.parse import urlencode
import urllib3
urllib3.disable_warnings()
class ExecutionHandler(object):
@@ -47,7 +57,7 @@ class OANDAExecutionHandler(ExecutionHandler):
"Content-Type": "application/x-www-form-urlencoded",
"Authorization": "Bearer " + self.access_token
}
params = urllib.urlencode({
params = urlencode({
"instrument" : instrument,
"units" : event.units,
"type" : event.order_type,
@@ -59,5 +69,5 @@ class OANDAExecutionHandler(ExecutionHandler):
params, headers
)
response = self.conn.getresponse().read()
print response
print(response)
+6 -3
View File
@@ -1,3 +1,5 @@
from __future__ import print_function
from copy import deepcopy
from decimal import Decimal, getcontext, ROUND_HALF_DOWN
import os
@@ -73,7 +75,7 @@ class Portfolio(object):
out_file = os.path.join(OUTPUT_RESULTS_DIR, filename)
df_equity = pd.DataFrame.from_records(self.equity, index='time')
df_equity.to_csv(out_file)
print "Simulation complete and results exported to %s" % filename
print("Simulation complete and results exported to %s" % filename)
def execute_signal(self, signal_event):
side = signal_event.side
@@ -123,5 +125,6 @@ class Portfolio(object):
order = OrderEvent(currency_pair, units, "market", side)
self.events.put(order)
print "Balance: %0.2f" % self.balance
self.append_equity_row(time, self.balance)
print("Balance: %0.2f" % self.balance)
self.append_equity_row(time, self.balance)
+4 -2
View File
@@ -92,7 +92,8 @@ class Position(object):
self.update_position_price()
# Calculate PnL
pnl = self.calculate_pips() * qh_close * dec_units
return pnl.quantize(Decimal("0.01", ROUND_HALF_DOWN))
getcontext().rounding = ROUND_HALF_DOWN
return pnl.quantize(Decimal("0.01"))
def close_position(self):
ticker_cp = self.ticker.prices[self.currency_pair]
@@ -106,4 +107,5 @@ class Position(object):
self.update_position_price()
# Calculate PnL
pnl = self.calculate_pips() * qh_close * self.units
return pnl.quantize(Decimal("0.01", ROUND_HALF_DOWN))
getcontext().rounding = ROUND_HALF_DOWN
return pnl.quantize(Decimal("0.01"))
+1 -5
View File
@@ -1,4 +1,4 @@
from decimal import Decimal, getcontext
from decimal import Decimal
import unittest
from position import Position
@@ -28,7 +28,6 @@ class TestLongGBPUSDPosition(unittest.TestCase):
denominated currency of GBP, using 2,000 units of GBP/USD.
"""
def setUp(self):
getcontext.prec = 2
home_currency = "GBP"
position_type = "long"
currency_pair = "GBPUSD"
@@ -78,7 +77,6 @@ class TestShortGBPUSDPosition(unittest.TestCase):
denominated currency of GBP, using 2,000 units of GBP/USD.
"""
def setUp(self):
getcontext.prec = 2
home_currency = "GBP"
position_type = "short"
currency_pair = "GBPUSD"
@@ -132,7 +130,6 @@ class TestLongEURUSDPosition(unittest.TestCase):
denominated currency of GBP, using 2,000 units of EUR/USD.
"""
def setUp(self):
getcontext.prec = 2
home_currency = "GBP"
position_type = "long"
currency_pair = "EURUSD"
@@ -183,7 +180,6 @@ class TestLongEURUSDPosition(unittest.TestCase):
denominated currency of GBP, using 2,000 units of EUR/USD.
"""
def setUp(self):
getcontext.prec = 2
home_currency = "GBP"
position_type = "short"
currency_pair = "EURUSD"
+8 -5
View File
@@ -1,8 +1,11 @@
import copy
import Queue
from decimal import Decimal, getcontext
try:
import Queue as queue
except ImportError:
import queue
import threading
import time
from decimal import Decimal, getcontext
from qsforex.execution.execution import OANDAExecutionHandler
from qsforex.portfolio.portfolio import Portfolio
@@ -22,7 +25,7 @@ def trade(events, strategy, portfolio, execution, heartbeat):
while True:
try:
event = events.get(False)
except Queue.Empty:
except queue.Empty:
pass
else:
if event is not None:
@@ -40,7 +43,7 @@ if __name__ == "__main__":
getcontext().prec = 2
heartbeat = 0.0 # Half a second between polling
events = Queue.Queue()
events = queue.Queue()
equity = settings.EQUITY
# Trade "Cable"
@@ -81,4 +84,4 @@ if __name__ == "__main__":
# Start both threads
trade_thread.start()
price_thread.start()
price_thread.start()