first commit

This commit is contained in:
newellp88
2018-05-08 20:51:20 +08:00
commit 55c11b374a
12 changed files with 342 additions and 0 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+25
View File
@@ -0,0 +1,25 @@
# account details for export
from oandapyV20 import API
from oandapyV20.endpoints.accounts import AccountSummary
from .config import accountID, token
api = API(token)
r = AccountSummary(accountID)
summary = api.request(r) # base dict
account = summary['account'] # item containing dict of account data
account_summary = dict()
balance = account['balance']
open_trades = account['openTradeCount']
open_positions = account['openPositionCount']
pnl = account['pl']
carrying_costs = account['financing']
open_pnl = account['unrealizedPL']
nav = account['NAV']
margin_used = account['marginUsed']
margin_available = account['marginAvailable']
margin_call_pct = account['marginCallPercent']
margin_rate = account['marginRate']
+20
View File
@@ -0,0 +1,20 @@
# contains settings and common lists of assets to trade
# basic account/environment details
accountID = '101-011-4913967-001'
token = '88899e549cd4edf80ddcf7e4f8a57f60-f7067b6e2e3c2ef5ba5de3116e7ae5e2'
env = 'practice' # change this to 'live' when you're ready
# major portfolios
currencies = ['EUR_USD', 'GBP_USD', 'USD_JPY', 'AUD_USD', 'NZD_USD',
'USD_CHF', 'USD_CAD', 'XAU_USD', 'AUD_JPY', 'EUR_JPY',
'GBP_JPY']
indicies = ['SPX500_USD', 'AU200_AUD', 'CN50_USD', 'EU50_EUR', 'FR40_EUR',
'DE30_EUR', 'HK33_HKD', 'IN50_USD', 'JP225_USD', 'NL25_EUR',
'SG30_SGD', 'TWIX_USD', 'UK100_GBP', 'US30_USD', 'NAS100_USD',
'US2000_USD']
commodities = ['BCO_USD', 'XCU_USD', 'CORN_USD', 'NATGAS_USD', 'SOYBN_USD',
'SUGAR_USD', 'WTICO_USD', 'WHEAT_USD']
+112
View File
@@ -0,0 +1,112 @@
# short list of trading indicators
import numpy as np
import pandas as pd
from sklearn import ensemble, tree
from sklearn.model_selection import train_test_split
def sma(series, window):
mavg = series.rolling(window=window, min_periods=window).mean()
return mavg
# exponential weighted moving average
def ewma(series, span):
ema = pd.ewma(series, span=span)
return ema
def pivotPoints(df):
n = len(df) - 1 # pivotPoints would be based on the last candle
pp = (df['High'] + df['Low'] + df['Close']) / 3
r1 = (2 * pp) - df['Low']
s1 = (2 * pp) - df['High']
r2 = (pp - s1) + r1
s2 = pp - (r1 - s1)
r3 = (pp - s2) + r2
s3 = pp - (r2 - s2)
pivots = {'PP': pp, 'R1': r1, 'R2': r2, 'R3': r3,
'S1': s1, 'S2': s2, 'S3': s3}
return pivots
# rate of change, applied directly to the dataframe
def roc(df):
closes = df['Close'].apply(float)
df['ROC'] = closes.diff() * 100
df['ROC'].fillna(0)
return df
# stochastic oscillator, applied directly to the dataframe
def stoch(df, period_K, period_D, graph=False):
df['Low'] = pd.to_numeric(df['Low'], errors='coerce')
df['Lstoch'] = df['Low'].rolling(window=period_K).min()
df['High'] = pd.to_numeric(df['High'], errors='coerce')
df['Hstoch'] = df['High'].rolling(window=period_K).max()
df['Close'] = pd.to_numeric(df['Close'], errors='coerce')
df['%K'] = 100*((df['Close'] - df['Lstoch']) / (df['Hstoch'] - df['Lstoch']))
df['%D'] = df['%K'].rolling(window=period_D).mean()
if graph == True:
fig, axes = plt.subplots(nrows=2, ncols=1, figsize=(20,10))
df['Close'].plot(ax=axes[0])#, title='Close'
df[['K', 'D']].plot(ax=axes[1])#, title='Oscillator'
plt.show()
return df
# bollinger bands, applied directly to the dataframe
def bollBands(df, window, n_std, graph=False):
close = df['Close']
rolling_mean = close.rolling(window).mean()
rolling_std = close.rolling(window).std()
df['rolling_mean'] = rolling_mean
df['boll_high'] = rolling_mean + (rolling_std * n_std)
df['boll_low'] = rolling_mean - (rolling_std * n_std)
if graph == True:
plt.plot(close)
plt.plot(df['Rolling Mean'])
plt.plot(df['Bollinger High'])
plt.plot(df['Bollinger Low'])
plt.show()
return df
# AdaBoostRegressor with Decision Tree base, uses most of the standard df
def AdaBoost(df):
# clean the data
n = len(df)
X = np.asarray(df[['Open','High','Low','Volume']][:n-1]) # add or subtract input data columns here
X = X.reshape(n-1, 4) # adjust '4' to match the number of input columns used above
y = np.asarray(df[['Close']][1:])
# build and score the model
split = 0.8
X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=split)
dtree = tree.DecisionTreeRegressor(max_depth=1000)
model = ensemble.AdaBoostRegressor(n_estimators=5000, learning_rate=2.0, base_estimator=dtree)
model.fit(X_train, y_train)
score = model.score(X_test, y_test)
#print("Model1 accuracy: ", score)
# make a prediction
prediction = model.predict(df[['Open','High','Low','Volume']][n-1:])
#print("AdaBoost predicted close for next candle: ", prediction)
return prediction
# RandomForestRegressor with Decision Tree base, uses most of the standard df
def RandomForest(df):
# clean the data
n = len(df)
X = np.asarray(df[['Open','High','Low','Volume']][:n-1]) # add or subtract input data columns here
X = X.reshape(n-1, 4) # adjust '4' to match the number of input columns used above
y = np.asarray(df[['Close']][1:])
# build and score the model
split = 0.8
X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=split)
model = ensemble.RandomForestRegressor(n_estimators=10000, max_depth=1000)
model.fit(X_train, y_train)
score = model.score(X_test, y_test)
#print("Model2 accuracy: ", score)
# make a prediction
prediction = model.predict(df[['Open','High','Low','Volume']][n-1:])
#print("RandomForest predicted close for next candle: ", prediction)
return prediction
+77
View File
@@ -0,0 +1,77 @@
# class to support opening and closing trades
import json
from .config import accountID, token
from oandapyV20 import API
import oandapyV20.endpoints.trades as trades
import oandapyV20.endpoints.orders as orders
from oandapyV20.contrib.requests import TradeCloseRequest
from oandapyV20.exceptions import V20Error
from .account import margin_available, margin_rate
from oandapyV20.contrib.requests import (MarketOrderRequest,
TakeProfitDetails,
StopLossDetails,
TrailingStopLossOrderRequest)
api = API(token)
def weight(price, allocation):
trade_margin = float(margin_available) * allocation
trade_value = trade_margin / float(margin_rate)
w = round((trade_value/float(price)), 0)
return w
def order(instrument, weight, price, TP, SL):
if weight > 0:
mktOrder = MarketOrderRequest(
instrument=instrument,
units=weight,
takeProfitOnFill=TakeProfitDetails(price=TP).data,
stopLossOnFill=StopLossDetails(price=SL).data)
r = orders.OrderCreate(accountID, data=mktOrder.data)
try:
rv = api.request(r)
#print(r.status_code)
except V20Error as e:
print(r.status_code, e)
else:
#print(json.dumps(rv, indent=4))
pass
else:
mktOrder = MarketOrderRequest(
instrument=instrument,
units=weight,
takeProfitOnFill=TakeProfitDetails(price=TP).data,
stopLossOnFill=StopLossDetails(price=SL).data)
r = orders.OrderCreate(accountID, data=mktOrder.data)
try:
rv = api.request(r)
#print(r.status_code)
except V20Error as e:
print(r.status_code, e)
else:
#print(json.dumps(rv, indent=4))
pass
return r.response
def trailingStop(tradeID, distance=0.1):
activeStop = TrailingStopLossOrderRequest(tradeID=tradeID,
r = orders.OrderCreate(accountID,
data=activeStop.data))
api.request(r)
return r.response
def close(tradeID):
close_trade = TradeCloseRequest()
r = trades.TradeClose(accountID, tradeID, data=close_trade.data)
api.request(r)
return r.response
def closeAll(tradeID_list):
for trade in tradeID_list:
close(trade)
print(trade, "Closed")
+57
View File
@@ -0,0 +1,57 @@
# price history or stream functions
from .config import token, accountID, env
from oandapyV20 import API
from oandapyV20.endpoints.instruments import InstrumentsCandles
from oandapyV20.endpoints.pricing import PricingStream
import pandas as pd
import time
api = API(token)
# returns the last 500 OHLCV candles for an instrument
# maximum count is 500
# window: M1, M5, M15, H, H4, D, etc.
def history(instrument, window, collection=False):
instrument = instrument
data = list()
client = API(token)
params = {"count": 500, "granularity": window}
r = InstrumentsCandles(instrument, params)
client.request(r)
resp = r.response
for candle in resp.get('candles'):
dt = candle['time']
Open = candle['mid']['o']
High = candle['mid']['h']
Low = candle['mid']['l']
Close = candle['mid']['c']
Volume = candle['volume']
update = [dt, Open, High, Low, Close, Volume]
data.append(update)
df = pd.DataFrame(data, columns=['dt','Open','High','Low','Close','Volume'])
# collect data, useful for research and weekends/holidays when the market isn't open
if collection == True:
title = 'data/%s_%s_history.csv' % (instrument, window)
df.to_csv(title)
return df
# creates a pricing stream,
def stream(instrument, window):
request_params = {"timeout":100}
params = {"instruments":instrument, "granularity":window}
api = API(access_token=token,environment=env, request_params=request_params)
r = PricingStream(accountID=accountID, params=params)
while True:
try:
api.request(r)
for R in r.response:
time = R['time']
ask = R['asks'][0]['price']
bid = R['bids'][0]['price']
return time, ask, bid
except Exception as e:
print(e)
continue
+51
View File
@@ -0,0 +1,51 @@
"""
script that runs continuously and collects pricing and technical indicators data,
entering the data into instrument/window data tables.
"""
import sqlite3
import sqlalchemy
import pandas as pd
from datetime import datetime
from backend.pricing import history
from backend.config import currencies
from backend.indicators import sma, stoch, pivotPoints, bollBands
windows = ['M5', 'M15', 'H1', 'H4', 'D']
for instr in currencies:
for w in windows:
LiteCurrencyDB(instr, w)
def LiteCurrencyDB(instr, w):
# connect to the DB
db = sqlite3.connect('liteDB/currencies.db')
c = db.cursor()
table_name = "%s_%s" % (instr, w)
# get last 500 data points
df = history(instr, w)
prices = df['Close']
# set the dataframe with our technical indicators
df['fast_sma'] = sma(prices, 6)
df['slow_sma'] = sma(prices, 10)
df = stoch(df, 6, 3)
df = bollBands(df, 5, 0.5)
pp = pd.DataFrame(data=pivotPoints(df))
df = pd.concat([df,pp], axis=1, join_axes=[df.index])
inputs = list(tuple(row for idx, row in df.iterrows()))
# insert them into the dedicated table for this currency and timeframe
c.execute('''CREATE TABLE IF NOT EXISTS {}(
dt TEXT, Open REAL, High REAL, Low REAL, Close REAL,
Volume INTEGER, fast_sma REAL, slow_sma REAL, Lstoch REAL,
Hstoch REAL, K REAL, D REAL, rolling_mean REAL, boll_high REAL,
boll_low REAL, PP REAL, R1 REAL, R2 REAL, R3 REAL, S1 REAL,
S2 REAL, S3 REAL
)'''.format(table_name))
c.executemany('''INSERT INTO {}(
dt, Open, High, Low, Close, Volume, fast_sma, slow_sma, Lstoch,
Hstoch, K, D, rolling_mean, boll_high, boll_low, PP, R1, R2, R3,
S1, S2, S3
) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)'''
.format(table_name), inputs)
db.commit()
print('table created successfully')
return db, df
Binary file not shown.