qstrader
qstrader copied to clipboard
An idea to ensure the PriceHandler has the up to date prices?
Hi,
Looking for ways to integrate FXCM data into QSTrader and one problem is the PriceHandler
has a built-in 'price lag' which amplifies on higher times frames.
Take the following example:
Current Short Position
- Sold EUR, Bought USD
- EURUSD
- 10K lot
- Price 1.12035
Based on how the Position
object is coded and with zero commission, this would translate to 10000 * 1.12035 = 11200.35USD
My account currency is GBP, so on each iteration, the Portfolio
should update equity
in GBP, not USD. This is easy, just make sure that GBPUSD is included in the backtest data and make the conversion.
- GBPUSD = 1.23456
- 11200.35 \ 1.23456
- Position Value 9072.34GBP
If using say Daily
data, the values used to calculate the exchange rate would be 1 Day behind, because the Portfolio
is calling the PriceHandler
for the last known value and of course the most current value has not been iterated through the event loop.
To make sure the PriceHandler
has all the values stored with the same timestamp. I have implemented the following code below.
The code will call next
until the date is greater than the last. The last greater than date is saved and only placed into the queue on the next iteration.
Some Event
log output to visualise.
Type: EventType.BAR, Ticker: EURUSD, Time: 2013-12-23 22:00:00, Period: 1day, BidOpen: 13696800, BidHigh: 13715599, BidLow: 13655899, BidClose: 13676400, AskOpen: 13695300, AskHigh: 13713400, AskLow: 13654300, AskClose: 13674400,Volume: 49603
Type: EventType.BAR, Ticker: GBPUSD, Time: 2013-12-23 22:00:00, Period: 1day, BidOpen: 16361000, BidHigh: 16382000, BidLow: 16323700, BidClose: 16370399, AskOpen: 16351900, AskHigh: 16380999, AskLow: 16321500, AskClose: 16367500,Volume: 61296
Type: EventType.BAR, Ticker: USDOLLAR, Time: 2013-12-23 22:00:00, Period: 1day, BidOpen: 106830000000, BidHigh: 107000000000, BidLow: 106820000000, BidClose: 106920000000, AskOpen: 106800000000, AskHigh: 106970000000, AskLow: 106770000000, AskClose: 106890000000,Volume: 2171
Reset
Type: EventType.BAR, Ticker: USDOLLAR, Time: 2013-12-24 22:00:00, Period: 1day, BidOpen: 106920000000, BidHigh: 106920000000, BidLow: 106920000000, BidClose: 106920000000, AskOpen: 106890000000, AskHigh: 106890000000, AskLow: 106890000000, AskClose: 106890000000,Volume: 1
Reset
Type: EventType.BAR, Ticker: EURUSD, Time: 2013-12-25 22:00:00, Period: 1day, BidOpen: 13676400, BidHigh: 13703100, BidLow: 13675700, BidClose: 13692100, AskOpen: 13674400, AskHigh: 13701400, AskLow: 13673200, AskClose: 13689900,Volume: 38743
Type: EventType.BAR, Ticker: GBPUSD, Time: 2013-12-25 22:00:00, Period: 1day, BidOpen: 16370399, BidHigh: 16439199, BidLow: 16370399, BidClose: 16412500, AskOpen: 16367500, AskHigh: 16437200, AskLow: 16367500, AskClose: 16408799,Volume: 54611
Type: EventType.BAR, Ticker: USDOLLAR, Time: 2013-12-25 22:00:00, Period: 1day, BidOpen: 106920000000, BidHigh: 107080000000, BidLow: 106920000000, BidClose: 106980000000, AskOpen: 106890000000, AskHigh: 107050000000, AskLow: 106890000000, AskClose: 106950000000,Volume: 1784
Reset
Type: EventType.BAR, Ticker: EURUSD, Time: 2013-12-26 22:00:00, Period: 1day, BidOpen: 13692100, BidHigh: 13894899, BidLow: 13688200, BidClose: 13749799, AskOpen: 13689900, AskHigh: 13892900, AskLow: 13686399, AskClose: 13745800,Volume: 141970
Type: EventType.BAR, Ticker: GBPUSD, Time: 2013-12-26 22:00:00, Period: 1day, BidOpen: 16412500, BidHigh: 16578900, BidLow: 16405599, BidClose: 16486599, AskOpen: 16408799, AskHigh: 16577400, AskLow: 16405200, AskClose: 16473099,Volume: 114972
Type: EventType.BAR, Ticker: USDOLLAR, Time: 2013-12-26 22:00:00, Period: 1day, BidOpen: 106980000000, BidHigh: 107030000000, BidLow: 106330000000, BidClose: 106910000000, AskOpen: 106950000000, AskHigh: 107000000000, AskLow: 106310000000, AskClose: 106850000000,Volume: 4002
Reset
Type: EventType.BAR, Ticker: EURUSD, Time: 2013-12-29 22:00:00, Period: 1day, BidOpen: 13760200, BidHigh: 13819600, BidLow: 13729000, BidClose: 13802400, AskOpen: 13753700, AskHigh: 13818500, AskLow: 13727600, AskClose: 13797900,Volume: 98382
Type: EventType.BAR, Ticker: GBPUSD, Time: 2013-12-29 22:00:00, Period: 1day, BidOpen: 16485700, BidHigh: 16533799, BidLow: 16460800, BidClose: 16498499, AskOpen: 16473099, AskHigh: 16531900, AskLow: 16459200, AskClose: 16495899,Volume: 92096
Type: EventType.BAR, Ticker: USDOLLAR, Time: 2013-12-29 22:00:00, Period: 1day, BidOpen: 106910000000, BidHigh: 107050000000, BidLow: 106500000000, BidClose: 106670000000, AskOpen: 106850000000, AskHigh: 107030000000, AskLow: 106480000000, AskClose: 106640000000,Volume: 3341
Reset
Type: EventType.BAR, Ticker: EURUSD, Time: 2013-12-30 22:00:00, Period: 1day, BidOpen: 13802400, BidHigh: 13813400, BidLow: 13760299, BidClose: 13779500, AskOpen: 13797900, AskHigh: 13811900, AskLow: 13759200, AskClose: 13777400,Volume: 60476
Type: EventType.BAR, Ticker: GBPUSD, Time: 2013-12-30 22:00:00, Period: 1day, BidOpen: 16498499, BidHigh: 16579499, BidLow: 16475400, BidClose: 16572800, AskOpen: 16495899, AskHigh: 16577400, AskLow: 16473799, AskClose: 16570799,Volume: 55302
Type: EventType.BAR, Ticker: USDOLLAR, Time: 2013-12-30 22:00:00, Period: 1day, BidOpen: 106670000000, BidHigh: 106710000000, BidLow: 106470000000, BidClose: 106560000000, AskOpen: 106640000000, AskHigh: 106670000000, AskLow: 106450000000, AskClose: 106530000000,Volume: 2345
Reset
def __init__(self):
.....
.....
self.last_row = None
self.row_saved = False
.....
[snip]
def _iter_nextrow(self):
"""
Get next row from the pandas DataFrame
"""
try:
return next(self.bar_stream)
except StopIteration:
self.continue_backtest = False
return None, None
def place_into_queue(self, index, row):
"""
Place the next FXCMBarEvent onto the event queue
"""
# Obtain all elements of the bar from the dataframe
ticker = row["Ticker"]
period = 86400 # Seconds in a day
# Create the tick event for the queue
bev = self._create_event(index, period, ticker, row)
# Store event
self._store_event(bev)
# Send event to queue
self.events_queue.put(bev)
def stream_next(self):
"""
Stream all bars that have the same date.
"""
# No row saved on system startup
if self.row_saved:
# Get last saved row and reset
index, row = self.last_row
self.place_into_queue(index, row)
self.row_saved = False
# System starts here on first run
while True:
index, row = self._iter_nextrow()
if row is None:
return
if self.last_row is not None:
if index > self.last_row[0]:
# Save last row for later
self.last_row = index, row
self.row_saved = True
return
# Update last row
self.last_row = index, row
self.place_into_queue(index, row)
Any ideas or comments please?
Many Thanks
James
is anyone there?