using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using QuantConnect.Securities;
using QuantConnect.Models;
namespace QuantConnect {
public partial class OandaAutochartist : QCAlgorithm
{
public string[] OandacfdMajors = {
"AUDJPY","AUDUSD","EURAUD","EURCHF","EURGBP","EURJPY","EURUSD","GBPCHF","GBPJPY","GBPUSD",
"NZDUSD","USDCAD","USDCHF","USDJPY" };
[Parameter]
public string accessToken;
[Parameter]
public string timeZone = "Australia/Brisbane";
[Parameter]
public int lotSize = 10;
[Parameter]
public bool isLive = false;
public string[] Symbols;
public bool test = true;
public override void Initialize()
{
SetTimeZone(timeZone);
SetStartDate(DateTime.Now.Date.AddDays(-1));
SetCash(100000);
SetBrokerageModel(BrokerageName.OandaBrokerage);
Symbols = OandacfdMajors;
foreach (var symbol in Symbols)
{
AddCfd(symbol, Resolution.Hour, Market.Oanda);
}
Schedule.On(DateRules.EveryDay(), TimeRules.Every(TimeSpan.FromMinutes(10)), () =>
{
if ((isLive || test) && accessToken != "<enter>")
{
ProcessAutochartistSignals(QueryAutochartist());
test = false;
}
});
}
public void OnData(TradeBars data)
{
ExpireSignals();
}
public override void OnOrderEvent(OrderEvent orderEvent)
{
BracketEvent(orderEvent);
}
}
}
using RestSharp; // http://restsharp.org/
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace QuantConnect {
public partial class OandaAutochartist : QCAlgorithm
{
public string QueryAutochartist(string type = "chartpattern")
{
var url = "https://api-fxtrade.oanda.com/labs/v1/signal/autochartist?type=";
var auth = "Bearer " + accessToken;
var client = new RestClient();
client.BaseUrl = new Uri(url + type);
var request = new RestRequest();
request.AddHeader("Authorization", auth);
IRestResponse response = client.Execute(request);
return response.Content;
}
public void ProcessAutochartistSignals(String json)
{
JObject jobj = JObject.Parse(json);
IList<JToken> jtoks = jobj?["signals"].Children().ToList();
foreach (JToken jtok in jtoks)
{
Signal signal = jtok.ToObject<Signal>();
ExecuteSignal(signal);
}
}
public void ExecuteSignal(Signal signal)
{
var activeSignal = GenActiveSignal(signal);
if (!ValidateSignal(activeSignal))
{
return;
}
MarketOrder(activeSignal.Symbol, signal.meta.direction * lotSize, false, GenSignalTag(activeSignal));
}
public bool ValidateSignal(ActiveSignal activeSignal)
{
var symbol = activeSignal.Symbol;
return (Symbols.Contains(symbol)
&& activeSignal.IsCompleted
&& !Portfolio[symbol].Invested
&& (IsMarketOpen(symbol) || !isLive)
&& !IsExpired(activeSignal.Expiration)
&& IsApproachingTarget(activeSignal))
? true : false;
}
public bool IsApproachingTarget(ActiveSignal activeSignal)
{
var currentPrice = Securities[activeSignal.Symbol].Price;
return ((activeSignal.IsLong && currentPrice < activeSignal.Forecast)
|| (activeSignal.IsShort && currentPrice > activeSignal.Forecast)) ? true : false;
}
public bool IsExpired(DateTime expiration)
{
return Time >= expiration ? true : false;
}
public bool IsHedgingPortfolio(ActiveSignal activeSignal)
{
return ((Portfolio[activeSignal.Symbol].IsLong && activeSignal.IsShort)
|| (Portfolio[activeSignal.Symbol].IsShort && activeSignal.IsLong))
? true : false;
}
public ActiveSignal GenActiveSignal(Signal signal)
{
var activeSignal = new ActiveSignal();
activeSignal.Id = signal.id;
activeSignal.IsCompleted = signal.meta.completed == 1 ? true : false;
activeSignal.IsLong = signal.meta.direction == 1 ? true : false;
activeSignal.IsShort = signal.meta.direction == -1 ? true : false;
activeSignal.Symbol = signal.instrument.Replace("_","");
activeSignal.Expiration = DateTimeOffset.FromUnixTimeSeconds(signal.data.prediction.timeto).DateTime;
activeSignal.Forecast = (decimal)(signal.meta.direction == 1 ? signal.data.prediction.pricelow : signal.data.prediction.pricehigh);
return activeSignal;
}
public class ActiveSignal
{
public int Id { get; set; }
public bool IsCompleted { get; set; }
public bool IsLong { get; set; }
public bool IsShort { get; set; }
public string Symbol { get; set; }
public DateTime Expiration { get; set; }
public decimal Forecast { get; set; }
}
public string GenSignalTag(ActiveSignal activeSignal)
{
var orderTag = new OrderTag();
orderTag.SignalId = activeSignal.Id;
orderTag.Expiration = activeSignal.Expiration;
orderTag.Target = activeSignal.Forecast;
return JsonConvert.SerializeObject(orderTag);
}
public class OrderTag
{
public int SignalId { get; set; } = 0;
public DateTime Expiration { get; set; } = DateTime.MaxValue;
public decimal Target { get; set; } = 0;
}
public void BracketEvent(OrderEvent orderEvent)
{
var orderTicket = Transactions.GetOrderTicket(orderEvent.OrderId);
if (orderTicket.Status == OrderStatus.Submitted
&& orderTicket.OrderType == OrderType.Market)
{
AddBracket(orderTicket);
}
else if (orderTicket.Status.IsClosed()
&& (orderTicket.OrderType == OrderType.StopMarket
|| orderTicket.OrderType == OrderType.Limit))
{
CloseBracket(orderTicket.Symbol);
}
}
public void AddBracket(OrderTicket submittedTicket)
{
if (!Transactions.GetOrderTickets(x => x.Status.IsOpen()
&& x.Symbol == submittedTicket.Symbol
&& x.OrderType == OrderType.StopMarket).Any())
{
SetStopLoss(submittedTicket);
}
if (!Transactions.GetOrderTickets(x => x.Status.IsOpen()
&& x.Symbol == submittedTicket.Symbol
&& x.OrderType == OrderType.Limit).Any())
{
SetTakeProfit(submittedTicket);
}
}
public void SetStopLoss(OrderTicket submittedOpenTicket)
{
StopMarketOrder(submittedOpenTicket.Symbol, -submittedOpenTicket.Quantity, CalcStopLoss(submittedOpenTicket), submittedOpenTicket.Tag);
}
public decimal CalcStopLoss(OrderTicket openTicket)
{
OrderTag orderTag = JsonConvert.DeserializeObject<OrderTag>(openTicket.Tag);
var openPrice = Securities[openTicket.Symbol].Price;
var profitRange = Math.Abs(orderTag.Target - openPrice);
var lossRange = profitRange / 2;
return orderTag.Target > openPrice ? openPrice - lossRange : openPrice + lossRange;
}
public void SetTakeProfit(OrderTicket submittedOpenTicket)
{
OrderTag openTag = JsonConvert.DeserializeObject<OrderTag>(submittedOpenTicket.Tag);
LimitOrder(submittedOpenTicket.Symbol, -submittedOpenTicket.Quantity, openTag.Target, submittedOpenTicket.Tag);
}
public void CloseBracket(string symbol)
{
Transactions.CancelOpenOrders(symbol);
}
public void ExpireSignals()
{
foreach (Order openOrder in Transactions.GetOpenOrders())
{
OrderTag orderTag = JsonConvert.DeserializeObject<OrderTag>(openOrder.Tag);
if (IsExpired(orderTag.Expiration))
{
Liquidate(openOrder.Symbol);
CloseBracket(openOrder.Symbol);
}
}
}
}
}