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:
@@ -1,5 +1,6 @@
|
||||
*~
|
||||
*.py[co]
|
||||
__pycache__
|
||||
|
||||
# Packages
|
||||
*.egg
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,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
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user