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